selected_links 0.0.1 → 0.0.2

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: a72ed39a28bc86f1968e5917acf8d22bcafbc4ae
4
- data.tar.gz: 06fe422e7a22075166d2a18c1a23ff8979e49c7e
3
+ metadata.gz: 62a30a37be7b8ed9394a6c728b664f415a7132ee
4
+ data.tar.gz: a0b6aa5bb7c513ebb8b81a1cd89788425ee72034
5
5
  SHA512:
6
- metadata.gz: 92fcbf275164b2e9f23395fde587ac2762b323aba350016b4063bb95eaab2ccf62445dd9811f37219705a1d6220d6992e8f3fe629145501a23694b4b1957a3b2
7
- data.tar.gz: 1773584622c80ad0f56234d433d9f7102b464b834c512cb7bd10bba5387e9fb1cff3fbf4afdd871bc0f7a8bcacbb39c12fe01bdc8691e04b6124782d3cd89559
6
+ metadata.gz: 390d347634eeacedf9a152afb93f73def7045399ee5f87932acd291ae27a4fb5caf480216e2e8c55df0ec31c82b48d467eb80aeecd743e6209d7c1f4b84b73c8
7
+ data.tar.gz: 9c24559d76be4f71a83814976d0c50fa78c278f0514418f81a7d51fb783e27d95c8c40c4ca0adcec578fa9fa19b8db2f51ba93e944cc25e91d4efc8ffd341cb9
data/.gitignore CHANGED
@@ -16,3 +16,4 @@ test/tmp
16
16
  test/version_tmp
17
17
  tmp
18
18
  .project
19
+ /nbproject
data/.travis.yml ADDED
@@ -0,0 +1,4 @@
1
+ language: ruby
2
+ rvm:
3
+ - "1.9.3"
4
+ - "2.0.0"
data/CHANGELOG.md CHANGED
@@ -1,3 +1,7 @@
1
+ ## v0.0.2
2
+
3
+ * Added fallback behaviour support via initializer setting
4
+
1
5
  ## v0.0.1
2
6
 
3
7
  * Initial Release
