actionview 5.2.8.1 → 6.0.6.1
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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +280 -94
- data/MIT-LICENSE +1 -1
- data/README.rdoc +5 -3
- data/lib/action_view/base.rb +108 -11
- data/lib/action_view/buffers.rb +15 -0
- data/lib/action_view/cache_expiry.rb +53 -0
- data/lib/action_view/context.rb +5 -9
- data/lib/action_view/digestor.rb +12 -20
- data/lib/action_view/flows.rb +0 -1
- data/lib/action_view/gem_version.rb +3 -3
- data/lib/action_view/helpers/active_model_helper.rb +0 -1
- data/lib/action_view/helpers/asset_tag_helper.rb +8 -31
- data/lib/action_view/helpers/asset_url_helper.rb +4 -3
- data/lib/action_view/helpers/cache_helper.rb +19 -12
- data/lib/action_view/helpers/capture_helper.rb +4 -0
- data/lib/action_view/helpers/csp_helper.rb +4 -2
- data/lib/action_view/helpers/csrf_helper.rb +1 -1
- data/lib/action_view/helpers/date_helper.rb +70 -27
- data/lib/action_view/helpers/form_helper.rb +240 -8
- data/lib/action_view/helpers/form_options_helper.rb +27 -18
- data/lib/action_view/helpers/form_tag_helper.rb +17 -15
- data/lib/action_view/helpers/javascript_helper.rb +9 -8
- data/lib/action_view/helpers/number_helper.rb +8 -2
- data/lib/action_view/helpers/output_safety_helper.rb +1 -1
- data/lib/action_view/helpers/rendering_helper.rb +6 -4
- data/lib/action_view/helpers/sanitize_helper.rb +12 -18
- data/lib/action_view/helpers/tag_helper.rb +8 -7
- data/lib/action_view/helpers/tags/base.rb +9 -6
- data/lib/action_view/helpers/tags/check_box.rb +0 -1
- data/lib/action_view/helpers/tags/collection_check_boxes.rb +0 -1
- data/lib/action_view/helpers/tags/collection_helpers.rb +0 -1
- data/lib/action_view/helpers/tags/collection_radio_buttons.rb +0 -1
- data/lib/action_view/helpers/tags/color_field.rb +1 -2
- data/lib/action_view/helpers/tags/date_field.rb +0 -1
- data/lib/action_view/helpers/tags/date_select.rb +0 -1
- data/lib/action_view/helpers/tags/datetime_field.rb +0 -1
- data/lib/action_view/helpers/tags/datetime_local_field.rb +0 -1
- data/lib/action_view/helpers/tags/label.rb +0 -1
- data/lib/action_view/helpers/tags/month_field.rb +0 -1
- data/lib/action_view/helpers/tags/radio_button.rb +0 -1
- data/lib/action_view/helpers/tags/select.rb +0 -1
- data/lib/action_view/helpers/tags/text_field.rb +0 -1
- data/lib/action_view/helpers/tags/time_field.rb +0 -1
- data/lib/action_view/helpers/tags/translator.rb +1 -6
- data/lib/action_view/helpers/tags/week_field.rb +0 -1
- data/lib/action_view/helpers/text_helper.rb +3 -4
- data/lib/action_view/helpers/translation_helper.rb +19 -17
- data/lib/action_view/helpers/url_helper.rb +14 -14
- data/lib/action_view/helpers.rb +0 -2
- data/lib/action_view/layouts.rb +5 -8
- data/lib/action_view/log_subscriber.rb +6 -7
- data/lib/action_view/lookup_context.rb +75 -32
- data/lib/action_view/path_set.rb +5 -11
- data/lib/action_view/railtie.rb +24 -1
- data/lib/action_view/record_identifier.rb +2 -3
- data/lib/action_view/renderer/abstract_renderer.rb +56 -4
- data/lib/action_view/renderer/partial_renderer/collection_caching.rb +63 -17
- data/lib/action_view/renderer/partial_renderer.rb +67 -57
- data/lib/action_view/renderer/renderer.rb +16 -4
- data/lib/action_view/renderer/streaming_template_renderer.rb +5 -7
- data/lib/action_view/renderer/template_renderer.rb +25 -20
- data/lib/action_view/rendering.rb +51 -32
- data/lib/action_view/routing_url_for.rb +12 -11
- data/lib/action_view/template/error.rb +30 -15
- data/lib/action_view/template/handlers/builder.rb +2 -2
- data/lib/action_view/template/handlers/erb/erubi.rb +7 -3
- data/lib/action_view/template/handlers/erb.rb +17 -8
- data/lib/action_view/template/handlers/html.rb +1 -1
- data/lib/action_view/template/handlers/raw.rb +2 -2
- data/lib/action_view/template/handlers.rb +27 -1
- data/lib/action_view/template/html.rb +14 -5
- data/lib/action_view/template/inline.rb +22 -0
- data/lib/action_view/template/raw_file.rb +28 -0
- data/lib/action_view/template/resolver.rb +134 -135
- data/lib/action_view/template/sources/file.rb +17 -0
- data/lib/action_view/template/sources.rb +13 -0
- data/lib/action_view/template/text.rb +5 -3
- data/lib/action_view/template.rb +102 -71
- data/lib/action_view/test_case.rb +3 -4
- data/lib/action_view/testing/resolvers.rb +33 -21
- data/lib/action_view/unbound_template.rb +31 -0
- data/lib/action_view/view_paths.rb +25 -2
- data/lib/action_view.rb +4 -2
- data/lib/assets/compiled/rails-ujs.js +30 -4
- metadata +27 -18
- data/lib/action_view/helpers/record_tag_helper.rb +0 -23
data/lib/action_view/template.rb
CHANGED
@@ -2,13 +2,23 @@
|
|
2
2
|
|
3
3
|
require "active_support/core_ext/object/try"
|
4
4
|
require "active_support/core_ext/kernel/singleton_class"
|
5
|
+
require "active_support/deprecation"
|
5
6
|
require "thread"
|
7
|
+
require "delegate"
|
6
8
|
|
7
9
|
module ActionView
|
8
10
|
# = Action View Template
|
9
11
|
class Template
|
10
12
|
extend ActiveSupport::Autoload
|
11
13
|
|
14
|
+
def self.finalize_compiled_template_methods
|
15
|
+
ActiveSupport::Deprecation.warn "ActionView::Template.finalize_compiled_template_methods is deprecated and has no effect"
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.finalize_compiled_template_methods=(_)
|
19
|
+
ActiveSupport::Deprecation.warn "ActionView::Template.finalize_compiled_template_methods= is deprecated and has no effect"
|
20
|
+
end
|
21
|
+
|
12
22
|
# === Encodings in ActionView::Template
|
13
23
|
#
|
14
24
|
# ActionView::Template is one of a few sources of potential
|
@@ -103,44 +113,60 @@ module ActionView
|
|
103
113
|
|
104
114
|
eager_autoload do
|
105
115
|
autoload :Error
|
116
|
+
autoload :RawFile
|
106
117
|
autoload :Handlers
|
107
118
|
autoload :HTML
|
119
|
+
autoload :Inline
|
120
|
+
autoload :Sources
|
108
121
|
autoload :Text
|
109
122
|
autoload :Types
|
110
123
|
end
|
111
124
|
|
112
125
|
extend Template::Handlers
|
113
126
|
|
114
|
-
|
115
|
-
|
116
|
-
attr_reader :source, :identifier, :handler, :original_encoding, :updated_at
|
127
|
+
attr_reader :identifier, :handler, :original_encoding, :updated_at
|
128
|
+
attr_reader :variable, :format, :variant, :locals, :virtual_path
|
117
129
|
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
mod.module_eval do
|
123
|
-
remove_possible_method method_name
|
124
|
-
end
|
130
|
+
def initialize(source, identifier, handler, format: nil, variant: nil, locals: nil, virtual_path: nil, updated_at: nil)
|
131
|
+
unless locals
|
132
|
+
ActiveSupport::Deprecation.warn "ActionView::Template#initialize requires a locals parameter"
|
133
|
+
locals = []
|
125
134
|
end
|
126
|
-
end
|
127
|
-
|
128
|
-
def initialize(source, identifier, handler, details)
|
129
|
-
format = details[:format] || (handler.default_format if handler.respond_to?(:default_format))
|
130
135
|
|
131
136
|
@source = source
|
132
137
|
@identifier = identifier
|
133
138
|
@handler = handler
|
134
139
|
@compiled = false
|
135
|
-
@
|
136
|
-
@
|
137
|
-
|
138
|
-
@
|
139
|
-
|
140
|
-
|
140
|
+
@locals = locals
|
141
|
+
@virtual_path = virtual_path
|
142
|
+
|
143
|
+
@variable = if @virtual_path
|
144
|
+
base = @virtual_path[-1] == "/" ? "" : ::File.basename(@virtual_path)
|
145
|
+
base =~ /\A_?(.*?)(?:\.\w+)*\z/
|
146
|
+
$1.to_sym
|
147
|
+
end
|
148
|
+
|
149
|
+
if updated_at
|
150
|
+
ActiveSupport::Deprecation.warn "ActionView::Template#updated_at is deprecated"
|
151
|
+
@updated_at = updated_at
|
152
|
+
else
|
153
|
+
@updated_at = Time.now
|
154
|
+
end
|
155
|
+
@format = format
|
156
|
+
@variant = variant
|
141
157
|
@compile_mutex = Mutex.new
|
142
158
|
end
|
143
159
|
|
160
|
+
deprecate :original_encoding
|
161
|
+
deprecate :updated_at
|
162
|
+
deprecate def virtual_path=(_); end
|
163
|
+
deprecate def locals=(_); end
|
164
|
+
deprecate def formats=(_); end
|
165
|
+
deprecate def formats; Array(format); end
|
166
|
+
deprecate def variants=(_); end
|
167
|
+
deprecate def variants; [variant]; end
|
168
|
+
deprecate def refresh(_); self; end
|
169
|
+
|
144
170
|
# Returns whether the underlying handler supports streaming. If so,
|
145
171
|
# a streaming buffer *may* be passed when it starts rendering.
|
146
172
|
def supports_streaming?
|
@@ -153,40 +179,29 @@ module ActionView
|
|
153
179
|
# This method is instrumented as "!render_template.action_view". Notice that
|
154
180
|
# we use a bang in this instrumentation because you don't want to
|
155
181
|
# consume this in production. This is only slow if it's being listened to.
|
156
|
-
def render(view, locals, buffer =
|
182
|
+
def render(view, locals, buffer = ActionView::OutputBuffer.new, &block)
|
157
183
|
instrument_render_template do
|
158
184
|
compile!(view)
|
159
|
-
view.
|
185
|
+
view._run(method_name, self, locals, buffer, &block)
|
160
186
|
end
|
161
187
|
rescue => e
|
162
188
|
handle_render_error(view, e)
|
163
189
|
end
|
164
190
|
|
165
191
|
def type
|
166
|
-
@type ||= Types[
|
192
|
+
@type ||= Types[format]
|
167
193
|
end
|
168
194
|
|
169
|
-
|
170
|
-
|
171
|
-
# This method is useful if you have a template object but it does not contain its source
|
172
|
-
# anymore since it was already compiled. In such cases, all you need to do is to call
|
173
|
-
# refresh passing in the view object.
|
174
|
-
#
|
175
|
-
# Notice this method raises an error if the template to be refreshed does not have a
|
176
|
-
# virtual path set (true just for inline templates).
|
177
|
-
def refresh(view)
|
178
|
-
raise "A template needs to have a virtual path in order to be refreshed" unless @virtual_path
|
179
|
-
lookup = view.lookup_context
|
180
|
-
pieces = @virtual_path.split("/")
|
181
|
-
name = pieces.pop
|
182
|
-
partial = !!name.sub!(/^_/, "")
|
183
|
-
lookup.disable_cache do
|
184
|
-
lookup.find_template(name, [ pieces.join("/") ], partial, @locals)
|
185
|
-
end
|
195
|
+
def short_identifier
|
196
|
+
@short_identifier ||= defined?(Rails.root) ? identifier.sub("#{Rails.root}/", "") : identifier
|
186
197
|
end
|
187
198
|
|
188
199
|
def inspect
|
189
|
-
|
200
|
+
"#<#{self.class.name} #{short_identifier} locals=#{@locals.inspect}>"
|
201
|
+
end
|
202
|
+
|
203
|
+
def source
|
204
|
+
@source.to_s
|
190
205
|
end
|
191
206
|
|
192
207
|
# This method is responsible for properly setting the encoding of the
|
@@ -200,7 +215,9 @@ module ActionView
|
|
200
215
|
# before passing the source on to the template engine, leaving a
|
201
216
|
# blank line in its stead.
|
202
217
|
def encode!
|
203
|
-
|
218
|
+
source = self.source
|
219
|
+
|
220
|
+
return source unless source.encoding == Encoding::BINARY
|
204
221
|
|
205
222
|
# Look for # encoding: *. If we find one, we'll encode the
|
206
223
|
# String in that encoding, otherwise, we'll use the
|
@@ -233,8 +250,20 @@ module ActionView
|
|
233
250
|
end
|
234
251
|
end
|
235
252
|
|
236
|
-
private
|
237
253
|
|
254
|
+
# Exceptions are marshalled when using the parallel test runner with DRb, so we need
|
255
|
+
# to ensure that references to the template object can be marshalled as well. This means forgoing
|
256
|
+
# the marshalling of the compiler mutex and instantiating that again on unmarshalling.
|
257
|
+
def marshal_dump # :nodoc:
|
258
|
+
[ @source, @identifier, @handler, @compiled, @locals, @virtual_path, @updated_at, @format, @variant ]
|
259
|
+
end
|
260
|
+
|
261
|
+
def marshal_load(array) # :nodoc:
|
262
|
+
@source, @identifier, @handler, @compiled, @locals, @virtual_path, @updated_at, @format, @variant = *array
|
263
|
+
@compile_mutex = Mutex.new
|
264
|
+
end
|
265
|
+
|
266
|
+
private
|
238
267
|
# Compile a template. This method ensures a template is compiled
|
239
268
|
# just once and removes the source after it is compiled.
|
240
269
|
def compile!(view)
|
@@ -249,23 +278,25 @@ module ActionView
|
|
249
278
|
# re-compilation
|
250
279
|
return if @compiled
|
251
280
|
|
252
|
-
|
253
|
-
mod = ActionView::CompiledTemplates
|
254
|
-
else
|
255
|
-
mod = view.singleton_class
|
256
|
-
end
|
281
|
+
mod = view.compiled_method_container
|
257
282
|
|
258
283
|
instrument("!compile_template") do
|
259
284
|
compile(mod)
|
260
285
|
end
|
261
286
|
|
262
|
-
# Just discard the source if we have a virtual path. This
|
263
|
-
# means we can get the template back.
|
264
|
-
@source = nil if @virtual_path
|
265
287
|
@compiled = true
|
266
288
|
end
|
267
289
|
end
|
268
290
|
|
291
|
+
class LegacyTemplate < DelegateClass(Template) # :nodoc:
|
292
|
+
attr_reader :source
|
293
|
+
|
294
|
+
def initialize(template, source)
|
295
|
+
super(template)
|
296
|
+
@source = source
|
297
|
+
end
|
298
|
+
end
|
299
|
+
|
269
300
|
# Among other things, this method is responsible for properly setting
|
270
301
|
# the encoding of the compiled template.
|
271
302
|
#
|
@@ -279,16 +310,15 @@ module ActionView
|
|
279
310
|
# In general, this means that templates will be UTF-8 inside of Rails,
|
280
311
|
# regardless of the original source encoding.
|
281
312
|
def compile(mod)
|
282
|
-
encode!
|
283
|
-
code = @handler.call(self)
|
313
|
+
source = encode!
|
314
|
+
code = @handler.call(self, source)
|
284
315
|
|
285
316
|
# Make sure that the resulting String to be eval'd is in the
|
286
317
|
# encoding of the code
|
287
|
-
|
318
|
+
original_source = source
|
319
|
+
source = +<<-end_src
|
288
320
|
def #{method_name}(local_assigns, output_buffer)
|
289
|
-
|
290
|
-
ensure
|
291
|
-
@virtual_path, @output_buffer = _old_virtual_path, _old_output_buffer
|
321
|
+
@virtual_path = #{@virtual_path.inspect};#{locals_code};#{code}
|
292
322
|
end
|
293
323
|
end_src
|
294
324
|
|
@@ -303,11 +333,17 @@ module ActionView
|
|
303
333
|
# handler is valid in the default_internal. This is for handlers
|
304
334
|
# that handle encoding but screw up
|
305
335
|
unless source.valid_encoding?
|
306
|
-
raise WrongEncodingError.new(
|
336
|
+
raise WrongEncodingError.new(source, Encoding.default_internal)
|
307
337
|
end
|
308
338
|
|
309
|
-
|
310
|
-
|
339
|
+
begin
|
340
|
+
mod.module_eval(source, identifier, 0)
|
341
|
+
rescue SyntaxError
|
342
|
+
# Account for when code in the template is not syntactically valid; e.g. if we're using
|
343
|
+
# ERB and the user writes <%= foo( %>, attempting to call a helper `foo` and interpolate
|
344
|
+
# the result into the template, but missing an end parenthesis.
|
345
|
+
raise SyntaxErrorInTemplate.new(self, original_source)
|
346
|
+
end
|
311
347
|
end
|
312
348
|
|
313
349
|
def handle_render_error(view, e)
|
@@ -315,12 +351,7 @@ module ActionView
|
|
315
351
|
e.sub_template_of(self)
|
316
352
|
raise e
|
317
353
|
else
|
318
|
-
|
319
|
-
unless template.source
|
320
|
-
template = refresh(view)
|
321
|
-
template.encode!
|
322
|
-
end
|
323
|
-
raise Template::Error.new(template)
|
354
|
+
raise Template::Error.new(self)
|
324
355
|
end
|
325
356
|
end
|
326
357
|
|
@@ -331,19 +362,19 @@ module ActionView
|
|
331
362
|
locals = locals.grep(/\A@?(?![A-Z0-9])(?:[[:alnum:]_]|[^\0-\177])+\z/)
|
332
363
|
|
333
364
|
# Assign for the same variable is to suppress unused variable warning
|
334
|
-
locals.each_with_object(""
|
365
|
+
locals.each_with_object(+"") { |key, code| code << "#{key} = local_assigns[:#{key}]; #{key} = #{key};" }
|
335
366
|
end
|
336
367
|
|
337
368
|
def method_name
|
338
369
|
@method_name ||= begin
|
339
|
-
m = "_#{identifier_method_name}__#{@identifier.hash}_#{__id__}"
|
340
|
-
m.tr!("-"
|
370
|
+
m = +"_#{identifier_method_name}__#{@identifier.hash}_#{__id__}"
|
371
|
+
m.tr!("-", "_")
|
341
372
|
m
|
342
373
|
end
|
343
374
|
end
|
344
375
|
|
345
376
|
def identifier_method_name
|
346
|
-
|
377
|
+
short_identifier.tr("^a-z_", "_")
|
347
378
|
end
|
348
379
|
|
349
380
|
def instrument(action, &block) # :doc:
|
@@ -351,7 +382,7 @@ module ActionView
|
|
351
382
|
end
|
352
383
|
|
353
384
|
def instrument_render_template(&block)
|
354
|
-
ActiveSupport::Notifications.instrument("!render_template.action_view"
|
385
|
+
ActiveSupport::Notifications.instrument("!render_template.action_view", instrument_payload, &block)
|
355
386
|
end
|
356
387
|
|
357
388
|
def instrument_payload
|
@@ -75,8 +75,9 @@ module ActionView
|
|
75
75
|
methods.flatten.each do |method|
|
76
76
|
_helpers.module_eval <<-end_eval, __FILE__, __LINE__ + 1
|
77
77
|
def #{method}(*args, &block) # def current_user(*args, &block)
|
78
|
-
_test_case.send(
|
78
|
+
_test_case.send(:'#{method}', *args, &block) # _test_case.send(:'current_user', *args, &block)
|
79
79
|
end # end
|
80
|
+
ruby2_keywords(:'#{method}') if respond_to?(:ruby2_keywords, true)
|
80
81
|
end_eval
|
81
82
|
end
|
82
83
|
end
|
@@ -93,7 +94,6 @@ module ActionView
|
|
93
94
|
end
|
94
95
|
|
95
96
|
private
|
96
|
-
|
97
97
|
def include_helper_modules!
|
98
98
|
helper(helper_class) if helper_class
|
99
99
|
include _helpers
|
@@ -107,7 +107,7 @@ module ActionView
|
|
107
107
|
# empty string ensures buffer has UTF-8 encoding as
|
108
108
|
# new without arguments returns ASCII-8BIT encoded buffer like String#new
|
109
109
|
@output_buffer = ActiveSupport::SafeBuffer.new ""
|
110
|
-
@rendered = ""
|
110
|
+
@rendered = +""
|
111
111
|
|
112
112
|
make_test_case_available_to_view!
|
113
113
|
say_no_to_protect_against_forgery!
|
@@ -163,7 +163,6 @@ module ActionView
|
|
163
163
|
end
|
164
164
|
|
165
165
|
private
|
166
|
-
|
167
166
|
# Need to experiment if this priority is the best one: rendered => output_buffer
|
168
167
|
def document_root_element
|
169
168
|
Nokogiri::HTML::Document.parse(@rendered.blank? ? @output_buffer : @rendered).root
|
@@ -7,12 +7,19 @@ module ActionView #:nodoc:
|
|
7
7
|
# file system. This is used internally by Rails' own test suite, and is
|
8
8
|
# useful for testing extensions that have no way of knowing what the file
|
9
9
|
# system will look like at runtime.
|
10
|
-
class FixtureResolver <
|
11
|
-
attr_reader :hash
|
12
|
-
|
10
|
+
class FixtureResolver < OptimizedFileSystemResolver
|
13
11
|
def initialize(hash = {}, pattern = nil)
|
14
|
-
super(
|
12
|
+
super("")
|
13
|
+
if pattern
|
14
|
+
ActiveSupport::Deprecation.warn "Specifying a custom path for #{self.class} is deprecated. Implement a custom Resolver subclass instead."
|
15
|
+
@pattern = pattern
|
16
|
+
end
|
15
17
|
@hash = hash
|
18
|
+
@path = ""
|
19
|
+
end
|
20
|
+
|
21
|
+
def data
|
22
|
+
@hash
|
16
23
|
end
|
17
24
|
|
18
25
|
def to_s
|
@@ -20,35 +27,40 @@ module ActionView #:nodoc:
|
|
20
27
|
end
|
21
28
|
|
22
29
|
private
|
30
|
+
def query(path, exts, _, locals, cache:)
|
31
|
+
regex = build_regex(path, exts)
|
23
32
|
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
query << "(" << exts[ext].map { |e| e && Regexp.escape(".#{e}") }.join("|") << "|)"
|
28
|
-
end
|
29
|
-
query = /^(#{Regexp.escape(path)})#{query}$/
|
30
|
-
|
31
|
-
templates = []
|
32
|
-
@hash.each do |_path, array|
|
33
|
-
source, updated_at = array
|
34
|
-
next unless query.match?(_path)
|
33
|
+
@hash.select do |_path, _|
|
34
|
+
("/" + _path).match?(regex)
|
35
|
+
end.map do |_path, source|
|
35
36
|
handler, format, variant = extract_handler_and_format_and_variant(_path)
|
36
|
-
|
37
|
+
|
38
|
+
Template.new(source, _path, handler,
|
37
39
|
virtual_path: path.virtual,
|
38
40
|
format: format,
|
39
41
|
variant: variant,
|
40
|
-
|
42
|
+
locals: locals
|
41
43
|
)
|
44
|
+
end.sort_by do |t|
|
45
|
+
match = ("/" + t.identifier).match(regex)
|
46
|
+
EXTENSIONS.keys.reverse.map do |ext|
|
47
|
+
if ext == :variants && exts[ext] == :any
|
48
|
+
match[ext].nil? ? 0 : 1
|
49
|
+
elsif match[ext].nil?
|
50
|
+
exts[ext].length
|
51
|
+
else
|
52
|
+
found = match[ext].to_sym
|
53
|
+
exts[ext].index(found)
|
54
|
+
end
|
55
|
+
end
|
42
56
|
end
|
43
|
-
|
44
|
-
templates.sort_by { |t| -t.identifier.match(/^#{query}$/).captures.reject(&:blank?).size }
|
45
57
|
end
|
46
58
|
end
|
47
59
|
|
48
60
|
class NullResolver < PathResolver
|
49
|
-
def query(path, exts, _,
|
61
|
+
def query(path, exts, _, locals, cache:)
|
50
62
|
handler, format, variant = extract_handler_and_format_and_variant(path)
|
51
|
-
[ActionView::Template.new("Template generated by Null Resolver", path.virtual, handler, virtual_path: path.virtual, format: format, variant: variant)]
|
63
|
+
[ActionView::Template.new("Template generated by Null Resolver", path.virtual, handler, virtual_path: path.virtual, format: format, variant: variant, locals: locals)]
|
52
64
|
end
|
53
65
|
end
|
54
66
|
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "concurrent/map"
|
4
|
+
|
5
|
+
module ActionView
|
6
|
+
class UnboundTemplate
|
7
|
+
def initialize(source, identifer, handler, options)
|
8
|
+
@source = source
|
9
|
+
@identifer = identifer
|
10
|
+
@handler = handler
|
11
|
+
@options = options
|
12
|
+
|
13
|
+
@templates = Concurrent::Map.new(initial_capacity: 2)
|
14
|
+
end
|
15
|
+
|
16
|
+
def bind_locals(locals)
|
17
|
+
@templates[locals] ||= build_template(locals)
|
18
|
+
end
|
19
|
+
|
20
|
+
private
|
21
|
+
def build_template(locals)
|
22
|
+
options = @options.merge(locals: locals)
|
23
|
+
Template.new(
|
24
|
+
@source,
|
25
|
+
@identifer,
|
26
|
+
@handler,
|
27
|
+
**options
|
28
|
+
)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -5,13 +5,21 @@ module ActionView
|
|
5
5
|
extend ActiveSupport::Concern
|
6
6
|
|
7
7
|
included do
|
8
|
-
|
8
|
+
ViewPaths.set_view_paths(self, ActionView::PathSet.new.freeze)
|
9
9
|
end
|
10
10
|
|
11
11
|
delegate :template_exists?, :any_templates?, :view_paths, :formats, :formats=,
|
12
12
|
:locale, :locale=, to: :lookup_context
|
13
13
|
|
14
14
|
module ClassMethods
|
15
|
+
def _view_paths
|
16
|
+
ViewPaths.get_view_paths(self)
|
17
|
+
end
|
18
|
+
|
19
|
+
def _view_paths=(paths)
|
20
|
+
ViewPaths.set_view_paths(self, paths)
|
21
|
+
end
|
22
|
+
|
15
23
|
def _prefixes # :nodoc:
|
16
24
|
@_prefixes ||= begin
|
17
25
|
return local_prefixes if superclass.abstract?
|
@@ -21,7 +29,6 @@ module ActionView
|
|
21
29
|
end
|
22
30
|
|
23
31
|
private
|
24
|
-
|
25
32
|
# Override this method in your controller if you want to change paths prefixes for finding views.
|
26
33
|
# Prefixes defined here will still be added to parents' <tt>._prefixes</tt>.
|
27
34
|
def local_prefixes
|
@@ -29,6 +36,22 @@ module ActionView
|
|
29
36
|
end
|
30
37
|
end
|
31
38
|
|
39
|
+
# :stopdoc:
|
40
|
+
@all_view_paths = {}
|
41
|
+
|
42
|
+
def self.get_view_paths(klass)
|
43
|
+
@all_view_paths[klass] || get_view_paths(klass.superclass)
|
44
|
+
end
|
45
|
+
|
46
|
+
def self.set_view_paths(klass, paths)
|
47
|
+
@all_view_paths[klass] = paths
|
48
|
+
end
|
49
|
+
|
50
|
+
def self.all_view_paths
|
51
|
+
@all_view_paths.values.uniq
|
52
|
+
end
|
53
|
+
# :startdoc:
|
54
|
+
|
32
55
|
# The prefixes used in render "foo" shortcuts.
|
33
56
|
def _prefixes # :nodoc:
|
34
57
|
self.class._prefixes
|
data/lib/action_view.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
#--
|
4
|
-
# Copyright (c) 2004-
|
4
|
+
# Copyright (c) 2004-2019 David Heinemeier Hansson
|
5
5
|
#
|
6
6
|
# Permission is hereby granted, free of charge, to any person obtaining
|
7
7
|
# a copy of this software and associated documentation files (the
|
@@ -35,7 +35,6 @@ module ActionView
|
|
35
35
|
eager_autoload do
|
36
36
|
autoload :Base
|
37
37
|
autoload :Context
|
38
|
-
autoload :CompiledTemplates, "action_view/context"
|
39
38
|
autoload :Digestor
|
40
39
|
autoload :Helpers
|
41
40
|
autoload :LookupContext
|
@@ -45,6 +44,7 @@ module ActionView
|
|
45
44
|
autoload :Rendering
|
46
45
|
autoload :RoutingUrlFor
|
47
46
|
autoload :Template
|
47
|
+
autoload :UnboundTemplate
|
48
48
|
autoload :ViewPaths
|
49
49
|
|
50
50
|
autoload_under "renderer" do
|
@@ -77,10 +77,12 @@ module ActionView
|
|
77
77
|
autoload :ActionViewError
|
78
78
|
autoload :EncodingError
|
79
79
|
autoload :TemplateError
|
80
|
+
autoload :SyntaxErrorInTemplate
|
80
81
|
autoload :WrongEncodingError
|
81
82
|
end
|
82
83
|
end
|
83
84
|
|
85
|
+
autoload :CacheExpiry
|
84
86
|
autoload :TestCase
|
85
87
|
|
86
88
|
def self.eager_load!
|
@@ -1,6 +1,6 @@
|
|
1
1
|
/*
|
2
2
|
Unobtrusive JavaScript
|
3
|
-
https://github.com/rails/rails/blob/
|
3
|
+
https://github.com/rails/rails/blob/main/actionview/app/assets/javascripts
|
4
4
|
Released under the MIT license
|
5
5
|
*/;
|
6
6
|
|
@@ -320,6 +320,9 @@ Released under the MIT license
|
|
320
320
|
if (!input.name || input.disabled) {
|
321
321
|
return;
|
322
322
|
}
|
323
|
+
if (matches(input, 'fieldset[disabled] *')) {
|
324
|
+
return;
|
325
|
+
}
|
323
326
|
if (matches(input, 'select')) {
|
324
327
|
return toArray(input.options).forEach(function(option) {
|
325
328
|
if (option.selected) {
|
@@ -370,6 +373,10 @@ Released under the MIT license
|
|
370
373
|
}
|
371
374
|
};
|
372
375
|
|
376
|
+
Rails.confirm = function(message, element) {
|
377
|
+
return confirm(message);
|
378
|
+
};
|
379
|
+
|
373
380
|
allowAction = function(element) {
|
374
381
|
var answer, callback, message;
|
375
382
|
message = element.getAttribute('data-confirm');
|
@@ -379,7 +386,7 @@ Released under the MIT license
|
|
379
386
|
answer = false;
|
380
387
|
if (fire(element, 'confirm')) {
|
381
388
|
try {
|
382
|
-
answer = confirm(message);
|
389
|
+
answer = Rails.confirm(message, element);
|
383
390
|
} catch (error) {}
|
384
391
|
callback = fire(element, 'confirm:complete', [answer]);
|
385
392
|
}
|
@@ -388,7 +395,7 @@ Released under the MIT license
|
|
388
395
|
|
389
396
|
}).call(this);
|
390
397
|
(function() {
|
391
|
-
var disableFormElement, disableFormElements, disableLinkElement, enableFormElement, enableFormElements, enableLinkElement, formElements, getData, matches, setData, stopEverything;
|
398
|
+
var disableFormElement, disableFormElements, disableLinkElement, enableFormElement, enableFormElements, enableLinkElement, formElements, getData, isXhrRedirect, matches, setData, stopEverything;
|
392
399
|
|
393
400
|
matches = Rails.matches, getData = Rails.getData, setData = Rails.setData, stopEverything = Rails.stopEverything, formElements = Rails.formElements;
|
394
401
|
|
@@ -402,7 +409,14 @@ Released under the MIT license
|
|
402
409
|
|
403
410
|
Rails.enableElement = function(e) {
|
404
411
|
var element;
|
405
|
-
|
412
|
+
if (e instanceof Event) {
|
413
|
+
if (isXhrRedirect(e)) {
|
414
|
+
return;
|
415
|
+
}
|
416
|
+
element = e.target;
|
417
|
+
} else {
|
418
|
+
element = e;
|
419
|
+
}
|
406
420
|
if (matches(element, Rails.linkDisableSelector)) {
|
407
421
|
return enableLinkElement(element);
|
408
422
|
} else if (matches(element, Rails.buttonDisableSelector) || matches(element, Rails.formEnableSelector)) {
|
@@ -426,6 +440,9 @@ Released under the MIT license
|
|
426
440
|
|
427
441
|
disableLinkElement = function(element) {
|
428
442
|
var replacement;
|
443
|
+
if (getData(element, 'ujs:disabled')) {
|
444
|
+
return;
|
445
|
+
}
|
429
446
|
replacement = element.getAttribute('data-disable-with');
|
430
447
|
if (replacement != null) {
|
431
448
|
setData(element, 'ujs:enable-with', element.innerHTML);
|
@@ -452,6 +469,9 @@ Released under the MIT license
|
|
452
469
|
|
453
470
|
disableFormElement = function(element) {
|
454
471
|
var replacement;
|
472
|
+
if (getData(element, 'ujs:disabled')) {
|
473
|
+
return;
|
474
|
+
}
|
455
475
|
replacement = element.getAttribute('data-disable-with');
|
456
476
|
if (replacement != null) {
|
457
477
|
if (matches(element, 'button')) {
|
@@ -485,6 +505,12 @@ Released under the MIT license
|
|
485
505
|
return setData(element, 'ujs:disabled', null);
|
486
506
|
};
|
487
507
|
|
508
|
+
isXhrRedirect = function(event) {
|
509
|
+
var ref, xhr;
|
510
|
+
xhr = (ref = event.detail) != null ? ref[0] : void 0;
|
511
|
+
return (xhr != null ? xhr.getResponseHeader("X-Xhr-Redirect") : void 0) != null;
|
512
|
+
};
|
513
|
+
|
488
514
|
}).call(this);
|
489
515
|
(function() {
|
490
516
|
var stopEverything;
|