actionview 5.2.4.4 → 6.1.1
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of actionview might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/CHANGELOG.md +221 -93
- data/MIT-LICENSE +1 -1
- data/README.rdoc +5 -3
- data/lib/action_view.rb +7 -2
- data/lib/action_view/base.rb +81 -15
- data/lib/action_view/buffers.rb +15 -0
- data/lib/action_view/cache_expiry.rb +52 -0
- data/lib/action_view/context.rb +5 -9
- data/lib/action_view/dependency_tracker.rb +10 -4
- data/lib/action_view/digestor.rb +15 -22
- data/lib/action_view/flows.rb +0 -1
- data/lib/action_view/gem_version.rb +4 -4
- data/lib/action_view/helpers.rb +0 -2
- data/lib/action_view/helpers/active_model_helper.rb +0 -1
- data/lib/action_view/helpers/asset_tag_helper.rb +63 -46
- data/lib/action_view/helpers/asset_url_helper.rb +9 -6
- data/lib/action_view/helpers/atom_feed_helper.rb +2 -1
- data/lib/action_view/helpers/cache_helper.rb +23 -22
- data/lib/action_view/helpers/capture_helper.rb +4 -0
- data/lib/action_view/helpers/csp_helper.rb +4 -2
- data/lib/action_view/helpers/csrf_helper.rb +1 -1
- data/lib/action_view/helpers/date_helper.rb +73 -30
- data/lib/action_view/helpers/form_helper.rb +305 -37
- data/lib/action_view/helpers/form_options_helper.rb +23 -23
- data/lib/action_view/helpers/form_tag_helper.rb +19 -16
- data/lib/action_view/helpers/javascript_helper.rb +12 -11
- data/lib/action_view/helpers/number_helper.rb +14 -8
- data/lib/action_view/helpers/output_safety_helper.rb +1 -1
- data/lib/action_view/helpers/rendering_helper.rb +17 -7
- data/lib/action_view/helpers/sanitize_helper.rb +12 -18
- data/lib/action_view/helpers/tag_helper.rb +98 -22
- data/lib/action_view/helpers/tags/base.rb +18 -11
- data/lib/action_view/helpers/tags/check_box.rb +0 -1
- data/lib/action_view/helpers/tags/collection_check_boxes.rb +0 -1
- data/lib/action_view/helpers/tags/collection_helpers.rb +0 -1
- data/lib/action_view/helpers/tags/collection_radio_buttons.rb +0 -1
- data/lib/action_view/helpers/tags/color_field.rb +1 -2
- data/lib/action_view/helpers/tags/date_field.rb +1 -2
- data/lib/action_view/helpers/tags/date_select.rb +2 -3
- data/lib/action_view/helpers/tags/datetime_field.rb +0 -1
- data/lib/action_view/helpers/tags/datetime_local_field.rb +1 -2
- data/lib/action_view/helpers/tags/label.rb +4 -1
- data/lib/action_view/helpers/tags/month_field.rb +1 -2
- data/lib/action_view/helpers/tags/radio_button.rb +0 -1
- data/lib/action_view/helpers/tags/select.rb +1 -2
- data/lib/action_view/helpers/tags/text_field.rb +0 -1
- data/lib/action_view/helpers/tags/time_field.rb +1 -2
- data/lib/action_view/helpers/tags/translator.rb +1 -6
- data/lib/action_view/helpers/tags/week_field.rb +1 -2
- data/lib/action_view/helpers/text_helper.rb +3 -4
- data/lib/action_view/helpers/translation_helper.rb +93 -55
- data/lib/action_view/helpers/url_helper.rb +121 -27
- data/lib/action_view/layouts.rb +8 -10
- data/lib/action_view/log_subscriber.rb +30 -15
- data/lib/action_view/lookup_context.rb +63 -35
- data/lib/action_view/path_set.rb +3 -12
- data/lib/action_view/railtie.rb +42 -26
- data/lib/action_view/record_identifier.rb +2 -3
- data/lib/action_view/renderer/abstract_renderer.rb +142 -11
- data/lib/action_view/renderer/collection_renderer.rb +196 -0
- data/lib/action_view/renderer/object_renderer.rb +34 -0
- data/lib/action_view/renderer/partial_renderer.rb +21 -273
- data/lib/action_view/renderer/partial_renderer/collection_caching.rb +61 -16
- data/lib/action_view/renderer/renderer.rb +59 -4
- data/lib/action_view/renderer/streaming_template_renderer.rb +10 -8
- data/lib/action_view/renderer/template_renderer.rb +35 -27
- data/lib/action_view/rendering.rb +54 -33
- data/lib/action_view/routing_url_for.rb +13 -12
- data/lib/action_view/template.rb +66 -75
- data/lib/action_view/template/error.rb +30 -15
- data/lib/action_view/template/handlers.rb +1 -1
- data/lib/action_view/template/handlers/builder.rb +2 -2
- data/lib/action_view/template/handlers/erb.rb +16 -11
- data/lib/action_view/template/handlers/erb/erubi.rb +15 -9
- data/lib/action_view/template/handlers/html.rb +1 -1
- data/lib/action_view/template/handlers/raw.rb +2 -2
- data/lib/action_view/template/html.rb +5 -6
- data/lib/action_view/template/inline.rb +22 -0
- data/lib/action_view/template/raw_file.rb +25 -0
- data/lib/action_view/template/renderable.rb +24 -0
- data/lib/action_view/template/resolver.rb +191 -150
- data/lib/action_view/template/sources.rb +13 -0
- data/lib/action_view/template/sources/file.rb +17 -0
- data/lib/action_view/template/text.rb +2 -3
- data/lib/action_view/test_case.rb +21 -29
- data/lib/action_view/testing/resolvers.rb +18 -27
- data/lib/action_view/unbound_template.rb +31 -0
- data/lib/action_view/view_paths.rb +59 -38
- data/lib/assets/compiled/rails-ujs.js +29 -3
- metadata +32 -21
- data/lib/action_view/helpers/record_tag_helper.rb +0 -23
@@ -1,6 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require "active_support/core_ext/object/try"
|
4
3
|
require "rails-html-sanitizer"
|
5
4
|
|
6
5
|
module ActionView
|
@@ -10,14 +9,14 @@ module ActionView
|
|
10
9
|
# These helper methods extend Action View making them callable within your template files.
|
11
10
|
module SanitizeHelper
|
12
11
|
extend ActiveSupport::Concern
|
13
|
-
# Sanitizes HTML input, stripping all tags and attributes
|
12
|
+
# Sanitizes HTML input, stripping all but known-safe tags and attributes.
|
14
13
|
#
|
15
14
|
# It also strips href/src attributes with unsafe protocols like
|
16
15
|
# <tt>javascript:</tt>, while also protecting against attempts to use Unicode,
|
17
16
|
# ASCII, and hex character references to work around these protocol filters.
|
18
17
|
# All special characters will be escaped.
|
19
18
|
#
|
20
|
-
# The default sanitizer is Rails::Html::
|
19
|
+
# The default sanitizer is Rails::Html::SafeListSanitizer. See {Rails HTML
|
21
20
|
# Sanitizers}[https://github.com/rails/rails-html-sanitizer] for more information.
|
22
21
|
#
|
23
22
|
# Custom sanitization rules can also be provided.
|
@@ -40,7 +39,7 @@ module ActionView
|
|
40
39
|
#
|
41
40
|
# <%= sanitize @comment.body %>
|
42
41
|
#
|
43
|
-
# Providing custom
|
42
|
+
# Providing custom lists of permitted tags and attributes:
|
44
43
|
#
|
45
44
|
# <%= sanitize @comment.body, tags: %w(strong em a), attributes: %w(href) %>
|
46
45
|
#
|
@@ -80,12 +79,12 @@ module ActionView
|
|
80
79
|
# config.action_view.sanitized_allowed_tags = ['strong', 'em', 'a']
|
81
80
|
# config.action_view.sanitized_allowed_attributes = ['href', 'title']
|
82
81
|
def sanitize(html, options = {})
|
83
|
-
self.class.
|
82
|
+
self.class.safe_list_sanitizer.sanitize(html, options)&.html_safe
|
84
83
|
end
|
85
84
|
|
86
85
|
# Sanitizes a block of CSS code. Used by +sanitize+ when it comes across a style attribute.
|
87
86
|
def sanitize_css(style)
|
88
|
-
self.class.
|
87
|
+
self.class.safe_list_sanitizer.sanitize_css(style)
|
89
88
|
end
|
90
89
|
|
91
90
|
# Strips all HTML tags from +html+, including comments and special characters.
|
@@ -123,20 +122,18 @@ module ActionView
|
|
123
122
|
end
|
124
123
|
|
125
124
|
module ClassMethods #:nodoc:
|
126
|
-
attr_writer :full_sanitizer, :link_sanitizer, :
|
125
|
+
attr_writer :full_sanitizer, :link_sanitizer, :safe_list_sanitizer
|
127
126
|
|
128
|
-
# Vendors the full, link and white list sanitizers.
|
129
|
-
# Provided strictly for compatibility and can be removed in Rails 5.1.
|
130
127
|
def sanitizer_vendor
|
131
128
|
Rails::Html::Sanitizer
|
132
129
|
end
|
133
130
|
|
134
131
|
def sanitized_allowed_tags
|
135
|
-
sanitizer_vendor.
|
132
|
+
sanitizer_vendor.safe_list_sanitizer.allowed_tags
|
136
133
|
end
|
137
134
|
|
138
135
|
def sanitized_allowed_attributes
|
139
|
-
sanitizer_vendor.
|
136
|
+
sanitizer_vendor.safe_list_sanitizer.allowed_attributes
|
140
137
|
end
|
141
138
|
|
142
139
|
# Gets the Rails::Html::FullSanitizer instance used by +strip_tags+. Replace with
|
@@ -145,7 +142,6 @@ module ActionView
|
|
145
142
|
# class Application < Rails::Application
|
146
143
|
# config.action_view.full_sanitizer = MySpecialSanitizer.new
|
147
144
|
# end
|
148
|
-
#
|
149
145
|
def full_sanitizer
|
150
146
|
@full_sanitizer ||= sanitizer_vendor.full_sanitizer.new
|
151
147
|
end
|
@@ -156,20 +152,18 @@ module ActionView
|
|
156
152
|
# class Application < Rails::Application
|
157
153
|
# config.action_view.link_sanitizer = MySpecialSanitizer.new
|
158
154
|
# end
|
159
|
-
#
|
160
155
|
def link_sanitizer
|
161
156
|
@link_sanitizer ||= sanitizer_vendor.link_sanitizer.new
|
162
157
|
end
|
163
158
|
|
164
|
-
# Gets the Rails::Html::
|
159
|
+
# Gets the Rails::Html::SafeListSanitizer instance used by sanitize and +sanitize_css+.
|
165
160
|
# Replace with any object that responds to +sanitize+.
|
166
161
|
#
|
167
162
|
# class Application < Rails::Application
|
168
|
-
# config.action_view.
|
163
|
+
# config.action_view.safe_list_sanitizer = MySpecialSanitizer.new
|
169
164
|
# end
|
170
|
-
|
171
|
-
|
172
|
-
@white_list_sanitizer ||= sanitizer_vendor.white_list_sanitizer.new
|
165
|
+
def safe_list_sanitizer
|
166
|
+
@safe_list_sanitizer ||= sanitizer_vendor.safe_list_sanitizer.new
|
173
167
|
end
|
174
168
|
end
|
175
169
|
end
|
@@ -13,19 +13,27 @@ module ActionView
|
|
13
13
|
include CaptureHelper
|
14
14
|
include OutputSafetyHelper
|
15
15
|
|
16
|
-
BOOLEAN_ATTRIBUTES = %w(allowfullscreen async autofocus
|
17
|
-
compact controls declare default
|
18
|
-
defaultmuted defaultselected defer
|
19
|
-
enabled formnovalidate hidden indeterminate
|
20
|
-
ismap itemscope loop multiple muted nohref
|
21
|
-
noresize noshade novalidate nowrap open
|
22
|
-
pauseonexit readonly required reversed
|
23
|
-
seamless selected sortable truespeed
|
24
|
-
visible).to_set
|
16
|
+
BOOLEAN_ATTRIBUTES = %w(allowfullscreen allowpaymentrequest async autofocus
|
17
|
+
autoplay checked compact controls declare default
|
18
|
+
defaultchecked defaultmuted defaultselected defer
|
19
|
+
disabled enabled formnovalidate hidden indeterminate
|
20
|
+
inert ismap itemscope loop multiple muted nohref
|
21
|
+
nomodule noresize noshade novalidate nowrap open
|
22
|
+
pauseonexit playsinline readonly required reversed
|
23
|
+
scoped seamless selected sortable truespeed
|
24
|
+
typemustmatch visible).to_set
|
25
25
|
|
26
26
|
BOOLEAN_ATTRIBUTES.merge(BOOLEAN_ATTRIBUTES.map(&:to_sym))
|
27
|
+
BOOLEAN_ATTRIBUTES.freeze
|
27
28
|
|
28
|
-
|
29
|
+
ARIA_PREFIXES = ["aria", :aria].to_set.freeze
|
30
|
+
DATA_PREFIXES = ["data", :data].to_set.freeze
|
31
|
+
|
32
|
+
TAG_TYPES = {}
|
33
|
+
TAG_TYPES.merge! BOOLEAN_ATTRIBUTES.index_with(:boolean)
|
34
|
+
TAG_TYPES.merge! DATA_PREFIXES.index_with(:data)
|
35
|
+
TAG_TYPES.merge! ARIA_PREFIXES.index_with(:aria)
|
36
|
+
TAG_TYPES.freeze
|
29
37
|
|
30
38
|
PRE_CONTENT_STRINGS = Hash.new { "" }
|
31
39
|
PRE_CONTENT_STRINGS[:textarea] = "\n"
|
@@ -41,6 +49,10 @@ module ActionView
|
|
41
49
|
@view_context = view_context
|
42
50
|
end
|
43
51
|
|
52
|
+
def p(*arguments, **options, &block)
|
53
|
+
tag_string(:p, *arguments, **options, &block)
|
54
|
+
end
|
55
|
+
|
44
56
|
def tag_string(name, content = nil, escape_attributes: true, **options, &block)
|
45
57
|
content = @view_context.capture(self, &block) if block_given?
|
46
58
|
if VOID_ELEMENTS.include?(name) && content.nil?
|
@@ -58,16 +70,34 @@ module ActionView
|
|
58
70
|
|
59
71
|
def tag_options(options, escape = true)
|
60
72
|
return if options.blank?
|
61
|
-
output = ""
|
73
|
+
output = +""
|
62
74
|
sep = " "
|
63
75
|
options.each_pair do |key, value|
|
64
|
-
|
76
|
+
type = TAG_TYPES[key]
|
77
|
+
if type == :data && value.is_a?(Hash)
|
78
|
+
value.each_pair do |k, v|
|
79
|
+
next if v.nil?
|
80
|
+
output << sep
|
81
|
+
output << prefix_tag_option(key, k, v, escape)
|
82
|
+
end
|
83
|
+
elsif type == :aria && value.is_a?(Hash)
|
65
84
|
value.each_pair do |k, v|
|
66
85
|
next if v.nil?
|
86
|
+
|
87
|
+
case v
|
88
|
+
when Array, Hash
|
89
|
+
tokens = TagHelper.build_tag_values(v)
|
90
|
+
next if tokens.none?
|
91
|
+
|
92
|
+
v = safe_join(tokens, " ")
|
93
|
+
else
|
94
|
+
v = v.to_s
|
95
|
+
end
|
96
|
+
|
67
97
|
output << sep
|
68
98
|
output << prefix_tag_option(key, k, v, escape)
|
69
99
|
end
|
70
|
-
elsif
|
100
|
+
elsif type == :boolean
|
71
101
|
if value
|
72
102
|
output << sep
|
73
103
|
output << boolean_tag_option(key)
|
@@ -85,12 +115,15 @@ module ActionView
|
|
85
115
|
end
|
86
116
|
|
87
117
|
def tag_option(key, value, escape)
|
88
|
-
|
89
|
-
|
118
|
+
case value
|
119
|
+
when Array, Hash
|
120
|
+
value = TagHelper.build_tag_values(value) if key.to_s == "class"
|
121
|
+
value = escape ? safe_join(value, " ") : value.join(" ")
|
90
122
|
else
|
91
123
|
value = escape ? ERB::Util.unwrapped_html_escape(value) : value.to_s
|
92
124
|
end
|
93
|
-
|
125
|
+
value = value.gsub('"', """) if value.include?('"')
|
126
|
+
%(#{key}="#{value}")
|
94
127
|
end
|
95
128
|
|
96
129
|
private
|
@@ -106,8 +139,8 @@ module ActionView
|
|
106
139
|
true
|
107
140
|
end
|
108
141
|
|
109
|
-
def method_missing(called, *args, &block)
|
110
|
-
tag_string(called, *args, &block)
|
142
|
+
def method_missing(called, *args, **options, &block)
|
143
|
+
tag_string(called, *args, **options, &block)
|
111
144
|
end
|
112
145
|
end
|
113
146
|
|
@@ -151,8 +184,8 @@ module ActionView
|
|
151
184
|
# tag.input type: 'text', disabled: true
|
152
185
|
# # => <input type="text" disabled="disabled">
|
153
186
|
#
|
154
|
-
# HTML5 <tt>data-*</tt> attributes can be set with a
|
155
|
-
# pointing to a hash of sub-attributes.
|
187
|
+
# HTML5 <tt>data-*</tt> and <tt>aria-*</tt> attributes can be set with a
|
188
|
+
# single +data+ or +aria+ key pointing to a hash of sub-attributes.
|
156
189
|
#
|
157
190
|
# To play nicely with JavaScript conventions, sub-attributes are dasherized.
|
158
191
|
#
|
@@ -227,11 +260,14 @@ module ActionView
|
|
227
260
|
# tag("img", src: "open & shut.png")
|
228
261
|
# # => <img src="open & shut.png" />
|
229
262
|
#
|
230
|
-
# tag("img", {src: "open & shut.png"}, false, false)
|
263
|
+
# tag("img", { src: "open & shut.png" }, false, false)
|
231
264
|
# # => <img src="open & shut.png" />
|
232
265
|
#
|
233
|
-
# tag("div", data: {name: 'Stephen', city_state: %w(Chicago IL)})
|
266
|
+
# tag("div", data: { name: 'Stephen', city_state: %w(Chicago IL) })
|
234
267
|
# # => <div data-name="Stephen" data-city-state="["Chicago","IL"]" />
|
268
|
+
#
|
269
|
+
# tag("div", class: { highlight: current_user.admin? })
|
270
|
+
# # => <div class="highlight" />
|
235
271
|
def tag(name = nil, options = nil, open = false, escape = true)
|
236
272
|
if name.nil?
|
237
273
|
tag_builder
|
@@ -259,6 +295,8 @@ module ActionView
|
|
259
295
|
# # => <div class="strong"><p>Hello world!</p></div>
|
260
296
|
# content_tag(:div, "Hello world!", class: ["strong", "highlight"])
|
261
297
|
# # => <div class="strong highlight">Hello world!</div>
|
298
|
+
# content_tag(:div, "Hello world!", class: ["strong", { highlight: current_user.admin? }])
|
299
|
+
# # => <div class="strong highlight">Hello world!</div>
|
262
300
|
# content_tag("select", options, multiple: true)
|
263
301
|
# # => <select multiple="multiple">...options...</select>
|
264
302
|
#
|
@@ -275,6 +313,24 @@ module ActionView
|
|
275
313
|
end
|
276
314
|
end
|
277
315
|
|
316
|
+
# Returns a string of tokens built from +args+.
|
317
|
+
#
|
318
|
+
# ==== Examples
|
319
|
+
# token_list("foo", "bar")
|
320
|
+
# # => "foo bar"
|
321
|
+
# token_list("foo", "foo bar")
|
322
|
+
# # => "foo bar"
|
323
|
+
# token_list({ foo: true, bar: false })
|
324
|
+
# # => "foo"
|
325
|
+
# token_list(nil, false, 123, "", "foo", { bar: true })
|
326
|
+
# # => "123 foo bar"
|
327
|
+
def token_list(*args)
|
328
|
+
tokens = build_tag_values(*args).flat_map { |value| value.to_s.split(/\s+/) }.uniq
|
329
|
+
|
330
|
+
safe_join(tokens, " ")
|
331
|
+
end
|
332
|
+
alias_method :class_names, :token_list
|
333
|
+
|
278
334
|
# Returns a CDATA section with the given +content+. CDATA sections
|
279
335
|
# are used to escape blocks of text containing characters which would
|
280
336
|
# otherwise be recognized as markup. CDATA sections begin with the string
|
@@ -305,6 +361,26 @@ module ActionView
|
|
305
361
|
end
|
306
362
|
|
307
363
|
private
|
364
|
+
def build_tag_values(*args)
|
365
|
+
tag_values = []
|
366
|
+
|
367
|
+
args.each do |tag_value|
|
368
|
+
case tag_value
|
369
|
+
when Hash
|
370
|
+
tag_value.each do |key, val|
|
371
|
+
tag_values << key.to_s if val && key.present?
|
372
|
+
end
|
373
|
+
when Array
|
374
|
+
tag_values.concat build_tag_values(*tag_value)
|
375
|
+
else
|
376
|
+
tag_values << tag_value.to_s if tag_value.present?
|
377
|
+
end
|
378
|
+
end
|
379
|
+
|
380
|
+
tag_values
|
381
|
+
end
|
382
|
+
module_function :build_tag_values
|
383
|
+
|
308
384
|
def tag_builder
|
309
385
|
@tag_builder ||= TagBuilder.new(self)
|
310
386
|
end
|
@@ -34,7 +34,6 @@ module ActionView
|
|
34
34
|
end
|
35
35
|
|
36
36
|
private
|
37
|
-
|
38
37
|
def value
|
39
38
|
if @allow_method_names_outside_object
|
40
39
|
object.public_send @method_name if object && object.respond_to?(@method_name)
|
@@ -106,19 +105,19 @@ module ActionView
|
|
106
105
|
end
|
107
106
|
|
108
107
|
def tag_name(multiple = false, index = nil)
|
109
|
-
# a little duplication to construct
|
108
|
+
# a little duplication to construct fewer strings
|
110
109
|
case
|
111
110
|
when @object_name.empty?
|
112
|
-
"#{sanitized_method_name}#{"[]"
|
111
|
+
"#{sanitized_method_name}#{multiple ? "[]" : ""}"
|
113
112
|
when index
|
114
|
-
"#{@object_name}[#{index}][#{sanitized_method_name}]#{"[]"
|
113
|
+
"#{@object_name}[#{index}][#{sanitized_method_name}]#{multiple ? "[]" : ""}"
|
115
114
|
else
|
116
|
-
"#{@object_name}[#{sanitized_method_name}]#{"[]"
|
115
|
+
"#{@object_name}[#{sanitized_method_name}]#{multiple ? "[]" : ""}"
|
117
116
|
end
|
118
117
|
end
|
119
118
|
|
120
119
|
def tag_id(index = nil)
|
121
|
-
# a little duplication to construct
|
120
|
+
# a little duplication to construct fewer strings
|
122
121
|
case
|
123
122
|
when @object_name.empty?
|
124
123
|
sanitized_method_name.dup
|
@@ -130,15 +129,15 @@ module ActionView
|
|
130
129
|
end
|
131
130
|
|
132
131
|
def sanitized_object_name
|
133
|
-
@sanitized_object_name ||= @object_name.gsub(/\]\[|[^-a-zA-Z0-9:.]/, "_").
|
132
|
+
@sanitized_object_name ||= @object_name.gsub(/\]\[|[^-a-zA-Z0-9:.]/, "_").delete_suffix("_")
|
134
133
|
end
|
135
134
|
|
136
135
|
def sanitized_method_name
|
137
|
-
@sanitized_method_name ||= @method_name.
|
136
|
+
@sanitized_method_name ||= @method_name.delete_suffix("?")
|
138
137
|
end
|
139
138
|
|
140
139
|
def sanitized_value(value)
|
141
|
-
value.to_s.gsub(
|
140
|
+
value.to_s.gsub(/[\s\.]/, "_").gsub(/[^-[[:word:]]]/, "").downcase
|
142
141
|
end
|
143
142
|
|
144
143
|
def select_content_tag(option_tags, options, html_options)
|
@@ -167,11 +166,19 @@ module ActionView
|
|
167
166
|
|
168
167
|
def add_options(option_tags, options, value = nil)
|
169
168
|
if options[:include_blank]
|
170
|
-
|
169
|
+
content = (options[:include_blank] if options[:include_blank].is_a?(String))
|
170
|
+
label = (" " unless content)
|
171
|
+
option_tags = tag_builder.content_tag_string("option", content, value: "", label: label) + "\n" + option_tags
|
171
172
|
end
|
173
|
+
|
172
174
|
if value.blank? && options[:prompt]
|
173
|
-
|
175
|
+
tag_options = { value: "" }.tap do |prompt_opts|
|
176
|
+
prompt_opts[:disabled] = true if options[:disabled] == ""
|
177
|
+
prompt_opts[:selected] = true if options[:selected] == ""
|
178
|
+
end
|
179
|
+
option_tags = tag_builder.content_tag_string("option", prompt_text(options[:prompt]), tag_options) + "\n" + option_tags
|
174
180
|
end
|
181
|
+
|
175
182
|
option_tags
|
176
183
|
end
|
177
184
|
|
@@ -13,7 +13,7 @@ module ActionView
|
|
13
13
|
end
|
14
14
|
|
15
15
|
def render
|
16
|
-
error_wrapping(datetime_selector(@options, @html_options).
|
16
|
+
error_wrapping(datetime_selector(@options, @html_options).public_send("select_#{select_type}").html_safe)
|
17
17
|
end
|
18
18
|
|
19
19
|
class << self
|
@@ -23,7 +23,6 @@ module ActionView
|
|
23
23
|
end
|
24
24
|
|
25
25
|
private
|
26
|
-
|
27
26
|
def select_type
|
28
27
|
self.class.select_type
|
29
28
|
end
|
@@ -59,7 +58,7 @@ module ActionView
|
|
59
58
|
time = Time.current
|
60
59
|
|
61
60
|
[:year, :month, :day, :hour, :min, :sec].each do |key|
|
62
|
-
default[key] ||= time.
|
61
|
+
default[key] ||= time.public_send(key)
|
63
62
|
end
|
64
63
|
|
65
64
|
Time.utc(
|