actionview 5.0.7.2 → 5.1.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +169 -345
- data/MIT-LICENSE +1 -1
- data/README.rdoc +1 -1
- data/lib/action_view/base.rb +19 -19
- data/lib/action_view/buffers.rb +1 -1
- data/lib/action_view/context.rb +1 -1
- data/lib/action_view/dependency_tracker.rb +4 -5
- data/lib/action_view/digestor.rb +22 -13
- data/lib/action_view/flows.rb +5 -6
- data/lib/action_view/gem_version.rb +2 -2
- data/lib/action_view/helpers/active_model_helper.rb +8 -8
- data/lib/action_view/helpers/asset_tag_helper.rb +62 -36
- data/lib/action_view/helpers/asset_url_helper.rb +111 -49
- data/lib/action_view/helpers/atom_feed_helper.rb +12 -13
- data/lib/action_view/helpers/cache_helper.rb +32 -20
- 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/csrf_helper.rb +3 -3
- data/lib/action_view/helpers/date_helper.rb +119 -109
- data/lib/action_view/helpers/debug_helper.rb +2 -3
- data/lib/action_view/helpers/form_helper.rb +440 -31
- data/lib/action_view/helpers/form_options_helper.rb +12 -12
- data/lib/action_view/helpers/form_tag_helper.rb +20 -19
- data/lib/action_view/helpers/javascript_helper.rb +6 -6
- data/lib/action_view/helpers/number_helper.rb +48 -46
- data/lib/action_view/helpers/output_safety_helper.rb +8 -8
- data/lib/action_view/helpers/record_tag_helper.rb +2 -2
- data/lib/action_view/helpers/rendering_helper.rb +2 -3
- data/lib/action_view/helpers/sanitize_helper.rb +16 -12
- data/lib/action_view/helpers/tag_helper.rb +194 -77
- data/lib/action_view/helpers/tags/base.rb +121 -102
- data/lib/action_view/helpers/tags/check_box.rb +17 -17
- data/lib/action_view/helpers/tags/collection_check_boxes.rb +9 -8
- data/lib/action_view/helpers/tags/collection_helpers.rb +60 -60
- data/lib/action_view/helpers/tags/collection_radio_buttons.rb +3 -2
- data/lib/action_view/helpers/tags/collection_select.rb +2 -2
- data/lib/action_view/helpers/tags/date_select.rb +36 -36
- data/lib/action_view/helpers/tags/grouped_collection_select.rb +2 -2
- data/lib/action_view/helpers/tags/label.rb +4 -0
- data/lib/action_view/helpers/tags/password_field.rb +1 -1
- data/lib/action_view/helpers/tags/radio_button.rb +4 -4
- data/lib/action_view/helpers/tags/select.rb +9 -9
- data/lib/action_view/helpers/tags/text_area.rb +1 -1
- data/lib/action_view/helpers/tags/text_field.rb +5 -5
- data/lib/action_view/helpers/tags/translator.rb +14 -12
- data/lib/action_view/helpers/text_helper.rb +20 -19
- data/lib/action_view/helpers/translation_helper.rb +6 -6
- data/lib/action_view/helpers/url_helper.rb +48 -46
- data/lib/action_view/helpers.rb +1 -1
- data/lib/action_view/layouts.rb +51 -47
- data/lib/action_view/log_subscriber.rb +25 -9
- data/lib/action_view/lookup_context.rb +19 -25
- data/lib/action_view/path_set.rb +19 -19
- data/lib/action_view/railtie.rb +13 -4
- data/lib/action_view/record_identifier.rb +6 -6
- data/lib/action_view/renderer/abstract_renderer.rb +17 -17
- data/lib/action_view/renderer/partial_renderer/collection_caching.rb +7 -1
- data/lib/action_view/renderer/partial_renderer.rb +188 -187
- data/lib/action_view/renderer/renderer.rb +4 -0
- data/lib/action_view/renderer/streaming_template_renderer.rb +45 -47
- data/lib/action_view/renderer/template_renderer.rb +64 -66
- data/lib/action_view/rendering.rb +4 -5
- data/lib/action_view/routing_url_for.rb +9 -13
- data/lib/action_view/tasks/cache_digests.rake +7 -7
- data/lib/action_view/template/error.rb +5 -15
- data/lib/action_view/template/handlers/builder.rb +7 -7
- data/lib/action_view/template/handlers/erb/deprecated_erubis.rb +9 -0
- data/lib/action_view/template/handlers/erb/erubi.rb +81 -0
- data/lib/action_view/template/handlers/erb/erubis.rb +81 -0
- data/lib/action_view/template/handlers/erb.rb +9 -76
- data/lib/action_view/template/handlers.rb +4 -4
- data/lib/action_view/template/html.rb +2 -4
- data/lib/action_view/template/resolver.rb +107 -90
- data/lib/action_view/template/text.rb +5 -8
- data/lib/action_view/template/types.rb +1 -1
- data/lib/action_view/template.rb +26 -27
- data/lib/action_view/test_case.rb +20 -21
- data/lib/action_view/testing/resolvers.rb +29 -30
- data/lib/action_view/version.rb +1 -1
- data/lib/action_view/view_paths.rb +20 -8
- data/lib/action_view.rb +5 -5
- data/lib/assets/compiled/rails-ujs.js +683 -0
- metadata +18 -12
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
require
|
|
2
|
-
require
|
|
3
|
-
require
|
|
4
|
-
require
|
|
1
|
+
require "action_view/helpers/javascript_helper"
|
|
2
|
+
require "active_support/core_ext/array/access"
|
|
3
|
+
require "active_support/core_ext/hash/keys"
|
|
4
|
+
require "active_support/core_ext/string/output_safety"
|
|
5
5
|
|
|
6
6
|
module ActionView
|
|
7
7
|
# = Action View URL Helpers
|
|
@@ -35,20 +35,20 @@ module ActionView
|
|
|
35
35
|
when :back
|
|
36
36
|
_back_url
|
|
37
37
|
else
|
|
38
|
-
raise ArgumentError, "arguments passed to url_for can't be handled. Please require "
|
|
38
|
+
raise ArgumentError, "arguments passed to url_for can't be handled. Please require " \
|
|
39
39
|
"routes or provide your own implementation"
|
|
40
40
|
end
|
|
41
41
|
end
|
|
42
42
|
|
|
43
43
|
def _back_url # :nodoc:
|
|
44
|
-
_filtered_referrer ||
|
|
44
|
+
_filtered_referrer || "javascript:history.back()"
|
|
45
45
|
end
|
|
46
46
|
protected :_back_url
|
|
47
47
|
|
|
48
48
|
def _filtered_referrer # :nodoc:
|
|
49
49
|
if controller.respond_to?(:request)
|
|
50
50
|
referrer = controller.request.env["HTTP_REFERER"]
|
|
51
|
-
if referrer && URI(referrer).scheme !=
|
|
51
|
+
if referrer && URI(referrer).scheme != "javascript"
|
|
52
52
|
referrer
|
|
53
53
|
end
|
|
54
54
|
end
|
|
@@ -105,10 +105,9 @@ module ActionView
|
|
|
105
105
|
# driver to prompt with the question specified (in this case, the
|
|
106
106
|
# resulting text would be <tt>question?</tt>. If the user accepts, the
|
|
107
107
|
# link is processed normally, otherwise no action is taken.
|
|
108
|
-
# * <tt>:disable_with</tt> - Value of this parameter will be
|
|
109
|
-
#
|
|
110
|
-
#
|
|
111
|
-
# by the unobtrusive JavaScript driver.
|
|
108
|
+
# * <tt>:disable_with</tt> - Value of this parameter will be used as the
|
|
109
|
+
# name for a disabled version of the link. This feature is provided by
|
|
110
|
+
# the unobtrusive JavaScript driver.
|
|
112
111
|
#
|
|
113
112
|
# ==== Examples
|
|
114
113
|
# Because it relies on +url_for+, +link_to+ supports both older-style controller/action/id arguments
|
|
@@ -298,34 +297,34 @@ module ActionView
|
|
|
298
297
|
html_options = html_options.stringify_keys
|
|
299
298
|
|
|
300
299
|
url = options.is_a?(String) ? options : url_for(options)
|
|
301
|
-
remote = html_options.delete(
|
|
302
|
-
params = html_options.delete(
|
|
300
|
+
remote = html_options.delete("remote")
|
|
301
|
+
params = html_options.delete("params")
|
|
303
302
|
|
|
304
|
-
method = html_options.delete(
|
|
305
|
-
method_tag = BUTTON_TAG_METHOD_VERBS.include?(method) ? method_tag(method) :
|
|
303
|
+
method = html_options.delete("method").to_s
|
|
304
|
+
method_tag = BUTTON_TAG_METHOD_VERBS.include?(method) ? method_tag(method) : "".freeze.html_safe
|
|
306
305
|
|
|
307
|
-
form_method = method ==
|
|
308
|
-
form_options = html_options.delete(
|
|
309
|
-
form_options[:class] ||= html_options.delete(
|
|
306
|
+
form_method = method == "get" ? "get" : "post"
|
|
307
|
+
form_options = html_options.delete("form") || {}
|
|
308
|
+
form_options[:class] ||= html_options.delete("form_class") || "button_to"
|
|
310
309
|
form_options[:method] = form_method
|
|
311
310
|
form_options[:action] = url
|
|
312
311
|
form_options[:'data-remote'] = true if remote
|
|
313
312
|
|
|
314
|
-
request_token_tag = if form_method ==
|
|
315
|
-
request_method = method.empty? ?
|
|
313
|
+
request_token_tag = if form_method == "post"
|
|
314
|
+
request_method = method.empty? ? "post" : method
|
|
316
315
|
token_tag(nil, form_options: { action: url, method: request_method })
|
|
317
316
|
else
|
|
318
|
-
|
|
317
|
+
"".freeze
|
|
319
318
|
end
|
|
320
319
|
|
|
321
320
|
html_options = convert_options_to_data_attributes(options, html_options)
|
|
322
|
-
html_options[
|
|
321
|
+
html_options["type"] = "submit"
|
|
323
322
|
|
|
324
323
|
button = if block_given?
|
|
325
|
-
content_tag(
|
|
324
|
+
content_tag("button", html_options, &block)
|
|
326
325
|
else
|
|
327
|
-
html_options[
|
|
328
|
-
tag(
|
|
326
|
+
html_options["value"] = name || url
|
|
327
|
+
tag("input", html_options)
|
|
329
328
|
end
|
|
330
329
|
|
|
331
330
|
inner_tags = method_tag.safe_concat(button).safe_concat(request_token_tag)
|
|
@@ -334,7 +333,7 @@ module ActionView
|
|
|
334
333
|
inner_tags.safe_concat tag(:input, type: "hidden", name: param[:name], value: param[:value])
|
|
335
334
|
end
|
|
336
335
|
end
|
|
337
|
-
content_tag(
|
|
336
|
+
content_tag("form", inner_tags, form_options)
|
|
338
337
|
end
|
|
339
338
|
|
|
340
339
|
# Creates a link tag of the given +name+ using a URL created by the set of
|
|
@@ -481,7 +480,7 @@ module ActionView
|
|
|
481
480
|
option = html_options.delete(item).presence || next
|
|
482
481
|
"#{item.dasherize}=#{ERB::Util.url_encode(option)}"
|
|
483
482
|
}.compact
|
|
484
|
-
extras = extras.empty? ?
|
|
483
|
+
extras = extras.empty? ? "".freeze : "?" + extras.join("&")
|
|
485
484
|
|
|
486
485
|
encoded_email_address = ERB::Util.url_encode(email_address).gsub("%40", "@")
|
|
487
486
|
html_options["href"] = "mailto:#{encoded_email_address}#{extras}"
|
|
@@ -518,6 +517,9 @@ module ActionView
|
|
|
518
517
|
# current_page?('http://www.example.com/shop/checkout')
|
|
519
518
|
# # => true
|
|
520
519
|
#
|
|
520
|
+
# current_page?('http://www.example.com/shop/checkout', check_parameters: true)
|
|
521
|
+
# # => false
|
|
522
|
+
#
|
|
521
523
|
# current_page?('/shop/checkout')
|
|
522
524
|
# # => true
|
|
523
525
|
#
|
|
@@ -531,7 +533,7 @@ module ActionView
|
|
|
531
533
|
#
|
|
532
534
|
# We can also pass in the symbol arguments instead of strings.
|
|
533
535
|
#
|
|
534
|
-
def current_page?(options)
|
|
536
|
+
def current_page?(options, check_parameters: false)
|
|
535
537
|
unless request
|
|
536
538
|
raise "You cannot use helpers that need to determine the current " \
|
|
537
539
|
"page unless your view context provides a Request object " \
|
|
@@ -540,17 +542,22 @@ module ActionView
|
|
|
540
542
|
|
|
541
543
|
return false unless request.get? || request.head?
|
|
542
544
|
|
|
545
|
+
check_parameters ||= options.is_a?(Hash) && options.delete(:check_parameters)
|
|
543
546
|
url_string = URI.parser.unescape(url_for(options)).force_encoding(Encoding::BINARY)
|
|
544
547
|
|
|
545
548
|
# We ignore any extra parameters in the request_uri if the
|
|
546
549
|
# submitted url doesn't have any either. This lets the function
|
|
547
550
|
# work with things like ?order=asc
|
|
548
|
-
|
|
551
|
+
# the behaviour can be disabled with check_parameters: true
|
|
552
|
+
request_uri = url_string.index("?") || check_parameters ? request.fullpath : request.path
|
|
549
553
|
request_uri = URI.parser.unescape(request_uri).force_encoding(Encoding::BINARY)
|
|
550
554
|
|
|
551
|
-
|
|
555
|
+
if url_string.start_with?("/") && url_string != "/"
|
|
556
|
+
url_string.chomp!("/")
|
|
557
|
+
request_uri.chomp!("/")
|
|
558
|
+
end
|
|
552
559
|
|
|
553
|
-
if url_string
|
|
560
|
+
if %r{^\w+://}.match?(url_string)
|
|
554
561
|
url_string == "#{request.protocol}#{request.host_with_port}#{request_uri}"
|
|
555
562
|
else
|
|
556
563
|
url_string == request_uri
|
|
@@ -561,21 +568,21 @@ module ActionView
|
|
|
561
568
|
def convert_options_to_data_attributes(options, html_options)
|
|
562
569
|
if html_options
|
|
563
570
|
html_options = html_options.stringify_keys
|
|
564
|
-
html_options[
|
|
571
|
+
html_options["data-remote"] = "true".freeze if link_to_remote_options?(options) || link_to_remote_options?(html_options)
|
|
565
572
|
|
|
566
|
-
method
|
|
573
|
+
method = html_options.delete("method".freeze)
|
|
567
574
|
|
|
568
575
|
add_method_to_attributes!(html_options, method) if method
|
|
569
576
|
|
|
570
577
|
html_options
|
|
571
578
|
else
|
|
572
|
-
link_to_remote_options?(options) ? {
|
|
579
|
+
link_to_remote_options?(options) ? { "data-remote" => "true".freeze } : {}
|
|
573
580
|
end
|
|
574
581
|
end
|
|
575
582
|
|
|
576
583
|
def link_to_remote_options?(options)
|
|
577
584
|
if options.is_a?(Hash)
|
|
578
|
-
options.delete(
|
|
585
|
+
options.delete("remote".freeze) || options.delete(:remote)
|
|
579
586
|
end
|
|
580
587
|
end
|
|
581
588
|
|
|
@@ -586,24 +593,24 @@ module ActionView
|
|
|
586
593
|
html_options["data-method".freeze] = method
|
|
587
594
|
end
|
|
588
595
|
|
|
589
|
-
def token_tag(token=nil, form_options: {})
|
|
596
|
+
def token_tag(token = nil, form_options: {})
|
|
590
597
|
if token != false && protect_against_forgery?
|
|
591
598
|
token ||= form_authenticity_token(form_options: form_options)
|
|
592
599
|
tag(:input, type: "hidden", name: request_forgery_protection_token.to_s, value: token)
|
|
593
600
|
else
|
|
594
|
-
|
|
601
|
+
"".freeze
|
|
595
602
|
end
|
|
596
603
|
end
|
|
597
604
|
|
|
598
605
|
def method_tag(method)
|
|
599
|
-
tag(
|
|
606
|
+
tag("input", type: "hidden", name: "_method", value: method.to_s)
|
|
600
607
|
end
|
|
601
608
|
|
|
602
609
|
# Returns an array of hashes each containing :name and :value keys
|
|
603
610
|
# suitable for use as the names and values of form input fields:
|
|
604
611
|
#
|
|
605
612
|
# to_form_params(name: 'David', nationality: 'Danish')
|
|
606
|
-
# # => [{name:
|
|
613
|
+
# # => [{name: 'name', value: 'David'}, {name: 'nationality', value: 'Danish'}]
|
|
607
614
|
#
|
|
608
615
|
# to_form_params(country: {name: 'Denmark'})
|
|
609
616
|
# # => [{name: 'country[name]', value: 'Denmark'}]
|
|
@@ -615,13 +622,8 @@ module ActionView
|
|
|
615
622
|
#
|
|
616
623
|
# to_form_params({ name: 'Denmark' }, 'country')
|
|
617
624
|
# # => [{name: 'country[name]', value: 'Denmark'}]
|
|
618
|
-
def to_form_params(attribute, namespace = nil)
|
|
625
|
+
def to_form_params(attribute, namespace = nil)
|
|
619
626
|
attribute = if attribute.respond_to?(:permitted?)
|
|
620
|
-
unless attribute.permitted?
|
|
621
|
-
raise ArgumentError, "Attempting to generate a buttom from non-sanitized request parameters!" \
|
|
622
|
-
" Whitelist and sanitize passed parameters to be secure."
|
|
623
|
-
end
|
|
624
|
-
|
|
625
627
|
attribute.to_h
|
|
626
628
|
else
|
|
627
629
|
attribute
|
|
@@ -640,7 +642,7 @@ module ActionView
|
|
|
640
642
|
params.push(*to_form_params(value, array_prefix))
|
|
641
643
|
end
|
|
642
644
|
else
|
|
643
|
-
params << { name: namespace, value: attribute.to_param }
|
|
645
|
+
params << { name: namespace.to_s, value: attribute.to_param }
|
|
644
646
|
end
|
|
645
647
|
|
|
646
648
|
params.sort_by { |pair| pair[:name] }
|
data/lib/action_view/helpers.rb
CHANGED
data/lib/action_view/layouts.rb
CHANGED
|
@@ -91,16 +91,16 @@ module ActionView
|
|
|
91
91
|
# layout false
|
|
92
92
|
#
|
|
93
93
|
# In these examples, we have three implicit lookup scenarios:
|
|
94
|
-
# * The BankController uses the "bank" layout.
|
|
95
|
-
# * The ExchangeController uses the "exchange" layout.
|
|
96
|
-
# * The CurrencyController inherits the layout from BankController.
|
|
94
|
+
# * The +BankController+ uses the "bank" layout.
|
|
95
|
+
# * The +ExchangeController+ uses the "exchange" layout.
|
|
96
|
+
# * The +CurrencyController+ inherits the layout from BankController.
|
|
97
97
|
#
|
|
98
98
|
# However, when a layout is explicitly set, the explicitly set layout wins:
|
|
99
|
-
# * The InformationController uses the "information" layout, explicitly set.
|
|
100
|
-
# * The TellerController also uses the "information" layout, because the parent explicitly set it.
|
|
101
|
-
# * The EmployeeController uses the "employee" layout, because it set the layout to nil
|
|
102
|
-
# * The VaultController chooses a layout dynamically by calling the <tt>access_level_layout</tt> method.
|
|
103
|
-
# * The TillController does not use a layout at all.
|
|
99
|
+
# * The +InformationController+ uses the "information" layout, explicitly set.
|
|
100
|
+
# * The +TellerController+ also uses the "information" layout, because the parent explicitly set it.
|
|
101
|
+
# * The +EmployeeController+ uses the "employee" layout, because it set the layout to +nil+, resetting the parent configuration.
|
|
102
|
+
# * The +VaultController+ chooses a layout dynamically by calling the <tt>access_level_layout</tt> method.
|
|
103
|
+
# * The +TillController+ does not use a layout at all.
|
|
104
104
|
#
|
|
105
105
|
# == Types of layouts
|
|
106
106
|
#
|
|
@@ -148,8 +148,8 @@ module ActionView
|
|
|
148
148
|
# The template will be looked always in <tt>app/views/layouts/</tt> folder. But you can point
|
|
149
149
|
# <tt>layouts</tt> folder direct also. <tt>layout "layouts/demo"</tt> is the same as <tt>layout "demo"</tt>.
|
|
150
150
|
#
|
|
151
|
-
# Setting the layout to nil forces it to be looked up in the filesystem and fallbacks to the parent behavior if none exists.
|
|
152
|
-
# Setting it to nil is useful to re-enable template lookup overriding a previous configuration set in the parent:
|
|
151
|
+
# Setting the layout to +nil+ forces it to be looked up in the filesystem and fallbacks to the parent behavior if none exists.
|
|
152
|
+
# Setting it to +nil+ is useful to re-enable template lookup overriding a previous configuration set in the parent:
|
|
153
153
|
#
|
|
154
154
|
# class ApplicationController < ActionController::Base
|
|
155
155
|
# layout "application"
|
|
@@ -204,7 +204,7 @@ module ActionView
|
|
|
204
204
|
include ActionView::Rendering
|
|
205
205
|
|
|
206
206
|
included do
|
|
207
|
-
class_attribute :_layout, :_layout_conditions, :
|
|
207
|
+
class_attribute :_layout, :_layout_conditions, instance_accessor: false
|
|
208
208
|
self._layout = nil
|
|
209
209
|
self._layout_conditions = {}
|
|
210
210
|
_write_layout_method
|
|
@@ -223,36 +223,39 @@ module ActionView
|
|
|
223
223
|
module LayoutConditions # :nodoc:
|
|
224
224
|
private
|
|
225
225
|
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
226
|
+
# Determines whether the current action has a layout definition by
|
|
227
|
+
# checking the action name against the :only and :except conditions
|
|
228
|
+
# set by the <tt>layout</tt> method.
|
|
229
|
+
#
|
|
230
|
+
# ==== Returns
|
|
231
|
+
# * <tt>Boolean</tt> - True if the action has a layout definition, false otherwise.
|
|
232
|
+
def _conditional_layout?
|
|
233
|
+
return unless super
|
|
234
|
+
|
|
235
|
+
conditions = _layout_conditions
|
|
236
|
+
|
|
237
|
+
if only = conditions[:only]
|
|
238
|
+
only.include?(action_name)
|
|
239
|
+
elsif except = conditions[:except]
|
|
240
|
+
!except.include?(action_name)
|
|
241
|
+
else
|
|
242
|
+
true
|
|
243
|
+
end
|
|
243
244
|
end
|
|
244
|
-
end
|
|
245
245
|
end
|
|
246
246
|
|
|
247
247
|
# Specify the layout to use for this class.
|
|
248
248
|
#
|
|
249
249
|
# If the specified layout is a:
|
|
250
250
|
# String:: the String is the template name
|
|
251
|
-
# Symbol:: call the method specified by the symbol
|
|
251
|
+
# Symbol:: call the method specified by the symbol
|
|
252
|
+
# Proc:: call the passed Proc
|
|
252
253
|
# false:: There is no layout
|
|
253
254
|
# true:: raise an ArgumentError
|
|
254
255
|
# nil:: Force default layout behavior with inheritance
|
|
255
256
|
#
|
|
257
|
+
# Return value of +Proc+ and +Symbol+ arguments should be +String+, +false+, +true+ or +nil+
|
|
258
|
+
# with the same meaning as described above.
|
|
256
259
|
# ==== Parameters
|
|
257
260
|
# * <tt>layout</tt> - The layout to use.
|
|
258
261
|
#
|
|
@@ -262,7 +265,7 @@ module ActionView
|
|
|
262
265
|
def layout(layout, conditions = {})
|
|
263
266
|
include LayoutConditions unless conditions.empty?
|
|
264
267
|
|
|
265
|
-
conditions.each {|k, v| conditions[k] = Array(v).map(&:to_s) }
|
|
268
|
+
conditions.each { |k, v| conditions[k] = Array(v).map(&:to_s) }
|
|
266
269
|
self._layout_conditions = conditions
|
|
267
270
|
|
|
268
271
|
self._layout = layout
|
|
@@ -276,7 +279,7 @@ module ActionView
|
|
|
276
279
|
def _write_layout_method # :nodoc:
|
|
277
280
|
remove_possible_method(:_layout)
|
|
278
281
|
|
|
279
|
-
prefixes
|
|
282
|
+
prefixes = /\blayouts/.match?(_implied_layout_name) ? [] : ["layouts"]
|
|
280
283
|
default_behavior = "lookup_context.find_all('#{_implied_layout_name}', #{prefixes.inspect}, false, [], { formats: formats }).first || super"
|
|
281
284
|
name_clause = if name
|
|
282
285
|
default_behavior
|
|
@@ -286,7 +289,8 @@ module ActionView
|
|
|
286
289
|
RUBY
|
|
287
290
|
end
|
|
288
291
|
|
|
289
|
-
layout_definition =
|
|
292
|
+
layout_definition = \
|
|
293
|
+
case _layout
|
|
290
294
|
when String
|
|
291
295
|
_layout.inspect
|
|
292
296
|
when Symbol
|
|
@@ -313,9 +317,9 @@ module ActionView
|
|
|
313
317
|
raise ArgumentError, "Layouts must be specified as a String, Symbol, Proc, false, or nil"
|
|
314
318
|
when nil
|
|
315
319
|
name_clause
|
|
316
|
-
|
|
320
|
+
end
|
|
317
321
|
|
|
318
|
-
|
|
322
|
+
class_eval <<-RUBY, __FILE__, __LINE__ + 1
|
|
319
323
|
def _layout(formats)
|
|
320
324
|
if _conditional_layout?
|
|
321
325
|
#{layout_definition}
|
|
@@ -329,14 +333,14 @@ module ActionView
|
|
|
329
333
|
|
|
330
334
|
private
|
|
331
335
|
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
336
|
+
# If no layout is supplied, look for a template named the return
|
|
337
|
+
# value of this method.
|
|
338
|
+
#
|
|
339
|
+
# ==== Returns
|
|
340
|
+
# * <tt>String</tt> - A template name
|
|
341
|
+
def _implied_layout_name
|
|
342
|
+
controller_path
|
|
343
|
+
end
|
|
340
344
|
end
|
|
341
345
|
|
|
342
346
|
def _normalize_options(options) # :nodoc:
|
|
@@ -400,11 +404,11 @@ module ActionView
|
|
|
400
404
|
#
|
|
401
405
|
# ==== Parameters
|
|
402
406
|
# * <tt>formats</tt> - The formats accepted to this layout
|
|
403
|
-
# * <tt>require_layout</tt> - If set to true and layout is not found,
|
|
404
|
-
# an +ArgumentError+ exception is raised (defaults to false)
|
|
407
|
+
# * <tt>require_layout</tt> - If set to +true+ and layout is not found,
|
|
408
|
+
# an +ArgumentError+ exception is raised (defaults to +false+)
|
|
405
409
|
#
|
|
406
410
|
# ==== Returns
|
|
407
|
-
# * <tt>template</tt> - The template object for the default layout (or nil)
|
|
411
|
+
# * <tt>template</tt> - The template object for the default layout (or +nil+)
|
|
408
412
|
def _default_layout(formats, require_layout = false)
|
|
409
413
|
begin
|
|
410
414
|
value = _layout(formats) if action_has_layout?
|
|
@@ -421,7 +425,7 @@ module ActionView
|
|
|
421
425
|
end
|
|
422
426
|
|
|
423
427
|
def _include_layout?(options)
|
|
424
|
-
(options.keys & [:body, :
|
|
428
|
+
(options.keys & [:body, :plain, :html, :inline, :partial]).empty? || options.key?(:layout)
|
|
425
429
|
end
|
|
426
430
|
end
|
|
427
431
|
end
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
require
|
|
1
|
+
require "active_support/log_subscriber"
|
|
2
2
|
|
|
3
3
|
module ActionView
|
|
4
4
|
# = Action View Log Subscriber
|
|
@@ -19,10 +19,19 @@ module ActionView
|
|
|
19
19
|
message << " (#{event.duration.round(1)}ms)"
|
|
20
20
|
end
|
|
21
21
|
end
|
|
22
|
-
|
|
22
|
+
|
|
23
|
+
def render_partial(event)
|
|
24
|
+
info do
|
|
25
|
+
message = " Rendered #{from_rails_root(event.payload[:identifier])}"
|
|
26
|
+
message << " within #{from_rails_root(event.payload[:layout])}" if event.payload[:layout]
|
|
27
|
+
message << " (#{event.duration.round(1)}ms)"
|
|
28
|
+
message << " #{cache_message(event.payload)}" unless event.payload[:cache_hit].nil?
|
|
29
|
+
message
|
|
30
|
+
end
|
|
31
|
+
end
|
|
23
32
|
|
|
24
33
|
def render_collection(event)
|
|
25
|
-
identifier = event.payload[:identifier] ||
|
|
34
|
+
identifier = event.payload[:identifier] || "templates"
|
|
26
35
|
|
|
27
36
|
info do
|
|
28
37
|
" Rendered collection of #{from_rails_root(identifier)}" \
|
|
@@ -42,20 +51,20 @@ module ActionView
|
|
|
42
51
|
ActionView::Base.logger
|
|
43
52
|
end
|
|
44
53
|
|
|
45
|
-
|
|
54
|
+
private
|
|
46
55
|
|
|
47
|
-
EMPTY =
|
|
48
|
-
def from_rails_root(string)
|
|
56
|
+
EMPTY = ""
|
|
57
|
+
def from_rails_root(string) # :doc:
|
|
49
58
|
string = string.sub(rails_root, EMPTY)
|
|
50
59
|
string.sub!(VIEWS_PATTERN, EMPTY)
|
|
51
60
|
string
|
|
52
61
|
end
|
|
53
62
|
|
|
54
|
-
def rails_root
|
|
63
|
+
def rails_root # :doc:
|
|
55
64
|
@root ||= "#{Rails.root}/"
|
|
56
65
|
end
|
|
57
66
|
|
|
58
|
-
def render_count(payload)
|
|
67
|
+
def render_count(payload) # :doc:
|
|
59
68
|
if payload[:cache_hits]
|
|
60
69
|
"[#{payload[:cache_hits]} / #{payload[:count]} cache hits]"
|
|
61
70
|
else
|
|
@@ -63,7 +72,14 @@ module ActionView
|
|
|
63
72
|
end
|
|
64
73
|
end
|
|
65
74
|
|
|
66
|
-
|
|
75
|
+
def cache_message(payload) # :doc:
|
|
76
|
+
case payload[:cache_hit]
|
|
77
|
+
when :hit
|
|
78
|
+
"[cache hit]"
|
|
79
|
+
when :miss
|
|
80
|
+
"[cache miss]"
|
|
81
|
+
end
|
|
82
|
+
end
|
|
67
83
|
|
|
68
84
|
def log_rendering_start(payload)
|
|
69
85
|
info do
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
require
|
|
2
|
-
require
|
|
3
|
-
require
|
|
4
|
-
require
|
|
1
|
+
require "concurrent/map"
|
|
2
|
+
require "active_support/core_ext/module/remove_method"
|
|
3
|
+
require "active_support/core_ext/module/attribute_accessors"
|
|
4
|
+
require "action_view/template/resolver"
|
|
5
5
|
|
|
6
6
|
module ActionView
|
|
7
7
|
# = Action View Lookup Context
|
|
@@ -21,7 +21,7 @@ module ActionView
|
|
|
21
21
|
self.registered_details = []
|
|
22
22
|
|
|
23
23
|
def self.register_detail(name, &block)
|
|
24
|
-
|
|
24
|
+
registered_details << name
|
|
25
25
|
Accessors::DEFAULT_PROCS[name] = block
|
|
26
26
|
|
|
27
27
|
Accessors.send :define_method, :"default_#{name}", &block
|
|
@@ -63,7 +63,7 @@ module ActionView
|
|
|
63
63
|
details = details.dup
|
|
64
64
|
details[:formats] &= Template::Types.symbols
|
|
65
65
|
end
|
|
66
|
-
@details_keys[details] ||= new
|
|
66
|
+
@details_keys[details] ||= Concurrent::Map.new
|
|
67
67
|
end
|
|
68
68
|
|
|
69
69
|
def self.clear
|
|
@@ -71,13 +71,7 @@ module ActionView
|
|
|
71
71
|
end
|
|
72
72
|
|
|
73
73
|
def self.digest_caches
|
|
74
|
-
@details_keys.values
|
|
75
|
-
end
|
|
76
|
-
|
|
77
|
-
attr_reader :digest_cache
|
|
78
|
-
|
|
79
|
-
def initialize
|
|
80
|
-
@digest_cache = Concurrent::Map.new
|
|
74
|
+
@details_keys.values
|
|
81
75
|
end
|
|
82
76
|
end
|
|
83
77
|
|
|
@@ -99,9 +93,9 @@ module ActionView
|
|
|
99
93
|
@cache = old_value
|
|
100
94
|
end
|
|
101
95
|
|
|
102
|
-
|
|
96
|
+
private
|
|
103
97
|
|
|
104
|
-
def _set_detail(key, value)
|
|
98
|
+
def _set_detail(key, value) # :doc:
|
|
105
99
|
@details = @details.dup if @details_key
|
|
106
100
|
@details_key = nil
|
|
107
101
|
@details[key] = value
|
|
@@ -155,16 +149,16 @@ module ActionView
|
|
|
155
149
|
added_resolvers.times { view_paths.pop }
|
|
156
150
|
end
|
|
157
151
|
|
|
158
|
-
|
|
152
|
+
private
|
|
159
153
|
|
|
160
|
-
def args_for_lookup(name, prefixes, partial, keys, details_options)
|
|
154
|
+
def args_for_lookup(name, prefixes, partial, keys, details_options)
|
|
161
155
|
name, prefixes = normalize_name(name, prefixes)
|
|
162
156
|
details, details_key = detail_args_for(details_options)
|
|
163
157
|
[name, prefixes, partial || false, details, details_key, keys]
|
|
164
158
|
end
|
|
165
159
|
|
|
166
160
|
# Compute details hash and key according to user options (e.g. passed from #render).
|
|
167
|
-
def detail_args_for(options)
|
|
161
|
+
def detail_args_for(options) # :doc:
|
|
168
162
|
return @details, details_key if options.empty? # most common path.
|
|
169
163
|
user_details = @details.merge(options)
|
|
170
164
|
|
|
@@ -177,13 +171,13 @@ module ActionView
|
|
|
177
171
|
[user_details, details_key]
|
|
178
172
|
end
|
|
179
173
|
|
|
180
|
-
def args_for_any(name, prefixes, partial)
|
|
174
|
+
def args_for_any(name, prefixes, partial)
|
|
181
175
|
name, prefixes = normalize_name(name, prefixes)
|
|
182
176
|
details, details_key = detail_args_for_any
|
|
183
177
|
[name, prefixes, partial || false, details, details_key]
|
|
184
178
|
end
|
|
185
179
|
|
|
186
|
-
def detail_args_for_any
|
|
180
|
+
def detail_args_for_any
|
|
187
181
|
@detail_args_for_any ||= begin
|
|
188
182
|
details = {}
|
|
189
183
|
|
|
@@ -206,15 +200,15 @@ module ActionView
|
|
|
206
200
|
# Support legacy foo.erb names even though we now ignore .erb
|
|
207
201
|
# as well as incorrectly putting part of the path in the template
|
|
208
202
|
# name instead of the prefix.
|
|
209
|
-
def normalize_name(name, prefixes)
|
|
203
|
+
def normalize_name(name, prefixes)
|
|
210
204
|
prefixes = prefixes.presence
|
|
211
|
-
parts = name.to_s.split(
|
|
205
|
+
parts = name.to_s.split("/".freeze)
|
|
212
206
|
parts.shift if parts.first.empty?
|
|
213
|
-
name
|
|
207
|
+
name = parts.pop
|
|
214
208
|
|
|
215
209
|
return name, prefixes || [""] if parts.empty?
|
|
216
210
|
|
|
217
|
-
parts = parts.join(
|
|
211
|
+
parts = parts.join("/".freeze)
|
|
218
212
|
prefixes = prefixes ? prefixes.map { |p| "#{p}/#{parts}" } : [parts]
|
|
219
213
|
|
|
220
214
|
return name, prefixes
|
|
@@ -236,7 +230,7 @@ module ActionView
|
|
|
236
230
|
end
|
|
237
231
|
|
|
238
232
|
def digest_cache
|
|
239
|
-
details_key
|
|
233
|
+
details_key
|
|
240
234
|
end
|
|
241
235
|
|
|
242
236
|
def initialize_details(target, details)
|