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 +4 -0
- data/VERSION +1 -1
- data/lib/simple_navigation/core/item.rb +20 -6
- data/lib/simple_navigation/core/item_container.rb +5 -4
- data/lib/simple_navigation/rendering/renderer/breadcrumbs.rb +9 -1
- data/lib/simple_navigation/rendering/renderer/links.rb +9 -2
- data/lib/simple_navigation/rendering/renderer/list.rb +10 -2
- data/spec/lib/simple_navigation/core/item_container_spec.rb +55 -0
- data/spec/lib/simple_navigation/core/item_spec.rb +52 -0
- data/spec/lib/simple_navigation/rendering/renderer/links_spec.rb +1 -1
- data/spec/lib/simple_navigation/rendering/renderer/list_spec.rb +5 -2
- data/spec/spec_helper.rb +5 -4
- metadata +5 -5
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.
|
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,
|
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,
|
38
|
-
|
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 <<
|
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 <<
|
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 =
|
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
|
@@ -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(
|
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
|
data/spec/spec_helper.rb
CHANGED
@@ -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:
|
4
|
+
hash: 31
|
5
5
|
prerelease: false
|
6
6
|
segments:
|
7
7
|
- 3
|
8
|
-
-
|
9
|
-
-
|
10
|
-
version: 3.
|
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-
|
19
|
+
date: 2011-12-03 00:00:00 +00:00
|
20
20
|
default_executable:
|
21
21
|
dependencies:
|
22
22
|
- !ruby/object:Gem::Dependency
|