actionview 7.0.8.7 → 7.1.5.1

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 (91) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +309 -321
  3. data/MIT-LICENSE +1 -1
  4. data/README.rdoc +1 -1
  5. data/app/assets/javascripts/rails-ujs.esm.js +686 -0
  6. data/app/assets/javascripts/rails-ujs.js +630 -0
  7. data/lib/action_view/base.rb +34 -14
  8. data/lib/action_view/buffers.rb +106 -8
  9. data/lib/action_view/cache_expiry.rb +40 -43
  10. data/lib/action_view/context.rb +1 -1
  11. data/lib/action_view/deprecator.rb +7 -0
  12. data/lib/action_view/digestor.rb +1 -1
  13. data/lib/action_view/gem_version.rb +4 -4
  14. data/lib/action_view/helpers/active_model_helper.rb +1 -1
  15. data/lib/action_view/helpers/asset_tag_helper.rb +136 -52
  16. data/lib/action_view/helpers/asset_url_helper.rb +6 -5
  17. data/lib/action_view/helpers/atom_feed_helper.rb +5 -5
  18. data/lib/action_view/helpers/cache_helper.rb +7 -13
  19. data/lib/action_view/helpers/capture_helper.rb +30 -10
  20. data/lib/action_view/helpers/content_exfiltration_prevention_helper.rb +70 -0
  21. data/lib/action_view/helpers/controller_helper.rb +6 -0
  22. data/lib/action_view/helpers/csp_helper.rb +2 -2
  23. data/lib/action_view/helpers/csrf_helper.rb +2 -2
  24. data/lib/action_view/helpers/date_helper.rb +17 -19
  25. data/lib/action_view/helpers/debug_helper.rb +3 -3
  26. data/lib/action_view/helpers/form_helper.rb +54 -25
  27. data/lib/action_view/helpers/form_options_helper.rb +2 -1
  28. data/lib/action_view/helpers/form_tag_helper.rb +49 -15
  29. data/lib/action_view/helpers/javascript_helper.rb +1 -0
  30. data/lib/action_view/helpers/number_helper.rb +37 -330
  31. data/lib/action_view/helpers/output_safety_helper.rb +2 -2
  32. data/lib/action_view/helpers/rendering_helper.rb +1 -1
  33. data/lib/action_view/helpers/sanitize_helper.rb +51 -21
  34. data/lib/action_view/helpers/tag_helper.rb +5 -27
  35. data/lib/action_view/helpers/tags/base.rb +11 -52
  36. data/lib/action_view/helpers/tags/collection_check_boxes.rb +1 -0
  37. data/lib/action_view/helpers/tags/collection_radio_buttons.rb +1 -0
  38. data/lib/action_view/helpers/tags/collection_select.rb +3 -0
  39. data/lib/action_view/helpers/tags/date_field.rb +1 -1
  40. data/lib/action_view/helpers/tags/date_select.rb +2 -0
  41. data/lib/action_view/helpers/tags/datetime_field.rb +14 -6
  42. data/lib/action_view/helpers/tags/datetime_local_field.rb +11 -2
  43. data/lib/action_view/helpers/tags/grouped_collection_select.rb +3 -0
  44. data/lib/action_view/helpers/tags/month_field.rb +1 -1
  45. data/lib/action_view/helpers/tags/select.rb +3 -0
  46. data/lib/action_view/helpers/tags/select_renderer.rb +56 -0
  47. data/lib/action_view/helpers/tags/time_field.rb +1 -1
  48. data/lib/action_view/helpers/tags/time_zone_select.rb +3 -0
  49. data/lib/action_view/helpers/tags/week_field.rb +1 -1
  50. data/lib/action_view/helpers/tags/weekday_select.rb +3 -0
  51. data/lib/action_view/helpers/tags.rb +2 -0
  52. data/lib/action_view/helpers/text_helper.rb +156 -84
  53. data/lib/action_view/helpers/translation_helper.rb +3 -3
  54. data/lib/action_view/helpers/url_helper.rb +46 -17
  55. data/lib/action_view/helpers.rb +2 -0
  56. data/lib/action_view/layouts.rb +8 -6
  57. data/lib/action_view/log_subscriber.rb +49 -32
  58. data/lib/action_view/lookup_context.rb +29 -13
  59. data/lib/action_view/path_registry.rb +57 -0
  60. data/lib/action_view/path_set.rb +13 -14
  61. data/lib/action_view/railtie.rb +26 -3
  62. data/lib/action_view/record_identifier.rb +15 -8
  63. data/lib/action_view/renderer/abstract_renderer.rb +1 -1
  64. data/lib/action_view/renderer/collection_renderer.rb +10 -2
  65. data/lib/action_view/renderer/partial_renderer/collection_caching.rb +2 -1
  66. data/lib/action_view/renderer/partial_renderer.rb +2 -1
  67. data/lib/action_view/renderer/renderer.rb +2 -0
  68. data/lib/action_view/renderer/streaming_template_renderer.rb +3 -2
  69. data/lib/action_view/renderer/template_renderer.rb +3 -2
  70. data/lib/action_view/rendering.rb +22 -4
  71. data/lib/action_view/ripper_ast_parser.rb +5 -5
  72. data/lib/action_view/template/error.rb +14 -1
  73. data/lib/action_view/template/handlers/builder.rb +4 -4
  74. data/lib/action_view/template/handlers/erb/erubi.rb +23 -27
  75. data/lib/action_view/template/handlers/erb.rb +73 -1
  76. data/lib/action_view/template/handlers.rb +1 -1
  77. data/lib/action_view/template/html.rb +1 -1
  78. data/lib/action_view/template/raw_file.rb +1 -1
  79. data/lib/action_view/template/renderable.rb +1 -1
  80. data/lib/action_view/template/resolver.rb +10 -2
  81. data/lib/action_view/template/text.rb +1 -1
  82. data/lib/action_view/template/types.rb +25 -34
  83. data/lib/action_view/template.rb +249 -54
  84. data/lib/action_view/template_path.rb +2 -0
  85. data/lib/action_view/test_case.rb +176 -21
  86. data/lib/action_view/unbound_template.rb +17 -7
  87. data/lib/action_view/version.rb +1 -1
  88. data/lib/action_view/view_paths.rb +15 -24
  89. data/lib/action_view.rb +4 -1
  90. metadata +22 -23
  91. data/lib/assets/compiled/rails-ujs.js +0 -777
