actionview 7.0.8.6 → 7.1.0.beta1
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 +235 -387
- data/MIT-LICENSE +1 -1
- data/README.rdoc +1 -1
- data/app/assets/javascripts/rails-ujs.esm.js +668 -0
- data/app/assets/javascripts/rails-ujs.js +606 -0
- data/lib/action_view/base.rb +28 -7
- data/lib/action_view/buffers.rb +106 -8
- data/lib/action_view/cache_expiry.rb +40 -43
- data/lib/action_view/context.rb +1 -1
- data/lib/action_view/deprecator.rb +7 -0
- data/lib/action_view/digestor.rb +1 -1
- data/lib/action_view/gem_version.rb +4 -4
- data/lib/action_view/helpers/active_model_helper.rb +1 -1
- data/lib/action_view/helpers/asset_tag_helper.rb +130 -46
- data/lib/action_view/helpers/asset_url_helper.rb +6 -5
- data/lib/action_view/helpers/atom_feed_helper.rb +5 -5
- data/lib/action_view/helpers/cache_helper.rb +3 -9
- data/lib/action_view/helpers/capture_helper.rb +24 -10
- data/lib/action_view/helpers/content_exfiltration_prevention_helper.rb +70 -0
- data/lib/action_view/helpers/controller_helper.rb +6 -0
- data/lib/action_view/helpers/csp_helper.rb +2 -2
- data/lib/action_view/helpers/csrf_helper.rb +2 -2
- data/lib/action_view/helpers/date_helper.rb +17 -19
- data/lib/action_view/helpers/debug_helper.rb +3 -3
- data/lib/action_view/helpers/form_helper.rb +43 -18
- data/lib/action_view/helpers/form_options_helper.rb +2 -1
- data/lib/action_view/helpers/form_tag_helper.rb +43 -9
- data/lib/action_view/helpers/javascript_helper.rb +1 -0
- data/lib/action_view/helpers/number_helper.rb +2 -1
- data/lib/action_view/helpers/output_safety_helper.rb +2 -2
- data/lib/action_view/helpers/rendering_helper.rb +1 -1
- data/lib/action_view/helpers/sanitize_helper.rb +33 -14
- data/lib/action_view/helpers/tag_helper.rb +5 -27
- data/lib/action_view/helpers/tags/base.rb +11 -52
- data/lib/action_view/helpers/tags/collection_check_boxes.rb +1 -0
- data/lib/action_view/helpers/tags/collection_radio_buttons.rb +1 -0
- data/lib/action_view/helpers/tags/collection_select.rb +3 -0
- data/lib/action_view/helpers/tags/date_field.rb +1 -1
- data/lib/action_view/helpers/tags/date_select.rb +2 -0
- data/lib/action_view/helpers/tags/datetime_field.rb +14 -6
- data/lib/action_view/helpers/tags/datetime_local_field.rb +11 -2
- data/lib/action_view/helpers/tags/grouped_collection_select.rb +3 -0
- data/lib/action_view/helpers/tags/month_field.rb +1 -1
- data/lib/action_view/helpers/tags/select.rb +3 -0
- data/lib/action_view/helpers/tags/select_renderer.rb +56 -0
- data/lib/action_view/helpers/tags/time_field.rb +1 -1
- data/lib/action_view/helpers/tags/time_zone_select.rb +3 -0
- data/lib/action_view/helpers/tags/week_field.rb +1 -1
- data/lib/action_view/helpers/tags/weekday_select.rb +3 -0
- data/lib/action_view/helpers/tags.rb +2 -0
- data/lib/action_view/helpers/text_helper.rb +32 -16
- data/lib/action_view/helpers/translation_helper.rb +3 -3
- data/lib/action_view/helpers/url_helper.rb +41 -14
- data/lib/action_view/helpers.rb +2 -0
- data/lib/action_view/layouts.rb +4 -2
- data/lib/action_view/log_subscriber.rb +49 -32
- data/lib/action_view/lookup_context.rb +29 -13
- data/lib/action_view/path_registry.rb +57 -0
- data/lib/action_view/path_set.rb +13 -14
- data/lib/action_view/railtie.rb +26 -3
- data/lib/action_view/record_identifier.rb +15 -8
- data/lib/action_view/renderer/abstract_renderer.rb +1 -1
- data/lib/action_view/renderer/collection_renderer.rb +9 -1
- data/lib/action_view/renderer/partial_renderer/collection_caching.rb +2 -1
- data/lib/action_view/renderer/partial_renderer.rb +2 -1
- data/lib/action_view/renderer/renderer.rb +2 -0
- data/lib/action_view/renderer/streaming_template_renderer.rb +3 -2
- data/lib/action_view/renderer/template_renderer.rb +3 -2
- data/lib/action_view/rendering.rb +22 -4
- data/lib/action_view/ripper_ast_parser.rb +6 -6
- data/lib/action_view/template/error.rb +14 -1
- data/lib/action_view/template/handlers/builder.rb +4 -4
- data/lib/action_view/template/handlers/erb/erubi.rb +23 -27
- data/lib/action_view/template/handlers/erb.rb +73 -1
- data/lib/action_view/template/handlers.rb +1 -1
- data/lib/action_view/template/html.rb +1 -1
- data/lib/action_view/template/raw_file.rb +1 -1
- data/lib/action_view/template/renderable.rb +1 -1
- data/lib/action_view/template/resolver.rb +10 -2
- data/lib/action_view/template/text.rb +1 -1
- data/lib/action_view/template/types.rb +25 -34
- data/lib/action_view/template.rb +179 -52
- data/lib/action_view/template_path.rb +2 -0
- data/lib/action_view/test_case.rb +8 -5
- data/lib/action_view/unbound_template.rb +15 -5
- data/lib/action_view/version.rb +1 -1
- data/lib/action_view/view_paths.rb +15 -24
- data/lib/action_view.rb +4 -1
- metadata +29 -29
@@ -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
|
-
|
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)
|
@@ -4,11 +4,14 @@ require "active_support/core_ext/module/attribute_accessors"
|
|
4
4
|
|
5
5
|
module ActionView
|
6
6
|
class Template # :nodoc:
|
7
|
-
|
8
|
-
|
9
|
-
|
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
|
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
|
-
|
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
|
-
|
41
|
-
attr_accessor :type_klass
|
27
|
+
attr_reader :symbol
|
42
28
|
|
43
|
-
|
44
|
-
|
45
|
-
|
29
|
+
def initialize(symbol)
|
30
|
+
@symbol = symbol.to_sym
|
31
|
+
end
|
46
32
|
|
47
|
-
|
48
|
-
|
49
|
-
|
33
|
+
def to_s
|
34
|
+
@symbol.to_s
|
35
|
+
end
|
36
|
+
alias to_str to_s
|
50
37
|
|
51
|
-
|
52
|
-
|
53
|
-
end
|
38
|
+
def ref
|
39
|
+
@symbol
|
54
40
|
end
|
41
|
+
alias to_sym ref
|
55
42
|
|
56
|
-
|
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
|
data/lib/action_view/template.rb
CHANGED
@@ -4,18 +4,20 @@ require "thread"
|
|
4
4
|
require "delegate"
|
5
5
|
|
6
6
|
module ActionView
|
7
|
-
# = Action View Template
|
7
|
+
# = Action View \Template
|
8
8
|
class Template
|
9
9
|
extend ActiveSupport::Autoload
|
10
10
|
|
11
|
+
STRICT_LOCALS_REGEX = /\#\s+locals:\s+\((.*)\)/
|
12
|
+
|
11
13
|
# === Encodings in ActionView::Template
|
12
14
|
#
|
13
15
|
# ActionView::Template is one of a few sources of potential
|
14
|
-
# encoding issues in Rails. This is because the source for
|
16
|
+
# encoding issues in \Rails. This is because the source for
|
15
17
|
# templates are usually read from disk, and Ruby (like most
|
16
18
|
# encoding-aware programming languages) assumes that the
|
17
19
|
# String retrieved through File IO is encoded in the
|
18
|
-
# <tt>default_external</tt> encoding. In Rails, the default
|
20
|
+
# <tt>default_external</tt> encoding. In \Rails, the default
|
19
21
|
# <tt>default_external</tt> encoding is UTF-8.
|
20
22
|
#
|
21
23
|
# As a result, if a user saves their template as ISO-8859-1
|
@@ -34,13 +36,13 @@ module ActionView
|
|
34
36
|
# to the problem.
|
35
37
|
# 2. The user can specify the encoding using Ruby-style
|
36
38
|
# encoding comments in any template engine. If such
|
37
|
-
# a comment is supplied, Rails will apply that encoding
|
39
|
+
# a comment is supplied, \Rails will apply that encoding
|
38
40
|
# to the resulting compiled source returned by the
|
39
41
|
# template handler.
|
40
42
|
# 3. In all cases, we transcode the resulting String to
|
41
43
|
# the UTF-8.
|
42
44
|
#
|
43
|
-
# This means that other parts of Rails can always assume
|
45
|
+
# This means that other parts of \Rails can always assume
|
44
46
|
# that templates are encoded in UTF-8, even if the original
|
45
47
|
# source of the template was not UTF-8.
|
46
48
|
#
|
@@ -51,7 +53,7 @@ module ActionView
|
|
51
53
|
# === Instructions for template handlers
|
52
54
|
#
|
53
55
|
# The easiest thing for you to do is to simply ignore
|
54
|
-
# encodings. Rails will hand you the template source
|
56
|
+
# encodings. \Rails will hand you the template source
|
55
57
|
# as the default_internal (generally UTF-8), raising
|
56
58
|
# an exception for the user before sending the template
|
57
59
|
# to you if it could not determine the original encoding.
|
@@ -68,7 +70,7 @@ module ActionView
|
|
68
70
|
# you may indicate that you will handle encodings yourself
|
69
71
|
# by implementing <tt>handles_encoding?</tt> on your handler.
|
70
72
|
#
|
71
|
-
# If you do, Rails will not try to encode the String
|
73
|
+
# If you do, \Rails will not try to encode the String
|
72
74
|
# into the default_internal, passing you the unaltered
|
73
75
|
# bytes tagged with the assumed encoding (from
|
74
76
|
# default_external).
|
@@ -107,6 +109,7 @@ module ActionView
|
|
107
109
|
autoload :Handlers
|
108
110
|
autoload :HTML
|
109
111
|
autoload :Inline
|
112
|
+
autoload :Types
|
110
113
|
autoload :Sources
|
111
114
|
autoload :Text
|
112
115
|
autoload :Types
|
@@ -117,11 +120,24 @@ module ActionView
|
|
117
120
|
singleton_class.attr_accessor :frozen_string_literal
|
118
121
|
@frozen_string_literal = false
|
119
122
|
|
123
|
+
class << self # :nodoc:
|
124
|
+
def mime_types_implementation=(implementation)
|
125
|
+
# This method isn't thread-safe, but it's not supposed
|
126
|
+
# to be called after initialization
|
127
|
+
if self::Types != implementation
|
128
|
+
remove_const(:Types)
|
129
|
+
const_set(:Types, implementation)
|
130
|
+
end
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
120
134
|
attr_reader :identifier, :handler
|
121
|
-
attr_reader :variable, :format, :variant, :
|
135
|
+
attr_reader :variable, :format, :variant, :virtual_path
|
136
|
+
|
137
|
+
NONE = Object.new
|
122
138
|
|
123
139
|
def initialize(source, identifier, handler, locals:, format: nil, variant: nil, virtual_path: nil)
|
124
|
-
@source = source
|
140
|
+
@source = source.dup
|
125
141
|
@identifier = identifier
|
126
142
|
@handler = handler
|
127
143
|
@compiled = false
|
@@ -137,6 +153,36 @@ module ActionView
|
|
137
153
|
@format = format
|
138
154
|
@variant = variant
|
139
155
|
@compile_mutex = Mutex.new
|
156
|
+
@strict_locals = NONE
|
157
|
+
@type = nil
|
158
|
+
end
|
159
|
+
|
160
|
+
# The locals this template has been or will be compiled for, or nil if this
|
161
|
+
# is a strict locals template.
|
162
|
+
def locals
|
163
|
+
if strict_locals?
|
164
|
+
nil
|
165
|
+
else
|
166
|
+
@locals
|
167
|
+
end
|
168
|
+
end
|
169
|
+
|
170
|
+
def spot(location) # :nodoc:
|
171
|
+
ast = RubyVM::AbstractSyntaxTree.parse(compiled_source, keep_script_lines: true)
|
172
|
+
node_id = RubyVM::AbstractSyntaxTree.node_id_for_backtrace_location(location)
|
173
|
+
node = find_node_by_id(ast, node_id)
|
174
|
+
|
175
|
+
ErrorHighlight.spot(node)
|
176
|
+
end
|
177
|
+
|
178
|
+
# Translate an error location returned by ErrorHighlight to the correct
|
179
|
+
# source location inside the template.
|
180
|
+
def translate_location(backtrace_location, spot)
|
181
|
+
if handler.respond_to?(:translate_location)
|
182
|
+
handler.translate_location(spot, backtrace_location, encode!) || spot
|
183
|
+
else
|
184
|
+
spot
|
185
|
+
end
|
140
186
|
end
|
141
187
|
|
142
188
|
# Returns whether the underlying handler supports streaming. If so,
|
@@ -151,10 +197,15 @@ module ActionView
|
|
151
197
|
# This method is instrumented as "!render_template.action_view". Notice that
|
152
198
|
# we use a bang in this instrumentation because you don't want to
|
153
199
|
# consume this in production. This is only slow if it's being listened to.
|
154
|
-
def render(view, locals, buffer =
|
200
|
+
def render(view, locals, buffer = nil, add_to_stack: true, &block)
|
155
201
|
instrument_render_template do
|
156
202
|
compile!(view)
|
157
|
-
|
203
|
+
if buffer
|
204
|
+
view._run(method_name, self, locals, buffer, add_to_stack: add_to_stack, has_strict_locals: strict_locals?, &block)
|
205
|
+
nil
|
206
|
+
else
|
207
|
+
view._run(method_name, self, locals, OutputBuffer.new, add_to_stack: add_to_stack, has_strict_locals: strict_locals?, &block)&.to_s
|
208
|
+
end
|
158
209
|
end
|
159
210
|
rescue => e
|
160
211
|
handle_render_error(view, e)
|
@@ -169,13 +220,16 @@ module ActionView
|
|
169
220
|
end
|
170
221
|
|
171
222
|
def inspect
|
172
|
-
"#<#{self.class.name} #{short_identifier} locals=#{
|
223
|
+
"#<#{self.class.name} #{short_identifier} locals=#{locals.inspect}>"
|
173
224
|
end
|
174
225
|
|
175
226
|
def source
|
176
227
|
@source.to_s
|
177
228
|
end
|
178
229
|
|
230
|
+
LEADING_ENCODING_REGEXP = /\A#{ENCODING_FLAG}/
|
231
|
+
private_constant :LEADING_ENCODING_REGEXP
|
232
|
+
|
179
233
|
# This method is responsible for properly setting the encoding of the
|
180
234
|
# source. Until this point, we assume that the source is BINARY data.
|
181
235
|
# If no additional information is supplied, we assume the encoding is
|
@@ -194,7 +248,7 @@ module ActionView
|
|
194
248
|
# Look for # encoding: *. If we find one, we'll encode the
|
195
249
|
# String in that encoding, otherwise, we'll use the
|
196
250
|
# default external encoding.
|
197
|
-
if source.sub!(
|
251
|
+
if source.sub!(LEADING_ENCODING_REGEXP, "")
|
198
252
|
encoding = magic_encoding = $1
|
199
253
|
else
|
200
254
|
encoding = Encoding.default_external
|
@@ -222,6 +276,32 @@ module ActionView
|
|
222
276
|
end
|
223
277
|
end
|
224
278
|
|
279
|
+
# This method is responsible for marking a template as having strict locals
|
280
|
+
# which means the template can only accept the locals defined in a magic
|
281
|
+
# comment. For example, if your template acceps the locals +title+ and
|
282
|
+
# +comment_count+, add the following to your template file:
|
283
|
+
#
|
284
|
+
# <%# locals: (title: "Default title", comment_count: 0) %>
|
285
|
+
#
|
286
|
+
# Strict locals are useful for validating template arguments and for
|
287
|
+
# specifying defaults.
|
288
|
+
def strict_locals!
|
289
|
+
if @strict_locals == NONE
|
290
|
+
self.source.sub!(STRICT_LOCALS_REGEX, "")
|
291
|
+
@strict_locals = $1
|
292
|
+
|
293
|
+
return if @strict_locals.nil? # Magic comment not found
|
294
|
+
|
295
|
+
@strict_locals = "**nil" if @strict_locals.blank?
|
296
|
+
end
|
297
|
+
|
298
|
+
@strict_locals
|
299
|
+
end
|
300
|
+
|
301
|
+
# Returns whether a template is using strict locals.
|
302
|
+
def strict_locals?
|
303
|
+
strict_locals!
|
304
|
+
end
|
225
305
|
|
226
306
|
# Exceptions are marshalled when using the parallel test runner with DRb, so we need
|
227
307
|
# to ensure that references to the template object can be marshalled as well. This means forgoing
|
@@ -235,7 +315,26 @@ module ActionView
|
|
235
315
|
@compile_mutex = Mutex.new
|
236
316
|
end
|
237
317
|
|
318
|
+
def method_name # :nodoc:
|
319
|
+
@method_name ||= begin
|
320
|
+
m = +"_#{identifier_method_name}__#{@identifier.hash}_#{__id__}"
|
321
|
+
m.tr!("-", "_")
|
322
|
+
m
|
323
|
+
end
|
324
|
+
end
|
325
|
+
|
238
326
|
private
|
327
|
+
def find_node_by_id(node, node_id)
|
328
|
+
return node if node.node_id == node_id
|
329
|
+
|
330
|
+
node.children.grep(node.class).each do |child|
|
331
|
+
found = find_node_by_id(child, node_id)
|
332
|
+
return found if found
|
333
|
+
end
|
334
|
+
|
335
|
+
false
|
336
|
+
end
|
337
|
+
|
239
338
|
# Compile a template. This method ensures a template is compiled
|
240
339
|
# just once and removes the source after it is compiled.
|
241
340
|
def compile!(view)
|
@@ -260,27 +359,25 @@ module ActionView
|
|
260
359
|
end
|
261
360
|
end
|
262
361
|
|
263
|
-
#
|
264
|
-
#
|
265
|
-
#
|
266
|
-
|
267
|
-
|
268
|
-
# the template engine to support additional mechanisms for
|
269
|
-
# specifying the encoding. For instance, ERB supports <%# encoding: %>
|
270
|
-
#
|
271
|
-
# Otherwise, after we figure out the correct encoding, we then
|
272
|
-
# encode the source into <tt>Encoding.default_internal</tt>.
|
273
|
-
# In general, this means that templates will be UTF-8 inside of Rails,
|
274
|
-
# regardless of the original source encoding.
|
275
|
-
def compile(mod)
|
362
|
+
# This method compiles the source of the template. The compilation of templates
|
363
|
+
# involves setting strict_locals! if applicable, encoding the template, and setting
|
364
|
+
# frozen string literal.
|
365
|
+
def compiled_source
|
366
|
+
set_strict_locals = strict_locals!
|
276
367
|
source = encode!
|
277
368
|
code = @handler.call(self, source)
|
278
369
|
|
370
|
+
method_arguments =
|
371
|
+
if set_strict_locals
|
372
|
+
"output_buffer, #{set_strict_locals}"
|
373
|
+
else
|
374
|
+
"local_assigns, output_buffer"
|
375
|
+
end
|
376
|
+
|
279
377
|
# Make sure that the resulting String to be eval'd is in the
|
280
378
|
# encoding of the code
|
281
|
-
original_source = source
|
282
379
|
source = +<<-end_src
|
283
|
-
def #{method_name}(
|
380
|
+
def #{method_name}(#{method_arguments})
|
284
381
|
@virtual_path = #{@virtual_path.inspect};#{locals_code};#{code}
|
285
382
|
end
|
286
383
|
end_src
|
@@ -299,17 +396,61 @@ module ActionView
|
|
299
396
|
raise WrongEncodingError.new(source, Encoding.default_internal)
|
300
397
|
end
|
301
398
|
|
399
|
+
if Template.frozen_string_literal
|
400
|
+
"# frozen_string_literal: true\n#{source}"
|
401
|
+
else
|
402
|
+
source
|
403
|
+
end
|
404
|
+
end
|
405
|
+
|
406
|
+
# Among other things, this method is responsible for properly setting
|
407
|
+
# the encoding of the compiled template.
|
408
|
+
#
|
409
|
+
# If the template engine handles encodings, we send the encoded
|
410
|
+
# String to the engine without further processing. This allows
|
411
|
+
# the template engine to support additional mechanisms for
|
412
|
+
# specifying the encoding. For instance, ERB supports <%# encoding: %>
|
413
|
+
#
|
414
|
+
# Otherwise, after we figure out the correct encoding, we then
|
415
|
+
# encode the source into <tt>Encoding.default_internal</tt>.
|
416
|
+
# In general, this means that templates will be UTF-8 inside of Rails,
|
417
|
+
# regardless of the original source encoding.
|
418
|
+
def compile(mod)
|
302
419
|
begin
|
303
|
-
|
304
|
-
mod.module_eval("# frozen_string_literal: true\n#{source}", identifier, -1)
|
305
|
-
else
|
306
|
-
mod.module_eval(source, identifier, 0)
|
307
|
-
end
|
420
|
+
mod.module_eval(compiled_source, identifier, offset)
|
308
421
|
rescue SyntaxError
|
309
422
|
# Account for when code in the template is not syntactically valid; e.g. if we're using
|
310
423
|
# ERB and the user writes <%= foo( %>, attempting to call a helper `foo` and interpolate
|
311
424
|
# the result into the template, but missing an end parenthesis.
|
312
|
-
raise SyntaxErrorInTemplate.new(self,
|
425
|
+
raise SyntaxErrorInTemplate.new(self, encode!)
|
426
|
+
end
|
427
|
+
|
428
|
+
return unless strict_locals?
|
429
|
+
|
430
|
+
# Check compiled method parameters to ensure that only kwargs
|
431
|
+
# were provided as strict locals, preventing `locals: (foo, *foo)` etc
|
432
|
+
# and allowing `locals: (foo:)`.
|
433
|
+
|
434
|
+
non_kwarg_parameters =
|
435
|
+
(mod.instance_method(method_name).parameters - [[:req, :output_buffer]]).
|
436
|
+
select { |parameter| ![:keyreq, :key, :keyrest, :nokey].include?(parameter[0]) }
|
437
|
+
|
438
|
+
return unless non_kwarg_parameters.any?
|
439
|
+
|
440
|
+
mod.undef_method(method_name)
|
441
|
+
|
442
|
+
raise ArgumentError.new(
|
443
|
+
"#{non_kwarg_parameters.map { |_, name| "`#{name}`" }.to_sentence} set as non-keyword " \
|
444
|
+
"#{'argument'.pluralize(non_kwarg_parameters.length)} for #{short_identifier}. " \
|
445
|
+
"Locals can only be set as keyword arguments."
|
446
|
+
)
|
447
|
+
end
|
448
|
+
|
449
|
+
def offset
|
450
|
+
if Template.frozen_string_literal
|
451
|
+
-1
|
452
|
+
else
|
453
|
+
0
|
313
454
|
end
|
314
455
|
end
|
315
456
|
|
@@ -323,32 +464,18 @@ module ActionView
|
|
323
464
|
end
|
324
465
|
|
325
466
|
def locals_code
|
467
|
+
return "" if strict_locals?
|
468
|
+
|
326
469
|
# Only locals with valid variable names get set directly. Others will
|
327
470
|
# still be available in local_assigns.
|
328
471
|
locals = @locals - Module::RUBY_RESERVED_KEYWORDS
|
329
|
-
|
330
|
-
|
331
|
-
ActiveSupport::Deprecation.warn(<<~MSG)
|
332
|
-
Passing instance variables to `render` is deprecated.
|
333
|
-
In Rails 7.1, #{deprecated_locals.to_sentence} will be ignored.
|
334
|
-
MSG
|
335
|
-
locals = locals.grep(/\A@?(?![A-Z0-9])(?:[[:alnum:]_]|[^\0-\177])+\z/)
|
336
|
-
else
|
337
|
-
locals = locals.grep(/\A(?![A-Z0-9])(?:[[:alnum:]_]|[^\0-\177])+\z/)
|
338
|
-
end
|
472
|
+
|
473
|
+
locals = locals.grep(/\A(?![A-Z0-9])(?:[[:alnum:]_]|[^\0-\177])+\z/)
|
339
474
|
|
340
475
|
# Assign for the same variable is to suppress unused variable warning
|
341
476
|
locals.each_with_object(+"") { |key, code| code << "#{key} = local_assigns[:#{key}]; #{key} = #{key};" }
|
342
477
|
end
|
343
478
|
|
344
|
-
def method_name
|
345
|
-
@method_name ||= begin
|
346
|
-
m = +"_#{identifier_method_name}__#{@identifier.hash}_#{__id__}"
|
347
|
-
m.tr!("-", "_")
|
348
|
-
m
|
349
|
-
end
|
350
|
-
end
|
351
|
-
|
352
479
|
def identifier_method_name
|
353
480
|
short_identifier.tr("^a-z_", "_")
|
354
481
|
end
|
@@ -110,9 +110,7 @@ module ActionView
|
|
110
110
|
@controller = controller_class.new
|
111
111
|
@request = @controller.request
|
112
112
|
@view_flow = ActionView::OutputFlow.new
|
113
|
-
|
114
|
-
# new without arguments returns ASCII-8BIT encoded buffer like String#new
|
115
|
-
@output_buffer = ActiveSupport::SafeBuffer.new ""
|
113
|
+
@output_buffer = ActionView::OutputBuffer.new
|
116
114
|
@rendered = +""
|
117
115
|
|
118
116
|
test_case_instance = self
|
@@ -181,7 +179,7 @@ module ActionView
|
|
181
179
|
private
|
182
180
|
# Need to experiment if this priority is the best one: rendered => output_buffer
|
183
181
|
def document_root_element
|
184
|
-
|
182
|
+
Rails::Dom::Testing.html_document.parse(@rendered.blank? ? @output_buffer.to_str : @rendered).root
|
185
183
|
end
|
186
184
|
|
187
185
|
module Locals
|
@@ -227,6 +225,10 @@ module ActionView
|
|
227
225
|
:@_result,
|
228
226
|
:@_routes,
|
229
227
|
:@controller,
|
228
|
+
:@_controller,
|
229
|
+
:@_request,
|
230
|
+
:@_config,
|
231
|
+
:@_default_form_builder,
|
230
232
|
:@_layouts,
|
231
233
|
:@_files,
|
232
234
|
:@_rendered_views,
|
@@ -245,7 +247,7 @@ module ActionView
|
|
245
247
|
:@view_context_class,
|
246
248
|
:@view_flow,
|
247
249
|
:@_subscribers,
|
248
|
-
:@html_document
|
250
|
+
:@html_document,
|
249
251
|
]
|
250
252
|
|
251
253
|
def _user_defined_ivars
|
@@ -277,6 +279,7 @@ module ActionView
|
|
277
279
|
super
|
278
280
|
end
|
279
281
|
end
|
282
|
+
ruby2_keywords(:method_missing)
|
280
283
|
|
281
284
|
def respond_to_missing?(name, include_private = false)
|
282
285
|
begin
|
@@ -18,21 +18,31 @@ module ActionView
|
|
18
18
|
end
|
19
19
|
|
20
20
|
def bind_locals(locals)
|
21
|
-
|
22
|
-
template
|
23
|
-
else
|
21
|
+
unless template = @templates[locals]
|
24
22
|
@write_lock.synchronize do
|
25
23
|
normalized_locals = normalize_locals(locals)
|
26
24
|
|
27
25
|
# We need ||=, both to dedup on the normalized locals and to check
|
28
26
|
# while holding the lock.
|
29
|
-
@templates[normalized_locals] ||= build_template(normalized_locals)
|
27
|
+
template = (@templates[normalized_locals] ||= build_template(normalized_locals))
|
30
28
|
|
31
29
|
# This may have already been assigned, but we've already de-dup'd so
|
32
30
|
# reassignment is fine.
|
33
|
-
@templates[locals.dup] =
|
31
|
+
@templates[locals.dup] = template
|
32
|
+
|
33
|
+
if template.strict_locals?
|
34
|
+
# Under strict locals, we only need one template.
|
35
|
+
# This replaces the @templates Concurrent::Map with a hash which
|
36
|
+
# returns this template for every key.
|
37
|
+
@templates = Hash.new(template).freeze
|
38
|
+
end
|
34
39
|
end
|
35
40
|
end
|
41
|
+
template
|
42
|
+
end
|
43
|
+
|
44
|
+
def built_templates # :nodoc:
|
45
|
+
@templates.values
|
36
46
|
end
|
37
47
|
|
38
48
|
private
|
data/lib/action_view/version.rb
CHANGED