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.

Files changed (87) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +280 -94
  3. data/MIT-LICENSE +1 -1
  4. data/README.rdoc +5 -3
  5. data/lib/action_view/base.rb +108 -11
  6. data/lib/action_view/buffers.rb +15 -0
  7. data/lib/action_view/cache_expiry.rb +53 -0
  8. data/lib/action_view/context.rb +5 -9
  9. data/lib/action_view/digestor.rb +12 -20
  10. data/lib/action_view/flows.rb +0 -1
  11. data/lib/action_view/gem_version.rb +3 -3
  12. data/lib/action_view/helpers/active_model_helper.rb +0 -1
  13. data/lib/action_view/helpers/asset_tag_helper.rb +8 -31
  14. data/lib/action_view/helpers/asset_url_helper.rb +4 -3
  15. data/lib/action_view/helpers/cache_helper.rb +19 -12
  16. data/lib/action_view/helpers/capture_helper.rb +4 -0
  17. data/lib/action_view/helpers/csp_helper.rb +4 -2
  18. data/lib/action_view/helpers/csrf_helper.rb +1 -1
  19. data/lib/action_view/helpers/date_helper.rb +70 -27
  20. data/lib/action_view/helpers/form_helper.rb +240 -8
  21. data/lib/action_view/helpers/form_options_helper.rb +27 -18
  22. data/lib/action_view/helpers/form_tag_helper.rb +17 -15
  23. data/lib/action_view/helpers/javascript_helper.rb +9 -8
  24. data/lib/action_view/helpers/number_helper.rb +8 -2
  25. data/lib/action_view/helpers/output_safety_helper.rb +1 -1
  26. data/lib/action_view/helpers/rendering_helper.rb +6 -4
  27. data/lib/action_view/helpers/sanitize_helper.rb +12 -18
  28. data/lib/action_view/helpers/tag_helper.rb +8 -7
  29. data/lib/action_view/helpers/tags/base.rb +9 -6
  30. data/lib/action_view/helpers/tags/check_box.rb +0 -1
  31. data/lib/action_view/helpers/tags/collection_check_boxes.rb +0 -1
  32. data/lib/action_view/helpers/tags/collection_helpers.rb +0 -1
  33. data/lib/action_view/helpers/tags/collection_radio_buttons.rb +0 -1
  34. data/lib/action_view/helpers/tags/color_field.rb +1 -2
  35. data/lib/action_view/helpers/tags/date_field.rb +0 -1
  36. data/lib/action_view/helpers/tags/date_select.rb +0 -1
  37. data/lib/action_view/helpers/tags/datetime_field.rb +0 -1
  38. data/lib/action_view/helpers/tags/datetime_local_field.rb +0 -1
  39. data/lib/action_view/helpers/tags/label.rb +0 -1
  40. data/lib/action_view/helpers/tags/month_field.rb +0 -1
  41. data/lib/action_view/helpers/tags/radio_button.rb +0 -1
  42. data/lib/action_view/helpers/tags/select.rb +0 -1
  43. data/lib/action_view/helpers/tags/text_field.rb +0 -1
  44. data/lib/action_view/helpers/tags/time_field.rb +0 -1
  45. data/lib/action_view/helpers/tags/translator.rb +1 -6
  46. data/lib/action_view/helpers/tags/week_field.rb +0 -1
  47. data/lib/action_view/helpers/text_helper.rb +3 -4
  48. data/lib/action_view/helpers/translation_helper.rb +19 -17
  49. data/lib/action_view/helpers/url_helper.rb +14 -14
  50. data/lib/action_view/helpers.rb +0 -2
  51. data/lib/action_view/layouts.rb +5 -8
  52. data/lib/action_view/log_subscriber.rb +6 -7
  53. data/lib/action_view/lookup_context.rb +75 -32
  54. data/lib/action_view/path_set.rb +5 -11
  55. data/lib/action_view/railtie.rb +24 -1
  56. data/lib/action_view/record_identifier.rb +2 -3
  57. data/lib/action_view/renderer/abstract_renderer.rb +56 -4
  58. data/lib/action_view/renderer/partial_renderer/collection_caching.rb +63 -17
  59. data/lib/action_view/renderer/partial_renderer.rb +67 -57
  60. data/lib/action_view/renderer/renderer.rb +16 -4
  61. data/lib/action_view/renderer/streaming_template_renderer.rb +5 -7
  62. data/lib/action_view/renderer/template_renderer.rb +25 -20
  63. data/lib/action_view/rendering.rb +51 -32
  64. data/lib/action_view/routing_url_for.rb +12 -11
  65. data/lib/action_view/template/error.rb +30 -15
  66. data/lib/action_view/template/handlers/builder.rb +2 -2
  67. data/lib/action_view/template/handlers/erb/erubi.rb +7 -3
  68. data/lib/action_view/template/handlers/erb.rb +17 -8
  69. data/lib/action_view/template/handlers/html.rb +1 -1
  70. data/lib/action_view/template/handlers/raw.rb +2 -2
  71. data/lib/action_view/template/handlers.rb +27 -1
  72. data/lib/action_view/template/html.rb +14 -5
  73. data/lib/action_view/template/inline.rb +22 -0
  74. data/lib/action_view/template/raw_file.rb +28 -0
  75. data/lib/action_view/template/resolver.rb +134 -135
  76. data/lib/action_view/template/sources/file.rb +17 -0
  77. data/lib/action_view/template/sources.rb +13 -0
  78. data/lib/action_view/template/text.rb +5 -3
  79. data/lib/action_view/template.rb +102 -71
  80. data/lib/action_view/test_case.rb +3 -4
  81. data/lib/action_view/testing/resolvers.rb +33 -21
  82. data/lib/action_view/unbound_template.rb +31 -0
  83. data/lib/action_view/view_paths.rb +25 -2
  84. data/lib/action_view.rb +4 -2
  85. data/lib/assets/compiled/rails-ujs.js +30 -4
  86. metadata +27 -18
  87. data/lib/action_view/helpers/record_tag_helper.rb +0 -23
