twitter-bootstrap-for-rails 1.3.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (35) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +18 -0
  3. data/Gemfile +4 -0
  4. data/LICENSE.txt +22 -0
  5. data/README.md +694 -0
  6. data/Rakefile +1 -0
  7. data/app/helpers/bootstrap_panel_helper.rb +62 -0
  8. data/app/helpers/breadcrumbs_helper.rb +10 -0
  9. data/app/helpers/dropdown_helper.rb +144 -0
  10. data/app/helpers/flash_block_helper.rb +48 -0
  11. data/app/helpers/form_group_helper.rb +21 -0
  12. data/app/helpers/glyphicon_helper.rb +38 -0
  13. data/app/helpers/modal_dialog_helper.rb +81 -0
  14. data/app/helpers/navbar_helper.rb +234 -0
  15. data/app/helpers/paginator_helper.rb +63 -0
  16. data/app/helpers/resource_table_helper.rb +165 -0
  17. data/app/helpers/title_helper.rb +24 -0
  18. data/app/views/twitter-bootstrap/_breadcrumbs.erb +13 -0
  19. data/lib/bs_form_builder.rb +95 -0
  20. data/lib/form_builder.rb +125 -0
  21. data/lib/helpers.rb +14 -0
  22. data/lib/twitter/bootstrap/for/rails.rb +50 -0
  23. data/lib/twitter/bootstrap/for/rails/breadcrumbs.rb +65 -0
  24. data/lib/twitter/bootstrap/for/rails/version.rb +10 -0
  25. data/twitter-bootstrap-for-rails.gemspec +23 -0
  26. data/vendor/assets/fonts/glyphicons-halflings-regular.eot +0 -0
  27. data/vendor/assets/fonts/glyphicons-halflings-regular.svg +229 -0
  28. data/vendor/assets/fonts/glyphicons-halflings-regular.ttf +0 -0
  29. data/vendor/assets/fonts/glyphicons-halflings-regular.woff +0 -0
  30. data/vendor/assets/javascripts/bootstrap.js +2002 -0
  31. data/vendor/assets/javascripts/bootstrap.min.js +9 -0
  32. data/vendor/assets/javascripts/bs-confirmation-dialog.js.erb +24 -0
  33. data/vendor/assets/stylesheets/bootstrap.css.erb +7098 -0
  34. data/vendor/assets/stylesheets/bootstrap.min.css.erb +9 -0
  35. metadata +105 -0
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
@@ -0,0 +1,62 @@
1
+ require 'helpers'
2
+
3
+ module BootstrapPanelHelper
4
+ def panel(options={}, &block)
5
+ unless block_given?
6
+ raise 'Missing block'
7
+ end
8
+
9
+ panel_options = options.dup
10
+ panel_options[:class] = parse_html_classes_to_arr panel_options[:class]
11
+ panel_options[:class] << 'panel'
12
+
13
+ header = panel_options.delete :header
14
+ title = panel_options.delete :title
15
+ footer = panel_options.delete :footer
16
+ context = panel_options.delete :context
17
+
18
+ unless %w(primary info success warning danger).include? context.to_s
19
+ context = :default
20
+ end
21
+
22
+ panel_options[:class] << "panel-#{context}"
23
+
24
+ content = []
25
+ content << panel_header(header || title)
26
+ content << panel_body(&block)
27
+ content << panel_footer(footer)
28
+
29
+ content_tag :div, content.join("\n").html_safe, panel_options
30
+ end
31
+
32
+ private
33
+ def panel_body(&block)
34
+ content = capture &block
35
+
36
+ content_tag :div, content, class: 'panel-body'
37
+ end
38
+
39
+ def panel_header(header)
40
+ return unless header
41
+
42
+ if header.is_a? Hash
43
+ level = header[:level]
44
+
45
+ unless (1..6).include? level
46
+ level = 1
47
+ end
48
+
49
+ content = content_tag "h#{level}", header[:content], class: 'panel-title'
50
+ else
51
+ content = header
52
+ end
53
+
54
+ content_tag :div, content, class: 'panel-heading'
55
+ end
56
+
57
+ def panel_footer(content)
58
+ if content
59
+ content_tag :div, content, class: 'panel-footer'
60
+ end
61
+ end
62
+ end
@@ -0,0 +1,10 @@
1
+ require 'helpers'
2
+
3
+ module BreadcrumbsHelper
4
+ def render_breadcrumbs(options={})
5
+ br_options = options.dup
6
+ br_options[:class] = parse_html_classes_to_arr br_options[:class]
7
+ br_options[:class] << 'breadcrumb'
8
+ render :partial => 'twitter-bootstrap/breadcrumbs', :layout => false, locals: {options: br_options}
9
+ end
10
+ end
@@ -0,0 +1,144 @@
1
+ module DropdownHelper
2
+ require 'helpers'
3
+
4
+ def dropdown(text, options={}, &block)
5
+ container_options = options.dup
6
+ button_options = container_options.delete(:button) || {}
7
+ menu_options = container_options.delete(:menu) || {}
8
+
9
+ drop_direction = container_options.delete :drop_direction
10
+ container_classes = parse_html_classes_to_arr container_options[:class]
11
+ container_classes << 'btn-group'
12
+
13
+ if drop_direction == :up
14
+ container_classes << 'dropup'
15
+ end
16
+
17
+ container_options[:class] = container_classes
18
+
19
+ content_tag :div, render_dropdown(text, button_options, menu_options, &block), container_options
20
+ end
21
+
22
+ class Dropdown
23
+ include ActionView::Helpers::TagHelper
24
+
25
+ def item(text, link_or_options=nil, options={})
26
+ if link_or_options.is_a? Hash
27
+ link_or_options, options = nil, link_or_options
28
+ end
29
+
30
+ link_or_options ||= '#'
31
+
32
+ content = content_tag :a, text, href: link_or_options
33
+ content_tag :li, content, options
34
+ end
35
+
36
+ def divider(options={})
37
+ classes = parse_html_classes_to_arr options[:class]
38
+ classes << 'divider'
39
+ divider_options = options.dup
40
+ divider_options[:class] = classes
41
+ content_tag :li, '', divider_options
42
+ end
43
+
44
+ def header(text, options={})
45
+ header_options = options.dup
46
+ classes = parse_html_classes_to_arr header_options[:class]
47
+ classes << 'dropdown-header'
48
+ header_options[:class] = classes
49
+
50
+ content_tag :li, text, header_options
51
+ end
52
+ end
53
+
54
+ private
55
+ def render_dropdown(button_text, button_options, menu_options, &block)
56
+ content = []
57
+ content << render_button(button_text, button_options)
58
+ content << render_menu(menu_options, &block)
59
+ content.join("\n").html_safe
60
+ end
61
+
62
+ def btn_regex
63
+ /btn-(?>default|primary|warning|success|info|danger|link)/
64
+ end
65
+
66
+ def render_button(button_text, options={})
67
+ split = options[:split]
68
+
69
+ button_classes = parse_html_classes_to_arr options[:class]
70
+
71
+ unless button_classes.join =~ btn_regex
72
+ button_classes << 'btn-default'
73
+ options[:class] = button_classes
74
+ end
75
+
76
+ if split
77
+ render_split_button button_text, options
78
+ else
79
+ render_single_button button_text, options
80
+ end
81
+ end
82
+
83
+ def get_split_options(button_options)
84
+ split_options =
85
+ case button_options[:split]
86
+ when Hash then button_options[:split]
87
+ else {}
88
+ end
89
+
90
+ classes = parse_html_classes_to_arr split_options[:class]
91
+
92
+ unless classes.join =~ btn_regex
93
+ classes << btn_regex.match(parse_html_classes_to_arr(button_options[:class]).join)
94
+ end
95
+
96
+ classes << 'btn'
97
+ classes << 'dropdown-toggle'
98
+ split_options[:class] = classes
99
+ split_options[:type] = 'button'
100
+ split_options[:data] = { toggle: 'dropdown' }
101
+
102
+ split_options
103
+ end
104
+
105
+ def render_single_button(button_text, options)
106
+ content = []
107
+ content << button_text
108
+ content << caret
109
+
110
+ button_classes = parse_html_classes_to_arr options[:class]
111
+ button_classes << 'btn dropdown-toggle'
112
+ options[:class] = button_classes
113
+ options[:type] = 'button'
114
+ options[:data] = { toggle: 'dropdown' }
115
+
116
+ content_tag :button, content.join("\n").html_safe, options
117
+ end
118
+
119
+ def render_split_button(button_text, options)
120
+ content = []
121
+ split_options = get_split_options(options)
122
+ options.delete :split
123
+
124
+ classes = parse_html_classes_to_arr options[:class]
125
+ classes << 'btn'
126
+ options[:class] = classes
127
+ options[:type] = 'button'
128
+
129
+ content << content_tag(:button, button_text, options)
130
+ content << content_tag(:button, caret, split_options)
131
+ content.join("\n").html_safe
132
+ end
133
+
134
+ def caret
135
+ content_tag :span, '', class: 'caret'
136
+ end
137
+
138
+ def render_menu(options, &block)
139
+ content = capture Dropdown.new, &block
140
+ options[:class] = 'dropdown-menu'
141
+ options[:role] = 'menu'
142
+ content_tag :ul, content, options
143
+ end
144
+ end
@@ -0,0 +1,48 @@
1
+ require 'helpers'
2
+
3
+ module FlashBlockHelper
4
+ def flash_block(options={})
5
+ content = []
6
+
7
+ flash.each do |type, message|
8
+ content << bs_alert(type, message)
9
+ end
10
+
11
+ content_tag :div, content.join("\n").html_safe, options
12
+ end
13
+
14
+ def bs_alert(type, message, options={})
15
+ alert_options = options.dup
16
+ alert_options[:class] = parse_html_classes_to_arr alert_options[:class]
17
+ alert_options[:class] << 'alert'
18
+ alert_options[:class] << 'alert-dismissable'
19
+ alert_options[:class] << alert_class(type)
20
+
21
+ content = []
22
+ content << content_tag(:button, '&times'.html_safe, class: 'close', type: 'button', data: {dismiss: :alert}, aria: {hidden: 'true'})
23
+ content << message
24
+
25
+ content_tag :div, content.join("\n").html_safe, alert_options
26
+ end
27
+
28
+ private
29
+ #Render rules
30
+ #- `:success` render as `.alert-success`;
31
+ #- `:info` render as `.alert-info`;
32
+ #- `:warning` render as `.alert-warning`;
33
+ #- `:danger` render as `.alert-danger`;
34
+ #- `:notice` render as `.alert-success`;
35
+ #- `:alert` render as `.alert-danger`;
36
+ #- another keys render as `alert-info`.
37
+ def alert_class(type)
38
+ act_type =
39
+ case type
40
+ when :success, :notice then :success
41
+ when :danger, :alert then :danger
42
+ when :warning, :info then type
43
+ else :info
44
+ end
45
+
46
+ "alert-#{act_type}"
47
+ end
48
+ end
@@ -0,0 +1,21 @@
1
+ module FormGroupHelper
2
+ # Return a bootstrap form group markup
3
+ def form_group(options = {}, &block)
4
+ form_group_options = options.dup
5
+ classes = split_html_class options[:class]
6
+ classes << :'form-group'
7
+ form_group_options[:class] = classes
8
+ content = capture &block
9
+ content_tag :div, content, form_group_options
10
+ end
11
+
12
+ private
13
+ def split_html_class(classes)
14
+ case classes
15
+ when NilClass then []
16
+ when String then classes.split
17
+ when Array then classes
18
+ when Symbol then [classes]
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,38 @@
1
+ module GlyphiconHelper
2
+ require 'helpers'
3
+
4
+ # Return the Twitter Bootstrap glyphicon html markup
5
+ # Parameter name is the name of icon
6
+ # Parameter options is the hash of additional options generating span
7
+ #
8
+ #
9
+ # invoke
10
+ # glyph :search
11
+ #
12
+ # returns
13
+ # <span class="glyphicon glyphicon-search"></span>
14
+ #
15
+ #
16
+ # invoke
17
+ # glyph :search, class: 'pull-right'
18
+ #
19
+ # returns
20
+ # <span class="pull-right glyphicon glyphicon-search"></span>
21
+ #
22
+ #
23
+ # invoke
24
+ # glyph :search, class: 'pull-right', data: { action: 'search' }
25
+ #
26
+ # returns
27
+ # <span class="pull-right glyphicon glyphicon-search" data-action="search"></span>
28
+ def glyph(name, options={})
29
+ glyph_options = options.dup
30
+ glyph_classes = parse_html_classes_to_arr glyph_options[:class]
31
+ glyph_classes << 'glyphicon'
32
+ glyph_classes << "glyphicon-#{name.to_s.gsub('_', '-')}"
33
+ glyph_options[:class] = glyph_classes
34
+
35
+
36
+ content_tag :span, '', glyph_options
37
+ end
38
+ end
@@ -0,0 +1,81 @@
1
+ require 'helpers'
2
+
3
+ module ModalDialogHelper
4
+ def modal_dialog(options={})
5
+ modal_dialog_options = options.dup
6
+ modal_dialog_options[:class] = parse_html_classes_to_arr modal_dialog_options[:class]
7
+ modal_dialog_options[:class] << 'modal'
8
+ modal_dialog_options[:class] << 'fade'
9
+
10
+ modal_header = modal_dialog_options.delete :header
11
+ modal_body = modal_dialog_options.delete :body
12
+ modal_footer = modal_dialog_options.delete :footer
13
+
14
+ modal_dialog_builder = ModalDialog.new self, modal_header, modal_body, modal_footer
15
+
16
+ content = modal_dialog_builder.render
17
+
18
+ content_tag :div, content, modal_dialog_options
19
+ end
20
+
21
+ def dismiss_button(text, options={})
22
+ #<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
23
+ button_options = options.dup
24
+ button_options[:class] = parse_html_classes_to_arr button_options[:class]
25
+ button_options[:class] << 'btn'
26
+ button_options[:data] ||= {}
27
+ button_options[:data][:dismiss] = 'modal'
28
+
29
+ unless button_options[:class].join =~ /btn-(?>default|primary|warning|success|info|danger|link)/
30
+ button_options[:class] << 'btn-default'
31
+ end
32
+
33
+ content_tag :button, text, button_options
34
+ end
35
+
36
+ class ModalDialog
37
+ attr_accessor :parent, :header, :body, :footer
38
+ delegate :content_tag, to: :parent
39
+
40
+ def initialize(parent, header, body, footer)
41
+ @parent = parent
42
+ @header = header
43
+ @body = body
44
+ @footer = footer
45
+ end
46
+
47
+ def render
48
+ content_tag :div, modal_content_block, class: 'modal-dialog'
49
+ end
50
+
51
+ private
52
+ def modal_content_block
53
+ content = []
54
+ content << modal_header_block
55
+ content << modal_body_block
56
+ content << modal_footer_block
57
+
58
+ content_tag :div, content.join("\n").html_safe, class: 'modal-content'
59
+ end
60
+
61
+ def modal_header_block
62
+ if @header
63
+ content_tag :div, close_button + @header, class: 'modal-header'
64
+ end
65
+ end
66
+
67
+ def close_button
68
+ content_tag :button, '&times'.html_safe, type: 'button', class: 'close', data: {dismiss: 'modal'}, aria: {hidden: 'true'}
69
+ end
70
+
71
+ def modal_body_block
72
+ content_tag :div, @body, class: 'modal-body'
73
+ end
74
+
75
+ def modal_footer_block
76
+ if @footer
77
+ content_tag :div, @footer, class: 'modal-footer'
78
+ end
79
+ end
80
+ end
81
+ end
@@ -0,0 +1,234 @@
1
+ module NavbarHelper
2
+ require 'helpers'
3
+
4
+ def navbar(options={}, &block)
5
+ navbar_options = options.dup
6
+ navbar_options[:class] = parse_html_classes_to_arr navbar_options[:class]
7
+ navbar_options[:class] << 'navbar'
8
+ navbar_options[:class] << 'navbar-default'
9
+ navbar_options[:role] = :navigation
10
+
11
+ fixed = navbar_options.delete(:fixed).to_s
12
+
13
+ if fixed == 'top' || fixed == 'bottom'
14
+ navbar_options[:class] << "navbar-fixed-#{fixed}"
15
+ end
16
+
17
+ static = navbar_options.delete(:static).to_s
18
+
19
+ if static == 'top'
20
+ navbar_options[:class] << 'navbar-static-top'
21
+ end
22
+
23
+ inverse = navbar_options.delete :inverse
24
+
25
+ if inverse == true
26
+ navbar_options[:class] << 'navbar-inverse'
27
+ end
28
+
29
+ brand = navbar_options.delete :brand
30
+
31
+ navbar_id = SecureRandom.hex
32
+
33
+ content = []
34
+ content << render_navbar_header(brand, navbar_id)
35
+ content << render_navbar_body(navbar_id, &block)
36
+
37
+ content_tag :nav, content.join("\n").html_safe, navbar_options
38
+ end
39
+
40
+ def uri_state(uri)
41
+ root_url = request.host_with_port + '/'
42
+ request_uri = request.path[1..-1]
43
+
44
+ uri.gsub(root_url)
45
+
46
+ if uri.start_with? '/'
47
+ uri = uri[1..-1]
48
+ end
49
+
50
+ if uri == request_uri
51
+ return :active
52
+ end
53
+
54
+ uri_parts = uri.split '/'
55
+ request_uri_parts = request_uri.split '/'
56
+
57
+ uri_parts.each_with_index do |uri_part, index|
58
+ if uri_part != request_uri_parts[index]
59
+ return :inactive
60
+ end
61
+ end
62
+
63
+ :chosen
64
+ end
65
+
66
+ class Navbar
67
+ attr_accessor :parent
68
+
69
+ def initialize(parent)
70
+ self.parent = parent
71
+ end
72
+
73
+ delegate :capture, :content_tag, :to => :parent
74
+
75
+ def group(options={}, &block)
76
+ navbar_group_builder = NavbarGroup.new self.parent
77
+ content = capture navbar_group_builder, &block
78
+
79
+ menu_group_options = options.dup
80
+ menu_group_options[:class] = parse_html_classes_to_arr menu_group_options[:class]
81
+ menu_group_options[:class] << 'nav'
82
+ menu_group_options[:class] << 'navbar-nav'
83
+ pull = menu_group_options.delete(:pull).to_s
84
+
85
+ if pull == 'left' || pull == 'right'
86
+ menu_group_options[:class] << "navbar-#{pull}"
87
+ end
88
+
89
+ content_tag :ul, content, menu_group_options
90
+ end
91
+
92
+ def button(text, options={})
93
+ button_options = options.dup
94
+ button_options[:class] = parse_html_classes_to_arr button_options[:class]
95
+ button_options[:class] << 'btn'
96
+ button_options[:class] << 'navbar-btn'
97
+
98
+ unless button_options[:class].join =~ /btn-(?>default|primary|warning|success|info|danger|link)/
99
+ button_options[:class] << 'btn-default'
100
+ end
101
+
102
+ content_tag :button, text, button_options
103
+ end
104
+
105
+ def text(text, options={})
106
+ text_options = options.dup
107
+ text_options[:class] = parse_html_classes_to_arr text_options[:class]
108
+ text_options[:class] << 'navbar-text'
109
+
110
+ pull = text_options.delete(:pull).to_s
111
+
112
+ if pull == 'left' || pull == 'right'
113
+ text_options[:class] << "navbar-#{pull}"
114
+ end
115
+
116
+ content_tag :p, text, text_options
117
+ end
118
+
119
+ def link(text, uri, options={})
120
+ link_options = options.dup
121
+ link_options[:class] = parse_html_classes_to_arr link_options[:class]
122
+ link_options[:class] << 'navbar-link'
123
+ link_options[:href] = uri
124
+
125
+ content_tag :a, text, link_options
126
+ end
127
+ end
128
+
129
+ class NavbarGroup
130
+ attr_accessor :parent
131
+
132
+ def initialize(parent)
133
+ self.parent = parent
134
+ end
135
+
136
+ delegate :capture, :content_tag, :request, :link_to, :uri_state, :to => :parent
137
+
138
+ def item(text, uri, options={})
139
+ menu_item_options = options.dup
140
+ menu_item_options[:class] = parse_html_classes_to_arr menu_item_options[:class]
141
+
142
+ state = uri_state uri
143
+
144
+ if state == :active || state == :chosen
145
+ menu_item_options[:class] << 'active'
146
+ end
147
+
148
+ content = link_to text, uri
149
+ content_tag :li, content, menu_item_options
150
+ end
151
+
152
+ def dropdown(text, options={}, &block)
153
+ dropdown_builder = Dropdown.new self.parent
154
+ content = []
155
+ content << link_to("#{text} #{caret}".html_safe, '#', class: 'dropdown-toggle', data: {toggle: 'dropdown'})
156
+ items = capture dropdown_builder, &block
157
+ content << content_tag(:ul, items, class: 'dropdown-menu')
158
+
159
+ dropdown_options = options.dup
160
+ dropdown_options[:class] = parse_html_classes_to_arr dropdown_options[:class]
161
+ dropdown_options[:class] << 'dropdown'
162
+
163
+ if dropdown_builder.chosen
164
+ dropdown_options[:class] << 'active'
165
+ end
166
+
167
+ content_tag :li, content.join("\n").html_safe, dropdown_options
168
+ end
169
+
170
+ private
171
+ def caret
172
+ content_tag :span, '', class: 'caret'
173
+ end
174
+ end
175
+
176
+ class Dropdown
177
+ attr_accessor :parent, :chosen
178
+
179
+ def initialize(parent)
180
+ self.parent = parent
181
+ @chosen = false
182
+ end
183
+
184
+ delegate :capture, :content_tag, :request, :link_to, :uri_state, :to => :parent
185
+
186
+ def item(text, uri, options={})
187
+ menu_item_options = options.dup
188
+ menu_item_options[:class] = parse_html_classes_to_arr menu_item_options[:class]
189
+
190
+ state = uri_state uri
191
+
192
+ if state == :active || state == :chosen
193
+ menu_item_options[:class] << 'active'
194
+ @chosen = true
195
+ end
196
+
197
+ content = link_to text, uri
198
+ content_tag :li, content, menu_item_options
199
+ end
200
+
201
+ def divider
202
+ content_tag :li, '', class: 'divider'
203
+ end
204
+ end
205
+
206
+ private
207
+ def render_navbar_header(brand, navbar_id)
208
+ content = []
209
+ content << navbar_collapse_button(navbar_id)
210
+
211
+ unless brand.blank?
212
+ content << link_to(brand, root_path, class: 'navbar-brand')
213
+ end
214
+
215
+ content_tag :div, content.join("\n").html_safe, class: 'navbar-header'
216
+ end
217
+
218
+ def navbar_collapse_button(navbar_id)
219
+ content = []
220
+
221
+ 3.times do
222
+ content << content_tag(:span, '', class: 'icon-bar')
223
+ end
224
+
225
+ content_tag :button, content.join("\n").html_safe, type: 'button', class: 'navbar-toggle',
226
+ data: {toggle: 'collapse', target: "##{navbar_id}"}
227
+ end
228
+
229
+ def render_navbar_body(navbar_id, &block)
230
+ navbar_builder = Navbar.new self
231
+ content = capture navbar_builder, &block
232
+ content_tag :div, content, class: 'collapse navbar-collapse', id: navbar_id
233
+ end
234
+ end