actionview 6.0.6.1 → 6.1.0.rc1

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 (66) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +152 -325
  3. data/MIT-LICENSE +1 -1
  4. data/README.rdoc +1 -1
  5. data/lib/action_view/base.rb +20 -51
  6. data/lib/action_view/cache_expiry.rb +1 -2
  7. data/lib/action_view/context.rb +0 -1
  8. data/lib/action_view/dependency_tracker.rb +10 -4
  9. data/lib/action_view/digestor.rb +3 -2
  10. data/lib/action_view/gem_version.rb +3 -3
  11. data/lib/action_view/helpers/asset_tag_helper.rb +40 -15
  12. data/lib/action_view/helpers/asset_url_helper.rb +6 -4
  13. data/lib/action_view/helpers/atom_feed_helper.rb +2 -1
  14. data/lib/action_view/helpers/cache_helper.rb +10 -16
  15. data/lib/action_view/helpers/date_helper.rb +4 -4
  16. data/lib/action_view/helpers/form_helper.rb +59 -17
  17. data/lib/action_view/helpers/form_options_helper.rb +7 -16
  18. data/lib/action_view/helpers/form_tag_helper.rb +8 -6
  19. data/lib/action_view/helpers/javascript_helper.rb +3 -3
  20. data/lib/action_view/helpers/number_helper.rb +6 -6
  21. data/lib/action_view/helpers/rendering_helper.rb +11 -3
  22. data/lib/action_view/helpers/sanitize_helper.rb +2 -2
  23. data/lib/action_view/helpers/tag_helper.rb +96 -52
  24. data/lib/action_view/helpers/tags/base.rb +9 -5
  25. data/lib/action_view/helpers/tags/date_field.rb +1 -1
  26. data/lib/action_view/helpers/tags/date_select.rb +2 -2
  27. data/lib/action_view/helpers/tags/datetime_local_field.rb +1 -1
  28. data/lib/action_view/helpers/tags/label.rb +4 -0
  29. data/lib/action_view/helpers/tags/month_field.rb +1 -1
  30. data/lib/action_view/helpers/tags/select.rb +1 -1
  31. data/lib/action_view/helpers/tags/time_field.rb +1 -1
  32. data/lib/action_view/helpers/tags/week_field.rb +1 -1
  33. data/lib/action_view/helpers/text_helper.rb +1 -1
  34. data/lib/action_view/helpers/translation_helper.rb +88 -53
  35. data/lib/action_view/helpers/url_helper.rb +107 -13
  36. data/lib/action_view/layouts.rb +3 -2
  37. data/lib/action_view/log_subscriber.rb +26 -10
  38. data/lib/action_view/lookup_context.rb +3 -18
  39. data/lib/action_view/path_set.rb +0 -3
  40. data/lib/action_view/railtie.rb +35 -46
  41. data/lib/action_view/renderer/abstract_renderer.rb +93 -14
  42. data/lib/action_view/renderer/collection_renderer.rb +192 -0
  43. data/lib/action_view/renderer/object_renderer.rb +34 -0
  44. data/lib/action_view/renderer/partial_renderer/collection_caching.rb +25 -26
  45. data/lib/action_view/renderer/partial_renderer.rb +20 -282
  46. data/lib/action_view/renderer/renderer.rb +44 -1
  47. data/lib/action_view/renderer/streaming_template_renderer.rb +5 -1
  48. data/lib/action_view/renderer/template_renderer.rb +15 -12
  49. data/lib/action_view/rendering.rb +3 -1
  50. data/lib/action_view/routing_url_for.rb +1 -1
  51. data/lib/action_view/template/handlers/erb/erubi.rb +9 -7
  52. data/lib/action_view/template/handlers/erb.rb +10 -14
  53. data/lib/action_view/template/handlers.rb +0 -26
  54. data/lib/action_view/template/html.rb +1 -11
  55. data/lib/action_view/template/raw_file.rb +0 -3
  56. data/lib/action_view/template/renderable.rb +24 -0
  57. data/lib/action_view/template/resolver.rb +82 -40
  58. data/lib/action_view/template/text.rb +0 -3
  59. data/lib/action_view/template.rb +9 -49
  60. data/lib/action_view/test_case.rb +18 -25
  61. data/lib/action_view/testing/resolvers.rb +10 -31
  62. data/lib/action_view/unbound_template.rb +3 -3
  63. data/lib/action_view/view_paths.rb +34 -36
  64. data/lib/action_view.rb +4 -1
  65. data/lib/assets/compiled/rails-ujs.js +1 -1
  66. metadata +20 -18
