actionview 5.1.4 → 6.1.1
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 +5 -5
- data/CHANGELOG.md +199 -168
- data/MIT-LICENSE +1 -1
- data/README.rdoc +7 -5
- data/lib/action_view.rb +10 -4
- data/lib/action_view/base.rb +87 -23
- data/lib/action_view/buffers.rb +17 -0
- data/lib/action_view/cache_expiry.rb +52 -0
- data/lib/action_view/context.rb +7 -11
- data/lib/action_view/dependency_tracker.rb +12 -4
- data/lib/action_view/digestor.rb +24 -23
- data/lib/action_view/flows.rb +2 -1
- data/lib/action_view/gem_version.rb +4 -2
- data/lib/action_view/helpers.rb +4 -2
- data/lib/action_view/helpers/active_model_helper.rb +9 -4
- data/lib/action_view/helpers/asset_tag_helper.rb +220 -57
- data/lib/action_view/helpers/asset_url_helper.rb +28 -23
- data/lib/action_view/helpers/atom_feed_helper.rb +5 -2
- data/lib/action_view/helpers/cache_helper.rb +39 -28
- data/lib/action_view/helpers/capture_helper.rb +13 -7
- data/lib/action_view/helpers/controller_helper.rb +3 -1
- data/lib/action_view/helpers/csp_helper.rb +26 -0
- data/lib/action_view/helpers/csrf_helper.rb +5 -3
- data/lib/action_view/helpers/date_helper.rb +78 -33
- data/lib/action_view/helpers/debug_helper.rb +4 -2
- data/lib/action_view/helpers/form_helper.rb +357 -106
- data/lib/action_view/helpers/form_options_helper.rb +45 -39
- data/lib/action_view/helpers/form_tag_helper.rb +42 -27
- data/lib/action_view/helpers/javascript_helper.rb +28 -12
- data/lib/action_view/helpers/number_helper.rb +16 -8
- data/lib/action_view/helpers/output_safety_helper.rb +3 -1
- data/lib/action_view/helpers/rendering_helper.rb +20 -9
- data/lib/action_view/helpers/sanitize_helper.rb +15 -19
- data/lib/action_view/helpers/tag_helper.rb +100 -24
- data/lib/action_view/helpers/tags.rb +3 -1
- data/lib/action_view/helpers/tags/base.rb +30 -21
- data/lib/action_view/helpers/tags/check_box.rb +3 -2
- data/lib/action_view/helpers/tags/checkable.rb +4 -2
- data/lib/action_view/helpers/tags/collection_check_boxes.rb +2 -1
- data/lib/action_view/helpers/tags/collection_helpers.rb +2 -1
- data/lib/action_view/helpers/tags/collection_radio_buttons.rb +2 -1
- data/lib/action_view/helpers/tags/collection_select.rb +3 -1
- data/lib/action_view/helpers/tags/color_field.rb +4 -3
- data/lib/action_view/helpers/tags/date_field.rb +3 -2
- data/lib/action_view/helpers/tags/date_select.rb +5 -4
- data/lib/action_view/helpers/tags/datetime_field.rb +3 -2
- data/lib/action_view/helpers/tags/datetime_local_field.rb +3 -2
- data/lib/action_view/helpers/tags/datetime_select.rb +2 -0
- data/lib/action_view/helpers/tags/email_field.rb +2 -0
- data/lib/action_view/helpers/tags/file_field.rb +2 -0
- data/lib/action_view/helpers/tags/grouped_collection_select.rb +3 -1
- data/lib/action_view/helpers/tags/hidden_field.rb +2 -0
- data/lib/action_view/helpers/tags/label.rb +6 -5
- data/lib/action_view/helpers/tags/month_field.rb +3 -2
- data/lib/action_view/helpers/tags/number_field.rb +2 -0
- data/lib/action_view/helpers/tags/password_field.rb +2 -0
- data/lib/action_view/helpers/tags/placeholderable.rb +2 -0
- data/lib/action_view/helpers/tags/radio_button.rb +3 -2
- data/lib/action_view/helpers/tags/range_field.rb +2 -0
- data/lib/action_view/helpers/tags/search_field.rb +2 -0
- data/lib/action_view/helpers/tags/select.rb +4 -3
- data/lib/action_view/helpers/tags/tel_field.rb +2 -0
- data/lib/action_view/helpers/tags/text_area.rb +3 -1
- data/lib/action_view/helpers/tags/text_field.rb +3 -2
- data/lib/action_view/helpers/tags/time_field.rb +3 -2
- data/lib/action_view/helpers/tags/time_select.rb +2 -0
- data/lib/action_view/helpers/tags/time_zone_select.rb +3 -1
- data/lib/action_view/helpers/tags/translator.rb +3 -6
- data/lib/action_view/helpers/tags/url_field.rb +2 -0
- data/lib/action_view/helpers/tags/week_field.rb +3 -2
- data/lib/action_view/helpers/text_helper.rb +11 -10
- data/lib/action_view/helpers/translation_helper.rb +102 -52
- data/lib/action_view/helpers/url_helper.rb +150 -32
- data/lib/action_view/layouts.rb +15 -15
- data/lib/action_view/log_subscriber.rb +32 -15
- data/lib/action_view/lookup_context.rb +67 -39
- data/lib/action_view/model_naming.rb +2 -0
- data/lib/action_view/path_set.rb +5 -12
- data/lib/action_view/railtie.rb +46 -21
- data/lib/action_view/record_identifier.rb +4 -3
- data/lib/action_view/renderer/abstract_renderer.rb +144 -11
- data/lib/action_view/renderer/collection_renderer.rb +196 -0
- data/lib/action_view/renderer/object_renderer.rb +34 -0
- data/lib/action_view/renderer/partial_renderer.rb +33 -283
- data/lib/action_view/renderer/partial_renderer/collection_caching.rb +64 -17
- data/lib/action_view/renderer/renderer.rb +61 -4
- data/lib/action_view/renderer/streaming_template_renderer.rb +14 -8
- data/lib/action_view/renderer/template_renderer.rb +36 -26
- data/lib/action_view/rendering.rb +57 -38
- data/lib/action_view/routing_url_for.rb +15 -12
- data/lib/action_view/tasks/cache_digests.rake +2 -0
- data/lib/action_view/template.rb +69 -76
- data/lib/action_view/template/error.rb +32 -18
- data/lib/action_view/template/handlers.rb +4 -2
- data/lib/action_view/template/handlers/builder.rb +5 -6
- data/lib/action_view/template/handlers/erb.rb +20 -19
- data/lib/action_view/template/handlers/erb/erubi.rb +17 -9
- data/lib/action_view/template/handlers/html.rb +3 -1
- data/lib/action_view/template/handlers/raw.rb +4 -2
- data/lib/action_view/template/html.rb +8 -7
- data/lib/action_view/template/inline.rb +22 -0
- data/lib/action_view/template/raw_file.rb +25 -0
- data/lib/action_view/template/renderable.rb +24 -0
- data/lib/action_view/template/resolver.rb +194 -152
- data/lib/action_view/template/sources.rb +13 -0
- data/lib/action_view/template/sources/file.rb +17 -0
- data/lib/action_view/template/text.rb +5 -4
- data/lib/action_view/template/types.rb +3 -1
- data/lib/action_view/test_case.rb +38 -30
- data/lib/action_view/testing/resolvers.rb +20 -27
- data/lib/action_view/unbound_template.rb +31 -0
- data/lib/action_view/version.rb +2 -0
- data/lib/action_view/view_paths.rb +61 -40
- data/lib/assets/compiled/rails-ujs.js +84 -23
- metadata +34 -23
- data/lib/action_view/helpers/record_tag_helper.rb +0 -21
- data/lib/action_view/template/handlers/erb/deprecated_erubis.rb +0 -9
- data/lib/action_view/template/handlers/erb/erubis.rb +0 -81
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require "action_view/helpers/javascript_helper"
|
2
4
|
require "active_support/core_ext/array/access"
|
3
5
|
require "active_support/core_ext/hash/keys"
|
@@ -43,7 +45,7 @@ module ActionView
|
|
43
45
|
def _back_url # :nodoc:
|
44
46
|
_filtered_referrer || "javascript:history.back()"
|
45
47
|
end
|
46
|
-
|
48
|
+
private :_back_url
|
47
49
|
|
48
50
|
def _filtered_referrer # :nodoc:
|
49
51
|
if controller.respond_to?(:request)
|
@@ -54,12 +56,12 @@ module ActionView
|
|
54
56
|
end
|
55
57
|
rescue URI::InvalidURIError
|
56
58
|
end
|
57
|
-
|
59
|
+
private :_filtered_referrer
|
58
60
|
|
59
61
|
# Creates an anchor element of the given +name+ using a URL created by the set of +options+.
|
60
62
|
# See the valid options in the documentation for +url_for+. It's also possible to
|
61
|
-
# pass a String instead of an options hash, which generates an anchor element that uses the
|
62
|
-
# value of the String as the href for the link. Using a <tt>:back</tt> Symbol instead
|
63
|
+
# pass a \String instead of an options hash, which generates an anchor element that uses the
|
64
|
+
# value of the \String as the href for the link. Using a <tt>:back</tt> \Symbol instead
|
63
65
|
# of an options hash will generate a link to the referrer (a JavaScript back link
|
64
66
|
# will be used in place of a referrer if none exists). If +nil+ is passed as the name
|
65
67
|
# the value of the link itself will become the name.
|
@@ -137,6 +139,11 @@ module ActionView
|
|
137
139
|
# link_to "Profiles", controller: "profiles"
|
138
140
|
# # => <a href="/profiles">Profiles</a>
|
139
141
|
#
|
142
|
+
# When name is +nil+ the href is presented instead
|
143
|
+
#
|
144
|
+
# link_to nil, "http://example.com"
|
145
|
+
# # => <a href="http://www.example.com">http://www.example.com</a>
|
146
|
+
#
|
140
147
|
# You can use a block as well if your link target is hard to fit into the name parameter. ERB example:
|
141
148
|
#
|
142
149
|
# <%= link_to(@profile) do %>
|
@@ -170,7 +177,7 @@ module ActionView
|
|
170
177
|
# # => <a href="/searches?query=ruby+on+rails">Ruby on Rails search</a>
|
171
178
|
#
|
172
179
|
# link_to "Nonsense search", searches_path(foo: "bar", baz: "quux")
|
173
|
-
# # => <a href="/searches?foo=bar&
|
180
|
+
# # => <a href="/searches?foo=bar&baz=quux">Nonsense search</a>
|
174
181
|
#
|
175
182
|
# The only option specific to +link_to+ (<tt>:method</tt>) is used as follows:
|
176
183
|
#
|
@@ -193,9 +200,9 @@ module ActionView
|
|
193
200
|
html_options = convert_options_to_data_attributes(options, html_options)
|
194
201
|
|
195
202
|
url = url_for(options)
|
196
|
-
html_options["href"
|
203
|
+
html_options["href"] ||= url
|
197
204
|
|
198
|
-
content_tag("a"
|
205
|
+
content_tag("a", name || url, html_options, &block)
|
199
206
|
end
|
200
207
|
|
201
208
|
# Generates a form containing a single button that submits to the URL created
|
@@ -219,7 +226,7 @@ module ActionView
|
|
219
226
|
# The +options+ hash accepts the same options as +url_for+.
|
220
227
|
#
|
221
228
|
# There are a few special +html_options+:
|
222
|
-
# * <tt>:method</tt> - Symbol of HTTP verb. Supported verbs are <tt>:post</tt>, <tt>:get</tt>,
|
229
|
+
# * <tt>:method</tt> - \Symbol of HTTP verb. Supported verbs are <tt>:post</tt>, <tt>:get</tt>,
|
223
230
|
# <tt>:delete</tt>, <tt>:patch</tt>, and <tt>:put</tt>. By default it will be <tt>:post</tt>.
|
224
231
|
# * <tt>:disabled</tt> - If set to true, it will generate a disabled button.
|
225
232
|
# * <tt>:data</tt> - This option can be used to add custom data attributes.
|
@@ -228,7 +235,7 @@ module ActionView
|
|
228
235
|
# * <tt>:form</tt> - This hash will be form attributes
|
229
236
|
# * <tt>:form_class</tt> - This controls the class of the form within which the submit button will
|
230
237
|
# be placed
|
231
|
-
# * <tt>:params</tt> - Hash of parameters to be rendered as hidden fields within the form.
|
238
|
+
# * <tt>:params</tt> - \Hash of parameters to be rendered as hidden fields within the form.
|
232
239
|
#
|
233
240
|
# ==== Data attributes
|
234
241
|
#
|
@@ -246,7 +253,7 @@ module ActionView
|
|
246
253
|
# # <input value="New" type="submit" />
|
247
254
|
# # </form>"
|
248
255
|
#
|
249
|
-
# <%= button_to "New",
|
256
|
+
# <%= button_to "New", new_article_path %>
|
250
257
|
# # => "<form method="post" action="/articles/new" class="button_to">
|
251
258
|
# # <input value="New" type="submit" />
|
252
259
|
# # </form>"
|
@@ -283,7 +290,7 @@ module ActionView
|
|
283
290
|
#
|
284
291
|
#
|
285
292
|
# <%= button_to('Destroy', 'http://www.example.com',
|
286
|
-
# method:
|
293
|
+
# method: :delete, remote: true, data: { confirm: 'Are you sure?', disable_with: 'loading...' }) %>
|
287
294
|
# # => "<form class='button_to' method='post' action='http://www.example.com' data-remote='true'>
|
288
295
|
# # <input name='_method' value='delete' type='hidden' />
|
289
296
|
# # <input value='Destroy' type='submit' data-disable-with='loading...' data-confirm='Are you sure?' />
|
@@ -301,7 +308,7 @@ module ActionView
|
|
301
308
|
params = html_options.delete("params")
|
302
309
|
|
303
310
|
method = html_options.delete("method").to_s
|
304
|
-
method_tag = BUTTON_TAG_METHOD_VERBS.include?(method) ? method_tag(method) : "".
|
311
|
+
method_tag = BUTTON_TAG_METHOD_VERBS.include?(method) ? method_tag(method) : "".html_safe
|
305
312
|
|
306
313
|
form_method = method == "get" ? "get" : "post"
|
307
314
|
form_options = html_options.delete("form") || {}
|
@@ -314,7 +321,7 @@ module ActionView
|
|
314
321
|
request_method = method.empty? ? "post" : method
|
315
322
|
token_tag(nil, form_options: { action: url, method: request_method })
|
316
323
|
else
|
317
|
-
""
|
324
|
+
""
|
318
325
|
end
|
319
326
|
|
320
327
|
html_options = convert_options_to_data_attributes(options, html_options)
|
@@ -405,8 +412,7 @@ module ActionView
|
|
405
412
|
# Creates a link tag of the given +name+ using a URL created by the set of
|
406
413
|
# +options+ if +condition+ is true, otherwise only the name is
|
407
414
|
# returned. To specialize the default behavior, you can pass a block that
|
408
|
-
# accepts the name or the full argument list for +
|
409
|
-
# in +link_to_unless+).
|
415
|
+
# accepts the name or the full argument list for +link_to_if+.
|
410
416
|
#
|
411
417
|
# ==== Examples
|
412
418
|
# <%= link_to_if(@current_user.nil?, "Login", { controller: "sessions", action: "new" }) %>
|
@@ -480,12 +486,12 @@ module ActionView
|
|
480
486
|
option = html_options.delete(item).presence || next
|
481
487
|
"#{item.dasherize}=#{ERB::Util.url_encode(option)}"
|
482
488
|
}.compact
|
483
|
-
extras = extras.empty? ? ""
|
489
|
+
extras = extras.empty? ? "" : "?" + extras.join("&")
|
484
490
|
|
485
491
|
encoded_email_address = ERB::Util.url_encode(email_address).gsub("%40", "@")
|
486
492
|
html_options["href"] = "mailto:#{encoded_email_address}#{extras}"
|
487
493
|
|
488
|
-
content_tag("a"
|
494
|
+
content_tag("a", name || email_address, html_options, &block)
|
489
495
|
end
|
490
496
|
|
491
497
|
# True if the current request URI was generated by the given +options+.
|
@@ -543,14 +549,14 @@ module ActionView
|
|
543
549
|
return false unless request.get? || request.head?
|
544
550
|
|
545
551
|
check_parameters ||= options.is_a?(Hash) && options.delete(:check_parameters)
|
546
|
-
url_string = URI.
|
552
|
+
url_string = URI::DEFAULT_PARSER.unescape(url_for(options)).force_encoding(Encoding::BINARY)
|
547
553
|
|
548
554
|
# We ignore any extra parameters in the request_uri if the
|
549
|
-
# submitted
|
555
|
+
# submitted URL doesn't have any either. This lets the function
|
550
556
|
# work with things like ?order=asc
|
551
557
|
# the behaviour can be disabled with check_parameters: true
|
552
558
|
request_uri = url_string.index("?") || check_parameters ? request.fullpath : request.path
|
553
|
-
request_uri = URI.
|
559
|
+
request_uri = URI::DEFAULT_PARSER.unescape(request_uri).force_encoding(Encoding::BINARY)
|
554
560
|
|
555
561
|
if url_string.start_with?("/") && url_string != "/"
|
556
562
|
url_string.chomp!("/")
|
@@ -564,41 +570,153 @@ module ActionView
|
|
564
570
|
end
|
565
571
|
end
|
566
572
|
|
573
|
+
# Creates an SMS anchor link tag to the specified +phone_number+, which is
|
574
|
+
# also used as the name of the link unless +name+ is specified. Additional
|
575
|
+
# HTML attributes for the link can be passed in +html_options+.
|
576
|
+
#
|
577
|
+
# When clicked, an SMS message is prepopulated with the passed phone number
|
578
|
+
# and optional +body+ value.
|
579
|
+
#
|
580
|
+
# +sms_to+ has a +body+ option for customizing the SMS message itself by
|
581
|
+
# passing special keys to +html_options+.
|
582
|
+
#
|
583
|
+
# ==== Options
|
584
|
+
# * <tt>:body</tt> - Preset the body of the message.
|
585
|
+
#
|
586
|
+
# ==== Examples
|
587
|
+
# sms_to "5155555785"
|
588
|
+
# # => <a href="sms:5155555785;">5155555785</a>
|
589
|
+
#
|
590
|
+
# sms_to "5155555785", "Text me"
|
591
|
+
# # => <a href="sms:5155555785;">Text me</a>
|
592
|
+
#
|
593
|
+
# sms_to "5155555785", "Text me",
|
594
|
+
# body: "Hello Jim I have a question about your product."
|
595
|
+
# # => <a href="sms:5155555785;?body=Hello%20Jim%20I%20have%20a%20question%20about%20your%20product">Text me</a>
|
596
|
+
#
|
597
|
+
# You can use a block as well if your link target is hard to fit into the name parameter. \ERB example:
|
598
|
+
#
|
599
|
+
# <%= sms_to "5155555785" do %>
|
600
|
+
# <strong>Text me:</strong>
|
601
|
+
# <% end %>
|
602
|
+
# # => <a href="sms:5155555785;">
|
603
|
+
# <strong>Text me:</strong>
|
604
|
+
# </a>
|
605
|
+
def sms_to(phone_number, name = nil, html_options = {}, &block)
|
606
|
+
html_options, name = name, nil if block_given?
|
607
|
+
html_options = (html_options || {}).stringify_keys
|
608
|
+
|
609
|
+
extras = %w{ body }.map! { |item|
|
610
|
+
option = html_options.delete(item).presence || next
|
611
|
+
"#{item.dasherize}=#{ERB::Util.url_encode(option)}"
|
612
|
+
}.compact
|
613
|
+
extras = extras.empty? ? "" : "?&" + extras.join("&")
|
614
|
+
|
615
|
+
encoded_phone_number = ERB::Util.url_encode(phone_number)
|
616
|
+
html_options["href"] = "sms:#{encoded_phone_number};#{extras}"
|
617
|
+
|
618
|
+
content_tag("a", name || phone_number, html_options, &block)
|
619
|
+
end
|
620
|
+
|
621
|
+
# Creates a TEL anchor link tag to the specified +phone_number+, which is
|
622
|
+
# also used as the name of the link unless +name+ is specified. Additional
|
623
|
+
# HTML attributes for the link can be passed in +html_options+.
|
624
|
+
#
|
625
|
+
# When clicked, the default app to make calls is opened, and it
|
626
|
+
# is prepopulated with the passed phone number and optional
|
627
|
+
# +country_code+ value.
|
628
|
+
#
|
629
|
+
# +phone_to+ has an optional +country_code+ option which automatically adds the country
|
630
|
+
# code as well as the + sign in the phone numer that gets prepopulated,
|
631
|
+
# for example if +country_code: "01"+ +\+01+ will be prepended to the
|
632
|
+
# phone numer, by passing special keys to +html_options+.
|
633
|
+
#
|
634
|
+
# ==== Options
|
635
|
+
# * <tt>:country_code</tt> - Prepends the country code to the number
|
636
|
+
#
|
637
|
+
# ==== Examples
|
638
|
+
# phone_to "1234567890"
|
639
|
+
# # => <a href="tel:1234567890">1234567890</a>
|
640
|
+
#
|
641
|
+
# phone_to "1234567890", "Phone me"
|
642
|
+
# # => <a href="tel:134567890">Phone me</a>
|
643
|
+
#
|
644
|
+
# phone_to "1234567890", "Phone me", country_code: "01"
|
645
|
+
# # => <a href="tel:+015155555785">Phone me</a>
|
646
|
+
#
|
647
|
+
# You can use a block as well if your link target is hard to fit into the name parameter. \ERB example:
|
648
|
+
#
|
649
|
+
# <%= phone_to "1234567890" do %>
|
650
|
+
# <strong>Phone me:</strong>
|
651
|
+
# <% end %>
|
652
|
+
# # => <a href="tel:1234567890">
|
653
|
+
# <strong>Phone me:</strong>
|
654
|
+
# </a>
|
655
|
+
def phone_to(phone_number, name = nil, html_options = {}, &block)
|
656
|
+
html_options, name = name, nil if block_given?
|
657
|
+
html_options = (html_options || {}).stringify_keys
|
658
|
+
|
659
|
+
country_code = html_options.delete("country_code").presence
|
660
|
+
country_code = country_code.nil? ? "" : "+#{ERB::Util.url_encode(country_code)}"
|
661
|
+
|
662
|
+
encoded_phone_number = ERB::Util.url_encode(phone_number)
|
663
|
+
html_options["href"] = "tel:#{country_code}#{encoded_phone_number}"
|
664
|
+
|
665
|
+
content_tag("a", name || phone_number, html_options, &block)
|
666
|
+
end
|
667
|
+
|
567
668
|
private
|
568
669
|
def convert_options_to_data_attributes(options, html_options)
|
569
670
|
if html_options
|
570
671
|
html_options = html_options.stringify_keys
|
571
|
-
html_options["data-remote"] = "true"
|
672
|
+
html_options["data-remote"] = "true" if link_to_remote_options?(options) || link_to_remote_options?(html_options)
|
572
673
|
|
573
|
-
method = html_options.delete("method"
|
674
|
+
method = html_options.delete("method")
|
574
675
|
|
575
676
|
add_method_to_attributes!(html_options, method) if method
|
576
677
|
|
577
678
|
html_options
|
578
679
|
else
|
579
|
-
link_to_remote_options?(options) ? { "data-remote" => "true"
|
680
|
+
link_to_remote_options?(options) ? { "data-remote" => "true" } : {}
|
580
681
|
end
|
581
682
|
end
|
582
683
|
|
583
684
|
def link_to_remote_options?(options)
|
584
685
|
if options.is_a?(Hash)
|
585
|
-
options.delete("remote"
|
686
|
+
options.delete("remote") || options.delete(:remote)
|
586
687
|
end
|
587
688
|
end
|
588
689
|
|
589
690
|
def add_method_to_attributes!(html_options, method)
|
590
|
-
if method &&
|
591
|
-
|
691
|
+
if method_not_get_method?(method) && !html_options["rel"]&.match?(/nofollow/)
|
692
|
+
if html_options["rel"].blank?
|
693
|
+
html_options["rel"] = "nofollow"
|
694
|
+
else
|
695
|
+
html_options["rel"] = "#{html_options["rel"]} nofollow"
|
696
|
+
end
|
592
697
|
end
|
593
|
-
html_options["data-method"
|
698
|
+
html_options["data-method"] = method
|
699
|
+
end
|
700
|
+
|
701
|
+
STRINGIFIED_COMMON_METHODS = {
|
702
|
+
get: "get",
|
703
|
+
delete: "delete",
|
704
|
+
patch: "patch",
|
705
|
+
post: "post",
|
706
|
+
put: "put",
|
707
|
+
}.freeze
|
708
|
+
|
709
|
+
def method_not_get_method?(method)
|
710
|
+
return false unless method
|
711
|
+
(STRINGIFIED_COMMON_METHODS[method] || method.to_s.downcase) != "get"
|
594
712
|
end
|
595
713
|
|
596
714
|
def token_tag(token = nil, form_options: {})
|
597
|
-
if token != false && protect_against_forgery?
|
715
|
+
if token != false && defined?(protect_against_forgery?) && protect_against_forgery?
|
598
716
|
token ||= form_authenticity_token(form_options: form_options)
|
599
717
|
tag(:input, type: "hidden", name: request_forgery_protection_token.to_s, value: token)
|
600
718
|
else
|
601
|
-
""
|
719
|
+
""
|
602
720
|
end
|
603
721
|
end
|
604
722
|
|
@@ -610,9 +728,9 @@ module ActionView
|
|
610
728
|
# suitable for use as the names and values of form input fields:
|
611
729
|
#
|
612
730
|
# to_form_params(name: 'David', nationality: 'Danish')
|
613
|
-
# # => [{name:
|
731
|
+
# # => [{name: 'name', value: 'David'}, {name: 'nationality', value: 'Danish'}]
|
614
732
|
#
|
615
|
-
# to_form_params(country: {name: 'Denmark'})
|
733
|
+
# to_form_params(country: { name: 'Denmark' })
|
616
734
|
# # => [{name: 'country[name]', value: 'Denmark'}]
|
617
735
|
#
|
618
736
|
# to_form_params(countries: ['Denmark', 'Sweden']})
|
@@ -642,7 +760,7 @@ module ActionView
|
|
642
760
|
params.push(*to_form_params(value, array_prefix))
|
643
761
|
end
|
644
762
|
else
|
645
|
-
params << { name: namespace, value: attribute.to_param }
|
763
|
+
params << { name: namespace.to_s, value: attribute.to_param }
|
646
764
|
end
|
647
765
|
|
648
766
|
params.sort_by { |pair| pair[:name] }
|
data/lib/action_view/layouts.rb
CHANGED
@@ -1,5 +1,7 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require "action_view/rendering"
|
2
|
-
require "active_support/core_ext/module/
|
4
|
+
require "active_support/core_ext/module/redefine_method"
|
3
5
|
|
4
6
|
module ActionView
|
5
7
|
# Layouts reverse the common pattern of including shared headers and footers in many templates to isolate changes in
|
@@ -204,9 +206,9 @@ module ActionView
|
|
204
206
|
include ActionView::Rendering
|
205
207
|
|
206
208
|
included do
|
207
|
-
class_attribute :_layout,
|
208
|
-
|
209
|
-
|
209
|
+
class_attribute :_layout, instance_accessor: false
|
210
|
+
class_attribute :_layout_conditions, instance_accessor: false, default: {}
|
211
|
+
|
210
212
|
_write_layout_method
|
211
213
|
end
|
212
214
|
|
@@ -222,7 +224,6 @@ module ActionView
|
|
222
224
|
# that if no layout conditions are used, this method is not used
|
223
225
|
module LayoutConditions # :nodoc:
|
224
226
|
private
|
225
|
-
|
226
227
|
# Determines whether the current action has a layout definition by
|
227
228
|
# checking the action name against the :only and :except conditions
|
228
229
|
# set by the <tt>layout</tt> method.
|
@@ -277,7 +278,7 @@ module ActionView
|
|
277
278
|
# If a layout is not explicitly mentioned then look for a layout with the controller's name.
|
278
279
|
# if nothing is found then try same procedure to find super class's layout.
|
279
280
|
def _write_layout_method # :nodoc:
|
280
|
-
|
281
|
+
silence_redefinition_of_method(:_layout)
|
281
282
|
|
282
283
|
prefixes = /\blayouts/.match?(_implied_layout_name) ? [] : ["layouts"]
|
283
284
|
default_behavior = "lookup_context.find_all('#{_implied_layout_name}', #{prefixes.inspect}, false, [], { formats: formats }).first || super"
|
@@ -305,7 +306,7 @@ module ActionView
|
|
305
306
|
RUBY
|
306
307
|
when Proc
|
307
308
|
define_method :_layout_from_proc, &_layout
|
308
|
-
|
309
|
+
private :_layout_from_proc
|
309
310
|
<<-RUBY
|
310
311
|
result = _layout_from_proc(#{_layout.arity == 0 ? '' : 'self'})
|
311
312
|
return #{default_behavior} if result.nil?
|
@@ -320,7 +321,8 @@ module ActionView
|
|
320
321
|
end
|
321
322
|
|
322
323
|
class_eval <<-RUBY, __FILE__, __LINE__ + 1
|
323
|
-
|
324
|
+
# frozen_string_literal: true
|
325
|
+
def _layout(lookup_context, formats)
|
324
326
|
if _conditional_layout?
|
325
327
|
#{layout_definition}
|
326
328
|
else
|
@@ -332,7 +334,6 @@ module ActionView
|
|
332
334
|
end
|
333
335
|
|
334
336
|
private
|
335
|
-
|
336
337
|
# If no layout is supplied, look for a template named the return
|
337
338
|
# value of this method.
|
338
339
|
#
|
@@ -370,7 +371,6 @@ module ActionView
|
|
370
371
|
end
|
371
372
|
|
372
373
|
private
|
373
|
-
|
374
374
|
def _conditional_layout?
|
375
375
|
true
|
376
376
|
end
|
@@ -386,8 +386,8 @@ module ActionView
|
|
386
386
|
case name
|
387
387
|
when String then _normalize_layout(name)
|
388
388
|
when Proc then name
|
389
|
-
when true then Proc.new { |formats| _default_layout(formats, true) }
|
390
|
-
when :default then Proc.new { |formats| _default_layout(formats, false) }
|
389
|
+
when true then Proc.new { |lookup_context, formats| _default_layout(lookup_context, formats, true) }
|
390
|
+
when :default then Proc.new { |lookup_context, formats| _default_layout(lookup_context, formats, false) }
|
391
391
|
when false, nil then nil
|
392
392
|
else
|
393
393
|
raise ArgumentError,
|
@@ -396,7 +396,7 @@ module ActionView
|
|
396
396
|
end
|
397
397
|
|
398
398
|
def _normalize_layout(value)
|
399
|
-
value.is_a?(String) && value
|
399
|
+
value.is_a?(String) && !value.match?(/\blayouts/) ? "layouts/#{value}" : value
|
400
400
|
end
|
401
401
|
|
402
402
|
# Returns the default layout for this controller.
|
@@ -409,9 +409,9 @@ module ActionView
|
|
409
409
|
#
|
410
410
|
# ==== Returns
|
411
411
|
# * <tt>template</tt> - The template object for the default layout (or +nil+)
|
412
|
-
def _default_layout(formats, require_layout = false)
|
412
|
+
def _default_layout(lookup_context, formats, require_layout = false)
|
413
413
|
begin
|
414
|
-
value = _layout(formats) if action_has_layout?
|
414
|
+
value = _layout(lookup_context, formats) if action_has_layout?
|
415
415
|
rescue NameError => e
|
416
416
|
raise e, "Could not render layout: #{e.message}"
|
417
417
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require "active_support/log_subscriber"
|
2
4
|
|
3
5
|
module ActionView
|
@@ -14,35 +16,42 @@ module ActionView
|
|
14
16
|
|
15
17
|
def render_template(event)
|
16
18
|
info do
|
17
|
-
message = " Rendered #{from_rails_root(event.payload[:identifier])}"
|
19
|
+
message = +" Rendered #{from_rails_root(event.payload[:identifier])}"
|
18
20
|
message << " within #{from_rails_root(event.payload[:layout])}" if event.payload[:layout]
|
19
|
-
message << " (#{event.duration.round(1)}ms)"
|
21
|
+
message << " (Duration: #{event.duration.round(1)}ms | Allocations: #{event.allocations})"
|
20
22
|
end
|
21
23
|
end
|
22
24
|
|
23
25
|
def render_partial(event)
|
24
|
-
|
25
|
-
message = " Rendered #{from_rails_root(event.payload[:identifier])}"
|
26
|
+
debug do
|
27
|
+
message = +" Rendered #{from_rails_root(event.payload[:identifier])}"
|
26
28
|
message << " within #{from_rails_root(event.payload[:layout])}" if event.payload[:layout]
|
27
|
-
message << " (#{event.duration.round(1)}ms)"
|
29
|
+
message << " (Duration: #{event.duration.round(1)}ms | Allocations: #{event.allocations})"
|
28
30
|
message << " #{cache_message(event.payload)}" unless event.payload[:cache_hit].nil?
|
29
31
|
message
|
30
32
|
end
|
31
33
|
end
|
32
34
|
|
35
|
+
def render_layout(event)
|
36
|
+
info do
|
37
|
+
message = +" Rendered layout #{from_rails_root(event.payload[:identifier])}"
|
38
|
+
message << " (Duration: #{event.duration.round(1)}ms | Allocations: #{event.allocations})"
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
33
42
|
def render_collection(event)
|
34
43
|
identifier = event.payload[:identifier] || "templates"
|
35
44
|
|
36
|
-
|
37
|
-
" Rendered collection of #{from_rails_root(identifier)}"
|
38
|
-
" #{
|
45
|
+
debug do
|
46
|
+
message = +" Rendered collection of #{from_rails_root(identifier)}"
|
47
|
+
message << " within #{from_rails_root(event.payload[:layout])}" if event.payload[:layout]
|
48
|
+
message << " #{render_count(event.payload)} (Duration: #{event.duration.round(1)}ms | Allocations: #{event.allocations})"
|
49
|
+
message
|
39
50
|
end
|
40
51
|
end
|
41
52
|
|
42
53
|
def start(name, id, payload)
|
43
|
-
|
44
|
-
log_rendering_start(payload)
|
45
|
-
end
|
54
|
+
log_rendering_start(payload, name)
|
46
55
|
|
47
56
|
super
|
48
57
|
end
|
@@ -52,7 +61,6 @@ module ActionView
|
|
52
61
|
end
|
53
62
|
|
54
63
|
private
|
55
|
-
|
56
64
|
EMPTY = ""
|
57
65
|
def from_rails_root(string) # :doc:
|
58
66
|
string = string.sub(rails_root, EMPTY)
|
@@ -81,9 +89,18 @@ module ActionView
|
|
81
89
|
end
|
82
90
|
end
|
83
91
|
|
84
|
-
def log_rendering_start(payload)
|
85
|
-
|
86
|
-
|
92
|
+
def log_rendering_start(payload, name)
|
93
|
+
debug do
|
94
|
+
qualifier =
|
95
|
+
if name == "render_template.action_view"
|
96
|
+
""
|
97
|
+
elsif name == "render_layout.action_view"
|
98
|
+
"layout "
|
99
|
+
end
|
100
|
+
|
101
|
+
return unless qualifier
|
102
|
+
|
103
|
+
message = +" Rendering #{qualifier}#{from_rails_root(payload[:identifier])}"
|
87
104
|
message << " within #{from_rails_root(payload[:layout])}" if payload[:layout]
|
88
105
|
message
|
89
106
|
end
|