tabnav 1.1.0 → 1.2.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.
@@ -0,0 +1,24 @@
1
+ ## MAC OS
2
+ .DS_Store
3
+
4
+ ## TEXTMATE
5
+ *.tmproj
6
+ tmtags
7
+
8
+ ## EMACS
9
+ *~
10
+ \#*
11
+ .\#*
12
+
13
+ ## VIM
14
+ *.swp
15
+
16
+ ## PROJECT::GENERAL
17
+ coverage
18
+ rdoc
19
+ pkg
20
+ *.gem
21
+ .bundle
22
+ Gemfile.lock
23
+
24
+ ## PROJECT::SPECIFIC
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in tabnav.gemspec
4
+ gemspec
data/LICENSE CHANGED
@@ -2,7 +2,7 @@ LICENSE
2
2
 
3
3
  The MIT License
4
4
 
5
- Copyright (c) 2010 Alex Tomlins and Unboxed Consulting
5
+ Copyright (c) 2012 Alex Tomlins and Unboxed Consulting
6
6
 
7
7
  Permission is hereby granted, free of charge, to any person obtaining
8
8
  a copy of this software and associated documentation files (the
@@ -42,6 +42,53 @@ On any action in FrooblesController will output:
42
42
 
43
43
  See the highlights_on method of Tabnav::Tab for full details of the highlighting logic.
44
44
 
45
+ === Nested navbars
46
+
47
+ In your view:
48
+
49
+ <%
50
+ render_tabnav do |n|
51
+ n.add_tab do |t|
52
+ t.named "Home"
53
+ t.links_to root_path
54
+ t.highlights_on :controller => :home, :action => :index
55
+ end
56
+ n.add_sub_nav do |sn|
57
+ sn.named "Froobles"
58
+ sn.links_to froobles_path
59
+ sn.highlights_on :controller => :froobles
60
+
61
+ sn.add_tab do |t|
62
+ t.named "New Frooble"
63
+ t.links_to new_frooble_path
64
+ t.highlights_on :controller => :froobles, :action => :new
65
+ t.highlights_on :controller => :froobles, :action => :create
66
+ end
67
+
68
+ sn.add_tab do |t|
69
+ t.named "Search Froobles"
70
+ t.links_to search_froobles_path
71
+ t.highlights_on :controler => :froobles, :action => :search
72
+ end
73
+ end
74
+ end
75
+ %>
76
+
77
+ On FrooblesController#new will output:
78
+
79
+ <ul>
80
+ <li><a href="/">Home</a></li>
81
+ <li class="active">
82
+ <a href="/froobles">Froobles</a>
83
+ <ul>
84
+ <li class="active"><a href="/froobles/new">New Frooble</a></li>
85
+ <li><a href="/froobles/search">Search Froobles</a></li>
86
+ </ul>
87
+ </li>
88
+ </ul>
89
+
90
+ Navbars can be nested arbritarily deep.
91
+
45
92
  === Options for controlling markup
46
93
 
47
94
  View:
@@ -57,10 +104,14 @@ View:
57
104
  t.named "Froobles Heading"
58
105
  t.highlights_on :controller => :froobles
59
106
  end
60
- n.add_tab do |t|
61
- t.named "Froobles"
62
- t.links_to froobles_path, :target => "_blank", :rel => "http://foo.bar/"
63
- t.highlights_on :controller => :froobles, :action => :index
107
+ n.add_sub_nav :id => 'froobles' do |sn|
108
+ sn.named "Froobles"
109
+
110
+ sn.add_tab do |t|
111
+ t.named "All Froobles"
112
+ t.links_to froobles_path, :target => "_blank", :rel => "http://foo.bar/"
113
+ t.highlights_on :controller => :froobles, :action => :index
114
+ end
64
115
  end
65
116
  end
66
117
  %>
@@ -70,7 +121,12 @@ On froobles/index will output:
70
121
  <ul id="main_navigation" class="clearfix">
71
122
  <li class="home_tab"><a href="/">Home</a></li>
72
123
  <li class="heading active"><span>Froobles Heading</span></li>
73
- <li class="active"><a href="/froobles" target="_blank" rel="http://foo.bar/">Froobles</a></li>
124
+ <li id="froobles">
125
+ <span>Froobles</span>
126
+ <ul>
127
+ <li class="active"><a href="/froobles" target="_blank" rel="http://foo.bar/">All Froobles</a></li>
128
+ </ul>
129
+ </li>
74
130
  </ul>
75
131
 
76
132
  === Custom tab partial
@@ -137,4 +193,4 @@ The concept for this is based on the tabnav component from rails_widgets: http:/
137
193
 
138
194
  == Copyright
139
195
 
140
- Copyright (c) 2010 Unboxed. See LICENSE for details.
196
+ Copyright (c) 2012 Alex Tomlins and {Unboxed Consulting}[http://www.unboxedconsulting.com/]. See LICENSE for details.
data/Rakefile CHANGED
@@ -1,38 +1,17 @@
1
- require 'rubygems'
2
- require 'rake'
1
+ require 'bundler/gem_tasks'
3
2
 
4
- begin
5
- require 'jeweler'
6
- Jeweler::Tasks.new do |gem|
7
- gem.name = "tabnav"
8
- gem.summary = %Q{Rails helper for generating navbars}
9
- gem.description = %Q{Rails helper for generating navbars in a declarative manner}
10
- gem.email = "github@unboxedconsulting.com"
11
- gem.homepage = "http://github.com/unboxed/tabnav"
12
- gem.authors = ["Unboxed"]
13
- gem.add_dependency "actionpack", ">= 2.3.8"
14
- gem.add_development_dependency "rspec", "~> 2.6.0"
15
- gem.add_development_dependency "rspec-rails", "~> 2.6.1"
16
- gem.files.exclude "*.gemspec", '.gitignore', 'doc/*'
17
- end
18
- Jeweler::GemcutterTasks.new
19
- rescue LoadError
20
- puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler"
21
- end
3
+ $:.push File.expand_path("../lib", __FILE__)
4
+ require "tabnav/version"
22
5
 
23
6
  require 'rspec/core/rake_task'
24
7
  RSpec::Core::RakeTask.new(:spec)
25
8
 
26
- task :spec => :check_dependencies
27
-
28
9
  task :default => :spec
29
10
 
30
- require 'rake/rdoctask'
11
+ require 'rdoc/task'
31
12
  Rake::RDocTask.new do |rdoc|
32
- version = File.exist?('VERSION') ? File.read('VERSION') : ""
33
-
34
13
  rdoc.rdoc_dir = 'rdoc'
35
- rdoc.title = "tabnav #{version}"
14
+ rdoc.title = "tabnav #{Tabnav::VERSION}"
36
15
  rdoc.rdoc_files.include('README*')
37
16
  rdoc.rdoc_files.include('lib/**/*.rb')
38
17
  end
@@ -0,0 +1,53 @@
1
+
2
+ Flat Navbar:
3
+
4
+ <%
5
+ render_tabnav do |n|
6
+ n.add_tab do |t|
7
+ t.named "Home"
8
+ t.links_to root_path
9
+ t.highlights_on :controller => :home, :action => :index
10
+ end
11
+ n.add_tab do |t|
12
+ t.named "Froobles"
13
+ t.links_to froobles_path
14
+ t.highlights_on :controller => :froobles
15
+ end
16
+ end
17
+ %>
18
+
19
+ On home/index outputs:
20
+
21
+ <ul>
22
+ <li class="active"><a href="/">Home</a></li>
23
+ <li><a href="/froobles">Froobles</a></li>
24
+ </ul>
25
+
26
+ More markup options:
27
+
28
+ <%
29
+ render_tabnav :id => "main_navigation", :class => "clearfix" do |n|
30
+ n.add_tab :class => "home_tab" do |t|
31
+ t.named "Home"
32
+ t.links_to root_path
33
+ t.highlights_on :controller => :home, :action => :index
34
+ end
35
+ n.add_tab :class => "heading" do |t|
36
+ t.named "Froobles Heading"
37
+ t.highlights_on :controller => :froobles
38
+ end
39
+ n.add_tab do |t|
40
+ t.named "Froobles"
41
+ t.links_to froobles_path, :target => "_blank", :rel => "http://foo.bar/"
42
+ t.highlights_on :controller => :froobles, :action => :index
43
+ end
44
+ end
45
+ %>
46
+
47
+ On froobles/index outputs:
48
+
49
+ <ul id="main_navigation" class="clearfix">
50
+ <li class="home_tab"><a href="/">Home</a></li>
51
+ <li class="heading active"><span>Froobles Heading</span></li>
52
+ <li class="active"><a href="/froobles" target="_blank" rel="http://foo.bar/">Froobles</a></li>
53
+ </ul>
@@ -0,0 +1,88 @@
1
+ Custom partial for tab contents
2
+
3
+ <%
4
+ render_tabnav :html => {:id => "main_navigation", :class => "clearfix"} do |n|
5
+ n.tab_partial "/shared/my_custom_tab"
6
+ n.add_tab :html => {:class => "home_tab"} do |t|
7
+ t.named "Home"
8
+ t.links_to root_path
9
+ t.highlights_on :controller => :home, :action => :index
10
+ end
11
+ n.add_tab :html => {:class => "heading"} do |t|
12
+ t.named "Froobles Heading"
13
+ t.highlights_on :controller => :froobles
14
+ end
15
+ n.add_tab do |t|
16
+ t.named "Froobles"
17
+ t.links_to froobles_path, :target => "_blank", :rel => "http://foo.bar/"
18
+ t.highlights_on :controller => :froobles, :action => :index
19
+ end
20
+ end
21
+ %>
22
+
23
+ in /app/views/shared/_my_custom_tab.html.erb:
24
+
25
+ <div class="my_custom_class">
26
+ <%- if tab.has_link? -%>
27
+ <%= link_to tab.name, tab.url %>
28
+ <%- else -%>
29
+ <span><%= tab.name %></span>
30
+ <%- end -%>
31
+ </div>
32
+
33
+ On froobles/index outputs:
34
+
35
+ <ul id="main_navigation" class="clearfix">
36
+ <li class="home_tab"><div class="my_custom_class"><a href="/">Home</a></div></li>
37
+ <li class="heading active"><div class="my_custom_class"><span>Froobles Heading</span></div></li>
38
+ <li class="active"><div class="my_custom_class"><a href="/froobles">Froobles</a></div></li>
39
+ </ul>
40
+
41
+
42
+ With nested menus:
43
+
44
+ <%
45
+ render_tabnav do |n|
46
+ n.tab_partial "/shared/my_custom_tab"
47
+ n.add_tab do |t|
48
+ t.named "Home"
49
+ t.links_to root_path
50
+ t.highlights_on :controller => :home, :action => :index
51
+ end
52
+
53
+ n.add_sub_nav do |sn|
54
+ sn.named "Froobles"
55
+
56
+ sn.add_tab do |t|
57
+ t.named "All Froobles"
58
+ t.links_to froobles_path
59
+ t.highlights_on :controller => :froobles, :action => :index
60
+ end
61
+
62
+ sn.add_tab do |t|
63
+ t.named "New Frooble"
64
+ t.links_to new_frooble_path
65
+ t.highlights_on :controller => :froobles, :action => :new
66
+ t.highlights_on :controller => :froobles, :action => :create
67
+ end
68
+ end
69
+
70
+ n.add_tab do |t|
71
+ t.named "Something Else"
72
+ t.links_to "/somewhere"
73
+ end
74
+ end
75
+ %>
76
+
77
+ On the froobles index, outputs:
78
+
79
+ <ul>
80
+ <li><div class="my_custom_class"><a href="/">Home</a></div></li>
81
+ <li><div class="my_custom_class"><span>All Froobles</span></div>
82
+ <ul>
83
+ <li class="active"><a href="/froobles">Froobles</a></li>
84
+ <li><a href="/froobles/new">New Frooble</a></li>
85
+ </ul>
86
+ </li>
87
+ <li><div class="my_custom_class"><a href="/somewhere">Something Else</a></div></li>
88
+ </ul>
@@ -0,0 +1,47 @@
1
+
2
+ Nested Manus:
3
+
4
+ <%
5
+ render_tabnav do |n|
6
+ n.add_tab do |t|
7
+ t.named "Home"
8
+ t.links_to root_path
9
+ t.highlights_on :controller => :home, :action => :index
10
+ end
11
+
12
+ n.add_sub_nav do |sn|
13
+ sn.named "Froobles"
14
+
15
+ sn.add_tab do |t|
16
+ t.named "All Froobles"
17
+ t.links_to froobles_path
18
+ t.highlights_on :controller => :froobles, :action => :index
19
+ end
20
+
21
+ sn.add_tab do |t|
22
+ t.named "New Frooble"
23
+ t.links_to new_frooble_path
24
+ t.highlights_on :controller => :froobles, :action => :new
25
+ t.highlights_on :controller => :froobles, :action => :create
26
+ end
27
+ end
28
+
29
+ n.add_tab do |t|
30
+ t.named "Something Else"
31
+ t.links_to "/somewhere"
32
+ end
33
+ end
34
+ %>
35
+
36
+ On the froobles index, outputs:
37
+
38
+ <ul>
39
+ <li><a href="/">Home</a></li>
40
+ <li><span>All Froobles</span>
41
+ <ul>
42
+ <li class="active"><a href="/froobles">Froobles</a></li>
43
+ <li><a href="/froobles/new">New Frooble</a></li>
44
+ </ul>
45
+ </li>
46
+ <li><a href="/somewhere">Something Else</a></li>
47
+ </ul>
@@ -1,3 +1,4 @@
1
+ require 'tabnav/version'
1
2
 
2
3
  module Tabnav
3
4
  end
@@ -9,9 +9,9 @@ module Tabnav
9
9
  #
10
10
  # Finally, this renders the navbar, and concats the result into the view.
11
11
  def render_tabnav(options = {})
12
- n = Navbar.new(self, params, options)
12
+ n = Navbar.new(self, params, options.merge(:top_level => true))
13
13
  yield(n)
14
- concat( n.render )
14
+ concat( n.render_navbar )
15
15
  nil
16
16
  end
17
17
  end
@@ -1,10 +1,10 @@
1
1
  module Tabnav
2
- class Navbar
3
- def initialize(template, params, options = {}) # :nodoc:
4
- @template = template
5
- @params = params
6
- @html_options = options
2
+ class Navbar < Tab
3
+ def initialize(template, params, html_options = {}) # :nodoc:
4
+ @top_level = html_options.delete(:top_level)
5
+ super
7
6
  @tabs = []
7
+ @tab_content_partial = @partial
8
8
  end
9
9
 
10
10
  # Optionally specifies a partial to be used to render the tab content.
@@ -15,16 +15,22 @@ module Tabnav
15
15
  # +options+ is an optional hash of options which will be used to create the +li+ for the tab.
16
16
  #
17
17
  # yields the created Tab
18
- def add_tab(options = {})
19
- options[:tab_content_partial] = @tab_content_partial if @tab_content_partial
20
- t = Tab.new(@template, @params, options)
21
- yield t
22
- @tabs << t
18
+ def add_tab(options = {}, &block)
19
+ add_item(Tab, options, &block)
20
+ end
21
+
22
+ # Creates a sub Navbar and adds it to the navbar.
23
+ #
24
+ # +options+ is an optional hash of options which will be used to create the +li+ containing the sub navbar.
25
+ #
26
+ # yields the created Navbar
27
+ def add_sub_nav(options = {}, &block)
28
+ add_item(Navbar, options, &block)
23
29
  end
24
30
 
25
- def render # :nodoc:
26
- return '' if @tabs.empty?
27
- @template.content_tag :ul, @html_options do
31
+ def render_navbar # :nodoc:
32
+ return ''.html_safe if @tabs.empty?
33
+ @template.content_tag :ul, @top_level ? @html_options : nil do
28
34
  contents = ''.html_safe
29
35
  @tabs.each do |tab|
30
36
  contents << tab.render
@@ -32,5 +38,18 @@ module Tabnav
32
38
  contents
33
39
  end
34
40
  end
41
+
42
+ private
43
+
44
+ def add_item(klass, options)
45
+ options[:tab_content_partial] = @tab_content_partial if @tab_content_partial
46
+ i = klass.new(@template, @params, options)
47
+ yield i
48
+ @tabs << i
49
+ end
50
+
51
+ def render_tab
52
+ super + render_navbar
53
+ end
35
54
  end
36
55
  end
@@ -2,6 +2,7 @@ module Tabnav
2
2
  class Tab
3
3
 
4
4
  def initialize(template, params, html_options = {}) # :nodoc:
5
+ @partial = html_options.delete(:tab_content_partial)
5
6
  @html_options = html_options
6
7
  @params = params
7
8
  @template = template
@@ -52,23 +53,29 @@ module Tabnav
52
53
  end
53
54
  end
54
55
 
55
- # Returns +true+ of this tab is highlighted.
56
+ # Returns +true+ if this tab is highlighted.
56
57
  def active?
57
58
  @active
58
59
  end
59
60
 
60
61
  def render # :nodoc:
61
- @html_options[:class] = "#{@html_options[:class]} active".strip if self.active?
62
- partial = @html_options.delete(:tab_content_partial)
63
- @template.content_tag(:li, @html_options) do
64
- if partial
65
- @template.render :partial => partial, :locals => {:tab => self}
66
- elsif has_link?
67
- @template.link_to @name, @link_url, @link_options
68
- else
69
- @template.content_tag :span, @name
70
- end
62
+ options = @html_options.dup
63
+ options[:class] = "#{options[:class]} active".strip if self.active?
64
+ @template.content_tag(:li, options) do
65
+ render_tab
66
+ end
67
+ end
68
+
69
+ private
70
+
71
+ def render_tab
72
+ if @partial
73
+ @template.render :partial => @partial, :locals => {:tab => self}
74
+ elsif has_link?
75
+ @template.link_to @name, @link_url, @link_options
76
+ else
77
+ @template.content_tag :span, @name
71
78
  end
72
79
  end
73
80
  end
74
- end
81
+ end
@@ -0,0 +1,3 @@
1
+ module Tabnav
2
+ VERSION = "1.2.0"
3
+ end
@@ -12,21 +12,21 @@ describe Tabnav::Helper, :type => :helper do
12
12
  end
13
13
  it "should create a new navbar with the template and params and yield it to the block" do
14
14
  controller.params["foo"] = "bar"
15
- Tabnav::Navbar.should_receive(:new).with(@template, {"foo" => "bar"}, {}).and_return(@navbar)
15
+ Tabnav::Navbar.should_receive(:new).with(@template, {"foo" => "bar"}, anything()).and_return(@navbar)
16
16
  helper.render_tabnav do |n|
17
17
  n.should == @navbar
18
18
  end
19
19
  end
20
20
 
21
- it "should create a new navbar with any passed options" do
22
- Tabnav::Navbar.should_receive(:new).with(@template, {}, {:class => "my_class", :id => "my_id"}).and_return(@navbar)
21
+ it "should create a new navbar with any passed options setting it to be the top-level navbar" do
22
+ Tabnav::Navbar.should_receive(:new).with(@template, {}, {:class => "my_class", :id => "my_id", :top_level => true}).and_return(@navbar)
23
23
  helper.render_tabnav :class => "my_class", :id => "my_id" do |n|
24
24
  n.should == @navbar
25
25
  end
26
26
  end
27
27
 
28
28
  it "should concat the results of calling render on the navbar" do
29
- @navbar.should_receive(:render).and_return("Some Navbar Markup")
29
+ @navbar.should_receive(:render_navbar).and_return("Some Navbar Markup")
30
30
  helper.render_tabnav {|n| }
31
31
  helper.output_buffer.should == "Some Navbar Markup"
32
32
  end
@@ -176,7 +176,7 @@ describe Tabnav::Helper, :type => :helper do
176
176
  helper.should_receive(:render).twice do |args|
177
177
  args[:partial].should == '/tab_content'
178
178
  args[:locals][:tab].should be_a(Tabnav::Tab)
179
- "Custom markup for #{args[:locals][:tab].name}"
179
+ "Custom markup for #{args[:locals][:tab].name}".html_safe
180
180
  end
181
181
  helper.render_tabnav do |n|
182
182
  n.tab_content_partial = '/tab_content'
@@ -193,5 +193,205 @@ describe Tabnav::Helper, :type => :helper do
193
193
  '<ul><li>Custom markup for Home</li>' +
194
194
  '<li>Custom markup for Froobles</li></ul>'
195
195
  end
196
+
197
+ it "should carry custom partials into subnavbars" do
198
+ helper.should_receive(:render).exactly(3).times do |args|
199
+ args[:locals][:tab].should be_a(Tabnav::Tab)
200
+ "#{args[:partial]} markup for #{args[:locals][:tab].name}".html_safe
201
+ end
202
+ helper.render_tabnav do |n|
203
+ n.tab_content_partial = '/tab_content'
204
+ n.add_tab do |t|
205
+ t.named "Home"
206
+ t.links_to "/"
207
+ end
208
+ n.add_sub_nav do |sn|
209
+ sn.named "Froobles"
210
+ sn.links_to "/froobles"
211
+
212
+ sn.add_tab do |t|
213
+ t.named "New"
214
+ t.links_to "/froobles/new"
215
+ end
216
+ end
217
+ end
218
+ helper.output_buffer.should ==
219
+ '<ul><li>/tab_content markup for Home</li>' +
220
+ '<li>/tab_content markup for Froobles' +
221
+ '<ul><li>/tab_content markup for New</li></ul>' +
222
+ '</li></ul>'
223
+ end
224
+
225
+ it "should allow overriding custom partials in subnavbars" do
226
+ helper.should_receive(:render).exactly(3).times do |args|
227
+ args[:locals][:tab].should be_a(Tabnav::Tab)
228
+ "#{args[:partial]} markup for #{args[:locals][:tab].name}".html_safe
229
+ end
230
+ helper.render_tabnav do |n|
231
+ n.tab_content_partial = '/tab_content'
232
+ n.add_tab do |t|
233
+ t.named "Home"
234
+ t.links_to "/"
235
+ end
236
+ n.add_sub_nav do |sn|
237
+ sn.named "Froobles"
238
+ sn.links_to "/froobles"
239
+ sn.tab_content_partial = '/sub_tab_content'
240
+
241
+ sn.add_tab do |t|
242
+ t.named "New"
243
+ t.links_to "/froobles/new"
244
+ end
245
+ end
246
+ end
247
+ helper.output_buffer.should ==
248
+ '<ul><li>/tab_content markup for Home</li>' +
249
+ '<li>/tab_content markup for Froobles' +
250
+ '<ul><li>/sub_tab_content markup for New</li></ul>' +
251
+ '</li></ul>'
252
+ end
253
+ end
254
+
255
+ describe "nested navbars" do
256
+ it "should allow a nested navbar" do
257
+ helper.render_tabnav do |n|
258
+ n.add_tab do |t|
259
+ t.named "Home"
260
+ t.links_to '/'
261
+ t.highlights_on :controller => :home, :action => :index
262
+ end
263
+
264
+ n.add_sub_nav do |sn|
265
+ sn.named "Froobles"
266
+
267
+ sn.add_tab do |t|
268
+ t.named "All Froobles"
269
+ t.links_to '/froobles'
270
+ t.highlights_on :controller => :froobles, :action => :index
271
+ end
272
+
273
+ sn.add_tab do |t|
274
+ t.named "New Frooble"
275
+ t.links_to '/froobles/new'
276
+ t.highlights_on :controller => :froobles, :action => :new
277
+ t.highlights_on :controller => :froobles, :action => :create
278
+ end
279
+ end
280
+
281
+ n.add_tab do |t|
282
+ t.named "Something Else"
283
+ t.links_to "/somewhere"
284
+ end
285
+ end
286
+ helper.output_buffer.should == '<ul><li><a href="/">Home</a></li><li><span>Froobles</span>' +
287
+ '<ul><li><a href="/froobles">All Froobles</a></li><li><a href="/froobles/new">New Frooble</a></li></ul>' +
288
+ '</li><li><a href="/somewhere">Something Else</a></li></ul>'
289
+ end
290
+
291
+ it "should allow specifying class/id on a nested navbar" do
292
+ helper.render_tabnav do |n|
293
+ n.add_tab do |t|
294
+ t.named "Home"
295
+ t.links_to '/'
296
+ t.highlights_on :controller => :home, :action => :index
297
+ end
298
+
299
+ n.add_sub_nav :id => 'froobles' do |sn|
300
+ sn.named "Froobles"
301
+
302
+ sn.add_tab do |t|
303
+ t.named "All Froobles"
304
+ t.links_to '/froobles'
305
+ t.highlights_on :controller => :froobles, :action => :index
306
+ end
307
+
308
+ sn.add_tab do |t|
309
+ t.named "New Frooble"
310
+ t.links_to '/froobles/new'
311
+ t.highlights_on :controller => :froobles, :action => :new
312
+ t.highlights_on :controller => :froobles, :action => :create
313
+ end
314
+ end
315
+
316
+ n.add_tab do |t|
317
+ t.named "Something Else"
318
+ t.links_to "/somewhere"
319
+ end
320
+ end
321
+ helper.output_buffer.should == '<ul><li><a href="/">Home</a></li><li id="froobles"><span>Froobles</span>' +
322
+ '<ul><li><a href="/froobles">All Froobles</a></li><li><a href="/froobles/new">New Frooble</a></li></ul>' +
323
+ '</li><li><a href="/somewhere">Something Else</a></li></ul>'
324
+ end
325
+
326
+ it "highlighting logic should work on a subnavbar" do
327
+ controller.params['controller'] = 'wibble'
328
+ helper.render_tabnav do |n|
329
+ n.add_tab do |t|
330
+ t.named "Home"
331
+ t.links_to '/'
332
+ t.highlights_on :controller => :home, :action => :index
333
+ end
334
+
335
+ n.add_sub_nav do |sn|
336
+ sn.named "Froobles"
337
+ sn.highlights_on :controller => :wibble
338
+
339
+ sn.add_tab do |t|
340
+ t.named "All Froobles"
341
+ t.links_to '/froobles'
342
+ t.highlights_on :controller => :froobles, :action => :index
343
+ end
344
+
345
+ sn.add_tab do |t|
346
+ t.named "New Frooble"
347
+ t.links_to '/froobles/new'
348
+ t.highlights_on :controller => :froobles, :action => :new
349
+ t.highlights_on :controller => :froobles, :action => :create
350
+ end
351
+ end
352
+ end
353
+ helper.output_buffer.should == '<ul><li><a href="/">Home</a></li><li class="active"><span>Froobles</span>' +
354
+ '<ul><li><a href="/froobles">All Froobles</a></li><li><a href="/froobles/new">New Frooble</a></li></ul>' +
355
+ '</li></ul>'
356
+ end
357
+
358
+ it "should allow deep nesting of navbars" do
359
+ helper.render_tabnav do |n|
360
+ n.add_tab do |t|
361
+ t.named "Home"
362
+ t.links_to '/'
363
+ end
364
+
365
+ n.add_sub_nav do |sn|
366
+ sn.named "Foo"
367
+
368
+ sn.add_tab do |t|
369
+ t.named "All Foos"
370
+ t.links_to '/foos'
371
+ end
372
+
373
+ sn.add_sub_nav do |ssn|
374
+ ssn.named "Bars"
375
+ ssn.links_to '/foos/bars'
376
+
377
+ ssn.add_tab do |t|
378
+ t.named "New Bar"
379
+ t.links_to '/foos/bars/new'
380
+ end
381
+
382
+ ssn.add_tab do |t|
383
+ t.named "Wibble"
384
+ t.highlights_on Proc.new { true }
385
+ end
386
+ end
387
+ end
388
+ end
389
+ helper.output_buffer.should == '<ul><li><a href="/">Home</a></li><li><span>Foo</span>' +
390
+ '<ul><li><a href="/foos">All Foos</a></li><li>' +
391
+ '<a href="/foos/bars">Bars</a>' +
392
+ '<ul><li><a href="/foos/bars/new">New Bar</a></li><li class="active"><span>Wibble</span></li></ul>' +
393
+ '</li></ul>' +
394
+ '</li></ul>'
395
+ end
196
396
  end
197
397
  end
@@ -9,41 +9,121 @@ describe Tabnav::Navbar do
9
9
 
10
10
  it "should create a new tab with the passed template and params and yield it to the block" do
11
11
  n = Tabnav::Navbar.new(@template, {"foo" => "bar"})
12
- t = Tabnav::Tab.new(@template, {})
13
- Tabnav::Tab.should_receive(:new).with(@template, {"foo" => "bar"}, {}).and_return(t)
12
+ tab = Tabnav::Tab.new(@template, {})
13
+ Tabnav::Tab.should_receive(:new).with(@template, {"foo" => "bar"}, {}).and_return(tab)
14
14
  n.add_tab do |t|
15
- t.should == t
15
+ t.should == tab
16
16
  end
17
17
  end
18
18
 
19
19
  it "should create the tab with any passed options" do
20
20
  n = Tabnav::Navbar.new(@template, {})
21
- t = Tabnav::Tab.new(@template, {})
22
- Tabnav::Tab.should_receive(:new).with(@template, {}, {:class => "my_class", :id => "my_id"}).and_return(t)
21
+ tab = Tabnav::Tab.new(@template, {})
22
+ Tabnav::Tab.should_receive(:new).with(@template, {}, {:class => "my_class", :id => "my_id"}).and_return(tab)
23
23
  n.add_tab :class => "my_class", :id => "my_id" do |t|
24
- t.should == t
24
+ t.should == tab
25
25
  end
26
26
  end
27
27
 
28
28
  it "should add the custom partial to the options if set" do
29
29
  n = Tabnav::Navbar.new(@template, {})
30
30
  n.tab_content_partial = 'my_partial'
31
- t = Tabnav::Tab.new(@template, {})
32
- Tabnav::Tab.should_receive(:new).with(@template, {}, {:id => "my_id", :tab_content_partial => 'my_partial'}).and_return(t)
31
+ tab = Tabnav::Tab.new(@template, {})
32
+ Tabnav::Tab.should_receive(:new).with(@template, {}, {:id => "my_id", :tab_content_partial => 'my_partial'}).and_return(tab)
33
33
  n.add_tab :id => "my_id" do |t|
34
- t.should == t
34
+ t.should == tab
35
+ end
36
+ end
37
+
38
+ it "should add the tabnav's partial to the options if one was set" do
39
+ n = Tabnav::Navbar.new(@template, {}, :tab_content_partial => 'my_partial')
40
+ tab = Tabnav::Tab.new(@template, {})
41
+ Tabnav::Tab.should_receive(:new).with(@template, {}, {:id => "my_id", :tab_content_partial => 'my_partial'}).and_return(tab)
42
+ n.add_tab :id => "my_id" do |t|
43
+ t.should == tab
44
+ end
45
+ end
46
+
47
+ it "should use the custom partial in preference to the navbars partial" do
48
+ n = Tabnav::Navbar.new(@template, {}, :tab_content_partial => 'my_other_partial')
49
+ n.tab_content_partial = 'my_partial'
50
+ tab = Tabnav::Tab.new(@template, {})
51
+ Tabnav::Tab.should_receive(:new).with(@template, {}, {:id => "my_id", :tab_content_partial => 'my_partial'}).and_return(tab)
52
+ n.add_tab :id => "my_id" do |t|
53
+ t.should == tab
35
54
  end
36
55
  end
37
56
  end
38
57
 
39
- describe "render" do
58
+ describe "add_sub_nav" do
59
+ before :each do
60
+ @template = ActionView::Base.new()
61
+ end
62
+
63
+ it "should create a new navbar with the passed template and params and yield it to the block" do
64
+ n = Tabnav::Navbar.new(@template, {"foo" => "bar"})
65
+ subnav = Tabnav::Navbar.new(@template, {})
66
+ Tabnav::Navbar.should_receive(:new).with(@template, {"foo" => "bar"}, {}).and_return(subnav)
67
+ n.add_sub_nav do |sn|
68
+ sn.should == subnav
69
+ end
70
+ end
71
+
72
+ it "should create the tab with any passed options" do
73
+ n = Tabnav::Navbar.new(@template, {})
74
+ subnav = Tabnav::Navbar.new(@template, {})
75
+ Tabnav::Navbar.should_receive(:new).with(@template, {}, {:class => "my_class", :id => "my_id"}).and_return(subnav)
76
+ n.add_sub_nav :class => "my_class", :id => "my_id" do |sn|
77
+ sn.should == subnav
78
+ end
79
+ end
80
+
81
+ it "should add the custom partial to the options if set" do
82
+ n = Tabnav::Navbar.new(@template, {})
83
+ n.tab_content_partial = 'my_partial'
84
+ subnav = Tabnav::Navbar.new(@template, {})
85
+ Tabnav::Navbar.should_receive(:new).with(@template, {}, {:id => "my_id", :tab_content_partial => 'my_partial'}).and_return(subnav)
86
+ n.add_sub_nav :id => "my_id" do |sn|
87
+ sn.should == subnav
88
+ end
89
+ end
90
+
91
+ it "should add the tabnav's partial to the options if one was set" do
92
+ n = Tabnav::Navbar.new(@template, {}, :tab_content_partial => 'my_partial')
93
+ subnav = Tabnav::Navbar.new(@template, {})
94
+ Tabnav::Navbar.should_receive(:new).with(@template, {}, {:id => "my_id", :tab_content_partial => 'my_partial'}).and_return(subnav)
95
+ n.add_sub_nav :id => "my_id" do |sn|
96
+ sn.should == subnav
97
+ end
98
+ end
99
+
100
+ it "should use the custom partial in preference to the navbars partial" do
101
+ n = Tabnav::Navbar.new(@template, {}, :tab_content_partial => 'my_other_partial')
102
+ n.tab_content_partial = 'my_partial'
103
+ subnav = Tabnav::Navbar.new(@template, {})
104
+ Tabnav::Navbar.should_receive(:new).with(@template, {}, {:id => "my_id", :tab_content_partial => 'my_partial'}).and_return(subnav)
105
+ n.add_sub_nav :id => "my_id" do |sn|
106
+ sn.should == subnav
107
+ end
108
+ end
109
+ end
110
+
111
+ describe "Tab behaviour" do
112
+ it "should be a subclass of Tab" do
113
+ Tabnav::Navbar.new(nil, nil).should be_a(Tabnav::Tab)
114
+ end
115
+ end
116
+
117
+ describe "render_navbar" do
40
118
  before :each do
41
119
  @template = ActionView::Base.new()
42
120
  end
43
121
 
44
122
  it "should output nothing if no tabs have been added" do
45
123
  n = Tabnav::Navbar.new(@template, {})
46
- n.render.should == ''
124
+ html = n.render_navbar
125
+ html.should == ''
126
+ html.should be_html_safe
47
127
  end
48
128
 
49
129
  it "should output a ul containing the results of rendering each of it's tabs" do
@@ -57,63 +137,42 @@ describe Tabnav::Navbar do
57
137
  end
58
138
  t1.should_receive(:render).and_return("Tab 1 markup")
59
139
  t2.should_receive(:render).and_return("Tab 2 markup")
60
- n.render.should == '<ul>Tab 1 markupTab 2 markup</ul>'
140
+ n.render_navbar.should == '<ul>Tab 1 markupTab 2 markup</ul>'
61
141
  end
62
142
 
63
- it "should pass the options given on creation to the ul" do
64
- n = Tabnav::Navbar.new(@template, {}, :id => "my_id", :class => "my_class")
143
+ it "should pass the options given on creation to the ul when it's the top-level navbar" do
144
+ n = Tabnav::Navbar.new(@template, {}, :id => "my_id", :class => "my_class", :top_level => true)
65
145
  t1 = nil
66
146
  n.add_tab do |t|
67
147
  t1 = t
68
148
  end
69
149
  @template.should_receive(:content_tag).with(:ul, {:id => "my_id", :class => "my_class"}).and_return(:some_markup)
70
- n.render.should == :some_markup
71
- end
72
-
73
- # it "should output a li containing a span with the name if no link given" do
74
- # t = Tabnav::Tab.new(@template)
75
- # t.named "A Tab"
76
- # html = t.render
77
- # html.should == "<li><span>A Tab</span></li>"
78
- # end
79
- #
80
- # it "should output a li containing a link with the name" do
81
- # t = Tabnav::Tab.new(@template)
82
- # t.named "A Tab"
83
- # t.links_to "/wibble"
84
- # html = t.render
85
- # html.should == "<li><a href=\"/wibble\">A Tab</a></li>"
86
- # end
87
- #
88
- # context "with no name given" do
89
- # it "should output a blank tab if no link given" do
90
- # t = Tabnav::Tab.new(@template)
91
- # html = t.render
92
- # html.should == "<li><span></span></li>"
93
- # end
94
- #
95
- # it "should output an empty link" do
96
- # t = Tabnav::Tab.new(@template)
97
- # t.links_to "/wibble"
98
- # html = t.render
99
- # html.should == "<li><a href=\"/wibble\"></a></li>"
100
- # end
101
- # end
102
- #
103
- # it "should pass the options given on creation to the li" do
104
- # @template.should_receive(:content_tag).with(:li, {:id => "my_id", :class => "my_class"}).and_return(:some_markup)
105
- # t = Tabnav::Tab.new(@template, :id => "my_id", :class => "my_class")
106
- # t.named "A Tab"
107
- # t.render.should == :some_markup
108
- # end
109
- #
110
- # it "should pass the options given to the link to link_to" do
111
- # @template.should_receive(:link_to).with("A Tab", "/wibble", {:class => "link_class", :target => "_blank"}).and_return("A Link")
112
- # t = Tabnav::Tab.new(@template)
113
- # t.named "A Tab"
114
- # t.links_to "/wibble", :class => "link_class", :target => "_blank"
115
- # html = t.render
116
- # html.should == "<li>A Link</li>"
117
- # end
150
+ n.render_navbar.should == :some_markup
151
+ end
152
+
153
+ it "should not pass the options to the ul when it's not the top-level navbar" do
154
+ n = Tabnav::Navbar.new(@template, {}, :id => "my_id", :class => "my_class")
155
+ t1 = nil
156
+ n.add_tab do |t|
157
+ t1 = t
158
+ end
159
+ @template.should_receive(:content_tag).with(:ul, nil).and_return(:some_markup)
160
+ n.render_navbar.should == :some_markup
161
+ end
162
+ end
163
+
164
+ describe "render" do
165
+ # This only covers the functionality specific to navbars, the rest is covered in tab_spec
166
+ before :each do
167
+ @template = ActionView::Base.new()
168
+ end
169
+ it "should insert the navbar inside the end of the li" do
170
+ n = Tabnav::Navbar.new(@template, {})
171
+ n.stub!(:render_navbar).and_return("The Navbar")
172
+ n.named "A Tab"
173
+ html = n.render
174
+ html.should == "<li><span>A Tab</span>The Navbar</li>"
175
+ html.should be_html_safe
176
+ end
118
177
  end
119
- end
178
+ end
@@ -43,6 +43,7 @@ describe Tabnav::Tab do
43
43
  t.named "A Tab"
44
44
  html = t.render
45
45
  html.should == "<li><span>A Tab</span></li>"
46
+ html.should be_html_safe
46
47
  end
47
48
 
48
49
  it "should output a li containing a link with the name" do
@@ -51,6 +52,7 @@ describe Tabnav::Tab do
51
52
  t.links_to "/wibble"
52
53
  html = t.render
53
54
  html.should == "<li><a href=\"/wibble\">A Tab</a></li>"
55
+ html.should be_html_safe
54
56
  end
55
57
 
56
58
  context "with no name given" do
@@ -58,6 +60,7 @@ describe Tabnav::Tab do
58
60
  t = Tabnav::Tab.new(@template, {})
59
61
  html = t.render
60
62
  html.should == "<li><span></span></li>"
63
+ html.should be_html_safe
61
64
  end
62
65
 
63
66
  it "should output an empty link" do
@@ -65,6 +68,7 @@ describe Tabnav::Tab do
65
68
  t.links_to "/wibble"
66
69
  html = t.render
67
70
  html.should == "<li><a href=\"/wibble\"></a></li>"
71
+ html.should be_html_safe
68
72
  end
69
73
  end
70
74
 
@@ -82,6 +86,7 @@ describe Tabnav::Tab do
82
86
  t.links_to "/wibble", :class => "link_class", :target => "_blank"
83
87
  html = t.render
84
88
  html.should == "<li>A Link</li>"
89
+ html.should be_html_safe
85
90
  end
86
91
 
87
92
  context "with a custom partial" do
@@ -180,6 +185,15 @@ describe Tabnav::Tab do
180
185
  t.stub!(:active?).and_return(true)
181
186
  t.render.should == '<li class="my_class active"><span>A Tab</span></li>'
182
187
  end
188
+
189
+ it "should not modify the existing html_options on the tab" do
190
+ t = Tabnav::Tab.new(@template, {}, {:class => "my_class"})
191
+ t.named "A Tab"
192
+ t.stub!(:active?).and_return(true)
193
+ t.render
194
+ t.stub!(:active?).and_return(false)
195
+ t.render.should == '<li class="my_class"><span>A Tab</span></li>'
196
+ end
183
197
  end
184
198
  end
185
199
  end
@@ -0,0 +1,24 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "tabnav/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = %q{tabnav}
7
+ s.version = Tabnav::VERSION
8
+
9
+ s.authors = ["Alex Tomlins", "Unboxed Consulting"]
10
+ s.email = %q{github@unboxedconsulting.com}
11
+ s.homepage = %q{http://github.com/unboxed/tabnav}
12
+ s.summary = %q{Rails helper for generating navbars}
13
+ s.description = %q{Rails helper for generating navbars in a declarative manner}
14
+ s.license = 'MIT'
15
+
16
+ s.files = `git ls-files`.split("\n")
17
+ s.test_files = `git ls-files -- spec/*`.split("\n")
18
+ s.extra_rdoc_files = %w(LICENSE README.rdoc)
19
+ s.require_paths = ["lib"]
20
+
21
+ s.add_runtime_dependency(%q<actionpack>, [">= 2.3.8"])
22
+ s.add_development_dependency(%q<rspec>, ["~> 2.9.0"])
23
+ s.add_development_dependency(%q<rspec-rails>, ["~> 2.9.0"])
24
+ end
metadata CHANGED
@@ -1,129 +1,121 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  name: tabnav
3
- version: !ruby/object:Gem::Version
4
- hash: 19
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.2.0
5
5
  prerelease:
6
- segments:
7
- - 1
8
- - 1
9
- - 0
10
- version: 1.1.0
11
6
  platform: ruby
12
- authors:
13
- - Unboxed
7
+ authors:
8
+ - Alex Tomlins
9
+ - Unboxed Consulting
14
10
  autorequire:
15
11
  bindir: bin
16
12
  cert_chain: []
17
-
18
- date: 2011-07-15 00:00:00 +01:00
19
- default_executable:
20
- dependencies:
21
- - !ruby/object:Gem::Dependency
13
+ date: 2012-03-21 00:00:00.000000000 Z
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
22
16
  name: actionpack
23
- prerelease: false
24
- requirement: &id001 !ruby/object:Gem::Requirement
17
+ requirement: !ruby/object:Gem::Requirement
25
18
  none: false
26
- requirements:
27
- - - ">="
28
- - !ruby/object:Gem::Version
29
- hash: 19
30
- segments:
31
- - 2
32
- - 3
33
- - 8
19
+ requirements:
20
+ - - ! '>='
21
+ - !ruby/object:Gem::Version
34
22
  version: 2.3.8
35
23
  type: :runtime
36
- version_requirements: *id001
37
- - !ruby/object:Gem::Dependency
38
- name: rspec
39
24
  prerelease: false
40
- requirement: &id002 !ruby/object:Gem::Requirement
25
+ version_requirements: !ruby/object:Gem::Requirement
26
+ none: false
27
+ requirements:
28
+ - - ! '>='
29
+ - !ruby/object:Gem::Version
30
+ version: 2.3.8
31
+ - !ruby/object:Gem::Dependency
32
+ name: rspec
33
+ requirement: !ruby/object:Gem::Requirement
41
34
  none: false
42
- requirements:
35
+ requirements:
43
36
  - - ~>
44
- - !ruby/object:Gem::Version
45
- hash: 23
46
- segments:
47
- - 2
48
- - 6
49
- - 0
50
- version: 2.6.0
37
+ - !ruby/object:Gem::Version
38
+ version: 2.9.0
51
39
  type: :development
52
- version_requirements: *id002
53
- - !ruby/object:Gem::Dependency
54
- name: rspec-rails
55
40
  prerelease: false
56
- requirement: &id003 !ruby/object:Gem::Requirement
41
+ version_requirements: !ruby/object:Gem::Requirement
42
+ none: false
43
+ requirements:
44
+ - - ~>
45
+ - !ruby/object:Gem::Version
46
+ version: 2.9.0
47
+ - !ruby/object:Gem::Dependency
48
+ name: rspec-rails
49
+ requirement: !ruby/object:Gem::Requirement
57
50
  none: false
58
- requirements:
51
+ requirements:
59
52
  - - ~>
60
- - !ruby/object:Gem::Version
61
- hash: 21
62
- segments:
63
- - 2
64
- - 6
65
- - 1
66
- version: 2.6.1
53
+ - !ruby/object:Gem::Version
54
+ version: 2.9.0
67
55
  type: :development
68
- version_requirements: *id003
56
+ prerelease: false
57
+ version_requirements: !ruby/object:Gem::Requirement
58
+ none: false
59
+ requirements:
60
+ - - ~>
61
+ - !ruby/object:Gem::Version
62
+ version: 2.9.0
69
63
  description: Rails helper for generating navbars in a declarative manner
70
64
  email: github@unboxedconsulting.com
71
65
  executables: []
72
-
73
66
  extensions: []
74
-
75
- extra_rdoc_files:
67
+ extra_rdoc_files:
76
68
  - LICENSE
77
69
  - README.rdoc
78
- files:
79
- - .document
70
+ files:
71
+ - .gitignore
80
72
  - .rspec
73
+ - Gemfile
81
74
  - LICENSE
82
75
  - README.rdoc
83
76
  - Rakefile
84
- - VERSION
77
+ - doc/ideas/basic_flat_navbar.html.erb
78
+ - doc/ideas/custom_tab partial.html.erb
79
+ - doc/ideas/nested_versions.html.erb
85
80
  - lib/tabnav.rb
86
81
  - lib/tabnav/helper.rb
87
82
  - lib/tabnav/navbar.rb
88
83
  - lib/tabnav/tab.rb
84
+ - lib/tabnav/version.rb
89
85
  - spec/spec_helper.rb
90
86
  - spec/tabnav/helper_spec.rb
91
87
  - spec/tabnav/integration_spec.rb
92
88
  - spec/tabnav/navbar_spec.rb
93
89
  - spec/tabnav/tab_spec.rb
94
- has_rdoc: true
90
+ - tabnav.gemspec
95
91
  homepage: http://github.com/unboxed/tabnav
96
- licenses: []
97
-
92
+ licenses:
93
+ - MIT
98
94
  post_install_message:
99
95
  rdoc_options: []
100
-
101
- require_paths:
96
+ require_paths:
102
97
  - lib
103
- required_ruby_version: !ruby/object:Gem::Requirement
98
+ required_ruby_version: !ruby/object:Gem::Requirement
104
99
  none: false
105
- requirements:
106
- - - ">="
107
- - !ruby/object:Gem::Version
108
- hash: 3
109
- segments:
110
- - 0
111
- version: "0"
112
- required_rubygems_version: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ! '>='
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ required_rubygems_version: !ruby/object:Gem::Requirement
113
105
  none: false
114
- requirements:
115
- - - ">="
116
- - !ruby/object:Gem::Version
117
- hash: 3
118
- segments:
119
- - 0
120
- version: "0"
106
+ requirements:
107
+ - - ! '>='
108
+ - !ruby/object:Gem::Version
109
+ version: '0'
121
110
  requirements: []
122
-
123
111
  rubyforge_project:
124
- rubygems_version: 1.4.2
112
+ rubygems_version: 1.8.19
125
113
  signing_key:
126
114
  specification_version: 3
127
115
  summary: Rails helper for generating navbars
128
- test_files: []
129
-
116
+ test_files:
117
+ - spec/spec_helper.rb
118
+ - spec/tabnav/helper_spec.rb
119
+ - spec/tabnav/integration_spec.rb
120
+ - spec/tabnav/navbar_spec.rb
121
+ - spec/tabnav/tab_spec.rb
data/.document DELETED
@@ -1,5 +0,0 @@
1
- README.rdoc
2
- lib/**/*.rb
3
- bin/*
4
- features/**/*.feature
5
- LICENSE
data/VERSION DELETED
@@ -1 +0,0 @@
1
- 1.1.0