actionview 7.0.8.3 → 7.1.0.beta1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +235 -372
- 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 +5 -5
- 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 +26 -26
@@ -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