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.
Files changed (84) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +169 -345
  3. data/MIT-LICENSE +1 -1
  4. data/README.rdoc +1 -1
  5. data/lib/action_view/base.rb +19 -19
  6. data/lib/action_view/buffers.rb +1 -1
  7. data/lib/action_view/context.rb +1 -1
  8. data/lib/action_view/dependency_tracker.rb +4 -5
  9. data/lib/action_view/digestor.rb +22 -13
  10. data/lib/action_view/flows.rb +5 -6
  11. data/lib/action_view/gem_version.rb +2 -2
  12. data/lib/action_view/helpers/active_model_helper.rb +8 -8
  13. data/lib/action_view/helpers/asset_tag_helper.rb +62 -36
  14. data/lib/action_view/helpers/asset_url_helper.rb +111 -49
  15. data/lib/action_view/helpers/atom_feed_helper.rb +12 -13
  16. data/lib/action_view/helpers/cache_helper.rb +32 -20
  17. data/lib/action_view/helpers/capture_helper.rb +2 -2
  18. data/lib/action_view/helpers/controller_helper.rb +2 -2
  19. data/lib/action_view/helpers/csrf_helper.rb +3 -3
  20. data/lib/action_view/helpers/date_helper.rb +119 -109
  21. data/lib/action_view/helpers/debug_helper.rb +2 -3
  22. data/lib/action_view/helpers/form_helper.rb +440 -31
  23. data/lib/action_view/helpers/form_options_helper.rb +12 -12
  24. data/lib/action_view/helpers/form_tag_helper.rb +20 -19
  25. data/lib/action_view/helpers/javascript_helper.rb +6 -6
  26. data/lib/action_view/helpers/number_helper.rb +48 -46
  27. data/lib/action_view/helpers/output_safety_helper.rb +8 -8
  28. data/lib/action_view/helpers/record_tag_helper.rb +2 -2
  29. data/lib/action_view/helpers/rendering_helper.rb +2 -3
  30. data/lib/action_view/helpers/sanitize_helper.rb +16 -12
  31. data/lib/action_view/helpers/tag_helper.rb +194 -77
  32. data/lib/action_view/helpers/tags/base.rb +121 -102
  33. data/lib/action_view/helpers/tags/check_box.rb +17 -17
  34. data/lib/action_view/helpers/tags/collection_check_boxes.rb +9 -8
  35. data/lib/action_view/helpers/tags/collection_helpers.rb +60 -60
  36. data/lib/action_view/helpers/tags/collection_radio_buttons.rb +3 -2
  37. data/lib/action_view/helpers/tags/collection_select.rb +2 -2
  38. data/lib/action_view/helpers/tags/date_select.rb +36 -36
  39. data/lib/action_view/helpers/tags/grouped_collection_select.rb +2 -2
  40. data/lib/action_view/helpers/tags/label.rb +4 -0
  41. data/lib/action_view/helpers/tags/password_field.rb +1 -1
  42. data/lib/action_view/helpers/tags/radio_button.rb +4 -4
  43. data/lib/action_view/helpers/tags/select.rb +9 -9
  44. data/lib/action_view/helpers/tags/text_area.rb +1 -1
  45. data/lib/action_view/helpers/tags/text_field.rb +5 -5
  46. data/lib/action_view/helpers/tags/translator.rb +14 -12
  47. data/lib/action_view/helpers/text_helper.rb +20 -19
  48. data/lib/action_view/helpers/translation_helper.rb +6 -6
  49. data/lib/action_view/helpers/url_helper.rb +48 -46
  50. data/lib/action_view/helpers.rb +1 -1
  51. data/lib/action_view/layouts.rb +51 -47
  52. data/lib/action_view/log_subscriber.rb +25 -9
  53. data/lib/action_view/lookup_context.rb +19 -25
  54. data/lib/action_view/path_set.rb +19 -19
  55. data/lib/action_view/railtie.rb +13 -4
  56. data/lib/action_view/record_identifier.rb +6 -6
  57. data/lib/action_view/renderer/abstract_renderer.rb +17 -17
  58. data/lib/action_view/renderer/partial_renderer/collection_caching.rb +7 -1
  59. data/lib/action_view/renderer/partial_renderer.rb +188 -187
  60. data/lib/action_view/renderer/renderer.rb +4 -0
  61. data/lib/action_view/renderer/streaming_template_renderer.rb +45 -47
  62. data/lib/action_view/renderer/template_renderer.rb +64 -66
  63. data/lib/action_view/rendering.rb +4 -5
  64. data/lib/action_view/routing_url_for.rb +9 -13
  65. data/lib/action_view/tasks/cache_digests.rake +7 -7
  66. data/lib/action_view/template/error.rb +5 -15
  67. data/lib/action_view/template/handlers/builder.rb +7 -7
  68. data/lib/action_view/template/handlers/erb/deprecated_erubis.rb +9 -0
  69. data/lib/action_view/template/handlers/erb/erubi.rb +81 -0
  70. data/lib/action_view/template/handlers/erb/erubis.rb +81 -0
  71. data/lib/action_view/template/handlers/erb.rb +9 -76
  72. data/lib/action_view/template/handlers.rb +4 -4
  73. data/lib/action_view/template/html.rb +2 -4
  74. data/lib/action_view/template/resolver.rb +107 -90
  75. data/lib/action_view/template/text.rb +5 -8
  76. data/lib/action_view/template/types.rb +1 -1
  77. data/lib/action_view/template.rb +26 -27
  78. data/lib/action_view/test_case.rb +20 -21
  79. data/lib/action_view/testing/resolvers.rb +29 -30
  80. data/lib/action_view/version.rb +1 -1
  81. data/lib/action_view/view_paths.rb +20 -8
  82. data/lib/action_view.rb +5 -5
  83. data/lib/assets/compiled/rails-ujs.js +683 -0
  84. metadata +18 -12