@@ -10,7 +10,7 @@ require "action_view/template"
10
10
  require "action_view/lookup_context"
11
11
 
12
12
  module ActionView # :nodoc:
13
- # = Action View Base
13
+ # = Action View \Base
14
14
  #
15
15
  # Action View templates can be written in several ways.
16
16
  # If the template file has a <tt>.erb</tt> extension, then it uses the erubi[https://rubygems.org/gems/erubi]
@@ -44,9 +44,9 @@ module ActionView # :nodoc:
44
44
  # Using sub templates allows you to sidestep tedious replication and extract common display structures in shared templates. The
45
45
  # classic example is the use of a header and footer (even though the Action Pack-way would be to use Layouts):
46
46
  #
47
- # <%= render "shared/header" %>
47
+ # <%= render "application/header" %>
48
48
  # Something really specific and terrific
49
- # <%= render "shared/footer" %>
49
+ # <%= render "application/footer" %>
50
50
  #
51
51
  # As you see, we use the output embeddings for the render methods. The render call itself will just return a string holding the
52
52
  # result of the rendering. The output embedding writes it to the current template.
@@ -55,7 +55,7 @@ module ActionView # :nodoc:
55
55
  # variables defined using the regular embedding tags. Like this:
56
56
  #
57
57
  # <% @page_title = "A Wonderful Hello" %>
58
- # <%= render "shared/header" %>
58
+ # <%= render "application/header" %>
59
59
  #
60
60
  # Now the header can pick up on the <tt>@page_title</tt> variable and use it for outputting a title tag:
61
61
  #
@@ -65,9 +65,9 @@ module ActionView # :nodoc:
65
65
  #
66
66
  # You can pass local variables to sub templates by using a hash with the variable names as keys and the objects as values:
67
67
  #
68
- # <%= render "shared/header", { headline: "Welcome", person: person } %>
68
+ # <%= render "application/header", { headline: "Welcome", person: person } %>
69
69
  #
70
- # These can now be accessed in <tt>shared/header</tt> with:
70
+ # These can now be accessed in <tt>application/header</tt> with:
71
71
  #
72
72
  # Headline: <%= headline %>
