simple-navigation 3.5.1 → 3.6.0

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGELOG CHANGED
@@ -1,3 +1,7 @@
1
+ *3.6.0
2
+
3
+ * Added linkless items functionality - the `url` parameter is now optional, items which aren't links will be rendered within a 'span' element rather than an 'a' element. `options` remain optional (defaults to an empty Hash). `options` may be provided without providing a `url` (detected by checking if the '`url`' parameter is a Hash or otherwise).
4
+
1
5
  *3.5.1
2
6
 
3
7
  * Fixed specs related to testing name_generator functionality - stub the name_generator method rather than calling it to ensure subsequent tests aren't affected.
data/VERSION CHANGED
@@ -1 +1 @@
1
- 3.5.1
1
+ 3.6.0
@@ -8,16 +8,14 @@ module SimpleNavigation
8
8
  # see ItemContainer#item
9
9
  #
10
10
  # The subnavigation (if any) is either provided by a block or passed in directly as <tt>items</tt>
11
- def initialize(container, key, name, url, options, items=nil, &sub_nav_block)
11
+ def initialize(container, key, name, url_or_options = {}, options_or_nil={}, items=nil, &sub_nav_block)
12
12
  @container = container
13
+ options = setup_url_and_options(url_or_options, options_or_nil)
13
14
  @container.dom_class = options.delete(:container_class) if options[:container_class]
14
15
  @container.dom_id = options.delete(:container_id) if options[:container_id]
15
16
  @key = key
16
17
  @method = options.delete(:method)
17
18
  @name = name
18
- @url = url.instance_of?(Proc) ? url.call : url
19
- @highlights_on = options.delete(:highlights_on)
20
- @html_options = options
21
19
  if sub_nav_block || items
22
20
  @sub_navigation = ItemContainer.new(@container.level + 1)
23
21
  sub_nav_block.call @sub_navigation if sub_nav_block
@@ -95,7 +93,7 @@ module SimpleNavigation
95
93
  raise ArgumentError, ':highlights_on must be a Regexp, Proc or :subpath'
96
94
  end
97
95
  elsif auto_highlight?
98
- !!(root_path_match? || SimpleNavigation.current_page?(url_without_anchor))
96
+ !!(root_path_match? || (url_without_anchor && SimpleNavigation.current_page?(url_without_anchor)))
99
97
  else
100
98
  false
101
99
  end
@@ -122,8 +120,24 @@ module SimpleNavigation
122
120
  end
123
121
 
124
122
  def url_without_anchor
125
- url.split('#').first
123
+ url && url.split('#').first
126
124
  end
127
125
 
126
+ private
127
+ def setup_url_and_options(url_or_options, options_or_nil)
128
+ options = options_or_nil
129
+ url = url_or_options
130
+ case url_or_options
131
+ when Hash
132
+ # url_or_options is options (there is no url)
133
+ options = url_or_options
134
+ when Proc
135
+ @url = url.call
136
+ else
137
+ @url = url
138
+ end
139
+ @highlights_on = options.delete(:highlights_on)
140
+ @html_options = options
141
+ end
128
142
  end
129
143
  end
@@ -19,7 +19,7 @@ module SimpleNavigation
19
19
  #
20
20
  # The <tt>name</tt> will be displayed in the rendered navigation. This can also be a call to your I18n-framework.
21
21
  #
22
- # The <tt>url</tt> is the address that the generated item points to. You can also use url_helpers (named routes, restful routes helper, url_for etc.)
22
+ # The <tt>url</tt> is the address that the generated item points to. You can also use url_helpers (named routes, restful routes helper, url_for etc.) <tt>url</tt> is optional - items without URLs should not be rendered as links.
23
23
  #
24
24
  # The <tt>options</tt> can be used to specify the following things:
25
25
  # * <tt>any html_attributes</tt> - will be included in the rendered navigation item (e.g. id, class etc.)
@@ -34,8 +34,9 @@ module SimpleNavigation
34
34
  # when the item should be highlighted, you can set a regexp which is matched againstthe current URI.
