actionview 4.2.11.1 → 6.0.4

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.

Files changed (114) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +201 -192
  3. data/MIT-LICENSE +1 -1
  4. data/README.rdoc +9 -8
  5. data/lib/action_view/base.rb +144 -37
  6. data/lib/action_view/buffers.rb +18 -1
  7. data/lib/action_view/cache_expiry.rb +53 -0
  8. data/lib/action_view/context.rb +8 -12
  9. data/lib/action_view/dependency_tracker.rb +54 -20
  10. data/lib/action_view/digestor.rb +88 -85
  11. data/lib/action_view/flows.rb +11 -12
  12. data/lib/action_view/gem_version.rb +6 -4
  13. data/lib/action_view/helpers/active_model_helper.rb +16 -11
  14. data/lib/action_view/helpers/asset_tag_helper.rb +241 -82
  15. data/lib/action_view/helpers/asset_url_helper.rb +171 -67
  16. data/lib/action_view/helpers/atom_feed_helper.rb +19 -17
  17. data/lib/action_view/helpers/cache_helper.rb +112 -42
  18. data/lib/action_view/helpers/capture_helper.rb +20 -13
  19. data/lib/action_view/helpers/controller_helper.rb +15 -4
  20. data/lib/action_view/helpers/csp_helper.rb +26 -0
  21. data/lib/action_view/helpers/csrf_helper.rb +8 -6
  22. data/lib/action_view/helpers/date_helper.rb +230 -129
  23. data/lib/action_view/helpers/debug_helper.rb +7 -6
  24. data/lib/action_view/helpers/form_helper.rb +755 -129
  25. data/lib/action_view/helpers/form_options_helper.rb +130 -75
  26. data/lib/action_view/helpers/form_tag_helper.rb +116 -71
  27. data/lib/action_view/helpers/javascript_helper.rb +30 -14
  28. data/lib/action_view/helpers/number_helper.rb +84 -59
  29. data/lib/action_view/helpers/output_safety_helper.rb +36 -4
  30. data/lib/action_view/helpers/rendering_helper.rb +11 -8
  31. data/lib/action_view/helpers/sanitize_helper.rb +30 -31
  32. data/lib/action_view/helpers/tag_helper.rb +201 -75
  33. data/lib/action_view/helpers/tags/base.rb +138 -98
  34. data/lib/action_view/helpers/tags/check_box.rb +20 -19
  35. data/lib/action_view/helpers/tags/checkable.rb +4 -2
  36. data/lib/action_view/helpers/tags/collection_check_boxes.rb +12 -34
  37. data/lib/action_view/helpers/tags/collection_helpers.rb +69 -36
  38. data/lib/action_view/helpers/tags/collection_radio_buttons.rb +6 -12
  39. data/lib/action_view/helpers/tags/collection_select.rb +4 -2
  40. data/lib/action_view/helpers/tags/color_field.rb +4 -3
  41. data/lib/action_view/helpers/tags/date_field.rb +2 -1
  42. data/lib/action_view/helpers/tags/date_select.rb +37 -36
  43. data/lib/action_view/helpers/tags/datetime_field.rb +4 -3
  44. data/lib/action_view/helpers/tags/datetime_local_field.rb +2 -1
  45. data/lib/action_view/helpers/tags/datetime_select.rb +2 -0
  46. data/lib/action_view/helpers/tags/email_field.rb +2 -0
  47. data/lib/action_view/helpers/tags/file_field.rb +2 -0
  48. data/lib/action_view/helpers/tags/grouped_collection_select.rb +4 -2
  49. data/lib/action_view/helpers/tags/hidden_field.rb +2 -0
  50. data/lib/action_view/helpers/tags/label.rb +3 -2
  51. data/lib/action_view/helpers/tags/month_field.rb +2 -1
  52. data/lib/action_view/helpers/tags/number_field.rb +2 -0
  53. data/lib/action_view/helpers/tags/password_field.rb +3 -1
  54. data/lib/action_view/helpers/tags/placeholderable.rb +3 -1
  55. data/lib/action_view/helpers/tags/radio_button.rb +7 -6
  56. data/lib/action_view/helpers/tags/range_field.rb +2 -0
  57. data/lib/action_view/helpers/tags/search_field.rb +14 -9
  58. data/lib/action_view/helpers/tags/select.rb +11 -10
  59. data/lib/action_view/helpers/tags/tel_field.rb +2 -0
  60. data/lib/action_view/helpers/tags/text_area.rb +4 -2
  61. data/lib/action_view/helpers/tags/text_field.rb +8 -8
  62. data/lib/action_view/helpers/tags/time_field.rb +2 -1
  63. data/lib/action_view/helpers/tags/time_select.rb +2 -0
  64. data/lib/action_view/helpers/tags/time_zone_select.rb +3 -1
  65. data/lib/action_view/helpers/tags/translator.rb +15 -16
  66. data/lib/action_view/helpers/tags/url_field.rb +2 -0
  67. data/lib/action_view/helpers/tags/week_field.rb +2 -1
  68. data/lib/action_view/helpers/tags.rb +3 -1
  69. data/lib/action_view/helpers/text_helper.rb +56 -38
  70. data/lib/action_view/helpers/translation_helper.rb +91 -47
  71. data/lib/action_view/helpers/url_helper.rb +160 -105
  72. data/lib/action_view/helpers.rb +5 -3
  73. data/lib/action_view/layouts.rb +65 -61
  74. data/lib/action_view/log_subscriber.rb +61 -10
  75. data/lib/action_view/lookup_context.rb +147 -89
  76. data/lib/action_view/model_naming.rb +3 -1
  77. data/lib/action_view/path_set.rb +28 -23
  78. data/lib/action_view/railtie.rb +62 -6
  79. data/lib/action_view/record_identifier.rb +53 -26
  80. data/lib/action_view/renderer/abstract_renderer.rb +71 -13
  81. data/lib/action_view/renderer/partial_renderer/collection_caching.rb +103 -0
  82. data/lib/action_view/renderer/partial_renderer.rb +239 -225
  83. data/lib/action_view/renderer/renderer.rb +22 -8
  84. data/lib/action_view/renderer/streaming_template_renderer.rb +54 -54
  85. data/lib/action_view/renderer/template_renderer.rb +79 -73
  86. data/lib/action_view/rendering.rb +68 -44
  87. data/lib/action_view/routing_url_for.rb +33 -22
  88. data/lib/action_view/tasks/cache_digests.rake +25 -0
  89. data/lib/action_view/template/error.rb +44 -29
  90. data/lib/action_view/template/handlers/builder.rb +12 -13
  91. data/lib/action_view/template/handlers/erb/erubi.rb +87 -0
  92. data/lib/action_view/template/handlers/erb.rb +24 -86
  93. data/lib/action_view/template/handlers/html.rb +11 -0
  94. data/lib/action_view/template/handlers/raw.rb +4 -4
  95. data/lib/action_view/template/handlers.rb +38 -8
  96. data/lib/action_view/template/html.rb +19 -10
  97. data/lib/action_view/template/inline.rb +22 -0
  98. data/lib/action_view/template/raw_file.rb +28 -0
  99. data/lib/action_view/template/resolver.rb +217 -193
  100. data/lib/action_view/template/sources/file.rb +17 -0
  101. data/lib/action_view/template/sources.rb +13 -0
  102. data/lib/action_view/template/text.rb +11 -10
  103. data/lib/action_view/template/types.rb +18 -18
  104. data/lib/action_view/template.rb +146 -90
  105. data/lib/action_view/test_case.rb +52 -32
  106. data/lib/action_view/testing/resolvers.rb +46 -34
  107. data/lib/action_view/unbound_template.rb +31 -0
  108. data/lib/action_view/version.rb +3 -1
  109. data/lib/action_view/view_paths.rb +48 -31
  110. data/lib/action_view.rb +11 -8
  111. data/lib/assets/compiled/rails-ujs.js +746 -0
  112. metadata +38 -29
  113. data/lib/action_view/helpers/record_tag_helper.rb +0 -108
  114. data/lib/action_view/tasks/dependencies.rake +0 -23
