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
@@ -63,7 +63,7 @@ module ActionView
63
63
  end
64
64
 
65
65
  def call_method_name
66
- self.last.first
66
+ self[2].first
67
67
  end
68
68
 
69
69
  def to_string
@@ -86,11 +86,11 @@ module ActionView
86
86
  end
87
87
 
88
88
  def hash_from_body(body)
89
- body.map do |hash_node|
89
+ body.to_h do |hash_node|
90
90
  return nil if hash_node.type != :assoc_new
91
91
 
92
92
  [hash_node[0], hash_node[1]]
93
- end.to_h
93
+ end
94
94
  end
95
95
 
96
96
  def symbol?
@@ -189,9 +189,9 @@ module ActionView
189
189
  parser = RenderCallExtractor.new(code)
190
190
  parser.parse
191
191
 
192
- parser.render_calls.group_by(&:first).collect do |method, nodes|
192
+ parser.render_calls.group_by(&:first).to_h do |method, nodes|
193
193
  [ method.to_sym, nodes.collect { |v| v[1] } ]
194
- end.to_h
194
+ end
195
195
  end
196
196
  end
197
197
  end
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "active_support/core_ext/enumerable"
4
+ require "active_support/syntax_error_proxy"
4
5
 
5
6
  module ActionView
6
7
  # = Action View Errors
@@ -156,13 +157,25 @@ module ActionView
156
157
  # Override to prevent #cause resetting during re-raise.
157
158
  attr_reader :cause
158
159
 
160
+ attr_reader :template
161
+
159
162
  def initialize(template)
160
163
  super($!.message)
161
- set_backtrace($!.backtrace)
162
164
  @cause = $!
165
+ if @cause.is_a?(SyntaxError)
166
+ @cause = ActiveSupport::SyntaxErrorProxy.new(@cause)
167
+ end
163
168
  @template, @sub_templates = template, nil
164
169
  end
165
170
 
171
+ def backtrace
172
+ @cause.backtrace
173
+ end
174
+
175
+ def backtrace_locations
176
+ @cause.backtrace_locations
177
+ end
178
+
166
179
  def file_name
167
180
  @template.identifier
168
181
  end
@@ -7,10 +7,10 @@ module ActionView
7
7
 
8
8
  def call(template, source)
9
9
  require_engine
10
- "xml = ::Builder::XmlMarkup.new(:indent => 2);" \
11
- "self.output_buffer = xml.target!;" +
12
- source +
13
- ";xml.target!;"
10
+ # the double assignment is to silence "assigned but unused variable" warnings
11
+ "xml = xml = ::Builder::XmlMarkup.new(indent: 2, target: output_buffer.raw);" \
12
+ "#{source};" \
13
+ "output_buffer.to_s"
14
14
  end
15
15
 
16
16
  private
@@ -16,22 +16,16 @@ module ActionView
16
16
 
17
17
  properties[:bufvar] ||= "@output_buffer"
18
18
  properties[:preamble] ||= ""
19
- properties[:postamble] ||= "#{properties[:bufvar]}.to_s"
19
+ properties[:postamble] ||= "#{properties[:bufvar]}"
20
+
21
+ # Tell Eruby that whether template will be compiled with `frozen_string_literal: true`
22
+ properties[:freeze_template_literals] = !Template.frozen_string_literal
20
23
 
21
24
  properties[:escapefunc] = ""
22
25
 
23
26
  super
24
27
  end
25
28
 
26
- def evaluate(action_view_erb_handler_context)
27
- src = @src
28
- view = Class.new(ActionView::Base) {
29
- include action_view_erb_handler_context._routes.url_helpers
30
- class_eval("define_method(:_template) { |local_assigns, output_buffer| #{src} }", defined?(@filename) ? @filename : "(erubi)", 0)
31
- }.empty
32
- view._run(:_template, nil, {}, ActionView::OutputBuffer.new)
33
- end
34
-
35
29
  private
36
30
  def add_text(text)
37
31
  return if text.empty?
@@ -39,30 +33,32 @@ module ActionView
39
33
  if text == "\n"
40
34
  @newline_pending += 1
41
35
  else
