actionview 5.2.8.1 → 6.1.6.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 +4 -4
- data/CHANGELOG.md +284 -112
- data/MIT-LICENSE +1 -2
- data/README.rdoc +5 -3
- data/lib/action_view/base.rb +81 -15
- data/lib/action_view/buffers.rb +15 -0
- data/lib/action_view/cache_expiry.rb +52 -0
- data/lib/action_view/context.rb +5 -9
- data/lib/action_view/dependency_tracker.rb +10 -4
- data/lib/action_view/digestor.rb +15 -22
- data/lib/action_view/flows.rb +0 -1
- data/lib/action_view/gem_version.rb +3 -3
- data/lib/action_view/helpers/active_model_helper.rb +0 -1
- data/lib/action_view/helpers/asset_tag_helper.rb +65 -48
- data/lib/action_view/helpers/asset_url_helper.rb +9 -6
- data/lib/action_view/helpers/atom_feed_helper.rb +2 -1
- data/lib/action_view/helpers/cache_helper.rb +23 -22
- data/lib/action_view/helpers/capture_helper.rb +4 -0
- data/lib/action_view/helpers/csp_helper.rb +4 -2
- data/lib/action_view/helpers/csrf_helper.rb +1 -1
- data/lib/action_view/helpers/date_helper.rb +75 -31
- data/lib/action_view/helpers/form_helper.rb +305 -37
- data/lib/action_view/helpers/form_options_helper.rb +23 -23
- data/lib/action_view/helpers/form_tag_helper.rb +21 -18
- data/lib/action_view/helpers/javascript_helper.rb +12 -11
- data/lib/action_view/helpers/number_helper.rb +14 -8
- data/lib/action_view/helpers/output_safety_helper.rb +1 -1
- data/lib/action_view/helpers/rendering_helper.rb +17 -7
- data/lib/action_view/helpers/sanitize_helper.rb +12 -18
- data/lib/action_view/helpers/tag_helper.rb +103 -26
- data/lib/action_view/helpers/tags/base.rb +19 -12
- data/lib/action_view/helpers/tags/check_box.rb +1 -2
- data/lib/action_view/helpers/tags/collection_check_boxes.rb +0 -1
- data/lib/action_view/helpers/tags/collection_helpers.rb +0 -1
- data/lib/action_view/helpers/tags/collection_radio_buttons.rb +0 -1
- data/lib/action_view/helpers/tags/color_field.rb +1 -2
- data/lib/action_view/helpers/tags/date_field.rb +1 -2
- data/lib/action_view/helpers/tags/date_select.rb +2 -3
- data/lib/action_view/helpers/tags/datetime_field.rb +0 -1
- data/lib/action_view/helpers/tags/datetime_local_field.rb +1 -2
- data/lib/action_view/helpers/tags/hidden_field.rb +4 -0
- data/lib/action_view/helpers/tags/label.rb +4 -1
- data/lib/action_view/helpers/tags/month_field.rb +1 -2
- data/lib/action_view/helpers/tags/radio_button.rb +0 -1
- data/lib/action_view/helpers/tags/select.rb +1 -2
- data/lib/action_view/helpers/tags/text_field.rb +0 -1
- data/lib/action_view/helpers/tags/time_field.rb +1 -2
- data/lib/action_view/helpers/tags/translator.rb +1 -6
- data/lib/action_view/helpers/tags/week_field.rb +1 -2
- data/lib/action_view/helpers/text_helper.rb +4 -5
- data/lib/action_view/helpers/translation_helper.rb +94 -54
- data/lib/action_view/helpers/url_helper.rb +150 -38
- data/lib/action_view/helpers.rb +0 -2
- data/lib/action_view/layouts.rb +8 -10
- data/lib/action_view/log_subscriber.rb +30 -15
- data/lib/action_view/lookup_context.rb +63 -35
- data/lib/action_view/path_set.rb +3 -12
- data/lib/action_view/railtie.rb +42 -26
- data/lib/action_view/record_identifier.rb +2 -3
- data/lib/action_view/renderer/abstract_renderer.rb +142 -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/collection_caching.rb +61 -16
- data/lib/action_view/renderer/partial_renderer.rb +21 -273
- data/lib/action_view/renderer/renderer.rb +59 -4
- data/lib/action_view/renderer/streaming_template_renderer.rb +10 -8
- data/lib/action_view/renderer/template_renderer.rb +35 -27
- data/lib/action_view/rendering.rb +54 -33
- data/lib/action_view/routing_url_for.rb +13 -12
- data/lib/action_view/template/error.rb +30 -15
- data/lib/action_view/template/handlers/builder.rb +2 -2
- data/lib/action_view/template/handlers/erb/erubi.rb +15 -9
- data/lib/action_view/template/handlers/erb.rb +16 -11
- data/lib/action_view/template/handlers/html.rb +1 -1
- data/lib/action_view/template/handlers/raw.rb +2 -2
- data/lib/action_view/template/handlers.rb +1 -1
- data/lib/action_view/template/html.rb +5 -6
- 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 +191 -150
- data/lib/action_view/template/sources/file.rb +17 -0
- data/lib/action_view/template/sources.rb +13 -0
- data/lib/action_view/template/text.rb +2 -3
- data/lib/action_view/template.rb +66 -75
- data/lib/action_view/test_case.rb +21 -29
- data/lib/action_view/testing/resolvers.rb +18 -27
- data/lib/action_view/unbound_template.rb +31 -0
- data/lib/action_view/view_paths.rb +59 -38
- data/lib/action_view.rb +7 -2
- data/lib/assets/compiled/rails-ujs.js +32 -6
- metadata +28 -16
- data/lib/action_view/helpers/record_tag_helper.rb +0 -23
@@ -45,7 +45,7 @@ module ActionView
|
|
45
45
|
def _back_url # :nodoc:
|
46
46
|
_filtered_referrer || "javascript:history.back()"
|
47
47
|
end
|
48
|
-
|
48
|
+
private :_back_url
|
49
49
|
|
50
50
|
def _filtered_referrer # :nodoc:
|
51
51
|
if controller.respond_to?(:request)
|
@@ -56,12 +56,12 @@ module ActionView
|
|
56
56
|
end
|
57
57
|
rescue URI::InvalidURIError
|
58
58
|
end
|
59
|
-
|
59
|
+
private :_filtered_referrer
|
60
60
|
|
61
61
|
# Creates an anchor element of the given +name+ using a URL created by the set of +options+.
|
62
62
|
# See the valid options in the documentation for +url_for+. It's also possible to
|
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
|
+
# 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
|
65
65
|
# of an options hash will generate a link to the referrer (a JavaScript back link
|
66
66
|
# will be used in place of a referrer if none exists). If +nil+ is passed as the name
|
67
67
|
# the value of the link itself will become the name.
|
@@ -177,7 +177,7 @@ module ActionView
|
|
177
177
|
# # => <a href="/searches?query=ruby+on+rails">Ruby on Rails search</a>
|
178
178
|
#
|
179
179
|
# link_to "Nonsense search", searches_path(foo: "bar", baz: "quux")
|
180
|
-
# # => <a href="/searches?foo=bar&
|
180
|
+
# # => <a href="/searches?foo=bar&baz=quux">Nonsense search</a>
|
181
181
|
#
|
182
182
|
# The only option specific to +link_to+ (<tt>:method</tt>) is used as follows:
|
183
183
|
#
|
@@ -200,9 +200,9 @@ module ActionView
|
|
200
200
|
html_options = convert_options_to_data_attributes(options, html_options)
|
201
201
|
|
202
202
|
url = url_for(options)
|
203
|
-
html_options["href"
|
203
|
+
html_options["href"] ||= url
|
204
204
|
|
205
|
-
content_tag("a"
|
205
|
+
content_tag("a", name || url, html_options, &block)
|
206
206
|
end
|
207
207
|
|
208
208
|
# Generates a form containing a single button that submits to the URL created
|
@@ -226,7 +226,7 @@ module ActionView
|
|
226
226
|
# The +options+ hash accepts the same options as +url_for+.
|
227
227
|
#
|
228
228
|
# There are a few special +html_options+:
|
229
|
-
# * <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>,
|
230
230
|
# <tt>:delete</tt>, <tt>:patch</tt>, and <tt>:put</tt>. By default it will be <tt>:post</tt>.
|
231
231
|
# * <tt>:disabled</tt> - If set to true, it will generate a disabled button.
|
232
232
|
# * <tt>:data</tt> - This option can be used to add custom data attributes.
|
@@ -235,7 +235,7 @@ module ActionView
|
|
235
235
|
# * <tt>:form</tt> - This hash will be form attributes
|
236
236
|
# * <tt>:form_class</tt> - This controls the class of the form within which the submit button will
|
237
237
|
# be placed
|
238
|
-
# * <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.
|
239
239
|
#
|
240
240
|
# ==== Data attributes
|
241
241
|
#
|
@@ -290,7 +290,7 @@ module ActionView
|
|
290
290
|
#
|
291
291
|
#
|
292
292
|
# <%= button_to('Destroy', 'http://www.example.com',
|
293
|
-
# method:
|
293
|
+
# method: :delete, remote: true, data: { confirm: 'Are you sure?', disable_with: 'loading...' }) %>
|
294
294
|
# # => "<form class='button_to' method='post' action='http://www.example.com' data-remote='true'>
|
295
295
|
# # <input name='_method' value='delete' type='hidden' />
|
296
296
|
# # <input value='Destroy' type='submit' data-disable-with='loading...' data-confirm='Are you sure?' />
|
@@ -308,7 +308,7 @@ module ActionView
|
|
308
308
|
params = html_options.delete("params")
|
309
309
|
|
310
310
|
method = html_options.delete("method").to_s
|
311
|
-
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
|
312
312
|
|
313
313
|
form_method = method == "get" ? "get" : "post"
|
314
314
|
form_options = html_options.delete("form") || {}
|
@@ -321,7 +321,7 @@ module ActionView
|
|
321
321
|
request_method = method.empty? ? "post" : method
|
322
322
|
token_tag(nil, form_options: { action: url, method: request_method })
|
323
323
|
else
|
324
|
-
""
|
324
|
+
""
|
325
325
|
end
|
326
326
|
|
327
327
|
html_options = convert_options_to_data_attributes(options, html_options)
|
@@ -337,7 +337,8 @@ module ActionView
|
|
337
337
|
inner_tags = method_tag.safe_concat(button).safe_concat(request_token_tag)
|
338
338
|
if params
|
339
339
|
to_form_params(params).each do |param|
|
340
|
-
inner_tags.safe_concat tag(:input, type: "hidden", name: param[:name], value: param[:value]
|
340
|
+
inner_tags.safe_concat tag(:input, type: "hidden", name: param[:name], value: param[:value],
|
341
|
+
autocomplete: "off")
|
341
342
|
end
|
342
343
|
end
|
343
344
|
content_tag("form", inner_tags, form_options)
|
@@ -412,8 +413,7 @@ module ActionView
|
|
412
413
|
# Creates a link tag of the given +name+ using a URL created by the set of
|
413
414
|
# +options+ if +condition+ is true, otherwise only the name is
|
414
415
|
# returned. To specialize the default behavior, you can pass a block that
|
415
|
-
# accepts the name or the full argument list for +
|
416
|
-
# in +link_to_unless+).
|
416
|
+
# accepts the name or the full argument list for +link_to_if+.
|
417
417
|
#
|
418
418
|
# ==== Examples
|
419
419
|
# <%= link_to_if(@current_user.nil?, "Login", { controller: "sessions", action: "new" }) %>
|
@@ -487,12 +487,12 @@ module ActionView
|
|
487
487
|
option = html_options.delete(item).presence || next
|
488
488
|
"#{item.dasherize}=#{ERB::Util.url_encode(option)}"
|
489
489
|
}.compact
|
490
|
-
extras = extras.empty? ? ""
|
490
|
+
extras = extras.empty? ? "" : "?" + extras.join("&")
|
491
491
|
|
492
492
|
encoded_email_address = ERB::Util.url_encode(email_address).gsub("%40", "@")
|
493
493
|
html_options["href"] = "mailto:#{encoded_email_address}#{extras}"
|
494
494
|
|
495
|
-
content_tag("a"
|
495
|
+
content_tag("a", name || email_address, html_options, &block)
|
496
496
|
end
|
497
497
|
|
498
498
|
# True if the current request URI was generated by the given +options+.
|
@@ -540,7 +540,7 @@ module ActionView
|
|
540
540
|
#
|
541
541
|
# We can also pass in the symbol arguments instead of strings.
|
542
542
|
#
|
543
|
-
def current_page?(options, check_parameters: false)
|
543
|
+
def current_page?(options = nil, check_parameters: false, **options_as_kwargs)
|
544
544
|
unless request
|
545
545
|
raise "You cannot use helpers that need to determine the current " \
|
546
546
|
"page unless your view context provides a Request object " \
|
@@ -549,52 +549,159 @@ module ActionView
|
|
549
549
|
|
550
550
|
return false unless request.get? || request.head?
|
551
551
|
|
552
|
+
options ||= options_as_kwargs
|
552
553
|
check_parameters ||= options.is_a?(Hash) && options.delete(:check_parameters)
|
553
|
-
url_string = URI.
|
554
|
+
url_string = URI::DEFAULT_PARSER.unescape(url_for(options)).force_encoding(Encoding::BINARY)
|
554
555
|
|
555
556
|
# We ignore any extra parameters in the request_uri if the
|
556
|
-
# submitted
|
557
|
+
# submitted URL doesn't have any either. This lets the function
|
557
558
|
# work with things like ?order=asc
|
558
559
|
# the behaviour can be disabled with check_parameters: true
|
559
560
|
request_uri = url_string.index("?") || check_parameters ? request.fullpath : request.path
|
560
|
-
request_uri = URI.
|
561
|
+
request_uri = URI::DEFAULT_PARSER.unescape(request_uri).force_encoding(Encoding::BINARY)
|
561
562
|
|
562
|
-
if
|
563
|
-
|
564
|
-
request_uri.chomp!("/")
|
563
|
+
if %r{^\w+://}.match?(url_string)
|
564
|
+
request_uri = +"#{request.protocol}#{request.host_with_port}#{request_uri}"
|
565
565
|
end
|
566
566
|
|
567
|
-
|
568
|
-
|
569
|
-
|
570
|
-
|
567
|
+
remove_trailing_slash!(url_string)
|
568
|
+
remove_trailing_slash!(request_uri)
|
569
|
+
|
570
|
+
url_string == request_uri
|
571
|
+
end
|
572
|
+
|
573
|
+
if RUBY_VERSION.start_with?("2.7")
|
574
|
+
using Module.new {
|
575
|
+
refine UrlHelper do
|
576
|
+
alias :_current_page? :current_page?
|
577
|
+
end
|
578
|
+
}
|
579
|
+
|
580
|
+
def current_page?(*args) # :nodoc:
|
581
|
+
options = args.pop
|
582
|
+
options.is_a?(Hash) ? _current_page?(*args, **options) : _current_page?(*args, options)
|
571
583
|
end
|
572
584
|
end
|
573
585
|
|
586
|
+
# Creates an SMS anchor link tag to the specified +phone_number+, which is
|
587
|
+
# also used as the name of the link unless +name+ is specified. Additional
|
588
|
+
# HTML attributes for the link can be passed in +html_options+.
|
589
|
+
#
|
590
|
+
# When clicked, an SMS message is prepopulated with the passed phone number
|
591
|
+
# and optional +body+ value.
|
592
|
+
#
|
593
|
+
# +sms_to+ has a +body+ option for customizing the SMS message itself by
|
594
|
+
# passing special keys to +html_options+.
|
595
|
+
#
|
596
|
+
# ==== Options
|
597
|
+
# * <tt>:body</tt> - Preset the body of the message.
|
598
|
+
#
|
599
|
+
# ==== Examples
|
600
|
+
# sms_to "5155555785"
|
601
|
+
# # => <a href="sms:5155555785;">5155555785</a>
|
602
|
+
#
|
603
|
+
# sms_to "5155555785", "Text me"
|
604
|
+
# # => <a href="sms:5155555785;">Text me</a>
|
605
|
+
#
|
606
|
+
# sms_to "5155555785", "Text me",
|
607
|
+
# body: "Hello Jim I have a question about your product."
|
608
|
+
# # => <a href="sms:5155555785;?body=Hello%20Jim%20I%20have%20a%20question%20about%20your%20product">Text me</a>
|
609
|
+
#
|
610
|
+
# You can use a block as well if your link target is hard to fit into the name parameter. \ERB example:
|
611
|
+
#
|
612
|
+
# <%= sms_to "5155555785" do %>
|
613
|
+
# <strong>Text me:</strong>
|
614
|
+
# <% end %>
|
615
|
+
# # => <a href="sms:5155555785;">
|
616
|
+
# <strong>Text me:</strong>
|
617
|
+
# </a>
|
618
|
+
def sms_to(phone_number, name = nil, html_options = {}, &block)
|
619
|
+
html_options, name = name, nil if block_given?
|
620
|
+
html_options = (html_options || {}).stringify_keys
|
621
|
+
|
622
|
+
extras = %w{ body }.map! { |item|
|
623
|
+
option = html_options.delete(item).presence || next
|
624
|
+
"#{item.dasherize}=#{ERB::Util.url_encode(option)}"
|
625
|
+
}.compact
|
626
|
+
extras = extras.empty? ? "" : "?&" + extras.join("&")
|
627
|
+
|
628
|
+
encoded_phone_number = ERB::Util.url_encode(phone_number)
|
629
|
+
html_options["href"] = "sms:#{encoded_phone_number};#{extras}"
|
630
|
+
|
631
|
+
content_tag("a", name || phone_number, html_options, &block)
|
632
|
+
end
|
633
|
+
|
634
|
+
# Creates a TEL anchor link tag to the specified +phone_number+, which is
|
635
|
+
# also used as the name of the link unless +name+ is specified. Additional
|
636
|
+
# HTML attributes for the link can be passed in +html_options+.
|
637
|
+
#
|
638
|
+
# When clicked, the default app to make calls is opened, and it
|
639
|
+
# is prepopulated with the passed phone number and optional
|
640
|
+
# +country_code+ value.
|
641
|
+
#
|
642
|
+
# +phone_to+ has an optional +country_code+ option which automatically adds the country
|
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+.
|
646
|
+
#
|
647
|
+
# ==== Options
|
648
|
+
# * <tt>:country_code</tt> - Prepends the country code to the number
|
649
|
+
#
|
650
|
+
# ==== Examples
|
651
|
+
# phone_to "1234567890"
|
652
|
+
# # => <a href="tel:1234567890">1234567890</a>
|
653
|
+
#
|
654
|
+
# phone_to "1234567890", "Phone me"
|
655
|
+
# # => <a href="tel:134567890">Phone me</a>
|
656
|
+
#
|
657
|
+
# phone_to "1234567890", "Phone me", country_code: "01"
|
658
|
+
# # => <a href="tel:+015155555785">Phone me</a>
|
659
|
+
#
|
660
|
+
# You can use a block as well if your link target is hard to fit into the name parameter. \ERB example:
|
661
|
+
#
|
662
|
+
# <%= phone_to "1234567890" do %>
|
663
|
+
# <strong>Phone me:</strong>
|
664
|
+
# <% end %>
|
665
|
+
# # => <a href="tel:1234567890">
|
666
|
+
# <strong>Phone me:</strong>
|
667
|
+
# </a>
|
668
|
+
def phone_to(phone_number, name = nil, html_options = {}, &block)
|
669
|
+
html_options, name = name, nil if block_given?
|
670
|
+
html_options = (html_options || {}).stringify_keys
|
671
|
+
|
672
|
+
country_code = html_options.delete("country_code").presence
|
673
|
+
country_code = country_code.nil? ? "" : "+#{ERB::Util.url_encode(country_code)}"
|
674
|
+
|
675
|
+
encoded_phone_number = ERB::Util.url_encode(phone_number)
|
676
|
+
html_options["href"] = "tel:#{country_code}#{encoded_phone_number}"
|
677
|
+
|
678
|
+
content_tag("a", name || phone_number, html_options, &block)
|
679
|
+
end
|
680
|
+
|
574
681
|
private
|
575
682
|
def convert_options_to_data_attributes(options, html_options)
|
576
683
|
if html_options
|
577
684
|
html_options = html_options.stringify_keys
|
578
|
-
html_options["data-remote"] = "true"
|
685
|
+
html_options["data-remote"] = "true" if link_to_remote_options?(options) || link_to_remote_options?(html_options)
|
579
686
|
|
580
|
-
method = html_options.delete("method"
|
687
|
+
method = html_options.delete("method")
|
581
688
|
|
582
689
|
add_method_to_attributes!(html_options, method) if method
|
583
690
|
|
584
691
|
html_options
|
585
692
|
else
|
586
|
-
link_to_remote_options?(options) ? { "data-remote" => "true"
|
693
|
+
link_to_remote_options?(options) ? { "data-remote" => "true" } : {}
|
587
694
|
end
|
588
695
|
end
|
589
696
|
|
590
697
|
def link_to_remote_options?(options)
|
591
698
|
if options.is_a?(Hash)
|
592
|
-
options.delete("remote"
|
699
|
+
options.delete("remote") || options.delete(:remote)
|
593
700
|
end
|
594
701
|
end
|
595
702
|
|
596
703
|
def add_method_to_attributes!(html_options, method)
|
597
|
-
if method_not_get_method?(method) && html_options["rel"]
|
704
|
+
if method_not_get_method?(method) && !html_options["rel"]&.match?(/nofollow/)
|
598
705
|
if html_options["rel"].blank?
|
599
706
|
html_options["rel"] = "nofollow"
|
600
707
|
else
|
@@ -618,16 +725,16 @@ module ActionView
|
|
618
725
|
end
|
619
726
|
|
620
727
|
def token_tag(token = nil, form_options: {})
|
621
|
-
if token != false && protect_against_forgery?
|
728
|
+
if token != false && defined?(protect_against_forgery?) && protect_against_forgery?
|
622
729
|
token ||= form_authenticity_token(form_options: form_options)
|
623
|
-
tag(:input, type: "hidden", name: request_forgery_protection_token.to_s, value: token)
|
730
|
+
tag(:input, type: "hidden", name: request_forgery_protection_token.to_s, value: token, autocomplete: "off")
|
624
731
|
else
|
625
|
-
""
|
732
|
+
""
|
626
733
|
end
|
627
734
|
end
|
628
735
|
|
629
736
|
def method_tag(method)
|
630
|
-
tag("input", type: "hidden", name: "_method", value: method.to_s)
|
737
|
+
tag("input", type: "hidden", name: "_method", value: method.to_s, autocomplete: "off")
|
631
738
|
end
|
632
739
|
|
633
740
|
# Returns an array of hashes each containing :name and :value keys
|
@@ -636,7 +743,7 @@ module ActionView
|
|
636
743
|
# to_form_params(name: 'David', nationality: 'Danish')
|
637
744
|
# # => [{name: 'name', value: 'David'}, {name: 'nationality', value: 'Danish'}]
|
638
745
|
#
|
639
|
-
# to_form_params(country: {name: 'Denmark'})
|
746
|
+
# to_form_params(country: { name: 'Denmark' })
|
640
747
|
# # => [{name: 'country[name]', value: 'Denmark'}]
|
641
748
|
#
|
642
749
|
# to_form_params(countries: ['Denmark', 'Sweden']})
|
@@ -671,6 +778,11 @@ module ActionView
|
|
671
778
|
|
672
779
|
params.sort_by { |pair| pair[:name] }
|
673
780
|
end
|
781
|
+
|
782
|
+
def remove_trailing_slash!(url_string)
|
783
|
+
trailing_index = (url_string.index("?") || 0) - 1
|
784
|
+
url_string[trailing_index] = "" if url_string[trailing_index] == "/"
|
785
|
+
end
|
674
786
|
end
|
675
787
|
end
|
676
788
|
end
|
data/lib/action_view/helpers.rb
CHANGED
@@ -23,7 +23,6 @@ module ActionView #:nodoc:
|
|
23
23
|
autoload :JavaScriptHelper, "action_view/helpers/javascript_helper"
|
24
24
|
autoload :NumberHelper
|
25
25
|
autoload :OutputSafetyHelper
|
26
|
-
autoload :RecordTagHelper
|
27
26
|
autoload :RenderingHelper
|
28
27
|
autoload :SanitizeHelper
|
29
28
|
autoload :TagHelper
|
@@ -57,7 +56,6 @@ module ActionView #:nodoc:
|
|
57
56
|
include JavaScriptHelper
|
58
57
|
include NumberHelper
|
59
58
|
include OutputSafetyHelper
|
60
|
-
include RecordTagHelper
|
61
59
|
include RenderingHelper
|
62
60
|
include SanitizeHelper
|
63
61
|
include TagHelper
|
data/lib/action_view/layouts.rb
CHANGED
@@ -224,7 +224,6 @@ module ActionView
|
|
224
224
|
# that if no layout conditions are used, this method is not used
|
225
225
|
module LayoutConditions # :nodoc:
|
226
226
|
private
|
227
|
-
|
228
227
|
# Determines whether the current action has a layout definition by
|
229
228
|
# checking the action name against the :only and :except conditions
|
230
229
|
# set by the <tt>layout</tt> method.
|
@@ -307,7 +306,7 @@ module ActionView
|
|
307
306
|
RUBY
|
308
307
|
when Proc
|
309
308
|
define_method :_layout_from_proc, &_layout
|
310
|
-
|
309
|
+
private :_layout_from_proc
|
311
310
|
<<-RUBY
|
312
311
|
result = _layout_from_proc(#{_layout.arity == 0 ? '' : 'self'})
|
313
312
|
return #{default_behavior} if result.nil?
|
@@ -322,7 +321,8 @@ module ActionView
|
|
322
321
|
end
|
323
322
|
|
324
323
|
class_eval <<-RUBY, __FILE__, __LINE__ + 1
|
325
|
-
|
324
|
+
# frozen_string_literal: true
|
325
|
+
def _layout(lookup_context, formats)
|
326
326
|
if _conditional_layout?
|
327
327
|
#{layout_definition}
|
328
328
|
else
|
@@ -334,7 +334,6 @@ module ActionView
|
|
334
334
|
end
|
335
335
|
|
336
336
|
private
|
337
|
-
|
338
337
|
# If no layout is supplied, look for a template named the return
|
339
338
|
# value of this method.
|
340
339
|
#
|
@@ -372,7 +371,6 @@ module ActionView
|
|
372
371
|
end
|
373
372
|
|
374
373
|
private
|
375
|
-
|
376
374
|
def _conditional_layout?
|
377
375
|
true
|
378
376
|
end
|
@@ -388,8 +386,8 @@ module ActionView
|
|
388
386
|
case name
|
389
387
|
when String then _normalize_layout(name)
|
390
388
|
when Proc then name
|
391
|
-
when true then Proc.new { |formats| _default_layout(formats, true) }
|
392
|
-
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) }
|
393
391
|
when false, nil then nil
|
394
392
|
else
|
395
393
|
raise ArgumentError,
|
@@ -398,7 +396,7 @@ module ActionView
|
|
398
396
|
end
|
399
397
|
|
400
398
|
def _normalize_layout(value)
|
401
|
-
value.is_a?(String) && value
|
399
|
+
value.is_a?(String) && !value.match?(/\blayouts/) ? "layouts/#{value}" : value
|
402
400
|
end
|
403
401
|
|
404
402
|
# Returns the default layout for this controller.
|
@@ -411,9 +409,9 @@ module ActionView
|
|
411
409
|
#
|
412
410
|
# ==== Returns
|
413
411
|
# * <tt>template</tt> - The template object for the default layout (or +nil+)
|
414
|
-
def _default_layout(formats, require_layout = false)
|
412
|
+
def _default_layout(lookup_context, formats, require_layout = false)
|
415
413
|
begin
|
416
|
-
value = _layout(formats) if action_has_layout?
|
414
|
+
value = _layout(lookup_context, formats) if action_has_layout?
|
417
415
|
rescue NameError => e
|
418
416
|
raise e, "Could not render layout: #{e.message}"
|
419
417
|
end
|
@@ -16,35 +16,42 @@ module ActionView
|
|
16
16
|
|
17
17
|
def render_template(event)
|
18
18
|
info do
|
19
|
-
message = " Rendered #{from_rails_root(event.payload[:identifier])}"
|
19
|
+
message = +" Rendered #{from_rails_root(event.payload[:identifier])}"
|
20
20
|
message << " within #{from_rails_root(event.payload[:layout])}" if event.payload[:layout]
|
21
|
-
message << " (#{event.duration.round(1)}ms)"
|
21
|
+
message << " (Duration: #{event.duration.round(1)}ms | Allocations: #{event.allocations})"
|
22
22
|
end
|
23
23
|
end
|
24
24
|
|
25
25
|
def render_partial(event)
|
26
|
-
|
27
|
-
message = " Rendered #{from_rails_root(event.payload[:identifier])}"
|
26
|
+
debug do
|
27
|
+
message = +" Rendered #{from_rails_root(event.payload[:identifier])}"
|
28
28
|
message << " within #{from_rails_root(event.payload[:layout])}" if event.payload[:layout]
|
29
|
-
message << " (#{event.duration.round(1)}ms)"
|
29
|
+
message << " (Duration: #{event.duration.round(1)}ms | Allocations: #{event.allocations})"
|
30
30
|
message << " #{cache_message(event.payload)}" unless event.payload[:cache_hit].nil?
|
31
31
|
message
|
32
32
|
end
|
33
33
|
end
|
34
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
|
+
|
35
42
|
def render_collection(event)
|
36
43
|
identifier = event.payload[:identifier] || "templates"
|
37
44
|
|
38
|
-
|
39
|
-
" Rendered collection of #{from_rails_root(identifier)}"
|
40
|
-
" #{
|
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
|
41
50
|
end
|
42
51
|
end
|
43
52
|
|
44
53
|
def start(name, id, payload)
|
45
|
-
|
46
|
-
log_rendering_start(payload)
|
47
|
-
end
|
54
|
+
log_rendering_start(payload, name)
|
48
55
|
|
49
56
|
super
|
50
57
|
end
|
@@ -54,7 +61,6 @@ module ActionView
|
|
54
61
|
end
|
55
62
|
|
56
63
|
private
|
57
|
-
|
58
64
|
EMPTY = ""
|
59
65
|
def from_rails_root(string) # :doc:
|
60
66
|
string = string.sub(rails_root, EMPTY)
|
@@ -83,9 +89,18 @@ module ActionView
|
|
83
89
|
end
|
84
90
|
end
|
85
91
|
|
86
|
-
def log_rendering_start(payload)
|
87
|
-
|
88
|
-
|
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])}"
|
89
104
|
message << " within #{from_rails_root(payload[:layout])}" if payload[:layout]
|
90
105
|
message
|
91
106
|
end
|