@@ -3,7 +3,6 @@
3
3
  require "active_support/core_ext/module/attr_internal"
4
4
  require "active_support/core_ext/module/attribute_accessors"
5
5
  require "active_support/ordered_options"
6
- require "active_support/deprecation"
7
6
  require "action_view/log_subscriber"
8
7
  require "action_view/helpers"
9
8
  require "action_view/context"
@@ -28,7 +27,7 @@ module ActionView #:nodoc:
28
27
  # Name: <%= person.name %><br/>
29
28
  # <% end %>
30
29
  #
31
- # The loop is setup in regular embedding tags <tt><% %></tt>, and the name is written using the output embedding tag <tt><%= %></tt>. Note that this
30
+ # The loop is set up in regular embedding tags <tt><% %></tt>, and the name is written using the output embedding tag <tt><%= %></tt>. Note that this
32
31
  # is not just a usage suggestion. Regular output functions like print or puts won't work with ERB templates. So this would be wrong:
33
32
  #
34
33
  # <%# WRONG %>
@@ -163,6 +162,9 @@ module ActionView #:nodoc:
163
162
  # Specify whether submit_tag should automatically disable on click
164
163
  cattr_accessor :automatically_disable_submit_tag, default: true
165
164
 
165
+ # Annotate rendered view with file names
166
+ cattr_accessor :annotate_rendered_view_with_filenames, default: false
167
+
166
168
  class_attribute :_routes
167
169
  class_attribute :logger
168
170
 
@@ -188,6 +190,10 @@ module ActionView #:nodoc:
188
190
  # correctly.
189
191
  define_method(:compiled_method_container) { subclass }
190
192
  define_singleton_method(:compiled_method_container) { subclass }
193
+
194
+ def inspect
195
+ "#<ActionView::Base:#{'%#016x' % (object_id << 1)}>"
196
+ end
191
197
  }
192
198
  end
193
199
 
@@ -207,21 +213,6 @@ module ActionView #:nodoc:
207
213
 
208
214
  # :stopdoc:
209
215
 
210
- def self.build_lookup_context(context)
211
- case context
212
- when ActionView::Renderer
213
- context.lookup_context
214
- when Array
215
- ActionView::LookupContext.new(context)
216
- when ActionView::PathSet
217
- ActionView::LookupContext.new(context)
218
- when nil
219
- ActionView::LookupContext.new([])
220
- else
221
- raise NotImplementedError, context.class.name
222
- end
223
- end
224
-
225
216
  def self.empty
226
217
  with_view_paths([])
227
218
  end
@@ -234,58 +225,36 @@ module ActionView #:nodoc:
234
225
  new context, assigns, controller
235
226
  end
236
227
 
237
- NULL = Object.new
238
-
239
228
  # :startdoc:
240
229
 
241
- def initialize(lookup_context = nil, assigns = {}, controller = nil, formats = NULL) #:nodoc:
230
+ def initialize(lookup_context, assigns, controller) #:nodoc:
242
231
  @_config = ActiveSupport::InheritableOptions.new
243
232
 
244
- unless formats == NULL
245
- ActiveSupport::Deprecation.warn <<~eowarn.squish
246
- Passing formats to ActionView::Base.new is deprecated
247
- eowarn
248
- end
249
-
250
- case lookup_context
251
- when ActionView::LookupContext
252
- @lookup_context = lookup_context
253
- else
254
- ActiveSupport::Deprecation.warn <<~eowarn.squish
255
- ActionView::Base instances should be constructed with a lookup context,
256
- assignments, and a controller.
257
- eowarn
258
- @lookup_context = self.class.build_lookup_context(lookup_context)
259
- end
233
+ @lookup_context = lookup_context
260
234
 
261
235
  @view_renderer = ActionView::Renderer.new @lookup_context
