actionview 4.2.11.1 → 6.0.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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +201 -192
- data/MIT-LICENSE +1 -1
- data/README.rdoc +9 -8
- data/lib/action_view/base.rb +144 -37
- data/lib/action_view/buffers.rb +18 -1
- data/lib/action_view/cache_expiry.rb +53 -0
- data/lib/action_view/context.rb +8 -12
- data/lib/action_view/dependency_tracker.rb +54 -20
- data/lib/action_view/digestor.rb +88 -85
- data/lib/action_view/flows.rb +11 -12
- data/lib/action_view/gem_version.rb +6 -4
- data/lib/action_view/helpers/active_model_helper.rb +16 -11
- data/lib/action_view/helpers/asset_tag_helper.rb +241 -82
- data/lib/action_view/helpers/asset_url_helper.rb +171 -67
- data/lib/action_view/helpers/atom_feed_helper.rb +19 -17
- data/lib/action_view/helpers/cache_helper.rb +112 -42
- 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 +230 -129
- data/lib/action_view/helpers/debug_helper.rb +7 -6
- data/lib/action_view/helpers/form_helper.rb +755 -129
- data/lib/action_view/helpers/form_options_helper.rb +130 -75
- data/lib/action_view/helpers/form_tag_helper.rb +116 -71
- data/lib/action_view/helpers/javascript_helper.rb +30 -14
- data/lib/action_view/helpers/number_helper.rb +84 -59
- data/lib/action_view/helpers/output_safety_helper.rb +36 -4
- data/lib/action_view/helpers/rendering_helper.rb +11 -8
- data/lib/action_view/helpers/sanitize_helper.rb +30 -31
- data/lib/action_view/helpers/tag_helper.rb +201 -75
- data/lib/action_view/helpers/tags/base.rb +138 -98
- 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 +2 -1
- data/lib/action_view/helpers/tags/date_select.rb +37 -36
- data/lib/action_view/helpers/tags/datetime_field.rb +4 -3
- data/lib/action_view/helpers/tags/datetime_local_field.rb +2 -1
- 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 +2 -0
- data/lib/action_view/helpers/tags/label.rb +3 -2
- data/lib/action_view/helpers/tags/month_field.rb +2 -1
- 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 +2 -1
- 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 +2 -1
- 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 +91 -47
- data/lib/action_view/helpers/url_helper.rb +160 -105
- data/lib/action_view/helpers.rb +5 -3
- data/lib/action_view/layouts.rb +65 -61
- data/lib/action_view/log_subscriber.rb +61 -10
- data/lib/action_view/lookup_context.rb +147 -89
- data/lib/action_view/model_naming.rb +3 -1
- data/lib/action_view/path_set.rb +28 -23
- data/lib/action_view/railtie.rb +62 -6
- data/lib/action_view/record_identifier.rb +53 -26
- data/lib/action_view/renderer/abstract_renderer.rb +71 -13
- data/lib/action_view/renderer/partial_renderer/collection_caching.rb +103 -0
- data/lib/action_view/renderer/partial_renderer.rb +239 -225
- data/lib/action_view/renderer/renderer.rb +22 -8
- data/lib/action_view/renderer/streaming_template_renderer.rb +54 -54
- data/lib/action_view/renderer/template_renderer.rb +79 -73
- data/lib/action_view/rendering.rb +68 -44
- data/lib/action_view/routing_url_for.rb +33 -22
- 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 +87 -0
- data/lib/action_view/template/handlers/erb.rb +24 -86
- 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 +38 -8
- data/lib/action_view/template/html.rb +19 -10
- data/lib/action_view/template/inline.rb +22 -0
- data/lib/action_view/template/raw_file.rb +28 -0
- data/lib/action_view/template/resolver.rb +217 -193
- 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 +11 -10
- data/lib/action_view/template/types.rb +18 -18
- data/lib/action_view/template.rb +146 -90
- data/lib/action_view/test_case.rb +52 -32
- data/lib/action_view/testing/resolvers.rb +46 -34
- data/lib/action_view/unbound_template.rb +31 -0
- data/lib/action_view/version.rb +3 -1
- data/lib/action_view/view_paths.rb +48 -31
- data/lib/action_view.rb +11 -8
- data/lib/assets/compiled/rails-ujs.js +746 -0
- metadata +38 -29
- data/lib/action_view/helpers/record_tag_helper.rb +0 -108
- data/lib/action_view/tasks/dependencies.rake +0 -23
@@ -1,29 +1,33 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
require
|
4
|
-
require
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "concurrent/map"
|
4
|
+
require "active_support/core_ext/module/remove_method"
|
5
|
+
require "active_support/core_ext/module/attribute_accessors"
|
6
|
+
require "active_support/deprecation"
|
7
|
+
require "action_view/template/resolver"
|
5
8
|
|
6
9
|
module ActionView
|
7
10
|
# = Action View Lookup Context
|
8
11
|
#
|
9
|
-
# LookupContext is the object responsible
|
10
|
-
# templates, i.e. view paths and details.
|
11
|
-
#
|
12
|
-
#
|
12
|
+
# <tt>LookupContext</tt> is the object responsible for holding all information
|
13
|
+
# required for looking up templates, i.e. view paths and details.
|
14
|
+
# <tt>LookupContext</tt> is also responsible for generating a key, given to
|
15
|
+
# view paths, used in the resolver cache lookup. Since this key is generated
|
16
|
+
# only once during the request, it speeds up all cache accesses.
|
13
17
|
class LookupContext #:nodoc:
|
14
18
|
attr_accessor :prefixes, :rendered_format
|
19
|
+
deprecate :rendered_format
|
20
|
+
deprecate :rendered_format=
|
15
21
|
|
16
|
-
mattr_accessor :fallbacks
|
17
|
-
@@fallbacks = FallbackFileSystemResolver.instances
|
22
|
+
mattr_accessor :fallbacks, default: FallbackFileSystemResolver.instances
|
18
23
|
|
19
|
-
mattr_accessor :registered_details
|
20
|
-
self.registered_details = []
|
24
|
+
mattr_accessor :registered_details, default: []
|
21
25
|
|
22
|
-
def self.register_detail(name,
|
23
|
-
|
24
|
-
|
26
|
+
def self.register_detail(name, &block)
|
27
|
+
registered_details << name
|
28
|
+
Accessors::DEFAULT_PROCS[name] = block
|
25
29
|
|
26
|
-
Accessors.
|
30
|
+
Accessors.define_method(:"default_#{name}", &block)
|
27
31
|
Accessors.module_eval <<-METHOD, __FILE__, __LINE__ + 1
|
28
32
|
def #{name}
|
29
33
|
@details.fetch(:#{name}, [])
|
@@ -33,16 +37,12 @@ module ActionView
|
|
33
37
|
value = value.present? ? Array(value) : default_#{name}
|
34
38
|
_set_detail(:#{name}, value) if value != @details[:#{name}]
|
35
39
|
end
|
36
|
-
|
37
|
-
remove_possible_method :initialize_details
|
38
|
-
def initialize_details(details)
|
39
|
-
#{initialize.join("\n")}
|
40
|
-
end
|
41
40
|
METHOD
|
42
41
|
end
|
43
42
|
|
44
43
|
# Holds accessors for the registered details.
|
45
44
|
module Accessors #:nodoc:
|
45
|
+
DEFAULT_PROCS = {}
|
46
46
|
end
|
47
47
|
|
48
48
|
register_detail(:locale) do
|
@@ -54,29 +54,45 @@ module ActionView
|
|
54
54
|
end
|
55
55
|
register_detail(:formats) { ActionView::Base.default_formats || [:html, :text, :js, :css, :xml, :json] }
|
56
56
|
register_detail(:variants) { [] }
|
57
|
-
register_detail(:handlers){ Template::Handlers.extensions }
|
57
|
+
register_detail(:handlers) { Template::Handlers.extensions }
|
58
58
|
|
59
59
|
class DetailsKey #:nodoc:
|
60
60
|
alias :eql? :equal?
|
61
|
-
alias :object_hash :hash
|
62
61
|
|
63
|
-
|
64
|
-
@
|
62
|
+
@details_keys = Concurrent::Map.new
|
63
|
+
@digest_cache = Concurrent::Map.new
|
64
|
+
@view_context_mutex = Mutex.new
|
65
65
|
|
66
|
-
def self.
|
66
|
+
def self.digest_cache(details)
|
67
|
+
@digest_cache[details_cache_key(details)] ||= Concurrent::Map.new
|
68
|
+
end
|
69
|
+
|
70
|
+
def self.details_cache_key(details)
|
67
71
|
if details[:formats]
|
68
72
|
details = details.dup
|
69
|
-
details[:formats] &=
|
73
|
+
details[:formats] &= Template::Types.symbols
|
70
74
|
end
|
71
|
-
@details_keys[details] ||= new
|
75
|
+
@details_keys[details] ||= Object.new
|
72
76
|
end
|
73
77
|
|
74
78
|
def self.clear
|
79
|
+
ActionView::ViewPaths.all_view_paths.each do |path_set|
|
80
|
+
path_set.each(&:clear_cache)
|
81
|
+
end
|
82
|
+
ActionView::LookupContext.fallbacks.each(&:clear_cache)
|
83
|
+
@view_context_class = nil
|
75
84
|
@details_keys.clear
|
85
|
+
@digest_cache.clear
|
76
86
|
end
|
77
87
|
|
78
|
-
def
|
79
|
-
@
|
88
|
+
def self.digest_caches
|
89
|
+
@digest_cache.values
|
90
|
+
end
|
91
|
+
|
92
|
+
def self.view_context_class(klass)
|
93
|
+
@view_context_mutex.synchronize do
|
94
|
+
@view_context_class ||= klass.with_empty_template_cache
|
95
|
+
end
|
80
96
|
end
|
81
97
|
end
|
82
98
|
|
@@ -87,7 +103,7 @@ module ActionView
|
|
87
103
|
# Calculate the details key. Remove the handlers from calculation to improve performance
|
88
104
|
# since the user cannot modify it explicitly.
|
89
105
|
def details_key #:nodoc:
|
90
|
-
@details_key ||= DetailsKey.
|
106
|
+
@details_key ||= DetailsKey.details_cache_key(@details) if @cache
|
91
107
|
end
|
92
108
|
|
93
109
|
# Temporary skip passing the details_key forward.
|
@@ -98,10 +114,10 @@ module ActionView
|
|
98
114
|
@cache = old_value
|
99
115
|
end
|
100
116
|
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
@
|
117
|
+
private
|
118
|
+
def _set_detail(key, value) # :doc:
|
119
|
+
@details = @details.dup if @digest_cache || @details_key
|
120
|
+
@digest_cache = nil
|
105
121
|
@details_key = nil
|
106
122
|
@details[key] = value
|
107
123
|
end
|
@@ -111,59 +127,71 @@ module ActionView
|
|
111
127
|
module ViewPaths
|
112
128
|
attr_reader :view_paths, :html_fallback_for_js
|
113
129
|
|
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
130
|
def find(name, prefixes = [], partial = false, keys = [], options = {})
|
121
131
|
@view_paths.find(*args_for_lookup(name, prefixes, partial, keys, options))
|
122
132
|
end
|
123
133
|
alias :find_template :find
|
124
134
|
|
125
|
-
|
126
|
-
|
127
|
-
end
|
135
|
+
alias :find_file :find
|
136
|
+
deprecate :find_file
|
128
137
|
|
129
138
|
def find_all(name, prefixes = [], partial = false, keys = [], options = {})
|
130
139
|
@view_paths.find_all(*args_for_lookup(name, prefixes, partial, keys, options))
|
131
140
|
end
|
132
141
|
|
133
|
-
def exists?(name, prefixes = [], partial = false, keys = [], options
|
142
|
+
def exists?(name, prefixes = [], partial = false, keys = [], **options)
|
134
143
|
@view_paths.exists?(*args_for_lookup(name, prefixes, partial, keys, options))
|
135
144
|
end
|
136
145
|
alias :template_exists? :exists?
|
137
146
|
|
147
|
+
def any?(name, prefixes = [], partial = false)
|
148
|
+
@view_paths.exists?(*args_for_any(name, prefixes, partial))
|
149
|
+
end
|
150
|
+
alias :any_templates? :any?
|
151
|
+
|
138
152
|
# Adds fallbacks to the view paths. Useful in cases when you are rendering
|
139
153
|
# a :file.
|
140
154
|
def with_fallbacks
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
155
|
+
view_paths = build_view_paths((@view_paths.paths + self.class.fallbacks).uniq)
|
156
|
+
|
157
|
+
if block_given?
|
158
|
+
ActiveSupport::Deprecation.warn <<~eowarn.squish
|
159
|
+
Calling `with_fallbacks` with a block is deprecated. Call methods on
|
160
|
+
the lookup context returned by `with_fallbacks` instead.
|
161
|
+
eowarn
|
162
|
+
|
163
|
+
begin
|
164
|
+
_view_paths = @view_paths
|
165
|
+
@view_paths = view_paths
|
166
|
+
yield
|
167
|
+
ensure
|
168
|
+
@view_paths = _view_paths
|
169
|
+
end
|
170
|
+
else
|
171
|
+
ActionView::LookupContext.new(view_paths, @details, @prefixes)
|
146
172
|
end
|
147
|
-
yield
|
148
|
-
ensure
|
149
|
-
added_resolvers.times { view_paths.pop }
|
150
173
|
end
|
151
174
|
|
152
|
-
|
175
|
+
private
|
176
|
+
# Whenever setting view paths, makes a copy so that we can manipulate them in
|
177
|
+
# instance objects as we wish.
|
178
|
+
def build_view_paths(paths)
|
179
|
+
ActionView::PathSet.new(Array(paths))
|
180
|
+
end
|
153
181
|
|
154
|
-
def args_for_lookup(name, prefixes, partial, keys, details_options)
|
182
|
+
def args_for_lookup(name, prefixes, partial, keys, details_options)
|
155
183
|
name, prefixes = normalize_name(name, prefixes)
|
156
184
|
details, details_key = detail_args_for(details_options)
|
157
185
|
[name, prefixes, partial || false, details, details_key, keys]
|
158
186
|
end
|
159
187
|
|
160
188
|
# Compute details hash and key according to user options (e.g. passed from #render).
|
161
|
-
def detail_args_for(options)
|
189
|
+
def detail_args_for(options) # :doc:
|
162
190
|
return @details, details_key if options.empty? # most common path.
|
163
191
|
user_details = @details.merge(options)
|
164
192
|
|
165
193
|
if @cache
|
166
|
-
details_key = DetailsKey.
|
194
|
+
details_key = DetailsKey.details_cache_key(user_details)
|
167
195
|
else
|
168
196
|
details_key = nil
|
169
197
|
end
|
@@ -171,18 +199,44 @@ module ActionView
|
|
171
199
|
[user_details, details_key]
|
172
200
|
end
|
173
201
|
|
202
|
+
def args_for_any(name, prefixes, partial)
|
203
|
+
name, prefixes = normalize_name(name, prefixes)
|
204
|
+
details, details_key = detail_args_for_any
|
205
|
+
[name, prefixes, partial || false, details, details_key]
|
206
|
+
end
|
207
|
+
|
208
|
+
def detail_args_for_any
|
209
|
+
@detail_args_for_any ||= begin
|
210
|
+
details = {}
|
211
|
+
|
212
|
+
registered_details.each do |k|
|
213
|
+
if k == :variants
|
214
|
+
details[k] = :any
|
215
|
+
else
|
216
|
+
details[k] = Accessors::DEFAULT_PROCS[k].call
|
217
|
+
end
|
218
|
+
end
|
219
|
+
|
220
|
+
if @cache
|
221
|
+
[details, DetailsKey.details_cache_key(details)]
|
222
|
+
else
|
223
|
+
[details, nil]
|
224
|
+
end
|
225
|
+
end
|
226
|
+
end
|
227
|
+
|
174
228
|
# Support legacy foo.erb names even though we now ignore .erb
|
175
229
|
# as well as incorrectly putting part of the path in the template
|
176
230
|
# name instead of the prefix.
|
177
|
-
def normalize_name(name, prefixes)
|
231
|
+
def normalize_name(name, prefixes)
|
178
232
|
prefixes = prefixes.presence
|
179
|
-
parts = name.to_s.split(
|
233
|
+
parts = name.to_s.split("/")
|
180
234
|
parts.shift if parts.first.empty?
|
181
|
-
name
|
235
|
+
name = parts.pop
|
182
236
|
|
183
237
|
return name, prefixes || [""] if parts.empty?
|
184
238
|
|
185
|
-
parts = parts.join(
|
239
|
+
parts = parts.join("/")
|
186
240
|
prefixes = prefixes ? prefixes.map { |p| "#{p}/#{parts}" } : [parts]
|
187
241
|
|
188
242
|
return name, prefixes
|
@@ -194,21 +248,47 @@ module ActionView
|
|
194
248
|
include ViewPaths
|
195
249
|
|
196
250
|
def initialize(view_paths, details = {}, prefixes = [])
|
197
|
-
@
|
198
|
-
@
|
251
|
+
@details_key = nil
|
252
|
+
@digest_cache = nil
|
199
253
|
@cache = true
|
200
254
|
@prefixes = prefixes
|
201
|
-
@rendered_format = nil
|
202
255
|
|
203
|
-
|
204
|
-
|
256
|
+
@details = initialize_details({}, details)
|
257
|
+
@view_paths = build_view_paths(view_paths)
|
258
|
+
end
|
259
|
+
|
260
|
+
def digest_cache
|
261
|
+
@digest_cache ||= DetailsKey.digest_cache(@details)
|
262
|
+
end
|
263
|
+
|
264
|
+
def with_prepended_formats(formats)
|
265
|
+
details = @details.dup
|
266
|
+
details[:formats] = formats
|
267
|
+
|
268
|
+
self.class.new(@view_paths, details, @prefixes)
|
205
269
|
end
|
206
270
|
|
271
|
+
def initialize_details(target, details)
|
272
|
+
registered_details.each do |k|
|
273
|
+
target[k] = details[k] || Accessors::DEFAULT_PROCS[k].call
|
274
|
+
end
|
275
|
+
target
|
276
|
+
end
|
277
|
+
private :initialize_details
|
278
|
+
|
207
279
|
# Override formats= to expand ["*/*"] values and automatically
|
208
280
|
# add :html as fallback to :js.
|
209
281
|
def formats=(values)
|
210
282
|
if values
|
283
|
+
values = values.dup
|
211
284
|
values.concat(default_formats) if values.delete "*/*"
|
285
|
+
values.uniq!
|
286
|
+
|
287
|
+
invalid_values = (values - Template::Types.symbols)
|
288
|
+
unless invalid_values.empty?
|
289
|
+
raise ArgumentError, "Invalid formats: #{invalid_values.map(&:inspect).join(", ")}"
|
290
|
+
end
|
291
|
+
|
212
292
|
if values == [:js]
|
213
293
|
values << :html
|
214
294
|
@html_fallback_for_js = true
|
@@ -217,12 +297,6 @@ module ActionView
|
|
217
297
|
super(values)
|
218
298
|
end
|
219
299
|
|
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
300
|
# Override locale to return a symbol instead of array.
|
227
301
|
def locale
|
228
302
|
@details[:locale].first
|
@@ -237,23 +311,7 @@ module ActionView
|
|
237
311
|
config.locale = value
|
238
312
|
end
|
239
313
|
|
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
|
314
|
+
super(default_locale)
|
257
315
|
end
|
258
316
|
end
|
259
317
|
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,47 @@ module ActionView #:nodoc:
|
|
46
48
|
find_all(*args).first || raise(MissingTemplate.new(self, *args))
|
47
49
|
end
|
48
50
|
|
49
|
-
|
50
|
-
|
51
|
-
end
|
51
|
+
alias :find_file :find
|
52
|
+
deprecate :find_file
|
52
53
|
|
53
54
|
def find_all(path, prefixes = [], *args)
|
54
|
-
_find_all path, prefixes, args
|
55
|
+
_find_all path, prefixes, args
|
55
56
|
end
|
56
57
|
|
57
58
|
def exists?(path, prefixes, *args)
|
58
59
|
find_all(path, prefixes, *args).any?
|
59
60
|
end
|
60
61
|
|
61
|
-
|
62
|
+
def find_all_with_query(query) # :nodoc:
|
63
|
+
paths.each do |resolver|
|
64
|
+
templates = resolver.find_all_with_query(query)
|
65
|
+
return templates unless templates.empty?
|
66
|
+
end
|
62
67
|
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
68
|
+
[]
|
69
|
+
end
|
70
|
+
|
71
|
+
private
|
72
|
+
def _find_all(path, prefixes, args)
|
73
|
+
prefixes = [prefixes] if String === prefixes
|
74
|
+
prefixes.each do |prefix|
|
75
|
+
paths.each do |resolver|
|
70
76
|
templates = resolver.find_all(path, prefix, *args)
|
77
|
+
return templates unless templates.empty?
|
71
78
|
end
|
72
|
-
return templates unless templates.empty?
|
73
79
|
end
|
80
|
+
[]
|
74
81
|
end
|
75
|
-
[]
|
76
|
-
end
|
77
82
|
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
83
|
+
def typecast(paths)
|
84
|
+
paths.map do |path|
|
85
|
+
case path
|
86
|
+
when Pathname, String
|
87
|
+
OptimizedFileSystemResolver.new path.to_s
|
88
|
+
else
|
89
|
+
path
|
90
|
+
end
|
85
91
|
end
|
86
92
|
end
|
87
|
-
end
|
88
93
|
end
|
89
94
|
end
|
data/lib/action_view/railtie.rb
CHANGED
@@ -1,11 +1,18 @@
|
|
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:
|
9
|
+
NULL_OPTION = Object.new
|
10
|
+
|
7
11
|
config.action_view = ActiveSupport::OrderedOptions.new
|
8
|
-
config.action_view.embed_authenticity_token_in_remote_forms =
|
12
|
+
config.action_view.embed_authenticity_token_in_remote_forms = nil
|
13
|
+
config.action_view.debug_missing_translation = true
|
14
|
+
config.action_view.default_enforce_utf8 = nil
|
15
|
+
config.action_view.finalize_compiled_template_methods = NULL_OPTION
|
9
16
|
|
10
17
|
config.eager_load_namespaces << ActionView
|
11
18
|
|
@@ -16,13 +23,48 @@ module ActionView
|
|
16
23
|
end
|
17
24
|
end
|
18
25
|
|
26
|
+
initializer "action_view.form_with_generates_remote_forms" do |app|
|
27
|
+
ActiveSupport.on_load(:action_view) do
|
28
|
+
form_with_generates_remote_forms = app.config.action_view.delete(:form_with_generates_remote_forms)
|
29
|
+
ActionView::Helpers::FormHelper.form_with_generates_remote_forms = form_with_generates_remote_forms
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
initializer "action_view.form_with_generates_ids" do |app|
|
34
|
+
ActiveSupport.on_load(:action_view) do
|
35
|
+
form_with_generates_ids = app.config.action_view.delete(:form_with_generates_ids)
|
36
|
+
unless form_with_generates_ids.nil?
|
37
|
+
ActionView::Helpers::FormHelper.form_with_generates_ids = form_with_generates_ids
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
initializer "action_view.default_enforce_utf8" do |app|
|
43
|
+
ActiveSupport.on_load(:action_view) do
|
44
|
+
default_enforce_utf8 = app.config.action_view.delete(:default_enforce_utf8)
|
45
|
+
unless default_enforce_utf8.nil?
|
46
|
+
ActionView::Helpers::FormTagHelper.default_enforce_utf8 = default_enforce_utf8
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
initializer "action_view.finalize_compiled_template_methods" do |app|
|
52
|
+
ActiveSupport.on_load(:action_view) do
|
53
|
+
option = app.config.action_view.delete(:finalize_compiled_template_methods)
|
54
|
+
|
55
|
+
if option != NULL_OPTION
|
56
|
+
ActiveSupport::Deprecation.warn "action_view.finalize_compiled_template_methods is deprecated and has no effect"
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
19
61
|
initializer "action_view.logger" do
|
20
62
|
ActiveSupport.on_load(:action_view) { self.logger ||= Rails.logger }
|
21
63
|
end
|
22
64
|
|
23
65
|
initializer "action_view.set_configs" do |app|
|
24
66
|
ActiveSupport.on_load(:action_view) do
|
25
|
-
app.config.action_view.each do |k,v|
|
67
|
+
app.config.action_view.each do |k, v|
|
26
68
|
send "#{k}=", v
|
27
69
|
end
|
28
70
|
end
|
@@ -36,14 +78,28 @@ module ActionView
|
|
36
78
|
end
|
37
79
|
end
|
38
80
|
|
81
|
+
initializer "action_view.per_request_digest_cache" do |app|
|
82
|
+
ActiveSupport.on_load(:action_view) do
|
83
|
+
unless ActionView::Resolver.caching?
|
84
|
+
app.executor.to_run ActionView::CacheExpiry::Executor.new(watcher: app.config.file_watcher)
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
39
89
|
initializer "action_view.setup_action_pack" do |app|
|
40
90
|
ActiveSupport.on_load(:action_controller) do
|
41
|
-
ActionView::RoutingUrlFor.
|
91
|
+
ActionView::RoutingUrlFor.include(ActionDispatch::Routing::UrlFor)
|
42
92
|
end
|
43
93
|
end
|
44
94
|
|
45
|
-
|
46
|
-
|
95
|
+
initializer "action_view.collection_caching", after: "action_controller.set_configs" do |app|
|
96
|
+
PartialRenderer.collection_cache = app.config.action_controller.cache_store
|
97
|
+
end
|
98
|
+
|
99
|
+
rake_tasks do |app|
|
100
|
+
unless app.config.api_only
|
101
|
+
load "action_view/tasks/cache_digests.rake"
|
102
|
+
end
|
47
103
|
end
|
48
104
|
end
|
49
105
|
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
|