actionview 4.2.11.1 → 6.1.5.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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +243 -186
- data/MIT-LICENSE +1 -2
- data/README.rdoc +9 -8
- data/lib/action_view/base.rb +115 -39
- data/lib/action_view/buffers.rb +18 -1
- data/lib/action_view/cache_expiry.rb +52 -0
- data/lib/action_view/context.rb +8 -12
- data/lib/action_view/dependency_tracker.rb +61 -21
- data/lib/action_view/digestor.rb +89 -85
- data/lib/action_view/flows.rb +11 -12
- data/lib/action_view/gem_version.rb +5 -3
- data/lib/action_view/helpers/active_model_helper.rb +16 -11
- data/lib/action_view/helpers/asset_tag_helper.rb +282 -83
- data/lib/action_view/helpers/asset_url_helper.rb +175 -69
- data/lib/action_view/helpers/atom_feed_helper.rb +20 -17
- data/lib/action_view/helpers/cache_helper.rb +107 -43
- data/lib/action_view/helpers/capture_helper.rb +20 -13
- data/lib/action_view/helpers/controller_helper.rb +15 -4
- data/lib/action_view/helpers/csp_helper.rb +26 -0
- data/lib/action_view/helpers/csrf_helper.rb +8 -6
- data/lib/action_view/helpers/date_helper.rb +232 -130
- data/lib/action_view/helpers/debug_helper.rb +7 -6
- data/lib/action_view/helpers/form_helper.rb +808 -146
- data/lib/action_view/helpers/form_options_helper.rb +124 -78
- data/lib/action_view/helpers/form_tag_helper.rb +120 -74
- data/lib/action_view/helpers/javascript_helper.rb +33 -17
- data/lib/action_view/helpers/number_helper.rb +87 -62
- data/lib/action_view/helpers/output_safety_helper.rb +36 -4
- data/lib/action_view/helpers/rendering_helper.rb +21 -10
- data/lib/action_view/helpers/sanitize_helper.rb +30 -31
- data/lib/action_view/helpers/tag_helper.rb +302 -69
- data/lib/action_view/helpers/tags/base.rb +141 -97
- data/lib/action_view/helpers/tags/check_box.rb +20 -19
- data/lib/action_view/helpers/tags/checkable.rb +4 -2
- data/lib/action_view/helpers/tags/collection_check_boxes.rb +12 -34
- data/lib/action_view/helpers/tags/collection_helpers.rb +69 -36
- data/lib/action_view/helpers/tags/collection_radio_buttons.rb +6 -12
- data/lib/action_view/helpers/tags/collection_select.rb +4 -2
- data/lib/action_view/helpers/tags/color_field.rb +4 -3
- data/lib/action_view/helpers/tags/date_field.rb +3 -2
- data/lib/action_view/helpers/tags/date_select.rb +38 -37
- data/lib/action_view/helpers/tags/datetime_field.rb +4 -3
- data/lib/action_view/helpers/tags/datetime_local_field.rb +3 -2
- data/lib/action_view/helpers/tags/datetime_select.rb +2 -0
- data/lib/action_view/helpers/tags/email_field.rb +2 -0
- data/lib/action_view/helpers/tags/file_field.rb +2 -0
- data/lib/action_view/helpers/tags/grouped_collection_select.rb +4 -2
- data/lib/action_view/helpers/tags/hidden_field.rb +6 -0
- data/lib/action_view/helpers/tags/label.rb +7 -2
- data/lib/action_view/helpers/tags/month_field.rb +3 -2
- data/lib/action_view/helpers/tags/number_field.rb +2 -0
- data/lib/action_view/helpers/tags/password_field.rb +3 -1
- data/lib/action_view/helpers/tags/placeholderable.rb +3 -1
- data/lib/action_view/helpers/tags/radio_button.rb +7 -6
- data/lib/action_view/helpers/tags/range_field.rb +2 -0
- data/lib/action_view/helpers/tags/search_field.rb +14 -9
- data/lib/action_view/helpers/tags/select.rb +11 -10
- data/lib/action_view/helpers/tags/tel_field.rb +2 -0
- data/lib/action_view/helpers/tags/text_area.rb +4 -2
- data/lib/action_view/helpers/tags/text_field.rb +8 -8
- data/lib/action_view/helpers/tags/time_field.rb +3 -2
- data/lib/action_view/helpers/tags/time_select.rb +2 -0
- data/lib/action_view/helpers/tags/time_zone_select.rb +3 -1
- data/lib/action_view/helpers/tags/translator.rb +15 -16
- data/lib/action_view/helpers/tags/url_field.rb +2 -0
- data/lib/action_view/helpers/tags/week_field.rb +3 -2
- data/lib/action_view/helpers/tags.rb +3 -1
- data/lib/action_view/helpers/text_helper.rb +56 -38
- data/lib/action_view/helpers/translation_helper.rb +150 -68
- data/lib/action_view/helpers/url_helper.rb +284 -117
- data/lib/action_view/helpers.rb +5 -3
- data/lib/action_view/layouts.rb +68 -63
- data/lib/action_view/log_subscriber.rb +77 -10
- data/lib/action_view/lookup_context.rb +134 -91
- data/lib/action_view/model_naming.rb +3 -1
- data/lib/action_view/path_set.rb +26 -24
- data/lib/action_view/railtie.rb +62 -13
- data/lib/action_view/record_identifier.rb +53 -26
- data/lib/action_view/renderer/abstract_renderer.rb +151 -14
- data/lib/action_view/renderer/collection_renderer.rb +196 -0
- data/lib/action_view/renderer/object_renderer.rb +34 -0
- data/lib/action_view/renderer/partial_renderer/collection_caching.rb +102 -0
- data/lib/action_view/renderer/partial_renderer.rb +55 -303
- data/lib/action_view/renderer/renderer.rb +66 -9
- data/lib/action_view/renderer/streaming_template_renderer.rb +58 -54
- data/lib/action_view/renderer/template_renderer.rb +82 -73
- data/lib/action_view/rendering.rb +71 -45
- data/lib/action_view/routing_url_for.rb +34 -23
- data/lib/action_view/tasks/cache_digests.rake +25 -0
- data/lib/action_view/template/error.rb +44 -29
- data/lib/action_view/template/handlers/builder.rb +12 -13
- data/lib/action_view/template/handlers/erb/erubi.rb +89 -0
- data/lib/action_view/template/handlers/erb.rb +23 -89
- data/lib/action_view/template/handlers/html.rb +11 -0
- data/lib/action_view/template/handlers/raw.rb +4 -4
- data/lib/action_view/template/handlers.rb +12 -8
- data/lib/action_view/template/html.rb +10 -11
- data/lib/action_view/template/inline.rb +22 -0
- data/lib/action_view/template/raw_file.rb +25 -0
- data/lib/action_view/template/renderable.rb +24 -0
- data/lib/action_view/template/resolver.rb +263 -197
- data/lib/action_view/template/sources/file.rb +17 -0
- data/lib/action_view/template/sources.rb +13 -0
- data/lib/action_view/template/text.rb +8 -10
- data/lib/action_view/template/types.rb +18 -18
- data/lib/action_view/template.rb +108 -92
- data/lib/action_view/test_case.rb +66 -53
- data/lib/action_view/testing/resolvers.rb +24 -33
- data/lib/action_view/unbound_template.rb +31 -0
- data/lib/action_view/version.rb +3 -1
- data/lib/action_view/view_paths.rb +73 -58
- data/lib/action_view.rb +14 -8
- data/lib/assets/compiled/rails-ujs.js +746 -0
- metadata +45 -32
- data/lib/action_view/helpers/record_tag_helper.rb +0 -108
- data/lib/action_view/tasks/dependencies.rake +0 -23
@@ -1,48 +1,44 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
require
|
4
|
-
require
|
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
|
10
|
-
# templates, i.e. view paths and details.
|
11
|
-
#
|
12
|
-
#
|
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.
|
13
15
|
class LookupContext #:nodoc:
|
14
16
|
attr_accessor :prefixes, :rendered_format
|
15
17
|
|
16
|
-
mattr_accessor :fallbacks
|
17
|
-
@@fallbacks = FallbackFileSystemResolver.instances
|
18
|
+
mattr_accessor :fallbacks, default: FallbackFileSystemResolver.instances
|
18
19
|
|
19
|
-
mattr_accessor :registered_details
|
20
|
-
self.registered_details = []
|
20
|
+
mattr_accessor :registered_details, default: []
|
21
21
|
|
22
|
-
def self.register_detail(name,
|
23
|
-
|
24
|
-
|
22
|
+
def self.register_detail(name, &block)
|
23
|
+
registered_details << name
|
24
|
+
Accessors::DEFAULT_PROCS[name] = block
|
25
25
|
|
26
|
-
Accessors.
|
26
|
+
Accessors.define_method(:"default_#{name}", &block)
|
27
27
|
Accessors.module_eval <<-METHOD, __FILE__, __LINE__ + 1
|
28
28
|
def #{name}
|
29
|
-
@details
|
29
|
+
@details[:#{name}] || []
|
30
30
|
end
|
31
31
|
|
32
32
|
def #{name}=(value)
|
33
33
|
value = value.present? ? Array(value) : default_#{name}
|
34
34
|
_set_detail(:#{name}, value) if value != @details[:#{name}]
|
35
35
|
end
|
36
|
-
|
37
|
-
remove_possible_method :initialize_details
|
38
|
-
def initialize_details(details)
|
39
|
-
#{initialize.join("\n")}
|
40
|
-
end
|
41
36
|
METHOD
|
42
37
|
end
|
43
38
|
|
44
39
|
# Holds accessors for the registered details.
|
45
40
|
module Accessors #:nodoc:
|
41
|
+
DEFAULT_PROCS = {}
|
46
42
|
end
|
47
43
|
|
48
44
|
register_detail(:locale) do
|
@@ -54,29 +50,45 @@ module ActionView
|
|
54
50
|
end
|
55
51
|
register_detail(:formats) { ActionView::Base.default_formats || [:html, :text, :js, :css, :xml, :json] }
|
56
52
|
register_detail(:variants) { [] }
|
57
|
-
register_detail(:handlers){ Template::Handlers.extensions }
|
53
|
+
register_detail(:handlers) { Template::Handlers.extensions }
|
58
54
|
|
59
55
|
class DetailsKey #:nodoc:
|
60
56
|
alias :eql? :equal?
|
61
|
-
alias :object_hash :hash
|
62
57
|
|
63
|
-
|
64
|
-
@
|
58
|
+
@details_keys = Concurrent::Map.new
|
59
|
+
@digest_cache = Concurrent::Map.new
|
60
|
+
@view_context_mutex = Mutex.new
|
65
61
|
|
66
|
-
def self.
|
62
|
+
def self.digest_cache(details)
|
63
|
+
@digest_cache[details_cache_key(details)] ||= Concurrent::Map.new
|
64
|
+
end
|
65
|
+
|
66
|
+
def self.details_cache_key(details)
|
67
67
|
if details[:formats]
|
68
68
|
details = details.dup
|
69
|
-
details[:formats] &=
|
69
|
+
details[:formats] &= Template::Types.symbols
|
70
70
|
end
|
71
|
-
@details_keys[details] ||= new
|
71
|
+
@details_keys[details] ||= Object.new
|
72
72
|
end
|
73
73
|
|
74
74
|
def self.clear
|
75
|
+
ActionView::ViewPaths.all_view_paths.each do |path_set|
|
76
|
+
path_set.each(&:clear_cache)
|
77
|
+
end
|
78
|
+
ActionView::LookupContext.fallbacks.each(&:clear_cache)
|
79
|
+
@view_context_class = nil
|
75
80
|
@details_keys.clear
|
81
|
+
@digest_cache.clear
|
76
82
|
end
|
77
83
|
|
78
|
-
def
|
79
|
-
@
|
84
|
+
def self.digest_caches
|
85
|
+
@digest_cache.values
|
86
|
+
end
|
87
|
+
|
88
|
+
def self.view_context_class(klass)
|
89
|
+
@view_context_mutex.synchronize do
|
90
|
+
@view_context_class ||= klass.with_empty_template_cache
|
91
|
+
end
|
80
92
|
end
|
81
93
|
end
|
82
94
|
|
@@ -87,7 +99,7 @@ module ActionView
|
|
87
99
|
# Calculate the details key. Remove the handlers from calculation to improve performance
|
88
100
|
# since the user cannot modify it explicitly.
|
89
101
|
def details_key #:nodoc:
|
90
|
-
@details_key ||= DetailsKey.
|
102
|
+
@details_key ||= DetailsKey.details_cache_key(@details) if @cache
|
91
103
|
end
|
92
104
|
|
93
105
|
# Temporary skip passing the details_key forward.
|
@@ -98,10 +110,10 @@ module ActionView
|
|
98
110
|
@cache = old_value
|
99
111
|
end
|
100
112
|
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
@
|
113
|
+
private
|
114
|
+
def _set_detail(key, value) # :doc:
|
115
|
+
@details = @details.dup if @digest_cache || @details_key
|
116
|
+
@digest_cache = nil
|
105
117
|
@details_key = nil
|
106
118
|
@details[key] = value
|
107
119
|
end
|
@@ -111,59 +123,60 @@ module ActionView
|
|
111
123
|
module ViewPaths
|
112
124
|
attr_reader :view_paths, :html_fallback_for_js
|
113
125
|
|
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
126
|
def find(name, prefixes = [], partial = false, keys = [], options = {})
|
121
127
|
@view_paths.find(*args_for_lookup(name, prefixes, partial, keys, options))
|
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
132
|
@view_paths.find_all(*args_for_lookup(name, prefixes, partial, keys, options))
|
131
133
|
end
|
132
134
|
|
133
|
-
def exists?(name, prefixes = [], partial = false, keys = [], options
|
135
|
+
def exists?(name, prefixes = [], partial = false, keys = [], **options)
|
134
136
|
@view_paths.exists?(*args_for_lookup(name, prefixes, partial, keys, options))
|
135
137
|
end
|
136
138
|
alias :template_exists? :exists?
|
137
139
|
|
140
|
+
def any?(name, prefixes = [], partial = false)
|
141
|
+
@view_paths.exists?(*args_for_any(name, prefixes, partial))
|
142
|
+
end
|
143
|
+
alias :any_templates? :any?
|
144
|
+
|
138
145
|
# Adds fallbacks to the view paths. Useful in cases when you are rendering
|
139
146
|
# a :file.
|
140
147
|
def with_fallbacks
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
148
|
+
view_paths = build_view_paths((@view_paths.paths + self.class.fallbacks).uniq)
|
149
|
+
|
150
|
+
if block_given?
|
151
|
+
raise ArgumentError, <<~eowarn.squish
|
152
|
+
Calling `with_fallbacks` with a block is not supported. Call methods on
|
153
|
+
the lookup context returned by `with_fallbacks` instead.
|
154
|
+
eowarn
|
155
|
+
else
|
156
|
+
ActionView::LookupContext.new(view_paths, @details, @prefixes)
|
146
157
|
end
|
147
|
-
yield
|
148
|
-
ensure
|
149
|
-
added_resolvers.times { view_paths.pop }
|
150
158
|
end
|
151
159
|
|
152
|
-
|
160
|
+
private
|
161
|
+
# Whenever setting view paths, makes a copy so that we can manipulate them in
|
162
|
+
# instance objects as we wish.
|
163
|
+
def build_view_paths(paths)
|
164
|
+
ActionView::PathSet.new(Array(paths))
|
165
|
+
end
|
153
166
|
|
154
|
-
def args_for_lookup(name, prefixes, partial, keys, details_options)
|
167
|
+
def args_for_lookup(name, prefixes, partial, keys, details_options)
|
155
168
|
name, prefixes = normalize_name(name, prefixes)
|
156
169
|
details, details_key = detail_args_for(details_options)
|
157
170
|
[name, prefixes, partial || false, details, details_key, keys]
|
158
171
|
end
|
159
172
|
|
160
173
|
# Compute details hash and key according to user options (e.g. passed from #render).
|
161
|
-
def detail_args_for(options)
|
174
|
+
def detail_args_for(options) # :doc:
|
162
175
|
return @details, details_key if options.empty? # most common path.
|
163
176
|
user_details = @details.merge(options)
|
164
177
|
|
165
178
|
if @cache
|
166
|
-
details_key = DetailsKey.
|
179
|
+
details_key = DetailsKey.details_cache_key(user_details)
|
167
180
|
else
|
168
181
|
details_key = nil
|
169
182
|
end
|
@@ -171,18 +184,44 @@ module ActionView
|
|
171
184
|
[user_details, details_key]
|
172
185
|
end
|
173
186
|
|
187
|
+
def args_for_any(name, prefixes, partial)
|
188
|
+
name, prefixes = normalize_name(name, prefixes)
|
189
|
+
details, details_key = detail_args_for_any
|
190
|
+
[name, prefixes, partial || false, details, details_key]
|
191
|
+
end
|
192
|
+
|
193
|
+
def detail_args_for_any
|
194
|
+
@detail_args_for_any ||= begin
|
195
|
+
details = {}
|
196
|
+
|
197
|
+
registered_details.each do |k|
|
198
|
+
if k == :variants
|
199
|
+
details[k] = :any
|
200
|
+
else
|
201
|
+
details[k] = Accessors::DEFAULT_PROCS[k].call
|
202
|
+
end
|
203
|
+
end
|
204
|
+
|
205
|
+
if @cache
|
206
|
+
[details, DetailsKey.details_cache_key(details)]
|
207
|
+
else
|
208
|
+
[details, nil]
|
209
|
+
end
|
210
|
+
end
|
211
|
+
end
|
212
|
+
|
174
213
|
# Support legacy foo.erb names even though we now ignore .erb
|
175
214
|
# as well as incorrectly putting part of the path in the template
|
176
215
|
# name instead of the prefix.
|
177
|
-
def normalize_name(name, prefixes)
|
216
|
+
def normalize_name(name, prefixes)
|
178
217
|
prefixes = prefixes.presence
|
179
|
-
parts = name.to_s.split(
|
218
|
+
parts = name.to_s.split("/")
|
180
219
|
parts.shift if parts.first.empty?
|
181
|
-
name
|
220
|
+
name = parts.pop
|
182
221
|
|
183
222
|
return name, prefixes || [""] if parts.empty?
|
184
223
|
|
185
|
-
parts = parts.join(
|
224
|
+
parts = parts.join("/")
|
186
225
|
prefixes = prefixes ? prefixes.map { |p| "#{p}/#{parts}" } : [parts]
|
187
226
|
|
188
227
|
return name, prefixes
|
@@ -194,21 +233,47 @@ module ActionView
|
|
194
233
|
include ViewPaths
|
195
234
|
|
196
235
|
def initialize(view_paths, details = {}, prefixes = [])
|
197
|
-
@
|
198
|
-
@
|
236
|
+
@details_key = nil
|
237
|
+
@digest_cache = nil
|
199
238
|
@cache = true
|
200
239
|
@prefixes = prefixes
|
201
|
-
@rendered_format = nil
|
202
240
|
|
203
|
-
|
204
|
-
|
241
|
+
@details = initialize_details({}, details)
|
242
|
+
@view_paths = build_view_paths(view_paths)
|
243
|
+
end
|
244
|
+
|
245
|
+
def digest_cache
|
246
|
+
@digest_cache ||= DetailsKey.digest_cache(@details)
|
247
|
+
end
|
248
|
+
|
249
|
+
def with_prepended_formats(formats)
|
250
|
+
details = @details.dup
|
251
|
+
details[:formats] = formats
|
252
|
+
|
253
|
+
self.class.new(@view_paths, details, @prefixes)
|
254
|
+
end
|
255
|
+
|
256
|
+
def initialize_details(target, details)
|
257
|
+
registered_details.each do |k|
|
258
|
+
target[k] = details[k] || Accessors::DEFAULT_PROCS[k].call
|
259
|
+
end
|
260
|
+
target
|
205
261
|
end
|
262
|
+
private :initialize_details
|
206
263
|
|
207
264
|
# Override formats= to expand ["*/*"] values and automatically
|
208
265
|
# add :html as fallback to :js.
|
209
266
|
def formats=(values)
|
210
267
|
if values
|
268
|
+
values = values.dup
|
211
269
|
values.concat(default_formats) if values.delete "*/*"
|
270
|
+
values.uniq!
|
271
|
+
|
272
|
+
invalid_values = (values - Template::Types.symbols)
|
273
|
+
unless invalid_values.empty?
|
274
|
+
raise ArgumentError, "Invalid formats: #{invalid_values.map(&:inspect).join(", ")}"
|
275
|
+
end
|
276
|
+
|
212
277
|
if values == [:js]
|
213
278
|
values << :html
|
214
279
|
@html_fallback_for_js = true
|
@@ -217,12 +282,6 @@ module ActionView
|
|
217
282
|
super(values)
|
218
283
|
end
|
219
284
|
|
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
285
|
# Override locale to return a symbol instead of array.
|
227
286
|
def locale
|
228
287
|
@details[:locale].first
|
@@ -237,23 +296,7 @@ module ActionView
|
|
237
296
|
config.locale = value
|
238
297
|
end
|
239
298
|
|
240
|
-
super(
|
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
|
299
|
+
super(default_locale)
|
257
300
|
end
|
258
301
|
end
|
259
302
|
end
|
data/lib/action_view/path_set.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module ActionView #:nodoc:
|
2
4
|
# = Action View PathSet
|
3
5
|
#
|
@@ -46,44 +48,44 @@ module ActionView #:nodoc:
|
|
46
48
|
find_all(*args).first || raise(MissingTemplate.new(self, *args))
|
47
49
|
end
|
48
50
|
|
49
|
-
def find_file(path, prefixes = [], *args)
|
50
|
-
_find_all(path, prefixes, args, true).first || raise(MissingTemplate.new(self, path, prefixes, *args))
|
51
|
-
end
|
52
|
-
|
53
51
|
def find_all(path, prefixes = [], *args)
|
54
|
-
_find_all path, prefixes, args
|
52
|
+
_find_all path, prefixes, args
|
55
53
|
end
|
56
54
|
|
57
55
|
def exists?(path, prefixes, *args)
|
58
56
|
find_all(path, prefixes, *args).any?
|
59
57
|
end
|
60
58
|
|
61
|
-
|
59
|
+
def find_all_with_query(query) # :nodoc:
|
60
|
+
paths.each do |resolver|
|
61
|
+
templates = resolver.find_all_with_query(query)
|
62
|
+
return templates unless templates.empty?
|
63
|
+
end
|
62
64
|
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
65
|
+
[]
|
66
|
+
end
|
67
|
+
|
68
|
+
private
|
69
|
+
def _find_all(path, prefixes, args)
|
70
|
+
prefixes = [prefixes] if String === prefixes
|
71
|
+
prefixes.each do |prefix|
|
72
|
+
paths.each do |resolver|
|
70
73
|
templates = resolver.find_all(path, prefix, *args)
|
74
|
+
return templates unless templates.empty?
|
71
75
|
end
|
72
|
-
return templates unless templates.empty?
|
73
76
|
end
|
77
|
+
[]
|
74
78
|
end
|
75
|
-
[]
|
76
|
-
end
|
77
79
|
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
80
|
+
def typecast(paths)
|
81
|
+
paths.map do |path|
|
82
|
+
case path
|
83
|
+
when Pathname, String
|
84
|
+
OptimizedFileSystemResolver.new path.to_s
|
85
|
+
else
|
86
|
+
path
|
87
|
+
end
|
85
88
|
end
|
86
89
|
end
|
87
|
-
end
|
88
90
|
end
|
89
91
|
end
|
data/lib/action_view/railtie.rb
CHANGED
@@ -1,33 +1,64 @@
|
|
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::
|
8
|
+
class Railtie < Rails::Engine # :nodoc:
|
7
9
|
config.action_view = ActiveSupport::OrderedOptions.new
|
8
|
-
config.action_view.embed_authenticity_token_in_remote_forms =
|
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
|
9
13
|
|
10
14
|
config.eager_load_namespaces << ActionView
|
11
15
|
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
+
config.after_initialize do |app|
|
17
|
+
ActionView::Helpers::FormTagHelper.embed_authenticity_token_in_remote_forms =
|
18
|
+
app.config.action_view.delete(:embed_authenticity_token_in_remote_forms)
|
19
|
+
end
|
20
|
+
|
21
|
+
config.after_initialize do |app|
|
22
|
+
form_with_generates_remote_forms = app.config.action_view.delete(:form_with_generates_remote_forms)
|
23
|
+
ActionView::Helpers::FormHelper.form_with_generates_remote_forms = form_with_generates_remote_forms
|
24
|
+
end
|
25
|
+
|
26
|
+
config.after_initialize do |app|
|
27
|
+
form_with_generates_ids = app.config.action_view.delete(:form_with_generates_ids)
|
28
|
+
unless form_with_generates_ids.nil?
|
29
|
+
ActionView::Helpers::FormHelper.form_with_generates_ids = form_with_generates_ids
|
16
30
|
end
|
17
31
|
end
|
18
32
|
|
19
|
-
|
20
|
-
|
33
|
+
config.after_initialize do |app|
|
34
|
+
default_enforce_utf8 = app.config.action_view.delete(:default_enforce_utf8)
|
35
|
+
unless default_enforce_utf8.nil?
|
36
|
+
ActionView::Helpers::FormTagHelper.default_enforce_utf8 = default_enforce_utf8
|
37
|
+
end
|
21
38
|
end
|
22
39
|
|
23
|
-
|
40
|
+
config.after_initialize do |app|
|
41
|
+
ActionView::Helpers::AssetTagHelper.preload_links_header = app.config.action_view.delete(:preload_links_header)
|
42
|
+
end
|
43
|
+
|
44
|
+
config.after_initialize do |app|
|
24
45
|
ActiveSupport.on_load(:action_view) do
|
25
|
-
app.config.action_view.each do |k,v|
|
46
|
+
app.config.action_view.each do |k, v|
|
47
|
+
if k == :raise_on_missing_translations
|
48
|
+
ActiveSupport::Deprecation.warn \
|
49
|
+
"action_view.raise_on_missing_translations is deprecated and will be removed in Rails 7.0. " \
|
50
|
+
"Set i18n.raise_on_missing_translations instead. " \
|
51
|
+
"Note that this new setting also affects how missing translations are handled in controllers."
|
52
|
+
end
|
26
53
|
send "#{k}=", v
|
27
54
|
end
|
28
55
|
end
|
29
56
|
end
|
30
57
|
|
58
|
+
initializer "action_view.logger" do
|
59
|
+
ActiveSupport.on_load(:action_view) { self.logger ||= Rails.logger }
|
60
|
+
end
|
61
|
+
|
31
62
|
initializer "action_view.caching" do |app|
|
32
63
|
ActiveSupport.on_load(:action_view) do
|
33
64
|
if app.config.action_view.cache_template_loading.nil?
|
@@ -38,12 +69,30 @@ module ActionView
|
|
38
69
|
|
39
70
|
initializer "action_view.setup_action_pack" do |app|
|
40
71
|
ActiveSupport.on_load(:action_controller) do
|
41
|
-
ActionView::RoutingUrlFor.
|
72
|
+
ActionView::RoutingUrlFor.include(ActionDispatch::Routing::UrlFor)
|
42
73
|
end
|
43
74
|
end
|
44
75
|
|
45
|
-
|
46
|
-
|
76
|
+
initializer "action_view.collection_caching", after: "action_controller.set_configs" do |app|
|
77
|
+
PartialRenderer.collection_cache = app.config.action_controller.cache_store
|
78
|
+
end
|
79
|
+
|
80
|
+
config.after_initialize do |app|
|
81
|
+
enable_caching = if app.config.action_view.cache_template_loading.nil?
|
82
|
+
app.config.cache_classes
|
83
|
+
else
|
84
|
+
app.config.action_view.cache_template_loading
|
85
|
+
end
|
86
|
+
|
87
|
+
unless enable_caching
|
88
|
+
app.executor.to_run ActionView::CacheExpiry::Executor.new(watcher: app.config.file_watcher)
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
rake_tasks do |app|
|
93
|
+
unless app.config.api_only
|
94
|
+
load "action_view/tasks/cache_digests.rake"
|
95
|
+
end
|
47
96
|
end
|
48
97
|
end
|
49
98
|
end
|
@@ -1,38 +1,66 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "active_support/core_ext/module"
|
4
|
+
require "action_view/model_naming"
|
3
5
|
|
4
6
|
module ActionView
|
5
|
-
#
|
6
|
-
#
|
7
|
-
# a higher logical level.
|
7
|
+
# RecordIdentifier encapsulates methods used by various ActionView helpers
|
8
|
+
# to associate records with DOM elements.
|
8
9
|
#
|
9
|
-
#
|
10
|
-
# resources :posts
|
10
|
+
# Consider for example the following code that form of post:
|
11
11
|
#
|
12
|
-
#
|
13
|
-
#
|
14
|
-
#
|
15
|
-
# <% end %> </div>
|
12
|
+
# <%= form_for(post) do |f| %>
|
13
|
+
# <%= f.text_field :body %>
|
14
|
+
# <% end %>
|
16
15
|
#
|
17
|
-
#
|
18
|
-
#
|
19
|
-
# post = Post.find(params[:id])
|
20
|
-
# post.update(params[:post])
|
16
|
+
# When +post+ is a new, unsaved ActiveRecord::Base instance, the resulting HTML
|
17
|
+
# is:
|
21
18
|
#
|
22
|
-
#
|
23
|
-
#
|
19
|
+
# <form class="new_post" id="new_post" action="/posts" accept-charset="UTF-8" method="post">
|
20
|
+
# <input type="text" name="post[body]" id="post_body" />
|
21
|
+
# </form>
|
22
|
+
#
|
23
|
+
# When +post+ is a persisted ActiveRecord::Base instance, the resulting HTML
|
24
|
+
# is:
|
25
|
+
#
|
26
|
+
# <form class="edit_post" id="edit_post_42" action="/posts/42" accept-charset="UTF-8" method="post">
|
27
|
+
# <input type="text" value="What a wonderful world!" name="post[body]" id="post_body" />
|
28
|
+
# </form>
|
29
|
+
#
|
30
|
+
# In both cases, the +id+ and +class+ of the wrapping DOM element are
|
31
|
+
# automatically generated, following naming conventions encapsulated by the
|
32
|
+
# RecordIdentifier methods #dom_id and #dom_class:
|
33
|
+
#
|
34
|
+
# dom_id(Post.new) # => "new_post"
|
35
|
+
# dom_class(Post.new) # => "post"
|
36
|
+
# dom_id(Post.find 42) # => "post_42"
|
37
|
+
# dom_class(Post.find 42) # => "post"
|
24
38
|
#
|
25
|
-
#
|
26
|
-
#
|
27
|
-
#
|
39
|
+
# Note that these methods do not strictly require +Post+ to be a subclass of
|
40
|
+
# ActiveRecord::Base.
|
41
|
+
# Any +Post+ class will work as long as its instances respond to +to_key+
|
42
|
+
# and +model_name+, given that +model_name+ responds to +param_key+.
|
43
|
+
# For instance:
|
44
|
+
#
|
45
|
+
# class Post
|
46
|
+
# attr_accessor :to_key
|
47
|
+
#
|
48
|
+
# def model_name
|
49
|
+
# OpenStruct.new param_key: 'post'
|
50
|
+
# end
|
51
|
+
#
|
52
|
+
# def self.find(id)
|
53
|
+
# new.tap { |post| post.to_key = [id] }
|
54
|
+
# end
|
55
|
+
# end
|
28
56
|
module RecordIdentifier
|
29
57
|
extend self
|
30
58
|
extend ModelNaming
|
31
59
|
|
32
60
|
include ModelNaming
|
33
61
|
|
34
|
-
JOIN =
|
35
|
-
NEW =
|
62
|
+
JOIN = "_"
|
63
|
+
NEW = "new"
|
36
64
|
|
37
65
|
# The DOM class convention is to use the singular form of an object or class.
|
38
66
|
#
|
@@ -66,8 +94,7 @@ module ActionView
|
|
66
94
|
end
|
67
95
|
end
|
68
96
|
|
69
|
-
|
70
|
-
|
97
|
+
private
|
71
98
|
# Returns a string representation of the key attribute(s) that is suitable for use in an HTML DOM id.
|
72
99
|
# This can be overwritten to customize the default generated string representation if desired.
|
73
100
|
# If you need to read back a key from a dom_id in order to query for the underlying database record,
|
@@ -76,9 +103,9 @@ module ActionView
|
|
76
103
|
# overwritten version of the method. By default, this implementation passes the key string through a
|
77
104
|
# method that replaces all characters that are invalid inside DOM ids, with valid ones. You need to
|
78
105
|
# make sure yourself that your dom ids are valid, in case you overwrite this method.
|
79
|
-
def record_key_for_dom_id(record)
|
106
|
+
def record_key_for_dom_id(record) # :doc:
|
80
107
|
key = convert_to_model(record).to_key
|
81
|
-
key ? key.join(
|
108
|
+
key ? key.join(JOIN) : key
|
82
109
|
end
|
83
110
|
end
|
84
111
|
end
|