73
73
  # First name: <%= person.first_name %>
@@ -82,8 +82,8 @@ module ActionView # :nodoc:
82
82
  #
83
83
  # === Template caching
84
84
  #
85
- # By default, Rails will compile each template to a method in order to render it. When you alter a template,
86
- # Rails will check the file's modification time and recompile it in development mode.
85
+ # By default, \Rails will compile each template to a method in order to render it. When you alter a template,
86
+ # \Rails will check the file's modification time and recompile it in development mode.
87
87
  #
88
88
  # == Builder
89
89
  #
@@ -136,8 +136,7 @@ module ActionView # :nodoc:
136
136
  # end
137
137
  # end
138
138
  #
139
- # For more information on Builder please consult the {source
140
- # code}[https://github.com/jimweirich/builder].
139
+ # For more information on Builder please consult the {source code}[https://github.com/rails/builder].
141
140
  class Base
142
141
  include Helpers, ::ERB::Util, Context
143
142
 
@@ -205,7 +204,8 @@ module ActionView # :nodoc:
205
204
  delegate :formats, :formats=, :locale, :locale=, :view_paths, :view_paths=, to: :lookup_context
206
205
 
207
206
  def assign(new_assigns) # :nodoc:
208
- @_assigns = new_assigns.each { |key, value| instance_variable_set("@#{key}", value) }
207
+ @_assigns = new_assigns
208
+ new_assigns.each { |key, value| instance_variable_set("@#{key}", value) }
209
209
  end
210
210
 
211
211
  # :stopdoc:
@@ -232,16 +232,36 @@ module ActionView # :nodoc:
232
232
  @view_renderer = ActionView::Renderer.new @lookup_context
233
233
  @current_template = nil
234
234
 
235
- assign(assigns)
236
235
  assign_controller(controller)
237
236
  _prepare_context
237
+
238
+ super()
239
+
240
+ # Assigns must be called last to minimize the number of shapes
241
+ assign(assigns)
238
242
  end
239
243
 
240
- def _run(method, template, locals, buffer, add_to_stack: true, &block)
244
+ def _run(method, template, locals, buffer, add_to_stack: true, has_strict_locals: false, &block)
241
245
  _old_output_buffer, _old_virtual_path, _old_template = @output_buffer, @virtual_path, @current_template
242
246
  @current_template = template if add_to_stack
243
247
  @output_buffer = buffer
244
- public_send(method, locals, buffer, &block)
248
+
249
+ if has_strict_locals
250
+ begin
251
+ public_send(method, buffer, **locals, &block)
252
+ rescue ArgumentError => argument_error
253
+ raise(
254
+ ArgumentError,
255
+ argument_error.
256
+ message.
257
+ gsub("unknown keyword:", "unknown local:").
258
+ gsub("missing keyword:", "missing local:").
259
+ gsub("no keywords accepted", "no locals accepted")
260
+ )
261
+ end
262
+ else
263
+ public_send(method, locals, buffer, &block)
264
+ end
245
265
  ensure
246
266
  @output_buffer, @virtual_path, @current_template = _old_output_buffer, _old_virtual_path, _old_template
247
267
  end
@@ -18,24 +18,91 @@ module ActionView
18
18
  # sbuf << 5
19
19
  # puts sbuf # => "hello\u0005"
20
20
  #
21
- class OutputBuffer < ActiveSupport::SafeBuffer # :nodoc:
22
- def initialize(*)
23
- super
24
- encode!
21
+ class OutputBuffer # :nodoc:
22
+ def initialize(buffer = "")
23
+ @raw_buffer = String.new(buffer)
24
+ @raw_buffer.encode!
25
+ end
26
+
27
+ delegate :length, :empty?, :blank?, :encoding, :encode!, :force_encoding, to: :@raw_buffer
28
+
29
+ def to_s
30
+ @raw_buffer.html_safe
31
+ end
32
+ alias_method :html_safe, :to_s
33
+
34
+ def to_str
35
+ @raw_buffer.dup
36
+ end
37
+
38
+ def html_safe?
39
+ true
25
40
  end
26
41
 
27
42
  def <<(value)
28
- return self if value.nil?
29
- super(value.to_s)
43
+ unless value.nil?
44
+ value = value.to_s
45
+ @raw_buffer << if value.html_safe?
46
+ value
47
+ else
48
+ CGI.escapeHTML(value)
49
+ end
50
+ end
51
+ self
30
52
  end
