padrino-helpers 0.11.2 → 0.11.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.
- data/lib/padrino-helpers.rb +0 -1
- data/lib/padrino-helpers/asset_tag_helpers.rb +2 -2
- data/lib/padrino-helpers/breadcrumb_helpers.rb +54 -24
- data/lib/padrino-helpers/form_builder/abstract_form_builder.rb +8 -3
- data/lib/padrino-helpers/form_helpers.rb +95 -35
- data/lib/padrino-helpers/output_helpers.rb +1 -1
- data/lib/padrino-helpers/tag_helpers.rb +8 -1
- data/test/fixtures/markup_app/views/button_to.erb +8 -0
- data/test/fixtures/markup_app/views/button_to.haml +5 -0
- data/test/fixtures/markup_app/views/button_to.slim +6 -0
- data/test/fixtures/markup_app/views/form_tag.erb +9 -0
- data/test/fixtures/markup_app/views/form_tag.haml +8 -0
- data/test/fixtures/markup_app/views/form_tag.slim +9 -0
- data/test/test_asset_tag_helpers.rb +8 -2
- data/test/test_breadcrumb_helpers.rb +134 -0
- data/test/test_form_builder.rb +33 -0
- data/test/test_form_helpers.rb +214 -8
- data/test/test_tag_helpers.rb +2 -2
- metadata +12 -7
data/lib/padrino-helpers.rb
CHANGED
@@ -182,10 +182,10 @@ module Padrino
|
|
182
182
|
# @return [String] Meta html tag with specified +options+.
|
183
183
|
#
|
184
184
|
# @example
|
185
|
-
# # Generates: <meta name="keywords" content="weblog,news"
|
185
|
+
# # Generates: <meta name="keywords" content="weblog,news" />
|
186
186
|
# meta_tag "weblog,news", :name => "keywords"
|
187
187
|
#
|
188
|
-
# # Generates: <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"
|
188
|
+
# # Generates: <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
|
189
189
|
# meta_tag "text/html; charset=UTF-8", 'http-equiv' => "Content-Type"
|
190
190
|
#
|
191
191
|
# @api public
|
@@ -2,8 +2,7 @@ module Padrino
|
|
2
2
|
module Helpers
|
3
3
|
class Breadcrumb
|
4
4
|
|
5
|
-
attr_accessor :home
|
6
|
-
attr_accessor :items
|
5
|
+
attr_accessor :home, :items
|
7
6
|
|
8
7
|
DEFAULT_URL = "/"
|
9
8
|
DEFAULT_CAPTION ="Home Page"
|
@@ -18,8 +17,7 @@ module Padrino
|
|
18
17
|
#
|
19
18
|
# @api public
|
20
19
|
def initialize
|
21
|
-
|
22
|
-
reset
|
20
|
+
reset!
|
23
21
|
end
|
24
22
|
|
25
23
|
##
|
@@ -31,13 +29,21 @@ module Padrino
|
|
31
29
|
# @param [String] caption
|
32
30
|
# The text caption.
|
33
31
|
#
|
32
|
+
# @param [Hash] options
|
33
|
+
# The HTML options to include in li.
|
34
|
+
#
|
34
35
|
# @example
|
35
|
-
# breadcrumbs.set_home "/HomeFoo", "Foo Home"
|
36
|
+
# breadcrumbs.set_home "/HomeFoo", "Foo Home", :id => "home-breadcrumb"
|
36
37
|
#
|
37
38
|
#
|
38
39
|
# @api public
|
39
|
-
def set_home(url, caption)
|
40
|
-
self.home = {
|
40
|
+
def set_home(url, caption, options = {})
|
41
|
+
self.home = {
|
42
|
+
:url => url.to_s,
|
43
|
+
:caption => caption.to_s.humanize.html_safe,
|
44
|
+
:name => :home,
|
45
|
+
:options => options
|
46
|
+
}
|
41
47
|
reset
|
42
48
|
end
|
43
49
|
|
@@ -49,7 +55,7 @@ module Padrino
|
|
49
55
|
#
|
50
56
|
# @api public
|
51
57
|
def reset
|
52
|
-
self.items=[]
|
58
|
+
self.items = []
|
53
59
|
self.items << home
|
54
60
|
end
|
55
61
|
|
@@ -61,7 +67,12 @@ module Padrino
|
|
61
67
|
#
|
62
68
|
# @api public
|
63
69
|
def reset!
|
64
|
-
self.home = {
|
70
|
+
self.home = {
|
71
|
+
:name => :home,
|
72
|
+
:url => DEFAULT_URL,
|
73
|
+
:caption => DEFAULT_CAPTION,
|
74
|
+
:options => {}
|
75
|
+
}
|
65
76
|
reset
|
66
77
|
end
|
67
78
|
|
@@ -69,23 +80,31 @@ module Padrino
|
|
69
80
|
# Add a new breadcrumbs
|
70
81
|
#
|
71
82
|
# @param [String] name
|
72
|
-
# The name of resource
|
83
|
+
# The name of resource.
|
73
84
|
# @param [Symbol] name
|
74
|
-
# The name of resource
|
85
|
+
# The name of resource.
|
75
86
|
#
|
76
87
|
# @param [String] url
|
77
88
|
# The url href.
|
78
89
|
#
|
79
90
|
# @param [String] caption
|
80
|
-
# The text caption
|
91
|
+
# The text caption.
|
92
|
+
#
|
93
|
+
# @param [Hash] options
|
94
|
+
# The HTML options to include in li.
|
81
95
|
#
|
82
96
|
# @example
|
83
|
-
# breadcrumbs.add "foo", "/foo", "Foo Link"
|
84
|
-
# breadcrumbs.add :foo, "/foo", "Foo Link"
|
97
|
+
# breadcrumbs.add "foo", "/foo", "Foo Link", :id => "foo-id"
|
98
|
+
# breadcrumbs.add :foo, "/foo", "Foo Link", :class => "foo-class"
|
85
99
|
#
|
86
100
|
# @api public
|
87
|
-
def add(name, url, caption)
|
88
|
-
items << {
|
101
|
+
def add(name, url, caption, options = {})
|
102
|
+
items << {
|
103
|
+
:name => name.to_sym,
|
104
|
+
:url => url.to_s,
|
105
|
+
:caption => caption.to_s.humanize.html_safe,
|
106
|
+
:options => options
|
107
|
+
}
|
89
108
|
end
|
90
109
|
|
91
110
|
alias :<< :add
|
@@ -124,26 +143,37 @@ module Padrino
|
|
124
143
|
# @param [String] active
|
125
144
|
# Css class style set to active breadcrumb
|
126
145
|
#
|
146
|
+
# @param [Hash] options
|
147
|
+
# The HTML options to include in ul.
|
148
|
+
#
|
127
149
|
# @return [String] Unordered list with breadcrumbs
|
128
150
|
#
|
129
151
|
# @example
|
130
152
|
# = breadcrumbs @breacrumbs
|
131
153
|
# # Generates:
|
132
154
|
# # <ul>
|
133
|
-
# # <li><a
|
134
|
-
# # <li class="active"
|
155
|
+
# # <li><a href="/foo">Foo Link</a></li>
|
156
|
+
# # <li class="active"><a href="/bar">Bar Link</a></li>
|
135
157
|
# # </ul>
|
136
158
|
#
|
137
159
|
#
|
138
160
|
# @api public
|
139
|
-
def breadcrumbs(breadcrumbs, bootstrap=false, active="active")
|
140
|
-
content=""
|
161
|
+
def breadcrumbs(breadcrumbs, bootstrap = false, active = "active", options = {})
|
162
|
+
content = ""
|
141
163
|
breadcrumbs.items[0..-2].each do |item|
|
142
164
|
content << render_item(item, bootstrap)
|
143
165
|
end
|
144
|
-
last =
|
145
|
-
|
146
|
-
|
166
|
+
last = breadcrumbs.items.last
|
167
|
+
last_options = last[:options]
|
168
|
+
last = link_to(last[:caption], last[:url])
|
169
|
+
|
170
|
+
classes = [options[:class], last_options[:class]].map { |class_name| class_name.to_s.split(/\s/) }
|
171
|
+
classes[0] << "breadcrumb"
|
172
|
+
classes[1] << active if active
|
173
|
+
options[:class], last_options[:class] = classes.map { |class_name| class_name * " " }
|
174
|
+
|
175
|
+
content << safe_content_tag(:li, last, last_options)
|
176
|
+
safe_content_tag(:ul, content, options)
|
147
177
|
end
|
148
178
|
|
149
179
|
private
|
@@ -163,7 +193,7 @@ module Padrino
|
|
163
193
|
content = ""
|
164
194
|
content << link_to(item[:caption], item[:url])
|
165
195
|
content << safe_content_tag(:span, "/", :class => "divider") if bootstrap
|
166
|
-
safe_content_tag(:li, content )
|
196
|
+
safe_content_tag(:li, content, item[:options])
|
167
197
|
end
|
168
198
|
|
169
199
|
end # Breadcrumb
|
@@ -2,7 +2,7 @@ module Padrino
|
|
2
2
|
module Helpers
|
3
3
|
module FormBuilder # @private
|
4
4
|
class AbstractFormBuilder # @private
|
5
|
-
attr_accessor :template, :object
|
5
|
+
attr_accessor :template, :object, :multipart
|
6
6
|
|
7
7
|
def initialize(template, object, options={})
|
8
8
|
@template = template
|
@@ -139,13 +139,16 @@ module Padrino
|
|
139
139
|
|
140
140
|
# f.file_field :photo, :class => 'avatar'
|
141
141
|
def file_field(field, options={})
|
142
|
+
self.multipart = true
|
142
143
|
options.reverse_merge!(:id => field_id(field))
|
143
144
|
options.merge!(:class => field_error(field, options))
|
144
145
|
@template.file_field_tag field_name(field), options
|
145
146
|
end
|
146
147
|
|
147
148
|
# f.submit "Update", :class => 'large'
|
148
|
-
def submit(
|
149
|
+
def submit(*args)
|
150
|
+
options = args[-1].is_a?(Hash) ? args.pop : {}
|
151
|
+
caption = args.length >= 1 ? args.shift : "Submit"
|
149
152
|
@template.submit_tag caption, options
|
150
153
|
end
|
151
154
|
|
@@ -213,7 +216,9 @@ module Padrino
|
|
213
216
|
# field_name(:number) => "user_telephone_attributes_number"
|
214
217
|
# field_name(:street) => "user_addresses_attributes_0_street"
|
215
218
|
def field_id(field=nil, value=nil)
|
216
|
-
result =
|
219
|
+
result = []
|
220
|
+
result << "#{@options[:namespace]}_" if @options[:namespace] && root_form?
|
221
|
+
result << field_result
|
217
222
|
result << field_id_fragment if nested_form?
|
218
223
|
result << "_#{field}" unless field.blank?
|
219
224
|
result << "_#{value}" unless value.blank?
|
@@ -14,7 +14,9 @@ module Padrino
|
|
14
14
|
# @param [String] url
|
15
15
|
# The url this form will submit to.
|
16
16
|
# @param [Hash] settings
|
17
|
-
# The settings associated with this form.
|
17
|
+
# The settings associated with this form.
|
18
|
+
# Accepts a :namespace option that will be prepended to the id attributes of the form's elements.
|
19
|
+
# Also accepts html options.
|
18
20
|
# @option settings [String] :builder ("StandardFormBuilder")
|
19
21
|
# The FormBuilder class to use such as StandardFormBuilder.
|
20
22
|
# @param [Proc] block
|
@@ -32,6 +34,8 @@ module Padrino
|
|
32
34
|
def form_for(object, url, settings={}, &block)
|
33
35
|
instance = builder_instance(object, settings)
|
34
36
|
html = capture_html(instance, &block)
|
37
|
+
settings[:multipart] = instance.multipart unless settings.include?(:multipart)
|
38
|
+
settings.delete(:namespace)
|
35
39
|
form_tag(url, settings) { html }
|
36
40
|
end
|
37
41
|
|
@@ -79,13 +83,19 @@ module Padrino
|
|
79
83
|
def form_tag(url, options={}, &block)
|
80
84
|
desired_method = options[:method].to_s
|
81
85
|
options.delete(:method) unless desired_method =~ /get|post/i
|
82
|
-
options.reverse_merge!(:method => 'post',
|
86
|
+
options.reverse_merge!(:method => 'post',
|
87
|
+
:action => url,
|
88
|
+
:protect_from_csrf => is_protected_from_csrf? )
|
83
89
|
options[:enctype] = 'multipart/form-data' if options.delete(:multipart)
|
84
90
|
options['accept-charset'] ||= 'UTF-8'
|
85
91
|
inner_form_html = hidden_form_method_field(desired_method)
|
86
|
-
|
92
|
+
if options[:protect_from_csrf] == true && !(desired_method =~ /get/i)
|
93
|
+
inner_form_html << csrf_token_field
|
94
|
+
end
|
87
95
|
inner_form_html << mark_safe(capture_html(&block))
|
88
|
-
|
96
|
+
not_concat = options.delete(:not_concat)
|
97
|
+
form_html = content_tag(:form, inner_form_html, options)
|
98
|
+
not_concat ? form_html : concat_content(form_html)
|
89
99
|
end
|
90
100
|
|
91
101
|
##
|
@@ -251,7 +261,7 @@ module Padrino
|
|
251
261
|
error = if defined?(Ohm::Model) && object.is_a?(Ohm::Model)
|
252
262
|
I18n.t("ohm.errors.messages.#{error[0]}", :default => error[0].to_s)
|
253
263
|
else
|
254
|
-
# Array(error).first is necessary because some ORMs
|
264
|
+
# Array(error).first is necessary because some ORMs
|
255
265
|
# give us an array others directly a value
|
256
266
|
Array(error)[0]
|
257
267
|
end
|
@@ -347,13 +357,13 @@ module Padrino
|
|
347
357
|
#
|
348
358
|
# @example
|
349
359
|
# text_field_tag :first_name, :maxlength => 40, :required => true
|
350
|
-
# # => <input name="first_name" maxlength="40" required type="text"
|
360
|
+
# # => <input name="first_name" maxlength="40" required type="text" />
|
351
361
|
#
|
352
362
|
# text_field_tag :last_name, :class => 'string', :size => 40
|
353
|
-
# # => <input name="last_name" class="string" size="40" type="text"
|
363
|
+
# # => <input name="last_name" class="string" size="40" type="text" />
|
354
364
|
#
|
355
365
|
# text_field_tag :username, :placeholder => 'Your Username'
|
356
|
-
# # => <input name="username" placeholder="Your Username" type="text"
|
366
|
+
# # => <input name="username" placeholder="Your Username" type="text" />
|
357
367
|
#
|
358
368
|
# @api public
|
359
369
|
def text_field_tag(name, options={})
|
@@ -409,16 +419,16 @@ module Padrino
|
|
409
419
|
#
|
410
420
|
# @example
|
411
421
|
# number_field_tag :quanity, :class => 'numeric'
|
412
|
-
# # => <input name="quanity" class="numeric" type="number"
|
422
|
+
# # => <input name="quanity" class="numeric" type="number" />
|
413
423
|
#
|
414
424
|
# number_field_tag :zip_code, :pattern => /[0-9]{5}/
|
415
|
-
# # => <input name="zip_code" pattern="[0-9]{5}" type="number"
|
425
|
+
# # => <input name="zip_code" pattern="[0-9]{5}" type="number" />
|
416
426
|
#
|
417
427
|
# number_field_tag :credit_card, :autocomplete => :off
|
418
|
-
# # => <input name="credit_card" autocomplete="off" type="number"
|
428
|
+
# # => <input name="credit_card" autocomplete="off" type="number" />
|
419
429
|
#
|
420
430
|
# number_field_tag :age, :min => 18, :max => 120, :step => 1
|
421
|
-
# # => <input name="age" min="18" max="120" step="1" type="number"
|
431
|
+
# # => <input name="age" min="18" max="120" step="1" type="number" />
|
422
432
|
#
|
423
433
|
# @api public
|
424
434
|
def number_field_tag(name, options={})
|
@@ -432,15 +442,15 @@ module Padrino
|
|
432
442
|
#
|
433
443
|
# @example
|
434
444
|
# telephone_field_tag :phone_number, :class => 'string'
|
435
|
-
# # => <input name="phone_number" class="string" type="tel"
|
445
|
+
# # => <input name="phone_number" class="string" type="tel" />
|
436
446
|
#
|
437
447
|
# telephone_field_tag :cell_phone, :tabindex => 1
|
438
448
|
# telephone_field_tag :work_phone, :tabindex => 2
|
439
449
|
# telephone_field_tag :home_phone, :tabindex => 3
|
440
450
|
#
|
441
|
-
# # => <input name="cell_phone" tabindex="1" type="tel"
|
442
|
-
# # => <input name="work_phone" tabindex="2" type="tel"
|
443
|
-
# # => <input name="home_phone" tabindex="3" type="tel"
|
451
|
+
# # => <input name="cell_phone" tabindex="1" type="tel" />
|
452
|
+
# # => <input name="work_phone" tabindex="2" type="tel" />
|
453
|
+
# # => <input name="home_phone" tabindex="3" type="tel" />
|
444
454
|
#
|
445
455
|
# @api public
|
446
456
|
def telephone_field_tag(name, options={})
|
@@ -455,10 +465,10 @@ module Padrino
|
|
455
465
|
#
|
456
466
|
# @example
|
457
467
|
# email_field_tag :email, :placeholder => 'you@example.com'
|
458
|
-
# # => <input name="email" placeholder="you@example.com" type="email"
|
468
|
+
# # => <input name="email" placeholder="you@example.com" type="email" />
|
459
469
|
#
|
460
470
|
# email_field_tag :email, :value => 'padrinorb@gmail.com', :readonly => true
|
461
|
-
# # => <input name="email" value="padrinorb@gmail.com" readonly type="email"
|
471
|
+
# # => <input name="email" value="padrinorb@gmail.com" readonly type="email" />
|
462
472
|
#
|
463
473
|
# @api public
|
464
474
|
def email_field_tag(name, options={})
|
@@ -472,16 +482,16 @@ module Padrino
|
|
472
482
|
#
|
473
483
|
# @example
|
474
484
|
# search_field_tag :search, :placeholder => 'Search this website...'
|
475
|
-
# # => <input name="search" placeholder="Search this website..." type="search"
|
485
|
+
# # => <input name="search" placeholder="Search this website..." type="search" />
|
476
486
|
#
|
477
487
|
# search_field_tag :search, :maxlength => 15, :class => ['search', 'string']
|
478
|
-
# # => <input name="search" maxlength="15" class="search string"
|
488
|
+
# # => <input name="search" maxlength="15" class="search string" />
|
479
489
|
#
|
480
490
|
# search_field_tag :search, :id => 'search'
|
481
|
-
# # => <input name="search" id="search" type="search"
|
491
|
+
# # => <input name="search" id="search" type="search" />
|
482
492
|
#
|
483
493
|
# search_field_tag :search, :autofocus => true
|
484
|
-
# # => <input name="search" autofocus type="search"
|
494
|
+
# # => <input name="search" autofocus type="search" />
|
485
495
|
#
|
486
496
|
# @api public
|
487
497
|
def search_field_tag(name, options={})
|
@@ -495,10 +505,10 @@ module Padrino
|
|
495
505
|
#
|
496
506
|
# @example
|
497
507
|
# url_field_tag :favorite_website, :placeholder => 'http://padrinorb.com'
|
498
|
-
# <input name="favorite_website" placeholder="http://padrinorb.com." type="url"
|
508
|
+
# <input name="favorite_website" placeholder="http://padrinorb.com." type="url" />
|
499
509
|
#
|
500
510
|
# url_field_tag :home_page, :class => 'string url'
|
501
|
-
# <input name="home_page" class="string url", type="url"
|
511
|
+
# <input name="home_page" class="string url", type="url" />
|
502
512
|
#
|
503
513
|
# @api public
|
504
514
|
def url_field_tag(name, options={})
|
@@ -668,7 +678,7 @@ module Padrino
|
|
668
678
|
##
|
669
679
|
# Constructs a submit button from the given options
|
670
680
|
#
|
671
|
-
# @param [String] caption
|
681
|
+
# @param [String] caption (defaults to: +Submit+)
|
672
682
|
# The caption for the submit button.
|
673
683
|
# @param [Hash] options
|
674
684
|
# The html options for the input field.
|
@@ -677,9 +687,12 @@ module Padrino
|
|
677
687
|
#
|
678
688
|
# @example
|
679
689
|
# submit_tag "Create", :class => 'success'
|
690
|
+
# submit_tag :class => 'btn'
|
680
691
|
#
|
681
692
|
# @api public
|
682
|
-
def submit_tag(
|
693
|
+
def submit_tag(*args)
|
694
|
+
options = args[-1].is_a?(Hash) ? args.pop : {}
|
695
|
+
caption = args.length >= 1 ? args.shift : "Submit"
|
683
696
|
options.reverse_merge!(:value => caption)
|
684
697
|
input_tag(:submit, options)
|
685
698
|
end
|
@@ -758,12 +771,40 @@ module Padrino
|
|
758
771
|
if block_given?
|
759
772
|
form_tag(url, options, &block)
|
760
773
|
else
|
761
|
-
form_tag(url, options) do
|
774
|
+
form_tag(url, options.merge!(:not_concat => true)) do
|
762
775
|
submit_tag(name)
|
763
776
|
end
|
764
777
|
end
|
765
778
|
end
|
766
779
|
|
780
|
+
##
|
781
|
+
# Constructs a range tag from the given options
|
782
|
+
#
|
783
|
+
# @example
|
784
|
+
# range_field_tag('ranger_with_min_max', :min => 1, :max => 50)
|
785
|
+
# range_field_tag('ranger_with_range', :range => 1..5)
|
786
|
+
#
|
787
|
+
# @param [String] name
|
788
|
+
# The name of the range field.
|
789
|
+
# @param [Hash] options
|
790
|
+
# The html options for the range field.
|
791
|
+
# @option options [Integer] :min
|
792
|
+
# The min range of the range field
|
793
|
+
# @option options [Integer] :max
|
794
|
+
# The max range of the range field
|
795
|
+
# @option options [range] :range
|
796
|
+
# The range, in lieu of :min and :max. See examples for details
|
797
|
+
# @return [String] The html range field
|
798
|
+
#
|
799
|
+
# @api public
|
800
|
+
def range_field_tag(name, options = {})
|
801
|
+
options.reverse_merge!(:name => name)
|
802
|
+
if range = options.delete(:range)
|
803
|
+
options[:min], options[:max] = range.min, range.max
|
804
|
+
end
|
805
|
+
input_tag(:range, options)
|
806
|
+
end
|
807
|
+
|
767
808
|
protected
|
768
809
|
|
769
810
|
##
|
@@ -779,9 +820,10 @@ module Padrino
|
|
779
820
|
#
|
780
821
|
def options_for_select(option_items, selected_value=nil)
|
781
822
|
return [] if option_items.blank?
|
782
|
-
option_items.map do |caption, value|
|
823
|
+
option_items.map do |caption, value, disabled|
|
783
824
|
value ||= caption
|
784
|
-
|
825
|
+
disabled ||= false
|
826
|
+
content_tag(:option, caption, :value => value, :selected => option_is_selected?(value, caption, selected_value), :disabled => disabled)
|
785
827
|
end
|
786
828
|
end
|
787
829
|
|
@@ -791,15 +833,23 @@ module Padrino
|
|
791
833
|
def grouped_options_for_select(collection, selected=nil, prompt=false)
|
792
834
|
if collection.is_a?(Hash)
|
793
835
|
collection.map do |key, value|
|
794
|
-
|
795
|
-
|
796
|
-
|
836
|
+
# Hash format:
|
837
|
+
# {:first => [1,2,3], :second => [4,5,6]}
|
838
|
+
# or:
|
839
|
+
# {:first => [[1,2,3], {:disabled => true}], :second => [4,5,6]}
|
840
|
+
attributes_hash = value.last.is_a?(Hash) ? value.pop : nil
|
841
|
+
disabled ||= attributes_hash && attributes_hash.include?(:disabled) ? attributes_hash[:disabled] : false
|
842
|
+
content_tag :optgroup, options_for_select(value, selected), :label => key, :disabled => disabled
|
797
843
|
end
|
798
844
|
elsif collection.is_a?(Array)
|
845
|
+
# Array format:
|
846
|
+
# ["Option Label", [:option1, :option2, ...]]
|
847
|
+
# or:
|
848
|
+
# ["Option Label", [:option1, :option2, ...], true]
|
849
|
+
# the last item tells if it is disabled or not. This is keeps it backwards compatible.
|
799
850
|
collection.map do |optgroup|
|
800
|
-
|
801
|
-
|
802
|
-
end
|
851
|
+
disabled ||= optgroup.count > 2 ? optgroup.pop : false
|
852
|
+
content_tag :optgroup, options_for_select(optgroup.last, selected), :label => optgroup.first, :disabled => disabled
|
803
853
|
end
|
804
854
|
end
|
805
855
|
end
|
@@ -857,6 +907,16 @@ module Padrino
|
|
857
907
|
[value.to_s, caption.to_s].include?(selected.to_s)
|
858
908
|
end
|
859
909
|
end
|
910
|
+
|
911
|
+
##
|
912
|
+
# Returns whether the application is being protected from csrf
|
913
|
+
#
|
914
|
+
def is_protected_from_csrf?
|
915
|
+
return true unless defined? app
|
916
|
+
return true unless app.respond_to?(:protect_from_csrf)
|
917
|
+
return true if app.protect_from_csrf == nil
|
918
|
+
app.protect_from_csrf
|
919
|
+
end
|
860
920
|
end # FormHelpers
|
861
921
|
end # Helpers
|
862
922
|
end # Padrino
|
@@ -42,7 +42,7 @@ module Padrino
|
|
42
42
|
# @example
|
43
43
|
# ActiveSupport::SafeBuffer.new + capture_html { "<foo>" }
|
44
44
|
# # => "<foo>"
|
45
|
-
# ActiveSupport::SafeBuffer.safe_concat
|
45
|
+
# ActiveSupport::SafeBuffer.new.safe_concat(capture_html { "<foo>" })
|
46
46
|
# # => "<foo>"
|
47
47
|
#
|
48
48
|
# @api semipublic
|
@@ -8,6 +8,7 @@ module Padrino
|
|
8
8
|
# Tag values escaped to html entities
|
9
9
|
#
|
10
10
|
ESCAPE_VALUES = {
|
11
|
+
"&" => "&",
|
11
12
|
"<" => "<",
|
12
13
|
">" => ">",
|
13
14
|
'"' => """
|
@@ -31,7 +32,13 @@ module Padrino
|
|
31
32
|
:muted,
|
32
33
|
:readonly,
|
33
34
|
:required,
|
34
|
-
:selected
|
35
|
+
:selected,
|
36
|
+
:declare,
|
37
|
+
:defer,
|
38
|
+
:ismap,
|
39
|
+
:itemscope,
|
40
|
+
:noresize,
|
41
|
+
:novalidate
|
35
42
|
]
|
36
43
|
|
37
44
|
##
|
@@ -0,0 +1,8 @@
|
|
1
|
+
<% button_to 'Foo button', '/foo', :class => 'foo-form' do %>
|
2
|
+
<% field_set_tag do %>
|
3
|
+
<%= hidden_field_tag :session_id, :value => "__secret__" %>
|
4
|
+
<%= label_tag :username %>
|
5
|
+
<% end %>
|
6
|
+
<% end %>
|
7
|
+
<%= content_tag(:p, 'button_to test', :id => 'test-point') %>
|
8
|
+
<%= button_to 'Bar button', '/bar' %>
|
@@ -19,6 +19,8 @@
|
|
19
19
|
<%= label_tag :gender %>
|
20
20
|
<%= label_tag :color %>
|
21
21
|
<%= select_tag :color, :options => ['green', 'orange', 'purple'] %>
|
22
|
+
<%= select_tag :type, :grouped_options => { 'foo' => ['foo', 'bar'], 'bar' => ['foo', 'bar'] } %>
|
23
|
+
<%= select_tag :character, :grouped_options => [['Friends',['Yoda',['Obiwan',1]]],['Enemies',['Palpatine',['Darth Vader',3]]]] %>
|
22
24
|
<%= radio_button_tag :gender, :value => 'male' %>
|
23
25
|
<%= radio_button_tag :gender, :value => 'female' %>
|
24
26
|
<%= submit_tag %>
|
@@ -77,6 +79,10 @@
|
|
77
79
|
<p>
|
78
80
|
<%= check_box_tag :remember_me, :value => '1', :checked => true %>
|
79
81
|
<p>
|
82
|
+
<p>
|
83
|
+
<%= range_field_tag('ranger_with_min_max', :min => 1, :max => 50) %>
|
84
|
+
<%= range_field_tag('ranger_with_range', :range => 1..5) %>
|
85
|
+
</p>
|
80
86
|
<% end %>
|
81
87
|
<% field_set_tag(:class => 'buttons') do %>
|
82
88
|
<%= submit_tag "Login" %>
|
@@ -84,3 +90,6 @@
|
|
84
90
|
<%= image_submit_tag "buttons/submit.png" %>
|
85
91
|
<% end %>
|
86
92
|
<% end %>
|
93
|
+
|
94
|
+
<% form_tag '/dontprotect', :class => 'no-protection', :protect_from_csrf => false do %>
|
95
|
+
<% end %>
|
@@ -18,6 +18,8 @@
|
|
18
18
|
= search_field_tag :search
|
19
19
|
= label_tag :color
|
20
20
|
= select_tag :color, :options => ['green', 'orange', 'purple']
|
21
|
+
= select_tag :type, :grouped_options => { 'foo' => ['foo', 'bar'], 'bar' => ['foo', 'bar'] }
|
22
|
+
= select_tag :character, :grouped_options => [['Friends',['Yoda',['Obiwan',1]]],['Enemies',['Palpatine',['Darth Vader',3]]]]
|
21
23
|
= label_tag :gender
|
22
24
|
= radio_button_tag :gender, :value => 'male'
|
23
25
|
= radio_button_tag :gender, :value => 'female'
|
@@ -64,7 +66,13 @@
|
|
64
66
|
= select_tag :fav_color, :options => [ ['green', '1'], ['orange', '2'], ['purple', '3'] ], :selected => '2'
|
65
67
|
%p
|
66
68
|
= check_box_tag :remember_me, :value => "1", :checked => true
|
69
|
+
%p
|
70
|
+
= range_field_tag('ranger_with_min_max', :min => 1, :max => 50)
|
71
|
+
= range_field_tag('ranger_with_range', :range => 1..5)
|
67
72
|
- field_set_tag(:class => 'buttons') do
|
68
73
|
= submit_tag "Login"
|
69
74
|
= button_tag "Cancel"
|
70
75
|
= image_submit_tag "buttons/submit.png"
|
76
|
+
|
77
|
+
- form_tag '/dontprotect', :class => 'no-protection', :protect_from_csrf => false do
|
78
|
+
= submit_tag "Login"
|
@@ -18,6 +18,8 @@
|
|
18
18
|
= search_field_tag :search
|
19
19
|
= label_tag :color
|
20
20
|
= select_tag :color, :options => ['green', 'orange', 'purple']
|
21
|
+
= select_tag :type, :grouped_options => { 'foo' => ['foo', 'bar'], 'bar' => ['foo', 'bar'] }
|
22
|
+
= select_tag :character, :grouped_options => [['Friends',['Yoda',['Obiwan',1]]],['Enemies',['Palpatine',['Darth Vader',3]]]]
|
21
23
|
= label_tag :gender
|
22
24
|
= radio_button_tag :gender, :value => 'male'
|
23
25
|
= radio_button_tag :gender, :value => 'female'
|
@@ -64,7 +66,14 @@
|
|
64
66
|
= select_tag :fav_color, :options => [ ['green', '1'], ['orange', '2'], ['purple', '3'] ], :selected => '2'
|
65
67
|
p
|
66
68
|
= check_box_tag :remember_me, :value => "1", :checked => true
|
69
|
+
p
|
70
|
+
= range_field_tag('ranger_with_min_max', :min => 1, :max => 50)
|
71
|
+
= range_field_tag('ranger_with_range', :range => 1..5)
|
72
|
+
|
67
73
|
= field_set_tag(:class => 'buttons') do
|
68
74
|
= submit_tag "Login"
|
69
75
|
= button_tag "Cancel"
|
70
76
|
= image_submit_tag "buttons/submit.png"
|
77
|
+
|
78
|
+
= form_tag '/dontprotect', :class => 'no-protection', :protect_from_csrf => false do
|
79
|
+
= submit_tag "Login"
|
@@ -71,9 +71,9 @@ describe "AssetTagHelpers" do
|
|
71
71
|
end
|
72
72
|
|
73
73
|
should "escape the link text" do
|
74
|
-
actual_link = link_to('/register', :class => 'first', :id => 'binky') { "
|
74
|
+
actual_link = link_to('/register', :class => 'first', :id => 'binky') { "<&>" }
|
75
75
|
assert_has_tag('a#binky.first', :href => '/register') { actual_link }
|
76
|
-
assert_match "<>", actual_link
|
76
|
+
assert_match "<&>", actual_link
|
77
77
|
end
|
78
78
|
|
79
79
|
should "not escape image_tag" do
|
@@ -119,6 +119,12 @@ describe "AssetTagHelpers" do
|
|
119
119
|
assert_match %r{subject\=demo\%20test}, actual_html
|
120
120
|
end
|
121
121
|
|
122
|
+
should "escape & with encoded string and & in HTML" do
|
123
|
+
actual_html = mail_to('test@demo.com', "My&Email", :subject => "this&that")
|
124
|
+
assert_match 'this%26that', actual_html
|
125
|
+
assert_match 'My&Email', actual_html
|
126
|
+
end
|
127
|
+
|
122
128
|
should "display mail link element in haml" do
|
123
129
|
visit '/haml/mail_to'
|
124
130
|
assert_have_selector 'p.simple a', :href => 'mailto:test@demo.com', :content => 'test@demo.com'
|
@@ -0,0 +1,134 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/helper')
|
2
|
+
|
3
|
+
describe "BreadcrumbHelpers" do
|
4
|
+
include Padrino::Helpers::Breadcrumbs
|
5
|
+
|
6
|
+
def breadcrumb
|
7
|
+
@breadcrumb ||= Padrino::Helpers::Breadcrumb.new
|
8
|
+
end
|
9
|
+
|
10
|
+
before(:each) { breadcrumb.reset! }
|
11
|
+
|
12
|
+
context "for Breadcrumbs#breadcrumbs method" do
|
13
|
+
should "support breadcrumbs which is Padrino::Helpers::Breadcrumbs instance." do
|
14
|
+
breadcrumb.add "foo", "/foo", "foo link"
|
15
|
+
assert_has_tag(:a, :content => "Foo link", :href => "/foo") { breadcrumbs(breadcrumb) }
|
16
|
+
end
|
17
|
+
|
18
|
+
should "support bootstrap" do
|
19
|
+
breadcrumb.add "foo", "/foo", "foo link"
|
20
|
+
assert_has_tag(:span, :content => "/", :class => "divider") { breadcrumbs(breadcrumb, true) }
|
21
|
+
end
|
22
|
+
|
23
|
+
should "support active" do
|
24
|
+
breadcrumb.add "foo", "/foo", "foo link"
|
25
|
+
assert_has_tag(:li, :class => "custom-active") { breadcrumbs(breadcrumb, nil, "custom-active") }
|
26
|
+
end
|
27
|
+
|
28
|
+
should "support options" do
|
29
|
+
assert_has_tag(:ul, :class => "breadcrumbs-class breadcrumb", :id => "breadcrumbs-id") do
|
30
|
+
breadcrumbs(breadcrumb, nil, nil, :id => "breadcrumbs-id", :class => "breadcrumbs-class")
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
context "for #add method" do
|
36
|
+
should "support name of string and symbol type" do
|
37
|
+
breadcrumb.add "foo", "/foo", "Foo Link"
|
38
|
+
breadcrumb.add :bar, "/bar", "Bar Link"
|
39
|
+
|
40
|
+
actual_html = breadcrumbs(breadcrumb)
|
41
|
+
assert_has_tag(:a, :content => "Foo link", :href => "/foo") { actual_html }
|
42
|
+
assert_has_tag(:a, :content => "Bar link", :href => "/bar") { actual_html }
|
43
|
+
end
|
44
|
+
|
45
|
+
should "support url" do
|
46
|
+
breadcrumb.add :foo, "/foo", "Foo Link"
|
47
|
+
assert_has_tag(:a, :href => "/foo") { breadcrumbs(breadcrumb) }
|
48
|
+
end
|
49
|
+
|
50
|
+
should "support caption" do
|
51
|
+
breadcrumb.add :foo, "/foo", "Foo Link"
|
52
|
+
assert_has_tag(:a, :content => "Foo link") { breadcrumbs(breadcrumb) }
|
53
|
+
end
|
54
|
+
|
55
|
+
should "support options" do
|
56
|
+
breadcrumb.add :foo, "/foo", "Foo Link", :id => "foo-id", :class => "foo-class"
|
57
|
+
breadcrumb.add :bar, "/bar", "Bar Link", :id => "bar-id", :class => "bar-class"
|
58
|
+
|
59
|
+
actual_html = breadcrumbs(breadcrumb)
|
60
|
+
assert_has_tag(:li, :class => "foo-class", :id => "foo-id") { actual_html }
|
61
|
+
assert_has_tag(:li, :class => "bar-class active", :id => "bar-id") { actual_html }
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
context "for #del method" do
|
66
|
+
should "support name of string type" do
|
67
|
+
breadcrumb.add "foo", "/foo", "Foo Link"
|
68
|
+
breadcrumb.add :bar, "/bar", "Bar Link"
|
69
|
+
|
70
|
+
breadcrumb.del "foo"
|
71
|
+
breadcrumb.del "bar"
|
72
|
+
|
73
|
+
actual_html = breadcrumbs(breadcrumb)
|
74
|
+
assert_has_no_tag(:a, :content => "Foo link", :href => "/foo") { actual_html }
|
75
|
+
assert_has_no_tag(:a, :content => "Bar link", :href => "/bar") { actual_html }
|
76
|
+
end
|
77
|
+
|
78
|
+
should "support name of symbol type" do
|
79
|
+
breadcrumb.add "foo", "/foo", "Foo Link"
|
80
|
+
breadcrumb.add :bar, "/bar", "Bar Link"
|
81
|
+
|
82
|
+
breadcrumb.del :foo
|
83
|
+
breadcrumb.del :bar
|
84
|
+
|
85
|
+
actual_html = breadcrumbs(breadcrumb)
|
86
|
+
assert_has_no_tag(:a, :content => "Foo link", :href => "/foo") { actual_html }
|
87
|
+
assert_has_no_tag(:a, :content => "Bar link", :href => "/bar") { actual_html }
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
context "for #set_home method" do
|
92
|
+
should "modified home item elements." do
|
93
|
+
breadcrumb.set_home("/custom", "Custom Home Page")
|
94
|
+
assert_has_tag(:a, :content => "Custom home page", :href => "/custom") { breadcrumbs(breadcrumb) }
|
95
|
+
end
|
96
|
+
|
97
|
+
should "support options" do
|
98
|
+
breadcrumb.set_home("/custom", "Custom Home Page", :id => "home-id")
|
99
|
+
|
100
|
+
actual_html = breadcrumbs(breadcrumb)
|
101
|
+
assert_has_tag(:li, :id => "home-id") { actual_html }
|
102
|
+
assert_has_tag(:a, :content => "Custom home page", :href => "/custom") { actual_html }
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
context "for #reset method" do
|
107
|
+
should "be #items which contains only home item." do
|
108
|
+
breadcrumb.set_home("/custom", "Custom Home Page")
|
109
|
+
breadcrumb.add "foo", "/foo", "Foo Link"
|
110
|
+
breadcrumb.add :bar, "/bar", "Bar Link"
|
111
|
+
|
112
|
+
breadcrumb.reset
|
113
|
+
|
114
|
+
actual_html = breadcrumbs(breadcrumb)
|
115
|
+
assert_has_tag(:a, :content => "Custom home page", :href => "/custom") { actual_html }
|
116
|
+
assert_has_no_tag(:a, :content => "Foo link", :href => "/foo") { actual_html }
|
117
|
+
assert_has_no_tag(:a, :content => "Bar link", :href => "/bar") { actual_html }
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
context "for #reset! method" do
|
122
|
+
should "be #items which contains only default home item." do
|
123
|
+
breadcrumb.add "foo", "/foo", "foo link"
|
124
|
+
breadcrumb.add :bar, "/bar", "Bar Link"
|
125
|
+
|
126
|
+
breadcrumb.reset!
|
127
|
+
|
128
|
+
actual_html = breadcrumbs(breadcrumb)
|
129
|
+
assert_has_tag(:a, :content => "Home Page", :href => "/") { actual_html }
|
130
|
+
assert_has_no_tag(:a, :content => "Foo link", :href => "/foo") { actual_html }
|
131
|
+
assert_has_no_tag(:a, :content => "Bar link", :href => "/bar") { actual_html }
|
132
|
+
end
|
133
|
+
end
|
134
|
+
end
|
data/test/test_form_builder.rb
CHANGED
@@ -61,6 +61,16 @@ describe "FormBuilder" do
|
|
61
61
|
assert_has_tag('form', :"accept-charset" => "UTF-8", :action => '/update', :method => 'post', "data-remote" => 'true') { actual_html }
|
62
62
|
end
|
63
63
|
|
64
|
+
should "display correct form html with namespace option" do
|
65
|
+
actual_html = form_for(@user, '/update', :namespace => 'foo') do |f|
|
66
|
+
f.text_field(:first_name) << f.fields_for(:role_types) { |role| role.text_field(:name) }
|
67
|
+
end
|
68
|
+
|
69
|
+
assert_has_no_tag(:form, :namespace => 'foo') { actual_html }
|
70
|
+
assert_has_tag(:input, :type => 'text', :name => 'user[first_name]', :id => 'foo_user_first_name') { actual_html }
|
71
|
+
assert_has_tag(:input, :type => 'text', :name => 'user[role_types_attributes][0][name]', :id => 'foo_user_role_types_attributes_0_name') { actual_html }
|
72
|
+
end
|
73
|
+
|
64
74
|
should "display correct form html with remote option and method put" do
|
65
75
|
actual_html = form_for(@user, '/update', :"accept-charset" => "UTF-8", :remote => true, :method => 'put') { "Demo" }
|
66
76
|
assert_has_tag('form', :"accept-charset" => "UTF-8", :method => 'post', "data-remote" => 'true') { actual_html }
|
@@ -655,6 +665,17 @@ describe "FormBuilder" do
|
|
655
665
|
assert_have_selector '#demo input.user-photo', :type => 'file', :name => 'markup_user[photo]', :id => 'markup_user_photo'
|
656
666
|
assert_have_selector '#demo2 input.upload', :type => 'file', :name => 'markup_user[photo]', :id => 'markup_user_photo'
|
657
667
|
end
|
668
|
+
|
669
|
+
should "display correct form html with multipart, even if no 'multipart' option is specified" do
|
670
|
+
actual_html = form_for(@user, '/register', :"accept-charset" => "UTF-8") { |f| f.file_field :photo }
|
671
|
+
assert_has_tag('form', :"accept-charset" => "UTF-8", :action => '/register', :enctype => "multipart/form-data") { actual_html }
|
672
|
+
end
|
673
|
+
|
674
|
+
should "display correct form html without multipart, if 'multipart' option is specified 'false'" do
|
675
|
+
actual_html = form_for(@user, '/register', :"accept-charset" => "UTF-8", :multipart => false) { |f| f.file_field :photo }
|
676
|
+
assert_has_no_tag('form', :"accept-charset" => "UTF-8", :action => '/register', :enctype => "multipart/form-data") { actual_html }
|
677
|
+
end
|
678
|
+
|
658
679
|
end
|
659
680
|
|
660
681
|
context 'for #select method' do
|
@@ -742,6 +763,18 @@ describe "FormBuilder" do
|
|
742
763
|
assert_has_tag('input[type=submit]', :value => "Submit") { actual_html }
|
743
764
|
end
|
744
765
|
|
766
|
+
|
767
|
+
should "display correct submit button html with no caption" do
|
768
|
+
actual_html = standard_builder.submit(:class => 'btn')
|
769
|
+
assert_has_tag('input.btn[type=submit]', :value => "Submit") { actual_html }
|
770
|
+
end
|
771
|
+
|
772
|
+
should "display correct submit button html with nil caption" do
|
773
|
+
actual_html = standard_builder.submit(nil, :class => 'btn')
|
774
|
+
assert_has_tag('input.btn[type=submit]') { actual_html }
|
775
|
+
assert actual_html !~ %r{ value \* = }x
|
776
|
+
end
|
777
|
+
|
745
778
|
should "display correct submit button html" do
|
746
779
|
actual_html = standard_builder.submit("Commit", :class => 'large')
|
747
780
|
assert_has_tag('input.large[type=submit]', :value => "Commit") { actual_html }
|
data/test/test_form_helpers.rb
CHANGED
@@ -9,6 +9,8 @@ describe "FormHelpers" do
|
|
9
9
|
end
|
10
10
|
|
11
11
|
context 'for #form_tag method' do
|
12
|
+
after(:each) { app.set :protect_from_csrf, true }
|
13
|
+
|
12
14
|
should "display correct forms in ruby" do
|
13
15
|
actual_html = form_tag('/register', :"accept-charset" => "UTF-8", :class => 'test', :method => "post") { "Demo" }
|
14
16
|
assert_has_tag(:form, :"accept-charset" => "UTF-8", :class => "test") { actual_html }
|
@@ -54,25 +56,62 @@ describe "FormHelpers" do
|
|
54
56
|
assert_has_tag(:form, :enctype => "multipart/form-data") { actual_html }
|
55
57
|
end
|
56
58
|
|
59
|
+
should "have an authenticity_token for method :post, :put or :delete" do
|
60
|
+
%w(post put delete).each do |method|
|
61
|
+
actual_html = form_tag('/modify', :method => method) { "Demo" }
|
62
|
+
assert_has_tag(:input, :name => 'authenticity_token') { actual_html }
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
should "not have an authenticity_token if method: :get" do
|
67
|
+
actual_html = form_tag('/get', :method => :get) { "Demo" }
|
68
|
+
assert_has_no_tag(:input, :name => 'authenticity_token') { actual_html }
|
69
|
+
end
|
70
|
+
|
71
|
+
should "have an authenticity_token by default" do
|
72
|
+
actual_html = form_tag('/superadmindelete') { "Demo" }
|
73
|
+
assert_has_tag(:input, :name => 'authenticity_token') { actual_html }
|
74
|
+
end
|
75
|
+
|
76
|
+
should "not have an authenticity_token if passing protect_from_csrf: false" do
|
77
|
+
actual_html = form_tag('/superadmindelete', :protect_from_csrf => false) { "Demo" }
|
78
|
+
assert_has_no_tag(:input, :name => 'authenticity_token') { actual_html }
|
79
|
+
end
|
80
|
+
|
81
|
+
should "have an authenticity_token if protect_from_csrf is not set on app settings" do
|
82
|
+
app.set :protect_from_csrf, nil
|
83
|
+
actual_html = form_tag('/superadmindelete') { "Demo" }
|
84
|
+
assert_has_tag(:input, :name => 'authenticity_token') { actual_html }
|
85
|
+
end
|
86
|
+
|
87
|
+
should "not have an authenticity_token if protect_from_csrf is false on app settings" do
|
88
|
+
app.set :protect_from_csrf, false
|
89
|
+
actual_html = form_tag('/superadmindelete') { "Demo" }
|
90
|
+
assert_has_no_tag(:input, :name => 'authenticity_token') { actual_html }
|
91
|
+
end
|
92
|
+
|
57
93
|
should "display correct forms in erb" do
|
58
94
|
visit '/erb/form_tag'
|
59
95
|
assert_have_selector 'form.simple-form', :action => '/simple'
|
60
96
|
assert_have_selector 'form.advanced-form', :action => '/advanced', :id => 'advanced', :method => 'get'
|
61
|
-
assert_have_selector
|
97
|
+
assert_have_selector 'form.simple-form input', :name => 'authenticity_token'
|
98
|
+
assert_have_no_selector 'form.no-protection input', :name => 'authenticity_token'
|
62
99
|
end
|
63
100
|
|
64
101
|
should "display correct forms in haml" do
|
65
102
|
visit '/haml/form_tag'
|
66
103
|
assert_have_selector 'form.simple-form', :action => '/simple'
|
67
104
|
assert_have_selector 'form.advanced-form', :action => '/advanced', :id => 'advanced', :method => 'get'
|
68
|
-
assert_have_selector
|
105
|
+
assert_have_selector 'form.simple-form input', :name => 'authenticity_token'
|
106
|
+
assert_have_no_selector 'form.no-protection input', :name => 'authenticity_token'
|
69
107
|
end
|
70
108
|
|
71
109
|
should "display correct forms in slim" do
|
72
110
|
visit '/slim/form_tag'
|
73
111
|
assert_have_selector 'form.simple-form', :action => '/simple'
|
74
112
|
assert_have_selector 'form.advanced-form', :action => '/advanced', :id => 'advanced', :method => 'get'
|
75
|
-
assert_have_selector
|
113
|
+
assert_have_selector 'form.simple-form input', :name => 'authenticity_token'
|
114
|
+
assert_have_no_selector 'form.no-protection input', :name => 'authenticity_token'
|
76
115
|
end
|
77
116
|
end
|
78
117
|
|
@@ -611,7 +650,7 @@ describe "FormHelpers" do
|
|
611
650
|
assert_has_tag('select option:first-child', :value => "", :content => "") { actual_html }
|
612
651
|
end
|
613
652
|
|
614
|
-
should "
|
653
|
+
should "display select tag with grouped options for a nested array" do
|
615
654
|
opts = [
|
616
655
|
["Friends",["Yoda",["Obiwan",2]]],
|
617
656
|
["Enemies", ["Palpatine",['Darth Vader',3]]]
|
@@ -626,7 +665,33 @@ describe "FormHelpers" do
|
|
626
665
|
assert_has_tag(:option, :value => "3", :content => "Darth Vader") { actual_html }
|
627
666
|
end
|
628
667
|
|
629
|
-
should "
|
668
|
+
should "display select tag with grouped options for a nested array and accept disabled groups" do
|
669
|
+
opts = [
|
670
|
+
["Friends",["Yoda",["Obiwan",2]]],
|
671
|
+
["Enemies", ["Palpatine",['Darth Vader',3]], true]
|
672
|
+
]
|
673
|
+
actual_html = select_tag( 'name', :grouped_options => opts )
|
674
|
+
assert_has_tag(:select, :name => "name") { actual_html }
|
675
|
+
assert_has_tag(:option, :disabled => 'disabled', :count => 0) { actual_html }
|
676
|
+
assert_has_tag(:optgroup, :disabled => 'disabled', :count => 1) { actual_html }
|
677
|
+
assert_has_tag(:optgroup, :label => "Enemies", :disabled => 'disabled') { actual_html }
|
678
|
+
end
|
679
|
+
|
680
|
+
should "display select tag with grouped options for a nested array and accept disabled groups and/or with disabled options" do
|
681
|
+
opts = [
|
682
|
+
["Friends",["Yoda",["Obiwan",2, true]]],
|
683
|
+
["Enemies", [["Palpatine", "Palpatine", true],['Darth Vader',3]], true]
|
684
|
+
]
|
685
|
+
actual_html = select_tag( 'name', :grouped_options => opts )
|
686
|
+
assert_has_tag(:select, :name => "name") { actual_html }
|
687
|
+
assert_has_tag(:option, :disabled => 'disabled', :count => 2) { actual_html }
|
688
|
+
assert_has_tag(:optgroup, :disabled => 'disabled', :count => 1) { actual_html }
|
689
|
+
assert_has_tag(:option, :content => "Obiwan", :disabled => 'disabled') { actual_html }
|
690
|
+
assert_has_tag(:optgroup, :label => "Enemies", :disabled => 'disabled') { actual_html }
|
691
|
+
assert_has_tag(:option, :value => "Palpatine", :content => "Palpatine", :disabled => 'disabled') { actual_html }
|
692
|
+
end
|
693
|
+
|
694
|
+
should "display select tag with grouped options for a hash" do
|
630
695
|
opts = {
|
631
696
|
"Friends" => ["Yoda",["Obiwan",2]],
|
632
697
|
"Enemies" => ["Palpatine",['Darth Vader',3]]
|
@@ -641,6 +706,33 @@ describe "FormHelpers" do
|
|
641
706
|
assert_has_tag(:option, :value => "3", :content => "Darth Vader") { actual_html }
|
642
707
|
end
|
643
708
|
|
709
|
+
should "display select tag with grouped options for a hash and accept disabled groups" do
|
710
|
+
opts = {
|
711
|
+
"Friends" => ["Yoda",["Obiwan",2]],
|
712
|
+
"Enemies" => ["Palpatine",['Darth Vader',3], {:disabled => true}]
|
713
|
+
}
|
714
|
+
actual_html = select_tag( 'name', :grouped_options => opts )
|
715
|
+
assert_has_tag(:select, :name => "name") { actual_html }
|
716
|
+
assert_has_tag(:option, :disabled => 'disabled', :count => 0) { actual_html }
|
717
|
+
assert_has_tag(:optgroup, :disabled => 'disabled', :count => 1) { actual_html }
|
718
|
+
assert_has_tag(:optgroup, :label => "Enemies", :disabled => 'disabled') { actual_html }
|
719
|
+
end
|
720
|
+
|
721
|
+
should "display select tag with grouped options for a hash and accept disabled groups and/or with disabled options" do
|
722
|
+
opts = {
|
723
|
+
"Friends" => ["Yoda",["Obiwan",2,true]],
|
724
|
+
"Enemies" => [["Palpatine","Palpatine",true],["Darth Vader",3], {:disabled => true}]
|
725
|
+
}
|
726
|
+
actual_html = select_tag( 'name', :grouped_options => opts )
|
727
|
+
assert_has_tag(:select, :name => "name") { actual_html }
|
728
|
+
assert_has_tag(:option, :disabled => 'disabled', :count => 2) { actual_html }
|
729
|
+
assert_has_tag(:optgroup, :disabled => 'disabled', :count => 1) { actual_html }
|
730
|
+
assert_has_tag(:option, :content => "Obiwan", :disabled => 'disabled') { actual_html }
|
731
|
+
assert_has_tag(:optgroup, :label => "Enemies", :disabled => 'disabled') { actual_html }
|
732
|
+
assert_has_tag(:option, :value => "Palpatine", :content => "Palpatine", :disabled => 'disabled') { actual_html }
|
733
|
+
end
|
734
|
+
|
735
|
+
|
644
736
|
should "display select tag in ruby with multiple attribute" do
|
645
737
|
actual_html = select_tag(:favorite_color, :multiple => true, :options => ['only', 'option'])
|
646
738
|
assert_has_tag(:select, :multiple => 'multiple', :name => 'favorite_color[]') { actual_html }
|
@@ -656,6 +748,16 @@ describe "FormHelpers" do
|
|
656
748
|
assert_has_tag('select option', :content => 'Black', :value => 'black1') { actual_html }
|
657
749
|
end
|
658
750
|
|
751
|
+
should "display options with values and accept disabled options" do
|
752
|
+
options = [['Green', 'green1', true], ['Blue', 'blue1'], ['Black', "black1"]]
|
753
|
+
actual_html = select_tag(:favorite_color, :options => options)
|
754
|
+
assert_has_tag(:select, :name => 'favorite_color') { actual_html }
|
755
|
+
assert_has_tag('select option', :disabled => 'disabled', :count => 1) { actual_html }
|
756
|
+
assert_has_tag('select option', :content => 'Green', :value => 'green1', :disabled => 'disabled') { actual_html }
|
757
|
+
assert_has_tag('select option', :content => 'Blue', :value => 'blue1') { actual_html }
|
758
|
+
assert_has_tag('select option', :content => 'Black', :value => 'black1') { actual_html }
|
759
|
+
end
|
760
|
+
|
659
761
|
should "display option with values and multiple selected" do
|
660
762
|
options = [['Green', 'green1'], ['Blue', 'blue1'], ['Black', "black1"]]
|
661
763
|
actual_html = select_tag(:favorite_color, :options => options, :selected => ['green1', 'Black'])
|
@@ -680,10 +782,20 @@ describe "FormHelpers" do
|
|
680
782
|
assert_have_selector('select option', :content => 'green', :value => 'green')
|
681
783
|
assert_have_selector('select option', :content => 'orange', :value => 'orange')
|
682
784
|
assert_have_selector('select option', :content => 'purple', :value => 'purple')
|
683
|
-
assert_have_selector
|
785
|
+
assert_have_selector('form.advanced-form select', :name => 'fav_color')
|
684
786
|
assert_have_selector('select option', :content => 'green', :value => '1')
|
685
787
|
assert_have_selector('select option', :content => 'orange', :value => '2', :selected => 'selected')
|
686
788
|
assert_have_selector('select option', :content => 'purple', :value => '3')
|
789
|
+
assert_have_selector('select optgroup', :label => 'foo')
|
790
|
+
assert_have_selector('select optgroup', :label => 'bar')
|
791
|
+
assert_have_selector('select optgroup option', :content => 'foo', :value => 'foo')
|
792
|
+
assert_have_selector('select optgroup option', :content => 'bar', :value => 'bar')
|
793
|
+
assert_have_selector('select optgroup', :label => 'Friends')
|
794
|
+
assert_have_selector('select optgroup', :label => 'Enemies')
|
795
|
+
assert_have_selector('select optgroup option', :content => 'Yoda', :value => 'Yoda')
|
796
|
+
assert_have_selector('select optgroup option', :content => 'Obiwan', :value => '1')
|
797
|
+
assert_have_selector('select optgroup option', :content => 'Palpatine', :value => 'Palpatine')
|
798
|
+
assert_have_selector('select optgroup option', :content => 'Darth Vader', :value => '3')
|
687
799
|
end
|
688
800
|
|
689
801
|
should "display select tag in haml" do
|
@@ -692,10 +804,20 @@ describe "FormHelpers" do
|
|
692
804
|
assert_have_selector('select option', :content => 'green', :value => 'green')
|
693
805
|
assert_have_selector('select option', :content => 'orange', :value => 'orange')
|
694
806
|
assert_have_selector('select option', :content => 'purple', :value => 'purple')
|
695
|
-
assert_have_selector
|
807
|
+
assert_have_selector('form.advanced-form select', :name => 'fav_color')
|
696
808
|
assert_have_selector('select option', :content => 'green', :value => '1')
|
697
809
|
assert_have_selector('select option', :content => 'orange', :value => '2', :selected => 'selected')
|
698
810
|
assert_have_selector('select option', :content => 'purple', :value => '3')
|
811
|
+
assert_have_selector('select optgroup', :label => 'foo')
|
812
|
+
assert_have_selector('select optgroup', :label => 'bar')
|
813
|
+
assert_have_selector('select optgroup option', :content => 'foo', :value => 'foo')
|
814
|
+
assert_have_selector('select optgroup option', :content => 'bar', :value => 'bar')
|
815
|
+
assert_have_selector('select optgroup', :label => 'Friends')
|
816
|
+
assert_have_selector('select optgroup', :label => 'Enemies')
|
817
|
+
assert_have_selector('select optgroup option', :content => 'Yoda', :value => 'Yoda')
|
818
|
+
assert_have_selector('select optgroup option', :content => 'Obiwan', :value => '1')
|
819
|
+
assert_have_selector('select optgroup option', :content => 'Palpatine', :value => 'Palpatine')
|
820
|
+
assert_have_selector('select optgroup option', :content => 'Darth Vader', :value => '3')
|
699
821
|
end
|
700
822
|
|
701
823
|
should "display select tag in slim" do
|
@@ -704,10 +826,20 @@ describe "FormHelpers" do
|
|
704
826
|
assert_have_selector('select option', :content => 'green', :value => 'green')
|
705
827
|
assert_have_selector('select option', :content => 'orange', :value => 'orange')
|
706
828
|
assert_have_selector('select option', :content => 'purple', :value => 'purple')
|
707
|
-
assert_have_selector
|
829
|
+
assert_have_selector('form.advanced-form select', :name => 'fav_color')
|
708
830
|
assert_have_selector('select option', :content => 'green', :value => '1')
|
709
831
|
assert_have_selector('select option', :content => 'orange', :value => '2', :selected => 'selected')
|
710
832
|
assert_have_selector('select option', :content => 'purple', :value => '3')
|
833
|
+
assert_have_selector('select optgroup', :label => 'foo')
|
834
|
+
assert_have_selector('select optgroup', :label => 'bar')
|
835
|
+
assert_have_selector('select optgroup option', :content => 'foo', :value => 'foo')
|
836
|
+
assert_have_selector('select optgroup option', :content => 'bar', :value => 'bar')
|
837
|
+
assert_have_selector('select optgroup', :label => 'Friends')
|
838
|
+
assert_have_selector('select optgroup', :label => 'Enemies')
|
839
|
+
assert_have_selector('select optgroup option', :content => 'Yoda', :value => 'Yoda')
|
840
|
+
assert_have_selector('select optgroup option', :content => 'Obiwan', :value => '1')
|
841
|
+
assert_have_selector('select optgroup option', :content => 'Palpatine', :value => 'Palpatine')
|
842
|
+
assert_have_selector('select optgroup option', :content => 'Darth Vader', :value => '3')
|
711
843
|
end
|
712
844
|
end
|
713
845
|
|
@@ -734,6 +866,26 @@ describe "FormHelpers" do
|
|
734
866
|
assert_have_selector 'form.simple-form input[type=submit]', :count => 1, :value => "Submit"
|
735
867
|
assert_have_selector 'form.advanced-form input[type=submit]', :count => 1, :value => "Login"
|
736
868
|
end
|
869
|
+
|
870
|
+
context 'for omitted args' do
|
871
|
+
should "display submit tag with default caption" do
|
872
|
+
actual_html = submit_tag()
|
873
|
+
assert_has_tag(:input, :type => 'submit', :value => 'Submit') { actual_html }
|
874
|
+
end
|
875
|
+
end
|
876
|
+
|
877
|
+
context 'for omitted caption arg' do
|
878
|
+
should "display submit tag with default caption" do
|
879
|
+
actual_html = submit_tag(:class => 'success')
|
880
|
+
assert_has_tag(:input, :type => 'submit', :class => 'success', :value => 'Submit') { actual_html }
|
881
|
+
end
|
882
|
+
|
883
|
+
should "display submit tag without caption value when nil" do
|
884
|
+
actual_html = submit_tag(nil, :class => 'success')
|
885
|
+
assert_has_tag(:input, :type => 'submit', :class => 'success') { actual_html }
|
886
|
+
assert_has_no_tag(:input, :type => 'submit', :class => 'success', :value => 'Submit') { actual_html }
|
887
|
+
end
|
888
|
+
end
|
737
889
|
end
|
738
890
|
|
739
891
|
context 'for #button_tag method' do
|
@@ -808,5 +960,59 @@ describe "FormHelpers" do
|
|
808
960
|
end
|
809
961
|
assert_has_tag('form button', :type => 'submit', :content => "My button's content", :title => "My button") { actual_html }
|
810
962
|
end
|
963
|
+
|
964
|
+
should 'display correct button_to in erb' do
|
965
|
+
visit '/erb/button_to'
|
966
|
+
assert_have_selector('form', :action => '/foo')
|
967
|
+
assert_have_selector('form label', :for => 'username', :content => 'Username: ')
|
968
|
+
assert_have_selector('form', :action => '/bar')
|
969
|
+
assert_have_selector('#test-point ~ form > input[type=submit]', :value => 'Bar button')
|
970
|
+
end
|
971
|
+
|
972
|
+
should 'display correct button_to in haml' do
|
973
|
+
visit '/haml/button_to'
|
974
|
+
assert_have_selector('form', :action => '/foo')
|
975
|
+
assert_have_selector('form label', :for => 'username', :content => 'Username: ')
|
976
|
+
assert_have_selector('form', :action => '/bar')
|
977
|
+
assert_have_selector('#test-point ~ form > input[type=submit]', :value => 'Bar button')
|
978
|
+
end
|
979
|
+
|
980
|
+
should 'display correct button_to in slim' do
|
981
|
+
visit '/slim/button_to'
|
982
|
+
assert_have_selector('form', :action => '/foo')
|
983
|
+
assert_have_selector('form label', :for => 'username', :content => 'Username: ')
|
984
|
+
assert_have_selector('form', :action => '/bar')
|
985
|
+
assert_have_selector('#test-point ~ form > input[type=submit]', :value => 'Bar button')
|
986
|
+
end
|
987
|
+
end
|
988
|
+
|
989
|
+
context 'for #range_field_tag' do
|
990
|
+
should "create an input tag with min and max options" do
|
991
|
+
actual_html = range_field_tag('ranger', :min => 20, :max => 50)
|
992
|
+
assert_has_tag('input', :type => 'range', :name => 'ranger', :min => '20', :max => '50') { actual_html }
|
993
|
+
end
|
994
|
+
|
995
|
+
should "create an input tag with range" do
|
996
|
+
actual_html = range_field_tag('ranger', :range => 1..20)
|
997
|
+
assert_has_tag('input', :min => '1', :max => '20') { actual_html }
|
998
|
+
end
|
999
|
+
|
1000
|
+
should "display correct range_field_tag in erb" do
|
1001
|
+
visit '/erb/form_tag'
|
1002
|
+
assert_have_selector 'input', :type => 'range', :name => 'ranger_with_min_max', :min => '1', :max => '50', :count => 1
|
1003
|
+
assert_have_selector 'input', :type => 'range', :name => 'ranger_with_range', :min => '1', :max => '5', :count => 1
|
1004
|
+
end
|
1005
|
+
|
1006
|
+
should "display correct range_field_tag in haml" do
|
1007
|
+
visit '/haml/form_tag'
|
1008
|
+
assert_have_selector 'input', :type => 'range', :name => 'ranger_with_min_max', :min => '1', :max => '50', :count => 1
|
1009
|
+
assert_have_selector 'input', :type => 'range', :name => 'ranger_with_range', :min => '1', :max => '5', :count => 1
|
1010
|
+
end
|
1011
|
+
|
1012
|
+
should "display correct range_field_tag in slim" do
|
1013
|
+
visit '/slim/form_tag'
|
1014
|
+
assert_have_selector 'input', :type => 'range', :name => 'ranger_with_min_max', :min => '1', :max => '50', :count => 1
|
1015
|
+
assert_have_selector 'input', :type => 'range', :name => 'ranger_with_range', :min => '1', :max => '5', :count => 1
|
1016
|
+
end
|
811
1017
|
end
|
812
1018
|
end
|
data/test/test_tag_helpers.rb
CHANGED
@@ -37,8 +37,8 @@ describe "TagHelpers" do
|
|
37
37
|
end
|
38
38
|
|
39
39
|
should "escape html" do
|
40
|
-
actual_html = tag(:br, :class => 'Example "bar"')
|
41
|
-
assert_equal "<br class=\"Example "bar"\" />", actual_html
|
40
|
+
actual_html = tag(:br, :class => 'Example <foo> & "bar"')
|
41
|
+
assert_equal "<br class=\"Example <foo> & "bar"\" />", actual_html
|
42
42
|
end
|
43
43
|
end
|
44
44
|
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: padrino-helpers
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.11.
|
4
|
+
version: 0.11.3
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -12,7 +12,7 @@ authors:
|
|
12
12
|
autorequire:
|
13
13
|
bindir: bin
|
14
14
|
cert_chain: []
|
15
|
-
date: 2013-
|
15
|
+
date: 2013-07-29 00:00:00.000000000 Z
|
16
16
|
dependencies:
|
17
17
|
- !ruby/object:Gem::Dependency
|
18
18
|
name: padrino-core
|
@@ -21,7 +21,7 @@ dependencies:
|
|
21
21
|
requirements:
|
22
22
|
- - '='
|
23
23
|
- !ruby/object:Gem::Version
|
24
|
-
version: 0.11.
|
24
|
+
version: 0.11.3
|
25
25
|
type: :runtime
|
26
26
|
prerelease: false
|
27
27
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -29,7 +29,7 @@ dependencies:
|
|
29
29
|
requirements:
|
30
30
|
- - '='
|
31
31
|
- !ruby/object:Gem::Version
|
32
|
-
version: 0.11.
|
32
|
+
version: 0.11.3
|
33
33
|
- !ruby/object:Gem::Dependency
|
34
34
|
name: i18n
|
35
35
|
requirement: !ruby/object:Gem::Requirement
|
@@ -99,6 +99,9 @@ files:
|
|
99
99
|
- lib/padrino-helpers/translation_helpers.rb
|
100
100
|
- padrino-helpers.gemspec
|
101
101
|
- test/fixtures/markup_app/app.rb
|
102
|
+
- test/fixtures/markup_app/views/button_to.erb
|
103
|
+
- test/fixtures/markup_app/views/button_to.haml
|
104
|
+
- test/fixtures/markup_app/views/button_to.slim
|
102
105
|
- test/fixtures/markup_app/views/capture_concat.erb
|
103
106
|
- test/fixtures/markup_app/views/capture_concat.haml
|
104
107
|
- test/fixtures/markup_app/views/capture_concat.slim
|
@@ -151,6 +154,7 @@ files:
|
|
151
154
|
- test/fixtures/render_app/views/template/some_template.haml
|
152
155
|
- test/helper.rb
|
153
156
|
- test/test_asset_tag_helpers.rb
|
157
|
+
- test/test_breadcrumb_helpers.rb
|
154
158
|
- test/test_form_builder.rb
|
155
159
|
- test/test_form_helpers.rb
|
156
160
|
- test/test_format_helpers.rb
|
@@ -172,9 +176,6 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
172
176
|
- - ! '>='
|
173
177
|
- !ruby/object:Gem::Version
|
174
178
|
version: '0'
|
175
|
-
segments:
|
176
|
-
- 0
|
177
|
-
hash: -1875793301041170039
|
178
179
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
179
180
|
none: false
|
180
181
|
requirements:
|
@@ -189,6 +190,9 @@ specification_version: 3
|
|
189
190
|
summary: Helpers for padrino
|
190
191
|
test_files:
|
191
192
|
- test/fixtures/markup_app/app.rb
|
193
|
+
- test/fixtures/markup_app/views/button_to.erb
|
194
|
+
- test/fixtures/markup_app/views/button_to.haml
|
195
|
+
- test/fixtures/markup_app/views/button_to.slim
|
192
196
|
- test/fixtures/markup_app/views/capture_concat.erb
|
193
197
|
- test/fixtures/markup_app/views/capture_concat.haml
|
194
198
|
- test/fixtures/markup_app/views/capture_concat.slim
|
@@ -241,6 +245,7 @@ test_files:
|
|
241
245
|
- test/fixtures/render_app/views/template/some_template.haml
|
242
246
|
- test/helper.rb
|
243
247
|
- test/test_asset_tag_helpers.rb
|
248
|
+
- test/test_breadcrumb_helpers.rb
|
244
249
|
- test/test_form_builder.rb
|
245
250
|
- test/test_form_helpers.rb
|
246
251
|
- test/test_format_helpers.rb
|