simple-navigation 3.5.1 → 3.6.0
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.
- 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
|