262
236
  @current_template = nil
263
237
 
264
- @cache_hit = {}
265
238
  assign(assigns)
266
239
  assign_controller(controller)
267
240
  _prepare_context
268
241
  end
269
242
 
270
- def _run(method, template, locals, buffer, &block)
271
- _old_output_buffer, _old_virtual_path, _old_template = @output_buffer, @virtual_path, @current_template
272
- @current_template = template
243
+ def _run(method, template, locals, buffer, add_to_stack: true, &block)
244
+ _old_output_buffer, _old_template = @output_buffer, @current_template
245
+ @current_template = template if add_to_stack
273
246
  @output_buffer = buffer
274
- send(method, locals, buffer, &block)
247
+ public_send(method, locals, buffer, &block)
275
248
  ensure
276
- @output_buffer, @virtual_path, @current_template = _old_output_buffer, _old_virtual_path, _old_template
249
+ @output_buffer, @current_template = _old_output_buffer, _old_template
277
250
  end
278
251
 
279
252
  def compiled_method_container
280
- if self.class == ActionView::Base
281
- ActiveSupport::Deprecation.warn <<~eowarn.squish
282
- ActionView::Base instances must implement `compiled_method_container`
283
- or use the class method `with_empty_template_cache` for constructing
284
- an ActionView::Base instance that has an empty cache.
285
- eowarn
286
- end
287
-
288
- self.class
253
+ raise NotImplementedError, <<~msg.squish
254
+ Subclasses of ActionView::Base must implement `compiled_method_container`
255
+ or use the class method `with_empty_template_cache` for constructing
256
+ an ActionView::Base subclass that has an empty cache.
257
+ msg
289
258
  end
290
259
 
291
260
  def in_rendering_context(options)
@@ -42,8 +42,7 @@ module ActionView
42
42
 
43
43
  private
44
44
  def dirs_to_watch
45
- fs_paths = all_view_paths.grep(FileSystemResolver)
46
- fs_paths.map(&:path).sort.uniq
45
+ all_view_paths.grep(FileSystemResolver).map!(&:path).tap(&:uniq!).sort!
47
46
  end
48
47
 
49
48
  def all_view_paths
@@ -18,7 +18,6 @@ module ActionView
18
18
  def _prepare_context
19
19
  @view_flow = OutputFlow.new
20
20
  @output_buffer = nil
21
- @virtual_path = nil
22
21
  end
23
22
 
24
23
  # Encapsulates the interaction with the view flow so it
@@ -130,8 +130,9 @@ module ActionView
130
130
 
131
131
  def add_dependencies(render_dependencies, arguments, pattern)
132
132
  arguments.scan(pattern) do
133
- add_dynamic_dependency(render_dependencies, Regexp.last_match[:dynamic])
134
- add_static_dependency(render_dependencies, Regexp.last_match[:static])
133
+ match = Regexp.last_match
134
+ add_dynamic_dependency(render_dependencies, match[:dynamic])
135
+ add_static_dependency(render_dependencies, match[:static], match[:quote])
135
136
  end
136
137
  end
137
138
 
@@ -141,7 +142,12 @@ module ActionView
141
142
  end
142
143
  end
143
144
 
144
- def add_static_dependency(dependencies, dependency)
145
+ def add_static_dependency(dependencies, dependency, quote_type)
146
+ if quote_type == '"'
147
+ # Ignore if there is interpolation
148
+ return if dependency.include?('#{')
149
+ end
150
+
145
151
  if dependency
146
152
  if dependency.include?("/")
147
153
  dependencies << dependency
@@ -164,7 +170,7 @@ module ActionView
164
170
  def explicit_dependencies
165
171
  dependencies = source.scan(EXPLICIT_DEPENDENCY).flatten.uniq
166
172
 
167
- wildcards, explicits = dependencies.partition { |dependency| dependency[-1] == "*" }
173
+ wildcards, explicits = dependencies.partition { |dependency| dependency.end_with?("*") }
168
174
 
169
175
  (explicits + resolve_directories(wildcards)).uniq
170
176
  end
@@ -41,8 +41,9 @@ module ActionView
41
41
  # Create a dependency tree for template named +name+.