@@ -1,5 +1,7 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "action_view/rendering"
2
- require "active_support/core_ext/module/remove_method"
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
@@ -91,16 +93,16 @@ module ActionView
91
93
  # layout false
92
94
  #
93
95
  # 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.
96
+ # * The +BankController+ uses the "bank" layout.
97
+ # * The +ExchangeController+ uses the "exchange" layout.
98
+ # * The +CurrencyController+ inherits the layout from BankController.
97
99
  #
98
100
  # 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.
101
+ # * The +InformationController+ uses the "information" layout, explicitly set.
102
+ # * The +TellerController+ also uses the "information" layout, because the parent explicitly set it.
103
+ # * The +EmployeeController+ uses the "employee" layout, because it set the layout to +nil+, resetting the parent configuration.
104
+ # * The +VaultController+ chooses a layout dynamically by calling the <tt>access_level_layout</tt> method.
105
+ # * The +TillController+ does not use a layout at all.
104
106
  #
105
107
  # == Types of layouts
106
108
  #
@@ -148,8 +150,8 @@ module ActionView
148
150
  # The template will be looked always in <tt>app/views/layouts/</tt> folder. But you can point
149
151
  # <tt>layouts</tt> folder direct also. <tt>layout "layouts/demo"</tt> is the same as <tt>layout "demo"</tt>.
