actionview 4.2.11.1 → 7.0.2.4

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 (124) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +229 -215
  3. data/MIT-LICENSE +1 -1
  4. data/README.rdoc +9 -8
  5. data/lib/action_view/base.rb +116 -43
  6. data/lib/action_view/buffers.rb +20 -3
  7. data/lib/action_view/cache_expiry.rb +66 -0
  8. data/lib/action_view/context.rb +8 -12
  9. data/lib/action_view/dependency_tracker/erb_tracker.rb +154 -0
  10. data/lib/action_view/dependency_tracker/ripper_tracker.rb +59 -0
  11. data/lib/action_view/dependency_tracker.rb +21 -122
  12. data/lib/action_view/digestor.rb +92 -85
  13. data/lib/action_view/flows.rb +15 -16
  14. data/lib/action_view/gem_version.rb +6 -4
  15. data/lib/action_view/helpers/active_model_helper.rb +17 -12
  16. data/lib/action_view/helpers/asset_tag_helper.rb +356 -101
  17. data/lib/action_view/helpers/asset_url_helper.rb +180 -74
  18. data/lib/action_view/helpers/atom_feed_helper.rb +21 -19
  19. data/lib/action_view/helpers/cache_helper.rb +156 -43
  20. data/lib/action_view/helpers/capture_helper.rb +21 -14
  21. data/lib/action_view/helpers/controller_helper.rb +16 -5
  22. data/lib/action_view/helpers/csp_helper.rb +26 -0
  23. data/lib/action_view/helpers/csrf_helper.rb +8 -6
  24. data/lib/action_view/helpers/date_helper.rb +288 -132
  25. data/lib/action_view/helpers/debug_helper.rb +9 -6
  26. data/lib/action_view/helpers/form_helper.rb +956 -173
  27. data/lib/action_view/helpers/form_options_helper.rb +178 -97
  28. data/lib/action_view/helpers/form_tag_helper.rb +220 -101
  29. data/lib/action_view/helpers/javascript_helper.rb +33 -19
  30. data/lib/action_view/helpers/number_helper.rb +88 -63
  31. data/lib/action_view/helpers/output_safety_helper.rb +38 -6
  32. data/lib/action_view/helpers/rendering_helper.rb +21 -10
  33. data/lib/action_view/helpers/sanitize_helper.rb +31 -32
  34. data/lib/action_view/helpers/tag_helper.rb +332 -71
  35. data/lib/action_view/helpers/tags/base.rb +123 -99
  36. data/lib/action_view/helpers/tags/check_box.rb +21 -20
  37. data/lib/action_view/helpers/tags/checkable.rb +4 -2
  38. data/lib/action_view/helpers/tags/collection_check_boxes.rb +12 -34
  39. data/lib/action_view/helpers/tags/collection_helpers.rb +69 -36
  40. data/lib/action_view/helpers/tags/collection_radio_buttons.rb +6 -12
  41. data/lib/action_view/helpers/tags/collection_select.rb +5 -3
  42. data/lib/action_view/helpers/tags/color_field.rb +4 -3
  43. data/lib/action_view/helpers/tags/date_field.rb +3 -2
  44. data/lib/action_view/helpers/tags/date_select.rb +38 -37
  45. data/lib/action_view/helpers/tags/datetime_field.rb +4 -3
  46. data/lib/action_view/helpers/tags/datetime_local_field.rb +3 -2
  47. data/lib/action_view/helpers/tags/datetime_select.rb +2 -0
  48. data/lib/action_view/helpers/tags/email_field.rb +2 -0
  49. data/lib/action_view/helpers/tags/file_field.rb +18 -0
  50. data/lib/action_view/helpers/tags/grouped_collection_select.rb +4 -2
  51. data/lib/action_view/helpers/tags/hidden_field.rb +6 -0
  52. data/lib/action_view/helpers/tags/label.rb +7 -2
  53. data/lib/action_view/helpers/tags/month_field.rb +3 -2
  54. data/lib/action_view/helpers/tags/number_field.rb +2 -0
  55. data/lib/action_view/helpers/tags/password_field.rb +3 -1
  56. data/lib/action_view/helpers/tags/placeholderable.rb +3 -1
  57. data/lib/action_view/helpers/tags/radio_button.rb +7 -6
  58. data/lib/action_view/helpers/tags/range_field.rb +2 -0
  59. data/lib/action_view/helpers/tags/search_field.rb +14 -9
  60. data/lib/action_view/helpers/tags/select.rb +11 -10
  61. data/lib/action_view/helpers/tags/tel_field.rb +2 -0
  62. data/lib/action_view/helpers/tags/text_area.rb +4 -2
  63. data/lib/action_view/helpers/tags/text_field.rb +8 -8
  64. data/lib/action_view/helpers/tags/time_field.rb +12 -2
  65. data/lib/action_view/helpers/tags/time_select.rb +2 -0
  66. data/lib/action_view/helpers/tags/time_zone_select.rb +3 -1
  67. data/lib/action_view/helpers/tags/translator.rb +15 -16
  68. data/lib/action_view/helpers/tags/url_field.rb +2 -0
  69. data/lib/action_view/helpers/tags/week_field.rb +3 -2
  70. data/lib/action_view/helpers/tags/weekday_select.rb +28 -0
  71. data/lib/action_view/helpers/tags.rb +5 -2
  72. data/lib/action_view/helpers/text_helper.rb +80 -51
  73. data/lib/action_view/helpers/translation_helper.rb +120 -69
  74. data/lib/action_view/helpers/url_helper.rb +398 -171
  75. data/lib/action_view/helpers.rb +29 -27
  76. data/lib/action_view/layouts.rb +68 -63
  77. data/lib/action_view/log_subscriber.rb +77 -10
  78. data/lib/action_view/lookup_context.rb +137 -113
  79. data/lib/action_view/model_naming.rb +4 -2
  80. data/lib/action_view/path_set.rb +28 -32
  81. data/lib/action_view/railtie.rb +74 -13
  82. data/lib/action_view/record_identifier.rb +53 -26
  83. data/lib/action_view/render_parser.rb +188 -0
  84. data/lib/action_view/renderer/abstract_renderer.rb +152 -15
  85. data/lib/action_view/renderer/collection_renderer.rb +196 -0
  86. data/lib/action_view/renderer/object_renderer.rb +34 -0
  87. data/lib/action_view/renderer/partial_renderer/collection_caching.rb +102 -0
  88. data/lib/action_view/renderer/partial_renderer.rb +51 -333
  89. data/lib/action_view/renderer/renderer.rb +68 -11
  90. data/lib/action_view/renderer/streaming_template_renderer.rb +60 -56
  91. data/lib/action_view/renderer/template_renderer.rb +87 -74
  92. data/lib/action_view/rendering.rb +73 -47
  93. data/lib/action_view/ripper_ast_parser.rb +198 -0
  94. data/lib/action_view/routing_url_for.rb +35 -24
  95. data/lib/action_view/tasks/cache_digests.rake +25 -0
  96. data/lib/action_view/template/error.rb +151 -41
  97. data/lib/action_view/template/handlers/builder.rb +12 -13
  98. data/lib/action_view/template/handlers/erb/erubi.rb +89 -0
  99. data/lib/action_view/template/handlers/erb.rb +29 -89
  100. data/lib/action_view/template/handlers/html.rb +11 -0
  101. data/lib/action_view/template/handlers/raw.rb +4 -4
  102. data/lib/action_view/template/handlers.rb +14 -10
  103. data/lib/action_view/template/html.rb +12 -13
  104. data/lib/action_view/template/inline.rb +22 -0
  105. data/lib/action_view/template/raw_file.rb +25 -0
  106. data/lib/action_view/template/renderable.rb +24 -0
  107. data/lib/action_view/template/resolver.rb +139 -300
  108. data/lib/action_view/template/sources/file.rb +17 -0
  109. data/lib/action_view/template/sources.rb +13 -0
  110. data/lib/action_view/template/text.rb +10 -12
  111. data/lib/action_view/template/types.rb +28 -26
  112. data/lib/action_view/template.rb +123 -91
  113. data/lib/action_view/template_details.rb +66 -0
  114. data/lib/action_view/template_path.rb +64 -0
  115. data/lib/action_view/test_case.rb +70 -53
  116. data/lib/action_view/testing/resolvers.rb +25 -35
  117. data/lib/action_view/unbound_template.rb +57 -0
  118. data/lib/action_view/version.rb +3 -1
  119. data/lib/action_view/view_paths.rb +73 -58
  120. data/lib/action_view.rb +16 -11
  121. data/lib/assets/compiled/rails-ujs.js +746 -0
  122. metadata +52 -32
  123. data/lib/action_view/helpers/record_tag_helper.rb +0 -108
  124. data/lib/action_view/tasks/dependencies.rake +0 -23
