actionview 6.1.7.10 → 7.0.0.alpha1
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 +89 -409
- data/MIT-LICENSE +2 -1
- data/lib/action_view/base.rb +3 -3
- 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 +1 -1
- data/lib/action_view/helpers/asset_tag_helper.rb +84 -29
- data/lib/action_view/helpers/asset_url_helper.rb +7 -7
- data/lib/action_view/helpers/atom_feed_helper.rb +3 -4
- data/lib/action_view/helpers/cache_helper.rb +51 -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 +6 -7
- data/lib/action_view/helpers/debug_helper.rb +3 -1
- data/lib/action_view/helpers/form_helper.rb +72 -12
- data/lib/action_view/helpers/form_options_helper.rb +65 -33
- data/lib/action_view/helpers/form_tag_helper.rb +75 -32
- 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 +25 -44
- data/lib/action_view/helpers/tags/base.rb +3 -15
- 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 +0 -4
- data/lib/action_view/helpers/tags/time_field.rb +10 -1
- data/lib/action_view/helpers/tags/weekday_select.rb +27 -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 +1 -2
- data/lib/action_view/helpers/url_helper.rb +102 -77
- data/lib/action_view/helpers.rb +25 -25
- data/lib/action_view/lookup_context.rb +33 -52
- data/lib/action_view/model_naming.rb +1 -1
- data/lib/action_view/path_set.rb +16 -22
- data/lib/action_view/railtie.rb +14 -1
- 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 +10 -1
- 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
- data/lib/assets/compiled/rails-ujs.js +5 -36
- metadata +22 -16
@@ -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
|
@@ -101,17 +103,8 @@ module ActionView
|
|
101
103
|
# completion of the Ajax request and performing JavaScript operations once
|
102
104
|
# they're complete
|
103
105
|
#
|
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
106
|
# ==== Examples
|
107
|
+
#
|
115
108
|
# Because it relies on +url_for+, +link_to+ supports both older-style controller/action/id arguments
|
116
109
|
# and newer RESTful routes. Current Rails style favors RESTful routes whenever possible, so base
|
117
110
|
# your application on resources and use
|
@@ -184,15 +177,27 @@ module ActionView
|
|
184
177
|
# link_to("Destroy", "http://www.example.com", method: :delete)
|
185
178
|
# # => <a href='http://www.example.com' rel="nofollow" data-method="delete">Destroy</a>
|
186
179
|
#
|
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
180
|
# Also you can set any link attributes such as <tt>target</tt>, <tt>rel</tt>, <tt>type</tt>:
|
193
181
|
#
|
194
182
|
# link_to "External link", "http://www.rubyonrails.org/", target: "_blank", rel: "nofollow"
|
195
183
|
# # => <a href="http://www.rubyonrails.org/" target="_blank" rel="nofollow">External link</a>
|
184
|
+
#
|
185
|
+
# ==== Deprecated: Rails UJS attributes
|
186
|
+
#
|
187
|
+
# Prior to Rails 7, Rails shipped with a JavaScript library called @rails/ujs on by default. Following Rails 7,
|
188
|
+
# this library is no longer on by default. This library integrated with the following options:
|
189
|
+
#
|
190
|
+
# * <tt>confirm: 'question?'</tt> - This will allow the unobtrusive JavaScript
|
191
|
+
# driver to prompt with the question specified (in this case, the
|
192
|
+
# resulting text would be <tt>question?</tt>. If the user accepts, the
|
193
|
+
# link is processed normally, otherwise no action is taken.
|
194
|
+
# * <tt>:disable_with</tt> - Value of this parameter will be used as the
|
195
|
+
# name for a disabled version of the link. This feature is provided by
|
196
|
+
# the unobtrusive JavaScript driver.
|
197
|
+
#
|
198
|
+
# link_to "Visit Other Site", "http://www.rubyonrails.org/", data: { confirm: "Are you sure?" }
|
199
|
+
# # => <a href="http://www.rubyonrails.org/" data-confirm="Are you sure?">Visit Other Site</a>
|
200
|
+
#
|
196
201
|
def link_to(name = nil, options = nil, html_options = nil, &block)
|
197
202
|
html_options, options, name = options, name, block if block_given?
|
198
203
|
options ||= {}
|
@@ -212,20 +217,24 @@ module ActionView
|
|
212
217
|
# using the +link_to+ method with the <tt>:method</tt> modifier as described in
|
213
218
|
# the +link_to+ documentation.
|
214
219
|
#
|
215
|
-
#
|
216
|
-
#
|
217
|
-
#
|
218
|
-
#
|
219
|
-
#
|
220
|
-
#
|
221
|
-
#
|
222
|
-
#
|
223
|
-
#
|
220
|
+
# You can control the form and button behavior with +html_options+. Most
|
221
|
+
# values in +html_options+ are passed through to the button element. For
|
222
|
+
# example, passing a +:class+ option within +html_options+ will set the
|
223
|
+
# class attribute of the button element.
|
224
|
+
#
|
225
|
+
# The class attribute of the form element can be set by passing a
|
226
|
+
# +:form_class+ option within +html_options+. It defaults to
|
227
|
+
# <tt>"button_to"</tt> to allow styling of the form and its children.
|
228
|
+
#
|
229
|
+
# The form submits a POST request by default. You can specify a different
|
230
|
+
# HTTP verb via the +:method+ option within +html_options+.
|
224
231
|
#
|
225
232
|
# ==== Options
|
226
233
|
# The +options+ hash accepts the same options as +url_for+.
|
227
234
|
#
|
228
|
-
#
|
235
|
+
# Most values in +html_options+ are passed through to the button element,
|
236
|
+
# but there are a few special options:
|
237
|
+
#
|
229
238
|
# * <tt>:method</tt> - \Symbol of HTTP verb. Supported verbs are <tt>:post</tt>, <tt>:get</tt>,
|
230
239
|
# <tt>:delete</tt>, <tt>:patch</tt>, and <tt>:put</tt>. By default it will be <tt>:post</tt>.
|
231
240
|
# * <tt>:disabled</tt> - If set to true, it will generate a disabled button.
|
@@ -250,12 +259,21 @@ module ActionView
|
|
250
259
|
# ==== Examples
|
251
260
|
# <%= button_to "New", action: "new" %>
|
252
261
|
# # => "<form method="post" action="/controller/new" class="button_to">
|
253
|
-
# # <
|
262
|
+
# # <button type="submit">New</button>
|
263
|
+
# # <input name="authenticity_token" type="hidden" value="10f2163b45388899ad4d5ae948988266befcb6c3d1b2451cf657a0c293d605a6"/>
|
254
264
|
# # </form>"
|
255
265
|
#
|
256
266
|
# <%= button_to "New", new_article_path %>
|
257
267
|
# # => "<form method="post" action="/articles/new" class="button_to">
|
258
|
-
# # <
|
268
|
+
# # <button type="submit">New</button>
|
269
|
+
# # <input name="authenticity_token" type="hidden" value="10f2163b45388899ad4d5ae948988266befcb6c3d1b2451cf657a0c293d605a6"/>
|
270
|
+
# # </form>"
|
271
|
+
#
|
272
|
+
# <%= button_to "New", new_article_path, params: { time: Time.now } %>
|
273
|
+
# # => "<form method="post" action="/articles/new" class="button_to">
|
274
|
+
# # <button type="submit">New</button>
|
275
|
+
# # <input name="authenticity_token" type="hidden" value="10f2163b45388899ad4d5ae948988266befcb6c3d1b2451cf657a0c293d605a6"/>
|
276
|
+
# # <input type="hidden" name="time" value="2021-04-08 14:06:09 -0500">
|
259
277
|
# # </form>"
|
260
278
|
#
|
261
279
|
# <%= button_to [:make_happy, @user] do %>
|
@@ -265,35 +283,34 @@ module ActionView
|
|
265
283
|
# # <button type="submit">
|
266
284
|
# # Make happy <strong><%= @user.name %></strong>
|
267
285
|
# # </button>
|
286
|
+
# # <input name="authenticity_token" type="hidden" value="10f2163b45388899ad4d5ae948988266befcb6c3d1b2451cf657a0c293d605a6"/>
|
268
287
|
# # </form>"
|
269
288
|
#
|
270
289
|
# <%= button_to "New", { action: "new" }, form_class: "new-thing" %>
|
271
290
|
# # => "<form method="post" action="/controller/new" class="new-thing">
|
272
|
-
# # <
|
291
|
+
# # <button type="submit">New</button>
|
292
|
+
# # <input name="authenticity_token" type="hidden" value="10f2163b45388899ad4d5ae948988266befcb6c3d1b2451cf657a0c293d605a6"/>
|
273
293
|
# # </form>"
|
274
294
|
#
|
275
|
-
#
|
276
295
|
# <%= button_to "Create", { action: "create" }, remote: true, form: { "data-type" => "json" } %>
|
277
296
|
# # => "<form method="post" action="/images/create" class="button_to" data-remote="true" data-type="json">
|
278
|
-
# # <
|
297
|
+
# # <button type="submit">Create</button>
|
279
298
|
# # <input name="authenticity_token" type="hidden" value="10f2163b45388899ad4d5ae948988266befcb6c3d1b2451cf657a0c293d605a6"/>
|
280
299
|
# # </form>"
|
281
300
|
#
|
282
|
-
#
|
283
301
|
# <%= button_to "Delete Image", { action: "delete", id: @image.id },
|
284
302
|
# method: :delete, data: { confirm: "Are you sure?" } %>
|
285
303
|
# # => "<form method="post" action="/images/delete/1" class="button_to">
|
286
304
|
# # <input type="hidden" name="_method" value="delete" />
|
287
|
-
# # <
|
305
|
+
# # <button data-confirm='Are you sure?' type="submit">Delete Image</button>
|
288
306
|
# # <input name="authenticity_token" type="hidden" value="10f2163b45388899ad4d5ae948988266befcb6c3d1b2451cf657a0c293d605a6"/>
|
289
307
|
# # </form>"
|
290
308
|
#
|
291
|
-
#
|
292
309
|
# <%= button_to('Destroy', 'http://www.example.com',
|
293
310
|
# method: :delete, remote: true, data: { confirm: 'Are you sure?', disable_with: 'loading...' }) %>
|
294
311
|
# # => "<form class='button_to' method='post' action='http://www.example.com' data-remote='true'>
|
295
312
|
# # <input name='_method' value='delete' type='hidden' />
|
296
|
-
# # <
|
313
|
+
# # <button type='submit' data-disable-with='loading...' data-confirm='Are you sure?'>Destroy</button>
|
297
314
|
# # <input name="authenticity_token" type="hidden" value="10f2163b45388899ad4d5ae948988266befcb6c3d1b2451cf657a0c293d605a6"/>
|
298
315
|
# # </form>"
|
299
316
|
# #
|
@@ -327,8 +344,8 @@ module ActionView
|
|
327
344
|
html_options = convert_options_to_data_attributes(options, html_options)
|
328
345
|
html_options["type"] = "submit"
|
329
346
|
|
330
|
-
button = if block_given?
|
331
|
-
content_tag("button", html_options, &block)
|
347
|
+
button = if block_given? || button_to_generates_button_tag
|
348
|
+
content_tag("button", name || url, html_options, &block)
|
332
349
|
else
|
333
350
|
html_options["value"] = name || url
|
334
351
|
tag("input", html_options)
|
@@ -337,8 +354,7 @@ module ActionView
|
|
337
354
|
inner_tags = method_tag.safe_concat(button).safe_concat(request_token_tag)
|
338
355
|
if params
|
339
356
|
to_form_params(params).each do |param|
|
340
|
-
inner_tags.safe_concat tag(:input, type: "hidden", name: param[:name], value: param[:value]
|
341
|
-
autocomplete: "off")
|
357
|
+
inner_tags.safe_concat tag(:input, type: "hidden", name: param[:name], value: param[:value])
|
342
358
|
end
|
343
359
|
end
|
344
360
|
content_tag("form", inner_tags, form_options)
|
@@ -467,9 +483,9 @@ module ActionView
|
|
467
483
|
# mail_to "me@domain.com", "My email"
|
468
484
|
# # => <a href="mailto:me@domain.com">My email</a>
|
469
485
|
#
|
470
|
-
# mail_to "me@domain.com",
|
486
|
+
# mail_to "me@domain.com", cc: "ccaddress@domain.com",
|
471
487
|
# subject: "This is an example email"
|
472
|
-
# # => <a href="mailto:me@domain.com?cc=ccaddress@domain.com&subject=This%20is%20an%20example%20email">
|
488
|
+
# # => <a href="mailto:me@domain.com?cc=ccaddress@domain.com&subject=This%20is%20an%20example%20email">me@domain.com</a>
|
473
489
|
#
|
474
490
|
# You can use a block as well if your link target is hard to fit into the name parameter. ERB example:
|
475
491
|
#
|
@@ -480,7 +496,7 @@ module ActionView
|
|
480
496
|
# <strong>Email me:</strong> <span>me@domain.com</span>
|
481
497
|
# </a>
|
482
498
|
def mail_to(email_address, name = nil, html_options = {}, &block)
|
483
|
-
html_options, name = name, nil if
|
499
|
+
html_options, name = name, nil if name.is_a?(Hash)
|
484
500
|
html_options = (html_options || {}).stringify_keys
|
485
501
|
|
486
502
|
extras = %w{ cc bcc body subject reply_to }.map! { |item|
|
@@ -583,29 +599,37 @@ module ActionView
|
|
583
599
|
end
|
584
600
|
end
|
585
601
|
|
586
|
-
# Creates an SMS anchor link tag to the specified +phone_number
|
587
|
-
#
|
588
|
-
#
|
602
|
+
# Creates an SMS anchor link tag to the specified +phone_number+. When the
|
603
|
+
# link is clicked, the default SMS messaging app is opened ready to send a
|
604
|
+
# message to the linked phone number. If the +body+ option is specified,
|
605
|
+
# the contents of the message will be preset to +body+.
|
589
606
|
#
|
590
|
-
#
|
591
|
-
#
|
607
|
+
# If +name+ is not specified, +phone_number+ will be used as the name of
|
608
|
+
# the link.
|
592
609
|
#
|
593
|
-
# +
|
594
|
-
#
|
610
|
+
# A +country_code+ option is supported, which prepends a plus sign and the
|
611
|
+
# given country code to the linked phone number. For example,
|
612
|
+
# <tt>country_code: "01"</tt> will prepend <tt>+01</tt> to the linked
|
613
|
+
# phone number.
|
614
|
+
#
|
615
|
+
# Additional HTML attributes for the link can be passed via +html_options+.
|
595
616
|
#
|
596
617
|
# ==== Options
|
618
|
+
# * <tt>:country_code</tt> - Prepend the country code to the phone number.
|
597
619
|
# * <tt>:body</tt> - Preset the body of the message.
|
598
620
|
#
|
599
621
|
# ==== Examples
|
600
622
|
# sms_to "5155555785"
|
601
623
|
# # => <a href="sms:5155555785;">5155555785</a>
|
602
624
|
#
|
625
|
+
# sms_to "5155555785", country_code: "01"
|
626
|
+
# # => <a href="sms:+015155555785;">5155555785</a>
|
627
|
+
#
|
603
628
|
# sms_to "5155555785", "Text me"
|
604
629
|
# # => <a href="sms:5155555785;">Text me</a>
|
605
630
|
#
|
606
|
-
# sms_to "5155555785", "
|
607
|
-
#
|
608
|
-
# # => <a href="sms:5155555785;?body=Hello%20Jim%20I%20have%20a%20question%20about%20your%20product">Text me</a>
|
631
|
+
# sms_to "5155555785", body: "I have a question about your product."
|
632
|
+
# # => <a href="sms:5155555785;?body=I%20have%20a%20question%20about%20your%20product">5155555785</a>
|
609
633
|
#
|
610
634
|
# You can use a block as well if your link target is hard to fit into the name parameter. \ERB example:
|
611
635
|
#
|
@@ -616,46 +640,47 @@ module ActionView
|
|
616
640
|
# <strong>Text me:</strong>
|
617
641
|
# </a>
|
618
642
|
def sms_to(phone_number, name = nil, html_options = {}, &block)
|
619
|
-
html_options, name = name, nil if
|
643
|
+
html_options, name = name, nil if name.is_a?(Hash)
|
620
644
|
html_options = (html_options || {}).stringify_keys
|
621
645
|
|
622
|
-
|
623
|
-
|
624
|
-
|
625
|
-
|
626
|
-
|
646
|
+
country_code = html_options.delete("country_code").presence
|
647
|
+
country_code = country_code ? "+#{ERB::Util.url_encode(country_code)}" : ""
|
648
|
+
|
649
|
+
body = html_options.delete("body").presence
|
650
|
+
body = body ? "?&body=#{ERB::Util.url_encode(body)}" : ""
|
627
651
|
|
628
652
|
encoded_phone_number = ERB::Util.url_encode(phone_number)
|
629
|
-
html_options["href"] = "sms:#{encoded_phone_number};#{
|
653
|
+
html_options["href"] = "sms:#{country_code}#{encoded_phone_number};#{body}"
|
630
654
|
|
631
655
|
content_tag("a", name || phone_number, html_options, &block)
|
632
656
|
end
|
633
657
|
|
634
|
-
# Creates a TEL anchor link tag to the specified +phone_number
|
635
|
-
#
|
636
|
-
#
|
658
|
+
# Creates a TEL anchor link tag to the specified +phone_number+. When the
|
659
|
+
# link is clicked, the default app to make phone calls is opened and
|
660
|
+
# prepopulated with the phone number.
|
661
|
+
#
|
662
|
+
# If +name+ is not specified, +phone_number+ will be used as the name of
|
663
|
+
# the link.
|
637
664
|
#
|
638
|
-
#
|
639
|
-
#
|
640
|
-
#
|
665
|
+
# A +country_code+ option is supported, which prepends a plus sign and the
|
666
|
+
# given country code to the linked phone number. For example,
|
667
|
+
# <tt>country_code: "01"</tt> will prepend <tt>+01</tt> to the linked
|
668
|
+
# phone number.
|
641
669
|
#
|
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+.
|
670
|
+
# Additional HTML attributes for the link can be passed via +html_options+.
|
646
671
|
#
|
647
672
|
# ==== Options
|
648
|
-
# * <tt>:country_code</tt> - Prepends the country code to the number
|
673
|
+
# * <tt>:country_code</tt> - Prepends the country code to the phone number
|
649
674
|
#
|
650
675
|
# ==== Examples
|
651
676
|
# phone_to "1234567890"
|
652
677
|
# # => <a href="tel:1234567890">1234567890</a>
|
653
678
|
#
|
654
679
|
# phone_to "1234567890", "Phone me"
|
655
|
-
# # => <a href="tel:
|
680
|
+
# # => <a href="tel:1234567890">Phone me</a>
|
656
681
|
#
|
657
|
-
# phone_to "1234567890",
|
658
|
-
# # => <a href="tel:+
|
682
|
+
# phone_to "1234567890", country_code: "01"
|
683
|
+
# # => <a href="tel:+011234567890">1234567890</a>
|
659
684
|
#
|
660
685
|
# You can use a block as well if your link target is hard to fit into the name parameter. \ERB example:
|
661
686
|
#
|
@@ -666,7 +691,7 @@ module ActionView
|
|
666
691
|
# <strong>Phone me:</strong>
|
667
692
|
# </a>
|
668
693
|
def phone_to(phone_number, name = nil, html_options = {}, &block)
|
669
|
-
html_options, name = name, nil if
|
694
|
+
html_options, name = name, nil if name.is_a?(Hash)
|
670
695
|
html_options = (html_options || {}).stringify_keys
|
671
696
|
|
672
697
|
country_code = html_options.delete("country_code").presence
|
@@ -727,14 +752,14 @@ module ActionView
|
|
727
752
|
def token_tag(token = nil, form_options: {})
|
728
753
|
if token != false && defined?(protect_against_forgery?) && protect_against_forgery?
|
729
754
|
token ||= form_authenticity_token(form_options: form_options)
|
730
|
-
tag(:input, type: "hidden", name: request_forgery_protection_token.to_s, value: token
|
755
|
+
tag(:input, type: "hidden", name: request_forgery_protection_token.to_s, value: token)
|
731
756
|
else
|
732
757
|
""
|
733
758
|
end
|
734
759
|
end
|
735
760
|
|
736
761
|
def method_tag(method)
|
737
|
-
tag("input", type: "hidden", name: "_method", value: method.to_s
|
762
|
+
tag("input", type: "hidden", name: "_method", value: method.to_s)
|
738
763
|
end
|
739
764
|
|
740
765
|
# Returns an array of hashes each containing :name and :value keys
|
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!
|
@@ -12,12 +12,11 @@ module ActionView
|
|
12
12
|
# <tt>LookupContext</tt> is also responsible for generating a key, given to
|
13
13
|
# view paths, used in the resolver cache lookup. Since this key is generated
|
14
14
|
# only once during the request, it speeds up all cache accesses.
|
15
|
-
class LookupContext
|
15
|
+
class LookupContext # :nodoc:
|
16
16
|
attr_accessor :prefixes, :rendered_format
|
17
17
|
|
18
|
-
|
19
|
-
|
20
|
-
mattr_accessor :registered_details, default: []
|
18
|
+
singleton_class.attr_accessor :registered_details
|
19
|
+
self.registered_details = []
|
21
20
|
|
22
21
|
def self.register_detail(name, &block)
|
23
22
|
registered_details << name
|
@@ -37,7 +36,7 @@ module ActionView
|
|
37
36
|
end
|
38
37
|
|
39
38
|
# Holds accessors for the registered details.
|
40
|
-
module Accessors
|
39
|
+
module Accessors # :nodoc:
|
41
40
|
DEFAULT_PROCS = {}
|
42
41
|
end
|
43
42
|
|
@@ -52,7 +51,7 @@ module ActionView
|
|
52
51
|
register_detail(:variants) { [] }
|
53
52
|
register_detail(:handlers) { Template::Handlers.extensions }
|
54
53
|
|
55
|
-
class DetailsKey
|
54
|
+
class DetailsKey # :nodoc:
|
56
55
|
alias :eql? :equal?
|
57
56
|
|
58
57
|
@details_keys = Concurrent::Map.new
|
@@ -68,14 +67,13 @@ module ActionView
|
|
68
67
|
details = details.dup
|
69
68
|
details[:formats] &= Template::Types.symbols
|
70
69
|
end
|
71
|
-
@details_keys[details] ||=
|
70
|
+
@details_keys[details] ||= TemplateDetails::Requested.new(**details)
|
72
71
|
end
|
73
72
|
|
74
73
|
def self.clear
|
75
74
|
ActionView::ViewPaths.all_view_paths.each do |path_set|
|
76
75
|
path_set.each(&:clear_cache)
|
77
76
|
end
|
78
|
-
ActionView::LookupContext.fallbacks.each(&:clear_cache)
|
79
77
|
@view_context_class = nil
|
80
78
|
@details_keys.clear
|
81
79
|
@digest_cache.clear
|
@@ -98,7 +96,7 @@ module ActionView
|
|
98
96
|
|
99
97
|
# Calculate the details key. Remove the handlers from calculation to improve performance
|
100
98
|
# since the user cannot modify it explicitly.
|
101
|
-
def details_key
|
99
|
+
def details_key # :nodoc:
|
102
100
|
@details_key ||= DetailsKey.details_cache_key(@details) if @cache
|
103
101
|
end
|
104
102
|
|
@@ -124,39 +122,32 @@ module ActionView
|
|
124
122
|
attr_reader :view_paths, :html_fallback_for_js
|
125
123
|
|
126
124
|
def find(name, prefixes = [], partial = false, keys = [], options = {})
|
127
|
-
|
125
|
+
name, prefixes = normalize_name(name, prefixes)
|
126
|
+
details, details_key = detail_args_for(options)
|
127
|
+
@view_paths.find(name, prefixes, partial, details, details_key, keys)
|
128
128
|
end
|
129
129
|
alias :find_template :find
|
130
130
|
|
131
131
|
def find_all(name, prefixes = [], partial = false, keys = [], options = {})
|
132
|
-
|
132
|
+
name, prefixes = normalize_name(name, prefixes)
|
133
|
+
details, details_key = detail_args_for(options)
|
134
|
+
@view_paths.find_all(name, prefixes, partial, details, details_key, keys)
|
133
135
|
end
|
134
136
|
|
135
137
|
def exists?(name, prefixes = [], partial = false, keys = [], **options)
|
136
|
-
|
138
|
+
name, prefixes = normalize_name(name, prefixes)
|
139
|
+
details, details_key = detail_args_for(options)
|
140
|
+
@view_paths.exists?(name, prefixes, partial, details, details_key, keys)
|
137
141
|
end
|
138
142
|
alias :template_exists? :exists?
|
139
143
|
|
140
144
|
def any?(name, prefixes = [], partial = false)
|
141
|
-
|
145
|
+
name, prefixes = normalize_name(name, prefixes)
|
146
|
+
details, details_key = detail_args_for_any
|
147
|
+
@view_paths.exists?(name, prefixes, partial, details, details_key, [])
|
142
148
|
end
|
143
149
|
alias :any_templates? :any?
|
144
150
|
|
145
|
-
# Adds fallbacks to the view paths. Useful in cases when you are rendering
|
146
|
-
# a :file.
|
147
|
-
def with_fallbacks
|
148
|
-
view_paths = build_view_paths((@view_paths.paths + self.class.fallbacks).uniq)
|
149
|
-
|
150
|
-
if block_given?
|
151
|
-
raise ArgumentError, <<~eowarn.squish
|
152
|
-
Calling `with_fallbacks` with a block is not supported. Call methods on
|
153
|
-
the lookup context returned by `with_fallbacks` instead.
|
154
|
-
eowarn
|
155
|
-
else
|
156
|
-
ActionView::LookupContext.new(view_paths, @details, @prefixes)
|
157
|
-
end
|
158
|
-
end
|
159
|
-
|
160
151
|
private
|
161
152
|
# Whenever setting view paths, makes a copy so that we can manipulate them in
|
162
153
|
# instance objects as we wish.
|
@@ -164,12 +155,6 @@ module ActionView
|
|
164
155
|
ActionView::PathSet.new(Array(paths))
|
165
156
|
end
|
166
157
|
|
167
|
-
def args_for_lookup(name, prefixes, partial, keys, details_options)
|
168
|
-
name, prefixes = normalize_name(name, prefixes)
|
169
|
-
details, details_key = detail_args_for(details_options)
|
170
|
-
[name, prefixes, partial || false, details, details_key, keys]
|
171
|
-
end
|
172
|
-
|
173
158
|
# Compute details hash and key according to user options (e.g. passed from #render).
|
174
159
|
def detail_args_for(options) # :doc:
|
175
160
|
return @details, details_key if options.empty? # most common path.
|
@@ -184,17 +169,11 @@ module ActionView
|
|
184
169
|
[user_details, details_key]
|
185
170
|
end
|
186
171
|
|
187
|
-
def args_for_any(name, prefixes, partial)
|
188
|
-
name, prefixes = normalize_name(name, prefixes)
|
189
|
-
details, details_key = detail_args_for_any
|
190
|
-
[name, prefixes, partial || false, details, details_key]
|
191
|
-
end
|
192
|
-
|
193
172
|
def detail_args_for_any
|
194
173
|
@detail_args_for_any ||= begin
|
195
174
|
details = {}
|
196
175
|
|
197
|
-
registered_details.each do |k|
|
176
|
+
LookupContext.registered_details.each do |k|
|
198
177
|
if k == :variants
|
199
178
|
details[k] = :any
|
200
179
|
else
|
@@ -210,19 +189,21 @@ module ActionView
|
|
210
189
|
end
|
211
190
|
end
|
212
191
|
|
213
|
-
#
|
214
|
-
# as well as incorrectly putting part of the path in the template
|
215
|
-
# name instead of the prefix.
|
192
|
+
# Fix when prefix is specified as part of the template name
|
216
193
|
def normalize_name(name, prefixes)
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
name = parts.pop
|
194
|
+
name = name.to_s
|
195
|
+
idx = name.rindex("/")
|
196
|
+
return name, prefixes.presence || [""] unless idx
|
221
197
|
|
222
|
-
|
198
|
+
path_prefix = name[0, idx]
|
199
|
+
path_prefix = path_prefix.from(1) if path_prefix.start_with?("/")
|
200
|
+
name = name.from(idx + 1)
|
223
201
|
|
224
|
-
|
225
|
-
|
202
|
+
if !prefixes || prefixes.empty?
|
203
|
+
prefixes = [path_prefix]
|
204
|
+
else
|
205
|
+
prefixes = prefixes.map { |p| "#{p}/#{path_prefix}" }
|
206
|
+
end
|
226
207
|
|
227
208
|
return name, prefixes
|
228
209
|
end
|
@@ -254,7 +235,7 @@ module ActionView
|
|
254
235
|
end
|
255
236
|
|
256
237
|
def initialize_details(target, details)
|
257
|
-
registered_details.each do |k|
|
238
|
+
LookupContext.registered_details.each do |k|
|
258
239
|
target[k] = details[k] || Accessors::DEFAULT_PROCS[k].call
|
259
240
|
end
|
260
241
|
target
|