actionview 6.1.4.1 → 7.0.0.rc2
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 +189 -248
- data/MIT-LICENSE +1 -1
- data/lib/action_view/base.rb +4 -7
- data/lib/action_view/buffers.rb +2 -2
- data/lib/action_view/cache_expiry.rb +46 -32
- data/lib/action_view/dependency_tracker/erb_tracker.rb +154 -0
- data/lib/action_view/dependency_tracker/ripper_tracker.rb +59 -0
- data/lib/action_view/dependency_tracker.rb +6 -147
- data/lib/action_view/digestor.rb +7 -4
- data/lib/action_view/flows.rb +4 -4
- data/lib/action_view/gem_version.rb +4 -4
- data/lib/action_view/helpers/active_model_helper.rb +2 -2
- data/lib/action_view/helpers/asset_tag_helper.rb +84 -29
- data/lib/action_view/helpers/asset_url_helper.rb +9 -9
- data/lib/action_view/helpers/atom_feed_helper.rb +3 -4
- data/lib/action_view/helpers/cache_helper.rb +52 -3
- data/lib/action_view/helpers/capture_helper.rb +2 -2
- data/lib/action_view/helpers/controller_helper.rb +2 -2
- data/lib/action_view/helpers/csp_helper.rb +1 -1
- data/lib/action_view/helpers/csrf_helper.rb +1 -1
- data/lib/action_view/helpers/date_helper.rb +62 -7
- data/lib/action_view/helpers/debug_helper.rb +3 -1
- data/lib/action_view/helpers/form_helper.rb +190 -75
- data/lib/action_view/helpers/form_options_helper.rb +68 -33
- data/lib/action_view/helpers/form_tag_helper.rb +126 -36
- data/lib/action_view/helpers/javascript_helper.rb +3 -5
- data/lib/action_view/helpers/number_helper.rb +3 -4
- data/lib/action_view/helpers/output_safety_helper.rb +2 -2
- data/lib/action_view/helpers/rendering_helper.rb +1 -1
- data/lib/action_view/helpers/sanitize_helper.rb +2 -2
- data/lib/action_view/helpers/tag_helper.rb +34 -6
- data/lib/action_view/helpers/tags/base.rb +4 -24
- data/lib/action_view/helpers/tags/check_box.rb +2 -2
- data/lib/action_view/helpers/tags/collection_select.rb +1 -1
- data/lib/action_view/helpers/tags/hidden_field.rb +4 -0
- data/lib/action_view/helpers/tags/time_field.rb +10 -1
- data/lib/action_view/helpers/tags/weekday_select.rb +28 -0
- data/lib/action_view/helpers/tags.rb +3 -2
- data/lib/action_view/helpers/text_helper.rb +24 -13
- data/lib/action_view/helpers/translation_helper.rb +10 -41
- data/lib/action_view/helpers/url_helper.rb +166 -91
- data/lib/action_view/helpers.rb +25 -25
- data/lib/action_view/lookup_context.rb +33 -52
- data/lib/action_view/model_naming.rb +2 -2
- data/lib/action_view/path_set.rb +16 -22
- data/lib/action_view/railtie.rb +19 -7
- data/lib/action_view/render_parser.rb +188 -0
- data/lib/action_view/renderer/abstract_renderer.rb +2 -2
- data/lib/action_view/renderer/partial_renderer.rb +0 -34
- data/lib/action_view/renderer/renderer.rb +4 -4
- data/lib/action_view/renderer/streaming_template_renderer.rb +3 -3
- data/lib/action_view/renderer/template_renderer.rb +6 -2
- data/lib/action_view/rendering.rb +2 -2
- data/lib/action_view/ripper_ast_parser.rb +198 -0
- data/lib/action_view/routing_url_for.rb +1 -1
- data/lib/action_view/template/error.rb +108 -13
- data/lib/action_view/template/handlers/erb.rb +6 -0
- data/lib/action_view/template/handlers.rb +3 -3
- data/lib/action_view/template/html.rb +3 -3
- data/lib/action_view/template/inline.rb +3 -3
- data/lib/action_view/template/raw_file.rb +3 -3
- data/lib/action_view/template/resolver.rb +84 -311
- data/lib/action_view/template/text.rb +3 -3
- data/lib/action_view/template/types.rb +14 -12
- data/lib/action_view/template.rb +18 -2
- data/lib/action_view/template_details.rb +66 -0
- data/lib/action_view/template_path.rb +64 -0
- data/lib/action_view/test_case.rb +6 -2
- data/lib/action_view/testing/resolvers.rb +11 -12
- data/lib/action_view/unbound_template.rb +33 -7
- data/lib/action_view.rb +3 -4
- metadata +22 -14
@@ -2,21 +2,21 @@
|
|
2
2
|
|
3
3
|
require "cgi"
|
4
4
|
require "erb"
|
5
|
-
require "action_view/helpers/form_helper"
|
6
5
|
require "active_support/core_ext/string/output_safety"
|
7
6
|
require "active_support/core_ext/array/extract_options"
|
8
7
|
require "active_support/core_ext/array/wrap"
|
8
|
+
require "action_view/helpers/text_helper"
|
9
9
|
|
10
10
|
module ActionView
|
11
11
|
# = Action View Form Option Helpers
|
12
|
-
module Helpers
|
12
|
+
module Helpers # :nodoc:
|
13
13
|
# Provides a number of methods for turning different kinds of containers into a set of option tags.
|
14
14
|
#
|
15
15
|
# The <tt>collection_select</tt>, <tt>select</tt> and <tt>time_zone_select</tt> methods take an <tt>options</tt> parameter, a hash:
|
16
16
|
#
|
17
17
|
# * <tt>:include_blank</tt> - set to true or a prompt string if the first option element of the select element is a blank. Useful if there is not a default value required for the select element.
|
18
18
|
#
|
19
|
-
# select(
|
19
|
+
# select(:post, :category, Post::CATEGORIES, { include_blank: true })
|
20
20
|
#
|
21
21
|
# could become:
|
22
22
|
#
|
@@ -30,7 +30,7 @@ module ActionView
|
|
30
30
|
#
|
31
31
|
# Example with <tt>@post.person_id => 2</tt>:
|
32
32
|
#
|
33
|
-
# select(
|
33
|
+
# select(:post, :person_id, Person.all.collect { |p| [ p.name, p.id ] }, { include_blank: "None" })
|
34
34
|
#
|
35
35
|
# could become:
|
36
36
|
#
|
@@ -43,7 +43,7 @@ module ActionView
|
|
43
43
|
#
|
44
44
|
# * <tt>:prompt</tt> - set to true or a prompt string. When the select element doesn't have a value yet, this prepends an option with a generic prompt -- "Please select" -- or the given prompt string.
|
45
45
|
#
|
46
|
-
# select(
|
46
|
+
# select(:post, :person_id, Person.all.collect { |p| [ p.name, p.id ] }, { prompt: "Select Person" })
|
47
47
|
#
|
48
48
|
# could become:
|
49
49
|
#
|
@@ -54,10 +54,10 @@ module ActionView
|
|
54
54
|
# <option value="3">Rafael</option>
|
55
55
|
# </select>
|
56
56
|
#
|
57
|
-
# * <tt>:index</tt> - like the other form helpers,
|
57
|
+
# * <tt>:index</tt> - like the other form helpers, <tt>select</tt> can accept an <tt>:index</tt> option to manually set the ID used in the resulting output. Unlike other helpers, <tt>select</tt> expects this
|
58
58
|
# option to be in the +html_options+ parameter.
|
59
59
|
#
|
60
|
-
# select("album[]",
|
60
|
+
# select("album[]", :genre, %w[ rap rock country ], {}, { index: nil })
|
61
61
|
#
|
62
62
|
# becomes:
|
63
63
|
#
|
@@ -69,7 +69,7 @@ module ActionView
|
|
69
69
|
#
|
70
70
|
# * <tt>:disabled</tt> - can be a single value or an array of values that will be disabled options in the final output.
|
71
71
|
#
|
72
|
-
# select(
|
72
|
+
# select(:post, :category, Post::CATEGORIES, { disabled: "restricted" })
|
73
73
|
#
|
74
74
|
# could become:
|
75
75
|
#
|
@@ -90,7 +90,6 @@ module ActionView
|
|
90
90
|
# <option value="3">Jokes</option>
|
91
91
|
# <option value="4">Poems</option>
|
92
92
|
# </select>
|
93
|
-
#
|
94
93
|
module FormOptionsHelper
|
95
94
|
# ERB::Util can mask some helpers like textilize. Make sure to include them.
|
96
95
|
include TextHelper
|
@@ -100,25 +99,22 @@ module ActionView
|
|
100
99
|
#
|
101
100
|
# There are two possible formats for the +choices+ parameter, corresponding to other helpers' output:
|
102
101
|
#
|
103
|
-
# * A flat collection (see
|
104
|
-
#
|
105
|
-
# * A nested collection (see +grouped_options_for_select+).
|
102
|
+
# * A flat collection (see <tt>options_for_select</tt>).
|
103
|
+
# * A nested collection (see <tt>grouped_options_for_select</tt>).
|
106
104
|
#
|
107
|
-
#
|
105
|
+
# Example with <tt>@post.person_id => 2</tt>:
|
108
106
|
#
|
109
|
-
# select
|
107
|
+
# select :post, :person_id, Person.all.collect { |p| [ p.name, p.id ] }, { include_blank: true })
|
110
108
|
#
|
111
109
|
# would become:
|
112
110
|
#
|
113
111
|
# <select name="post[person_id]" id="post_person_id">
|
114
112
|
# <option value="" label=" "></option>
|
115
|
-
# <option value="1"
|
116
|
-
# <option value="2">Eileen</option>
|
113
|
+
# <option value="1">David</option>
|
114
|
+
# <option value="2" selected="selected">Eileen</option>
|
117
115
|
# <option value="3">Rafael</option>
|
118
116
|
# </select>
|
119
117
|
#
|
120
|
-
# assuming the associated person has ID 1.
|
121
|
-
#
|
122
118
|
# This can be used to provide a default set of options in the standard way: before rendering the create form, a
|
123
119
|
# new model instance is assigned the default options and bound to @model_name. Usually this model is not saved
|
124
120
|
# to the database. Instead, a second model object is created when the create request is received.
|
@@ -132,9 +128,9 @@ module ActionView
|
|
132
128
|
# A block can be passed to +select+ to customize how the options tags will be rendered. This
|
133
129
|
# is useful when the options tag has complex attributes.
|
134
130
|
#
|
135
|
-
# select(report,
|
131
|
+
# select(report, :campaign_ids) do
|
136
132
|
# available_campaigns.each do |c|
|
137
|
-
#
|
133
|
+
# tag.option(c.name, value: c.id, data: { tags: c.tags.to_json })
|
138
134
|
# end
|
139
135
|
# end
|
140
136
|
#
|
@@ -159,7 +155,6 @@ module ActionView
|
|
159
155
|
#
|
160
156
|
# In case if you don't want the helper to generate this hidden field you can specify
|
161
157
|
# <tt>include_hidden: false</tt> option.
|
162
|
-
#
|
163
158
|
def select(object, method, choices = nil, options = {}, html_options = {}, &block)
|
164
159
|
Tags::Select.new(object, method, self, choices, options, html_options, &block).render
|
165
160
|
end
|
@@ -183,6 +178,7 @@ module ActionView
|
|
183
178
|
#
|
184
179
|
# class Author < ActiveRecord::Base
|
185
180
|
# has_many :posts
|
181
|
+
#
|
186
182
|
# def name_with_initial
|
187
183
|
# "#{first_name.first}. #{last_name}"
|
188
184
|
# end
|
@@ -227,19 +223,19 @@ module ActionView
|
|
227
223
|
#
|
228
224
|
# Example object structure for use with this method:
|
229
225
|
#
|
226
|
+
# # attributes: id, name
|
230
227
|
# class Continent < ActiveRecord::Base
|
231
228
|
# has_many :countries
|
232
|
-
# # attribs: id, name
|
233
229
|
# end
|
234
230
|
#
|
231
|
+
# # attributes: id, name, continent_id
|
235
232
|
# class Country < ActiveRecord::Base
|
236
233
|
# belongs_to :continent
|
237
|
-
# # attribs: id, name, continent_id
|
238
234
|
# end
|
239
235
|
#
|
236
|
+
# # attributes: id, name, country_id
|
240
237
|
# class City < ActiveRecord::Base
|
241
238
|
# belongs_to :country
|
242
|
-
# # attribs: id, name, country_id
|
243
239
|
# end
|
244
240
|
#
|
245
241
|
# Sample usage:
|
@@ -258,7 +254,6 @@ module ActionView
|
|
258
254
|
# <option value="2">Ireland</option>
|
259
255
|
# </optgroup>
|
260
256
|
# </select>
|
261
|
-
#
|
262
257
|
def grouped_collection_select(object, method, collection, group_method, group_label_method, option_key_method, option_value_method, options = {}, html_options = {})
|
263
258
|
Tags::GroupedCollectionSelect.new(object, method, self, collection, group_method, group_label_method, option_key_method, option_value_method, options, html_options).render
|
264
259
|
end
|
@@ -282,21 +277,27 @@ module ActionView
|
|
282
277
|
# Finally, this method supports a <tt>:default</tt> option, which selects
|
283
278
|
# a default ActiveSupport::TimeZone if the object's time zone is +nil+.
|
284
279
|
#
|
285
|
-
# time_zone_select(
|
280
|
+
# time_zone_select(:user, :time_zone, nil, include_blank: true)
|
286
281
|
#
|
287
|
-
# time_zone_select(
|
282
|
+
# time_zone_select(:user, :time_zone, nil, default: "Pacific Time (US & Canada)")
|
288
283
|
#
|
289
|
-
# time_zone_select(
|
284
|
+
# time_zone_select(:user, :time_zone, ActiveSupport::TimeZone.us_zones, default: "Pacific Time (US & Canada)")
|
290
285
|
#
|
291
|
-
# time_zone_select(
|
286
|
+
# time_zone_select(:user, :time_zone, [ ActiveSupport::TimeZone["Alaska"], ActiveSupport::TimeZone["Hawaii"] ])
|
292
287
|
#
|
293
|
-
# time_zone_select(
|
288
|
+
# time_zone_select(:user, :time_zone, /Australia/)
|
294
289
|
#
|
295
|
-
# time_zone_select(
|
290
|
+
# time_zone_select(:user, :time_zone, ActiveSupport::TimeZone.all.sort, model: ActiveSupport::TimeZone)
|
296
291
|
def time_zone_select(object, method, priority_zones = nil, options = {}, html_options = {})
|
297
292
|
Tags::TimeZoneSelect.new(object, method, self, priority_zones, options, html_options).render
|
298
293
|
end
|
299
294
|
|
295
|
+
# Returns select and option tags for the given object and method, using
|
296
|
+
# <tt>weekday_options_for_select</tt> to generate the list of option tags.
|
297
|
+
def weekday_select(object, method, options = {}, html_options = {}, &block)
|
298
|
+
Tags::WeekdaySelect.new(object, method, self, options, html_options, &block).render
|
299
|
+
end
|
300
|
+
|
300
301
|
# Accepts a container (hash, array, enumerable, your type) and returns a string of option tags. Given a container
|
301
302
|
# where the elements respond to first and last (such as a two-element array), the "lasts" serve as option values and
|
302
303
|
# the "firsts" as option text. Hashes are turned into this form automatically, so the keys become "firsts" and values
|
@@ -593,6 +594,25 @@ module ActionView
|
|
593
594
|
zone_options.safe_concat options_for_select(convert_zones[zones], selected)
|
594
595
|
end
|
595
596
|
|
597
|
+
# Returns a string of option tags for the days of the week.
|
598
|
+
#
|
599
|
+
# Options:
|
600
|
+
# * <tt>:index_as_value</tt> - Defaults to false, set to true to use the indexes from
|
601
|
+
# `I18n.translate("date.day_names")` as the values. By default, Sunday is always 0.
|
602
|
+
# * <tt>:day_format</tt> - The I18n key of the array to use for the weekday options.
|
603
|
+
# Defaults to :day_names, set to :abbr_day_names for abbreviations.
|
604
|
+
# * <tt>:beginning_of_week</tt> - Defaults to Date.beginning_of_week.
|
605
|
+
#
|
606
|
+
# NOTE: Only the option tags are returned, you have to wrap this call in
|
607
|
+
# a regular HTML select tag.
|
608
|
+
def weekday_options_for_select(selected = nil, index_as_value: false, day_format: :day_names, beginning_of_week: Date.beginning_of_week)
|
609
|
+
day_names = I18n.translate("date.#{day_format}")
|
610
|
+
day_names = day_names.map.with_index.to_a if index_as_value
|
611
|
+
day_names = day_names.rotate(Date::DAYS_INTO_WEEK.fetch(beginning_of_week))
|
612
|
+
|
613
|
+
options_for_select(day_names, selected)
|
614
|
+
end
|
615
|
+
|
596
616
|
# Returns radio button tags for the collection of existing return values
|
597
617
|
# of +method+ for +object+'s class. The value returned from calling
|
598
618
|
# +method+ on the instance +object+ will be selected. If calling +method+
|
@@ -606,11 +626,14 @@ module ActionView
|
|
606
626
|
# retrieve the value/text.
|
607
627
|
#
|
608
628
|
# Example object structure for use with this method:
|
629
|
+
#
|
609
630
|
# class Post < ActiveRecord::Base
|
610
631
|
# belongs_to :author
|
611
632
|
# end
|
633
|
+
#
|
612
634
|
# class Author < ActiveRecord::Base
|
613
635
|
# has_many :posts
|
636
|
+
#
|
614
637
|
# def name_with_initial
|
615
638
|
# "#{first_name.first}. #{last_name}"
|
616
639
|
# end
|
@@ -793,9 +816,9 @@ module ActionView
|
|
793
816
|
|
794
817
|
def extract_values_from_collection(collection, value_method, selected)
|
795
818
|
if selected.is_a?(Proc)
|
796
|
-
collection.
|
819
|
+
collection.filter_map do |element|
|
797
820
|
element.public_send(value_method) if selected.call(element)
|
798
|
-
end
|
821
|
+
end
|
799
822
|
else
|
800
823
|
selected
|
801
824
|
end
|
@@ -859,6 +882,18 @@ module ActionView
|
|
859
882
|
@template.time_zone_select(@object_name, method, priority_zones, objectify_options(options), @default_html_options.merge(html_options))
|
860
883
|
end
|
861
884
|
|
885
|
+
# Wraps ActionView::Helpers::FormOptionsHelper#weekday_select for form builders:
|
886
|
+
#
|
887
|
+
# <%= form_for @user do |f| %>
|
888
|
+
# <%= f.weekday_select :weekday, include_blank: true %>
|
889
|
+
# <%= f.submit %>
|
890
|
+
# <% end %>
|
891
|
+
#
|
892
|
+
# Please refer to the documentation of the base helper for details.
|
893
|
+
def weekday_select(method, options = {}, html_options = {})
|
894
|
+
@template.weekday_select(@object_name, method, objectify_options(options), @default_html_options.merge(html_options))
|
895
|
+
end
|
896
|
+
|
862
897
|
# Wraps ActionView::Helpers::FormOptionsHelper#collection_check_boxes for form builders:
|
863
898
|
#
|
864
899
|
# <%= form_for @post do |f| %>
|
@@ -1,14 +1,14 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require "cgi"
|
4
|
-
require "action_view/helpers/
|
4
|
+
require "action_view/helpers/url_helper"
|
5
|
+
require "action_view/helpers/text_helper"
|
5
6
|
require "active_support/core_ext/string/output_safety"
|
6
7
|
require "active_support/core_ext/module/attribute_accessors"
|
7
|
-
require "active_support/core_ext/symbol/starts_ends_with"
|
8
8
|
|
9
9
|
module ActionView
|
10
10
|
# = Action View Form Tag Helpers
|
11
|
-
module Helpers
|
11
|
+
module Helpers # :nodoc:
|
12
12
|
# Provides a number of methods for creating form tags that don't rely on an Active Record object assigned to the template like
|
13
13
|
# FormHelper does. Instead, you provide the names and values manually.
|
14
14
|
#
|
@@ -62,6 +62,9 @@ module ActionView
|
|
62
62
|
#
|
63
63
|
# <%= form_tag('/posts', remote: true) %>
|
64
64
|
# # => <form action="/posts" method="post" data-remote="true">
|
65
|
+
|
66
|
+
# form_tag(false, method: :get)
|
67
|
+
# # => <form method="get">
|
65
68
|
#
|
66
69
|
# form_tag('http://far.away.com/form', authenticity_token: false)
|
67
70
|
# # form without authenticity token
|
@@ -78,6 +81,68 @@ module ActionView
|
|
78
81
|
end
|
79
82
|
end
|
80
83
|
|
84
|
+
# Generate an HTML <tt>id</tt> attribute value for the given name and
|
85
|
+
# field combination
|
86
|
+
#
|
87
|
+
# Return the value generated by the <tt>FormBuilder</tt> for the given
|
88
|
+
# attribute name.
|
89
|
+
#
|
90
|
+
# <%= label_tag :post, :title %>
|
91
|
+
# <%= text_field_tag :post, :title, aria: { describedby: field_id(:post, :title, :error) } %>
|
92
|
+
# <%= tag.span("is blank", id: field_id(:post, :title, :error) %>
|
93
|
+
#
|
94
|
+
# In the example above, the <tt><input type="text"></tt> element built by
|
95
|
+
# the call to <tt>text_field_tag</tt> declares an
|
96
|
+
# <tt>aria-describedby</tt> attribute referencing the <tt><span></tt>
|
97
|
+
# element, sharing a common <tt>id</tt> root (<tt>post_title</tt>, in this
|
98
|
+
# case).
|
99
|
+
def field_id(object_name, method_name, *suffixes, index: nil)
|
100
|
+
if object_name.respond_to?(:model_name)
|
101
|
+
object_name = object_name.model_name.singular
|
102
|
+
end
|
103
|
+
|
104
|
+
sanitized_object_name = object_name.to_s.gsub(/\]\[|[^-a-zA-Z0-9:.]/, "_").delete_suffix("_")
|
105
|
+
|
106
|
+
sanitized_method_name = method_name.to_s.delete_suffix("?")
|
107
|
+
|
108
|
+
# a little duplication to construct fewer strings
|
109
|
+
if sanitized_object_name.empty?
|
110
|
+
sanitized_method_name
|
111
|
+
elsif suffixes.any?
|
112
|
+
[sanitized_object_name, index, sanitized_method_name, *suffixes].compact.join("_")
|
113
|
+
elsif index
|
114
|
+
"#{sanitized_object_name}_#{index}_#{sanitized_method_name}"
|
115
|
+
else
|
116
|
+
"#{sanitized_object_name}_#{sanitized_method_name}"
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
# Generate an HTML <tt>name</tt> attribute value for the given name and
|
121
|
+
# field combination
|
122
|
+
#
|
123
|
+
# Return the value generated by the <tt>FormBuilder</tt> for the given
|
124
|
+
# attribute name.
|
125
|
+
#
|
126
|
+
# <%= text_field_tag :post, :title, name: field_name(:post, :title, :subtitle) %>
|
127
|
+
# <%# => <input type="text" name="post[title][subtitle]">
|
128
|
+
#
|
129
|
+
# <%= text_field_tag :post, :tag, name: field_name(:post, :tag, multiple: true) %>
|
130
|
+
# <%# => <input type="text" name="post[tag][]">
|
131
|
+
#
|
132
|
+
def field_name(object_name, method_name, *method_names, multiple: false, index: nil)
|
133
|
+
names = method_names.map! { |name| "[#{name}]" }.join
|
134
|
+
|
135
|
+
# a little duplication to construct fewer strings
|
136
|
+
case
|
137
|
+
when object_name.empty?
|
138
|
+
"#{method_name}#{names}#{multiple ? "[]" : ""}"
|
139
|
+
when index
|
140
|
+
"#{object_name}[#{index}][#{method_name}]#{names}#{multiple ? "[]" : ""}"
|
141
|
+
else
|
142
|
+
"#{object_name}[#{method_name}]#{names}#{multiple ? "[]" : ""}"
|
143
|
+
end
|
144
|
+
end
|
145
|
+
|
81
146
|
# Creates a dropdown selection box, or if the <tt>:multiple</tt> option is set to true, a multiple
|
82
147
|
# choice selection box.
|
83
148
|
#
|
@@ -167,8 +232,8 @@ module ActionView
|
|
167
232
|
# * <tt>:size</tt> - The number of visible characters that will fit in the input.
|
168
233
|
# * <tt>:maxlength</tt> - The maximum number of characters that the browser will allow the user to enter.
|
169
234
|
# * <tt>:placeholder</tt> - The text contained in the field by default which is removed when the field receives focus.
|
170
|
-
# If set to true, use
|
171
|
-
# (through helpers.
|
235
|
+
# If set to true, use the translation found in the current I18n locale
|
236
|
+
# (through helpers.placeholder.<modelname>.<attribute>).
|
172
237
|
# * Any other key creates standard HTML attributes for the tag.
|
173
238
|
#
|
174
239
|
# ==== Examples
|
@@ -241,7 +306,7 @@ module ActionView
|
|
241
306
|
# # => <input id="collected_input" name="collected_input" onchange="alert('Input collected!')"
|
242
307
|
# # type="hidden" value="" />
|
243
308
|
def hidden_field_tag(name, value = nil, options = {})
|
244
|
-
text_field_tag(name, value, options.merge(type: :hidden))
|
309
|
+
text_field_tag(name, value, options.merge(type: :hidden, autocomplete: "off"))
|
245
310
|
end
|
246
311
|
|
247
312
|
# Creates a file upload field. If you are using file uploads then you will also need
|
@@ -280,7 +345,7 @@ module ActionView
|
|
280
345
|
# file_field_tag 'file', accept: 'text/html', class: 'upload', value: 'index.html'
|
281
346
|
# # => <input accept="text/html" class="upload" id="file" name="file" type="file" value="index.html" />
|
282
347
|
def file_field_tag(name, options = {})
|
283
|
-
text_field_tag(name, nil, convert_direct_upload_option_to_url(options.merge(type: :file)))
|
348
|
+
text_field_tag(name, nil, convert_direct_upload_option_to_url(name, options.merge(type: :file)))
|
284
349
|
end
|
285
350
|
|
286
351
|
# Creates a password field, a masked text field that will hide the users input behind a mask character.
|
@@ -417,16 +482,6 @@ module ActionView
|
|
417
482
|
# * <tt>:disabled</tt> - If true, the user will not be able to use this input.
|
418
483
|
# * Any other key creates standard HTML options for the tag.
|
419
484
|
#
|
420
|
-
# ==== Data attributes
|
421
|
-
#
|
422
|
-
# * <tt>confirm: 'question?'</tt> - If present the unobtrusive JavaScript
|
423
|
-
# drivers will provide a prompt with the question specified. If the user accepts,
|
424
|
-
# the form is processed normally, otherwise no action is taken.
|
425
|
-
# * <tt>:disable_with</tt> - Value of this parameter will be used as the value for a
|
426
|
-
# disabled version of the submit button when the form is submitted. This feature is
|
427
|
-
# provided by the unobtrusive JavaScript driver. To disable this feature for a single submit tag
|
428
|
-
# pass <tt>:data => { disable_with: false }</tt> Defaults to value attribute.
|
429
|
-
#
|
430
485
|
# ==== Examples
|
431
486
|
# submit_tag
|
432
487
|
# # => <input name="commit" data-disable-with="Save changes" type="submit" value="Save changes" />
|
@@ -437,15 +492,28 @@ module ActionView
|
|
437
492
|
# submit_tag "Save edits", disabled: true
|
438
493
|
# # => <input disabled="disabled" name="commit" data-disable-with="Save edits" type="submit" value="Save edits" />
|
439
494
|
#
|
440
|
-
# submit_tag "Complete sale", data: { disable_with: "Submitting..." }
|
441
|
-
# # => <input name="commit" data-disable-with="Submitting..." type="submit" value="Complete sale" />
|
442
|
-
#
|
443
495
|
# submit_tag nil, class: "form_submit"
|
444
496
|
# # => <input class="form_submit" name="commit" type="submit" />
|
445
497
|
#
|
446
498
|
# submit_tag "Edit", class: "edit_button"
|
447
499
|
# # => <input class="edit_button" data-disable-with="Edit" name="commit" type="submit" value="Edit" />
|
448
500
|
#
|
501
|
+
# ==== Deprecated: Rails UJS attributes
|
502
|
+
#
|
503
|
+
# Prior to Rails 7, Rails shipped with the JavaScript library called @rails/ujs on by default. Following Rails 7,
|
504
|
+
# this library is no longer on by default. This library integrated with the following options:
|
505
|
+
#
|
506
|
+
# * <tt>confirm: 'question?'</tt> - If present the unobtrusive JavaScript
|
507
|
+
# drivers will provide a prompt with the question specified. If the user accepts,
|
508
|
+
# the form is processed normally, otherwise no action is taken.
|
509
|
+
# * <tt>:disable_with</tt> - Value of this parameter will be used as the value for a
|
510
|
+
# disabled version of the submit button when the form is submitted. This feature is
|
511
|
+
# provided by the unobtrusive JavaScript driver. To disable this feature for a single submit tag
|
512
|
+
# pass <tt>:data => { disable_with: false }</tt> Defaults to value attribute.
|
513
|
+
#
|
514
|
+
# submit_tag "Complete sale", data: { disable_with: "Submitting..." }
|
515
|
+
# # => <input name="commit" data-disable-with="Submitting..." type="submit" value="Complete sale" />
|
516
|
+
#
|
449
517
|
# submit_tag "Save", data: { confirm: "Are you sure?" }
|
450
518
|
# # => <input name='commit' type='submit' value='Save' data-disable-with="Save" data-confirm="Are you sure?" />
|
451
519
|
#
|
@@ -470,17 +538,6 @@ module ActionView
|
|
470
538
|
# use this input.
|
471
539
|
# * Any other key creates standard HTML options for the tag.
|
472
540
|
#
|
473
|
-
# ==== Data attributes
|
474
|
-
#
|
475
|
-
# * <tt>confirm: 'question?'</tt> - If present, the
|
476
|
-
# unobtrusive JavaScript drivers will provide a prompt with
|
477
|
-
# the question specified. If the user accepts, the form is
|
478
|
-
# processed normally, otherwise no action is taken.
|
479
|
-
# * <tt>:disable_with</tt> - Value of this parameter will be
|
480
|
-
# used as the value for a disabled version of the submit
|
481
|
-
# button when the form is submitted. This feature is provided
|
482
|
-
# by the unobtrusive JavaScript driver.
|
483
|
-
#
|
484
541
|
# ==== Examples
|
485
542
|
# button_tag
|
486
543
|
# # => <button name="button" type="submit">Button</button>
|
@@ -501,6 +558,20 @@ module ActionView
|
|
501
558
|
# # <strong>Ask me!</strong>
|
502
559
|
# # </button>
|
503
560
|
#
|
561
|
+
# ==== Deprecated: Rails UJS attributes
|
562
|
+
#
|
563
|
+
# Prior to Rails 7, Rails shipped with a JavaScript library called @rails/ujs on by default. Following Rails 7,
|
564
|
+
# this library is no longer on by default. This library integrated with the following options:
|
565
|
+
#
|
566
|
+
# * <tt>confirm: 'question?'</tt> - If present, the
|
567
|
+
# unobtrusive JavaScript drivers will provide a prompt with
|
568
|
+
# the question specified. If the user accepts, the form is
|
569
|
+
# processed normally, otherwise no action is taken.
|
570
|
+
# * <tt>:disable_with</tt> - Value of this parameter will be
|
571
|
+
# used as the value for a disabled version of the submit
|
572
|
+
# button when the form is submitted. This feature is provided
|
573
|
+
# by the unobtrusive JavaScript driver.
|
574
|
+
#
|
504
575
|
# button_tag "Save", data: { confirm: "Are you sure?" }
|
505
576
|
# # => <button name="button" type="submit" data-confirm="Are you sure?">Save</button>
|
506
577
|
#
|
@@ -677,6 +748,7 @@ module ActionView
|
|
677
748
|
# * <tt>:min</tt> - The minimum acceptable value.
|
678
749
|
# * <tt>:max</tt> - The maximum acceptable value.
|
679
750
|
# * <tt>:step</tt> - The acceptable value granularity.
|
751
|
+
# * <tt>:include_seconds</tt> - Include seconds and ms in the output timestamp format (true by default).
|
680
752
|
# * Otherwise accepts the same options as text_field_tag.
|
681
753
|
def time_field_tag(name, value = nil, options = {})
|
682
754
|
text_field_tag(name, value, options.merge(type: :time))
|
@@ -823,7 +895,7 @@ module ActionView
|
|
823
895
|
# Use raw HTML to ensure the value is written as an HTML entity; it
|
824
896
|
# needs to be the right character regardless of which encoding the
|
825
897
|
# browser infers.
|
826
|
-
'<input name="utf8" type="hidden" value="✓" />'.html_safe
|
898
|
+
'<input name="utf8" type="hidden" value="✓" autocomplete="off" />'.html_safe
|
827
899
|
end
|
828
900
|
|
829
901
|
private
|
@@ -832,13 +904,17 @@ module ActionView
|
|
832
904
|
html_options["enctype"] = "multipart/form-data" if html_options.delete("multipart")
|
833
905
|
# The following URL is unescaped, this is just a hash of options, and it is the
|
834
906
|
# responsibility of the caller to escape all the values.
|
835
|
-
html_options["action"]
|
907
|
+
if url_for_options == false || html_options["action"] == false
|
908
|
+
html_options.delete("action")
|
909
|
+
else
|
910
|
+
html_options["action"] = url_for(url_for_options)
|
911
|
+
end
|
836
912
|
html_options["accept-charset"] = "UTF-8"
|
837
913
|
|
838
914
|
html_options["data-remote"] = true if html_options.delete("remote")
|
839
915
|
|
840
916
|
if html_options["data-remote"] &&
|
841
|
-
|
917
|
+
embed_authenticity_token_in_remote_forms == false &&
|
842
918
|
html_options["authenticity_token"].blank?
|
843
919
|
# The authenticity token is taken from the meta tag in this case
|
844
920
|
html_options["authenticity_token"] = false
|
@@ -887,7 +963,7 @@ module ActionView
|
|
887
963
|
|
888
964
|
def form_tag_with_body(html_options, content)
|
889
965
|
output = form_tag_html(html_options)
|
890
|
-
output << content
|
966
|
+
output << content.to_s if content
|
891
967
|
output.safe_concat("</form>")
|
892
968
|
end
|
893
969
|
|
@@ -911,9 +987,23 @@ module ActionView
|
|
911
987
|
tag_options.delete("data-disable-with")
|
912
988
|
end
|
913
989
|
|
914
|
-
def convert_direct_upload_option_to_url(options)
|
990
|
+
def convert_direct_upload_option_to_url(name, options)
|
915
991
|
if options.delete(:direct_upload) && respond_to?(:rails_direct_uploads_url)
|
916
992
|
options["data-direct-upload-url"] = rails_direct_uploads_url
|
993
|
+
|
994
|
+
if options[:object] && options[:object].class.respond_to?(:reflect_on_attachment)
|
995
|
+
attachment_reflection = options[:object].class.reflect_on_attachment(name)
|
996
|
+
|
997
|
+
class_with_attachment = "#{options[:object].class.name.underscore}##{name}"
|
998
|
+
options["data-direct-upload-attachment-name"] = class_with_attachment
|
999
|
+
|
1000
|
+
service_name = attachment_reflection.options[:service_name] || ActiveStorage::Blob.service.name
|
1001
|
+
options["data-direct-upload-token"] = ActiveStorage::DirectUploadToken.generate_direct_upload_token(
|
1002
|
+
class_with_attachment,
|
1003
|
+
service_name,
|
1004
|
+
session
|
1005
|
+
)
|
1006
|
+
end
|
917
1007
|
end
|
918
1008
|
options
|
919
1009
|
end
|
@@ -1,12 +1,10 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require "action_view/helpers/tag_helper"
|
4
|
-
|
5
3
|
module ActionView
|
6
|
-
module Helpers
|
4
|
+
module Helpers # :nodoc:
|
7
5
|
module JavaScriptHelper
|
8
6
|
JS_ESCAPE_MAP = {
|
9
|
-
|
7
|
+
"\\" => "\\\\",
|
10
8
|
"</" => '<\/',
|
11
9
|
"\r\n" => '\n',
|
12
10
|
"\n" => '\n',
|
@@ -89,7 +87,7 @@ module ActionView
|
|
89
87
|
content_tag("script", javascript_cdata_section(content), html_options)
|
90
88
|
end
|
91
89
|
|
92
|
-
def javascript_cdata_section(content)
|
90
|
+
def javascript_cdata_section(content) # :nodoc:
|
93
91
|
"\n//#{cdata_section("\n#{content}\n//")}\n".html_safe
|
94
92
|
end
|
95
93
|
end
|
@@ -6,7 +6,7 @@ require "active_support/number_helper"
|
|
6
6
|
|
7
7
|
module ActionView
|
8
8
|
# = Action View Number Helpers
|
9
|
-
module Helpers
|
9
|
+
module Helpers # :nodoc:
|
10
10
|
# Provides methods for converting numbers into formatted strings.
|
11
11
|
# Methods are provided for phone numbers, currency, percentage,
|
12
12
|
# precision, positional notation, file size and pretty printing.
|
@@ -448,9 +448,8 @@ module ActionView
|
|
448
448
|
end
|
449
449
|
|
450
450
|
def parse_float(number, raise_error)
|
451
|
-
Float(number)
|
452
|
-
|
453
|
-
raise InvalidNumberError, number if raise_error
|
451
|
+
result = Float(number, exception: false)
|
452
|
+
raise InvalidNumberError, number if result.nil? && raise_error
|
454
453
|
end
|
455
454
|
end
|
456
455
|
end
|
@@ -2,9 +2,9 @@
|
|
2
2
|
|
3
3
|
require "active_support/core_ext/string/output_safety"
|
4
4
|
|
5
|
-
module ActionView
|
5
|
+
module ActionView # :nodoc:
|
6
6
|
# = Action View Raw Output Helper
|
7
|
-
module Helpers
|
7
|
+
module Helpers # :nodoc:
|
8
8
|
module OutputSafetyHelper
|
9
9
|
# This method outputs without escaping a string. Since escaping tags is
|
10
10
|
# now default, this can be used when you don't want Rails to automatically
|
@@ -4,7 +4,7 @@ require "rails-html-sanitizer"
|
|
4
4
|
|
5
5
|
module ActionView
|
6
6
|
# = Action View Sanitize Helpers
|
7
|
-
module Helpers
|
7
|
+
module Helpers # :nodoc:
|
8
8
|
# The SanitizeHelper module provides a set of methods for scrubbing text of undesired HTML elements.
|
9
9
|
# These helper methods extend Action View making them callable within your template files.
|
10
10
|
module SanitizeHelper
|
@@ -121,7 +121,7 @@ module ActionView
|
|
121
121
|
self.class.link_sanitizer.sanitize(html)
|
122
122
|
end
|
123
123
|
|
124
|
-
module ClassMethods
|
124
|
+
module ClassMethods # :nodoc:
|
125
125
|
attr_writer :full_sanitizer, :link_sanitizer, :safe_list_sanitizer
|
126
126
|
|
127
127
|
def sanitizer_vendor
|