actionview 6.1.7.2 → 7.1.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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +299 -277
- data/MIT-LICENSE +2 -1
- data/README.rdoc +3 -3
- data/app/assets/javascripts/rails-ujs.esm.js +686 -0
- data/app/assets/javascripts/rails-ujs.js +630 -0
- data/lib/action_view/base.rb +37 -19
- data/lib/action_view/buffers.rb +107 -9
- data/lib/action_view/cache_expiry.rb +48 -37
- data/lib/action_view/context.rb +1 -1
- 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/deprecator.rb +7 -0
- data/lib/action_view/digestor.rb +8 -5
- 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 +3 -3
- data/lib/action_view/helpers/asset_tag_helper.rb +200 -60
- data/lib/action_view/helpers/asset_url_helper.rb +22 -21
- data/lib/action_view/helpers/atom_feed_helper.rb +8 -9
- data/lib/action_view/helpers/cache_helper.rb +55 -12
- data/lib/action_view/helpers/capture_helper.rb +34 -14
- data/lib/action_view/helpers/content_exfiltration_prevention_helper.rb +70 -0
- data/lib/action_view/helpers/controller_helper.rb +8 -2
- data/lib/action_view/helpers/csp_helper.rb +3 -3
- data/lib/action_view/helpers/csrf_helper.rb +4 -4
- data/lib/action_view/helpers/date_helper.rb +123 -57
- data/lib/action_view/helpers/debug_helper.rb +6 -4
- data/lib/action_view/helpers/form_helper.rb +253 -97
- data/lib/action_view/helpers/form_options_helper.rb +72 -34
- data/lib/action_view/helpers/form_tag_helper.rb +189 -58
- data/lib/action_view/helpers/javascript_helper.rb +4 -5
- data/lib/action_view/helpers/number_helper.rb +43 -335
- data/lib/action_view/helpers/output_safety_helper.rb +6 -6
- data/lib/action_view/helpers/rendering_helper.rb +6 -7
- data/lib/action_view/helpers/sanitize_helper.rb +54 -24
- data/lib/action_view/helpers/tag_helper.rb +42 -35
- data/lib/action_view/helpers/tags/base.rb +16 -77
- data/lib/action_view/helpers/tags/check_box.rb +1 -1
- data/lib/action_view/helpers/tags/collection_check_boxes.rb +1 -0
- data/lib/action_view/helpers/tags/collection_radio_buttons.rb +1 -0
- data/lib/action_view/helpers/tags/collection_select.rb +4 -1
- data/lib/action_view/helpers/tags/date_field.rb +1 -1
- data/lib/action_view/helpers/tags/date_select.rb +2 -0
- data/lib/action_view/helpers/tags/datetime_field.rb +14 -6
- data/lib/action_view/helpers/tags/datetime_local_field.rb +11 -2
- data/lib/action_view/helpers/tags/file_field.rb +16 -0
- data/lib/action_view/helpers/tags/grouped_collection_select.rb +3 -0
- data/lib/action_view/helpers/tags/month_field.rb +1 -1
- data/lib/action_view/helpers/tags/select.rb +4 -1
- data/lib/action_view/helpers/tags/select_renderer.rb +56 -0
- data/lib/action_view/helpers/tags/time_field.rb +11 -2
- data/lib/action_view/helpers/tags/time_zone_select.rb +3 -0
- data/lib/action_view/helpers/tags/week_field.rb +1 -1
- data/lib/action_view/helpers/tags/weekday_select.rb +31 -0
- data/lib/action_view/helpers/tags.rb +5 -2
- data/lib/action_view/helpers/text_helper.rb +180 -97
- data/lib/action_view/helpers/translation_helper.rb +14 -45
- data/lib/action_view/helpers/url_helper.rb +230 -132
- data/lib/action_view/helpers.rb +27 -25
- data/lib/action_view/layouts.rb +15 -10
- data/lib/action_view/log_subscriber.rb +49 -32
- data/lib/action_view/lookup_context.rb +58 -61
- data/lib/action_view/model_naming.rb +2 -2
- data/lib/action_view/path_registry.rb +57 -0
- data/lib/action_view/path_set.rb +28 -35
- data/lib/action_view/railtie.rb +44 -9
- data/lib/action_view/record_identifier.rb +16 -9
- data/lib/action_view/render_parser.rb +188 -0
- data/lib/action_view/renderer/abstract_renderer.rb +3 -3
- data/lib/action_view/renderer/collection_renderer.rb +10 -2
- data/lib/action_view/renderer/partial_renderer/collection_caching.rb +21 -3
- data/lib/action_view/renderer/partial_renderer.rb +3 -36
- data/lib/action_view/renderer/renderer.rb +6 -4
- data/lib/action_view/renderer/streaming_template_renderer.rb +6 -5
- data/lib/action_view/renderer/template_renderer.rb +9 -4
- data/lib/action_view/rendering.rb +25 -7
- data/lib/action_view/ripper_ast_parser.rb +198 -0
- data/lib/action_view/routing_url_for.rb +8 -5
- data/lib/action_view/template/error.rb +122 -14
- data/lib/action_view/template/handlers/builder.rb +4 -4
- data/lib/action_view/template/handlers/erb/erubi.rb +23 -27
- data/lib/action_view/template/handlers/erb.rb +79 -1
- data/lib/action_view/template/handlers.rb +4 -4
- data/lib/action_view/template/html.rb +4 -4
- data/lib/action_view/template/inline.rb +3 -3
- data/lib/action_view/template/raw_file.rb +4 -4
- data/lib/action_view/template/renderable.rb +1 -1
- data/lib/action_view/template/resolver.rb +96 -313
- data/lib/action_view/template/text.rb +4 -4
- data/lib/action_view/template/types.rb +25 -32
- data/lib/action_view/template.rb +245 -41
- data/lib/action_view/template_details.rb +66 -0
- data/lib/action_view/template_path.rb +66 -0
- data/lib/action_view/test_case.rb +182 -23
- data/lib/action_view/testing/resolvers.rb +11 -12
- data/lib/action_view/unbound_template.rb +43 -7
- data/lib/action_view/version.rb +1 -1
- data/lib/action_view/view_paths.rb +19 -28
- data/lib/action_view.rb +6 -4
- data/lib/assets/compiled/rails-ujs.js +36 -5
- metadata +32 -25
|
@@ -1,13 +1,15 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require "action_view/helpers/javascript_helper"
|
|
4
3
|
require "active_support/core_ext/array/access"
|
|
5
4
|
require "active_support/core_ext/hash/keys"
|
|
6
5
|
require "active_support/core_ext/string/output_safety"
|
|
6
|
+
require "action_view/helpers/content_exfiltration_prevention_helper"
|
|
7
|
+
require "action_view/helpers/tag_helper"
|
|
7
8
|
|
|
8
9
|
module ActionView
|
|
9
|
-
|
|
10
|
-
|
|
10
|
+
module Helpers # :nodoc:
|
|
11
|
+
# = Action View URL \Helpers
|
|
12
|
+
#
|
|
11
13
|
# Provides a set of methods for making links and getting URLs that
|
|
12
14
|
# depend on the routing subsystem (see ActionDispatch::Routing).
|
|
13
15
|
# This allows you to use the same format for links in views
|
|
@@ -22,6 +24,7 @@ module ActionView
|
|
|
22
24
|
extend ActiveSupport::Concern
|
|
23
25
|
|
|
24
26
|
include TagHelper
|
|
27
|
+
include ContentExfiltrationPreventionHelper
|
|
25
28
|
|
|
26
29
|
module ClassMethods
|
|
27
30
|
def _url_for_modules
|
|
@@ -29,6 +32,8 @@ module ActionView
|
|
|
29
32
|
end
|
|
30
33
|
end
|
|
31
34
|
|
|
35
|
+
mattr_accessor :button_to_generates_button_tag, default: false
|
|
36
|
+
|
|
32
37
|
# Basic implementation of url_for to allow use helpers without routes existence
|
|
33
38
|
def url_for(options = nil) # :nodoc:
|
|
34
39
|
case options
|
|
@@ -83,37 +88,15 @@ module ActionView
|
|
|
83
88
|
# # name
|
|
84
89
|
# end
|
|
85
90
|
#
|
|
91
|
+
# link_to(active_record_model)
|
|
92
|
+
#
|
|
86
93
|
# ==== Options
|
|
87
94
|
# * <tt>:data</tt> - This option can be used to add custom data attributes.
|
|
88
|
-
# * <tt>method: symbol of HTTP verb</tt> - This modifier will dynamically
|
|
89
|
-
# create an HTML form and immediately submit the form for processing using
|
|
90
|
-
# the HTTP verb specified. Useful for having links perform a POST operation
|
|
91
|
-
# in dangerous actions like deleting a record (which search bots can follow
|
|
92
|
-
# while spidering your site). Supported verbs are <tt>:post</tt>, <tt>:delete</tt>, <tt>:patch</tt>, and <tt>:put</tt>.
|
|
93
|
-
# Note that if the user has JavaScript disabled, the request will fall back
|
|
94
|
-
# to using GET. If <tt>href: '#'</tt> is used and the user has JavaScript
|
|
95
|
-
# disabled clicking the link will have no effect. If you are relying on the
|
|
96
|
-
# POST behavior, you should check for it in your controller's action by using
|
|
97
|
-
# the request object's methods for <tt>post?</tt>, <tt>delete?</tt>, <tt>patch?</tt>, or <tt>put?</tt>.
|
|
98
|
-
# * <tt>remote: true</tt> - This will allow the unobtrusive JavaScript
|
|
99
|
-
# driver to make an Ajax request to the URL in question instead of following
|
|
100
|
-
# the link. The drivers each provide mechanisms for listening for the
|
|
101
|
-
# completion of the Ajax request and performing JavaScript operations once
|
|
102
|
-
# they're complete
|
|
103
|
-
#
|
|
104
|
-
# ==== Data attributes
|
|
105
|
-
#
|
|
106
|
-
# * <tt>confirm: 'question?'</tt> - This will allow the unobtrusive JavaScript
|
|
107
|
-
# driver to prompt with the question specified (in this case, the
|
|
108
|
-
# resulting text would be <tt>question?</tt>. If the user accepts, the
|
|
109
|
-
# link is processed normally, otherwise no action is taken.
|
|
110
|
-
# * <tt>:disable_with</tt> - Value of this parameter will be used as the
|
|
111
|
-
# name for a disabled version of the link. This feature is provided by
|
|
112
|
-
# the unobtrusive JavaScript driver.
|
|
113
95
|
#
|
|
114
96
|
# ==== Examples
|
|
97
|
+
#
|
|
115
98
|
# Because it relies on +url_for+, +link_to+ supports both older-style controller/action/id arguments
|
|
116
|
-
# and newer RESTful routes. Current Rails style favors RESTful routes whenever possible, so base
|
|
99
|
+
# and newer RESTful routes. Current \Rails style favors RESTful routes whenever possible, so base
|
|
117
100
|
# your application on resources and use
|
|
118
101
|
#
|
|
119
102
|
# link_to "Profile", profile_path(@profile)
|
|
@@ -144,6 +127,12 @@ module ActionView
|
|
|
144
127
|
# link_to nil, "http://example.com"
|
|
145
128
|
# # => <a href="http://www.example.com">http://www.example.com</a>
|
|
146
129
|
#
|
|
130
|
+
# More concise yet, when +name+ is an Active Record model that defines a
|
|
131
|
+
# +to_s+ method returning a default value or a model instance attribute
|
|
132
|
+
#
|
|
133
|
+
# link_to @profile
|
|
134
|
+
# # => <a href="http://www.example.com/profiles/1">Eileen</a>
|
|
135
|
+
#
|
|
147
136
|
# You can use a block as well if your link target is hard to fit into the name parameter. ERB example:
|
|
148
137
|
#
|
|
149
138
|
# <%= link_to(@profile) do %>
|
|
@@ -179,27 +168,76 @@ module ActionView
|
|
|
179
168
|
# link_to "Nonsense search", searches_path(foo: "bar", baz: "quux")
|
|
180
169
|
# # => <a href="/searches?foo=bar&baz=quux">Nonsense search</a>
|
|
181
170
|
#
|
|
182
|
-
#
|
|
171
|
+
# You can set any link attributes such as <tt>target</tt>, <tt>rel</tt>, <tt>type</tt>:
|
|
172
|
+
#
|
|
173
|
+
# link_to "External link", "http://www.rubyonrails.org/", target: "_blank", rel: "nofollow"
|
|
174
|
+
# # => <a href="http://www.rubyonrails.org/" target="_blank" rel="nofollow">External link</a>
|
|
175
|
+
#
|
|
176
|
+
# ==== Turbo
|
|
177
|
+
#
|
|
178
|
+
# Rails 7 ships with Turbo enabled by default. Turbo provides the following +:data+ options:
|
|
179
|
+
#
|
|
180
|
+
# * <tt>turbo_method: symbol of HTTP verb</tt> - Performs a Turbo link visit
|
|
181
|
+
# with the given HTTP verb. Forms are recommended when performing non-+GET+ requests.
|
|
182
|
+
# Only use <tt>data-turbo-method</tt> where a form is not possible.
|
|
183
|
+
#
|
|
184
|
+
# * <tt>turbo_confirm: "question?"</tt> - Adds a confirmation dialog to the link with the
|
|
185
|
+
# given value.
|
|
183
186
|
#
|
|
184
|
-
#
|
|
185
|
-
#
|
|
187
|
+
# {Consult the Turbo Handbook for more information on the options
|
|
188
|
+
# above.}[https://turbo.hotwired.dev/handbook/drive#performing-visits-with-a-different-method]
|
|
186
189
|
#
|
|
187
|
-
#
|
|
190
|
+
# ===== \Examples
|
|
191
|
+
#
|
|
192
|
+
# link_to "Delete profile", @profile, data: { turbo_method: :delete }
|
|
193
|
+
# # => <a href="/profiles/1" data-turbo-method="delete">Delete profile</a>
|
|
194
|
+
#
|
|
195
|
+
# link_to "Visit Other Site", "https://rubyonrails.org/", data: { turbo_confirm: "Are you sure?" }
|
|
196
|
+
# # => <a href="https://rubyonrails.org/" data-turbo-confirm="Are you sure?">Visit Other Site</a>
|
|
197
|
+
#
|
|
198
|
+
# ==== Deprecated: \Rails UJS Attributes
|
|
199
|
+
#
|
|
200
|
+
# Prior to \Rails 7, \Rails shipped with a JavaScript library called <tt>@rails/ujs</tt> on by default. Following \Rails 7,
|
|
201
|
+
# this library is no longer on by default. This library integrated with the following options:
|
|
202
|
+
#
|
|
203
|
+
# * <tt>method: symbol of HTTP verb</tt> - This modifier will dynamically
|
|
204
|
+
# create an HTML form and immediately submit the form for processing using
|
|
205
|
+
# the HTTP verb specified. Useful for having links perform a POST operation
|
|
206
|
+
# in dangerous actions like deleting a record (which search bots can follow
|
|
207
|
+
# while spidering your site). Supported verbs are <tt>:post</tt>, <tt>:delete</tt>, <tt>:patch</tt>, and <tt>:put</tt>.
|
|
208
|
+
# Note that if the user has JavaScript disabled, the request will fall back
|
|
209
|
+
# to using GET. If <tt>href: '#'</tt> is used and the user has JavaScript
|
|
210
|
+
# disabled clicking the link will have no effect. If you are relying on the
|
|
211
|
+
# POST behavior, you should check for it in your controller's action by using
|
|
212
|
+
# the request object's methods for <tt>post?</tt>, <tt>delete?</tt>, <tt>patch?</tt>, or <tt>put?</tt>.
|
|
213
|
+
# * <tt>remote: true</tt> - This will allow <tt>@rails/ujs</tt>
|
|
214
|
+
# to make an Ajax request to the URL in question instead of following
|
|
215
|
+
# the link.
|
|
216
|
+
#
|
|
217
|
+
# <tt>@rails/ujs</tt> also integrated with the following +:data+ options:
|
|
218
|
+
#
|
|
219
|
+
# * <tt>confirm: "question?"</tt> - This will allow <tt>@rails/ujs</tt>
|
|
220
|
+
# to prompt with the question specified (in this case, the
|
|
221
|
+
# resulting text would be <tt>question?</tt>). If the user accepts, the
|
|
222
|
+
# link is processed normally, otherwise no action is taken.
|
|
223
|
+
# * <tt>:disable_with</tt> - Value of this parameter will be used as the
|
|
224
|
+
# name for a disabled version of the link.
|
|
225
|
+
#
|
|
226
|
+
# ===== \Rails UJS Examples
|
|
227
|
+
#
|
|
228
|
+
# link_to "Remove Profile", profile_path(@profile), method: :delete
|
|
229
|
+
# # => <a href="/profiles/1" rel="nofollow" data-method="delete">Remove Profile</a>
|
|
188
230
|
#
|
|
189
231
|
# link_to "Visit Other Site", "http://www.rubyonrails.org/", data: { confirm: "Are you sure?" }
|
|
190
232
|
# # => <a href="http://www.rubyonrails.org/" data-confirm="Are you sure?">Visit Other Site</a>
|
|
191
233
|
#
|
|
192
|
-
# Also you can set any link attributes such as <tt>target</tt>, <tt>rel</tt>, <tt>type</tt>:
|
|
193
|
-
#
|
|
194
|
-
# link_to "External link", "http://www.rubyonrails.org/", target: "_blank", rel: "nofollow"
|
|
195
|
-
# # => <a href="http://www.rubyonrails.org/" target="_blank" rel="nofollow">External link</a>
|
|
196
234
|
def link_to(name = nil, options = nil, html_options = nil, &block)
|
|
197
235
|
html_options, options, name = options, name, block if block_given?
|
|
198
236
|
options ||= {}
|
|
199
237
|
|
|
200
238
|
html_options = convert_options_to_data_attributes(options, html_options)
|
|
201
239
|
|
|
202
|
-
url =
|
|
240
|
+
url = url_target(name, options)
|
|
203
241
|
html_options["href"] ||= url
|
|
204
242
|
|
|
205
243
|
content_tag("a", name || url, html_options, &block)
|
|
@@ -208,54 +246,64 @@ module ActionView
|
|
|
208
246
|
# Generates a form containing a single button that submits to the URL created
|
|
209
247
|
# by the set of +options+. This is the safest method to ensure links that
|
|
210
248
|
# cause changes to your data are not triggered by search bots or accelerators.
|
|
211
|
-
#
|
|
212
|
-
#
|
|
213
|
-
#
|
|
214
|
-
#
|
|
215
|
-
#
|
|
216
|
-
#
|
|
217
|
-
#
|
|
218
|
-
#
|
|
219
|
-
#
|
|
220
|
-
#
|
|
221
|
-
#
|
|
222
|
-
#
|
|
223
|
-
#
|
|
249
|
+
#
|
|
250
|
+
# You can control the form and button behavior with +html_options+. Most
|
|
251
|
+
# values in +html_options+ are passed through to the button element. For
|
|
252
|
+
# example, passing a +:class+ option within +html_options+ will set the
|
|
253
|
+
# class attribute of the button element.
|
|
254
|
+
#
|
|
255
|
+
# The class attribute of the form element can be set by passing a
|
|
256
|
+
# +:form_class+ option within +html_options+. It defaults to
|
|
257
|
+
# <tt>"button_to"</tt> to allow styling of the form and its children.
|
|
258
|
+
#
|
|
259
|
+
# The form submits a POST request by default. You can specify a different
|
|
260
|
+
# HTTP verb via the +:method+ option within +html_options+.
|
|
261
|
+
#
|
|
262
|
+
# If the HTML button generated from +button_to+ does not work with your layout, you can
|
|
263
|
+
# consider using the +link_to+ method with the +data-turbo-method+
|
|
264
|
+
# attribute as described in the +link_to+ documentation.
|
|
224
265
|
#
|
|
225
266
|
# ==== Options
|
|
226
|
-
# The +options+ hash accepts the same options as +url_for+.
|
|
267
|
+
# The +options+ hash accepts the same options as +url_for+. To generate a
|
|
268
|
+
# <tt><form></tt> element without an <tt>[action]</tt> attribute, pass
|
|
269
|
+
# <tt>false</tt>:
|
|
270
|
+
#
|
|
271
|
+
# <%= button_to "New", false %>
|
|
272
|
+
# # => "<form method="post" class="button_to">
|
|
273
|
+
# # <button type="submit">New</button>
|
|
274
|
+
# # <input name="authenticity_token" type="hidden" value="10f2163b45388899ad4d5ae948988266befcb6c3d1b2451cf657a0c293d605a6"/>
|
|
275
|
+
# # </form>"
|
|
276
|
+
#
|
|
277
|
+
# Most values in +html_options+ are passed through to the button element,
|
|
278
|
+
# but there are a few special options:
|
|
227
279
|
#
|
|
228
|
-
# There are a few special +html_options+:
|
|
229
280
|
# * <tt>:method</tt> - \Symbol of HTTP verb. Supported verbs are <tt>:post</tt>, <tt>:get</tt>,
|
|
230
281
|
# <tt>:delete</tt>, <tt>:patch</tt>, and <tt>:put</tt>. By default it will be <tt>:post</tt>.
|
|
231
282
|
# * <tt>:disabled</tt> - If set to true, it will generate a disabled button.
|
|
232
283
|
# * <tt>:data</tt> - This option can be used to add custom data attributes.
|
|
233
|
-
# * <tt>:remote</tt> - If set to true, will allow the Unobtrusive JavaScript drivers to control the
|
|
234
|
-
# submit behavior. By default this behavior is an ajax submit.
|
|
235
284
|
# * <tt>:form</tt> - This hash will be form attributes
|
|
236
285
|
# * <tt>:form_class</tt> - This controls the class of the form within which the submit button will
|
|
237
286
|
# be placed
|
|
238
287
|
# * <tt>:params</tt> - \Hash of parameters to be rendered as hidden fields within the form.
|
|
239
288
|
#
|
|
240
|
-
# ==== Data attributes
|
|
241
|
-
#
|
|
242
|
-
# * <tt>:confirm</tt> - This will use the unobtrusive JavaScript driver to
|
|
243
|
-
# prompt with the question specified. If the user accepts, the link is
|
|
244
|
-
# processed normally, otherwise no action is taken.
|
|
245
|
-
# * <tt>:disable_with</tt> - Value of this parameter will be
|
|
246
|
-
# used as the value for a disabled version of the submit
|
|
247
|
-
# button when the form is submitted. This feature is provided
|
|
248
|
-
# by the unobtrusive JavaScript driver.
|
|
249
|
-
#
|
|
250
289
|
# ==== Examples
|
|
251
290
|
# <%= button_to "New", action: "new" %>
|
|
252
291
|
# # => "<form method="post" action="/controller/new" class="button_to">
|
|
253
|
-
# # <
|
|
292
|
+
# # <button type="submit">New</button>
|
|
293
|
+
# # <input name="authenticity_token" type="hidden" value="10f2163b45388899ad4d5ae948988266befcb6c3d1b2451cf657a0c293d605a6" autocomplete="off"/>
|
|
254
294
|
# # </form>"
|
|
255
295
|
#
|
|
256
296
|
# <%= button_to "New", new_article_path %>
|
|
257
297
|
# # => "<form method="post" action="/articles/new" class="button_to">
|
|
258
|
-
# # <
|
|
298
|
+
# # <button type="submit">New</button>
|
|
299
|
+
# # <input name="authenticity_token" type="hidden" value="10f2163b45388899ad4d5ae948988266befcb6c3d1b2451cf657a0c293d605a6" autocomplete="off"/>
|
|
300
|
+
# # </form>"
|
|
301
|
+
#
|
|
302
|
+
# <%= button_to "New", new_article_path, params: { time: Time.now } %>
|
|
303
|
+
# # => "<form method="post" action="/articles/new" class="button_to">
|
|
304
|
+
# # <button type="submit">New</button>
|
|
305
|
+
# # <input name="authenticity_token" type="hidden" value="10f2163b45388899ad4d5ae948988266befcb6c3d1b2451cf657a0c293d605a6"/>
|
|
306
|
+
# # <input type="hidden" name="time" value="2021-04-08 14:06:09 -0500" autocomplete="off">
|
|
259
307
|
# # </form>"
|
|
260
308
|
#
|
|
261
309
|
# <%= button_to [:make_happy, @user] do %>
|
|
@@ -265,49 +313,64 @@ module ActionView
|
|
|
265
313
|
# # <button type="submit">
|
|
266
314
|
# # Make happy <strong><%= @user.name %></strong>
|
|
267
315
|
# # </button>
|
|
316
|
+
# # <input name="authenticity_token" type="hidden" value="10f2163b45388899ad4d5ae948988266befcb6c3d1b2451cf657a0c293d605a6" autocomplete="off"/>
|
|
268
317
|
# # </form>"
|
|
269
318
|
#
|
|
270
319
|
# <%= button_to "New", { action: "new" }, form_class: "new-thing" %>
|
|
271
320
|
# # => "<form method="post" action="/controller/new" class="new-thing">
|
|
272
|
-
# # <
|
|
321
|
+
# # <button type="submit">New</button>
|
|
322
|
+
# # <input name="authenticity_token" type="hidden" value="10f2163b45388899ad4d5ae948988266befcb6c3d1b2451cf657a0c293d605a6" autocomplete="off"/>
|
|
273
323
|
# # </form>"
|
|
274
324
|
#
|
|
275
|
-
#
|
|
276
|
-
#
|
|
277
|
-
# #
|
|
278
|
-
# # <input
|
|
279
|
-
# # <input name="authenticity_token" type="hidden" value="10f2163b45388899ad4d5ae948988266befcb6c3d1b2451cf657a0c293d605a6"/>
|
|
325
|
+
# <%= button_to "Create", { action: "create" }, form: { "data-type" => "json" } %>
|
|
326
|
+
# # => "<form method="post" action="/images/create" class="button_to" data-type="json">
|
|
327
|
+
# # <button type="submit">Create</button>
|
|
328
|
+
# # <input name="authenticity_token" type="hidden" value="10f2163b45388899ad4d5ae948988266befcb6c3d1b2451cf657a0c293d605a6" autocomplete="off"/>
|
|
280
329
|
# # </form>"
|
|
281
330
|
#
|
|
331
|
+
# ==== Deprecated: \Rails UJS Attributes
|
|
282
332
|
#
|
|
283
|
-
#
|
|
284
|
-
#
|
|
285
|
-
#
|
|
286
|
-
#
|
|
287
|
-
#
|
|
288
|
-
#
|
|
289
|
-
#
|
|
333
|
+
# Prior to \Rails 7, \Rails shipped with a JavaScript library called <tt>@rails/ujs</tt> on by default. Following \Rails 7,
|
|
334
|
+
# this library is no longer on by default. This library integrated with the following options:
|
|
335
|
+
#
|
|
336
|
+
# * <tt>:remote</tt> - If set to true, will allow <tt>@rails/ujs</tt> to control the
|
|
337
|
+
# submit behavior. By default this behavior is an Ajax submit.
|
|
338
|
+
#
|
|
339
|
+
# <tt>@rails/ujs</tt> also integrated with the following +:data+ options:
|
|
340
|
+
#
|
|
341
|
+
# * <tt>confirm: "question?"</tt> - This will allow <tt>@rails/ujs</tt>
|
|
342
|
+
# to prompt with the question specified (in this case, the
|
|
343
|
+
# resulting text would be <tt>question?</tt>). If the user accepts, the
|
|
344
|
+
# button is processed normally, otherwise no action is taken.
|
|
345
|
+
# * <tt>:disable_with</tt> - Value of this parameter will be
|
|
346
|
+
# used as the value for a disabled version of the submit
|
|
347
|
+
# button when the form is submitted.
|
|
348
|
+
#
|
|
349
|
+
# ===== \Rails UJS Examples
|
|
290
350
|
#
|
|
351
|
+
# <%= button_to "Create", { action: "create" }, remote: true, form: { "data-type" => "json" } %>
|
|
352
|
+
# # => "<form method="post" action="/images/create" class="button_to" data-remote="true" data-type="json">
|
|
353
|
+
# # <button type="submit">Create</button>
|
|
354
|
+
# # <input name="authenticity_token" type="hidden" value="10f2163b45388899ad4d5ae948988266befcb6c3d1b2451cf657a0c293d605a6" autocomplete="off"/>
|
|
355
|
+
# # </form>"
|
|
291
356
|
#
|
|
292
|
-
# <%= button_to('Destroy', 'http://www.example.com',
|
|
293
|
-
# method: :delete, remote: true, data: { confirm: 'Are you sure?', disable_with: 'loading...' }) %>
|
|
294
|
-
# # => "<form class='button_to' method='post' action='http://www.example.com' data-remote='true'>
|
|
295
|
-
# # <input name='_method' value='delete' type='hidden' />
|
|
296
|
-
# # <input value='Destroy' type='submit' data-disable-with='loading...' data-confirm='Are you sure?' />
|
|
297
|
-
# # <input name="authenticity_token" type="hidden" value="10f2163b45388899ad4d5ae948988266befcb6c3d1b2451cf657a0c293d605a6"/>
|
|
298
|
-
# # </form>"
|
|
299
|
-
# #
|
|
300
357
|
def button_to(name = nil, options = nil, html_options = nil, &block)
|
|
301
358
|
html_options, options = options, name if block_given?
|
|
302
|
-
options ||= {}
|
|
303
359
|
html_options ||= {}
|
|
304
360
|
html_options = html_options.stringify_keys
|
|
305
361
|
|
|
306
|
-
url
|
|
362
|
+
url =
|
|
363
|
+
case options
|
|
364
|
+
when FalseClass then nil
|
|
365
|
+
else url_for(options)
|
|
366
|
+
end
|
|
367
|
+
|
|
307
368
|
remote = html_options.delete("remote")
|
|
308
369
|
params = html_options.delete("params")
|
|
309
370
|
|
|
310
|
-
|
|
371
|
+
authenticity_token = html_options.delete("authenticity_token")
|
|
372
|
+
|
|
373
|
+
method = (html_options.delete("method").presence || method_for_options(options)).to_s
|
|
311
374
|
method_tag = BUTTON_TAG_METHOD_VERBS.include?(method) ? method_tag(method) : "".html_safe
|
|
312
375
|
|
|
313
376
|
form_method = method == "get" ? "get" : "post"
|
|
@@ -319,7 +382,7 @@ module ActionView
|
|
|
319
382
|
|
|
320
383
|
request_token_tag = if form_method == "post"
|
|
321
384
|
request_method = method.empty? ? "post" : method
|
|
322
|
-
token_tag(
|
|
385
|
+
token_tag(authenticity_token, form_options: { action: url, method: request_method })
|
|
323
386
|
else
|
|
324
387
|
""
|
|
325
388
|
end
|
|
@@ -329,6 +392,8 @@ module ActionView
|
|
|
329
392
|
|
|
330
393
|
button = if block_given?
|
|
331
394
|
content_tag("button", html_options, &block)
|
|
395
|
+
elsif button_to_generates_button_tag
|
|
396
|
+
content_tag("button", name || url, html_options, &block)
|
|
332
397
|
else
|
|
333
398
|
html_options["value"] = name || url
|
|
334
399
|
tag("input", html_options)
|
|
@@ -341,7 +406,8 @@ module ActionView
|
|
|
341
406
|
autocomplete: "off")
|
|
342
407
|
end
|
|
343
408
|
end
|
|
344
|
-
content_tag("form", inner_tags, form_options)
|
|
409
|
+
html = content_tag("form", inner_tags, form_options)
|
|
410
|
+
prevent_content_exfiltration(html)
|
|
345
411
|
end
|
|
346
412
|
|
|
347
413
|
# Creates a link tag of the given +name+ using a URL created by the set of
|
|
@@ -453,10 +519,10 @@ module ActionView
|
|
|
453
519
|
# * <tt>:body</tt> - Preset the body of the email.
|
|
454
520
|
# * <tt>:cc</tt> - Carbon Copy additional recipients on the email.
|
|
455
521
|
# * <tt>:bcc</tt> - Blind Carbon Copy additional recipients on the email.
|
|
456
|
-
# * <tt>:reply_to</tt> - Preset the Reply-To field of the email.
|
|
522
|
+
# * <tt>:reply_to</tt> - Preset the +Reply-To+ field of the email.
|
|
457
523
|
#
|
|
458
524
|
# ==== Obfuscation
|
|
459
|
-
# Prior to Rails 4.0, +mail_to+ provided options for encoding the address
|
|
525
|
+
# Prior to \Rails 4.0, +mail_to+ provided options for encoding the address
|
|
460
526
|
# in order to hinder email harvesters. To take advantage of these options,
|
|
461
527
|
# install the +actionview-encoded_mail_to+ gem.
|
|
462
528
|
#
|
|
@@ -467,9 +533,9 @@ module ActionView
|
|
|
467
533
|
# mail_to "me@domain.com", "My email"
|
|
468
534
|
# # => <a href="mailto:me@domain.com">My email</a>
|
|
469
535
|
#
|
|
470
|
-
# mail_to "me@domain.com",
|
|
536
|
+
# mail_to "me@domain.com", cc: "ccaddress@domain.com",
|
|
471
537
|
# subject: "This is an example email"
|
|
472
|
-
# # => <a href="mailto:me@domain.com?cc=ccaddress@domain.com&subject=This%20is%20an%20example%20email">
|
|
538
|
+
# # => <a href="mailto:me@domain.com?cc=ccaddress@domain.com&subject=This%20is%20an%20example%20email">me@domain.com</a>
|
|
473
539
|
#
|
|
474
540
|
# You can use a block as well if your link target is hard to fit into the name parameter. ERB example:
|
|
475
541
|
#
|
|
@@ -480,7 +546,7 @@ module ActionView
|
|
|
480
546
|
# <strong>Email me:</strong> <span>me@domain.com</span>
|
|
481
547
|
# </a>
|
|
482
548
|
def mail_to(email_address, name = nil, html_options = {}, &block)
|
|
483
|
-
html_options, name = name, nil if
|
|
549
|
+
html_options, name = name, nil if name.is_a?(Hash)
|
|
484
550
|
html_options = (html_options || {}).stringify_keys
|
|
485
551
|
|
|
486
552
|
extras = %w{ cc bcc body subject reply_to }.map! { |item|
|
|
@@ -556,7 +622,7 @@ module ActionView
|
|
|
556
622
|
# We ignore any extra parameters in the request_uri if the
|
|
557
623
|
# submitted URL doesn't have any either. This lets the function
|
|
558
624
|
# work with things like ?order=asc
|
|
559
|
-
# the
|
|
625
|
+
# the behavior can be disabled with check_parameters: true
|
|
560
626
|
request_uri = url_string.index("?") || check_parameters ? request.fullpath : request.path
|
|
561
627
|
request_uri = URI::DEFAULT_PARSER.unescape(request_uri).force_encoding(Encoding::BINARY)
|
|
562
628
|
|
|
@@ -583,29 +649,37 @@ module ActionView
|
|
|
583
649
|
end
|
|
584
650
|
end
|
|
585
651
|
|
|
586
|
-
# Creates an SMS anchor link tag to the specified +phone_number
|
|
587
|
-
#
|
|
588
|
-
#
|
|
652
|
+
# Creates an SMS anchor link tag to the specified +phone_number+. When the
|
|
653
|
+
# link is clicked, the default SMS messaging app is opened ready to send a
|
|
654
|
+
# message to the linked phone number. If the +body+ option is specified,
|
|
655
|
+
# the contents of the message will be preset to +body+.
|
|
589
656
|
#
|
|
590
|
-
#
|
|
591
|
-
#
|
|
657
|
+
# If +name+ is not specified, +phone_number+ will be used as the name of
|
|
658
|
+
# the link.
|
|
592
659
|
#
|
|
593
|
-
# +
|
|
594
|
-
#
|
|
660
|
+
# A +country_code+ option is supported, which prepends a plus sign and the
|
|
661
|
+
# given country code to the linked phone number. For example,
|
|
662
|
+
# <tt>country_code: "01"</tt> will prepend <tt>+01</tt> to the linked
|
|
663
|
+
# phone number.
|
|
664
|
+
#
|
|
665
|
+
# Additional HTML attributes for the link can be passed via +html_options+.
|
|
595
666
|
#
|
|
596
667
|
# ==== Options
|
|
668
|
+
# * <tt>:country_code</tt> - Prepend the country code to the phone number.
|
|
597
669
|
# * <tt>:body</tt> - Preset the body of the message.
|
|
598
670
|
#
|
|
599
671
|
# ==== Examples
|
|
600
672
|
# sms_to "5155555785"
|
|
601
673
|
# # => <a href="sms:5155555785;">5155555785</a>
|
|
602
674
|
#
|
|
675
|
+
# sms_to "5155555785", country_code: "01"
|
|
676
|
+
# # => <a href="sms:+015155555785;">5155555785</a>
|
|
677
|
+
#
|
|
603
678
|
# sms_to "5155555785", "Text me"
|
|
604
679
|
# # => <a href="sms:5155555785;">Text me</a>
|
|
605
680
|
#
|
|
606
|
-
# sms_to "5155555785", "
|
|
607
|
-
#
|
|
608
|
-
# # => <a href="sms:5155555785;?body=Hello%20Jim%20I%20have%20a%20question%20about%20your%20product">Text me</a>
|
|
681
|
+
# sms_to "5155555785", body: "I have a question about your product."
|
|
682
|
+
# # => <a href="sms:5155555785;?body=I%20have%20a%20question%20about%20your%20product">5155555785</a>
|
|
609
683
|
#
|
|
610
684
|
# You can use a block as well if your link target is hard to fit into the name parameter. \ERB example:
|
|
611
685
|
#
|
|
@@ -616,46 +690,47 @@ module ActionView
|
|
|
616
690
|
# <strong>Text me:</strong>
|
|
617
691
|
# </a>
|
|
618
692
|
def sms_to(phone_number, name = nil, html_options = {}, &block)
|
|
619
|
-
html_options, name = name, nil if
|
|
693
|
+
html_options, name = name, nil if name.is_a?(Hash)
|
|
620
694
|
html_options = (html_options || {}).stringify_keys
|
|
621
695
|
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
696
|
+
country_code = html_options.delete("country_code").presence
|
|
697
|
+
country_code = country_code ? "+#{ERB::Util.url_encode(country_code)}" : ""
|
|
698
|
+
|
|
699
|
+
body = html_options.delete("body").presence
|
|
700
|
+
body = body ? "?&body=#{ERB::Util.url_encode(body)}" : ""
|
|
627
701
|
|
|
628
702
|
encoded_phone_number = ERB::Util.url_encode(phone_number)
|
|
629
|
-
html_options["href"] = "sms:#{encoded_phone_number};#{
|
|
703
|
+
html_options["href"] = "sms:#{country_code}#{encoded_phone_number};#{body}"
|
|
630
704
|
|
|
631
705
|
content_tag("a", name || phone_number, html_options, &block)
|
|
632
706
|
end
|
|
633
707
|
|
|
634
|
-
# Creates a TEL anchor link tag to the specified +phone_number
|
|
635
|
-
#
|
|
636
|
-
#
|
|
708
|
+
# Creates a TEL anchor link tag to the specified +phone_number+. When the
|
|
709
|
+
# link is clicked, the default app to make phone calls is opened and
|
|
710
|
+
# prepopulated with the phone number.
|
|
711
|
+
#
|
|
712
|
+
# If +name+ is not specified, +phone_number+ will be used as the name of
|
|
713
|
+
# the link.
|
|
637
714
|
#
|
|
638
|
-
#
|
|
639
|
-
#
|
|
640
|
-
#
|
|
715
|
+
# A +country_code+ option is supported, which prepends a plus sign and the
|
|
716
|
+
# given country code to the linked phone number. For example,
|
|
717
|
+
# <tt>country_code: "01"</tt> will prepend <tt>+01</tt> to the linked
|
|
718
|
+
# phone number.
|
|
641
719
|
#
|
|
642
|
-
#
|
|
643
|
-
# code as well as the + sign in the phone numer that gets prepopulated,
|
|
644
|
-
# for example if +country_code: "01"+ +\+01+ will be prepended to the
|
|
645
|
-
# phone numer, by passing special keys to +html_options+.
|
|
720
|
+
# Additional HTML attributes for the link can be passed via +html_options+.
|
|
646
721
|
#
|
|
647
722
|
# ==== Options
|
|
648
|
-
# * <tt>:country_code</tt> - Prepends the country code to the number
|
|
723
|
+
# * <tt>:country_code</tt> - Prepends the country code to the phone number
|
|
649
724
|
#
|
|
650
725
|
# ==== Examples
|
|
651
726
|
# phone_to "1234567890"
|
|
652
727
|
# # => <a href="tel:1234567890">1234567890</a>
|
|
653
728
|
#
|
|
654
729
|
# phone_to "1234567890", "Phone me"
|
|
655
|
-
# # => <a href="tel:
|
|
730
|
+
# # => <a href="tel:1234567890">Phone me</a>
|
|
656
731
|
#
|
|
657
|
-
# phone_to "1234567890",
|
|
658
|
-
# # => <a href="tel:+
|
|
732
|
+
# phone_to "1234567890", country_code: "01"
|
|
733
|
+
# # => <a href="tel:+011234567890">1234567890</a>
|
|
659
734
|
#
|
|
660
735
|
# You can use a block as well if your link target is hard to fit into the name parameter. \ERB example:
|
|
661
736
|
#
|
|
@@ -666,7 +741,7 @@ module ActionView
|
|
|
666
741
|
# <strong>Phone me:</strong>
|
|
667
742
|
# </a>
|
|
668
743
|
def phone_to(phone_number, name = nil, html_options = {}, &block)
|
|
669
|
-
html_options, name = name, nil if
|
|
744
|
+
html_options, name = name, nil if name.is_a?(Hash)
|
|
670
745
|
html_options = (html_options || {}).stringify_keys
|
|
671
746
|
|
|
672
747
|
country_code = html_options.delete("country_code").presence
|
|
@@ -694,6 +769,14 @@ module ActionView
|
|
|
694
769
|
end
|
|
695
770
|
end
|
|
696
771
|
|
|
772
|
+
def url_target(name, options)
|
|
773
|
+
if name.respond_to?(:model_name) && options.is_a?(Hash) && options.empty?
|
|
774
|
+
url_for(name)
|
|
775
|
+
else
|
|
776
|
+
url_for(options)
|
|
777
|
+
end
|
|
778
|
+
end
|
|
779
|
+
|
|
697
780
|
def link_to_remote_options?(options)
|
|
698
781
|
if options.is_a?(Hash)
|
|
699
782
|
options.delete("remote") || options.delete(:remote)
|
|
@@ -711,6 +794,16 @@ module ActionView
|
|
|
711
794
|
html_options["data-method"] = method
|
|
712
795
|
end
|
|
713
796
|
|
|
797
|
+
def method_for_options(options)
|
|
798
|
+
if options.is_a?(Array)
|
|
799
|
+
method_for_options(options.last)
|
|
800
|
+
elsif options.respond_to?(:persisted?)
|
|
801
|
+
options.persisted? ? :patch : :post
|
|
802
|
+
elsif options.respond_to?(:to_model)
|
|
803
|
+
method_for_options(options.to_model)
|
|
804
|
+
end
|
|
805
|
+
end
|
|
806
|
+
|
|
714
807
|
STRINGIFIED_COMMON_METHODS = {
|
|
715
808
|
get: "get",
|
|
716
809
|
delete: "delete",
|
|
@@ -726,7 +819,12 @@ module ActionView
|
|
|
726
819
|
|
|
727
820
|
def token_tag(token = nil, form_options: {})
|
|
728
821
|
if token != false && defined?(protect_against_forgery?) && protect_against_forgery?
|
|
729
|
-
token
|
|
822
|
+
token =
|
|
823
|
+
if token == true || token.nil?
|
|
824
|
+
form_authenticity_token(form_options: form_options.merge(authenticity_token: token))
|
|
825
|
+
else
|
|
826
|
+
token
|
|
827
|
+
end
|
|
730
828
|
tag(:input, type: "hidden", name: request_forgery_protection_token.to_s, value: token, autocomplete: "off")
|
|
731
829
|
else
|
|
732
830
|
""
|