bootstrap-navbar 0.0.13
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.travis.yml +6 -0
- data/Gemfile +3 -0
- data/Guardfile +9 -0
- data/LICENSE.txt +22 -0
- data/README.md +513 -0
- data/Rakefile +5 -0
- data/bootstrap-navbar.gemspec +29 -0
- data/lib/bootstrap-navbar.rb +13 -0
- data/lib/bootstrap-navbar/helpers.rb +201 -0
- data/lib/bootstrap-navbar/version.rb +3 -0
- data/spec/bootstrap_navbar/helpers_spec.rb +353 -0
- data/spec/spec_helper.rb +10 -0
- metadata +128 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: e1a8ce95231b5f0e27729be22f6f1c510c7425e4
|
4
|
+
data.tar.gz: 5bff4661ff302e82b4e113daadb54e0b6f33b838
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 71f6ece8a5c288f346e1b195cefd700d4fddc62d9a4d8ded4c2eded71de02732d8c7fce1cfab7879f8df6cddae3d01e6eadab4fe133a00f4806f4a3a2b571423
|
7
|
+
data.tar.gz: 6e0a9f2d3805b95e08570f824efcc488581227084c73f07da188581b118fe7bfc18508bc7d494eef1e41c88291d337352d9e0d887880f6771ab9a5ddaa7644cb
|
data/.travis.yml
ADDED
data/Gemfile
ADDED
data/Guardfile
ADDED
@@ -0,0 +1,9 @@
|
|
1
|
+
guard 'rspec', cli: '--drb --profile', all_after_pass: false do
|
2
|
+
# Specs
|
3
|
+
watch(%r(^spec/.+_spec\.rb$))
|
4
|
+
watch('spec/spec_helper.rb') { 'spec' }
|
5
|
+
watch(%r(^spec/support/(.+)\.rb$)) { 'spec' }
|
6
|
+
|
7
|
+
# Files
|
8
|
+
watch(%r(^lib/(.+)\.rb$)) { |m| "spec/#{m[1]}_spec.rb" }
|
9
|
+
end
|
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2013 kraut computing UG (haftungsbeschränkt)
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,513 @@
|
|
1
|
+
# BootstrapNavbar
|
2
|
+
|
3
|
+
[![Gem Version](https://badge.fury.io/rb/bootstrap-navbar.png)](http://badge.fury.io/rb/bootstrap-navbar)
|
4
|
+
[![Build Status](https://secure.travis-ci.org/krautcomputing/bootstrap-navbar.png)](http://travis-ci.org/krautcomputing/bootstrap-navbar)
|
5
|
+
[![Dependency Status](https://gemnasium.com/krautcomputing/bootstrap-navbar.png)](https://gemnasium.com/krautcomputing/bootstrap-navbar)
|
6
|
+
[![Code Climate](https://codeclimate.com/github/krautcomputing/bootstrap-navbar.png)](https://codeclimate.com/github/krautcomputing/bootstrap-navbar)
|
7
|
+
|
8
|
+
Helpers to generate a Twitter Bootstrap style navbar
|
9
|
+
|
10
|
+
## Installation
|
11
|
+
|
12
|
+
This gem only provides a helper module with methods to generate HTML. It can be used by other gems to make these helpers available to a framework's rendering engine, e.g.:
|
13
|
+
|
14
|
+
* For Rails: https://github.com/julescopeland/Rails-Bootstrap-Navbar
|
15
|
+
* For [Middleman](http://middlemanapp.com/): https://github.com/krautcomputing/middleman-bootstrap-navbar
|
16
|
+
|
17
|
+
In short: __Unless you know what you're doing, do not use this gem directly in your app!__
|
18
|
+
|
19
|
+
## Setup
|
20
|
+
|
21
|
+
### Set current_url_method (required)
|
22
|
+
|
23
|
+
BootstrapNavbar has to be able to query for the current URL when rendering the navbar, e.g. to determine if a menu item is active or not. Since the way the current URL is determined varies depending on whether you use Rails, Sinatra, etc., this has to be set beforehand in some kind of initializer:
|
24
|
+
|
25
|
+
```ruby
|
26
|
+
# For Rails >= 3.2
|
27
|
+
BootstrapNavbar.current_url_method = 'request.original_url'
|
28
|
+
```
|
29
|
+
|
30
|
+
`current_url_method` should be set to a string which can be `eval`ed later.
|
31
|
+
|
32
|
+
### Set up HTML escaping (optional)
|
33
|
+
|
34
|
+
If the framework or rendering engine that you use BootstrapNavbar with escapes HTML by default, you can instruct BootstrapNavbar to mark the returned HTML as html_safe by default by overriding `BootstrapNavbar#prepare_html`:
|
35
|
+
|
36
|
+
```ruby
|
37
|
+
# For Rails
|
38
|
+
module BootstrapNavbar::Helpers
|
39
|
+
def prepare_html(html)
|
40
|
+
html.html_safe
|
41
|
+
end
|
42
|
+
end
|
43
|
+
```
|
44
|
+
|
45
|
+
### Mix in the helpers into the rendering engine (required)
|
46
|
+
|
47
|
+
```ruby
|
48
|
+
# For Rails
|
49
|
+
ActionView::Base.send :include, BootstrapNavbar::Helpers
|
50
|
+
```
|
51
|
+
|
52
|
+
## Usage
|
53
|
+
|
54
|
+
Check out the [Twitter Bootstrap docs](http://twitter.github.io/bootstrap/components.html#navbar) for how a navbar can be constructed. All components and options mentioned there should be supported by this gem, so you don't need to write any HTML by hand. If there is something missing or wrong HTML is generated, please [open an issue](https://github.com/krautcomputing/bootstrap-navbar/issues).
|
55
|
+
|
56
|
+
Let's assume you have mixed in the helper in your rendering engine and use Haml.
|
57
|
+
|
58
|
+
### Full example
|
59
|
+
|
60
|
+
```ruby
|
61
|
+
= nav_bar fixed: :top, responsive: true do
|
62
|
+
= brand_link 'My great app'
|
63
|
+
= menu_group class: 'foo', id: 'menu' do
|
64
|
+
= menu_text 'Pick an option:'
|
65
|
+
= menu_item "Home", root_path
|
66
|
+
= menu_item "About Us", about_us_path
|
67
|
+
= menu_item contact_path do
|
68
|
+
= image_tag 'contact.jpg'
|
69
|
+
Contact Us!
|
70
|
+
= menu_divider
|
71
|
+
= drop_down "Stuff" do
|
72
|
+
= drop_down_header 'Great stuff!'
|
73
|
+
= menu_item "One", one_path
|
74
|
+
= menu_item "Two", two_path
|
75
|
+
= menu_item "Three", three_path
|
76
|
+
- if current_user.admin?
|
77
|
+
= drop_down_divider
|
78
|
+
= sub_drop_down 'Admin Stuff' do
|
79
|
+
= menu_item "Admin Dashboard", admin_path
|
80
|
+
= menu_item "Users", admin_users_path
|
81
|
+
= menu_group pull: 'right' do
|
82
|
+
- if current_user
|
83
|
+
= menu_item "Log Out", log_out_path
|
84
|
+
- else
|
85
|
+
= menu_item "Log In", log_in_path
|
86
|
+
```
|
87
|
+
|
88
|
+
### Methods
|
89
|
+
|
90
|
+
#### nav_bar
|
91
|
+
|
92
|
+
This method sets up the basic structure of a navbar.
|
93
|
+
|
94
|
+
```haml
|
95
|
+
= nav_bar
|
96
|
+
```
|
97
|
+
|
98
|
+
generates:
|
99
|
+
|
100
|
+
```html
|
101
|
+
<div class="navbar">
|
102
|
+
<div class="navbar-inner">
|
103
|
+
<div class="container">
|
104
|
+
</div>
|
105
|
+
</div>
|
106
|
+
</div>
|
107
|
+
```
|
108
|
+
|
109
|
+
The content of the navbar is supplied by the block and the available options:
|
110
|
+
|
111
|
+
```haml
|
112
|
+
= nav_bar do
|
113
|
+
Yay!
|
114
|
+
```
|
115
|
+
|
116
|
+
generates:
|
117
|
+
|
118
|
+
```html
|
119
|
+
<div class="navbar">
|
120
|
+
<div class="navbar-inner">
|
121
|
+
<div class="container">
|
122
|
+
Yay!
|
123
|
+
</div>
|
124
|
+
</div>
|
125
|
+
</div>
|
126
|
+
```
|
127
|
+
|
128
|
+
Options `brand` and `brand_link` autogenerate the brand link:
|
129
|
+
|
130
|
+
```haml
|
131
|
+
= nav_bar brand: 'My great app', brand_link: '/start'
|
132
|
+
```
|
133
|
+
|
134
|
+
generates:
|
135
|
+
|
136
|
+
```html
|
137
|
+
<div class="navbar">
|
138
|
+
<div class="navbar-inner">
|
139
|
+
<div class="container">
|
140
|
+
<a href="/start" class="brand">My great app</a>
|
141
|
+
</div>
|
142
|
+
</div>
|
143
|
+
</div>
|
144
|
+
```
|
145
|
+
|
146
|
+
If only `brand` is defined, `brand_link` defaults to `/`.
|
147
|
+
|
148
|
+
Option `responsive` generates a responsive navbar:
|
149
|
+
|
150
|
+
```haml
|
151
|
+
= nav_bar responsive: true
|
152
|
+
```
|
153
|
+
|
154
|
+
generates:
|
155
|
+
|
156
|
+
```html
|
157
|
+
<div class="navbar">
|
158
|
+
<div class="navbar-inner">
|
159
|
+
<div class="container">
|
160
|
+
<a class="btn btn-navbar" data-toggle="collapse" data-target=".nav-collapse">
|
161
|
+
<span class='icon-bar'></span>
|
162
|
+
<span class='icon-bar'></span>
|
163
|
+
<span class='icon-bar'></span>
|
164
|
+
</div>
|
165
|
+
</div>
|
166
|
+
</div>
|
167
|
+
```
|
168
|
+
|
169
|
+
Option `fluid` changes the grid system to be [fluid](http://twitter.github.io/bootstrap/scaffolding.html#fluidGridSystem):
|
170
|
+
|
171
|
+
```haml
|
172
|
+
= nav_bar fluid: true
|
173
|
+
```
|
174
|
+
|
175
|
+
generates:
|
176
|
+
|
177
|
+
```html
|
178
|
+
<div class="navbar">
|
179
|
+
<div class="navbar-inner">
|
180
|
+
<div class="container-fluid">
|
181
|
+
</div>
|
182
|
+
</div>
|
183
|
+
</div>
|
184
|
+
```
|
185
|
+
|
186
|
+
#### brand_link
|
187
|
+
|
188
|
+
This method generates a menu divider, to be used in a `nav_bar`.
|
189
|
+
|
190
|
+
```haml
|
191
|
+
= brand_link 'My App', '/home'
|
192
|
+
```
|
193
|
+
|
194
|
+
generates:
|
195
|
+
|
196
|
+
```html
|
197
|
+
<a href="/home" class="brand">My App</a>
|
198
|
+
```
|
199
|
+
|
200
|
+
If the path (`/home` in this case) is not specified, it defaults to `/`.
|
201
|
+
|
202
|
+
#### menu_text
|
203
|
+
|
204
|
+
This method generates some menu text, to be used in a `nav_bar`.
|
205
|
+
|
206
|
+
```haml
|
207
|
+
= menu_text 'Select a option:'
|
208
|
+
```
|
209
|
+
|
210
|
+
generates:
|
211
|
+
|
212
|
+
```html
|
213
|
+
<p class="navbar-text">
|
214
|
+
Select a option:
|
215
|
+
</p>
|
216
|
+
```
|
217
|
+
|
218
|
+
A option can be supplied to make the text float to the right or left:
|
219
|
+
|
220
|
+
```haml
|
221
|
+
= menu_text 'Select a option:', :right
|
222
|
+
```
|
223
|
+
|
224
|
+
generates:
|
225
|
+
|
226
|
+
```html
|
227
|
+
<p class="navbar-text pull-right">
|
228
|
+
Select a option:
|
229
|
+
</p>
|
230
|
+
```
|
231
|
+
|
232
|
+
The content can alternatively be supplied in a block:
|
233
|
+
|
234
|
+
```haml
|
235
|
+
= menu_text do
|
236
|
+
Current country:
|
237
|
+
= image_text 'flags/en.jpg'
|
238
|
+
```
|
239
|
+
|
240
|
+
generates:
|
241
|
+
|
242
|
+
```html
|
243
|
+
<p class="navbar-text">
|
244
|
+
Current country:
|
245
|
+
<img src="/images/flags/en.jpg">
|
246
|
+
</p>
|
247
|
+
```
|
248
|
+
|
249
|
+
#### menu_group
|
250
|
+
|
251
|
+
This method generates a menu group, to be used in a `nav_bar`.
|
252
|
+
|
253
|
+
```haml
|
254
|
+
= menu_group
|
255
|
+
```
|
256
|
+
|
257
|
+
generates:
|
258
|
+
|
259
|
+
```html
|
260
|
+
<ul class="nav">
|
261
|
+
</ul>
|
262
|
+
```
|
263
|
+
|
264
|
+
The content of the menu group is supplied by the blocks:
|
265
|
+
|
266
|
+
```haml
|
267
|
+
= menu_group do
|
268
|
+
Yay!
|
269
|
+
```
|
270
|
+
|
271
|
+
generates:
|
272
|
+
|
273
|
+
```html
|
274
|
+
<ul class="nav">
|
275
|
+
Yay!
|
276
|
+
</ul>
|
277
|
+
```
|
278
|
+
|
279
|
+
You can add a `pull` option to make the group float to the right or left, and add more classes and other attributes:
|
280
|
+
|
281
|
+
```haml
|
282
|
+
= menu_group pull: 'right', class: 'large', id: 'menu'
|
283
|
+
```
|
284
|
+
|
285
|
+
generates:
|
286
|
+
|
287
|
+
```html
|
288
|
+
<ul class="nav pull-right large" id="menu">
|
289
|
+
</ul>
|
290
|
+
```
|
291
|
+
|
292
|
+
#### menu_item
|
293
|
+
|
294
|
+
This method generates a menu item, to be used in a `menu_group`.
|
295
|
+
|
296
|
+
```haml
|
297
|
+
= menu_item 'Home', '/home'
|
298
|
+
```
|
299
|
+
|
300
|
+
generates:
|
301
|
+
|
302
|
+
```html
|
303
|
+
<li>
|
304
|
+
<a href="/home">
|
305
|
+
Home
|
306
|
+
</a>
|
307
|
+
</li>
|
308
|
+
```
|
309
|
+
|
310
|
+
If the path (`/home` in this case) is not specified, it defaults to `#`.
|
311
|
+
|
312
|
+
You can also use a block (e.g., in case the link name is more than a single word):
|
313
|
+
|
314
|
+
```haml
|
315
|
+
= menu_item /home' do
|
316
|
+
= image_tag 'home.png'
|
317
|
+
Home
|
318
|
+
```
|
319
|
+
|
320
|
+
generates:
|
321
|
+
|
322
|
+
```html
|
323
|
+
<li>
|
324
|
+
<a href="/home">
|
325
|
+
<img src="/images/home.png">
|
326
|
+
Home
|
327
|
+
</a>
|
328
|
+
</li>
|
329
|
+
```
|
330
|
+
|
331
|
+
You can add options that will be passed on to the `li` and `a` elements:
|
332
|
+
|
333
|
+
```haml
|
334
|
+
= menu_item 'Home', '/home', { class: 'list-item' }, { id: 'home' }
|
335
|
+
```
|
336
|
+
|
337
|
+
generates:
|
338
|
+
|
339
|
+
```html
|
340
|
+
<li class="list-item">
|
341
|
+
<a href="/home" id="home">
|
342
|
+
Home
|
343
|
+
</a>
|
344
|
+
</li>
|
345
|
+
```
|
346
|
+
|
347
|
+
If the specified path/URL is the [current url](#set-current_url_method-required), it will be marked as `active`. Note that it doesn't matter if you link to a full URL or just the path, or if `BootstrapNavbar.current_url_method` returns a full URL or just the path, it will work regardless.
|
348
|
+
|
349
|
+
```haml
|
350
|
+
= menu_item 'Home', '/home'
|
351
|
+
```
|
352
|
+
|
353
|
+
generates:
|
354
|
+
|
355
|
+
```html
|
356
|
+
<!-- If the current path is /home -->
|
357
|
+
|
358
|
+
<li class="active">
|
359
|
+
<a href="/home">
|
360
|
+
Home
|
361
|
+
</a>
|
362
|
+
</li>
|
363
|
+
```
|
364
|
+
|
365
|
+
#### menu_divider
|
366
|
+
|
367
|
+
This method generates a menu divider, to be used in a `menu_group`.
|
368
|
+
|
369
|
+
```haml
|
370
|
+
= menu_divider
|
371
|
+
```
|
372
|
+
|
373
|
+
generates:
|
374
|
+
|
375
|
+
```html
|
376
|
+
<li class="divider-vertical"></li>
|
377
|
+
```
|
378
|
+
|
379
|
+
#### drop_down
|
380
|
+
|
381
|
+
This method generates a dropdown, to be used in a `menu_group`.
|
382
|
+
|
383
|
+
```haml
|
384
|
+
= drop_down 'Settings'
|
385
|
+
```
|
386
|
+
|
387
|
+
generates:
|
388
|
+
|
389
|
+
```html
|
390
|
+
<li class="dropdown">
|
391
|
+
<a href="#" class="dropdown-toggle" data-toggle="dropdown">
|
392
|
+
Settings <b class="caret"></b>
|
393
|
+
</a>
|
394
|
+
<ul class="dropdown-menu">
|
395
|
+
</ul>
|
396
|
+
</li>
|
397
|
+
```
|
398
|
+
|
399
|
+
The content of the dropdown can be defined in the block using `menu_item`s:
|
400
|
+
|
401
|
+
```haml
|
402
|
+
= drop_down 'Settings' do
|
403
|
+
= menu_item 'Basic', '/settings/basic'
|
404
|
+
= menu_item 'Advanced', '/settings/advanced'
|
405
|
+
```
|
406
|
+
|
407
|
+
generates:
|
408
|
+
|
409
|
+
```html
|
410
|
+
<li class="dropdown">
|
411
|
+
<a href="#" class="dropdown-toggle" data-toggle="dropdown">
|
412
|
+
Settings <b class="caret"></b>
|
413
|
+
</a>
|
414
|
+
<ul class="dropdown-menu">
|
415
|
+
<li>
|
416
|
+
<a href="/settings/basic">
|
417
|
+
Basic
|
418
|
+
</a>
|
419
|
+
</li>
|
420
|
+
<li>
|
421
|
+
<a href="/settings/advanced">
|
422
|
+
Advanced
|
423
|
+
</a>
|
424
|
+
</li>
|
425
|
+
</ul>
|
426
|
+
</li>
|
427
|
+
```
|
428
|
+
|
429
|
+
#### sub_drop_down
|
430
|
+
|
431
|
+
This method generates a sub dropdown, to be used in a `drop_down`.
|
432
|
+
|
433
|
+
```haml
|
434
|
+
= sub_drop_down 'Admin Settings'
|
435
|
+
```
|
436
|
+
|
437
|
+
generates:
|
438
|
+
|
439
|
+
```html
|
440
|
+
<li class="dropdown-submenu">
|
441
|
+
<a href="#">
|
442
|
+
Admin Settings
|
443
|
+
</a>
|
444
|
+
<ul class="dropdown-menu">
|
445
|
+
</ul>
|
446
|
+
</li>
|
447
|
+
```
|
448
|
+
|
449
|
+
Just like in the `drop_down`, the content of the sub dropdown is defined in the block:
|
450
|
+
|
451
|
+
```haml
|
452
|
+
= sub_drop_down 'Admin Settings' do
|
453
|
+
= menu_item 'Users', '/settings/admin/users'
|
454
|
+
= menu_item 'Stats', '/settings/admin/stats'
|
455
|
+
```
|
456
|
+
|
457
|
+
generates:
|
458
|
+
|
459
|
+
```html
|
460
|
+
<li class="dropdown-submenu">
|
461
|
+
<a href="#">
|
462
|
+
Admin Settings
|
463
|
+
</a>
|
464
|
+
<ul class="dropdown-menu">
|
465
|
+
<li>
|
466
|
+
<a href="/settings/admin/users">
|
467
|
+
Users
|
468
|
+
</a>
|
469
|
+
</li>
|
470
|
+
<li>
|
471
|
+
<a href="/settings/admin/stats">
|
472
|
+
Stats
|
473
|
+
</a>
|
474
|
+
</li>
|
475
|
+
</ul>
|
476
|
+
</li>
|
477
|
+
```
|
478
|
+
|
479
|
+
#### drop_down_divider
|
480
|
+
|
481
|
+
This method generates a dropdown divider, to be used in a `drop_down` or `sub_drop_down`.
|
482
|
+
|
483
|
+
```haml
|
484
|
+
= drop_down_divider
|
485
|
+
```
|
486
|
+
|
487
|
+
generates:
|
488
|
+
|
489
|
+
```html
|
490
|
+
<li class="divider"></li>
|
491
|
+
```
|
492
|
+
|
493
|
+
#### drop_down_header
|
494
|
+
|
495
|
+
This method generates a dropdown header, to be used in a `drop_down` or `sub_drop_down`.
|
496
|
+
|
497
|
+
```haml
|
498
|
+
= drop_down_header 'Important!'
|
499
|
+
```
|
500
|
+
|
501
|
+
generates:
|
502
|
+
|
503
|
+
```html
|
504
|
+
<li class="nav-header">Important!</li>
|
505
|
+
```
|
506
|
+
|
507
|
+
## Contributing
|
508
|
+
|
509
|
+
1. Fork it
|
510
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
511
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
512
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
513
|
+
5. Create new Pull Request
|
data/Rakefile
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
lib = File.expand_path('../lib', __FILE__)
|
4
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
5
|
+
|
6
|
+
require 'bootstrap-navbar/version'
|
7
|
+
|
8
|
+
Gem::Specification.new do |gem|
|
9
|
+
gem.name = 'bootstrap-navbar'
|
10
|
+
gem.version = BootstrapNavbar::VERSION
|
11
|
+
gem.platform = Gem::Platform::RUBY
|
12
|
+
gem.authors = ['Manuel Meurer']
|
13
|
+
gem.email = 'manuel.meurer@gmail.com'
|
14
|
+
gem.summary = 'Helpers to generate a Twitter Bootstrap style navbar'
|
15
|
+
gem.description = 'Helpers to generate a Twitter Bootstrap style navbar'
|
16
|
+
gem.homepage = 'https://github.com/krautcomputing/bootstrap-navbar'
|
17
|
+
gem.license = 'MIT'
|
18
|
+
|
19
|
+
gem.files = `git ls-files`.split($/)
|
20
|
+
gem.executables = gem.files.grep(%r(^bin/)).map { |f| File.basename(f) }
|
21
|
+
gem.test_files = gem.files.grep(%r(^(test|spec|features)/))
|
22
|
+
gem.require_paths = ['lib']
|
23
|
+
|
24
|
+
gem.add_development_dependency 'rake', '>= 10.0.0'
|
25
|
+
gem.add_development_dependency 'rspec', '~> 2.13.0'
|
26
|
+
gem.add_development_dependency 'rspec-html-matchers', '~> 0.4.3'
|
27
|
+
gem.add_development_dependency 'guard-rspec', '~> 3.0'
|
28
|
+
gem.add_development_dependency 'padrino-helpers', '~> 0.11.2'
|
29
|
+
end
|
@@ -0,0 +1,201 @@
|
|
1
|
+
require 'uri'
|
2
|
+
|
3
|
+
module BootstrapNavbar::Helpers
|
4
|
+
def nav_bar(options = {}, &block)
|
5
|
+
nav_bar_div options do
|
6
|
+
navbar_inner_div do
|
7
|
+
container_div options[:brand], options[:brand_link], options[:responsive], options[:fluid], &block
|
8
|
+
end
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
def menu_group(options = {}, &block)
|
13
|
+
css_classes = %w(nav).tap do |css_classes|
|
14
|
+
css_classes << "pull-#{options.delete(:pull)}" if options.has_key?(:pull)
|
15
|
+
css_classes << options.delete(:class) if options.has_key?(:class)
|
16
|
+
end
|
17
|
+
attributes = attribute_hash_to_string({ class: css_classes.join(' ') }.merge(options))
|
18
|
+
prepare_html <<-HTML.chomp!
|
19
|
+
<ul#{with_preceding_space attributes}>
|
20
|
+
#{capture(&block) if block_given?}
|
21
|
+
</ul>
|
22
|
+
HTML
|
23
|
+
end
|
24
|
+
|
25
|
+
def menu_item(name = nil, path = nil, list_item_options = nil, link_options = nil, &block)
|
26
|
+
name, path, list_item_options, link_options = capture(&block), name, path, list_item_options if block_given?
|
27
|
+
path ||= '#'
|
28
|
+
list_item_options ||= {}
|
29
|
+
link_options ||= {}
|
30
|
+
|
31
|
+
list_item_css_classes = [].tap do |css_classes|
|
32
|
+
css_classes << 'active' if current_url?(path)
|
33
|
+
css_classes << list_item_options.delete(:class) if list_item_options.has_key?(:class)
|
34
|
+
end
|
35
|
+
list_item_attributes = attribute_hash_to_string(
|
36
|
+
{ class: list_item_css_classes.join(' ') }
|
37
|
+
.delete_if { |k, v| v.empty? }
|
38
|
+
.merge(list_item_options)
|
39
|
+
)
|
40
|
+
link_attributes = attribute_hash_to_string(link_options)
|
41
|
+
prepare_html <<-HTML.chomp!
|
42
|
+
<li#{with_preceding_space list_item_attributes}>
|
43
|
+
<a href="#{path}"#{with_preceding_space link_attributes}>
|
44
|
+
#{name}
|
45
|
+
</a>
|
46
|
+
</li>
|
47
|
+
HTML
|
48
|
+
end
|
49
|
+
|
50
|
+
def drop_down(name, &block)
|
51
|
+
prepare_html <<-HTML.chomp!
|
52
|
+
<li class="dropdown">
|
53
|
+
<a href="#" class="dropdown-toggle" data-toggle="dropdown">
|
54
|
+
#{name} <b class="caret"></b>
|
55
|
+
</a>
|
56
|
+
#{drop_down_menu(&block)}
|
57
|
+
</li>
|
58
|
+
HTML
|
59
|
+
end
|
60
|
+
|
61
|
+
def sub_drop_down(name, list_item_options = {}, link_options = {}, &block)
|
62
|
+
list_item_css_classes = %w(dropdown-submenu).tap do |css_classes|
|
63
|
+
css_classes << list_item_options.delete(:class) if list_item_options.has_key?(:class)
|
64
|
+
end
|
65
|
+
list_item_attributes = attribute_hash_to_string({ class: list_item_css_classes.join(' ') }.merge(list_item_options))
|
66
|
+
link_attributes = attribute_hash_to_string(link_options)
|
67
|
+
prepare_html <<-HTML.chomp!
|
68
|
+
<li#{with_preceding_space list_item_attributes}>
|
69
|
+
<a href="#"#{with_preceding_space link_attributes}>
|
70
|
+
#{name}
|
71
|
+
</a>
|
72
|
+
#{drop_down_menu(&block)}
|
73
|
+
</li>
|
74
|
+
HTML
|
75
|
+
end
|
76
|
+
|
77
|
+
def drop_down_divider
|
78
|
+
prepare_html %(<li class="divider"></li>)
|
79
|
+
end
|
80
|
+
|
81
|
+
def drop_down_header(text)
|
82
|
+
prepare_html %(<li class="nav-header">#{text}</li>)
|
83
|
+
end
|
84
|
+
|
85
|
+
def menu_divider
|
86
|
+
prepare_html %(<li class="divider-vertical"></li>)
|
87
|
+
end
|
88
|
+
|
89
|
+
def menu_text(text = nil, pull = nil, &block)
|
90
|
+
css_classes = %w(navbar-text).tap do |css_classes|
|
91
|
+
css_classes << "pull-#{pull}" if pull
|
92
|
+
end
|
93
|
+
prepare_html <<-HTML.chomp!
|
94
|
+
<p class="#{css_classes.join(' ')}">
|
95
|
+
#{block_given? ? capture(&block) : text}
|
96
|
+
</p>
|
97
|
+
HTML
|
98
|
+
end
|
99
|
+
|
100
|
+
def brand_link(name, url = nil)
|
101
|
+
prepare_html %(<a href="#{url || '/'}" class="brand">#{name}</a>)
|
102
|
+
end
|
103
|
+
|
104
|
+
private
|
105
|
+
|
106
|
+
def nav_bar_div(options, &block)
|
107
|
+
position = case
|
108
|
+
when options.has_key?(:static)
|
109
|
+
"static-#{options[:static]}"
|
110
|
+
when options.has_key?(:fixed)
|
111
|
+
"fixed-#{options[:fixed]}"
|
112
|
+
end
|
113
|
+
|
114
|
+
css_classes = %w(navbar).tap do |css_classes|
|
115
|
+
css_classes << "navbar-#{position}" if position
|
116
|
+
css_classes << 'navbar-inverse' if options[:inverse]
|
117
|
+
end
|
118
|
+
|
119
|
+
prepare_html <<-HTML.chomp!
|
120
|
+
<div class="#{css_classes.join(' ')}">
|
121
|
+
#{capture(&block) if block_given?}
|
122
|
+
</div>
|
123
|
+
HTML
|
124
|
+
end
|
125
|
+
|
126
|
+
def navbar_inner_div(&block)
|
127
|
+
prepare_html <<-HTML.chomp!
|
128
|
+
<div class="navbar-inner">
|
129
|
+
#{capture(&block) if block_given?}
|
130
|
+
</div>
|
131
|
+
HTML
|
132
|
+
end
|
133
|
+
|
134
|
+
def container_div(brand, brand_link, responsive, fluid, &block)
|
135
|
+
css_class = fluid ? 'container-fluid' : 'container'
|
136
|
+
content = [].tap do |content|
|
137
|
+
content << responsive_button if responsive
|
138
|
+
content << brand_link(brand, brand_link) if brand || brand_link
|
139
|
+
content << if responsive
|
140
|
+
responsive_wrapper(&block)
|
141
|
+
else
|
142
|
+
capture(&block) if block_given?
|
143
|
+
end
|
144
|
+
end
|
145
|
+
prepare_html <<-HTML.chomp!
|
146
|
+
<div class="#{css_class}">
|
147
|
+
#{content.join("\n")}
|
148
|
+
</div>
|
149
|
+
HTML
|
150
|
+
end
|
151
|
+
|
152
|
+
def responsive_wrapper(&block)
|
153
|
+
prepare_html <<-HTML.chomp!
|
154
|
+
<div class="nav-collapse collapse">
|
155
|
+
#{capture(&block) if block_given?}
|
156
|
+
</div>
|
157
|
+
HTML
|
158
|
+
end
|
159
|
+
|
160
|
+
def responsive_button
|
161
|
+
prepare_html <<-HTML.chomp!
|
162
|
+
<a class="btn btn-navbar" data-toggle="collapse" data-target=".nav-collapse">
|
163
|
+
<span class='icon-bar'></span>
|
164
|
+
<span class='icon-bar'></span>
|
165
|
+
<span class='icon-bar'></span>
|
166
|
+
</a>
|
167
|
+
HTML
|
168
|
+
end
|
169
|
+
|
170
|
+
def drop_down_menu(&block)
|
171
|
+
prepare_html <<-HTML.chomp!
|
172
|
+
<ul class="dropdown-menu">
|
173
|
+
#{capture(&block) if block_given?}
|
174
|
+
</ul>
|
175
|
+
HTML
|
176
|
+
end
|
177
|
+
|
178
|
+
def with_preceding_space(attributes)
|
179
|
+
' ' << attributes unless [nil, ''].include?(attributes)
|
180
|
+
end
|
181
|
+
|
182
|
+
def attribute_hash_to_string(hash)
|
183
|
+
hash.map { |k, v| %(#{k}="#{v}") }.join(' ')
|
184
|
+
end
|
185
|
+
|
186
|
+
def current_url?(url)
|
187
|
+
normalized_path, normalized_current_path = [url, current_url].map do |url|
|
188
|
+
URI.parse(url).path.sub(%r(/\z), '') rescue nil
|
189
|
+
end
|
190
|
+
normalized_path == normalized_current_path
|
191
|
+
end
|
192
|
+
|
193
|
+
def current_url
|
194
|
+
raise StandardError, 'current_url_method is not defined.' if BootstrapNavbar.current_url_method.nil?
|
195
|
+
eval BootstrapNavbar.current_url_method
|
196
|
+
end
|
197
|
+
|
198
|
+
def prepare_html(html)
|
199
|
+
html
|
200
|
+
end
|
201
|
+
end
|
@@ -0,0 +1,353 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'padrino-helpers'
|
3
|
+
|
4
|
+
shared_examples 'active menu item' do
|
5
|
+
it 'generates the correct HTML' do
|
6
|
+
paths_and_urls.each do |current_path_or_url|
|
7
|
+
paths_and_urls.each do |menu_path_or_url|
|
8
|
+
BootstrapNavbar.current_url_method = "'#{current_path_or_url}'"
|
9
|
+
subject.menu_item('foo', menu_path_or_url).should have_tag(:li, with: { class: 'active' })
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
describe BootstrapNavbar::Helpers do
|
16
|
+
subject do
|
17
|
+
Class.new do
|
18
|
+
include Padrino::Helpers::OutputHelpers
|
19
|
+
include BootstrapNavbar::Helpers
|
20
|
+
end.new
|
21
|
+
end
|
22
|
+
|
23
|
+
before do
|
24
|
+
BootstrapNavbar.current_url_method = ''
|
25
|
+
end
|
26
|
+
|
27
|
+
describe '#nav_bar' do
|
28
|
+
context 'without parameters' do
|
29
|
+
it 'generates the correct HTML' do
|
30
|
+
subject.nav_bar.should have_tag(:div, with: { class: 'navbar' }) do
|
31
|
+
with_tag :div, with: { class: 'navbar-inner' } do
|
32
|
+
with_tag :div, with: { class: 'container' }
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
context 'with a block' do
|
39
|
+
it 'generates the correct HTML' do
|
40
|
+
subject.nav_bar { 'foo' }.should have_tag(:div, with: { class: 'navbar' }, content: 'foo')
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
context 'with "static" parameter' do
|
45
|
+
it 'generates the correct HTML' do
|
46
|
+
subject.nav_bar(static: 'top').should have_tag(:div, with: { class: 'navbar navbar-static-top' })
|
47
|
+
subject.nav_bar(static: 'bottom').should have_tag(:div, with: { class: 'navbar navbar-static-bottom' })
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
context 'with "fixed" parameter' do
|
52
|
+
it 'generates the correct HTML' do
|
53
|
+
subject.nav_bar(fixed: 'top').should have_tag(:div, with: { class: 'navbar navbar-fixed-top' })
|
54
|
+
subject.nav_bar(fixed: 'bottom').should have_tag(:div, with: { class: 'navbar navbar-fixed-bottom' })
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
context 'with "inverse" parameter' do
|
59
|
+
it 'generates the correct HTML' do
|
60
|
+
subject.nav_bar(inverse: true).should have_tag(:div, with: { class: 'navbar navbar-inverse' })
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
context 'with "brand" and "brank_link" parameters' do
|
65
|
+
it 'generates the correct HTML' do
|
66
|
+
subject.nav_bar(brand: 'foo').should have_tag(:a, with: { href: '/', class: 'brand' }, content: 'foo')
|
67
|
+
subject.nav_bar(brand: 'foo', brand_link: 'http://google.com').should have_tag(:a, with: { href: 'http://google.com', class: 'brand' }, content: 'foo')
|
68
|
+
subject.nav_bar(brand_link: 'http://google.com').should have_tag(:a, with: { href: 'http://google.com', class: 'brand' })
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
context 'with "responsive" parameter' do
|
73
|
+
it 'generates the correct HTML' do
|
74
|
+
subject.nav_bar(responsive: true).should have_tag(:a, with: { class: 'btn btn-navbar', :'data-toggle' => 'collapse', :'data-target' => '.nav-collapse' }) do
|
75
|
+
3.times do
|
76
|
+
with_tag :span, with: { class: 'icon-bar' }
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
context 'with "fluid" parameter' do
|
83
|
+
it 'generates the correct HTML' do
|
84
|
+
subject.nav_bar(fluid: true).should have_tag(:div, with: { class: 'container-fluid' })
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
describe '#menu_group' do
|
90
|
+
context 'without parameters' do
|
91
|
+
it 'generates the correct HTML' do
|
92
|
+
subject.menu_group.should have_tag(:ul, with: { class: 'nav' })
|
93
|
+
subject.menu_group { 'foo' }.should have_tag(:ul, with: { class: 'nav' }, content: 'foo')
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
context 'with "pull" parameter' do
|
98
|
+
it 'generates the correct HTML' do
|
99
|
+
subject.menu_group(pull: 'right').should have_tag(:ul, with: { class: 'nav pull-right' })
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
context 'with "class" parameter' do
|
104
|
+
it 'generates the correct HTML' do
|
105
|
+
subject.menu_group(class: 'foo').should have_tag(:ul, with: { class: 'nav foo' })
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
context 'with random parameters' do
|
110
|
+
it 'generates the correct HTML' do
|
111
|
+
subject.menu_group(:'data-foo' => 'bar').should have_tag(:ul, with: { class: 'nav', :'data-foo' => 'bar' })
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
context 'with many parameters' do
|
116
|
+
it 'generates the correct HTML' do
|
117
|
+
subject.menu_group(pull: 'right', class: 'foo', :'data-foo' => 'bar').should have_tag(:ul, with: { class: 'nav foo pull-right', :'data-foo' => 'bar' })
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
describe '#menu_item' do
|
123
|
+
context 'with current URL or path' do
|
124
|
+
# With root URL or path
|
125
|
+
it_behaves_like 'active menu item' do
|
126
|
+
let(:paths_and_urls) do
|
127
|
+
%w(
|
128
|
+
http://www.foobar.com/
|
129
|
+
http://www.foobar.com
|
130
|
+
/
|
131
|
+
http://www.foobar.com/?foo=bar
|
132
|
+
http://www.foobar.com?foo=bar
|
133
|
+
/?foo=bar
|
134
|
+
http://www.foobar.com/#foo
|
135
|
+
http://www.foobar.com#foo
|
136
|
+
/#foo
|
137
|
+
http://www.foobar.com/#foo?foo=bar
|
138
|
+
http://www.foobar.com#foo?foo=bar
|
139
|
+
/#foo?foo=bar
|
140
|
+
)
|
141
|
+
end
|
142
|
+
end
|
143
|
+
|
144
|
+
# With sub URL or path
|
145
|
+
it_behaves_like 'active menu item' do
|
146
|
+
let(:paths_and_urls) do
|
147
|
+
%w(
|
148
|
+
http://www.foobar.com/foo
|
149
|
+
http://www.foobar.com/foo/
|
150
|
+
/foo
|
151
|
+
/foo/
|
152
|
+
http://www.foobar.com/foo?foo=bar
|
153
|
+
http://www.foobar.com/foo/?foo=bar
|
154
|
+
/foo?foo=bar
|
155
|
+
/foo/?foo=bar
|
156
|
+
http://www.foobar.com/foo#foo
|
157
|
+
http://www.foobar.com/foo/#foo
|
158
|
+
/foo#foo
|
159
|
+
/foo/#foo
|
160
|
+
http://www.foobar.com/foo#foo?foo=bar
|
161
|
+
http://www.foobar.com/foo/#foo?foo=bar
|
162
|
+
/foo#foo?foo=bar
|
163
|
+
/foo/#foo?foo=bar
|
164
|
+
)
|
165
|
+
end
|
166
|
+
end
|
167
|
+
|
168
|
+
context 'with list item options' do
|
169
|
+
it 'generates the correct HTML' do
|
170
|
+
BootstrapNavbar.current_url_method = '"/"'
|
171
|
+
subject.menu_item('foo', '/', class: 'bar', id: 'baz').should have_tag(:li, with: { class: 'active bar', id: 'baz' })
|
172
|
+
end
|
173
|
+
end
|
174
|
+
|
175
|
+
context 'with link options' do
|
176
|
+
it 'generates the correct HTML' do
|
177
|
+
BootstrapNavbar.current_url_method = '"/"'
|
178
|
+
subject.menu_item('foo', '/', {}, class: 'pelle', id: 'fant').should have_tag(:li, with: { class: 'active' }) do
|
179
|
+
with_tag :a, with: { href: '/', class: 'pelle', id: 'fant' }, content: 'foo'
|
180
|
+
end
|
181
|
+
end
|
182
|
+
end
|
183
|
+
|
184
|
+
context 'with list item options and link options' do
|
185
|
+
it 'generates the correct HTML' do
|
186
|
+
BootstrapNavbar.current_url_method = '"/"'
|
187
|
+
subject.menu_item('foo', '/', { class: 'bar', id: 'baz' }, class: 'pelle', id: 'fant').should have_tag(:li, with: { class: 'active bar', id: 'baz' }) do
|
188
|
+
with_tag :a, with: { href: '/', class: 'pelle', id: 'fant' }, content: 'foo'
|
189
|
+
end
|
190
|
+
end
|
191
|
+
end
|
192
|
+
end
|
193
|
+
|
194
|
+
context 'without current URL' do
|
195
|
+
it 'generates the correct HTML' do
|
196
|
+
BootstrapNavbar.current_url_method = '"/foo"'
|
197
|
+
subject.menu_item('foo').should have_tag(:li, without: { class: 'active' }) do
|
198
|
+
with_tag :a, with: { href: '#' }, content: 'foo'
|
199
|
+
end
|
200
|
+
subject.menu_item('foo', '/').should have_tag(:li, without: { class: 'active' }) do
|
201
|
+
with_tag :a, with: { href: '/' }, content: 'foo'
|
202
|
+
end
|
203
|
+
subject.menu_item('foo', '/bar').should have_tag(:li, without: { class: 'active' }) do
|
204
|
+
with_tag :a, with: { href: '/bar' }, content: 'foo'
|
205
|
+
end
|
206
|
+
|
207
|
+
BootstrapNavbar.current_url_method = '"/"'
|
208
|
+
subject.menu_item('foo', '/foo').should have_tag(:li, without: { class: 'active' }) do
|
209
|
+
with_tag :a, with: { href: '/foo' }, content: 'foo'
|
210
|
+
end
|
211
|
+
end
|
212
|
+
|
213
|
+
context 'with list item options' do
|
214
|
+
it 'generates the correct HTML' do
|
215
|
+
BootstrapNavbar.current_url_method = '"/foo"'
|
216
|
+
subject.menu_item('foo', '/', class: 'bar', id: 'baz').should have_tag(:li, without: { class: 'active' }, with: { class: 'bar', id: 'baz' })
|
217
|
+
end
|
218
|
+
end
|
219
|
+
end
|
220
|
+
|
221
|
+
context 'with a block' do
|
222
|
+
it 'generates the correct HTML' do
|
223
|
+
subject.menu_item { 'bar' }.should have_tag(:li) do
|
224
|
+
with_tag :a, with: { href: '#' }, content: 'bar'
|
225
|
+
end
|
226
|
+
end
|
227
|
+
|
228
|
+
context 'with list item options' do
|
229
|
+
it 'generates the correct HTML' do
|
230
|
+
subject.menu_item('/foo', class: 'pelle', id: 'fant') { 'bar' }.should have_tag(:li, with: { class: 'pelle', id: 'fant' }) do
|
231
|
+
with_tag :a, with: { href: '/foo' }, content: 'bar'
|
232
|
+
end
|
233
|
+
end
|
234
|
+
end
|
235
|
+
|
236
|
+
context 'with link options' do
|
237
|
+
it 'generates the correct HTML' do
|
238
|
+
subject.menu_item('/foo', {}, class: 'pelle', id: 'fant') { 'bar' }.should have_tag(:li) do
|
239
|
+
with_tag :a, with: { href: '/foo', class: 'pelle', id: 'fant' }, content: 'bar'
|
240
|
+
end
|
241
|
+
end
|
242
|
+
end
|
243
|
+
|
244
|
+
context 'with list item options and link options' do
|
245
|
+
it 'generates the correct HTML' do
|
246
|
+
subject.menu_item('/foo', { class: 'bar', id: 'baz' }, class: 'pelle', id: 'fant') { 'shnoo' }.should have_tag(:li, with: { class: 'bar', id: 'baz' }) do
|
247
|
+
with_tag :a, with: { href: '/foo', class: 'pelle', id: 'fant' }, content: 'shnoo'
|
248
|
+
end
|
249
|
+
end
|
250
|
+
end
|
251
|
+
end
|
252
|
+
end
|
253
|
+
|
254
|
+
context 'drop downs' do
|
255
|
+
def with_drop_down_menu(content = nil)
|
256
|
+
options = { with: { class: 'dropdown-menu' } }
|
257
|
+
options[:content] = content unless content.nil?
|
258
|
+
with_tag :ul, options
|
259
|
+
end
|
260
|
+
|
261
|
+
describe '#drop_down' do
|
262
|
+
it 'generates the correct HTML' do
|
263
|
+
subject.drop_down('foo').should have_tag(:li, with: { class: 'dropdown' }) do
|
264
|
+
with_tag :a, with: { href: '#', class: 'dropdown-toggle', :'data-toggle' => 'dropdown' } do
|
265
|
+
with_text /foo/
|
266
|
+
with_tag :b, with: { class: 'caret' }
|
267
|
+
end
|
268
|
+
with_drop_down_menu
|
269
|
+
end
|
270
|
+
|
271
|
+
subject.drop_down('foo') { 'bar' }.should have_tag(:li, with: { class: 'dropdown' }) do
|
272
|
+
with_tag :a, with: { href: '#', class: 'dropdown-toggle', :'data-toggle' => 'dropdown' } do
|
273
|
+
with_text /foo/
|
274
|
+
with_tag :b, with: { class: 'caret' }
|
275
|
+
end
|
276
|
+
with_drop_down_menu('bar')
|
277
|
+
end
|
278
|
+
end
|
279
|
+
end
|
280
|
+
|
281
|
+
describe '#sub_drop_down' do
|
282
|
+
it 'generates the correct HTML' do
|
283
|
+
subject.sub_drop_down('foo').should have_tag(:li, with: { class: 'dropdown-submenu' }) do
|
284
|
+
with_tag :a, with: { href: '#' }, content: 'foo'
|
285
|
+
with_drop_down_menu
|
286
|
+
end
|
287
|
+
|
288
|
+
subject.sub_drop_down('foo') { 'bar' }.should have_tag(:li, with: { class: 'dropdown-submenu' }) do
|
289
|
+
with_tag :a, with: { href: '#' }, content: 'foo'
|
290
|
+
with_drop_down_menu('bar')
|
291
|
+
end
|
292
|
+
end
|
293
|
+
|
294
|
+
context 'with list item options' do
|
295
|
+
it 'generates the correct HTML' do
|
296
|
+
subject.sub_drop_down('foo', class: 'bar', id: 'baz').should have_tag(:li, with: { class: 'dropdown-submenu bar', id: 'baz' }) do
|
297
|
+
with_tag :a, with: { href: '#' }, content: 'foo'
|
298
|
+
end
|
299
|
+
end
|
300
|
+
end
|
301
|
+
|
302
|
+
context 'with link options' do
|
303
|
+
it 'generates the correct HTML' do
|
304
|
+
subject.sub_drop_down('foo', {}, class: 'pelle', id: 'fant').should have_tag(:li, with: { class: 'dropdown-submenu' }) do
|
305
|
+
with_tag :a, with: { href: '#', class: 'pelle', id: 'fant' }, content: 'foo'
|
306
|
+
end
|
307
|
+
end
|
308
|
+
end
|
309
|
+
|
310
|
+
context 'with list item options and link options' do
|
311
|
+
it 'generates the correct HTML' do
|
312
|
+
subject.sub_drop_down('foo', { class: 'bar', id: 'baz' }, class: 'pelle', id: 'fant').should have_tag(:li, with: { class: 'dropdown-submenu bar', id: 'baz' }) do
|
313
|
+
with_tag :a, with: { href: '#', class: 'pelle', id: 'fant' }, content: 'foo'
|
314
|
+
end
|
315
|
+
end
|
316
|
+
end
|
317
|
+
end
|
318
|
+
end
|
319
|
+
|
320
|
+
describe '#drop_down_divider' do
|
321
|
+
it 'generates the correct HTML' do
|
322
|
+
subject.drop_down_divider.should have_tag(:li, with: { class: 'divider' }, content: '')
|
323
|
+
end
|
324
|
+
end
|
325
|
+
|
326
|
+
describe '#drop_down_header' do
|
327
|
+
it 'generates the correct HTML' do
|
328
|
+
subject.drop_down_header('foo').should have_tag(:li, with: { class: 'nav-header' }, content: 'foo')
|
329
|
+
end
|
330
|
+
end
|
331
|
+
|
332
|
+
describe '#menu_divider' do
|
333
|
+
it 'generates the correct HTML' do
|
334
|
+
subject.menu_divider.should have_tag(:li, with: { class: 'divider-vertical' }, content: '')
|
335
|
+
end
|
336
|
+
end
|
337
|
+
|
338
|
+
describe '#menu_text' do
|
339
|
+
it 'generates the correct HTML' do
|
340
|
+
subject.menu_text('foo').should have_tag(:p, with: { class: 'navbar-text' }, content: 'foo')
|
341
|
+
subject.menu_text { 'foo' }.should have_tag(:p, with: { class: 'navbar-text' }, content: 'foo')
|
342
|
+
subject.menu_text('foo', 'right').should have_tag(:p, with: { class: 'navbar-text pull-right' }, content: 'foo')
|
343
|
+
subject.menu_text(nil, 'left') { 'foo' }.should have_tag(:p, with: { class: 'navbar-text pull-left' }, content: 'foo')
|
344
|
+
end
|
345
|
+
end
|
346
|
+
|
347
|
+
describe '#brand_link' do
|
348
|
+
it 'generates the correct HTML' do
|
349
|
+
subject.brand_link('foo').should have_tag(:a, with: { class: 'brand', href: '/' }, content: 'foo')
|
350
|
+
subject.brand_link('foo', '/foo').should have_tag(:a, with: { class: 'brand', href: '/foo' }, content: 'foo')
|
351
|
+
end
|
352
|
+
end
|
353
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,10 @@
|
|
1
|
+
require 'bootstrap-navbar'
|
2
|
+
require 'rspec-html-matchers'
|
3
|
+
|
4
|
+
RSpec.configure do |config|
|
5
|
+
config.treat_symbols_as_metadata_keys_with_true_values = true
|
6
|
+
config.run_all_when_everything_filtered = true
|
7
|
+
config.filter_run :focus
|
8
|
+
|
9
|
+
config.order = 'random'
|
10
|
+
end
|
metadata
ADDED
@@ -0,0 +1,128 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: bootstrap-navbar
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.13
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Manuel Meurer
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2013-08-05 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: rake
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - '>='
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: 10.0.0
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - '>='
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: 10.0.0
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rspec
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ~>
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: 2.13.0
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ~>
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: 2.13.0
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rspec-html-matchers
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ~>
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: 0.4.3
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ~>
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: 0.4.3
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: guard-rspec
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ~>
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '3.0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ~>
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '3.0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: padrino-helpers
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ~>
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: 0.11.2
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ~>
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: 0.11.2
|
83
|
+
description: Helpers to generate a Twitter Bootstrap style navbar
|
84
|
+
email: manuel.meurer@gmail.com
|
85
|
+
executables: []
|
86
|
+
extensions: []
|
87
|
+
extra_rdoc_files: []
|
88
|
+
files:
|
89
|
+
- .travis.yml
|
90
|
+
- Gemfile
|
91
|
+
- Guardfile
|
92
|
+
- LICENSE.txt
|
93
|
+
- README.md
|
94
|
+
- Rakefile
|
95
|
+
- bootstrap-navbar.gemspec
|
96
|
+
- lib/bootstrap-navbar.rb
|
97
|
+
- lib/bootstrap-navbar/helpers.rb
|
98
|
+
- lib/bootstrap-navbar/version.rb
|
99
|
+
- spec/bootstrap_navbar/helpers_spec.rb
|
100
|
+
- spec/spec_helper.rb
|
101
|
+
homepage: https://github.com/krautcomputing/bootstrap-navbar
|
102
|
+
licenses:
|
103
|
+
- MIT
|
104
|
+
metadata: {}
|
105
|
+
post_install_message:
|
106
|
+
rdoc_options: []
|
107
|
+
require_paths:
|
108
|
+
- lib
|
109
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
110
|
+
requirements:
|
111
|
+
- - '>='
|
112
|
+
- !ruby/object:Gem::Version
|
113
|
+
version: '0'
|
114
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
115
|
+
requirements:
|
116
|
+
- - '>='
|
117
|
+
- !ruby/object:Gem::Version
|
118
|
+
version: '0'
|
119
|
+
requirements: []
|
120
|
+
rubyforge_project:
|
121
|
+
rubygems_version: 2.0.2
|
122
|
+
signing_key:
|
123
|
+
specification_version: 4
|
124
|
+
summary: Helpers to generate a Twitter Bootstrap style navbar
|
125
|
+
test_files:
|
126
|
+
- spec/bootstrap_navbar/helpers_spec.rb
|
127
|
+
- spec/spec_helper.rb
|
128
|
+
has_rdoc:
|