data/README.md CHANGED
@@ -1,4 +1,6 @@
1
- # SelectedLinks
1
+ # Selected Links
2
+
3
+ [![Build Status](https://travis-ci.org/kainage/selected_links.png)](https://travis-ci.org/kainage/selected_links)
2
4
 
3
5
  Adds a link helper to ActionView::Base to that adds a class of _selected_
4
6
  to the link when matched to a pattern, usually a url.
@@ -29,6 +31,14 @@ SelectedLinks.setup do |config|
29
31
  end
30
32
  ```
31
33
 
34
+ You can also change the fallback behaviour to check the name if the matcher fails
35
+
36
+ ```ruby
37
+ SelectedLinks.setup do |config|
38
+ config.fallback_to_name = false
39
+ end
40
+ ```
41
+
32
42
  ### Useage
33
43
 
34
44
  To make this link have a class of _selected_ when the url is at the top level:
@@ -1,41 +1,41 @@
1
1
  require 'action_view'
2
2
 
3
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
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
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
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
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
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
41
  end
@@ -1,55 +1,62 @@
1
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
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
+ # Always return true if the source and the matcher match.
35
+ return true if url_match?(@source, @matcher)
36
+ # If not check for fallback and presence of @matcher and check again if necessary.
37
+ if (@matcher && SelectedLinks.fallback_to_name) || !@matcher
38
+ return url_match?(@source, @name)
39
+ else
40
+ return false
41
+ end
42
+ end
43
+
44
+ def url_match?(source, matcher)
45
+ return false unless matcher # nil.to_s returns ""
46
+ source =~ /#{matcher}/i
47
+ end
48
+
49
+ def cleanup
50
+ remove_matcher
51
+ remove_source
52
+ end
53
+
54
+ def remove_matcher
55
+ @html_options.delete(:matcher)
56
+ end
57
+
58
+ def remove_source
59
+ @html_options.delete(:source)
60
+ end
61
+ end
55
62
  end
@@ -1,9 +1,9 @@
1
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
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
9
  end
@@ -1,3 +1,3 @@
1
1
  module SelectedLinks
2
- VERSION = "0.0.1"
2
+ VERSION = "0.0.2"
3
3
  end
@@ -3,16 +3,19 @@ require 'selected_links/link'
3
3
  require 'selected_links/action_view'
4
4
 
5
5
  if defined? Rails
6
- require 'selected_links/railtie'
6
+ require 'selected_links/railtie'
7
7
  else
8
- ActionView::Base.send(:include, SelectedLinks::ActionView)
8
+ ActionView::Base.send(:include, SelectedLinks::ActionView)
9
9
  end
10
10
 
11
11
  module SelectedLinks
12
- mattr_accessor :default_source
13
- @@default_source = 'request.path'
12
+ mattr_accessor :default_source
13
+ @@default_source = 'request.path'
14
14
 
15
- def self.setup
16
- yield self
17
- end
15
+ mattr_accessor :fallback_to_name
16
+ @@fallback_to_name = false
17
+
18
+ def self.setup
19
+ yield self
20
+ end
18
21
  end
@@ -1,151 +1,164 @@
1
1
  require 'spec_helper'
2
2
 
3
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
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
+
108
+ context "fallback to named path" do
109
+ it "should not fallback by default" do
110
+ @link = SelectedLinks::Link.new('Foo', 'options', :source => '/foo', :matcher => 'bar')
111
+ @link.send(:is_match?).should be_false
112
+ end
113
+
114
+ it "should fallback when setting is on" do
115
+ SelectedLinks.fallback_to_name = true
116
+ @link = SelectedLinks::Link.new('Foo', 'options', :source => '/foo', :matcher => 'bar')
117
+ @link.send(:is_match?).should be_true
118
+ end
119
+ end
120
+ end
121
+
122
+ describe "fully constructed link" do
123
+ context "with a matcher link" do
124
+ it "should have a class of selected added" do
125
+ @link = SelectedLinks::Link.new('Name', 'options', :source => '/foo', :matcher => 'foo').generate
126
+ @link.html_options[:class].should =~ /selected/
127
+ end
128
+
129
+ it "should not have a class of selected if there was not a match" do
130
+ @link = SelectedLinks::Link.new('Name', 'options', :source => '/foo', :matcher => 'bar').generate
131
+ @link.html_options[:class].should_not =~ /selected/
132
+ end
133
+ end
134
+
135
+ context "with a named link" do
136
+ it "should have a class of selected added" do
137
+ @link = SelectedLinks::Link.new('Foo', 'options', :source => '/foo').generate
138
+ @link.html_options[:class].should =~ /selected/
139
+ end
140
+
141
+ it "should not have a class of selected if there was not a match" do
142
+ @link = SelectedLinks::Link.new('Bar', 'options', :source => '/foo').generate
143
+ @link.html_options[:class].should_not =~ /selected/
144
+ end
145
+ end
146
+
147
+ context "with an existing class" do
148
+ it "should have a class of selected added" do
149
+ @link = SelectedLinks::Link.new('Name', 'options', :source => '/foo', :matcher => 'foo', :class => 'nav').generate
150
+ @link.html_options[:class].should =~ /selected/
151
+ end
152
+
153
+ it "should not have a class of selected if there was not a match" do
154
+ @link = SelectedLinks::Link.new('Name', 'options', :source => '/foo', :matcher => 'bar', :class => 'nav').generate
155
+ @link.html_options[:class].should_not =~ /selected/
156
+ end
157
+
158
+ it 'should have a space between the existing classes and the selected class' do
159
+ @link = SelectedLinks::Link.new('Name', 'options', :source => '/foo', :matcher => 'foo', :class => 'nav').generate
160
+ @link.html_options[:class].should == 'nav selected'
161
+ end
162
+ end
163
+ end
151
164
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: selected_links
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Kainage
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2013-05-23 00:00:00.000000000 Z
11
+ date: 2013-08-28 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -75,6 +75,7 @@ extra_rdoc_files: []
75
75
  files:
76
76
  - .gitignore
77
77
  - .rspec
78
+ - .travis.yml
78
79
  - CHANGELOG.md
79
80
  - Gemfile
80
81
  - LICENSE.txt