35
35
  #
36
36
  # The <tt>block</tt> - if specified - will hold the item's sub_navigation.
37
- def item(key, name, url, options={}, &block)
38
- (@items << SimpleNavigation::Item.new(self, key, name, url, options, nil, &block)) if should_add_item?(options)
37
+ def item(key, name, url_or_options = {}, options_or_nil = {}, &block)
38
+ options = url_or_options.is_a?(Hash) ? url_or_options : options_or_nil
39
+ (@items << SimpleNavigation::Item.new(self, key, name, url_or_options, options_or_nil, nil, &block)) if should_add_item?(options)
39
40
  end
40
41
 
41
42
  def items=(items)
@@ -143,4 +144,4 @@ module SimpleNavigation
143
144
 
144
145
  end
145
146
 
146
- end
147
+ end
@@ -19,7 +19,7 @@ module SimpleNavigation
19
19
  def a_tags(item_container)
20
20
  item_container.items.inject([]) do |list, item|
21
21
  if item.selected?
22
- list << link_to(item.name, item.url, {:method => item.method}.merge(item.html_options.except(:class,:id))) if item.selected?
22
+ list << tag_for(item) if item.selected?
23
23
  if include_sub_navigation?(item)
24
24
  list.concat a_tags(item.sub_navigation)
25
25
  end
@@ -31,6 +31,14 @@ module SimpleNavigation
31
31
  def join_with
32
32
  @join_with ||= options[:join_with] || " "
33
33
  end
34
+
35
+ def tag_for(item)
36
+ if item.url.nil?
37
+ content_tag('span', item.name, item.html_options.except(:class,:id))
38
+ else
39
+ link_to(item.name, item.url, {:method => item.method}.merge(item.html_options.except(:class,:id)))
40
+ end
41
+ end
34
42
  end
35
43
 
36
44
  end
@@ -14,12 +14,19 @@ module SimpleNavigation
14
14
 
15
15
  def render(item_container)
16
16
  div_content = item_container.items.inject([]) do |list, item|
17
- list << link_to(item.name, item.url, {:method => item.method}.merge(item.html_options))
17
+ list << tag_for(item)
18
18
  end.join
19
19
  content_tag(:div, div_content, {:id => item_container.dom_id, :class => item_container.dom_class})
20
20
  end
21
21
 
22
+ def tag_for(item)
23
+ if item.url.nil?
24
+ content_tag('span', item.name, item.html_options)
25
+ else
26
+ link_to(item.name, item.url, {:method => item.method}.merge(item.html_options))
27
+ end
28
+ end
22
29
  end
23
30
 
24
31
  end
25
- end
32
+ end
@@ -13,7 +13,7 @@ module SimpleNavigation
13
13
  def render(item_container)
14
14
  list_content = item_container.items.inject([]) do |list, item|
15
15
  li_options = item.html_options.reject {|k, v| k == :link}
16
- li_content = link_to(item.name, item.url, link_options_for(item))
16
+ li_content = tag_for(item)
17
17
  if include_sub_navigation?(item)
18
18
  li_content << render_sub_navigation_for(item)
19
19
  end
@@ -27,7 +27,15 @@ module SimpleNavigation
27
27
  end
28
28
 
29
29
  protected
30
-
30
+
31
+ def tag_for(item)
32
+ if item.url.nil?
33
+ content_tag('span', item.name, link_options_for(item).except(:method))
34
+ else
35
+ link_to(item.name, item.url, link_options_for(item))
36
+ end
37
+ end
38
+
31
39
  # Extracts the options relevant for the generated link
32
40
  #
33
41
  def link_options_for(item)
@@ -220,6 +220,61 @@ describe SimpleNavigation::ItemContainer do
220
220
 
221
221
  end
222
222
 