53
+ alias :concat :<<
31
54
  alias :append= :<<
32
55
 
56
+ def safe_concat(value)
57
+ @raw_buffer << value
58
+ self
59
+ end
60
+ alias :safe_append= :safe_concat
61
+
33
62
  def safe_expr_append=(val)
34
63
  return self if val.nil?
35
- safe_concat val.to_s
64
+ @raw_buffer << val.to_s
65
+ self
36
66
  end
37
67
 
38
- alias :safe_append= :safe_concat
68
+ def initialize_copy(other)
69
+ @raw_buffer = other.to_str
70
+ end
71
+
72
+ def capture(*args)
73
+ new_buffer = +""
74
+ old_buffer, @raw_buffer = @raw_buffer, new_buffer
75
+ yield(*args)
76
+ new_buffer.html_safe
77
+ ensure
78
+ @raw_buffer = old_buffer
79
+ end
80
+
81
+ def ==(other)
82
+ other.class == self.class && @raw_buffer == other.to_str
83
+ end
84
+
85
+ def raw
86
+ RawOutputBuffer.new(self)
87
+ end
88
+
89
+ attr_reader :raw_buffer
90
+ end
91
+
92
+ class RawOutputBuffer # :nodoc:
93
+ def initialize(buffer)
94
+ @buffer = buffer
95
+ end
96
+
97
+ def <<(value)
98
+ unless value.nil?
99
+ @buffer.raw_buffer << value.to_s
100
+ end
101
+ end
102
+
103
+ def raw
104
+ self
105
+ end
39
106
  end
40
107
 
41
108
  class StreamingBuffer # :nodoc:
@@ -56,6 +123,15 @@ module ActionView
56
123
  end
57
124
  alias :safe_append= :safe_concat
58
125
 
126
+ def capture
127
+ buffer = +""
128
+ old_block, @block = @block, ->(value) { buffer << value }
129
+ yield
130
+ buffer.html_safe
131
+ ensure
132
+ @block = old_block
133
+ end
134
+
59
135
  def html_safe?
60
136
  true
61
137
  end
@@ -63,5 +139,27 @@ module ActionView
63
139
  def html_safe
64
140
  self
65
141
  end
142
+
143
+ def raw
144
+ RawStreamingBuffer.new(self)
145
+ end
146
+
147
+ attr_reader :block
148
+ end
149
+
150
+ class RawStreamingBuffer # :nodoc:
151
+ def initialize(buffer)
152
+ @buffer = buffer
153
+ end
154
+
155
+ def <<(value)
156
+ unless value.nil?
157
+ @buffer.block.call(value.to_s)
158
+ end
159
+ end
160
+
161
+ def raw
162
+ self
163
+ end
66
164
  end
67
165
  end
@@ -1,65 +1,62 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module ActionView
4
- class CacheExpiry
5
- class Executor
6
- def initialize(watcher:)
7
- @execution_lock = Concurrent::ReentrantReadWriteLock.new
8
- @cache_expiry = ViewModificationWatcher.new(watcher: watcher) do
9
- clear_cache
10
- end
11
- end
4
+ module CacheExpiry # :nodoc: all
5
+ class ViewReloader
6
+ def initialize(watcher:, &block)
7
+ @mutex = Mutex.new
8
+ @watcher_class = watcher
9
+ @watched_dirs = nil
10
+ @watcher = nil
11
+ @previous_change = false
12
12
 
13
- def run
14
- ActiveSupport::Dependencies.interlock.permit_concurrent_loads do
15
- @cache_expiry.execute_if_updated
16
- @execution_lock.acquire_read_lock
17
- end
13
+ rebuild_watcher
14
+
15
+ ActionView::PathRegistry.file_system_resolver_hooks << method(:rebuild_watcher)
18
16
  end
19
17
 
20
- def complete(_)
21
- @execution_lock.release_read_lock
18
+ def updated?
19
+ @previous_change || @watcher.updated?
22
20
  end
23
21
 
24
- private
25
- def clear_cache
26
- @execution_lock.with_write_lock do
27
- ActionView::LookupContext::DetailsKey.clear
28
- end
22
+ def execute
23
+ watcher = nil
24
+ @mutex.synchronize do
25
+ @previous_change = false
26
+ watcher = @watcher
29
27
  end
