actionview 4.2.10 → 5.1.0
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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +141 -272
- data/MIT-LICENSE +1 -1
- data/README.rdoc +2 -3
- data/lib/action_view/base.rb +33 -21
- data/lib/action_view/buffers.rb +1 -1
- data/lib/action_view/context.rb +1 -1
- data/lib/action_view/dependency_tracker.rb +52 -20
- data/lib/action_view/digestor.rb +86 -83
- data/lib/action_view/flows.rb +9 -11
- data/lib/action_view/gem_version.rb +3 -3
- data/lib/action_view/helpers/active_model_helper.rb +8 -8
- data/lib/action_view/helpers/asset_tag_helper.rb +74 -38
- data/lib/action_view/helpers/asset_url_helper.rb +160 -59
- data/lib/action_view/helpers/atom_feed_helper.rb +16 -16
- data/lib/action_view/helpers/cache_helper.rb +90 -35
- data/lib/action_view/helpers/capture_helper.rb +7 -6
- data/lib/action_view/helpers/controller_helper.rb +3 -2
- data/lib/action_view/helpers/csrf_helper.rb +3 -3
- data/lib/action_view/helpers/date_helper.rb +156 -108
- data/lib/action_view/helpers/debug_helper.rb +3 -4
- data/lib/action_view/helpers/form_helper.rb +475 -94
- data/lib/action_view/helpers/form_options_helper.rb +87 -47
- data/lib/action_view/helpers/form_tag_helper.rb +88 -57
- data/lib/action_view/helpers/javascript_helper.rb +10 -10
- data/lib/action_view/helpers/number_helper.rb +76 -59
- data/lib/action_view/helpers/output_safety_helper.rb +34 -4
- data/lib/action_view/helpers/record_tag_helper.rb +12 -99
- data/lib/action_view/helpers/rendering_helper.rb +3 -3
- data/lib/action_view/helpers/sanitize_helper.rb +17 -14
- data/lib/action_view/helpers/tag_helper.rb +198 -73
- data/lib/action_view/helpers/tags/base.rb +132 -97
- data/lib/action_view/helpers/tags/check_box.rb +17 -17
- data/lib/action_view/helpers/tags/collection_check_boxes.rb +9 -33
- data/lib/action_view/helpers/tags/collection_helpers.rb +68 -36
- data/lib/action_view/helpers/tags/collection_radio_buttons.rb +3 -11
- data/lib/action_view/helpers/tags/collection_select.rb +2 -2
- data/lib/action_view/helpers/tags/date_select.rb +36 -36
- data/lib/action_view/helpers/tags/datetime_field.rb +1 -1
- data/lib/action_view/helpers/tags/grouped_collection_select.rb +2 -2
- data/lib/action_view/helpers/tags/label.rb +5 -1
- data/lib/action_view/helpers/tags/password_field.rb +1 -1
- data/lib/action_view/helpers/tags/placeholderable.rb +1 -1
- data/lib/action_view/helpers/tags/radio_button.rb +4 -4
- data/lib/action_view/helpers/tags/search_field.rb +12 -9
- data/lib/action_view/helpers/tags/select.rb +9 -9
- data/lib/action_view/helpers/tags/text_area.rb +1 -1
- data/lib/action_view/helpers/tags/text_field.rb +5 -6
- data/lib/action_view/helpers/tags/translator.rb +15 -13
- data/lib/action_view/helpers/text_helper.rb +47 -30
- data/lib/action_view/helpers/translation_helper.rb +60 -30
- data/lib/action_view/helpers/url_helper.rb +132 -104
- data/lib/action_view/helpers.rb +1 -1
- data/lib/action_view/layouts.rb +59 -54
- data/lib/action_view/log_subscriber.rb +56 -7
- data/lib/action_view/lookup_context.rb +76 -61
- data/lib/action_view/model_naming.rb +1 -1
- data/lib/action_view/path_set.rb +28 -19
- data/lib/action_view/railtie.rb +30 -6
- data/lib/action_view/record_identifier.rb +51 -25
- data/lib/action_view/renderer/abstract_renderer.rb +19 -15
- data/lib/action_view/renderer/partial_renderer/collection_caching.rb +55 -0
- data/lib/action_view/renderer/partial_renderer.rb +208 -206
- data/lib/action_view/renderer/renderer.rb +2 -6
- data/lib/action_view/renderer/streaming_template_renderer.rb +46 -48
- data/lib/action_view/renderer/template_renderer.rb +65 -66
- data/lib/action_view/rendering.rb +16 -9
- data/lib/action_view/routing_url_for.rb +25 -17
- data/lib/action_view/tasks/cache_digests.rake +23 -0
- data/lib/action_view/template/error.rb +14 -13
- data/lib/action_view/template/handlers/builder.rb +7 -7
- data/lib/action_view/template/handlers/erb/deprecated_erubis.rb +9 -0
- data/lib/action_view/template/handlers/erb/erubi.rb +81 -0
- data/lib/action_view/template/handlers/erb/erubis.rb +81 -0
- data/lib/action_view/template/handlers/erb.rb +9 -76
- data/lib/action_view/template/handlers/html.rb +9 -0
- data/lib/action_view/template/handlers/raw.rb +1 -3
- data/lib/action_view/template/handlers.rb +8 -6
- data/lib/action_view/template/html.rb +2 -4
- data/lib/action_view/template/resolver.rb +133 -109
- data/lib/action_view/template/text.rb +5 -8
- data/lib/action_view/template/types.rb +15 -17
- data/lib/action_view/template.rb +51 -28
- data/lib/action_view/test_case.rb +32 -27
- data/lib/action_view/testing/resolvers.rb +29 -31
- data/lib/action_view/version.rb +1 -1
- data/lib/action_view/view_paths.rb +26 -32
- data/lib/action_view.rb +5 -5
- data/lib/assets/compiled/rails-ujs.js +685 -0
- metadata +23 -23
- data/lib/action_view/tasks/dependencies.rake +0 -23
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
require
|
|
1
|
+
require "action_view/helpers/tags/collection_helpers"
|
|
2
2
|
|
|
3
3
|
module ActionView
|
|
4
4
|
module Helpers
|
|
@@ -7,50 +7,26 @@ module ActionView
|
|
|
7
7
|
include CollectionHelpers
|
|
8
8
|
|
|
9
9
|
class CheckBoxBuilder < Builder # :nodoc:
|
|
10
|
-
def check_box(extra_html_options={})
|
|
10
|
+
def check_box(extra_html_options = {})
|
|
11
11
|
html_options = extra_html_options.merge(@input_html_options)
|
|
12
|
+
html_options[:multiple] = true
|
|
12
13
|
@template_object.check_box(@object_name, @method_name, html_options, @value, nil)
|
|
13
14
|
end
|
|
14
15
|
end
|
|
15
16
|
|
|
16
17
|
def render(&block)
|
|
17
|
-
|
|
18
|
-
default_html_options[:multiple] = true
|
|
19
|
-
builder = instantiate_builder(CheckBoxBuilder, item, value, text, default_html_options)
|
|
20
|
-
|
|
21
|
-
if block_given?
|
|
22
|
-
@template_object.capture(builder, &block)
|
|
23
|
-
else
|
|
24
|
-
render_component(builder)
|
|
25
|
-
end
|
|
26
|
-
end
|
|
27
|
-
|
|
28
|
-
# Append a hidden field to make sure something will be sent back to the
|
|
29
|
-
# server if all check boxes are unchecked.
|
|
30
|
-
if @options.fetch(:include_hidden, true)
|
|
31
|
-
rendered_collection + hidden_field
|
|
32
|
-
else
|
|
33
|
-
rendered_collection
|
|
34
|
-
end
|
|
18
|
+
render_collection_for(CheckBoxBuilder, &block)
|
|
35
19
|
end
|
|
36
20
|
|
|
37
21
|
private
|
|
38
22
|
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
end
|
|
42
|
-
|
|
43
|
-
def hidden_field
|
|
44
|
-
hidden_name = @html_options[:name]
|
|
45
|
-
|
|
46
|
-
hidden_name ||= if @options.has_key?(:index)
|
|
47
|
-
"#{tag_name_with_index(@options[:index])}[]"
|
|
48
|
-
else
|
|
49
|
-
"#{tag_name}[]"
|
|
23
|
+
def render_component(builder)
|
|
24
|
+
builder.check_box + builder.label
|
|
50
25
|
end
|
|
51
26
|
|
|
52
|
-
|
|
53
|
-
|
|
27
|
+
def hidden_field_name
|
|
28
|
+
"#{super}[]"
|
|
29
|
+
end
|
|
54
30
|
end
|
|
55
31
|
end
|
|
56
32
|
end
|
|
@@ -17,8 +17,10 @@ module ActionView
|
|
|
17
17
|
@input_html_options = input_html_options
|
|
18
18
|
end
|
|
19
19
|
|
|
20
|
-
def label(label_html_options={}, &block)
|
|
20
|
+
def label(label_html_options = {}, &block)
|
|
21
21
|
html_options = @input_html_options.slice(:index, :namespace).merge(label_html_options)
|
|
22
|
+
html_options[:for] ||= @input_html_options[:id] if @input_html_options[:id]
|
|
23
|
+
|
|
22
24
|
@template_object.label(@object_name, @sanitized_attribute_name, @text, html_options, &block)
|
|
23
25
|
end
|
|
24
26
|
end
|
|
@@ -34,51 +36,81 @@ module ActionView
|
|
|
34
36
|
|
|
35
37
|
private
|
|
36
38
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
39
|
+
def instantiate_builder(builder_class, item, value, text, html_options)
|
|
40
|
+
builder_class.new(@template_object, @object_name, @method_name, item,
|
|
41
|
+
sanitize_attribute_name(value), text, value, html_options)
|
|
42
|
+
end
|
|
41
43
|
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
44
|
+
# Generate default options for collection helpers, such as :checked and
|
|
45
|
+
# :disabled.
|
|
46
|
+
def default_html_options_for_collection(item, value)
|
|
47
|
+
html_options = @html_options.dup
|
|
46
48
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
49
|
+
[:checked, :selected, :disabled, :readonly].each do |option|
|
|
50
|
+
current_value = @options[option]
|
|
51
|
+
next if current_value.nil?
|
|
50
52
|
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
53
|
+
accept = if current_value.respond_to?(:call)
|
|
54
|
+
current_value.call(item)
|
|
55
|
+
else
|
|
56
|
+
Array(current_value).map(&:to_s).include?(value.to_s)
|
|
57
|
+
end
|
|
56
58
|
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
59
|
+
if accept
|
|
60
|
+
html_options[option] = true
|
|
61
|
+
elsif option == :checked
|
|
62
|
+
html_options[option] = false
|
|
63
|
+
end
|
|
61
64
|
end
|
|
65
|
+
|
|
66
|
+
html_options[:object] = @object
|
|
67
|
+
html_options
|
|
62
68
|
end
|
|
63
69
|
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
70
|
+
def sanitize_attribute_name(value)
|
|
71
|
+
"#{sanitized_method_name}_#{sanitized_value(value)}"
|
|
72
|
+
end
|
|
67
73
|
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
74
|
+
def render_collection
|
|
75
|
+
@collection.map do |item|
|
|
76
|
+
value = value_for_collection(item, @value_method)
|
|
77
|
+
text = value_for_collection(item, @text_method)
|
|
78
|
+
default_html_options = default_html_options_for_collection(item, value)
|
|
79
|
+
additional_html_options = option_html_attributes(item)
|
|
71
80
|
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
text = value_for_collection(item, @text_method)
|
|
76
|
-
default_html_options = default_html_options_for_collection(item, value)
|
|
77
|
-
additional_html_options = option_html_attributes(item)
|
|
81
|
+
yield item, value, text, default_html_options.merge(additional_html_options)
|
|
82
|
+
end.join.html_safe
|
|
83
|
+
end
|
|
78
84
|
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
85
|
+
def render_collection_for(builder_class, &block)
|
|
86
|
+
options = @options.stringify_keys
|
|
87
|
+
rendered_collection = render_collection do |item, value, text, default_html_options|
|
|
88
|
+
builder = instantiate_builder(builder_class, item, value, text, default_html_options)
|
|
89
|
+
|
|
90
|
+
if block_given?
|
|
91
|
+
@template_object.capture(builder, &block)
|
|
92
|
+
else
|
|
93
|
+
render_component(builder)
|
|
94
|
+
end
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
# Prepend a hidden field to make sure something will be sent back to the
|
|
98
|
+
# server if all radio buttons are unchecked.
|
|
99
|
+
if options.fetch("include_hidden", true)
|
|
100
|
+
hidden_field + rendered_collection
|
|
101
|
+
else
|
|
102
|
+
rendered_collection
|
|
103
|
+
end
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
def hidden_field
|
|
107
|
+
hidden_name = @html_options[:name] || hidden_field_name
|
|
108
|
+
@template_object.hidden_field_tag(hidden_name, "", id: nil)
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
def hidden_field_name
|
|
112
|
+
"#{tag_name(false, @options[:index])}"
|
|
113
|
+
end
|
|
82
114
|
end
|
|
83
115
|
end
|
|
84
116
|
end
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
require
|
|
1
|
+
require "action_view/helpers/tags/collection_helpers"
|
|
2
2
|
|
|
3
3
|
module ActionView
|
|
4
4
|
module Helpers
|
|
@@ -7,22 +7,14 @@ module ActionView
|
|
|
7
7
|
include CollectionHelpers
|
|
8
8
|
|
|
9
9
|
class RadioButtonBuilder < Builder # :nodoc:
|
|
10
|
-
def radio_button(extra_html_options={})
|
|
10
|
+
def radio_button(extra_html_options = {})
|
|
11
11
|
html_options = extra_html_options.merge(@input_html_options)
|
|
12
12
|
@template_object.radio_button(@object_name, @method_name, @value, html_options)
|
|
13
13
|
end
|
|
14
14
|
end
|
|
15
15
|
|
|
16
16
|
def render(&block)
|
|
17
|
-
|
|
18
|
-
builder = instantiate_builder(RadioButtonBuilder, item, value, text, default_html_options)
|
|
19
|
-
|
|
20
|
-
if block_given?
|
|
21
|
-
@template_object.capture(builder, &block)
|
|
22
|
-
else
|
|
23
|
-
render_component(builder)
|
|
24
|
-
end
|
|
25
|
-
end
|
|
17
|
+
render_collection_for(RadioButtonBuilder, &block)
|
|
26
18
|
end
|
|
27
19
|
|
|
28
20
|
private
|
|
@@ -13,8 +13,8 @@ module ActionView
|
|
|
13
13
|
|
|
14
14
|
def render
|
|
15
15
|
option_tags_options = {
|
|
16
|
-
:
|
|
17
|
-
:
|
|
16
|
+
selected: @options.fetch(:selected) { value(@object) },
|
|
17
|
+
disabled: @options[:disabled]
|
|
18
18
|
}
|
|
19
19
|
|
|
20
20
|
select_content_tag(
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
require
|
|
1
|
+
require "active_support/core_ext/time/calculations"
|
|
2
2
|
|
|
3
3
|
module ActionView
|
|
4
4
|
module Helpers
|
|
@@ -16,56 +16,56 @@ module ActionView
|
|
|
16
16
|
|
|
17
17
|
class << self
|
|
18
18
|
def select_type
|
|
19
|
-
@select_type ||=
|
|
19
|
+
@select_type ||= name.split("::").last.sub("Select", "").downcase
|
|
20
20
|
end
|
|
21
21
|
end
|
|
22
22
|
|
|
23
23
|
private
|
|
24
24
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
25
|
+
def select_type
|
|
26
|
+
self.class.select_type
|
|
27
|
+
end
|
|
28
28
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
29
|
+
def datetime_selector(options, html_options)
|
|
30
|
+
datetime = options.fetch(:selected) { value(object) || default_datetime(options) }
|
|
31
|
+
@auto_index ||= nil
|
|
32
32
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
33
|
+
options = options.dup
|
|
34
|
+
options[:field_name] = @method_name
|
|
35
|
+
options[:include_position] = true
|
|
36
|
+
options[:prefix] ||= @object_name
|
|
37
|
+
options[:index] = @auto_index if @auto_index && !options.has_key?(:index)
|
|
38
38
|
|
|
39
|
-
|
|
40
|
-
|
|
39
|
+
DateTimeSelector.new(datetime, options, html_options)
|
|
40
|
+
end
|
|
41
41
|
|
|
42
|
-
|
|
43
|
-
|
|
42
|
+
def default_datetime(options)
|
|
43
|
+
return if options[:include_blank] || options[:prompt]
|
|
44
44
|
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
45
|
+
case options[:default]
|
|
46
|
+
when nil
|
|
47
|
+
Time.current
|
|
48
|
+
when Date, Time
|
|
49
|
+
options[:default]
|
|
50
|
+
else
|
|
51
|
+
default = options[:default].dup
|
|
52
52
|
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
53
|
+
# Rename :minute and :second to :min and :sec
|
|
54
|
+
default[:min] ||= default[:minute]
|
|
55
|
+
default[:sec] ||= default[:second]
|
|
56
56
|
|
|
57
|
-
|
|
57
|
+
time = Time.current
|
|
58
58
|
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
59
|
+
[:year, :month, :day, :hour, :min, :sec].each do |key|
|
|
60
|
+
default[key] ||= time.send(key)
|
|
61
|
+
end
|
|
62
62
|
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
63
|
+
Time.utc(
|
|
64
|
+
default[:year], default[:month], default[:day],
|
|
65
|
+
default[:hour], default[:min], default[:sec]
|
|
66
|
+
)
|
|
67
|
+
end
|
|
67
68
|
end
|
|
68
|
-
end
|
|
69
69
|
end
|
|
70
70
|
end
|
|
71
71
|
end
|
|
@@ -15,8 +15,8 @@ module ActionView
|
|
|
15
15
|
|
|
16
16
|
def render
|
|
17
17
|
option_tags_options = {
|
|
18
|
-
:
|
|
19
|
-
:
|
|
18
|
+
selected: @options.fetch(:selected) { value(@object) },
|
|
19
|
+
disabled: @options[:disabled]
|
|
20
20
|
}
|
|
21
21
|
|
|
22
22
|
select_content_tag(
|
|
@@ -17,7 +17,7 @@ module ActionView
|
|
|
17
17
|
method_and_value = @tag_value.present? ? "#{@method_name}.#{@tag_value}" : @method_name
|
|
18
18
|
|
|
19
19
|
content ||= Translator
|
|
20
|
-
.new(object, @object_name, method_and_value, "helpers.label")
|
|
20
|
+
.new(object, @object_name, method_and_value, scope: "helpers.label")
|
|
21
21
|
.translate
|
|
22
22
|
content ||= @method_name.humanize
|
|
23
23
|
|
|
@@ -73,6 +73,10 @@ module ActionView
|
|
|
73
73
|
def render_component(builder)
|
|
74
74
|
builder.translation
|
|
75
75
|
end
|
|
76
|
+
|
|
77
|
+
def skip_default_ids?
|
|
78
|
+
false # The id is used as the `for` attribute.
|
|
79
|
+
end
|
|
76
80
|
end
|
|
77
81
|
end
|
|
78
82
|
end
|
|
@@ -10,7 +10,7 @@ module ActionView
|
|
|
10
10
|
method_and_value = tag_value.is_a?(TrueClass) ? @method_name : "#{@method_name}.#{tag_value}"
|
|
11
11
|
|
|
12
12
|
placeholder ||= Tags::Translator
|
|
13
|
-
.new(object, @object_name, method_and_value, "helpers.placeholder")
|
|
13
|
+
.new(object, @object_name, method_and_value, scope: "helpers.placeholder")
|
|
14
14
|
.translate
|
|
15
15
|
placeholder ||= @method_name.humanize
|
|
16
16
|
@options[:placeholder] = placeholder
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
require
|
|
1
|
+
require "action_view/helpers/tags/checkable"
|
|
2
2
|
|
|
3
3
|
module ActionView
|
|
4
4
|
module Helpers
|
|
@@ -22,9 +22,9 @@ module ActionView
|
|
|
22
22
|
|
|
23
23
|
private
|
|
24
24
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
25
|
+
def checked?(value)
|
|
26
|
+
value.to_s == @tag_value.to_s
|
|
27
|
+
end
|
|
28
28
|
end
|
|
29
29
|
end
|
|
30
30
|
end
|
|
@@ -3,18 +3,21 @@ module ActionView
|
|
|
3
3
|
module Tags # :nodoc:
|
|
4
4
|
class SearchField < TextField # :nodoc:
|
|
5
5
|
def render
|
|
6
|
-
|
|
7
|
-
if options["autosave"]
|
|
8
|
-
if options["autosave"] == true
|
|
9
|
-
options["autosave"] = request.host.split(".").reverse.join(".")
|
|
10
|
-
end
|
|
11
|
-
options["results"] ||= 10
|
|
12
|
-
end
|
|
6
|
+
options = @options.stringify_keys
|
|
13
7
|
|
|
14
|
-
|
|
15
|
-
|
|
8
|
+
if options["autosave"]
|
|
9
|
+
if options["autosave"] == true
|
|
10
|
+
options["autosave"] = request.host.split(".").reverse.join(".")
|
|
16
11
|
end
|
|
12
|
+
options["results"] ||= 10
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
if options["onsearch"]
|
|
16
|
+
options["incremental"] = true unless options.has_key?("incremental")
|
|
17
17
|
end
|
|
18
|
+
|
|
19
|
+
@options = options
|
|
20
|
+
super
|
|
18
21
|
end
|
|
19
22
|
end
|
|
20
23
|
end
|
|
@@ -13,8 +13,8 @@ module ActionView
|
|
|
13
13
|
|
|
14
14
|
def render
|
|
15
15
|
option_tags_options = {
|
|
16
|
-
:
|
|
17
|
-
:
|
|
16
|
+
selected: @options.fetch(:selected) { value(@object) },
|
|
17
|
+
disabled: @options[:disabled]
|
|
18
18
|
}
|
|
19
19
|
|
|
20
20
|
option_tags = if grouped_choices?
|
|
@@ -28,13 +28,13 @@ module ActionView
|
|
|
28
28
|
|
|
29
29
|
private
|
|
30
30
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
31
|
+
# Grouped choices look like this:
|
|
32
|
+
#
|
|
33
|
+
# [nil, []]
|
|
34
|
+
# { nil => [] }
|
|
35
|
+
def grouped_choices?
|
|
36
|
+
!@choices.empty? && @choices.first.respond_to?(:last) && Array === @choices.first.last
|
|
37
|
+
end
|
|
38
38
|
end
|
|
39
39
|
end
|
|
40
40
|
end
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
require
|
|
1
|
+
require "action_view/helpers/tags/placeholderable"
|
|
2
2
|
|
|
3
3
|
module ActionView
|
|
4
4
|
module Helpers
|
|
@@ -11,22 +11,21 @@ module ActionView
|
|
|
11
11
|
options["size"] = options["maxlength"] unless options.key?("size")
|
|
12
12
|
options["type"] ||= field_type
|
|
13
13
|
options["value"] = options.fetch("value") { value_before_type_cast(object) } unless field_type == "file"
|
|
14
|
-
yield options if block_given?
|
|
15
14
|
add_default_name_and_id(options)
|
|
16
15
|
tag("input", options)
|
|
17
16
|
end
|
|
18
17
|
|
|
19
18
|
class << self
|
|
20
19
|
def field_type
|
|
21
|
-
@field_type ||=
|
|
20
|
+
@field_type ||= name.split("::").last.sub("Field", "").downcase
|
|
22
21
|
end
|
|
23
22
|
end
|
|
24
23
|
|
|
25
24
|
private
|
|
26
25
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
26
|
+
def field_type
|
|
27
|
+
self.class.field_type
|
|
28
|
+
end
|
|
30
29
|
end
|
|
31
30
|
end
|
|
32
31
|
end
|
|
@@ -2,7 +2,7 @@ module ActionView
|
|
|
2
2
|
module Helpers
|
|
3
3
|
module Tags # :nodoc:
|
|
4
4
|
class Translator # :nodoc:
|
|
5
|
-
def initialize(object, object_name, method_and_value, scope)
|
|
5
|
+
def initialize(object, object_name, method_and_value, scope:)
|
|
6
6
|
@object_name = object_name.gsub(/\[(.*)_attributes\]\[\d+\]/, '.\1')
|
|
7
7
|
@method_and_value = method_and_value
|
|
8
8
|
@scope = scope
|
|
@@ -14,26 +14,28 @@ module ActionView
|
|
|
14
14
|
translated_attribute || human_attribute_name
|
|
15
15
|
end
|
|
16
16
|
|
|
17
|
+
# TODO Change this to private once we've dropped Ruby 2.2 support.
|
|
18
|
+
# Workaround for Ruby 2.2 "private attribute?" warning.
|
|
17
19
|
protected
|
|
18
20
|
|
|
19
|
-
|
|
21
|
+
attr_reader :object_name, :method_and_value, :scope, :model
|
|
20
22
|
|
|
21
23
|
private
|
|
22
24
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
25
|
+
def i18n_default
|
|
26
|
+
if model
|
|
27
|
+
key = model.model_name.i18n_key
|
|
28
|
+
["#{key}.#{method_and_value}".to_sym, ""]
|
|
29
|
+
else
|
|
30
|
+
""
|
|
31
|
+
end
|
|
29
32
|
end
|
|
30
|
-
end
|
|
31
33
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
34
|
+
def human_attribute_name
|
|
35
|
+
if model && model.class.respond_to?(:human_attribute_name)
|
|
36
|
+
model.class.human_attribute_name(method_and_value)
|
|
37
|
+
end
|
|
35
38
|
end
|
|
36
|
-
end
|
|
37
39
|
end
|
|
38
40
|
end
|
|
39
41
|
end
|