42
42
  def tree(name, finder, partial = false, seen = {})
43
43
  logical_name = name.gsub(%r|/_|, "/")
44
+ interpolated = name.include?("#")
44
45
 
45
- if template = find_template(finder, logical_name, [], partial, [])
46
+ if !interpolated && (template = find_template(finder, logical_name, [], partial, []))
46
47
  if node = seen[template.identifier] # handle cycles in the tree
47
48
  node
48
49
  else
@@ -55,7 +56,7 @@ module ActionView
55
56
  node
56
57
  end
57
58
  else
58
- unless name.include?("#") # Dynamic template partial names can never be tracked
59
+ unless interpolated # Dynamic template partial names can never be tracked
59
60
  logger.error " Couldn't find template for digesting: #{name}"
60
61
  end
61
62
 
@@ -8,9 +8,9 @@ module ActionView
8
8
 
9
9
  module VERSION
10
10
  MAJOR = 6
11
- MINOR = 0
12
- TINY = 6
13
- PRE = "1"
11
+ MINOR = 1
12
+ TINY = 0
13
+ PRE = "rc1"
14
14
 
15
15
  STRING = [MAJOR, MINOR, TINY, PRE].compact.join(".")
16
16
  end
@@ -3,7 +3,6 @@
3
3
  require "active_support/core_ext/array/extract_options"
4
4
  require "active_support/core_ext/hash/keys"
5
5
  require "active_support/core_ext/object/inclusion"
6
- require "active_support/core_ext/object/try"
7
6
  require "action_view/helpers/asset_url_helper"
8
7
  require "action_view/helpers/tag_helper"
9
8
 
@@ -30,7 +29,7 @@ module ActionView
30
29
  # to <tt>assets/javascripts</tt>, full paths are assumed to be relative to the document
31
30
  # root. Relative paths are idiomatic, use absolute paths only when needed.
32
31
  #
33
- # When passing paths, the ".js" extension is optional. If you do not want ".js"
32
+ # When passing paths, the ".js" extension is optional. If you do not want ".js"
34
33
  # appended to the path <tt>extname: false</tt> can be set on the options.
35
34
  #
36
35
  # You can modify the HTML attributes of the script tag by passing a hash as the
@@ -87,13 +86,22 @@ module ActionView
87
86
  def javascript_include_tag(*sources)
88
87
  options = sources.extract_options!.stringify_keys
89
88
  path_options = options.extract!("protocol", "extname", "host", "skip_pipeline").symbolize_keys
90
- early_hints_links = []
89
+ preload_links = []
90
+ nopush = options["nopush"].nil? ? true : options.delete("nopush")
91
+ crossorigin = options.delete("crossorigin")
92
+ crossorigin = "anonymous" if crossorigin == true
91
93
 
92
94
  sources_tags = sources.uniq.map { |source|
93
95
  href = path_to_javascript(source, path_options)
94
- early_hints_links << "<#{href}>; rel=preload; as=script"
96
+ unless options["defer"]
97
+ preload_link = "<#{href}>; rel=preload; as=script"
98
+ preload_link += "; crossorigin=#{crossorigin}" unless crossorigin.nil?
99
+ preload_link += "; nopush" if nopush
100
+ preload_links << preload_link
101
+ end
95
102
  tag_options = {
96
- "src" => href
103
+ "src" => href,
104
+ "crossorigin" => crossorigin
97
105
  }.merge!(options)
98
106
  if tag_options["nonce"] == true
99
107
  tag_options["nonce"] = content_security_policy_nonce
@@ -101,7 +109,7 @@ module ActionView
101
109
  content_tag("script", "", tag_options)
102
110
  }.join("\n").html_safe
103
111
 
104
- request.send_early_hints("Link" => early_hints_links.join("\n")) if respond_to?(:request) && request
112
+ send_preload_links_header(preload_links)
105
113
 
106
114
  sources_tags
107
115
  end
@@ -137,20 +145,27 @@ module ActionView
137
145
  def stylesheet_link_tag(*sources)
138
146
  options = sources.extract_options!.stringify_keys
139
147
  path_options = options.extract!("protocol", "host", "skip_pipeline").symbolize_keys
