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.
Files changed (65) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +248 -220
  3. data/MIT-LICENSE +1 -2
  4. data/lib/action_view/base.rb +18 -49
  5. data/lib/action_view/cache_expiry.rb +1 -2
  6. data/lib/action_view/dependency_tracker.rb +10 -4
  7. data/lib/action_view/digestor.rb +3 -2
  8. data/lib/action_view/gem_version.rb +3 -3
  9. data/lib/action_view/helpers/asset_tag_helper.rb +57 -17
  10. data/lib/action_view/helpers/asset_url_helper.rb +6 -4
  11. data/lib/action_view/helpers/atom_feed_helper.rb +2 -1
  12. data/lib/action_view/helpers/cache_helper.rb +10 -16
  13. data/lib/action_view/helpers/date_helper.rb +6 -5
  14. data/lib/action_view/helpers/form_helper.rb +66 -30
  15. data/lib/action_view/helpers/form_options_helper.rb +7 -16
  16. data/lib/action_view/helpers/form_tag_helper.rb +4 -3
  17. data/lib/action_view/helpers/javascript_helper.rb +3 -3
  18. data/lib/action_view/helpers/number_helper.rb +6 -6
  19. data/lib/action_view/helpers/rendering_helper.rb +11 -3
  20. data/lib/action_view/helpers/tag_helper.rb +98 -22
  21. data/lib/action_view/helpers/tags/base.rb +10 -6
  22. data/lib/action_view/helpers/tags/check_box.rb +1 -1
  23. data/lib/action_view/helpers/tags/date_field.rb +1 -1
  24. data/lib/action_view/helpers/tags/date_select.rb +2 -2
  25. data/lib/action_view/helpers/tags/datetime_local_field.rb +1 -1
  26. data/lib/action_view/helpers/tags/hidden_field.rb +4 -0
  27. data/lib/action_view/helpers/tags/label.rb +4 -0
  28. data/lib/action_view/helpers/tags/month_field.rb +1 -1
  29. data/lib/action_view/helpers/tags/select.rb +1 -1
  30. data/lib/action_view/helpers/tags/time_field.rb +1 -1
  31. data/lib/action_view/helpers/tags/week_field.rb +1 -1
  32. data/lib/action_view/helpers/text_helper.rb +2 -2
  33. data/lib/action_view/helpers/translation_helper.rb +88 -50
  34. data/lib/action_view/helpers/url_helper.rb +136 -24
  35. data/lib/action_view/layouts.rb +3 -2
  36. data/lib/action_view/log_subscriber.rb +26 -10
  37. data/lib/action_view/lookup_context.rb +3 -18
  38. data/lib/action_view/path_set.rb +0 -3
  39. data/lib/action_view/railtie.rb +39 -46
  40. data/lib/action_view/renderer/abstract_renderer.rb +93 -14
  41. data/lib/action_view/renderer/collection_renderer.rb +196 -0
  42. data/lib/action_view/renderer/object_renderer.rb +34 -0
  43. data/lib/action_view/renderer/partial_renderer/collection_caching.rb +25 -26
  44. data/lib/action_view/renderer/partial_renderer.rb +20 -282
  45. data/lib/action_view/renderer/renderer.rb +44 -1
  46. data/lib/action_view/renderer/streaming_template_renderer.rb +5 -1
  47. data/lib/action_view/renderer/template_renderer.rb +15 -12
  48. data/lib/action_view/rendering.rb +3 -1
  49. data/lib/action_view/routing_url_for.rb +1 -1
  50. data/lib/action_view/template/handlers/erb/erubi.rb +9 -7
  51. data/lib/action_view/template/handlers/erb.rb +10 -14
  52. data/lib/action_view/template/handlers.rb +0 -26
  53. data/lib/action_view/template/html.rb +1 -11
  54. data/lib/action_view/template/raw_file.rb +0 -3
  55. data/lib/action_view/template/renderable.rb +24 -0
  56. data/lib/action_view/template/resolver.rb +82 -40
  57. data/lib/action_view/template/text.rb +0 -3
  58. data/lib/action_view/template.rb +9 -49
  59. data/lib/action_view/test_case.rb +18 -25
  60. data/lib/action_view/testing/resolvers.rb +10 -31
  61. data/lib/action_view/unbound_template.rb +3 -3
  62. data/lib/action_view/view_paths.rb +34 -36
  63. data/lib/action_view.rb +4 -1
  64. data/lib/assets/compiled/rails-ujs.js +38 -7
  65. 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.dup.force_encoding(Encoding::ASCII_8BIT)
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
- self.class.erb_implementation.new(
59
- erb,
48
+ options = {
60
49
  escape: (self.class.escape_ignore_list.include? template.type),
61
50
  trim: (self.class.erb_trim_mode == "-")
62
- ).src
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 = nil)
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
@@ -20,9 +20,6 @@ module ActionView #:nodoc:
20
20
  def render(*args)
21
21
  ::File.read(@filename)
22
22
  end
23
-
24
- def formats; Array(format); end
25
- deprecate :formats
26
23
  end
27
24
  end
28
25
  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
- # preallocate all the default blocks for performance/memory consumption reasons
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
- # usually a majority of template look ups return nothing, use this canonical preallocated array to save memory
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
- "#<#{self.class.name}:0x#{(object_id << 1).to_s(16)} keys=#{@data.size} queries=#{@query_cache.size}>"
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. Do not call this
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(pattern = nil)
168
- if pattern
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
- super()
202
+ @path_parser = PathParser.new
203
+ super
176
204
  end
177
205
 
178
206
  def clear_cache
179
207
  @unbound_templates.clear
180
- super()
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 = Template::Sources::File.new(template)
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!(/:action/, partial)
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
- pieces = File.basename(path).split(".")
274
- pieces.shift
275
-
276
- extension = pieces.pop
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, pattern = nil)
325
+ def initialize(path)
300
326
  raise ArgumentError, "path already is a Resolver class" if path.is_a?(Resolver)
301
- super(pattern)
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 find_template_paths_from_details(path, details)
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
- Dir[query].uniq.reject do |filename|
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.reverse.map do |ext|
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.uniq.map { |e| Regexp.escape(e) }.join("|")
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}))?"
@@ -27,9 +27,6 @@ module ActionView #:nodoc:
27
27
  def format
28
28
  :text
29
29
  end
30
-
31
- def formats; Array(format); end
32
- deprecate :formats
33
30
  end
34
31
  end
35
32
  end
@@ -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, :original_encoding, :updated_at
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, locals: nil, virtual_path: nil, updated_at: 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[-1] == "/" ? "" : ::File.basename(@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.sub("#{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, @updated_at, @format, @variant ]
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, @updated_at, @format, @variant = *array
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
- attr_writer :controller_path
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 = (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
- _helpers.module_eval <<-end_eval, __FILE__, __LINE__ + 1
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
- @controller = ActionView::TestCase::TestController.new
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
- make_test_case_available_to_view!
113
- say_no_to_protect_against_forgery!
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
- private
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
- def make_test_case_available_to_view!
181
- test_case_instance = self
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 = {}, pattern = nil)
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 query(path, exts, _, locals, cache:)
31
- regex = build_regex(path, exts)
32
-
33
- @hash.select do |_path, _|
34
- ("/" + _path).match?(regex)
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