actionview 6.0.6.1 → 6.1.7.6
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 +248 -220
- data/MIT-LICENSE +1 -2
- data/lib/action_view/base.rb +18 -49
- data/lib/action_view/cache_expiry.rb +1 -2
- data/lib/action_view/dependency_tracker.rb +10 -4
- data/lib/action_view/digestor.rb +3 -2
- data/lib/action_view/gem_version.rb +3 -3
- data/lib/action_view/helpers/asset_tag_helper.rb +57 -17
- data/lib/action_view/helpers/asset_url_helper.rb +6 -4
- data/lib/action_view/helpers/atom_feed_helper.rb +2 -1
- data/lib/action_view/helpers/cache_helper.rb +10 -16
- data/lib/action_view/helpers/date_helper.rb +6 -5
- data/lib/action_view/helpers/form_helper.rb +66 -30
- data/lib/action_view/helpers/form_options_helper.rb +7 -16
- data/lib/action_view/helpers/form_tag_helper.rb +4 -3
- data/lib/action_view/helpers/javascript_helper.rb +3 -3
- data/lib/action_view/helpers/number_helper.rb +6 -6
- data/lib/action_view/helpers/rendering_helper.rb +11 -3
- data/lib/action_view/helpers/tag_helper.rb +98 -22
- data/lib/action_view/helpers/tags/base.rb +10 -6
- data/lib/action_view/helpers/tags/check_box.rb +1 -1
- data/lib/action_view/helpers/tags/date_field.rb +1 -1
- data/lib/action_view/helpers/tags/date_select.rb +2 -2
- data/lib/action_view/helpers/tags/datetime_local_field.rb +1 -1
- data/lib/action_view/helpers/tags/hidden_field.rb +4 -0
- data/lib/action_view/helpers/tags/label.rb +4 -0
- data/lib/action_view/helpers/tags/month_field.rb +1 -1
- data/lib/action_view/helpers/tags/select.rb +1 -1
- data/lib/action_view/helpers/tags/time_field.rb +1 -1
- data/lib/action_view/helpers/tags/week_field.rb +1 -1
- data/lib/action_view/helpers/text_helper.rb +2 -2
- data/lib/action_view/helpers/translation_helper.rb +88 -50
- data/lib/action_view/helpers/url_helper.rb +136 -24
- data/lib/action_view/layouts.rb +3 -2
- data/lib/action_view/log_subscriber.rb +26 -10
- data/lib/action_view/lookup_context.rb +3 -18
- data/lib/action_view/path_set.rb +0 -3
- data/lib/action_view/railtie.rb +39 -46
- data/lib/action_view/renderer/abstract_renderer.rb +93 -14
- data/lib/action_view/renderer/collection_renderer.rb +196 -0
- data/lib/action_view/renderer/object_renderer.rb +34 -0
- data/lib/action_view/renderer/partial_renderer/collection_caching.rb +25 -26
- data/lib/action_view/renderer/partial_renderer.rb +20 -282
- data/lib/action_view/renderer/renderer.rb +44 -1
- data/lib/action_view/renderer/streaming_template_renderer.rb +5 -1
- data/lib/action_view/renderer/template_renderer.rb +15 -12
- data/lib/action_view/rendering.rb +3 -1
- data/lib/action_view/routing_url_for.rb +1 -1
- data/lib/action_view/template/handlers/erb/erubi.rb +9 -7
- data/lib/action_view/template/handlers/erb.rb +10 -14
- data/lib/action_view/template/handlers.rb +0 -26
- data/lib/action_view/template/html.rb +1 -11
- data/lib/action_view/template/raw_file.rb +0 -3
- data/lib/action_view/template/renderable.rb +24 -0
- data/lib/action_view/template/resolver.rb +82 -40
- data/lib/action_view/template/text.rb +0 -3
- data/lib/action_view/template.rb +9 -49
- data/lib/action_view/test_case.rb +18 -25
- data/lib/action_view/testing/resolvers.rb +10 -31
- data/lib/action_view/unbound_template.rb +3 -3
- data/lib/action_view/view_paths.rb +34 -36
- data/lib/action_view.rb +4 -1
- data/lib/assets/compiled/rails-ujs.js +38 -7
- metadata +15 -12
@@ -16,16 +16,6 @@ module ActionView
|
|
16
16
|
# Do not escape templates of these mime types.
|
17
17
|
class_attribute :escape_ignore_list, default: ["text/plain"]
|
18
18
|
|
19
|
-
[self, singleton_class].each do |base|
|
20
|
-
base.alias_method :escape_whitelist, :escape_ignore_list
|
21
|
-
base.alias_method :escape_whitelist=, :escape_ignore_list=
|
22
|
-
|
23
|
-
base.deprecate(
|
24
|
-
escape_whitelist: "use #escape_ignore_list instead",
|
25
|
-
:escape_whitelist= => "use #escape_ignore_list= instead"
|
26
|
-
)
|
27
|
-
end
|
28
|
-
|
29
19
|
ENCODING_TAG = Regexp.new("\\A(<%#{ENCODING_FLAG}-?%>)[ \\t]*")
|
30
20
|
|
31
21
|
def self.call(template, source)
|
@@ -45,7 +35,7 @@ module ActionView
|
|
45
35
|
# wrong, we can still find an encoding tag
|
46
36
|
# (<%# encoding %>) inside the String using a regular
|
47
37
|
# expression
|
48
|
-
template_source = source.
|
38
|
+
template_source = source.b
|
49
39
|
|
50
40
|
erb = template_source.gsub(ENCODING_TAG, "")
|
51
41
|
encoding = $2
|
@@ -55,11 +45,17 @@ module ActionView
|
|
55
45
|
# Always make sure we return a String in the default_internal
|
56
46
|
erb.encode!
|
57
47
|
|
58
|
-
|
59
|
-
erb,
|
48
|
+
options = {
|
60
49
|
escape: (self.class.escape_ignore_list.include? template.type),
|
61
50
|
trim: (self.class.erb_trim_mode == "-")
|
62
|
-
|
51
|
+
}
|
52
|
+
|
53
|
+
if ActionView::Base.annotate_rendered_view_with_filenames && template.format == :html
|
54
|
+
options[:preamble] = "@output_buffer.safe_append='<!-- BEGIN #{template.short_identifier} -->';"
|
55
|
+
options[:postamble] = "@output_buffer.safe_append='<!-- END #{template.short_identifier} -->';@output_buffer.to_s"
|
56
|
+
end
|
57
|
+
|
58
|
+
self.class.erb_implementation.new(erb, options).src
|
63
59
|
end
|
64
60
|
|
65
61
|
private
|
@@ -1,7 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require "active_support/deprecation"
|
4
|
-
|
5
3
|
module ActionView #:nodoc:
|
6
4
|
# = Action View Template Handlers
|
7
5
|
class Template #:nodoc:
|
@@ -26,35 +24,11 @@ module ActionView #:nodoc:
|
|
26
24
|
@@template_extensions ||= @@template_handlers.keys
|
27
25
|
end
|
28
26
|
|
29
|
-
class LegacyHandlerWrapper < SimpleDelegator # :nodoc:
|
30
|
-
def call(view, source)
|
31
|
-
__getobj__.call(ActionView::Template::LegacyTemplate.new(view, source))
|
32
|
-
end
|
33
|
-
end
|
34
|
-
|
35
27
|
# Register an object that knows how to handle template files with the given
|
36
28
|
# extensions. This can be used to implement new template types.
|
37
29
|
# The handler must respond to +:call+, which will be passed the template
|
38
30
|
# and should return the rendered template as a String.
|
39
31
|
def register_template_handler(*extensions, handler)
|
40
|
-
params = if handler.is_a?(Proc)
|
41
|
-
handler.parameters
|
42
|
-
else
|
43
|
-
handler.method(:call).parameters
|
44
|
-
end
|
45
|
-
|
46
|
-
unless params.find_all { |type, _| type == :req || type == :opt }.length >= 2
|
47
|
-
ActiveSupport::Deprecation.warn <<~eowarn
|
48
|
-
Single arity template handlers are deprecated. Template handlers must
|
49
|
-
now accept two parameters, the view object and the source for the view object.
|
50
|
-
Change:
|
51
|
-
>> #{handler}.call(#{params.map(&:last).join(", ")})
|
52
|
-
To:
|
53
|
-
>> #{handler}.call(#{params.map(&:last).join(", ")}, source)
|
54
|
-
eowarn
|
55
|
-
handler = LegacyHandlerWrapper.new(handler)
|
56
|
-
end
|
57
|
-
|
58
32
|
raise(ArgumentError, "Extension is required") if extensions.empty?
|
59
33
|
extensions.each do |extension|
|
60
34
|
@@template_handlers[extension.to_sym] = handler
|
@@ -1,19 +1,12 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require "active_support/deprecation"
|
4
|
-
|
5
3
|
module ActionView #:nodoc:
|
6
4
|
# = Action View HTML Template
|
7
5
|
class Template #:nodoc:
|
8
6
|
class HTML #:nodoc:
|
9
7
|
attr_reader :type
|
10
8
|
|
11
|
-
def initialize(string, type
|
12
|
-
unless type
|
13
|
-
ActiveSupport::Deprecation.warn "ActionView::Template::HTML#initialize requires a type parameter"
|
14
|
-
type = :html
|
15
|
-
end
|
16
|
-
|
9
|
+
def initialize(string, type)
|
17
10
|
@string = string.to_s
|
18
11
|
@type = type
|
19
12
|
end
|
@@ -35,9 +28,6 @@ module ActionView #:nodoc:
|
|
35
28
|
def format
|
36
29
|
@type
|
37
30
|
end
|
38
|
-
|
39
|
-
def formats; Array(format); end
|
40
|
-
deprecate :formats
|
41
31
|
end
|
42
32
|
end
|
43
33
|
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ActionView
|
4
|
+
# = Action View Renderable Template for objects that respond to #render_in
|
5
|
+
class Template
|
6
|
+
class Renderable # :nodoc:
|
7
|
+
def initialize(renderable)
|
8
|
+
@renderable = renderable
|
9
|
+
end
|
10
|
+
|
11
|
+
def identifier
|
12
|
+
@renderable.class.name
|
13
|
+
end
|
14
|
+
|
15
|
+
def render(context, *args)
|
16
|
+
@renderable.render_in(context)
|
17
|
+
end
|
18
|
+
|
19
|
+
def format
|
20
|
+
@renderable.format
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -35,6 +35,41 @@ module ActionView
|
|
35
35
|
alias :to_s :to_str
|
36
36
|
end
|
37
37
|
|
38
|
+
class PathParser # :nodoc:
|
39
|
+
def build_path_regex
|
40
|
+
handlers = Template::Handlers.extensions.map { |x| Regexp.escape(x) }.join("|")
|
41
|
+
formats = Template::Types.symbols.map { |x| Regexp.escape(x) }.join("|")
|
42
|
+
locales = "[a-z]{2}(?:-[A-Z]{2})?"
|
43
|
+
variants = "[^.]*"
|
44
|
+
|
45
|
+
%r{
|
46
|
+
\A
|
47
|
+
(?:(?<prefix>.*)/)?
|
48
|
+
(?<partial>_)?
|
49
|
+
(?<action>.*?)
|
50
|
+
(?:\.(?<locale>#{locales}))??
|
51
|
+
(?:\.(?<format>#{formats}))??
|
52
|
+
(?:\+(?<variant>#{variants}))??
|
53
|
+
(?:\.(?<handler>#{handlers}))?
|
54
|
+
\z
|
55
|
+
}x
|
56
|
+
end
|
57
|
+
|
58
|
+
def parse(path)
|
59
|
+
@regex ||= build_path_regex
|
60
|
+
match = @regex.match(path)
|
61
|
+
{
|
62
|
+
prefix: match[:prefix] || "",
|
63
|
+
action: match[:action],
|
64
|
+
partial: !!match[:partial],
|
65
|
+
locale: match[:locale]&.to_sym,
|
66
|
+
handler: match[:handler]&.to_sym,
|
67
|
+
format: match[:format]&.to_sym,
|
68
|
+
variant: match[:variant]
|
69
|
+
}
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
38
73
|
# Threadsafe template cache
|
39
74
|
class Cache #:nodoc:
|
40
75
|
class SmallCache < Concurrent::Map
|
@@ -43,13 +78,13 @@ module ActionView
|
|
43
78
|
end
|
44
79
|
end
|
45
80
|
|
46
|
-
#
|
81
|
+
# Preallocate all the default blocks for performance/memory consumption reasons
|
47
82
|
PARTIAL_BLOCK = lambda { |cache, partial| cache[partial] = SmallCache.new }
|
48
83
|
PREFIX_BLOCK = lambda { |cache, prefix| cache[prefix] = SmallCache.new(&PARTIAL_BLOCK) }
|
49
84
|
NAME_BLOCK = lambda { |cache, name| cache[name] = SmallCache.new(&PREFIX_BLOCK) }
|
50
85
|
KEY_BLOCK = lambda { |cache, key| cache[key] = SmallCache.new(&NAME_BLOCK) }
|
51
86
|
|
52
|
-
#
|
87
|
+
# Usually a majority of template look ups return nothing, use this canonical preallocated array to save memory
|
53
88
|
NO_TEMPLATES = [].freeze
|
54
89
|
|
55
90
|
def initialize
|
@@ -58,7 +93,7 @@ module ActionView
|
|
58
93
|
end
|
59
94
|
|
60
95
|
def inspect
|
61
|
-
"
|
96
|
+
"#{to_s[0..-2]} keys=#{@data.size} queries=#{@query_cache.size}>"
|
62
97
|
end
|
63
98
|
|
64
99
|
# Cache the templates returned by the block
|
@@ -75,7 +110,7 @@ module ActionView
|
|
75
110
|
@query_cache.clear
|
76
111
|
end
|
77
112
|
|
78
|
-
# Get the cache size.
|
113
|
+
# Get the cache size. Do not call this
|
79
114
|
# method. This method is not guaranteed to be here ever.
|
80
115
|
def size # :nodoc:
|
81
116
|
size = 0
|
@@ -121,9 +156,6 @@ module ActionView
|
|
121
156
|
end
|
122
157
|
end
|
123
158
|
|
124
|
-
alias :find_all_anywhere :find_all
|
125
|
-
deprecate :find_all_anywhere
|
126
|
-
|
127
159
|
def find_all_with_query(query) # :nodoc:
|
128
160
|
@cache.cache_query(query) { find_template_paths(File.join(@path, query)) }
|
129
161
|
end
|
@@ -164,20 +196,17 @@ module ActionView
|
|
164
196
|
EXTENSIONS = { locale: ".", formats: ".", variants: "+", handlers: "." }
|
165
197
|
DEFAULT_PATTERN = ":prefix/:action{.:locale,}{.:formats,}{+:variants,}{.:handlers,}"
|
166
198
|
|
167
|
-
def initialize
|
168
|
-
|
169
|
-
ActiveSupport::Deprecation.warn "Specifying a custom path for #{self.class} is deprecated. Implement a custom Resolver subclass instead."
|
170
|
-
@pattern = pattern
|
171
|
-
else
|
172
|
-
@pattern = DEFAULT_PATTERN
|
173
|
-
end
|
199
|
+
def initialize
|
200
|
+
@pattern = DEFAULT_PATTERN
|
174
201
|
@unbound_templates = Concurrent::Map.new
|
175
|
-
|
202
|
+
@path_parser = PathParser.new
|
203
|
+
super
|
176
204
|
end
|
177
205
|
|
178
206
|
def clear_cache
|
179
207
|
@unbound_templates.clear
|
180
|
-
|
208
|
+
@path_parser = PathParser.new
|
209
|
+
super
|
181
210
|
end
|
182
211
|
|
183
212
|
private
|
@@ -204,9 +233,13 @@ module ActionView
|
|
204
233
|
end
|
205
234
|
end
|
206
235
|
|
236
|
+
def source_for_template(template)
|
237
|
+
Template::Sources::File.new(template)
|
238
|
+
end
|
239
|
+
|
207
240
|
def build_unbound_template(template, virtual_path)
|
208
241
|
handler, format, variant = extract_handler_and_format_and_variant(template)
|
209
|
-
source =
|
242
|
+
source = source_for_template(template)
|
210
243
|
|
211
244
|
UnboundTemplate.new(
|
212
245
|
source,
|
@@ -223,6 +256,10 @@ module ActionView
|
|
223
256
|
end
|
224
257
|
|
225
258
|
def find_template_paths_from_details(path, details)
|
259
|
+
if path.name.include?(".")
|
260
|
+
ActiveSupport::Deprecation.warn("Rendering actions with '.' in the name is deprecated: #{path}")
|
261
|
+
end
|
262
|
+
|
226
263
|
query = build_query(path, details)
|
227
264
|
find_template_paths(query)
|
228
265
|
end
|
@@ -249,7 +286,7 @@ module ActionView
|
|
249
286
|
query.gsub!(/:prefix(\/)?/, prefix)
|
250
287
|
|
251
288
|
partial = escape_entry(path.partial? ? "_#{path.name}" : path.name)
|
252
|
-
query.gsub!(
|
289
|
+
query.gsub!(":action", partial)
|
253
290
|
|
254
291
|
details.each do |ext, candidates|
|
255
292
|
if ext == :variants && candidates == :any
|
@@ -270,22 +307,11 @@ module ActionView
|
|
270
307
|
# from the path, or the handler, we should return the array of formats given
|
271
308
|
# to the resolver.
|
272
309
|
def extract_handler_and_format_and_variant(path)
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
|
278
|
-
handler = Template.handler_for_extension(extension)
|
279
|
-
format, variant = pieces.last.split(EXTENSIONS[:variants], 2) if pieces.last
|
280
|
-
format = if format
|
281
|
-
Template::Types[format]&.ref
|
282
|
-
else
|
283
|
-
if handler.respond_to?(:default_format) # default_format can return nil
|
284
|
-
handler.default_format
|
285
|
-
else
|
286
|
-
nil
|
287
|
-
end
|
288
|
-
end
|
310
|
+
details = @path_parser.parse(path)
|
311
|
+
|
312
|
+
handler = Template.handler_for_extension(details[:handler])
|
313
|
+
format = details[:format] || handler.try(:default_format)
|
314
|
+
variant = details[:variant]
|
289
315
|
|
290
316
|
# Template::Types[format] and handler.default_format can return nil
|
291
317
|
[handler, format, variant]
|
@@ -296,9 +322,9 @@ module ActionView
|
|
296
322
|
class FileSystemResolver < PathResolver
|
297
323
|
attr_reader :path
|
298
324
|
|
299
|
-
def initialize(path
|
325
|
+
def initialize(path)
|
300
326
|
raise ArgumentError, "path already is a Resolver class" if path.is_a?(Resolver)
|
301
|
-
super(
|
327
|
+
super()
|
302
328
|
@path = File.expand_path(path)
|
303
329
|
end
|
304
330
|
|
@@ -320,14 +346,27 @@ module ActionView
|
|
320
346
|
end
|
321
347
|
|
322
348
|
private
|
323
|
-
def
|
349
|
+
def find_candidate_template_paths(path)
|
324
350
|
# Instead of checking for every possible path, as our other globs would
|
325
351
|
# do, scan the directory for files with the right prefix.
|
326
352
|
query = "#{escape_entry(File.join(@path, path))}*"
|
327
353
|
|
354
|
+
Dir[query].reject do |filename|
|
355
|
+
File.directory?(filename)
|
356
|
+
end
|
357
|
+
end
|
358
|
+
|
359
|
+
def find_template_paths_from_details(path, details)
|
360
|
+
if path.name.include?(".")
|
361
|
+
# Fall back to the unoptimized resolver, which will warn
|
362
|
+
return super
|
363
|
+
end
|
364
|
+
|
365
|
+
candidates = find_candidate_template_paths(path)
|
366
|
+
|
328
367
|
regex = build_regex(path, details)
|
329
368
|
|
330
|
-
|
369
|
+
candidates.uniq.reject do |filename|
|
331
370
|
# This regex match does double duty of finding only files which match
|
332
371
|
# details (instead of just matching the prefix) and also filtering for
|
333
372
|
# case-insensitive file systems.
|
@@ -339,7 +378,7 @@ module ActionView
|
|
339
378
|
# We can use the matches found by the regex and sort by their index in
|
340
379
|
# details.
|
341
380
|
match = filename.match(regex)
|
342
|
-
EXTENSIONS.keys.
|
381
|
+
EXTENSIONS.keys.map do |ext|
|
343
382
|
if ext == :variants && details[ext] == :any
|
344
383
|
match[ext].nil? ? 0 : 1
|
345
384
|
elsif match[ext].nil?
|
@@ -360,7 +399,10 @@ module ActionView
|
|
360
399
|
if ext == :variants && details[ext] == :any
|
361
400
|
".*?"
|
362
401
|
else
|
363
|
-
details[ext].compact
|
402
|
+
arr = details[ext].compact
|
403
|
+
arr.uniq!
|
404
|
+
arr.map! { |e| Regexp.escape(e) }
|
405
|
+
arr.join("|")
|
364
406
|
end
|
365
407
|
prefix = Regexp.escape(prefix)
|
366
408
|
"(#{prefix}(?<#{ext}>#{match}))?"
|
data/lib/action_view/template.rb
CHANGED
@@ -1,8 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require "active_support/core_ext/object/try"
|
4
|
-
require "active_support/core_ext/kernel/singleton_class"
|
5
|
-
require "active_support/deprecation"
|
6
3
|
require "thread"
|
7
4
|
require "delegate"
|
8
5
|
|
@@ -11,14 +8,6 @@ module ActionView
|
|
11
8
|
class Template
|
12
9
|
extend ActiveSupport::Autoload
|
13
10
|
|
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
|
-
|
22
11
|
# === Encodings in ActionView::Template
|
23
12
|
#
|
24
13
|
# ActionView::Template is one of a few sources of potential
|
@@ -114,6 +103,7 @@ module ActionView
|
|
114
103
|
eager_autoload do
|
115
104
|
autoload :Error
|
116
105
|
autoload :RawFile
|
106
|
+
autoload :Renderable
|
117
107
|
autoload :Handlers
|
118
108
|
autoload :HTML
|
119
109
|
autoload :Inline
|
@@ -124,15 +114,10 @@ module ActionView
|
|
124
114
|
|
125
115
|
extend Template::Handlers
|
126
116
|
|
127
|
-
attr_reader :identifier, :handler
|
117
|
+
attr_reader :identifier, :handler
|
128
118
|
attr_reader :variable, :format, :variant, :locals, :virtual_path
|
129
119
|
|
130
|
-
def initialize(source, identifier, handler, format: nil, variant: nil,
|
131
|
-
unless locals
|
132
|
-
ActiveSupport::Deprecation.warn "ActionView::Template#initialize requires a locals parameter"
|
133
|
-
locals = []
|
134
|
-
end
|
135
|
-
|
120
|
+
def initialize(source, identifier, handler, locals:, format: nil, variant: nil, virtual_path: nil)
|
136
121
|
@source = source
|
137
122
|
@identifier = identifier
|
138
123
|
@handler = handler
|
@@ -141,32 +126,16 @@ module ActionView
|
|
141
126
|
@virtual_path = virtual_path
|
142
127
|
|
143
128
|
@variable = if @virtual_path
|
144
|
-
base = @virtual_path
|
129
|
+
base = @virtual_path.end_with?("/") ? "" : ::File.basename(@virtual_path)
|
145
130
|
base =~ /\A_?(.*?)(?:\.\w+)*\z/
|
146
131
|
$1.to_sym
|
147
132
|
end
|
148
133
|
|
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
134
|
@format = format
|
156
135
|
@variant = variant
|
157
136
|
@compile_mutex = Mutex.new
|
158
137
|
end
|
159
138
|
|
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
|
-
|
170
139
|
# Returns whether the underlying handler supports streaming. If so,
|
171
140
|
# a streaming buffer *may* be passed when it starts rendering.
|
172
141
|
def supports_streaming?
|
@@ -179,10 +148,10 @@ module ActionView
|
|
179
148
|
# This method is instrumented as "!render_template.action_view". Notice that
|
180
149
|
# we use a bang in this instrumentation because you don't want to
|
181
150
|
# consume this in production. This is only slow if it's being listened to.
|
182
|
-
def render(view, locals, buffer = ActionView::OutputBuffer.new, &block)
|
151
|
+
def render(view, locals, buffer = ActionView::OutputBuffer.new, add_to_stack: true, &block)
|
183
152
|
instrument_render_template do
|
184
153
|
compile!(view)
|
185
|
-
view._run(method_name, self, locals, buffer, &block)
|
154
|
+
view._run(method_name, self, locals, buffer, add_to_stack: add_to_stack, &block)
|
186
155
|
end
|
187
156
|
rescue => e
|
188
157
|
handle_render_error(view, e)
|
@@ -193,7 +162,7 @@ module ActionView
|
|
193
162
|
end
|
194
163
|
|
195
164
|
def short_identifier
|
196
|
-
@short_identifier ||= defined?(Rails.root) ? identifier.
|
165
|
+
@short_identifier ||= defined?(Rails.root) ? identifier.delete_prefix("#{Rails.root}/") : identifier
|
197
166
|
end
|
198
167
|
|
199
168
|
def inspect
|
@@ -255,11 +224,11 @@ module ActionView
|
|
255
224
|
# to ensure that references to the template object can be marshalled as well. This means forgoing
|
256
225
|
# the marshalling of the compiler mutex and instantiating that again on unmarshalling.
|
257
226
|
def marshal_dump # :nodoc:
|
258
|
-
[ @source, @identifier, @handler, @compiled, @locals, @virtual_path, @
|
227
|
+
[ @source, @identifier, @handler, @compiled, @locals, @virtual_path, @format, @variant ]
|
259
228
|
end
|
260
229
|
|
261
230
|
def marshal_load(array) # :nodoc:
|
262
|
-
@source, @identifier, @handler, @compiled, @locals, @virtual_path, @
|
231
|
+
@source, @identifier, @handler, @compiled, @locals, @virtual_path, @format, @variant = *array
|
263
232
|
@compile_mutex = Mutex.new
|
264
233
|
end
|
265
234
|
|
@@ -288,15 +257,6 @@ module ActionView
|
|
288
257
|
end
|
289
258
|
end
|
290
259
|
|
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
|
-
|
300
260
|
# Among other things, this method is responsible for properly setting
|
301
261
|
# the encoding of the compiled template.
|
302
262
|
#
|
@@ -16,11 +16,12 @@ module ActionView
|
|
16
16
|
attr_accessor :request, :response, :params
|
17
17
|
|
18
18
|
class << self
|
19
|
-
|
19
|
+
# Overrides AbstractController::Base#controller_path
|
20
|
+
attr_accessor :controller_path
|
20
21
|
end
|
21
22
|
|
22
23
|
def controller_path=(path)
|
23
|
-
self.class.controller_path =
|
24
|
+
self.class.controller_path = path
|
24
25
|
end
|
25
26
|
|
26
27
|
def initialize
|
@@ -73,7 +74,7 @@ module ActionView
|
|
73
74
|
def helper_method(*methods)
|
74
75
|
# Almost a duplicate from ActionController::Helpers
|
75
76
|
methods.flatten.each do |method|
|
76
|
-
|
77
|
+
_helpers_for_modification.module_eval <<-end_eval, __FILE__, __LINE__ + 1
|
77
78
|
def #{method}(*args, &block) # def current_user(*args, &block)
|
78
79
|
_test_case.send(:'#{method}', *args, &block) # _test_case.send(:'current_user', *args, &block)
|
79
80
|
end # end
|
@@ -101,7 +102,8 @@ module ActionView
|
|
101
102
|
end
|
102
103
|
|
103
104
|
def setup_with_controller
|
104
|
-
|
105
|
+
controller_class = Class.new(ActionView::TestCase::TestController)
|
106
|
+
@controller = controller_class.new
|
105
107
|
@request = @controller.request
|
106
108
|
@view_flow = ActionView::OutputFlow.new
|
107
109
|
# empty string ensures buffer has UTF-8 encoding as
|
@@ -109,8 +111,8 @@ module ActionView
|
|
109
111
|
@output_buffer = ActiveSupport::SafeBuffer.new ""
|
110
112
|
@rendered = +""
|
111
113
|
|
112
|
-
|
113
|
-
|
114
|
+
test_case_instance = self
|
115
|
+
controller_class.define_method(:_test_case) { test_case_instance }
|
114
116
|
end
|
115
117
|
|
116
118
|
def config
|
@@ -160,33 +162,24 @@ module ActionView
|
|
160
162
|
included do
|
161
163
|
setup :setup_with_controller
|
162
164
|
ActiveSupport.run_load_hooks(:action_view_test_case, self)
|
163
|
-
end
|
164
165
|
|
165
|
-
|
166
|
-
# Need to experiment if this priority is the best one: rendered => output_buffer
|
167
|
-
def document_root_element
|
168
|
-
Nokogiri::HTML::Document.parse(@rendered.blank? ? @output_buffer : @rendered).root
|
169
|
-
end
|
170
|
-
|
171
|
-
def say_no_to_protect_against_forgery!
|
172
|
-
_helpers.module_eval do
|
173
|
-
silence_redefinition_of_method :protect_against_forgery?
|
166
|
+
helper do
|
174
167
|
def protect_against_forgery?
|
175
168
|
false
|
176
169
|
end
|
177
|
-
end
|
178
|
-
end
|
179
170
|
|
180
|
-
|
181
|
-
|
182
|
-
_helpers.module_eval do
|
183
|
-
unless private_method_defined?(:_test_case)
|
184
|
-
define_method(:_test_case) { test_case_instance }
|
185
|
-
private :_test_case
|
171
|
+
def _test_case
|
172
|
+
controller._test_case
|
186
173
|
end
|
187
174
|
end
|
188
175
|
end
|
189
176
|
|
177
|
+
private
|
178
|
+
# Need to experiment if this priority is the best one: rendered => output_buffer
|
179
|
+
def document_root_element
|
180
|
+
Nokogiri::HTML::Document.parse(@rendered.blank? ? @output_buffer : @rendered).root
|
181
|
+
end
|
182
|
+
|
190
183
|
module Locals
|
191
184
|
attr_accessor :rendered_views
|
192
185
|
|
@@ -283,7 +276,7 @@ module ActionView
|
|
283
276
|
|
284
277
|
def respond_to_missing?(name, include_private = false)
|
285
278
|
begin
|
286
|
-
routes = @controller.respond_to?(:_routes) && @controller._routes
|
279
|
+
routes = defined?(@controller) && @controller.respond_to?(:_routes) && @controller._routes
|
287
280
|
rescue
|
288
281
|
# Don't call routes, if there is an error on _routes call
|
289
282
|
end
|
@@ -8,12 +8,8 @@ module ActionView #:nodoc:
|
|
8
8
|
# useful for testing extensions that have no way of knowing what the file
|
9
9
|
# system will look like at runtime.
|
10
10
|
class FixtureResolver < OptimizedFileSystemResolver
|
11
|
-
def initialize(hash = {}
|
11
|
+
def initialize(hash = {})
|
12
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
|
17
13
|
@hash = hash
|
18
14
|
@path = ""
|
19
15
|
end
|
@@ -27,34 +23,17 @@ module ActionView #:nodoc:
|
|
27
23
|
end
|
28
24
|
|
29
25
|
private
|
30
|
-
def
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
end.map do |_path, source|
|
36
|
-
handler, format, variant = extract_handler_and_format_and_variant(_path)
|
37
|
-
|
38
|
-
Template.new(source, _path, handler,
|
39
|
-
virtual_path: path.virtual,
|
40
|
-
format: format,
|
41
|
-
variant: variant,
|
42
|
-
locals: locals
|
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
|
26
|
+
def find_candidate_template_paths(path)
|
27
|
+
@hash.keys.select do |fixture|
|
28
|
+
fixture.start_with?(path.virtual)
|
29
|
+
end.map do |fixture|
|
30
|
+
"/#{fixture}"
|
56
31
|
end
|
57
32
|
end
|
33
|
+
|
34
|
+
def source_for_template(template)
|
35
|
+
@hash[template[1..template.size]]
|
36
|
+
end
|
58
37
|
end
|
59
38
|
|
60
39
|
class NullResolver < PathResolver
|