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
@@ -1,13 +1,13 @@
|
|
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/tag_helper"
|
7
7
|
|
8
8
|
module ActionView
|
9
9
|
# = Action View URL Helpers
|
10
|
-
module Helpers
|
10
|
+
module Helpers # :nodoc:
|
11
11
|
# Provides a set of methods for making links and getting URLs that
|
12
12
|
# depend on the routing subsystem (see ActionDispatch::Routing).
|
13
13
|
# This allows you to use the same format for links in views
|
@@ -29,6 +29,8 @@ module ActionView
|
|
29
29
|
end
|
30
30
|
end
|
31
31
|
|
32
|
+
mattr_accessor :button_to_generates_button_tag, default: false
|
33
|
+
|
32
34
|
# Basic implementation of url_for to allow use helpers without routes existence
|
33
35
|
def url_for(options = nil) # :nodoc:
|
34
36
|
case options
|
@@ -83,6 +85,8 @@ module ActionView
|
|
83
85
|
# # name
|
84
86
|
# end
|
85
87
|
#
|
88
|
+
# link_to(active_record_model)
|
89
|
+
#
|
86
90
|
# ==== Options
|
87
91
|
# * <tt>:data</tt> - This option can be used to add custom data attributes.
|
88
92
|
# * <tt>method: symbol of HTTP verb</tt> - This modifier will dynamically
|
@@ -101,17 +105,8 @@ module ActionView
|
|
101
105
|
# completion of the Ajax request and performing JavaScript operations once
|
102
106
|
# they're complete
|
103
107
|
#
|
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
|
-
#
|
114
108
|
# ==== Examples
|
109
|
+
#
|
115
110
|
# Because it relies on +url_for+, +link_to+ supports both older-style controller/action/id arguments
|
116
111
|
# and newer RESTful routes. Current Rails style favors RESTful routes whenever possible, so base
|
117
112
|
# your application on resources and use
|
@@ -144,6 +139,12 @@ module ActionView
|
|
144
139
|
# link_to nil, "http://example.com"
|
145
140
|
# # => <a href="http://www.example.com">http://www.example.com</a>
|
146
141
|
#
|
142
|
+
# More concise yet, when +name+ is an Active Record model that defines a
|
143
|
+
# +to_s+ method returning a default value or a model instance attribute
|
144
|
+
#
|
145
|
+
# link_to @profile
|
146
|
+
# # => <a href="http://www.example.com/profiles/1">Eileen</a>
|
147
|
+
#
|
147
148
|
# You can use a block as well if your link target is hard to fit into the name parameter. ERB example:
|
148
149
|
#
|
149
150
|
# <%= link_to(@profile) do %>
|
@@ -184,22 +185,34 @@ module ActionView
|
|
184
185
|
# link_to("Destroy", "http://www.example.com", method: :delete)
|
185
186
|
# # => <a href='http://www.example.com' rel="nofollow" data-method="delete">Destroy</a>
|
186
187
|
#
|
187
|
-
# You can also use custom data attributes using the <tt>:data</tt> option:
|
188
|
-
#
|
189
|
-
# link_to "Visit Other Site", "http://www.rubyonrails.org/", data: { confirm: "Are you sure?" }
|
190
|
-
# # => <a href="http://www.rubyonrails.org/" data-confirm="Are you sure?">Visit Other Site</a>
|
191
|
-
#
|
192
188
|
# Also you can set any link attributes such as <tt>target</tt>, <tt>rel</tt>, <tt>type</tt>:
|
193
189
|
#
|
194
190
|
# link_to "External link", "http://www.rubyonrails.org/", target: "_blank", rel: "nofollow"
|
195
191
|
# # => <a href="http://www.rubyonrails.org/" target="_blank" rel="nofollow">External link</a>
|
192
|
+
#
|
193
|
+
# ==== Deprecated: Rails UJS attributes
|
194
|
+
#
|
195
|
+
# Prior to Rails 7, Rails shipped with a JavaScript library called @rails/ujs on by default. Following Rails 7,
|
196
|
+
# this library is no longer on by default. This library integrated with the following options:
|
197
|
+
#
|
198
|
+
# * <tt>confirm: 'question?'</tt> - This will allow the unobtrusive JavaScript
|
199
|
+
# driver to prompt with the question specified (in this case, the
|
200
|
+
# resulting text would be <tt>question?</tt>. If the user accepts, the
|
201
|
+
# link is processed normally, otherwise no action is taken.
|
202
|
+
# * <tt>:disable_with</tt> - Value of this parameter will be used as the
|
203
|
+
# name for a disabled version of the link. This feature is provided by
|
204
|
+
# the unobtrusive JavaScript driver.
|
205
|
+
#
|
206
|
+
# link_to "Visit Other Site", "http://www.rubyonrails.org/", data: { confirm: "Are you sure?" }
|
207
|
+
# # => <a href="http://www.rubyonrails.org/" data-confirm="Are you sure?">Visit Other Site</a>
|
208
|
+
#
|
196
209
|
def link_to(name = nil, options = nil, html_options = nil, &block)
|
197
210
|
html_options, options, name = options, name, block if block_given?
|
198
211
|
options ||= {}
|
199
212
|
|
200
213
|
html_options = convert_options_to_data_attributes(options, html_options)
|
201
214
|
|
202
|
-
url =
|
215
|
+
url = url_target(name, options)
|
203
216
|
html_options["href"] ||= url
|
204
217
|
|
205
218
|
content_tag("a", name || url, html_options, &block)
|
@@ -212,20 +225,32 @@ module ActionView
|
|
212
225
|
# using the +link_to+ method with the <tt>:method</tt> modifier as described in
|
213
226
|
# the +link_to+ documentation.
|
214
227
|
#
|
215
|
-
#
|
216
|
-
#
|
217
|
-
#
|
218
|
-
#
|
219
|
-
#
|
220
|
-
#
|
221
|
-
#
|
222
|
-
#
|
223
|
-
#
|
228
|
+
# You can control the form and button behavior with +html_options+. Most
|
229
|
+
# values in +html_options+ are passed through to the button element. For
|
230
|
+
# example, passing a +:class+ option within +html_options+ will set the
|
231
|
+
# class attribute of the button element.
|
232
|
+
#
|
233
|
+
# The class attribute of the form element can be set by passing a
|
234
|
+
# +:form_class+ option within +html_options+. It defaults to
|
235
|
+
# <tt>"button_to"</tt> to allow styling of the form and its children.
|
236
|
+
#
|
237
|
+
# The form submits a POST request by default. You can specify a different
|
238
|
+
# HTTP verb via the +:method+ option within +html_options+.
|
224
239
|
#
|
225
240
|
# ==== Options
|
226
|
-
# The +options+ hash accepts the same options as +url_for+.
|
241
|
+
# The +options+ hash accepts the same options as +url_for+. To generate a
|
242
|
+
# <tt><form></tt> element without an <tt>[action]</tt> attribute, pass
|
243
|
+
# <tt>false</tt>:
|
244
|
+
#
|
245
|
+
# <%= button_to "New", false %>
|
246
|
+
# # => "<form method="post" class="button_to">
|
247
|
+
# # <button type="submit">New</button>
|
248
|
+
# # <input name="authenticity_token" type="hidden" value="10f2163b45388899ad4d5ae948988266befcb6c3d1b2451cf657a0c293d605a6"/>
|
249
|
+
# # </form>"
|
250
|
+
#
|
251
|
+
# Most values in +html_options+ are passed through to the button element,
|
252
|
+
# but there are a few special options:
|
227
253
|
#
|
228
|
-
# There are a few special +html_options+:
|
229
254
|
# * <tt>:method</tt> - \Symbol of HTTP verb. Supported verbs are <tt>:post</tt>, <tt>:get</tt>,
|
230
255
|
# <tt>:delete</tt>, <tt>:patch</tt>, and <tt>:put</tt>. By default it will be <tt>:post</tt>.
|
231
256
|
# * <tt>:disabled</tt> - If set to true, it will generate a disabled button.
|
@@ -250,12 +275,21 @@ module ActionView
|
|
250
275
|
# ==== Examples
|
251
276
|
# <%= button_to "New", action: "new" %>
|
252
277
|
# # => "<form method="post" action="/controller/new" class="button_to">
|
253
|
-
# # <
|
278
|
+
# # <button type="submit">New</button>
|
279
|
+
# # <input name="authenticity_token" type="hidden" value="10f2163b45388899ad4d5ae948988266befcb6c3d1b2451cf657a0c293d605a6"/>
|
254
280
|
# # </form>"
|
255
281
|
#
|
256
282
|
# <%= button_to "New", new_article_path %>
|
257
283
|
# # => "<form method="post" action="/articles/new" class="button_to">
|
258
|
-
# # <
|
284
|
+
# # <button type="submit">New</button>
|
285
|
+
# # <input name="authenticity_token" type="hidden" value="10f2163b45388899ad4d5ae948988266befcb6c3d1b2451cf657a0c293d605a6"/>
|
286
|
+
# # </form>"
|
287
|
+
#
|
288
|
+
# <%= button_to "New", new_article_path, params: { time: Time.now } %>
|
289
|
+
# # => "<form method="post" action="/articles/new" class="button_to">
|
290
|
+
# # <button type="submit">New</button>
|
291
|
+
# # <input name="authenticity_token" type="hidden" value="10f2163b45388899ad4d5ae948988266befcb6c3d1b2451cf657a0c293d605a6"/>
|
292
|
+
# # <input type="hidden" name="time" value="2021-04-08 14:06:09 -0500">
|
259
293
|
# # </form>"
|
260
294
|
#
|
261
295
|
# <%= button_to [:make_happy, @user] do %>
|
@@ -265,49 +299,54 @@ module ActionView
|
|
265
299
|
# # <button type="submit">
|
266
300
|
# # Make happy <strong><%= @user.name %></strong>
|
267
301
|
# # </button>
|
302
|
+
# # <input name="authenticity_token" type="hidden" value="10f2163b45388899ad4d5ae948988266befcb6c3d1b2451cf657a0c293d605a6"/>
|
268
303
|
# # </form>"
|
269
304
|
#
|
270
305
|
# <%= button_to "New", { action: "new" }, form_class: "new-thing" %>
|
271
306
|
# # => "<form method="post" action="/controller/new" class="new-thing">
|
272
|
-
# # <
|
307
|
+
# # <button type="submit">New</button>
|
308
|
+
# # <input name="authenticity_token" type="hidden" value="10f2163b45388899ad4d5ae948988266befcb6c3d1b2451cf657a0c293d605a6"/>
|
273
309
|
# # </form>"
|
274
310
|
#
|
275
|
-
#
|
276
311
|
# <%= button_to "Create", { action: "create" }, remote: true, form: { "data-type" => "json" } %>
|
277
312
|
# # => "<form method="post" action="/images/create" class="button_to" data-remote="true" data-type="json">
|
278
|
-
# # <
|
313
|
+
# # <button type="submit">Create</button>
|
279
314
|
# # <input name="authenticity_token" type="hidden" value="10f2163b45388899ad4d5ae948988266befcb6c3d1b2451cf657a0c293d605a6"/>
|
280
315
|
# # </form>"
|
281
316
|
#
|
282
|
-
#
|
283
317
|
# <%= button_to "Delete Image", { action: "delete", id: @image.id },
|
284
318
|
# method: :delete, data: { confirm: "Are you sure?" } %>
|
285
319
|
# # => "<form method="post" action="/images/delete/1" class="button_to">
|
286
320
|
# # <input type="hidden" name="_method" value="delete" />
|
287
|
-
# # <
|
321
|
+
# # <button data-confirm='Are you sure?' type="submit">Delete Image</button>
|
288
322
|
# # <input name="authenticity_token" type="hidden" value="10f2163b45388899ad4d5ae948988266befcb6c3d1b2451cf657a0c293d605a6"/>
|
289
323
|
# # </form>"
|
290
324
|
#
|
291
|
-
#
|
292
325
|
# <%= button_to('Destroy', 'http://www.example.com',
|
293
326
|
# method: :delete, remote: true, data: { confirm: 'Are you sure?', disable_with: 'loading...' }) %>
|
294
327
|
# # => "<form class='button_to' method='post' action='http://www.example.com' data-remote='true'>
|
295
328
|
# # <input name='_method' value='delete' type='hidden' />
|
296
|
-
# # <
|
329
|
+
# # <button type='submit' data-disable-with='loading...' data-confirm='Are you sure?'>Destroy</button>
|
297
330
|
# # <input name="authenticity_token" type="hidden" value="10f2163b45388899ad4d5ae948988266befcb6c3d1b2451cf657a0c293d605a6"/>
|
298
331
|
# # </form>"
|
299
332
|
# #
|
300
333
|
def button_to(name = nil, options = nil, html_options = nil, &block)
|
301
334
|
html_options, options = options, name if block_given?
|
302
|
-
options ||= {}
|
303
335
|
html_options ||= {}
|
304
336
|
html_options = html_options.stringify_keys
|
305
337
|
|
306
|
-
url
|
338
|
+
url =
|
339
|
+
case options
|
340
|
+
when FalseClass then nil
|
341
|
+
else url_for(options)
|
342
|
+
end
|
343
|
+
|
307
344
|
remote = html_options.delete("remote")
|
308
345
|
params = html_options.delete("params")
|
309
346
|
|
310
|
-
|
347
|
+
authenticity_token = html_options.delete("authenticity_token")
|
348
|
+
|
349
|
+
method = (html_options.delete("method").presence || method_for_options(options)).to_s
|
311
350
|
method_tag = BUTTON_TAG_METHOD_VERBS.include?(method) ? method_tag(method) : "".html_safe
|
312
351
|
|
313
352
|
form_method = method == "get" ? "get" : "post"
|
@@ -319,7 +358,7 @@ module ActionView
|
|
319
358
|
|
320
359
|
request_token_tag = if form_method == "post"
|
321
360
|
request_method = method.empty? ? "post" : method
|
322
|
-
token_tag(
|
361
|
+
token_tag(authenticity_token, form_options: { action: url, method: request_method })
|
323
362
|
else
|
324
363
|
""
|
325
364
|
end
|
@@ -327,8 +366,8 @@ module ActionView
|
|
327
366
|
html_options = convert_options_to_data_attributes(options, html_options)
|
328
367
|
html_options["type"] = "submit"
|
329
368
|
|
330
|
-
button = if block_given?
|
331
|
-
content_tag("button", html_options, &block)
|
369
|
+
button = if block_given? || button_to_generates_button_tag
|
370
|
+
content_tag("button", name || url, html_options, &block)
|
332
371
|
else
|
333
372
|
html_options["value"] = name || url
|
334
373
|
tag("input", html_options)
|
@@ -337,7 +376,8 @@ module ActionView
|
|
337
376
|
inner_tags = method_tag.safe_concat(button).safe_concat(request_token_tag)
|
338
377
|
if params
|
339
378
|
to_form_params(params).each do |param|
|
340
|
-
inner_tags.safe_concat tag(:input, type: "hidden", name: param[:name], value: param[:value]
|
379
|
+
inner_tags.safe_concat tag(:input, type: "hidden", name: param[:name], value: param[:value],
|
380
|
+
autocomplete: "off")
|
341
381
|
end
|
342
382
|
end
|
343
383
|
content_tag("form", inner_tags, form_options)
|
@@ -466,9 +506,9 @@ module ActionView
|
|
466
506
|
# mail_to "me@domain.com", "My email"
|
467
507
|
# # => <a href="mailto:me@domain.com">My email</a>
|
468
508
|
#
|
469
|
-
# mail_to "me@domain.com",
|
509
|
+
# mail_to "me@domain.com", cc: "ccaddress@domain.com",
|
470
510
|
# subject: "This is an example email"
|
471
|
-
# # => <a href="mailto:me@domain.com?cc=ccaddress@domain.com&subject=This%20is%20an%20example%20email">
|
511
|
+
# # => <a href="mailto:me@domain.com?cc=ccaddress@domain.com&subject=This%20is%20an%20example%20email">me@domain.com</a>
|
472
512
|
#
|
473
513
|
# You can use a block as well if your link target is hard to fit into the name parameter. ERB example:
|
474
514
|
#
|
@@ -479,7 +519,7 @@ module ActionView
|
|
479
519
|
# <strong>Email me:</strong> <span>me@domain.com</span>
|
480
520
|
# </a>
|
481
521
|
def mail_to(email_address, name = nil, html_options = {}, &block)
|
482
|
-
html_options, name = name, nil if
|
522
|
+
html_options, name = name, nil if name.is_a?(Hash)
|
483
523
|
html_options = (html_options || {}).stringify_keys
|
484
524
|
|
485
525
|
extras = %w{ cc bcc body subject reply_to }.map! { |item|
|
@@ -559,16 +599,14 @@ module ActionView
|
|
559
599
|
request_uri = url_string.index("?") || check_parameters ? request.fullpath : request.path
|
560
600
|
request_uri = URI::DEFAULT_PARSER.unescape(request_uri).force_encoding(Encoding::BINARY)
|
561
601
|
|
562
|
-
if url_string.start_with?("/") && url_string != "/"
|
563
|
-
url_string.chomp!("/")
|
564
|
-
request_uri.chomp!("/")
|
565
|
-
end
|
566
|
-
|
567
602
|
if %r{^\w+://}.match?(url_string)
|
568
|
-
|
569
|
-
else
|
570
|
-
url_string == request_uri
|
603
|
+
request_uri = +"#{request.protocol}#{request.host_with_port}#{request_uri}"
|
571
604
|
end
|
605
|
+
|
606
|
+
remove_trailing_slash!(url_string)
|
607
|
+
remove_trailing_slash!(request_uri)
|
608
|
+
|
609
|
+
url_string == request_uri
|
572
610
|
end
|
573
611
|
|
574
612
|
if RUBY_VERSION.start_with?("2.7")
|
@@ -584,29 +622,37 @@ module ActionView
|
|
584
622
|
end
|
585
623
|
end
|
586
624
|
|
587
|
-
# Creates an SMS anchor link tag to the specified +phone_number
|
588
|
-
#
|
589
|
-
#
|
625
|
+
# Creates an SMS anchor link tag to the specified +phone_number+. When the
|
626
|
+
# link is clicked, the default SMS messaging app is opened ready to send a
|
627
|
+
# message to the linked phone number. If the +body+ option is specified,
|
628
|
+
# the contents of the message will be preset to +body+.
|
590
629
|
#
|
591
|
-
#
|
592
|
-
#
|
630
|
+
# If +name+ is not specified, +phone_number+ will be used as the name of
|
631
|
+
# the link.
|
593
632
|
#
|
594
|
-
# +
|
595
|
-
#
|
633
|
+
# A +country_code+ option is supported, which prepends a plus sign and the
|
634
|
+
# given country code to the linked phone number. For example,
|
635
|
+
# <tt>country_code: "01"</tt> will prepend <tt>+01</tt> to the linked
|
636
|
+
# phone number.
|
637
|
+
#
|
638
|
+
# Additional HTML attributes for the link can be passed via +html_options+.
|
596
639
|
#
|
597
640
|
# ==== Options
|
641
|
+
# * <tt>:country_code</tt> - Prepend the country code to the phone number.
|
598
642
|
# * <tt>:body</tt> - Preset the body of the message.
|
599
643
|
#
|
600
644
|
# ==== Examples
|
601
645
|
# sms_to "5155555785"
|
602
646
|
# # => <a href="sms:5155555785;">5155555785</a>
|
603
647
|
#
|
648
|
+
# sms_to "5155555785", country_code: "01"
|
649
|
+
# # => <a href="sms:+015155555785;">5155555785</a>
|
650
|
+
#
|
604
651
|
# sms_to "5155555785", "Text me"
|
605
652
|
# # => <a href="sms:5155555785;">Text me</a>
|
606
653
|
#
|
607
|
-
# sms_to "5155555785", "
|
608
|
-
#
|
609
|
-
# # => <a href="sms:5155555785;?body=Hello%20Jim%20I%20have%20a%20question%20about%20your%20product">Text me</a>
|
654
|
+
# sms_to "5155555785", body: "I have a question about your product."
|
655
|
+
# # => <a href="sms:5155555785;?body=I%20have%20a%20question%20about%20your%20product">5155555785</a>
|
610
656
|
#
|
611
657
|
# You can use a block as well if your link target is hard to fit into the name parameter. \ERB example:
|
612
658
|
#
|
@@ -617,46 +663,47 @@ module ActionView
|
|
617
663
|
# <strong>Text me:</strong>
|
618
664
|
# </a>
|
619
665
|
def sms_to(phone_number, name = nil, html_options = {}, &block)
|
620
|
-
html_options, name = name, nil if
|
666
|
+
html_options, name = name, nil if name.is_a?(Hash)
|
621
667
|
html_options = (html_options || {}).stringify_keys
|
622
668
|
|
623
|
-
|
624
|
-
|
625
|
-
|
626
|
-
|
627
|
-
|
669
|
+
country_code = html_options.delete("country_code").presence
|
670
|
+
country_code = country_code ? "+#{ERB::Util.url_encode(country_code)}" : ""
|
671
|
+
|
672
|
+
body = html_options.delete("body").presence
|
673
|
+
body = body ? "?&body=#{ERB::Util.url_encode(body)}" : ""
|
628
674
|
|
629
675
|
encoded_phone_number = ERB::Util.url_encode(phone_number)
|
630
|
-
html_options["href"] = "sms:#{encoded_phone_number};#{
|
676
|
+
html_options["href"] = "sms:#{country_code}#{encoded_phone_number};#{body}"
|
631
677
|
|
632
678
|
content_tag("a", name || phone_number, html_options, &block)
|
633
679
|
end
|
634
680
|
|
635
|
-
# Creates a TEL anchor link tag to the specified +phone_number
|
636
|
-
#
|
637
|
-
#
|
681
|
+
# Creates a TEL anchor link tag to the specified +phone_number+. When the
|
682
|
+
# link is clicked, the default app to make phone calls is opened and
|
683
|
+
# prepopulated with the phone number.
|
638
684
|
#
|
639
|
-
#
|
640
|
-
#
|
641
|
-
# +country_code+ value.
|
685
|
+
# If +name+ is not specified, +phone_number+ will be used as the name of
|
686
|
+
# the link.
|
642
687
|
#
|
643
|
-
#
|
644
|
-
#
|
645
|
-
#
|
646
|
-
# phone
|
688
|
+
# A +country_code+ option is supported, which prepends a plus sign and the
|
689
|
+
# given country code to the linked phone number. For example,
|
690
|
+
# <tt>country_code: "01"</tt> will prepend <tt>+01</tt> to the linked
|
691
|
+
# phone number.
|
692
|
+
#
|
693
|
+
# Additional HTML attributes for the link can be passed via +html_options+.
|
647
694
|
#
|
648
695
|
# ==== Options
|
649
|
-
# * <tt>:country_code</tt> - Prepends the country code to the number
|
696
|
+
# * <tt>:country_code</tt> - Prepends the country code to the phone number
|
650
697
|
#
|
651
698
|
# ==== Examples
|
652
699
|
# phone_to "1234567890"
|
653
700
|
# # => <a href="tel:1234567890">1234567890</a>
|
654
701
|
#
|
655
702
|
# phone_to "1234567890", "Phone me"
|
656
|
-
# # => <a href="tel:
|
703
|
+
# # => <a href="tel:1234567890">Phone me</a>
|
657
704
|
#
|
658
|
-
# phone_to "1234567890",
|
659
|
-
# # => <a href="tel:+
|
705
|
+
# phone_to "1234567890", country_code: "01"
|
706
|
+
# # => <a href="tel:+011234567890">1234567890</a>
|
660
707
|
#
|
661
708
|
# You can use a block as well if your link target is hard to fit into the name parameter. \ERB example:
|
662
709
|
#
|
@@ -667,7 +714,7 @@ module ActionView
|
|
667
714
|
# <strong>Phone me:</strong>
|
668
715
|
# </a>
|
669
716
|
def phone_to(phone_number, name = nil, html_options = {}, &block)
|
670
|
-
html_options, name = name, nil if
|
717
|
+
html_options, name = name, nil if name.is_a?(Hash)
|
671
718
|
html_options = (html_options || {}).stringify_keys
|
672
719
|
|
673
720
|
country_code = html_options.delete("country_code").presence
|
@@ -695,6 +742,14 @@ module ActionView
|
|
695
742
|
end
|
696
743
|
end
|
697
744
|
|
745
|
+
def url_target(name, options)
|
746
|
+
if name.respond_to?(:model_name) && options.empty?
|
747
|
+
url_for(name)
|
748
|
+
else
|
749
|
+
url_for(options)
|
750
|
+
end
|
751
|
+
end
|
752
|
+
|
698
753
|
def link_to_remote_options?(options)
|
699
754
|
if options.is_a?(Hash)
|
700
755
|
options.delete("remote") || options.delete(:remote)
|
@@ -712,6 +767,16 @@ module ActionView
|
|
712
767
|
html_options["data-method"] = method
|
713
768
|
end
|
714
769
|
|
770
|
+
def method_for_options(options)
|
771
|
+
if options.is_a?(Array)
|
772
|
+
method_for_options(options.last)
|
773
|
+
elsif options.respond_to?(:persisted?)
|
774
|
+
options.persisted? ? :patch : :post
|
775
|
+
elsif options.respond_to?(:to_model)
|
776
|
+
method_for_options(options.to_model)
|
777
|
+
end
|
778
|
+
end
|
779
|
+
|
715
780
|
STRINGIFIED_COMMON_METHODS = {
|
716
781
|
get: "get",
|
717
782
|
delete: "delete",
|
@@ -727,15 +792,20 @@ module ActionView
|
|
727
792
|
|
728
793
|
def token_tag(token = nil, form_options: {})
|
729
794
|
if token != false && defined?(protect_against_forgery?) && protect_against_forgery?
|
730
|
-
token
|
731
|
-
|
795
|
+
token =
|
796
|
+
if token == true || token.nil?
|
797
|
+
form_authenticity_token(form_options: form_options.merge(authenticity_token: token))
|
798
|
+
else
|
799
|
+
token
|
800
|
+
end
|
801
|
+
tag(:input, type: "hidden", name: request_forgery_protection_token.to_s, value: token, autocomplete: "off")
|
732
802
|
else
|
733
803
|
""
|
734
804
|
end
|
735
805
|
end
|
736
806
|
|
737
807
|
def method_tag(method)
|
738
|
-
tag("input", type: "hidden", name: "_method", value: method.to_s)
|
808
|
+
tag("input", type: "hidden", name: "_method", value: method.to_s, autocomplete: "off")
|
739
809
|
end
|
740
810
|
|
741
811
|
# Returns an array of hashes each containing :name and :value keys
|
@@ -779,6 +849,11 @@ module ActionView
|
|
779
849
|
|
780
850
|
params.sort_by { |pair| pair[:name] }
|
781
851
|
end
|
852
|
+
|
853
|
+
def remove_trailing_slash!(url_string)
|
854
|
+
trailing_index = (url_string.index("?") || 0) - 1
|
855
|
+
url_string[trailing_index] = "" if url_string[trailing_index] == "/"
|
856
|
+
end
|
782
857
|
end
|
783
858
|
end
|
784
859
|
end
|
data/lib/action_view/helpers.rb
CHANGED
@@ -1,34 +1,34 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require "active_support/benchmarkable"
|
4
|
+
require "action_view/helpers/capture_helper"
|
5
|
+
require "action_view/helpers/output_safety_helper"
|
6
|
+
require "action_view/helpers/tag_helper"
|
7
|
+
require "action_view/helpers/url_helper"
|
8
|
+
require "action_view/helpers/sanitize_helper"
|
9
|
+
require "action_view/helpers/text_helper"
|
10
|
+
require "action_view/helpers/active_model_helper"
|
11
|
+
require "action_view/helpers/asset_tag_helper"
|
12
|
+
require "action_view/helpers/asset_url_helper"
|
13
|
+
require "action_view/helpers/atom_feed_helper"
|
14
|
+
require "action_view/helpers/cache_helper"
|
15
|
+
require "action_view/helpers/controller_helper"
|
16
|
+
require "action_view/helpers/csp_helper"
|
17
|
+
require "action_view/helpers/csrf_helper"
|
18
|
+
require "action_view/helpers/date_helper"
|
19
|
+
require "action_view/helpers/debug_helper"
|
20
|
+
require "action_view/helpers/form_tag_helper"
|
21
|
+
require "action_view/helpers/form_helper"
|
22
|
+
require "action_view/helpers/form_options_helper"
|
23
|
+
require "action_view/helpers/javascript_helper"
|
24
|
+
require "action_view/helpers/number_helper"
|
25
|
+
require "action_view/helpers/rendering_helper"
|
26
|
+
require "action_view/helpers/translation_helper"
|
4
27
|
|
5
|
-
module ActionView
|
6
|
-
module Helpers
|
28
|
+
module ActionView # :nodoc:
|
29
|
+
module Helpers # :nodoc:
|
7
30
|
extend ActiveSupport::Autoload
|
8
31
|
|
9
|
-
autoload :ActiveModelHelper
|
10
|
-
autoload :AssetTagHelper
|
11
|
-
autoload :AssetUrlHelper
|
12
|
-
autoload :AtomFeedHelper
|
13
|
-
autoload :CacheHelper
|
14
|
-
autoload :CaptureHelper
|
15
|
-
autoload :ControllerHelper
|
16
|
-
autoload :CspHelper
|
17
|
-
autoload :CsrfHelper
|
18
|
-
autoload :DateHelper
|
19
|
-
autoload :DebugHelper
|
20
|
-
autoload :FormHelper
|
21
|
-
autoload :FormOptionsHelper
|
22
|
-
autoload :FormTagHelper
|
23
|
-
autoload :JavaScriptHelper, "action_view/helpers/javascript_helper"
|
24
|
-
autoload :NumberHelper
|
25
|
-
autoload :OutputSafetyHelper
|
26
|
-
autoload :RenderingHelper
|
27
|
-
autoload :SanitizeHelper
|
28
|
-
autoload :TagHelper
|
29
|
-
autoload :TextHelper
|
30
|
-
autoload :TranslationHelper
|
31
|
-
autoload :UrlHelper
|
32
32
|
autoload :Tags
|
33
33
|
|
34
34
|
def self.eager_load!
|