150
152
  #
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
+ # Setting the layout to +nil+ forces it to be looked up in the filesystem and fallbacks to the parent behavior if none exists.
154
+ # Setting it to +nil+ is useful to re-enable template lookup overriding a previous configuration set in the parent:
153
155
  #
154
156
  # class ApplicationController < ActionController::Base
155
157
  # layout "application"
@@ -204,9 +206,9 @@ module ActionView
204
206
  include ActionView::Rendering
205
207
 
206
208
  included do
207
- class_attribute :_layout, :_layout_conditions, :instance_accessor => false
208
- self._layout = nil
209
- self._layout_conditions = {}
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,37 +224,39 @@ 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
- # 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
227
+ # Determines whether the current action has a layout definition by
228
+ # checking the action name against the :only and :except conditions
229
+ # set by the <tt>layout</tt> method.
230
+ #
231
+ # ==== Returns
232
+ # * <tt>Boolean</tt> - True if the action has a layout definition, false otherwise.
233
+ def _conditional_layout?
234
+ return unless super
235
+
236
+ conditions = _layout_conditions
237
+
238
+ if only = conditions[:only]
239
+ only.include?(action_name)
240
+ elsif except = conditions[:except]
241
+ !except.include?(action_name)
242
+ else
243
+ true
244
+ end
243
245
  end
244
- end
245
246
  end
246
247
 
247
248
  # Specify the layout to use for this class.
248
249
  #
249
250
  # If the specified layout is a:
250
251
  # String:: the String is the template name
251
- # Symbol:: call the method specified by the symbol, which will return the template name
252
+ # Symbol:: call the method specified by the symbol
253
+ # Proc:: call the passed Proc
252
254
  # false:: There is no layout
253
255
  # true:: raise an ArgumentError
254
256
  # nil:: Force default layout behavior with inheritance
255
257
  #
258
+ # Return value of +Proc+ and +Symbol+ arguments should be +String+, +false+, +true+ or +nil+
259
+ # with the same meaning as described above.
256
260
  # ==== Parameters
257
261
  # * <tt>layout</tt> - The layout to use.
258
262
  #