223
+ context 'optional url and optional options' do
224
+ context 'item specifed without url or options' do
225
+ it 'should add the create item to the list of items' do
226
+ @item_container.items.should_receive(:<<)
227
+ @item_container.item('key', 'name')
228
+ end
229
+ end
230
+ context 'item specified with only a url' do
231
+ it 'should add the item to the list' do
232
+ @item_container.items.should_receive(:<<)
233
+ @item_container.item('key', 'name', 'url')
234
+ end
235
+ end
236
+ context 'item specified with only options' do
237
+ context 'containing no conditions' do
238
+ it 'should add the created item to the list of items' do
239
+ @item_container.items.should_receive(:<<)
240
+ @item_container.item('key', 'name', {:option => true})
241
+ end
242
+ end
243
+ context 'containing negative condition' do
244
+ it 'should not add the created item to the list of items' do
245
+ @item_container.items.should_not_receive(:<<)
246
+ @item_container.item('key', 'name', {:if => lambda{false}, :option => true})
247
+ end
248
+ end
249
+ context 'containing positive condition' do
250
+ it 'should add the created item to the list of items' do
251
+ @item_container.items.should_receive(:<<)
252
+ @item_container.item('key', 'name', {:if => lambda{true}, :option => true})
253
+ end
254
+ end
255
+ end
256
+ context 'item specified with a url and options' do
257
+ context 'containing no conditions' do
258
+ it 'should add the created item to the list of items' do
259
+ @item_container.items.should_receive(:<<)
260
+ @item_container.item('key', 'name', 'url', {:option => true})
261
+ end
262
+ end
263
+ context 'containing negative condition' do
264
+ it 'should not add the created item to the list of items' do
265
+ @item_container.items.should_not_receive(:<<)
266
+ @item_container.item('key', 'name', 'url', {:if => lambda{false}, :option => true})
267
+ end
268
+ end
269
+ context 'containing positive condition' do
270
+ it 'should add the created item to the list of items' do
271
+ @item_container.items.should_receive(:<<)
272
+ @item_container.item('key', 'name', 'url', {:if => lambda{true}, :option => true})
273
+ end
274
+ end
275
+ end
276
+ end
277
+
223
278
  context 'conditions given for item' do
224
279
 
225
280
  context '"if" given' do
@@ -114,8 +114,50 @@ describe SimpleNavigation::Item do
114
114
  end
115
115
  it {@item.url.should == 'my_url'}
116
116
  end
117
+ context 'url is nil' do
118
+ before(:each) do
119
+ @item = SimpleNavigation::Item.new(@item_container, :my_key, 'name', nil, {})
120
+ end
121
+ it {@item.url.should == nil}
122
+ end
123
+ context 'url is unspecified' do
124
+ before(:each) do
125
+ @item = SimpleNavigation::Item.new(@item_container, :my_key, 'name')
126
+ end
127
+ it {@item.url.should == nil}
128
+ end
117
129
  end
118
130
 
131
+ context 'optional url and optional options' do
132
+ context 'when constructed without any optional parameters' do
133
+ before(:each) do
134
+ @item = SimpleNavigation::Item.new(@item_container, :my_key, 'name')
135
+ end
136
+ it {@item.url.should == nil}
137
+ it {@item.instance_variable_get(:@html_options).should == {}}
138
+ end
139
+ context 'when constructed with only a url' do
140
+ before(:each) do
141
+ @item = SimpleNavigation::Item.new(@item_container, :my_key, 'name', 'url')
142
+ end
143
+ it {@item.url.should == 'url'}
144
+ it {@item.instance_variable_get(:@html_options).should == {}}
145
+ end
146
+ context 'when constructed with only options' do
147
+ before(:each) do
148
+ @item = SimpleNavigation::Item.new(@item_container, :my_key, 'name', {:option => true})
149
+ end
150
+ it {@item.url.should == nil}
151
+ it {@item.instance_variable_get(:@html_options).should == {:option => true}}
152
+ end
153
+ context 'when constructed with a url and options' do
154
+ before(:each) do
155
+ @item = SimpleNavigation::Item.new(@item_container, :my_key, 'name', 'url', {:option => true})
156
+ end
157
+ it {@item.url.should == 'url'}
158
+ it {@item.instance_variable_get(:@html_options).should == {:option => true}}
159
+ end
160
+ end
119
161
  end