@@ -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
- attr_accessor :locals, :formats, :variants, :virtual_path
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
- # This finalizer is needed (and exactly with a proc inside another proc)
119
- # otherwise templates leak in development.
120
- Finalizer = proc do |method_name, mod| # :nodoc:
121
- proc do
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
- @original_encoding = nil
136
- @locals = details[:locals] || []
137
- @virtual_path = details[:virtual_path]
138
- @updated_at = details[:updated_at] || Time.now
139
- @formats = Array(format).map { |f| f.respond_to?(:ref) ? f.ref : f }
140
- @variants = [details[:variant]]
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 = nil, &block)
182
+ def render(view, locals, buffer = ActionView::OutputBuffer.new, &block)
157
183
  instrument_render_template do
158
184
  compile!(view)
159
- view.send(method_name, locals, buffer, &block)
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[@formats.first] if @formats.first
192
+ @type ||= Types[format]
167
193
  end
168
194
 
169
- # Receives a view object and return a template similar to self by using @virtual_path.
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
- @inspect ||= defined?(Rails.root) ? identifier.sub("#{Rails.root}/", "".freeze) : identifier
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
- return unless source.encoding == Encoding::BINARY
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
- if view.is_a?(ActionView::CompiledTemplates)
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
- source = <<-end_src.dup
318
+ original_source = source
319
+ source = +<<-end_src
288
320
  def #{method_name}(local_assigns, output_buffer)
289
- _old_virtual_path, @virtual_path = @virtual_path, #{@virtual_path.inspect};_old_output_buffer = @output_buffer;#{locals_code};#{code}
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(@source, Encoding.default_internal)
336
+ raise WrongEncodingError.new(source, Encoding.default_internal)
307
337
  end
308
338
 
309
- mod.module_eval(source, identifier, 0)
310
- ObjectSpace.define_finalizer(self, Finalizer[method_name, mod])
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
- template = self
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("".dup) { |key, code| code << "#{key} = local_assigns[:#{key}]; #{key} = #{key};" }
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__}".dup
340
- m.tr!("-".freeze, "_".freeze)
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
- inspect.tr("^a-z_".freeze, "_".freeze)
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".freeze, instrument_payload, &block)
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(%(#{method}), *args, &block) # _test_case.send(%(current_user), *args, &block)
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 = "".dup
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 < PathResolver
11
- attr_reader :hash
12
-
10
+ class FixtureResolver < OptimizedFileSystemResolver
13
11
  def initialize(hash = {}, pattern = nil)
14
- super(pattern)
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
- def query(path, exts, _, _)
25
- query = "".dup
26
- EXTENSIONS.each_key do |ext|
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
- templates << Template.new(source, _path, handler,
37
+
38
+ Template.new(source, _path, handler,
37
39
  virtual_path: path.virtual,
38
40
  format: format,
39
41
  variant: variant,
40
- updated_at: updated_at
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
- class_attribute :_view_paths, default: ActionView::PathSet.new.freeze
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-2018 David Heinemeier Hansson
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/master/actionview/app/assets/javascripts
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
- element = e instanceof Event ? e.target : e;
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;