tabnav 1.1.0 → 1.2.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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