120
162
 
121
163
  describe 'name' do
@@ -399,6 +441,11 @@ describe SimpleNavigation::Item do
399
441
  @adapter.should_receive(:current_page?).with('url')
400
442
  @item.send(:selected_by_condition?)
401
443
  end
444
+ it "should not be queried when url is nil" do
445
+ @item.stub!(:url => nil)
446
+ @adapter.should_not_receive(:current_page?)
447
+ @item.send(:selected_by_condition?)
448
+ end
402
449
  it {@item.send(:selected_by_condition?).should be_true}
403
450
  end
404
451
  context 'no match' do
@@ -438,6 +485,11 @@ describe SimpleNavigation::Item do
438
485
  @item.stub!(:url => '/bli')
439
486
  @item.send(:root_path_match?).should be_false
440
487
  end
488
+ it "should not match if url is nil" do
489
+ @adapter.stub(:request_path => 'bla')
490
+ @item.stub!(:url => nil)
491
+ @item.send(:root_path_match?).should be_false
492
+ end
441
493
  end
442
494
 
443
495
  describe 'auto_highlight?' do
@@ -55,4 +55,4 @@ describe SimpleNavigation::Renderer::Links do
55
55
  end
56
56
 
57
57
  end
58
- end
58
+ end
@@ -24,11 +24,14 @@ describe SimpleNavigation::Renderer::List do
24
24
  HTML::Selector.new('ul.nav_dom_class').select(render).should have(1).entries
25
25
  end
26
26
  it "should render a li tag for each item" do
27
- HTML::Selector.new('li').select(render).should have(3).entries
27
+ HTML::Selector.new('li').select(render).should have(4).entries
28
28
  end
29
- it "should render an a-tag inside each li-tag" do
29
+ it "should render an a-tag inside each li-tag (for items with links)" do
30
30
  HTML::Selector.new('li a').select(render).should have(3).entries
31
31
  end
32
+ it "should render a span-tag inside each li-tag (for items without links)" do
33
+ HTML::Selector.new('li span').select(render).should have(1).entries
34
+ end
32
35
 
33
36
  context 'concerning item names' do
34
37
  context 'with a custom name generator defined' do
@@ -34,16 +34,17 @@ end
34
34
  # spec helper methods
35
35
  def sub_items
36
36
  [
37
- [:subnav1, 'subnav1', 'subnav1_url', {}],
38
- [:subnav2, 'subnav2', 'subnav2_url', {}]
37
+ [:subnav1, 'subnav1', 'subnav1_url'],
38
+ [:subnav2, 'subnav2', 'subnav2_url']
39
39
  ]
40
40
  end
41
41
 
42
42
  def primary_items
43
43
  [
44
44
  [:users, 'users', 'first_url', {:id => 'my_id'}],
45
- [:invoices, 'invoices', 'second_url', {}],
46
- [:accounts, 'accounts', 'third_url', {:style => 'float:right', :link => {:style => 'float:left'}}]
45
+ [:invoices, 'invoices', 'second_url'],
46
+ [:accounts, 'accounts', 'third_url', {:style => 'float:right', :link => {:style => 'float:left'}}],
47
+ [:miscellany, 'miscellany']
47
48
  ]
48
49
  end
49
50
 
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: simple-navigation
3
3
  version: !ruby/object:Gem::Version
4
- hash: 17
4
+ hash: 31
5
5
  prerelease: false
6
6
  segments:
7
7
  - 3
8
- - 5
9
- - 1
10
- version: 3.5.1
8
+ - 6
9
+ - 0
10
+ version: 3.6.0
11
11
  platform: ruby
12
12
  authors:
13
13
  - Andi Schacke
@@ -16,7 +16,7 @@ autorequire:
16
16
  bindir: bin
17
17
  cert_chain: []
18
18
 
19
- date: 2011-11-19 00:00:00 +00:00
19
+ date: 2011-12-03 00:00:00 +00:00
20
20
  default_executable:
21
21
  dependencies:
22
22
  - !ruby/object:Gem::Dependency