@@ -1,48 +1,43 @@
1
- require 'thread_safe'
2
- require 'active_support/core_ext/module/remove_method'
3
- require 'active_support/core_ext/module/attribute_accessors'
4
- require 'action_view/template/resolver'
1
+ # frozen_string_literal: true
2
+
3
+ require "concurrent/map"
4
+ require "active_support/core_ext/module/attribute_accessors"
5
+ require "action_view/template/resolver"
5
6
 
6
7
  module ActionView
7
8
  # = Action View Lookup Context
8
9
  #
9
- # LookupContext is the object responsible to hold all information required to lookup
10
- # templates, i.e. view paths and details. The LookupContext is also responsible to
11
- # generate a key, given to view paths, used in the resolver cache lookup. Since
12
- # this key is generated just once during the request, it speeds up all cache accesses.
13
- class LookupContext #:nodoc:
10
+ # <tt>LookupContext</tt> is the object responsible for holding all information
11
+ # required for looking up templates, i.e. view paths and details.
12
+ # <tt>LookupContext</tt> is also responsible for generating a key, given to
13
+ # view paths, used in the resolver cache lookup. Since this key is generated
14
+ # only once during the request, it speeds up all cache accesses.
15
+ class LookupContext # :nodoc:
14
16
  attr_accessor :prefixes, :rendered_format
