simple_navigation_bootstrap 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,15 @@
1
+ module SimpleNavigationBootstrap
2
+ # Returns the version of the currently loaded Rails as a <tt>Gem::Version</tt>
3
+ def self.gem_version
4
+ Gem::Version.new VERSION::STRING
5
+ end
6
+
7
+ module VERSION
8
+ MAJOR = 1
9
+ MINOR = 0
10
+ TINY = 0
11
+ PRE = nil
12
+
13
+ STRING = [MAJOR, MINOR, TINY, PRE].compact.join('.')
14
+ end
15
+ end
@@ -0,0 +1,29 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path('../lib', __FILE__)
3
+ require 'simple_navigation_bootstrap/version'
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = 'simple_navigation_bootstrap'
7
+ s.version = SimpleNavigationBootstrap::VERSION::STRING
8
+ s.platform = Gem::Platform::RUBY
9
+ s.authors = ['Pavel Shpak', 'Nicolas Rodriguez']
10
+ s.email = ['shpakvel@gmail.com', 'nrodriguez@jbox-web.com']
11
+ s.homepage = 'https://github.com/jbox-web/simple_navigation_bootstrap'
12
+ s.summary = %q{A Ruby gem that adds Bootstrap renderers for SimpleNavigation}
13
+ s.description = %q{This gem adds Bootstrap2 and Bootstrap3 renderers for SimpleNavigation}
14
+ s.license = 'MIT'
15
+
16
+ s.add_runtime_dependency 'simple-navigation', '~> 4.0'
17
+
18
+ s.add_development_dependency 'actionpack'
19
+ s.add_development_dependency 'actionview'
20
+ s.add_development_dependency 'rspec'
21
+ s.add_development_dependency 'simplecov'
22
+ s.add_development_dependency 'bundler', '~> 1.3'
23
+ s.add_development_dependency 'rake'
24
+
25
+ s.files = `git ls-files`.split("\n")
26
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
27
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
28
+ s.require_paths = ['lib']
29
+ end
@@ -0,0 +1,53 @@
1
+ require 'spec_helper'
2
+
3
+ describe SimpleNavigationBootstrap::Bootstrap2 do
4
+
5
+ describe '#render' do
6
+
7
+ it "wraps main menu in ul-tag with 'nav' class" do
8
+ check_selector build_menu(version: 2), 'ul.nav.navbar-nav', 0
9
+ check_selector build_menu(version: 2), 'ul.nav'
10
+ end
11
+
12
+
13
+ context "when ':header' option provided" do
14
+ context "for the first level item" do
15
+ it "does not set up 'dropdown-header' or 'nav-header' class on li-tag" do
16
+ check_selector build_menu(version: 2), 'ul.nav > li.to_check_header.nav-header', 0
17
+ end
18
+
19
+ it "creates link-tag for the item (standard item)" do
20
+ check_selector build_menu(version: 2), 'ul.nav > li.to_check_header > a'
21
+ end
22
+ end
23
+
24
+ context "for the second level item and deeper" do
25
+ it "sets up 'nav-header' class on li-tag" do
26
+ check_selector build_menu(version: 2), 'ul.dropdown-menu > li.to_check_header2.nav-header'
27
+ end
28
+
29
+ it "does not create link-tag for the item (standard item), but puts only item 'name'" do
30
+ check_selector build_menu(version: 2), 'ul.dropdown-menu > li.to_check_header2.nav-header > a', 0
31
+ check_title build_menu(version: 2), 'ul.dropdown-menu > li.to_check_header2.nav-header', 'Misc. Pages'
32
+ end
33
+ end
34
+ end
35
+
36
+
37
+ context "when ':navbar_text' option provided" do
38
+ it "creates p-tag with class 'navbar-text' and item 'name' as a content instead of link-tag for the item (standard item)" do
39
+ check_selector build_menu(version: 2), 'ul > li.to_check_navbar_text > a', 0
40
+ check_title build_menu(version: 2), 'ul > li.to_check_navbar_text > p.navbar-text', 'Signed in as Pavel Shpak'
41
+ end
42
+ end
43
+
44
+
45
+ context "when container is empty" do
46
+ it 'return empty list' do
47
+ check_selector build_menu(version: 2, menu_name: :empty_menu, menu_opts: { skip_if_empty: true }), 'ul > li', 0
48
+ end
49
+ end
50
+
51
+ end
52
+
53
+ end
@@ -0,0 +1,209 @@
1
+ require 'spec_helper'
2
+
3
+ describe SimpleNavigationBootstrap::Bootstrap3 do
4
+
5
+ describe '#render' do
6
+
7
+ it "wraps main menu in ul-tag with 'nav navbar-nav' classes" do
8
+ check_selector build_menu(version: 3), 'ul.nav.navbar-nav'
9
+ end
10
+
11
+
12
+ it "sets up 'active' class on selected items (on li-tags)" do
13
+ check_selector build_menu(version: 3), 'ul.nav.navbar-nav > li.active > a[href="news_index_path"]'
14
+ end
15
+
16
+
17
+ it "wraps submenu in ul-tag 'dropdown-menu' class" do
18
+ check_selector build_menu(version: 3), 'ul > li > ul.dropdown-menu > li > ul.dropdown-menu'
19
+ end
20
+
21
+
22
+ context "for the first level submenu (the second level menu)" do
23
+ it "sets up 'dropdown' class on li-tag which contains that submenu" do
24
+ check_selector build_menu(version: 3), 'ul > li.dropdown'
25
+ end
26
+
27
+ it "sets up 'dropdown-toggle' class on link-tag which is used for toggle that submenu" do
28
+ check_selector build_menu(version: 3), 'ul > li.dropdown > a.dropdown-toggle'
29
+ end
30
+
31
+ it "sets up 'data-toggle' attribute to 'dropdown' on link-tag which is used for toggle that submenu" do
32
+ check_selector build_menu(version: 3), 'ul > li.dropdown > a[data-toggle=dropdown]'
33
+ end
34
+
35
+ it "sets up 'data-target' attribute to '#' on link-tag which is used for toggle that submenu" do
36
+ check_selector build_menu(version: 3), 'ul > li.dropdown > a[data-target="#"]'
37
+ end
38
+
39
+ it "sets up 'href' attribute to '#' on link-tag which is used for toggle that submenu" do
40
+ check_selector build_menu(version: 3), 'ul > li.dropdown > a[href="#"]'
41
+ end
42
+
43
+ it "puts b-tag with 'caret' class in li-tag which contains that submenu" do
44
+ check_selector build_menu(version: 3), 'ul > li.dropdown > a[href="#"] > b.caret'
45
+ end
46
+ end
47
+
48
+
49
+ context "for nested submenu (the third level menu and deeper)" do
50
+ it "sets up 'dropdown-submenu' class on li-tag which contains that submenu" do
51
+ check_selector build_menu(version: 3), 'ul > li > ul.dropdown-menu > li.dropdown-submenu'
52
+ end
53
+ end
54
+
55
+
56
+ context "when ':split' option provided" do
57
+ context "for the first level item which contains submenu" do
58
+ it "splits item on two li-tags (left and right) and right li-tag will contain the first level submenu (second level menu)" do
59
+ check_selector build_menu(version: 3), 'ul > li.dropdown-split-left + li.dropdown.dropdown-split-right > ul.dropdown-menu'
60
+ end
61
+
62
+ it "sets up 'pull-right' class on ul-tag which is the submenu" do
63
+ check_selector build_menu(version: 3), 'ul > li > ul.dropdown-menu.pull-right'
64
+ end
65
+ end
66
+
67
+ context "for the second level item and deeper which contains submenu" do
68
+ it "does not splits item on two li-tags" do
69
+ check_selector build_menu(version: 3), 'ul.dropdown-menu > li.dropdown-split-left + li.dropdown.dropdown-split-right > ul.dropdown-menu', 0
70
+ check_selector build_menu(version: 3), 'ul.dropdown-menu > li.dropdown-submenu > ul.dropdown-menu'
71
+ end
72
+
73
+ it "does not sets up 'pull-right' class on ul-tag which is the submenu" do
74
+ check_selector build_menu(version: 3), 'ul.dropdown-menu > li > ul.dropdown-menu.pull-right', 0
75
+ end
76
+ end
77
+
78
+ context "for item which does not contain submenu" do
79
+ it "does not splits item on two li-tags" do
80
+ check_selector build_menu(version: 3), 'ul > li.to_check_split.dropdown-split-left + li.dropdown.dropdown-split-right', 0
81
+ check_selector build_menu(version: 3), 'ul > li.to_check_split'
82
+ end
83
+ end
84
+ end
85
+
86
+
87
+ context "when ':split' option is not provided" do
88
+ context "for the first level item which contains submenu" do
89
+ it "does not splits item on two li-tags (left and right) and right li-tag will contain the first level submenu (second level menu)" do
90
+ check_selector build_menu(version: 3, menu_name: :unsplited_menu), 'ul > li.dropdown-split-left + li.dropdown.dropdown-split-right > ul.dropdown-menu', 0
91
+ end
92
+
93
+ it "does not sets up 'pull-right' class on ul-tag which is the submenu" do
94
+ check_selector build_menu(version: 3, menu_name: :unsplited_menu), 'ul > li > ul.dropdown-menu.pull-right', 0
95
+ end
96
+ end
97
+
98
+ context "for the second level item and deeper which contains submenu" do
99
+ it "does not splits item on two li-tags" do
100
+ check_selector build_menu(version: 3, menu_name: :unsplited_menu), 'ul.dropdown-menu > li.dropdown-split-left + li.dropdown.dropdown-split-right > ul.dropdown-menu', 0
101
+ check_selector build_menu(version: 3, menu_name: :unsplited_menu), 'ul.dropdown-menu > li.dropdown-submenu > ul.dropdown-menu'
102
+ end
103
+
104
+ it "does not sets up 'pull-right' class on ul-tag which is the submenu" do
105
+ check_selector build_menu(version: 3, menu_name: :unsplited_menu), 'ul.dropdown-menu > li > ul.dropdown-menu.pull-right', 0
106
+ end
107
+ end
108
+
109
+ context "for item which does not contain submenu" do
110
+ it "does not splits item on two li-tags" do
111
+ check_selector build_menu(version: 3, menu_name: :unsplited_menu), 'ul > li.to_check_split.dropdown-split-left + li.dropdown.dropdown-split-right', 0
112
+ check_selector build_menu(version: 3, menu_name: :unsplited_menu), 'ul > li.to_check_split'
113
+ end
114
+ end
115
+ end
116
+
117
+
118
+ context "when ':navbar_text' option provided" do
119
+ it "creates p-tag with class 'navbar-text' and item 'name' as a content instead of link-tag for the item (standard item)" do
120
+ check_selector build_menu(version: 3), 'ul > li.to_check_navbar_text > a', 0
121
+ check_title build_menu(version: 3), 'ul > li.to_check_navbar_text > p.navbar-text', 'Signed in as Pavel Shpak'
122
+ end
123
+ end
124
+
125
+
126
+ context "when ':divider' option provided" do
127
+ it "does not create link-tag for the item (standard item)" do
128
+ check_selector build_menu(version: 3), 'ul > li.divider-vertical + li > a[href="divider_before_info_index_path"]', 0
129
+ check_selector build_menu(version: 3), 'ul.dropdown-menu > li.divider + li > a[href="divider_before_misc_info_pages"]', 0
130
+ check_selector build_menu(version: 3), 'ul.dropdown-menu > li.divider + li > a[href="divider_before_contact_info_page"]', 0
131
+ end
132
+
133
+ context "for the first level item" do
134
+ it "adds li-tag with class 'divider-vertical'" do
135
+ check_selector build_menu(version: 3), 'ul > li.divider-vertical + li > a[href="info_index_path"]'
136
+ end
137
+ end
138
+
139
+ context "for the second level item and deeper" do
140
+ it "adds li-tag with class 'divider'" do
141
+ check_selector build_menu(version: 3), 'ul.dropdown-menu > li.divider + li > a[href="misc_info_pages"]'
142
+ check_selector build_menu(version: 3), 'ul.dropdown-menu > li.divider + li > a[href="contact_info_page"]'
143
+ end
144
+ end
145
+ end
146
+
147
+
148
+ context "when ':header' option provided" do
149
+ context "for the first level item" do
150
+ it "does not set up 'dropdown-header' or 'nav-header' class on li-tag" do
151
+ check_selector build_menu(version: 3), 'ul.nav.navbar-nav > li.to_check_header.dropdown-header', 0
152
+ end
153
+
154
+ it "creates link-tag for the item (standard item)" do
155
+ check_selector build_menu(version: 3), 'ul.nav.navbar-nav > li.to_check_header > a'
156
+ end
157
+ end
158
+
159
+ context "for the second level item and deeper" do
160
+ it "sets up 'dropdown-header' class on li-tag" do
161
+ check_selector build_menu(version: 3), 'ul.dropdown-menu > li.to_check_header2.dropdown-header'
162
+ end
163
+
164
+ it "does not create link-tag for the item (standard item), but puts only item 'name'" do
165
+ check_selector build_menu(version: 3), 'ul.dropdown-menu > li.to_check_header2.dropdown-header > a', 0
166
+ check_title build_menu(version: 3), 'ul.dropdown-menu > li.to_check_header2.dropdown-header', 'Misc. Pages'
167
+ end
168
+ end
169
+ end
170
+
171
+
172
+ context "when 'hash' provided in place of 'name'" do
173
+ context "with ':icon' parameter" do
174
+ it "adds span-tag with classes from the parameter" do
175
+ check_selector build_menu(version: 3), 'ul > li > a > span.fa.fa-fw.fa-bullhorn'
176
+ end
177
+ end
178
+
179
+ context "with ':title' parameter" do
180
+ it "sets up 'title' attribute on icon's span-tag to the parameter value" do
181
+ check_selector build_menu(version: 3), 'ul > li > a > span.fa.fa-fw.fa-book[title="Info"]'
182
+ end
183
+ end
184
+
185
+ context "with ':text' parameter" do
186
+ it "uses the parameter value as 'name' of the item" do
187
+ expect(build_menu(version: 3).css('ul > li > a > span.fa.fa-fw.fa-bullhorn')[0].parent.children[1].to_s).to eq ' News'
188
+ end
189
+ end
190
+
191
+ context "without ':text' and ':icon' parameters" do
192
+ it "raises 'InvalidHash' error" do
193
+ expect {
194
+ build_menu(version: 3, stub_name: true)
195
+ }.to raise_error(SimpleNavigationBootstrap::InvalidHash)
196
+ end
197
+ end
198
+ end
199
+
200
+
201
+ context "when container is empty" do
202
+ it 'return empty list' do
203
+ check_selector build_menu(version: 3, menu_name: :empty_menu, menu_opts: { skip_if_empty: true }), 'ul > li', 0
204
+ end
205
+ end
206
+
207
+ end
208
+
209
+ end
@@ -0,0 +1,7 @@
1
+ require 'spec_helper'
2
+
3
+ describe SimpleNavigationBootstrap::InvalidHash do
4
+ it 'has specific default message' do
5
+ expect(subject.message).to eq "Hash does not contain any of parameters: 'text', 'icon'"
6
+ end
7
+ end
@@ -0,0 +1,11 @@
1
+ require 'spec_helper'
2
+
3
+ describe SimpleNavigationBootstrap do
4
+ it 'registers Bootstrap2 renderer' do
5
+ expect(SimpleNavigation.registered_renderers[:bootstrap2]).to eq SimpleNavigationBootstrap::Bootstrap2
6
+ end
7
+
8
+ it 'registers Bootstrap3 renderer' do
9
+ expect(SimpleNavigation.registered_renderers[:bootstrap3]).to eq SimpleNavigationBootstrap::Bootstrap3
10
+ end
11
+ end
@@ -0,0 +1,43 @@
1
+ require 'simplecov'
2
+ require 'codeclimate-test-reporter'
3
+
4
+ # Configure SimpleCov
5
+ SimpleCov.formatter = SimpleCov::Formatter::MultiFormatter.new([
6
+ SimpleCov::Formatter::HTMLFormatter,
7
+ CodeClimate::TestReporter::Formatter
8
+ ])
9
+
10
+ SimpleCov.start
11
+
12
+ # SimpleNavigation currently only works for Rails, Sinatra and Padrino apps
13
+ # This is a workaround to be able to test the lib
14
+ ## START ##
15
+ ENV['RAILS_ENV'] = 'test'
16
+
17
+ require 'action_controller'
18
+ require 'action_view'
19
+
20
+ module Rails
21
+ module VERSION
22
+ MAJOR = 2
23
+ end
24
+ end unless defined? Rails
25
+
26
+ RAILS_ROOT = './' unless defined?(RAILS_ROOT)
27
+ RAILS_ENV = 'test' unless defined?(RAILS_ENV)
28
+ ## END ##
29
+
30
+ current_dir = File.expand_path(File.dirname(File.dirname(__FILE__)))
31
+
32
+ # Requires supporting ruby files with custom matchers and macros, etc, in
33
+ # spec/support/ and its subdirectories.
34
+ Dir[File.join(current_dir, 'spec/support/**/*.rb')].each { |f| require f }
35
+
36
+ # Configure RSpec
37
+ RSpec.configure do |config|
38
+ # Include standard helpers
39
+ config.include TestHelper
40
+ end
41
+
42
+ # Require the lib to test
43
+ require 'simple_navigation_bootstrap'
@@ -0,0 +1,139 @@
1
+ module TestHelper
2
+
3
+ def build_menu(version:, menu_name: :splited_menu, stub_name: false, menu_opts: {})
4
+ case version
5
+ when 2
6
+ render_result(SimpleNavigationBootstrap::Bootstrap2, menu_name, stub_name, menu_opts)
7
+ when 3
8
+ render_result(SimpleNavigationBootstrap::Bootstrap3, menu_name, stub_name, menu_opts)
9
+ else
10
+ end
11
+ end
12
+
13
+
14
+ def check_selector(nav_menu, selector, nb_entries = 1)
15
+ expect(nav_menu.css(selector).size).to eq nb_entries
16
+ end
17
+
18
+
19
+ def check_title(menu, selector, title)
20
+ expect(menu.css(selector)[0].children[0].to_s).to eq title
21
+ end
22
+
23
+
24
+ private
25
+
26
+
27
+ # 'stub_name' neads to check raising error when invalid 'Item name hash' provided
28
+ #
29
+ def render_result(renderer, menu_name, stub_name, opts = {})
30
+ menu_opts = opts.merge(expand_all: true)
31
+ prepare_navigation_instance(renderer)
32
+ main_menu = build_main_menu(menu_name, stub_name).render(menu_opts)
33
+ html_document(main_menu)
34
+ end
35
+
36
+
37
+ def prepare_navigation_instance(renderer)
38
+ SimpleNavigation::Configuration.instance.renderer = renderer
39
+ allow(SimpleNavigation).to receive_messages(adapter: simple_navigation_adapter)
40
+ allow_any_instance_of(SimpleNavigation::Item).to receive_messages(selected?: false, selected_by_condition?: false)
41
+ end
42
+
43
+
44
+ def simple_navigation_adapter
45
+ SimpleNavigation::Adapters::Rails.new(
46
+ double(:context, view_context: ActionView::Base.new)
47
+ )
48
+ end
49
+
50
+
51
+ def build_main_menu(menu_name, stub_name)
52
+ # Create a new container
53
+ main_menu = SimpleNavigation::ItemContainer.new(1)
54
+ # Fill it with menu
55
+ send(menu_name, main_menu)
56
+ # Mark one entry as selected
57
+ selected = main_menu.items.find { |item| item.key == :news }
58
+ allow(selected).to receive_messages(selected?: true, selected_by_condition?: true)
59
+ # Stub if needed
60
+ main_menu.items[0].instance_variable_set(:@name, {}) if stub_name
61
+ # Return menu
62
+ main_menu
63
+ end
64
+
65
+
66
+ def html_document(html)
67
+ Loofah.fragment(html)
68
+ end
69
+
70
+
71
+ ### TESTED NAVIGATION CONTENT ###
72
+
73
+
74
+ def splited_menu(primary)
75
+ primary.item :news, { icon: 'fa fa-fw fa-bullhorn', text: 'News' }, 'news_index_path'
76
+ primary.item :concerts, 'Concerts', 'concerts_path', html: { class: 'to_check_header', header: true }
77
+ primary.item :video, 'Video', 'videos_path', html: { class: 'to_check_split', split: true }
78
+ primary.item :divider_before_info_index_path, '', '#', html: { divider: true }
79
+ primary.item :info, { icon: 'fa fa-fw fa-book', title: 'Info' }, 'info_index_path', html: { split: true } do |info_nav|
80
+ info_nav.item :main_info_page, 'Main info page', 'main_info_page'
81
+ info_nav.item :about_info_page, 'About', 'about_info_page'
82
+ info_nav.item :divider_before_misc_info_pages, '', '#', html: { divider: true }
83
+ info_nav.item :misc_info_pages, 'Misc.', 'misc_info_pages', html: { split: true } do |misc_nav|
84
+ misc_nav.item :header_misc_pages, 'Misc. Pages', '#', html: { class: 'to_check_header2', header: true }
85
+ misc_nav.item :page1, 'Page1', 'page1'
86
+ misc_nav.item :page2, 'Page2', 'page2'
87
+ end
88
+ info_nav.item :divider_before_contact_info_page, '', '#', html: { divider: true }
89
+ info_nav.item :contact_info_page, 'Contact', 'contact_info_page'
90
+ end
91
+ primary.item :signed_in, 'Signed in as Pavel Shpak', '#', html: { class: 'to_check_navbar_text', navbar_text: true }
92
+ end
93
+
94
+
95
+ def unsplited_menu(primary)
96
+ primary.item :news, { icon: 'fa fa-fw fa-bullhorn', text: 'News' }, 'news_index_path'
97
+ primary.item :concerts, 'Concerts', 'concerts_path', html: { class: 'to_check_header', header: true }
98
+ primary.item :video, 'Video', 'videos_path', html: { class: 'to_check_split', split: true }
99
+ primary.item :divider_before_info_index_path, '', '#', html: { divider: true }
100
+ primary.item :info, { icon: 'fa fa-fw fa-book', title: 'Info' }, 'info_index_path', html: { split: false } do |info_nav|
101
+ info_nav.item :main_info_page, 'Main info page', 'main_info_page'
102
+ info_nav.item :about_info_page, 'About', 'about_info_page'
103
+ info_nav.item :divider_before_misc_info_pages, '', '#', html: { divider: true }
104
+ info_nav.item :misc_info_pages, 'Misc.', 'misc_info_pages', html: { split: true } do |misc_nav|
105
+ misc_nav.item :header_misc_pages, 'Misc. Pages', '#', html: { class: 'to_check_header2', header: true }
106
+ misc_nav.item :page1, 'Page1', 'page1'
107
+ misc_nav.item :page2, 'Page2', 'page2'
108
+ end
109
+ info_nav.item :divider_before_contact_info_page, '', '#', html: { divider: true }
110
+ info_nav.item :contact_info_page, 'Contact', 'contact_info_page'
111
+ end
112
+ primary.item :signed_in, 'Signed in as Pavel Shpak', '#', html: { class: 'to_check_navbar_text', navbar_text: true }
113
+ end
114
+
115
+
116
+ def demo_menu(primary)
117
+ primary.item :news, { icon: 'fa fa-fw fa-bullhorn', text: 'News' }, '/news_index_path'
118
+ primary.item :concerts, 'Concerts', '/concerts_path'
119
+ primary.item :video, 'Video', '/videos_path'
120
+ primary.item :divider_before_info, '', '#', html: { divider: true }
121
+ primary.item :info, { icon: 'fa fa-fw fa-book', title: 'Info' }, '/info_index_path', html: { split: true } do |info_nav|
122
+ info_nav.item :main_info_page, 'Main info page', '/main_info_page'
123
+ info_nav.item :about_info_page, 'About', '/about_info_page'
124
+ info_nav.item :misc_info_pages, 'Misc.', '#' do |misc_nav|
125
+ misc_nav.item :header_misc_pages, 'Misc. Pages', '#', html: { header: true }
126
+ misc_nav.item :page1, 'Page1', '/page1'
127
+ misc_nav.item :page2, 'Page2', '/page2'
128
+ end
129
+ info_nav.item :divider_before_contact_info_page, '', '#', html: { divider: true }
130
+ info_nav.item :contact_info_page, 'Contact', '/contact_info_page'
131
+ end
132
+ primary.item :signed_in, 'Signed in as Pavel Shpak', '#', html: { navbar_text: true }
133
+ end
134
+
135
+
136
+ def empty_menu(primary)
137
+ end
138
+
139
+ end