@@ -1,7 +1,7 @@
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'
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 || 'javascript:history.back()'
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 != 'javascript'
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
- # used as the value for a disabled version of the submit
110
- # button when the form is submitted. This feature is provided
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('remote')
302
- params = html_options.delete('params')
300
+ remote = html_options.delete("remote")
301
+ params = html_options.delete("params")
303
302
 
304
- method = html_options.delete('method').to_s
305
- method_tag = BUTTON_TAG_METHOD_VERBS.include?(method) ? method_tag(method) : ''.freeze.html_safe
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 == 'get' ? 'get' : 'post'
308
- form_options = html_options.delete('form') || {}
309
- form_options[:class] ||= html_options.delete('form_class') || 'button_to'
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 == 'post'
315
- request_method = method.empty? ? 'post' : method
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
- ''.freeze
317
+ "".freeze
319
318
  end
320
319
 
321
320
  html_options = convert_options_to_data_attributes(options, html_options)
322
- html_options['type'] = 'submit'
321
+ html_options["type"] = "submit"
323
322
 
324
323
  button = if block_given?
325
- content_tag('button', html_options, &block)
324
+ content_tag("button", html_options, &block)
326
325
  else
327
- html_options['value'] = name || url
328
- tag('input', html_options)
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('form', inner_tags, form_options)
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? ? ''.freeze : '?' + extras.join('&')
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
- request_uri = url_string.index("?") ? request.fullpath : request.path
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
- url_string.chomp!("/") if url_string.start_with?("/") && url_string != "/"
555
+ if url_string.start_with?("/") && url_string != "/"
556
+ url_string.chomp!("/")
557
+ request_uri.chomp!("/")
558
+ end
552
559
 
553
- if url_string =~ /^\w+:\/\//
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['data-remote'] = 'true'.freeze if link_to_remote_options?(options) || link_to_remote_options?(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 = html_options.delete('method'.freeze)
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) ? {'data-remote' => 'true'.freeze} : {}
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('remote'.freeze) || options.delete(:remote)
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
- ''.freeze
601
+ "".freeze
595
602
  end
596
603
  end
597
604
 
598
605
  def method_tag(method)
599
- tag('input', type: 'hidden', name: '_method', value: method.to_s)
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: :name, value: 'David'}, {name: 'nationality', value: 'Danish'}]
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) # :nodoc:
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] }
@@ -1,4 +1,4 @@
1
- require 'active_support/benchmarkable'
1
+ require "active_support/benchmarkable"
2
2
 
3
3
  module ActionView #:nodoc:
4
4
  module Helpers #:nodoc:
@@ -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, 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.
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, :instance_accessor => false
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
- # 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
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, which will return the template name
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 = _implied_layout_name =~ /\blayouts/ ? [] : ["layouts"]
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 = case _layout
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
- end
320
+ end
317
321
 
318
- self.class_eval <<-RUBY, __FILE__, __LINE__ + 1
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
- # If no layout is supplied, look for a template named the return
333
- # value of this method.
334
- #
335
- # ==== Returns
336
- # * <tt>String</tt> - A template name
337
- def _implied_layout_name # :nodoc:
338
- controller_path
339
- end
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, :text, :plain, :html, :inline, :partial]).empty? || options.key?(:layout)
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 'active_support/log_subscriber'
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
- alias :render_partial :render_template
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] || 'templates'
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
- protected
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
- private
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 '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'
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
- self.registered_details << name
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.map(&:digest_cache)
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
- protected
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
- protected
152
+ private
159
153
 
160
- def args_for_lookup(name, prefixes, partial, keys, details_options) #:nodoc:
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) # :nodoc:
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 # :nodoc:
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) #:nodoc:
203
+ def normalize_name(name, prefixes)
210
204
  prefixes = prefixes.presence
211
- parts = name.to_s.split('/'.freeze)
205
+ parts = name.to_s.split("/".freeze)
212
206
  parts.shift if parts.first.empty?
213
- name = parts.pop
207
+ name = parts.pop
214
208
 
215
209
  return name, prefixes || [""] if parts.empty?
216
210
 
217
- parts = parts.join('/'.freeze)
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.digest_cache
233
+ details_key
240
234
  end
241
235
 
242
236
  def initialize_details(target, details)