15
17
 
16
- mattr_accessor :fallbacks
17
- @@fallbacks = FallbackFileSystemResolver.instances
18
-
19
- mattr_accessor :registered_details
18
+ singleton_class.attr_accessor :registered_details
20
19
  self.registered_details = []
21
20
 
22
- def self.register_detail(name, options = {}, &block)
23
- self.registered_details << name
24
- initialize = registered_details.map { |n| "@details[:#{n}] = details[:#{n}] || default_#{n}" }
21
+ def self.register_detail(name, &block)
22
+ registered_details << name
23
+ Accessors::DEFAULT_PROCS[name] = block
25
24
 
26
- Accessors.send :define_method, :"default_#{name}", &block
25
+ Accessors.define_method(:"default_#{name}", &block)
27
26
  Accessors.module_eval <<-METHOD, __FILE__, __LINE__ + 1
28
27
  def #{name}
29
- @details.fetch(:#{name}, [])
28
+ @details[:#{name}] || []
30
29
  end
31
30
 
32
31
  def #{name}=(value)
33
32
  value = value.present? ? Array(value) : default_#{name}
34
33
  _set_detail(:#{name}, value) if value != @details[:#{name}]
35
34
  end
36
-
37
- remove_possible_method :initialize_details
38
- def initialize_details(details)
39
- #{initialize.join("\n")}
40
- end
41
35
  METHOD
42
36
  end
43
37
 
44
38
  # Holds accessors for the registered details.
45
- module Accessors #:nodoc:
39
+ module Accessors # :nodoc:
40
+ DEFAULT_PROCS = {}
46
41
  end
47
42
 
48
43
  register_detail(:locale) do
@@ -54,29 +49,44 @@ module ActionView
54
49
  end
55
50
  register_detail(:formats) { ActionView::Base.default_formats || [:html, :text, :js, :css, :xml, :json] }
56
51
  register_detail(:variants) { [] }
57
- register_detail(:handlers){ Template::Handlers.extensions }
52
+ register_detail(:handlers) { Template::Handlers.extensions }
58
53
 
59
- class DetailsKey #:nodoc:
54
+ class DetailsKey # :nodoc:
60
55
  alias :eql? :equal?
61
- alias :object_hash :hash
62
56
 
63
- attr_reader :hash
64
- @details_keys = ThreadSafe::Cache.new
57
+ @details_keys = Concurrent::Map.new
58
+ @digest_cache = Concurrent::Map.new
59
+ @view_context_mutex = Mutex.new
65
60
 
66
- def self.get(details)
61
+ def self.digest_cache(details)
62
+ @digest_cache[details_cache_key(details)] ||= Concurrent::Map.new
63
+ end
64
+
65
+ def self.details_cache_key(details)
67
66
  if details[:formats]
68
67
  details = details.dup
69
- details[:formats] &= Mime::SET.symbols
68
+ details[:formats] &= Template::Types.symbols
70
69
  end
71
- @details_keys[details] ||= new
70
+ @details_keys[details] ||= TemplateDetails::Requested.new(**details)
72
71
  end
73
72
 
74
73
  def self.clear
74
+ ActionView::ViewPaths.all_view_paths.each do |path_set|
75
+ path_set.each(&:clear_cache)
76
+ end
77
+ @view_context_class = nil
75
78
  @details_keys.clear
79
+ @digest_cache.clear
76
80
  end
77
81
 
78
- def initialize
79
- @hash = object_hash
82
+ def self.digest_caches
83
+ @digest_cache.values
84
+ end
85
+
86
+ def self.view_context_class(klass)
87
+ @view_context_mutex.synchronize do
88
+ @view_context_class ||= klass.with_empty_template_cache
89
+ end
80
90
  end
81
91
  end
82
92
 
@@ -86,8 +96,8 @@ module ActionView
86
96
 
87
97
  # Calculate the details key. Remove the handlers from calculation to improve performance
88
98
  # since the user cannot modify it explicitly.
89
- def details_key #:nodoc:
90
- @details_key ||= DetailsKey.get(@details) if @cache
99
+ def details_key # :nodoc:
100
+ @details_key ||= DetailsKey.details_cache_key(@details) if @cache
91
101
  end
92
102
 
93
103
  # Temporary skip passing the details_key forward.
@@ -98,10 +108,10 @@ module ActionView
98
108
  @cache = old_value
99
109
  end
100
110
 
101
- protected
102
-
103
- def _set_detail(key, value)
104
- @details = @details.dup if @details_key
111
+ private
112
+ def _set_detail(key, value) # :doc:
113
+ @details = @details.dup if @digest_cache || @details_key
114
+ @digest_cache = nil
105
115
  @details_key = nil
106
116
  @details[key] = value
107
117
  end
@@ -111,59 +121,47 @@ module ActionView
111
121
  module ViewPaths
112
122
  attr_reader :view_paths, :html_fallback_for_js
113
123
 
114
- # Whenever setting view paths, makes a copy so that we can manipulate them in
115
- # instance objects as we wish.
116
- def view_paths=(paths)
117
- @view_paths = ActionView::PathSet.new(Array(paths))
118
- end
119
-
120
124
  def find(name, prefixes = [], partial = false, keys = [], options = {})
121
- @view_paths.find(*args_for_lookup(name, prefixes, partial, keys, options))
125
+ name, prefixes = normalize_name(name, prefixes)
126
+ details, details_key = detail_args_for(options)
127
+ @view_paths.find(name, prefixes, partial, details, details_key, keys)
122
128
  end
123
129
  alias :find_template :find
124
130
 
125
- def find_file(name, prefixes = [], partial = false, keys = [], options = {})
126
- @view_paths.find_file(*args_for_lookup(name, prefixes, partial, keys, options))
127
- end
128
-
129
131
  def find_all(name, prefixes = [], partial = false, keys = [], options = {})
130
- @view_paths.find_all(*args_for_lookup(name, prefixes, partial, keys, options))
132
+ name, prefixes = normalize_name(name, prefixes)
133
+ details, details_key = detail_args_for(options)
134
+ @view_paths.find_all(name, prefixes, partial, details, details_key, keys)
131
135
  end
132
136
 
133
- def exists?(name, prefixes = [], partial = false, keys = [], options = {})
134
- @view_paths.exists?(*args_for_lookup(name, prefixes, partial, keys, options))
137
+ def exists?(name, prefixes = [], partial = false, keys = [], **options)
138
+ name, prefixes = normalize_name(name, prefixes)
139
+ details, details_key = detail_args_for(options)
140
+ @view_paths.exists?(name, prefixes, partial, details, details_key, keys)
135
141
  end
136
142
  alias :template_exists? :exists?
137
143
 
138
- # Adds fallbacks to the view paths. Useful in cases when you are rendering
139
- # a :file.
140
- def with_fallbacks
141
- added_resolvers = 0
142
- self.class.fallbacks.each do |resolver|
143
- next if view_paths.include?(resolver)
144
- view_paths.push(resolver)
145
- added_resolvers += 1
146
- end
147
- yield
148
- ensure
149
- added_resolvers.times { view_paths.pop }
144
+ def any?(name, prefixes = [], partial = false)
145
+ name, prefixes = normalize_name(name, prefixes)
146
+ details, details_key = detail_args_for_any
147
+ @view_paths.exists?(name, prefixes, partial, details, details_key, [])
150
148
  end
149
+ alias :any_templates? :any?
151
150
 
152
- protected
153
-
154
- def args_for_lookup(name, prefixes, partial, keys, details_options) #:nodoc:
155
- name, prefixes = normalize_name(name, prefixes)
156
- details, details_key = detail_args_for(details_options)
157
- [name, prefixes, partial || false, details, details_key, keys]
151
+ private
152
+ # Whenever setting view paths, makes a copy so that we can manipulate them in
153
+ # instance objects as we wish.
154
+ def build_view_paths(paths)
155
+ ActionView::PathSet.new(Array(paths))
158
156
  end
159
157
 
160
158
  # Compute details hash and key according to user options (e.g. passed from #render).
161
- def detail_args_for(options)
159
+ def detail_args_for(options) # :doc:
162
160
  return @details, details_key if options.empty? # most common path.
163
161
  user_details = @details.merge(options)
164
162
 
165
163
  if @cache
166
- details_key = DetailsKey.get(user_details)
164
+ details_key = DetailsKey.details_cache_key(user_details)
167
165
  else
168
166
  details_key = nil
169
167
  end
@@ -171,19 +169,41 @@ module ActionView
171
169
  [user_details, details_key]
172
170
  end
173
171
 
174
- # Support legacy foo.erb names even though we now ignore .erb
175
- # as well as incorrectly putting part of the path in the template
176
- # name instead of the prefix.
177
- def normalize_name(name, prefixes) #:nodoc:
178
- prefixes = prefixes.presence
179
- parts = name.to_s.split('/')
180
- parts.shift if parts.first.empty?
181
- name = parts.pop
172
+ def detail_args_for_any
173
+ @detail_args_for_any ||= begin
174
+ details = {}
175
+
176
+ LookupContext.registered_details.each do |k|
177
+ if k == :variants
178
+ details[k] = :any
179
+ else
180
+ details[k] = Accessors::DEFAULT_PROCS[k].call
181
+ end
182
+ end
183
+
184
+ if @cache
185
+ [details, DetailsKey.details_cache_key(details)]
186
+ else
187
+ [details, nil]
188
+ end
189
+ end
190
+ end
182
191
 
183
- return name, prefixes || [""] if parts.empty?
192
+ # Fix when prefix is specified as part of the template name
193
+ def normalize_name(name, prefixes)
194
+ name = name.to_s
195
+ idx = name.rindex("/")
196
+ return name, prefixes.presence || [""] unless idx
184
197
 
185
- parts = parts.join('/')
186
- prefixes = prefixes ? prefixes.map { |p| "#{p}/#{parts}" } : [parts]
198
+ path_prefix = name[0, idx]
199
+ path_prefix = path_prefix.from(1) if path_prefix.start_with?("/")
200
+ name = name.from(idx + 1)
201
+
202
+ if !prefixes || prefixes.empty?
203
+ prefixes = [path_prefix]
204
+ else
205
+ prefixes = prefixes.map { |p| "#{p}/#{path_prefix}" }
206
+ end
187
207
 
188
208
  return name, prefixes
189
209
  end
@@ -194,21 +214,47 @@ module ActionView
194
214
  include ViewPaths
195
215
 
196
216
  def initialize(view_paths, details = {}, prefixes = [])
197
- @details, @details_key = {}, nil
198
- @skip_default_locale = false
217
+ @details_key = nil
218
+ @digest_cache = nil
199
219
  @cache = true
200
220
  @prefixes = prefixes
201
- @rendered_format = nil
202
221
 
203
- self.view_paths = view_paths
204
- initialize_details(details)
222
+ @details = initialize_details({}, details)
223
+ @view_paths = build_view_paths(view_paths)
205
224
  end
206
225
 
226
+ def digest_cache
227
+ @digest_cache ||= DetailsKey.digest_cache(@details)
228
+ end
229
+
230
+ def with_prepended_formats(formats)
231
+ details = @details.dup
232
+ details[:formats] = formats
233
+
234
+ self.class.new(@view_paths, details, @prefixes)
235
+ end
236
+
237
+ def initialize_details(target, details)
238
+ LookupContext.registered_details.each do |k|
239
+ target[k] = details[k] || Accessors::DEFAULT_PROCS[k].call
240
+ end
241
+ target
242
+ end
243
+ private :initialize_details
244
+
207
245
  # Override formats= to expand ["*/*"] values and automatically
208
246
  # add :html as fallback to :js.
209
247
  def formats=(values)
210
248
  if values
249
+ values = values.dup
211
250
  values.concat(default_formats) if values.delete "*/*"
251
+ values.uniq!
252
+
253
+ invalid_values = (values - Template::Types.symbols)
254
+ unless invalid_values.empty?
255
+ raise ArgumentError, "Invalid formats: #{invalid_values.map(&:inspect).join(", ")}"
256
+ end
257
+
212
258
  if values == [:js]
213
259
  values << :html
214
260
  @html_fallback_for_js = true
@@ -217,12 +263,6 @@ module ActionView
217
263
  super(values)
218
264
  end
219
265
 
220
- # Do not use the default locale on template lookup.
221
- def skip_default_locale!
222
- @skip_default_locale = true
223
- self.locale = nil
224
- end
225
-
226
266
  # Override locale to return a symbol instead of array.
227
267
  def locale
228
268
  @details[:locale].first
@@ -237,23 +277,7 @@ module ActionView
237
277
  config.locale = value
238
278
  end
239
279
 
240
- super(@skip_default_locale ? I18n.locale : default_locale)
241
- end
242
-
243
- # Uses the first format in the formats array for layout lookup.
244
- def with_layout_format
245
- if formats.size == 1
246
- yield
247
- else
248
- old_formats = formats
249
- _set_detail(:formats, formats[0,1])
250
-
251
- begin
252
- yield
253
- ensure
254
- _set_detail(:formats, old_formats)
255
- end
256
- end
280
+ super(default_locale)
257
281
  end
258
282
  end
259
283
  end
@@ -1,6 +1,8 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActionView
2
- module ModelNaming
3
- # Converts the given object to an ActiveModel compliant one.
4
+ module ModelNaming # :nodoc:
5
+ # Converts the given object to an Active Model compliant one.
4
6
  def convert_to_model(object)
5
7
  object.respond_to?(:to_model) ? object.to_model : object
6
8
  end
@@ -1,4 +1,6 @@
1
- module ActionView #:nodoc:
1
+ # frozen_string_literal: true
2
+
3
+ module ActionView # :nodoc:
2
4
  # = Action View PathSet
3
5
  #
4
6
  # This class is used to store and access paths in Action View. A number of
@@ -6,7 +8,7 @@ module ActionView #:nodoc:
6
8
  # set and also perform operations on other +PathSet+ objects.
7
9
  #
8
10
  # A +LookupContext+ will use a +PathSet+ to store the paths in its context.
9
- class PathSet #:nodoc:
11
+ class PathSet # :nodoc:
10
12
  include Enumerable
11
13
 
12
14
  attr_reader :paths
@@ -42,48 +44,42 @@ module ActionView #:nodoc:
42
44
  METHOD
43
45
  end
44
46
 
45
- def find(*args)
46
- find_all(*args).first || raise(MissingTemplate.new(self, *args))
47
- end
48
-
49
- def find_file(path, prefixes = [], *args)
50
- _find_all(path, prefixes, args, true).first || raise(MissingTemplate.new(self, path, prefixes, *args))
47
+ def find(path, prefixes, partial, details, details_key, locals)
48
+ find_all(path, prefixes, partial, details, details_key, locals).first ||
49
+ raise(MissingTemplate.new(self, path, prefixes, partial, details, details_key, locals))
51
50
  end
52
51
 
53
- def find_all(path, prefixes = [], *args)
54
- _find_all path, prefixes, args, false
52
+ def find_all(path, prefixes, partial, details, details_key, locals)
53
+ search_combinations(prefixes) do |resolver, prefix|
54
+ templates = resolver.find_all(path, prefix, partial, details, details_key, locals)
55
+ return templates unless templates.empty?
56
+ end
57
+ []
55
58
  end
56
59
 
57
- def exists?(path, prefixes, *args)
58
- find_all(path, prefixes, *args).any?
60
+ def exists?(path, prefixes, partial, details, details_key, locals)
61
+ find_all(path, prefixes, partial, details, details_key, locals).any?
59
62
  end
60
63
 
61
64
  private
62
-
63
- def _find_all(path, prefixes, args, outside_app)
64
- prefixes = [prefixes] if String === prefixes
65
- prefixes.each do |prefix|
66
- paths.each do |resolver|
67
- if outside_app
68
- templates = resolver.find_all_anywhere(path, prefix, *args)
69
- else
70
- templates = resolver.find_all(path, prefix, *args)
65
+ def search_combinations(prefixes)
66
+ prefixes = Array(prefixes)
67
+ prefixes.each do |prefix|
68
+ paths.each do |resolver|
69
+ yield resolver, prefix
71
70
  end
72
- return templates unless templates.empty?
73
71
  end
74
72
  end
75
- []
76
- end
77
73
 
78
- def typecast(paths)
79
- paths.map do |path|
80
- case path
81
- when Pathname, String
82
- OptimizedFileSystemResolver.new path.to_s
83
- else
84
- path
74
+ def typecast(paths)
75
+ paths.map do |path|
76
+ case path
77
+ when Pathname, String
78
+ FileSystemResolver.new path.to_s
79
+ else
80
+ path
81
+ end
85
82
  end
86
83
  end
87
- end
88
84
  end
89
85
  end
@@ -1,33 +1,76 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "action_view"
2
4
  require "rails"
3
5
 
4
6
  module ActionView
5
7
  # = Action View Railtie
6
- class Railtie < Rails::Railtie # :nodoc:
8
+ class Railtie < Rails::Engine # :nodoc:
7
9
  config.action_view = ActiveSupport::OrderedOptions.new
8
- config.action_view.embed_authenticity_token_in_remote_forms = false
10
+ config.action_view.embed_authenticity_token_in_remote_forms = nil
11
+ config.action_view.debug_missing_translation = true
12
+ config.action_view.default_enforce_utf8 = nil
13
+ config.action_view.image_loading = nil
14
+ config.action_view.image_decoding = nil
15
+ config.action_view.apply_stylesheet_media_default = true
9
16
 
10
17
  config.eager_load_namespaces << ActionView
11
18
 
12
- initializer "action_view.embed_authenticity_token_in_remote_forms" do |app|
13
- ActiveSupport.on_load(:action_view) do
14
- ActionView::Helpers::FormTagHelper.embed_authenticity_token_in_remote_forms =
15
- app.config.action_view.delete(:embed_authenticity_token_in_remote_forms)
19
+ config.after_initialize do |app|
20
+ ActionView::Helpers::FormTagHelper.embed_authenticity_token_in_remote_forms =
21
+ app.config.action_view.delete(:embed_authenticity_token_in_remote_forms)
22
+ end
23
+
24
+ config.after_initialize do |app|
25
+ form_with_generates_remote_forms = app.config.action_view.delete(:form_with_generates_remote_forms)
26
+ ActionView::Helpers::FormHelper.form_with_generates_remote_forms = form_with_generates_remote_forms
27
+ end
28
+
29
+ config.after_initialize do |app|
30
+ form_with_generates_ids = app.config.action_view.delete(:form_with_generates_ids)
31
+ unless form_with_generates_ids.nil?
32
+ ActionView::Helpers::FormHelper.form_with_generates_ids = form_with_generates_ids
16
33
  end
17
34
  end
18
35
 
19
- initializer "action_view.logger" do
20
- ActiveSupport.on_load(:action_view) { self.logger ||= Rails.logger }
36
+ config.after_initialize do |app|
37
+ default_enforce_utf8 = app.config.action_view.delete(:default_enforce_utf8)
38
+ unless default_enforce_utf8.nil?
39
+ ActionView::Helpers::FormTagHelper.default_enforce_utf8 = default_enforce_utf8
40
+ end
41
+ end
42
+
43
+ config.after_initialize do |app|
44
+ button_to_generates_button_tag = app.config.action_view.delete(:button_to_generates_button_tag)
45
+ unless button_to_generates_button_tag.nil?
46
+ ActionView::Helpers::UrlHelper.button_to_generates_button_tag = button_to_generates_button_tag
47
+ end
48
+ end
49
+
50
+ config.after_initialize do |app|
51
+ frozen_string_literal = app.config.action_view.delete(:frozen_string_literal)
52
+ ActionView::Template.frozen_string_literal = frozen_string_literal
21
53
  end
22
54
 
23
- initializer "action_view.set_configs" do |app|
55
+ config.after_initialize do |app|
56
+ ActionView::Helpers::AssetTagHelper.image_loading = app.config.action_view.delete(:image_loading)
57
+ ActionView::Helpers::AssetTagHelper.image_decoding = app.config.action_view.delete(:image_decoding)
58
+ ActionView::Helpers::AssetTagHelper.preload_links_header = app.config.action_view.delete(:preload_links_header)
59
+ ActionView::Helpers::AssetTagHelper.apply_stylesheet_media_default = app.config.action_view.delete(:apply_stylesheet_media_default)
60
+ end
61
+
62
+ config.after_initialize do |app|
24
63
  ActiveSupport.on_load(:action_view) do
25
- app.config.action_view.each do |k,v|
64
+ app.config.action_view.each do |k, v|
26
65
  send "#{k}=", v
27
66
  end
28
67
  end
29
68
  end
30
69
 
70
+ initializer "action_view.logger" do
71
+ ActiveSupport.on_load(:action_view) { self.logger ||= Rails.logger }
72
+ end
73
+
31
74
  initializer "action_view.caching" do |app|
32
75
  ActiveSupport.on_load(:action_view) do
33
76
  if app.config.action_view.cache_template_loading.nil?
@@ -38,12 +81,30 @@ module ActionView
38
81
 
39
82
  initializer "action_view.setup_action_pack" do |app|
40
83
  ActiveSupport.on_load(:action_controller) do
41
- ActionView::RoutingUrlFor.send(:include, ActionDispatch::Routing::UrlFor)
84
+ ActionView::RoutingUrlFor.include(ActionDispatch::Routing::UrlFor)
85
+ end
86
+ end
87
+
88
+ initializer "action_view.collection_caching", after: "action_controller.set_configs" do |app|
89
+ PartialRenderer.collection_cache = app.config.action_controller.cache_store
90
+ end
91
+
92
+ config.after_initialize do |app|
93
+ enable_caching = if app.config.action_view.cache_template_loading.nil?
94
+ app.config.cache_classes
95
+ else
96
+ app.config.action_view.cache_template_loading
97
+ end
98
+
99
+ unless enable_caching
100
+ app.executor.register_hook ActionView::CacheExpiry::Executor.new(watcher: app.config.file_watcher)
42
101
  end
43
102
  end
44
103
 
45
- rake_tasks do
46
- load "action_view/tasks/dependencies.rake"
104
+ rake_tasks do |app|
105
+ unless app.config.api_only
106
+ load "action_view/tasks/cache_digests.rake"
107
+ end
47
108
  end
48
109
  end
49
110
  end