@@ -262,7 +266,7 @@ module ActionView
262
266
  def layout(layout, conditions = {})
263
267
  include LayoutConditions unless conditions.empty?
264
268
 
265
- conditions.each {|k, v| conditions[k] = Array(v).map {|a| a.to_s} }
269
+ conditions.each { |k, v| conditions[k] = Array(v).map(&:to_s) }
266
270
  self._layout_conditions = conditions
267
271
 
268
272
  self._layout = layout
@@ -274,10 +278,10 @@ module ActionView
274
278
  # If a layout is not explicitly mentioned then look for a layout with the controller's name.
275
279
  # if nothing is found then try same procedure to find super class's layout.
276
280
  def _write_layout_method # :nodoc:
277
- remove_possible_method(:_layout)
281
+ silence_redefinition_of_method(:_layout)
278
282
 
279
- prefixes = _implied_layout_name =~ /\blayouts/ ? [] : ["layouts"]
280
- default_behavior = "lookup_context.find_all('#{_implied_layout_name}', #{prefixes.inspect}).first || super"
283
+ prefixes = /\blayouts/.match?(_implied_layout_name) ? [] : ["layouts"]
284
+ default_behavior = "lookup_context.find_all('#{_implied_layout_name}', #{prefixes.inspect}, false, [], { formats: formats }).first || super"
281
285
  name_clause = if name
282
286
  default_behavior
283
287
  else
@@ -286,7 +290,8 @@ module ActionView
286
290
  RUBY
287
291
  end
288
292
 
289
- layout_definition = case _layout
293
+ layout_definition = \
294
+ case _layout
290
295
  when String
291
296
  _layout.inspect
292
297
  when Symbol
@@ -313,10 +318,10 @@ module ActionView
313
318
  raise ArgumentError, "Layouts must be specified as a String, Symbol, Proc, false, or nil"
314
319
  when nil
315
320
  name_clause
316
- end
321
+ end
317
322
 
318
- self.class_eval <<-RUBY, __FILE__, __LINE__ + 1
319
- def _layout
323
+ class_eval <<-RUBY, __FILE__, __LINE__ + 1
324
+ def _layout(lookup_context, formats)
320
325
  if _conditional_layout?
321
326
  #{layout_definition}
322
327
  else
@@ -328,15 +333,14 @@ module ActionView
328
333
  end
329
334
 
330
335
  private
331
-
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:
@@ -366,13 +370,12 @@ module ActionView
366
370
  end
367
371
 
368
372
  private
369
-
370
373
  def _conditional_layout?
371
374
  true
372
375
  end
373
376
 
374
377
  # This will be overwritten by _write_layout_method
375
- def _layout; end
378
+ def _layout(*); end
376
379
 
377
380
  # Determine the layout for a given name, taking into account the name type.
378
381
  #
@@ -382,8 +385,8 @@ module ActionView
382
385
  case name
383
386
  when String then _normalize_layout(name)
384
387
  when Proc then name
385
- when true then Proc.new { _default_layout(true) }
386
- when :default then Proc.new { _default_layout(false) }
388
+ when true then Proc.new { |lookup_context, formats| _default_layout(lookup_context, formats, true) }
389
+ when :default then Proc.new { |lookup_context, formats| _default_layout(lookup_context, formats, false) }
387
390
  when false, nil then nil
388
391
  else
389
392
  raise ArgumentError,
@@ -399,14 +402,15 @@ module ActionView
399
402
  # Optionally raises an exception if the layout could not be found.
400
403
  #
401
404
  # ==== Parameters
402
- # * <tt>require_layout</tt> - If set to true and layout is not found,
403
- # an ArgumentError exception is raised (defaults to false)
405
+ # * <tt>formats</tt> - The formats accepted to this layout
406
+ # * <tt>require_layout</tt> - If set to +true+ and layout is not found,
407
+ # an +ArgumentError+ exception is raised (defaults to +false+)
404
408
  #