42
- src << bufvar << ".safe_append='"
43
- src << "\n" * @newline_pending if @newline_pending > 0
44
- src << text.gsub(/['\\]/, '\\\\\&')
45
- src << "'.freeze;"
46
-
36
+ with_buffer do
37
+ src << ".safe_append='"
38
+ src << "\n" * @newline_pending if @newline_pending > 0
39
+ src << text.gsub(/['\\]/, '\\\\\&') << @text_end
40
+ end
47
41
  @newline_pending = 0
48
42
  end
49
43
  end
50
44
 
51
- BLOCK_EXPR = /\s*((\s+|\))do|\{)(\s*\|[^|]*\|)?\s*\Z/
45
+ BLOCK_EXPR = /((\s|\))do|\{)(\s*\|[^|]*\|)?\s*\Z/
52
46
 
53
47
  def add_expression(indicator, code)
54
48
  flush_newline_if_pending(src)
55
49
 
56
- if (indicator == "==") || @escape
57
- src << bufvar << ".safe_expr_append="
58
- else
59
- src << bufvar << ".append="
60
- end
61
-
62
- if BLOCK_EXPR.match?(code)
63
- src << " " << code
64
- else
65
- src << "(" << code << ");"
50
+ with_buffer do
51
+ if (indicator == "==") || @escape
52
+ src << ".safe_expr_append="
53
+ else
54
+ src << ".append="
55
+ end
56
+
57
+ if BLOCK_EXPR.match?(code)
58
+ src << " " << code
59
+ else
60
+ src << "(" << code << ")"
61
+ end
66
62
  end
67
63
  end
68
64
 
@@ -78,7 +74,7 @@ module ActionView
78
74
 
79
75
  def flush_newline_if_pending(src)
80
76
  if @newline_pending > 0
81
- src << bufvar << ".safe_append='#{"\n" * @newline_pending}'.freeze;"
77
+ with_buffer { src << ".safe_append='#{"\n" * @newline_pending}" << @text_end }
82
78
  @newline_pending = 0
83
79
  end
84
80
  end
@@ -1,5 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require "strscan"
4
+ require "active_support/core_ext/erb/util"
5
+
3
6
  module ActionView
4
7
  class Template
5
8
  module Handlers
@@ -21,6 +24,8 @@ module ActionView
21
24
 
22
25
  ENCODING_TAG = Regexp.new("\\A(<%#{ENCODING_FLAG}-?%>)[ \\t]*")
23
26
 
27
+ LocationParsingError = Class.new(StandardError) # :nodoc:
28
+
24
29
  def self.call(template, source)
25
30
  new.call(template, source)
26
31
  end
@@ -33,6 +38,26 @@ module ActionView
33
38
  true
34
39
  end
35
40
 
41
+ # Translate an error location returned by ErrorHighlight to the correct
42
+ # source location inside the template.
43
+ def translate_location(spot, backtrace_location, source)
44
+ # Tokenize the source line
45
+ tokens = ::ERB::Util.tokenize(source.lines[backtrace_location.lineno - 1])
46
+ new_first_column = find_offset(spot[:snippet], tokens, spot[:first_column])
47
+ lineno_delta = spot[:first_lineno] - backtrace_location.lineno
48
+ spot[:first_lineno] -= lineno_delta
49
+ spot[:last_lineno] -= lineno_delta
50
+
51
+ column_delta = spot[:first_column] - new_first_column
52
+ spot[:first_column] -= column_delta
53
+ spot[:last_column] -= column_delta
54
+ spot[:script_lines] = source.lines
55
+
56
+ spot
57
+ rescue NotImplementedError, LocationParsingError
58
+ nil
59
+ end
60
+
36
61
  def call(template, source)
37
62
  # First, convert to BINARY, so in case the encoding is
38
63
  # wrong, we can still find an encoding tag
@@ -58,7 +83,7 @@ module ActionView
58
83
 
59
84
  if ActionView::Base.annotate_rendered_view_with_filenames && template.format == :html
60
85
  options[:preamble] = "@output_buffer.safe_append='<!-- BEGIN #{template.short_identifier} -->';"
61
- options[:postamble] = "@output_buffer.safe_append='<!-- END #{template.short_identifier} -->';@output_buffer.to_s"
86
+ options[:postamble] = "@output_buffer.safe_append='<!-- END #{template.short_identifier} -->';@output_buffer"
62
87
  end
63
88
 
64
89
  self.class.erb_implementation.new(erb, options).src
@@ -79,6 +104,53 @@ module ActionView
79
104
  # Otherwise, raise an exception
80
105
  raise WrongEncodingError.new(string, string.encoding)
81
106
  end
107
+
108
+ def find_offset(compiled, source_tokens, error_column)
109
+ compiled = StringScanner.new(compiled)
110
+
111
+ passed_tokens = []
112
+
113
+ while tok = source_tokens.shift
114
+ tok_name, str = *tok
115
+ case tok_name
116
+ when :TEXT
117
+ loop do
118
+ break if compiled.match?(str)
119
+ compiled.getch
120
+ end
121
+ raise LocationParsingError unless compiled.scan(str)
122
+ when :CODE
123
+ if compiled.pos > error_column
124
+ raise LocationParsingError, "We went too far"
125
+ end
126
+
127
+ if compiled.pos + str.bytesize >= error_column
128
+ offset = error_column - compiled.pos
129
+ return passed_tokens.map(&:last).join.bytesize + offset
130
+ else
131
+ unless compiled.scan(str)
132
+ raise LocationParsingError, "Couldn't find code snippet"
133
+ end
134
+ end
135
+ when :OPEN
136
+ next_tok = source_tokens.first.last
137
+ loop do
138
+ break if compiled.match?(next_tok)
139
+ compiled.getch
140
+ end
141
+ when :CLOSE
142
+ next_tok = source_tokens.first.last
143
+ loop do
144
+ break if compiled.match?(next_tok)
145
+ compiled.getch
146
+ end
147
+ else
148
+ raise LocationParsingError, "Not implemented: #{tok.first}"
149
+ end
150
+
151
+ passed_tokens << tok
152
+ end
153
+ end
82
154
  end
83
155
  end
84
156
  end
@@ -1,8 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module ActionView # :nodoc:
4
- # = Action View Template Handlers
5
4
  class Template # :nodoc:
5
+ # = Action View Template Handlers
6
6
  module Handlers # :nodoc:
7
7
  autoload :Raw, "action_view/template/handlers/raw"
8
8
  autoload :ERB, "action_view/template/handlers/erb"
@@ -1,8 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module ActionView # :nodoc:
4
- # = Action View HTML Template
5
4
  class Template # :nodoc:
5
+ # = Action View HTML Template
6
6
  class HTML # :nodoc:
7
7
  attr_reader :type
8
8
 
@@ -1,8 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module ActionView # :nodoc:
4
- # = Action View RawFile Template
5
4
  class Template # :nodoc:
5
+ # = Action View RawFile Template
6
6
  class RawFile # :nodoc:
7
7
  attr_accessor :type, :format
8
8
 
@@ -1,8 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module ActionView
4
- # = Action View Renderable Template for objects that respond to #render_in
5
4
  class Template
5
+ # = Action View Renderable Template for objects that respond to #render_in
6
6
  class Renderable # :nodoc:
7
7
  def initialize(renderable)
8
8
  @renderable = renderable
@@ -10,8 +10,7 @@ require "concurrent/map"
10
10
  module ActionView
11
11
  # = Action View Resolver
12
12
  class Resolver
13
- Path = ActionView::TemplatePath
14
- deprecate_constant :Path
13
+ include ActiveSupport::Deprecation::DeprecatedConstantAccessor
15
14
 
16
15
  class PathParser # :nodoc:
17
16
  ParsedPath = Struct.new(:path, :details)
@@ -65,6 +64,11 @@ module ActionView
65
64
  _find_all(name, prefix, partial, details, key, locals)
66
65
  end
67
66
 
67
+ def built_templates # :nodoc:
68
+ # Used for error pages
69
+ []
70
+ end
71
+
68
72
  def all_template_paths # :nodoc:
69
73
  # Not implemented by default
70
74
  []
@@ -122,6 +126,10 @@ module ActionView
122
126
  end
123
127
  end
124
128
 
129
+ def built_templates # :nodoc:
130
+ @unbound_templates.values.flatten.flat_map(&:built_templates)
131
+ end
132
+
125
133
  private
126
134
  def _find_all(name, prefix, partial, details, key, locals)
127
135
  requested_details = key || TemplateDetails::Requested.new(**details)
@@ -1,8 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module ActionView # :nodoc:
4
- # = Action View Text Template
5
4
  class Template # :nodoc:
5
+ # = Action View Text Template
6
6
  class Text # :nodoc:
7
7
  attr_accessor :type
8
8
 
@@ -4,11 +4,14 @@ require "active_support/core_ext/module/attribute_accessors"
4
4
 
5
5
  module ActionView
6
6
  class Template # :nodoc:
7
- module Types
8
- class Type
9
- SET = Struct.new(:symbols).new([ :html, :text, :js, :css, :xml, :json ])
7
+ # SimpleType is mostly just a stub implementation for when Action View
8
+ # is used without Action Dispatch.
9
+ class SimpleType # :nodoc:
10
+ @symbols = [ :html, :text, :js, :css, :xml, :json ]
11
+ class << self
12
+ attr_reader :symbols
10
13
 
11
- def self.[](type)
14
+ def [](type)
12
15
  if type.is_a?(self)
13
16
  type
14
17
  else
@@ -16,44 +19,32 @@ module ActionView
16
19
  end
17
20
  end
18
21
 
19
- attr_reader :symbol
20
-
21
- def initialize(symbol)
22
- @symbol = symbol.to_sym
23
- end
24
-
25
- def to_s
26
- @symbol.to_s
27
- end
28
- alias to_str to_s
29
-
30
- def ref
31
- @symbol
32
- end
33
- alias to_sym ref
34
-
35
- def ==(type)
36
- @symbol == type.to_sym unless type.blank?
22
+ def valid_symbols?(symbols) # :nodoc
23
+ symbols.all? { |s| @symbols.include?(s) }
37
24
  end
38
25
  end
39
26
 
40
- class << self
41
- attr_accessor :type_klass
27
+ attr_reader :symbol
42
28
 
43
- def delegate_to(klass)
44
- self.type_klass = klass
45
- end
29
+ def initialize(symbol)
30
+ @symbol = symbol.to_sym
31
+ end
46
32
 
47
- def [](type)
48
- type_klass[type]
49
- end
33
+ def to_s
34
+ @symbol.to_s
35
+ end
36
+ alias to_str to_s
50
37
 
51
- def symbols
52
- type_klass::SET.symbols
53
- end
38
+ def ref
39
+ @symbol
54
40
  end
41
+ alias to_sym ref
55
42
 
56
- delegate_to Type
43
+ def ==(type)
44
+ @symbol == type.to_sym unless type.blank?
45
+ end
57
46
  end
47
+
48
+ Types = SimpleType # :nodoc:
58
49
  end
59
50
  end