140
- early_hints_links = []
148
+ preload_links = []
149
+ crossorigin = options.delete("crossorigin")
150
+ crossorigin = "anonymous" if crossorigin == true
151
+ nopush = options["nopush"].nil? ? true : options.delete("nopush")
141
152
 
142
153
  sources_tags = sources.uniq.map { |source|
143
154
  href = path_to_stylesheet(source, path_options)
144
- early_hints_links << "<#{href}>; rel=preload; as=style"
155
+ preload_link = "<#{href}>; rel=preload; as=style"
156
+ preload_link += "; crossorigin=#{crossorigin}" unless crossorigin.nil?
157
+ preload_link += "; nopush" if nopush
158
+ preload_links << preload_link
145
159
  tag_options = {
146
160
  "rel" => "stylesheet",
147
161
  "media" => "screen",
162
+ "crossorigin" => crossorigin,
148
163
  "href" => href
149
164
  }.merge!(options)
150
165
  tag(:link, tag_options)
151
166
  }.join("\n").html_safe
152
167
 
153
- request.send_early_hints("Link" => early_hints_links.join("\n")) if respond_to?(:request) && request
168
+ send_preload_links_header(preload_links)
154
169
 
155
170
  sources_tags
156
171
  end
@@ -268,7 +283,7 @@ module ActionView
268
283
  def preload_link_tag(source, options = {})
269
284
  href = asset_path(source, skip_pipeline: options.delete(:skip_pipeline))
270
285
  extname = File.extname(source).downcase.delete(".")
271
- mime_type = options.delete(:type) || Template::Types[extname].try(:to_s)
286
+ mime_type = options.delete(:type) || Template::Types[extname]&.to_s
272
287
  as_type = options.delete(:as) || resolve_link_as(extname, mime_type)
273
288
  crossorigin = options.delete(:crossorigin)
274
289
  crossorigin = "anonymous" if crossorigin == true || (crossorigin.blank? && as_type == "font")
@@ -282,12 +297,12 @@ module ActionView
282
297
  crossorigin: crossorigin
283
298
  }.merge!(options.symbolize_keys))
284
299
 
285
- early_hints_link = "<#{href}>; rel=preload; as=#{as_type}"
286
- early_hints_link += "; type=#{mime_type}" if mime_type
287
- early_hints_link += "; crossorigin=#{crossorigin}" if crossorigin
288
- early_hints_link += "; nopush" if nopush
300
+ preload_link = "<#{href}>; rel=preload; as=#{as_type}"
301
+ preload_link += "; type=#{mime_type}" if mime_type
302
+ preload_link += "; crossorigin=#{crossorigin}" if crossorigin
303
+ preload_link += "; nopush" if nopush
289
304
 
290
- request.send_early_hints("Link" => early_hints_link) if respond_to?(:request) && request
305
+ send_preload_links_header([preload_link])
291
306
 
292
307
  link_tag
293
308
  end
@@ -483,6 +498,16 @@ module ActionView
483
498
  type
484
499
  end
485
500
  end
501
+
502
+ def send_preload_links_header(preload_links)
503
+ if respond_to?(:request) && request
504
+ request.send_early_hints("Link" => preload_links.join("\n"))
505
+ end
506
+
507
+ if respond_to?(:response) && response
508
+ response.headers["Link"] = [response.headers["Link"].presence, *preload_links].compact.join(",")
509
+ end
510
+ end
486
511
  end
487
512
  end
488
513
  end
@@ -52,7 +52,7 @@ module ActionView
52
52
  # solution being slower. You should be sure to measure your actual
53
53
  # performance across targeted browsers both before and after this change.
54
54
  #
55
- # To implement the corresponding hosts you can either setup four actual
55
+ # To implement the corresponding hosts you can either set up four actual
56
56
  # hosts or use wildcard DNS to CNAME the wildcard to a single asset host.
57
57
  # You can read more about setting up your DNS CNAME records from your ISP.
58
58
  #
@@ -80,7 +80,7 @@ module ActionView
80
80
  # absolute path of the asset, for example "/assets/rails.png".
81
81
  #
82
82
  # ActionController::Base.asset_host = Proc.new { |source|