30
- end
31
-
32
- class ViewModificationWatcher
33
- def initialize(watcher:, &block)
34
- @watched_dirs = nil
35
- @watcher_class = watcher
36
- @watcher = nil
37
- @mutex = Mutex.new
38
- @block = block
28
+ watcher.execute
39
29
  end
40
30
 
41
- def execute_if_updated
42
- @mutex.synchronize do
43
- watched_dirs = dirs_to_watch
44
- return if watched_dirs.empty?
31
+ private
32
+ def reload!
33
+ ActionView::LookupContext::DetailsKey.clear
34
+ end
45
35
 
46
- if watched_dirs != @watched_dirs
47
- @watched_dirs = watched_dirs
48
- @watcher = @watcher_class.new([], watched_dirs, &@block)
49
- @watcher.execute
50
- else
51
- @watcher.execute_if_updated
36
+ def rebuild_watcher
37
+ @mutex.synchronize do
38
+ old_watcher = @watcher
39
+
40
+ if @watched_dirs != dirs_to_watch
41
+ @watched_dirs = dirs_to_watch
42
+ new_watcher = @watcher_class.new([], @watched_dirs) do
43
+ reload!
44
+ end
45
+ @watcher = new_watcher
46
+
47
+ # We must check the old watcher after initializing the new one to
48
+ # ensure we don't miss any events
49
+ @previous_change ||= old_watcher&.updated?
50
+ end
52
51
  end
53
52
  end
54
- end
55
53
 
56
- private
57
54
  def dirs_to_watch
58
- all_view_paths.grep(FileSystemResolver).map!(&:path).tap(&:uniq!).sort!
55
+ all_view_paths.uniq.sort
59
56
  end
60
57
 
61
58
  def all_view_paths
62
- ActionView::ViewPaths.all_view_paths.flat_map(&:paths)
59
+ ActionView::PathRegistry.all_file_system_resolvers.map(&:path)
63
60
  end
64
61
  end
65
62
  end
@@ -17,7 +17,7 @@ module ActionView
17
17
  # Prepares the context by setting the appropriate instance variables.
18
18
  def _prepare_context
19
19
  @view_flow = OutputFlow.new
20
- @output_buffer = nil
20
+ @output_buffer = ActionView::OutputBuffer.new
21
21
  @virtual_path = nil
22
22
  end
23
23
 
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActionView
4
+ def self.deprecator # :nodoc:
5
+ @deprecator ||= ActiveSupport::Deprecation.new
6
+ end
7
+ end
@@ -11,7 +11,7 @@ module ActionView
11
11
  #
12
12
  # * <tt>name</tt> - Template name
13
13
  # * <tt>format</tt> - Template format
14
- # * <tt>finder</tt> - An instance of <tt>ActionView::LookupContext</tt>
14
+ # * +finder+ - An instance of ActionView::LookupContext
15
15
  # * <tt>dependencies</tt> - An array of dependent views
16
16
  def digest(name:, format: nil, finder:, dependencies: nil)
17
17
  if dependencies.nil? || dependencies.empty?
@@ -1,16 +1,16 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module ActionView
4
- # Returns the currently loaded version of Action View as a <tt>Gem::Version</tt>.
4
+ # Returns the currently loaded version of Action View as a +Gem::Version+.
5
5
  def self.gem_version
6
6
  Gem::Version.new VERSION::STRING
7
7
  end
8
8
 
9
9
  module VERSION
10
10
  MAJOR = 7
11
- MINOR = 0
12
- TINY = 8
13
- PRE = "7"
11
+ MINOR = 1
12
+ TINY = 5
13
+ PRE = "1"
14
14
 
15
15
  STRING = [MAJOR, MINOR, TINY, PRE].compact.join(".")
16
16
  end
@@ -4,11 +4,11 @@ require "active_support/core_ext/module/attribute_accessors"
4
4
  require "active_support/core_ext/enumerable"
5
5
 
6
6
  module ActionView
7
- # = Active Model Helpers
8
7
  module Helpers # :nodoc:
9
8
  module ActiveModelHelper
10
9
  end
11
10
 
11
+ # = Active \Model Instance Tag \Helpers
12
12
  module ActiveModelInstanceTag
13
13
  def object
14
14
  @active_model_object ||= begin