405
409
  # ==== Returns
406
- # * <tt>template</tt> - The template object for the default layout (or nil)
407
- def _default_layout(require_layout = false)
410
+ # * <tt>template</tt> - The template object for the default layout (or +nil+)
411
+ def _default_layout(lookup_context, formats, require_layout = false)
408
412
  begin
409
- value = _layout if action_has_layout?
413
+ value = _layout(lookup_context, formats) if action_has_layout?
410
414
  rescue NameError => e
411
415
  raise e, "Could not render layout: #{e.message}"
412
416
  end
@@ -420,7 +424,7 @@ module ActionView
420
424
  end
421
425
 
422
426
  def _include_layout?(options)
423
- (options.keys & [:body, :text, :plain, :html, :inline, :partial]).empty? || options.key?(:layout)
427
+ (options.keys & [:body, :plain, :html, :inline, :partial]).empty? || options.key?(:layout)
424
428
  end
425
429
  end
426
430
  end
@@ -1,4 +1,6 @@
1
- require 'active_support/log_subscriber'
1
+ # frozen_string_literal: true
2
+
3
+ require "active_support/log_subscriber"
2
4
 
3
5
  module ActionView
4
6
  # = Action View Log Subscriber
@@ -14,30 +16,79 @@ 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})"
22
+ end
23
+ end
24
+
25
+ def render_partial(event)
26
+ info do
27
+ message = +" Rendered #{from_rails_root(event.payload[:identifier])}"
28
+ message << " within #{from_rails_root(event.payload[:layout])}" if event.payload[:layout]
29
+ message << " (Duration: #{event.duration.round(1)}ms | Allocations: #{event.allocations})"
30
+ message << " #{cache_message(event.payload)}" unless event.payload[:cache_hit].nil?
31
+ message
32
+ end
33
+ end
34
+
35
+ def render_collection(event)
36
+ identifier = event.payload[:identifier] || "templates"
37
+
38
+ info do
39
+ " Rendered collection of #{from_rails_root(identifier)}" \
40
+ " #{render_count(event.payload)} (Duration: #{event.duration.round(1)}ms | Allocations: #{event.allocations})"
20
41
  end
21
42
  end
22
- alias :render_partial :render_template
23
- alias :render_collection :render_template
43
+
44
+ def start(name, id, payload)
45
+ if name == "render_template.action_view"
46
+ log_rendering_start(payload)
47
+ end
48
+
49
+ super
50
+ end
24
51
 
25
52
  def logger
26
53
  ActionView::Base.logger
27
54
  end
28
55
 
29
- protected
30
-
31
- EMPTY = ''
32
- def from_rails_root(string)
56
+ private
57
+ EMPTY = ""
58
+ def from_rails_root(string) # :doc:
33
59
  string = string.sub(rails_root, EMPTY)
34
60
  string.sub!(VIEWS_PATTERN, EMPTY)
35
61
  string
36
62
  end
37
63
 
38
- def rails_root
64
+ def rails_root # :doc:
39
65
  @root ||= "#{Rails.root}/"
40
66
  end
67
+
68
+ def render_count(payload) # :doc:
69
+ if payload[:cache_hits]
70
+ "[#{payload[:cache_hits]} / #{payload[:count]} cache hits]"
71
+ else
72
+ "[#{payload[:count]} times]"
73
+ end
74
+ end
75
+
76
+ def cache_message(payload) # :doc:
77
+ case payload[:cache_hit]
78
+ when :hit
79
+ "[cache hit]"
80
+ when :miss
81
+ "[cache miss]"
82
+ end
83
+ end
84
+
85
+ def log_rendering_start(payload)
86
+ info do
87
+ message = +" Rendering #{from_rails_root(payload[:identifier])}"
88
+ message << " within #{from_rails_root(payload[:layout])}" if payload[:layout]
89
+ message
90
+ end
91
+ end
41
92
  end
42
93
  end
43
94