83
- # if source.ends_with?('.css')
83
+ # if source.end_with?('.css')
84
84
  # "http://stylesheets.example.com"
85
85
  # else
86
86
  # "http://assets.example.com"
@@ -98,7 +98,7 @@ module ActionView
98
98
  # have SSL certificates for each of the asset hosts this technique allows you
99
99
  # to avoid warnings in the client about mixed media.
100
100
  # Note that the +request+ parameter might not be supplied, e.g. when the assets
101
- # are precompiled with the command `rails assets:precompile`. Make sure to use a
101
+ # are precompiled with the command `bin/rails assets:precompile`. Make sure to use a
102
102
  # +Proc+ instead of a lambda, since a +Proc+ allows missing parameters and sets them
103
103
  # to +nil+.
104
104
  #
@@ -133,6 +133,8 @@ module ActionView
133
133
  # which is implemented by sprockets-rails.
134
134
  #
135
135
  # asset_path("application.js") # => "/assets/application-60aa4fdc5cea14baf5400fba1abf4f2a46a5166bad4772b1effe341570f07de9.js"
136
+ # asset_path('application.js', host: 'example.com') # => "//example.com/assets/application.js"
137
+ # asset_path("application.js", host: 'example.com', protocol: 'https') # => "https://example.com/assets/application.js"
136
138
  #
137
139
  # === Without the asset pipeline (<tt>skip_pipeline: true</tt>)
138
140
  #
@@ -204,7 +206,7 @@ module ActionView
204
206
 
205
207
  relative_url_root = defined?(config.relative_url_root) && config.relative_url_root
206
208
  if relative_url_root
207
- source = File.join(relative_url_root, source) unless source.starts_with?("#{relative_url_root}/")
209
+ source = File.join(relative_url_root, source) unless source.start_with?("#{relative_url_root}/")
208
210
  end
209
211
 
210
212
  if host = compute_asset_host(source, options)
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "set"
4
+ require "active_support/core_ext/symbol/starts_ends_with"
4
5
 
5
6
  module ActionView
6
7
  # = Action View Atom Feed Helpers
@@ -115,7 +116,7 @@ module ActionView
115
116
  end
116
117
 
117
118
  feed_opts = { "xml:lang" => options[:language] || "en-US", "xmlns" => "http://www.w3.org/2005/Atom" }
118
- feed_opts.merge!(options).reject! { |k, v| !k.to_s.match(/^xml/) }
119
+ feed_opts.merge!(options).select! { |k, _| k.start_with?("xml") }
119
120
 
120
121
  xml.feed(feed_opts) do
121
122
  xml.id(options[:id] || "tag:#{request.host},#{options[:schema_date]}:#{request.fullpath.split(".")[0]}")
@@ -24,8 +24,8 @@ module ActionView
24
24
  # This approach will assume that when a new topic is added, you'll touch
25
25
  # the project. The cache key generated from this call will be something like:
26
26
  #
27
- # views/template/action.html.erb:7a1156131a6928cb0026877f8b749ac9/projects/123
28
- # ^template path ^template tree digest ^class ^id
27
+ # views/template/action:7a1156131a6928cb0026877f8b749ac9/projects/123
28
+ # ^template path ^template tree digest ^class ^id
29
29
  #
30
30
  # This cache key is stable, but it's combined with a cache version derived from the project
31
31
  # record. When the project updated_at is touched, the #cache_version changes, even
@@ -165,7 +165,7 @@ module ActionView
165
165
  # expire the cache.
166
166
  def cache(name = {}, options = {}, &block)
167
167
  if controller.respond_to?(:perform_caching) && controller.perform_caching
168
- name_options = options.slice(:skip_digest, :virtual_path)
168
+ name_options = options.slice(:skip_digest)
169
169
  safe_concat(fragment_for(cache_fragment_name(name, **name_options), options, &block))
170
170
  else
171
171
  yield
@@ -205,14 +205,11 @@ module ActionView
205
205
  # fragments can be manually bypassed. This is useful when cache fragments
206
206
  # cannot be manually expired unless you know the exact key which is the
207
207
  # case when using memcached.
