selected_links 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: a72ed39a28bc86f1968e5917acf8d22bcafbc4ae
4
+ data.tar.gz: 06fe422e7a22075166d2a18c1a23ff8979e49c7e
5
+ SHA512:
6
+ metadata.gz: 92fcbf275164b2e9f23395fde587ac2762b323aba350016b4063bb95eaab2ccf62445dd9811f37219705a1d6220d6992e8f3fe629145501a23694b4b1957a3b2
7
+ data.tar.gz: 1773584622c80ad0f56234d433d9f7102b464b834c512cb7bd10bba5387e9fb1cff3fbf4afdd871bc0f7a8bcacbb39c12fe01bdc8691e04b6124782d3cd89559
data/.gitignore ADDED
@@ -0,0 +1,18 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
18
+ .project
data/.rspec ADDED
@@ -0,0 +1 @@
1
+ --color
data/CHANGELOG.md ADDED
@@ -0,0 +1,3 @@
1
+ ## v0.0.1
2
+
3
+ * Initial Release
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in selected_links.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2013 Kainage
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,79 @@
1
+ # SelectedLinks
2
+
3
+ Adds a link helper to ActionView::Base to that adds a class of _selected_
4
+ to the link when matched to a pattern, usually a url.
5
+
6
+ ## Installation
7
+
8
+ Add this line to your application's Gemfile:
9
+
10
+ gem 'selected_links'
11
+
12
+ And then execute:
13
+
14
+ $ bundle
15
+
16
+ Or install it yourself as:
17
+
18
+ $ gem install selected_links
19
+
20
+ ## Configuration
21
+
22
+ Usage is the same as link_to and takes 2 optional arguments ```:matcher``` and ```:source```.
23
+
24
+ The default source matches to ```request.path```. This can be overridden in an initializer
25
+
26
+ ```ruby
27
+ SelectedLinks.setup do |config|
28
+ config.default_source = 'request.url'
29
+ end
30
+ ```
31
+
32
+ ### Useage
33
+
34
+ To make this link have a class of _selected_ when the url is at the top level:
35
+
36
+ ```
37
+ <%= selectable_link_to 'Home', root_url, :matcher => '\/\z' %>
38
+ ```
39
+
40
+ To make the link selected when the url has _topic_ anywhere in it:
41
+
42
+ ```
43
+ <%= selectable_link_to 'Topics', topics_url, :matcher => 'topic' %>
44
+ ```
45
+
46
+ Blocks still work and this will do the same thing as the previous example:
47
+
48
+ ```
49
+ <% selectable_link_to community_url, :matcher => 'topic' do %>
50
+ <%= content_tag :span, 'Community', :class => 'foo' %>
51
+ <% end %>
52
+ ```
53
+
54
+ Without a matcher option and NOT in the block form, this will look for _about_ in the source:
55
+
56
+ ```
57
+ <%= selectable_link_to 'ABOUT', about_url %>
58
+ ```
59
+
60
+ You can, of course, add this to links with other clases on them:
61
+
62
+ ```
63
+ <%= selectable_link_to 'ABOUT', about_url, :class => 'nav' %>
64
+ # => <a ... class="nav selected">ABOUT</a>
65
+ ```
66
+
67
+ To override the source per link, just add a ```:source``` argument:
68
+
69
+ ```
70
+ <%= selectable_link_to 'ABOUT', about_url, :source => request.url %>
71
+ ```
72
+
73
+ ## Contributing
74
+
75
+ 1. Fork it
76
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
77
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
78
+ 4. Push to the branch (`git push origin my-new-feature`)
79
+ 5. Create new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,6 @@
1
+ require "bundler/gem_tasks"
2
+ require 'rspec/core/rake_task'
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ task default: :spec
@@ -0,0 +1,18 @@
1
+ require "selected_links/version"
2
+ require 'selected_links/link'
3
+ require 'selected_links/action_view'
4
+
5
+ if defined? Rails
6
+ require 'selected_links/railtie'
7
+ else
8
+ ActionView::Base.send(:include, SelectedLinks::ActionView)
9
+ end
10
+
11
+ module SelectedLinks
12
+ mattr_accessor :default_source
13
+ @@default_source = 'request.path'
14
+
15
+ def self.setup
16
+ yield self
17
+ end
18
+ end
@@ -0,0 +1,41 @@
1
+ require 'action_view'
2
+
3
+ module SelectedLinks
4
+ # Usage is the same as link_to and takes an optional regex argument matcher.
5
+ #
6
+ # <%= selectable_link_to 'Home', root_url, :matcher => '\/\z' %>
7
+ #
8
+ # That would make this link have a class of 'selected' when the url is at the top level.
9
+ #
10
+ # <%= selectable_link_to 'Topics', topics_url, :matcher => 'topic' %>
11
+ #
12
+ # This will make the nav link selected when the url has 'topic' in it anywhere.
13
+ #
14
+ # <% selectable_link_to community_url, :matcher => 'topic' do %>
15
+ # <%= content_tag :span, 'Community', :class => 'foo' %>
16
+ # <% end %>
17
+ #
18
+ # Blocks still work and this will do the same thing as the previous example.
19
+ #
20
+ # <%= selectable_link_to 'ABOUT', about_url %>
21
+ #
22
+ # Without a matcher option and NOT in the block form, this will look for 'about' in the url.
23
+ module ActionView
24
+ def selectable_link_to(*args, &block)
25
+ link = Link.new(*args, &block).generate
26
+
27
+ # Add default source if none was given.
28
+ unless link.source
29
+ link.source = instance_eval(SelectedLinks.default_source)
30
+ # Can run generate again because there will for sure be no match here yet.
31
+ link.generate
32
+ end
33
+
34
+ if block_given?
35
+ raw link_to link.options, link.html_options, &block
36
+ else
37
+ raw link_to link.name, link.options, link.html_options
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,55 @@
1
+ module SelectedLinks
2
+ class Link
3
+ attr_reader :name, :options, :html_options
4
+ attr_accessor :source
5
+
6
+ def initialize(*args, &block)
7
+ @name, @options, @html_options = parse_args(block_given?, *args)
8
+ @matcher = @html_options[:matcher]
9
+ @source = @html_options[:source]
10
+ end
11
+
12
+ def generate
13
+ merge_classes if is_match?
14
+ cleanup
15
+
16
+ self
17
+ end
18
+
19
+ private
20
+
21
+ def parse_args(block, *args)
22
+ if block
23
+ [nil, args.first, args.second || {}]
24
+ else
25
+ [args[0], args[1], args[2] || {}]
26
+ end
27
+ end
28
+
29
+ def merge_classes
30
+ @html_options.merge!({class: 'selected'}) { |key, old_v, new_v| [old_v, new_v].join(' ') }
31
+ end
32
+
33
+ def is_match?
34
+ url_match?(@source, @matcher) || url_match?(@source, @name)
35
+ end
36
+
37
+ def url_match?(source, matcher)
38
+ return false unless matcher # nil.to_s returns ""
39
+ source =~ /#{matcher}/i
40
+ end
41
+
42
+ def cleanup
43
+ remove_matcher
44
+ remove_source
45
+ end
46
+
47
+ def remove_matcher
48
+ @html_options.delete(:matcher)
49
+ end
50
+
51
+ def remove_source
52
+ @html_options.delete(:source)
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,9 @@
1
+ module SelectedLinks
2
+ class Railtie < Rails::Railtie
3
+ initializer 'selected_links.action_view_extension' do
4
+ ActiveSupport.on_load :action_view do
5
+ include ActionView
6
+ end
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,3 @@
1
+ module SelectedLinks
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,26 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'selected_links/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "selected_links"
8
+ spec.version = SelectedLinks::VERSION
9
+ spec.authors = ["Kainage"]
10
+ spec.email = ["kainage@gmail.com"]
11
+ spec.description = %q{Add a selected class to a link when criteria is matched}
12
+ spec.summary = %q{Adds a link helper to ActionView to that adds a class of 'selected' when matched to a pattern}
13
+ spec.homepage = "https://github.com/kainage/selected_links"
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files`.split($/)
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_development_dependency "bundler", "~> 1.3"
22
+ spec.add_development_dependency "rake"
23
+ spec.add_development_dependency "rspec"
24
+
25
+ spec.add_dependency "actionpack"
26
+ end
@@ -0,0 +1,151 @@
1
+ require 'spec_helper'
2
+
3
+ describe SelectedLinks::Link do
4
+ describe "constructing a link" do
5
+ context "without a block" do
6
+ context "with valid options" do
7
+ before :each do
8
+ @link = SelectedLinks::Link.new('Name', 'options', :source => '/foo', :matcher => 'foo')
9
+ end
10
+
11
+ it "should have a name" do
12
+ @link.name.should eq 'Name'
13
+ end
14
+
15
+ it "should have options" do
16
+ @link.options.should eq 'options'
17
+ end
18
+
19
+ it "should have have html_options of a hash with two items" do
20
+ @link.html_options.should be_a(Hash)
21
+ @link.html_options.size.should eq 2
22
+ end
23
+ end
24
+
25
+ context "with a block" do
26
+ context "with valid options" do
27
+ before :each do
28
+ @link = SelectedLinks::Link.new 'options', :source => '/foo', :matcher => 'foo' do
29
+ 'Block Content'
30
+ end
31
+ end
32
+
33
+ it "should not have a name" do
34
+ @link.name.should be_nil
35
+ end
36
+
37
+ it "should have options" do
38
+ @link.options.should eq 'options'
39
+ end
40
+
41
+ it "should have have html_options of a hash with two items" do
42
+ @link.html_options.should be_a(Hash)
43
+ @link.html_options.size.should eq 2
44
+ end
45
+ end
46
+ end
47
+ end
48
+ end
49
+
50
+ describe "with valid options" do
51
+ before :each do
52
+ @link = SelectedLinks::Link.new('Name', 'options', :source => '/foo', :matcher => 'foo')
53
+ end
54
+
55
+ it "should remove source option" do
56
+ @link.send(:remove_source)
57
+ @link.html_options.has_key?(:source).should be_false
58
+ end
59
+
60
+ it "should remove matcher option" do
61
+ @link.send(:remove_matcher)
62
+ @link.html_options.has_key?(:matcher).should be_false
63
+ end
64
+
65
+ it "should remove both source and matcher options" do
66
+ @link.send(:cleanup)
67
+ @link.html_options.has_key?(:source).should be_false
68
+ @link.html_options.has_key?(:matcher).should be_false
69
+ end
70
+
71
+ describe "url_match?" do
72
+ it "should return true when url matches given strig" do
73
+ @link.send(:url_match?, '/hello', 'hello').should be_true
74
+ end
75
+
76
+ it "should return true when url partially matches string" do
77
+ @link.send(:url_match?, '/hello', 'ell').should be_true
78
+ end
79
+
80
+ it "should return false when string does not match" do
81
+ @link.send(:url_match?, '/hello', 'world').should be_false
82
+ end
83
+ end
84
+
85
+ context "for a matcher match" do
86
+ it "should return true for a match" do
87
+ @link.send(:is_match?).should be_true
88
+ end
89
+
90
+ it "should return false for a non match" do
91
+ @link = SelectedLinks::Link.new('Name', 'options', :source => '/bar', :matcher => 'foo')
92
+ @link.send(:is_match?).should be_false
93
+ end
94
+ end
95
+
96
+ context "for a named match" do
97
+ it "should return true for a named match" do
98
+ @link = SelectedLinks::Link.new('Foo', 'options', :source => '/foo')
99
+ @link.send(:is_match?).should be_true
100
+ end
101
+
102
+ it "should return false for a non match" do
103
+ @link = SelectedLinks::Link.new('Bar', 'options', :source => '/foo')
104
+ @link.send(:is_match?).should be_false
105
+ end
106
+ end
107
+ end
108
+
109
+ describe "fully constructed link" do
110
+ context "with a matcher link" do
111
+ it "should have a class of selected added" do
112
+ @link = SelectedLinks::Link.new('Name', 'options', :source => '/foo', :matcher => 'foo').generate
113
+ @link.html_options[:class].should =~ /selected/
114
+ end
115
+
116
+ it "should not have a class of selected if there was not a match" do
117
+ @link = SelectedLinks::Link.new('Name', 'options', :source => '/foo', :matcher => 'bar').generate
118
+ @link.html_options[:class].should_not =~ /selected/
119
+ end
120
+ end
121
+
122
+ context "with a named link" do
123
+ it "should have a class of selected added" do
124
+ @link = SelectedLinks::Link.new('Foo', 'options', :source => '/foo').generate
125
+ @link.html_options[:class].should =~ /selected/
126
+ end
127
+
128
+ it "should not have a class of selected if there was not a match" do
129
+ @link = SelectedLinks::Link.new('Bar', 'options', :source => '/foo').generate
130
+ @link.html_options[:class].should_not =~ /selected/
131
+ end
132
+ end
133
+
134
+ context "with an existing class" do
135
+ it "should have a class of selected added" do
136
+ @link = SelectedLinks::Link.new('Name', 'options', :source => '/foo', :matcher => 'foo', :class => 'nav').generate
137
+ @link.html_options[:class].should =~ /selected/
138
+ end
139
+
140
+ it "should not have a class of selected if there was not a match" do
141
+ @link = SelectedLinks::Link.new('Name', 'options', :source => '/foo', :matcher => 'bar', :class => 'nav').generate
142
+ @link.html_options[:class].should_not =~ /selected/
143
+ end
144
+
145
+ it 'should have a space between the existing classes and the selected class' do
146
+ @link = SelectedLinks::Link.new('Name', 'options', :source => '/foo', :matcher => 'foo', :class => 'nav').generate
147
+ @link.html_options[:class].should == 'nav selected'
148
+ end
149
+ end
150
+ end
151
+ end
@@ -0,0 +1 @@
1
+ require 'selected_links'
metadata ADDED
@@ -0,0 +1,118 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: selected_links
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Kainage
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2013-05-23 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ~>
18
+ - !ruby/object:Gem::Version
19
+ version: '1.3'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ~>
25
+ - !ruby/object:Gem::Version
26
+ version: '1.3'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - '>='
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - '>='
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rspec
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - '>='
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: actionpack
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - '>='
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ description: Add a selected class to a link when criteria is matched
70
+ email:
71
+ - kainage@gmail.com
72
+ executables: []
73
+ extensions: []
74
+ extra_rdoc_files: []
75
+ files:
76
+ - .gitignore
77
+ - .rspec
78
+ - CHANGELOG.md
79
+ - Gemfile
80
+ - LICENSE.txt
81
+ - README.md
82
+ - Rakefile
83
+ - lib/selected_links.rb
84
+ - lib/selected_links/action_view.rb
85
+ - lib/selected_links/link.rb
86
+ - lib/selected_links/railtie.rb
87
+ - lib/selected_links/version.rb
88
+ - selected_links.gemspec
89
+ - spec/selected_links/link_spec.rb
90
+ - spec/spec_helper.rb
91
+ homepage: https://github.com/kainage/selected_links
92
+ licenses:
93
+ - MIT
94
+ metadata: {}
95
+ post_install_message:
96
+ rdoc_options: []
97
+ require_paths:
98
+ - lib
99
+ required_ruby_version: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - '>='
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ required_rubygems_version: !ruby/object:Gem::Requirement
105
+ requirements:
106
+ - - '>='
107
+ - !ruby/object:Gem::Version
108
+ version: '0'
109
+ requirements: []
110
+ rubyforge_project:
111
+ rubygems_version: 2.0.3
112
+ signing_key:
113
+ specification_version: 4
114
+ summary: Adds a link helper to ActionView to that adds a class of 'selected' when
115
+ matched to a pattern
116
+ test_files:
117
+ - spec/selected_links/link_spec.rb
118
+ - spec/spec_helper.rb