208
- #
209
- # The digest will be generated using +virtual_path:+ if it is provided.
210
- #
211
- def cache_fragment_name(name = {}, skip_digest: nil, virtual_path: nil, digest_path: nil)
208
+ def cache_fragment_name(name = {}, skip_digest: nil, digest_path: nil)
212
209
  if skip_digest
213
210
  name
214
211
  else
215
- fragment_name_with_digest(name, virtual_path, digest_path)
212
+ fragment_name_with_digest(name, digest_path)
216
213
  end
217
214
  end
218
215
 
@@ -227,14 +224,11 @@ module ActionView
227
224
  end
228
225
 
229
226
  private
230
- def fragment_name_with_digest(name, virtual_path, digest_path)
231
- virtual_path ||= @virtual_path
232
-
233
- if virtual_path || digest_path
234
- name = controller.url_for(name).split("://").last if name.is_a?(Hash)
227
+ def fragment_name_with_digest(name, digest_path)
228
+ name = controller.url_for(name).split("://").last if name.is_a?(Hash)
235
229
 
230
+ if @current_template&.virtual_path || digest_path
236
231
  digest_path ||= digest_path_from_template(@current_template)
237
-
238
232
  [ digest_path, name ]
239
233
  else
240
234
  name
@@ -243,10 +237,10 @@ module ActionView
243
237
 
244
238
  def fragment_for(name = {}, options = nil, &block)
245
239
  if content = read_fragment_for(name, options)
246
- @view_renderer.cache_hits[@virtual_path] = :hit if defined?(@view_renderer)
240
+ @view_renderer.cache_hits[@current_template&.virtual_path] = :hit if defined?(@view_renderer)
247
241
  content
248
242
  else
249
- @view_renderer.cache_hits[@virtual_path] = :miss if defined?(@view_renderer)
243
+ @view_renderer.cache_hits[@current_template&.virtual_path] = :miss if defined?(@view_renderer)
250
244
  write_fragment_for(name, options, &block)
251
245
  end
252
246
  end
@@ -197,8 +197,8 @@ module ActionView
197
197
  # and +:name+ (string). A format string would be something like "%{name} (%<number>02d)" for example.
198
198
  # See <tt>Kernel.sprintf</tt> for documentation on format sequences.
199
199
  # * <tt>:date_separator</tt> - Specifies a string to separate the date fields. Default is "" (i.e. nothing).
200
- # * <tt>:time_separator</tt> - Specifies a string to separate the time fields. Default is "" (i.e. nothing).
201
- # * <tt>:datetime_separator</tt>- Specifies a string to separate the date and time fields. Default is "" (i.e. nothing).
200
+ # * <tt>:time_separator</tt> - Specifies a string to separate the time fields. Default is " : ".
201
+ # * <tt>:datetime_separator</tt>- Specifies a string to separate the date and time fields. Default is " &mdash; ".
202
202
  # * <tt>:start_year</tt> - Set the start year for the year select. Default is <tt>Date.today.year - 5</tt> if
203
203
  # you are creating new record. While editing existing record, <tt>:start_year</tt> defaults to
204
204
  # the current selected year minus 5.
@@ -1053,7 +1053,7 @@ module ActionView
1053
1053
  select_options[:class] = css_class_attribute(type, select_options[:class], @options[:with_css_classes]) if @options[:with_css_classes]
1054
1054
 
1055
1055
  select_html = +"\n"
1056
- select_html << content_tag("option", "", value: "") + "\n" if @options[:include_blank]
1056
+ select_html << content_tag("option", "", value: "", label: " ") + "\n" if @options[:include_blank]
1057
1057
  select_html << prompt_option_tag(type, @options[:prompt]) + "\n" if @options[:prompt]
1058
1058
  select_html << select_options_as_html
1059
1059
 
@@ -1138,7 +1138,7 @@ module ActionView
1138
1138
  first_visible = order.find { |type| !@options[:"discard_#{type}"] }
1139
1139
  order.reverse_each do |type|
1140
1140
  separator = separator(type) unless type == first_visible # don't add before first visible field
1141
- select.insert(0, separator.to_s + send("select_#{type}").to_s)
1141
+ select.insert(0, separator.to_s + public_send("select_#{type}").to_s)
1142
1142
  end
1143
1143
  select.html_safe
1144
1144
  end