actionview 5.0.7.2 → 5.1.7
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 +169 -345
- data/MIT-LICENSE +1 -1
- data/README.rdoc +1 -1
- data/lib/action_view/base.rb +19 -19
- data/lib/action_view/buffers.rb +1 -1
- data/lib/action_view/context.rb +1 -1
- data/lib/action_view/dependency_tracker.rb +4 -5
- data/lib/action_view/digestor.rb +22 -13
- data/lib/action_view/flows.rb +5 -6
- data/lib/action_view/gem_version.rb +2 -2
- data/lib/action_view/helpers/active_model_helper.rb +8 -8
- data/lib/action_view/helpers/asset_tag_helper.rb +62 -36
- data/lib/action_view/helpers/asset_url_helper.rb +111 -49
- data/lib/action_view/helpers/atom_feed_helper.rb +12 -13
- data/lib/action_view/helpers/cache_helper.rb +32 -20
- data/lib/action_view/helpers/capture_helper.rb +2 -2
- data/lib/action_view/helpers/controller_helper.rb +2 -2
- data/lib/action_view/helpers/csrf_helper.rb +3 -3
- data/lib/action_view/helpers/date_helper.rb +119 -109
- data/lib/action_view/helpers/debug_helper.rb +2 -3
- data/lib/action_view/helpers/form_helper.rb +440 -31
- data/lib/action_view/helpers/form_options_helper.rb +12 -12
- data/lib/action_view/helpers/form_tag_helper.rb +20 -19
- data/lib/action_view/helpers/javascript_helper.rb +6 -6
- data/lib/action_view/helpers/number_helper.rb +48 -46
- data/lib/action_view/helpers/output_safety_helper.rb +8 -8
- data/lib/action_view/helpers/record_tag_helper.rb +2 -2
- data/lib/action_view/helpers/rendering_helper.rb +2 -3
- data/lib/action_view/helpers/sanitize_helper.rb +16 -12
- data/lib/action_view/helpers/tag_helper.rb +194 -77
- data/lib/action_view/helpers/tags/base.rb +121 -102
- data/lib/action_view/helpers/tags/check_box.rb +17 -17
- data/lib/action_view/helpers/tags/collection_check_boxes.rb +9 -8
- data/lib/action_view/helpers/tags/collection_helpers.rb +60 -60
- data/lib/action_view/helpers/tags/collection_radio_buttons.rb +3 -2
- data/lib/action_view/helpers/tags/collection_select.rb +2 -2
- data/lib/action_view/helpers/tags/date_select.rb +36 -36
- data/lib/action_view/helpers/tags/grouped_collection_select.rb +2 -2
- data/lib/action_view/helpers/tags/label.rb +4 -0
- data/lib/action_view/helpers/tags/password_field.rb +1 -1
- data/lib/action_view/helpers/tags/radio_button.rb +4 -4
- data/lib/action_view/helpers/tags/select.rb +9 -9
- data/lib/action_view/helpers/tags/text_area.rb +1 -1
- data/lib/action_view/helpers/tags/text_field.rb +5 -5
- data/lib/action_view/helpers/tags/translator.rb +14 -12
- data/lib/action_view/helpers/text_helper.rb +20 -19
- data/lib/action_view/helpers/translation_helper.rb +6 -6
- data/lib/action_view/helpers/url_helper.rb +48 -46
- data/lib/action_view/helpers.rb +1 -1
- data/lib/action_view/layouts.rb +51 -47
- data/lib/action_view/log_subscriber.rb +25 -9
- data/lib/action_view/lookup_context.rb +19 -25
- data/lib/action_view/path_set.rb +19 -19
- data/lib/action_view/railtie.rb +13 -4
- data/lib/action_view/record_identifier.rb +6 -6
- data/lib/action_view/renderer/abstract_renderer.rb +17 -17
- data/lib/action_view/renderer/partial_renderer/collection_caching.rb +7 -1
- data/lib/action_view/renderer/partial_renderer.rb +188 -187
- data/lib/action_view/renderer/renderer.rb +4 -0
- data/lib/action_view/renderer/streaming_template_renderer.rb +45 -47
- data/lib/action_view/renderer/template_renderer.rb +64 -66
- data/lib/action_view/rendering.rb +4 -5
- data/lib/action_view/routing_url_for.rb +9 -13
- data/lib/action_view/tasks/cache_digests.rake +7 -7
- data/lib/action_view/template/error.rb +5 -15
- data/lib/action_view/template/handlers/builder.rb +7 -7
- data/lib/action_view/template/handlers/erb/deprecated_erubis.rb +9 -0
- data/lib/action_view/template/handlers/erb/erubi.rb +81 -0
- data/lib/action_view/template/handlers/erb/erubis.rb +81 -0
- data/lib/action_view/template/handlers/erb.rb +9 -76
- data/lib/action_view/template/handlers.rb +4 -4
- data/lib/action_view/template/html.rb +2 -4
- data/lib/action_view/template/resolver.rb +107 -90
- data/lib/action_view/template/text.rb +5 -8
- data/lib/action_view/template/types.rb +1 -1
- data/lib/action_view/template.rb +26 -27
- data/lib/action_view/test_case.rb +20 -21
- data/lib/action_view/testing/resolvers.rb +29 -30
- data/lib/action_view/version.rb +1 -1
- data/lib/action_view/view_paths.rb +20 -8
- data/lib/action_view.rb +5 -5
- data/lib/assets/compiled/rails-ujs.js +683 -0
- metadata +18 -12
@@ -1,87 +1,20 @@
|
|
1
|
-
require 'erubis'
|
2
|
-
|
3
1
|
module ActionView
|
4
2
|
class Template
|
5
3
|
module Handlers
|
6
|
-
|
7
|
-
def add_preamble(src)
|
8
|
-
@newline_pending = 0
|
9
|
-
src << "@output_buffer = output_buffer || ActionView::OutputBuffer.new;"
|
10
|
-
end
|
11
|
-
|
12
|
-
def add_text(src, text)
|
13
|
-
return if text.empty?
|
14
|
-
|
15
|
-
if text == "\n"
|
16
|
-
@newline_pending += 1
|
17
|
-
else
|
18
|
-
src << "@output_buffer.safe_append='"
|
19
|
-
src << "\n" * @newline_pending if @newline_pending > 0
|
20
|
-
src << escape_text(text)
|
21
|
-
src << "'.freeze;"
|
22
|
-
|
23
|
-
@newline_pending = 0
|
24
|
-
end
|
25
|
-
end
|
26
|
-
|
27
|
-
# Erubis toggles <%= and <%== behavior when escaping is enabled.
|
28
|
-
# We override to always treat <%== as escaped.
|
29
|
-
def add_expr(src, code, indicator)
|
30
|
-
case indicator
|
31
|
-
when '=='
|
32
|
-
add_expr_escaped(src, code)
|
33
|
-
else
|
34
|
-
super
|
35
|
-
end
|
36
|
-
end
|
37
|
-
|
38
|
-
BLOCK_EXPR = /\s*((\s+|\))do|\{)(\s*\|[^|]*\|)?\s*\Z/
|
39
|
-
|
40
|
-
def add_expr_literal(src, code)
|
41
|
-
flush_newline_if_pending(src)
|
42
|
-
if code =~ BLOCK_EXPR
|
43
|
-
src << '@output_buffer.append= ' << code
|
44
|
-
else
|
45
|
-
src << '@output_buffer.append=(' << code << ');'
|
46
|
-
end
|
47
|
-
end
|
48
|
-
|
49
|
-
def add_expr_escaped(src, code)
|
50
|
-
flush_newline_if_pending(src)
|
51
|
-
if code =~ BLOCK_EXPR
|
52
|
-
src << "@output_buffer.safe_expr_append= " << code
|
53
|
-
else
|
54
|
-
src << "@output_buffer.safe_expr_append=(" << code << ");"
|
55
|
-
end
|
56
|
-
end
|
57
|
-
|
58
|
-
def add_stmt(src, code)
|
59
|
-
flush_newline_if_pending(src)
|
60
|
-
super
|
61
|
-
end
|
62
|
-
|
63
|
-
def add_postamble(src)
|
64
|
-
flush_newline_if_pending(src)
|
65
|
-
src << '@output_buffer.to_s'
|
66
|
-
end
|
67
|
-
|
68
|
-
def flush_newline_if_pending(src)
|
69
|
-
if @newline_pending > 0
|
70
|
-
src << "@output_buffer.safe_append='#{"\n" * @newline_pending}'.freeze;"
|
71
|
-
@newline_pending = 0
|
72
|
-
end
|
73
|
-
end
|
74
|
-
end
|
4
|
+
autoload :Erubis, "action_view/template/handlers/erb/deprecated_erubis"
|
75
5
|
|
76
6
|
class ERB
|
7
|
+
autoload :Erubi, "action_view/template/handlers/erb/erubi"
|
8
|
+
autoload :Erubis, "action_view/template/handlers/erb/erubis"
|
9
|
+
|
77
10
|
# Specify trim mode for the ERB compiler. Defaults to '-'.
|
78
11
|
# See ERB documentation for suitable values.
|
79
12
|
class_attribute :erb_trim_mode
|
80
|
-
self.erb_trim_mode =
|
13
|
+
self.erb_trim_mode = "-"
|
81
14
|
|
82
15
|
# Default implementation used.
|
83
16
|
class_attribute :erb_implementation
|
84
|
-
self.erb_implementation =
|
17
|
+
self.erb_implementation = Erubi
|
85
18
|
|
86
19
|
# Do not escape templates of these mime types.
|
87
20
|
class_attribute :escape_whitelist
|
@@ -108,7 +41,7 @@ module ActionView
|
|
108
41
|
# expression
|
109
42
|
template_source = template.source.dup.force_encoding(Encoding::ASCII_8BIT)
|
110
43
|
|
111
|
-
erb = template_source.gsub(ENCODING_TAG,
|
44
|
+
erb = template_source.gsub(ENCODING_TAG, "")
|
112
45
|
encoding = $2
|
113
46
|
|
114
47
|
erb.force_encoding valid_encoding(template.source.dup, encoding)
|
@@ -118,8 +51,8 @@ module ActionView
|
|
118
51
|
|
119
52
|
self.class.erb_implementation.new(
|
120
53
|
erb,
|
121
|
-
:
|
122
|
-
:
|
54
|
+
escape: (self.class.escape_whitelist.include? template.type),
|
55
|
+
trim: (self.class.erb_trim_mode == "-")
|
123
56
|
).src
|
124
57
|
end
|
125
58
|
|
@@ -2,10 +2,10 @@ module ActionView #:nodoc:
|
|
2
2
|
# = Action View Template Handlers
|
3
3
|
class Template
|
4
4
|
module Handlers #:nodoc:
|
5
|
-
autoload :Raw,
|
6
|
-
autoload :ERB,
|
7
|
-
autoload :Html,
|
8
|
-
autoload :Builder,
|
5
|
+
autoload :Raw, "action_view/template/handlers/raw"
|
6
|
+
autoload :ERB, "action_view/template/handlers/erb"
|
7
|
+
autoload :Html, "action_view/template/handlers/html"
|
8
|
+
autoload :Builder, "action_view/template/handlers/builder"
|
9
9
|
|
10
10
|
def self.extended(base)
|
11
11
|
base.register_default_template_handler :raw, Raw.new
|
@@ -37,15 +37,15 @@ module ActionView
|
|
37
37
|
class Cache #:nodoc:
|
38
38
|
class SmallCache < Concurrent::Map
|
39
39
|
def initialize(options = {})
|
40
|
-
super(options.merge(:
|
40
|
+
super(options.merge(initial_capacity: 2))
|
41
41
|
end
|
42
42
|
end
|
43
43
|
|
44
44
|
# preallocate all the default blocks for performance/memory consumption reasons
|
45
|
-
PARTIAL_BLOCK = lambda {|cache, partial| cache[partial] = SmallCache.new}
|
46
|
-
PREFIX_BLOCK = lambda {|cache, prefix| cache[prefix] = SmallCache.new(&PARTIAL_BLOCK)}
|
47
|
-
NAME_BLOCK = lambda {|cache, name| cache[name] = SmallCache.new(&PREFIX_BLOCK)}
|
48
|
-
KEY_BLOCK = lambda {|cache, key| cache[key] = SmallCache.new(&NAME_BLOCK)}
|
45
|
+
PARTIAL_BLOCK = lambda { |cache, partial| cache[partial] = SmallCache.new }
|
46
|
+
PREFIX_BLOCK = lambda { |cache, prefix| cache[prefix] = SmallCache.new(&PARTIAL_BLOCK) }
|
47
|
+
NAME_BLOCK = lambda { |cache, name| cache[name] = SmallCache.new(&PREFIX_BLOCK) }
|
48
|
+
KEY_BLOCK = lambda { |cache, key| cache[key] = SmallCache.new(&NAME_BLOCK) }
|
49
49
|
|
50
50
|
# usually a majority of template look ups return nothing, use this canonical preallocated array to save memory
|
51
51
|
NO_TEMPLATES = [].freeze
|
@@ -88,24 +88,41 @@ module ActionView
|
|
88
88
|
@query_cache.clear
|
89
89
|
end
|
90
90
|
|
91
|
-
|
91
|
+
# Get the cache size. Do not call this
|
92
|
+
# method. This method is not guaranteed to be here ever.
|
93
|
+
def size # :nodoc:
|
94
|
+
size = 0
|
95
|
+
@data.each_value do |v1|
|
96
|
+
v1.each_value do |v2|
|
97
|
+
v2.each_value do |v3|
|
98
|
+
v3.each_value do |v4|
|
99
|
+
size += v4.size
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
92
104
|
|
93
|
-
|
94
|
-
templates.empty? ? NO_TEMPLATES : templates
|
105
|
+
size + @query_cache.size
|
95
106
|
end
|
96
107
|
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
return fresh_templates.blank? != cached_templates.blank?
|
108
|
+
private
|
109
|
+
|
110
|
+
def canonical_no_templates(templates)
|
111
|
+
templates.empty? ? NO_TEMPLATES : templates
|
102
112
|
end
|
103
113
|
|
104
|
-
|
114
|
+
def templates_have_changed?(cached_templates, fresh_templates)
|
115
|
+
# if either the old or new template list is empty, we don't need to (and can't)
|
116
|
+
# compare modification times, and instead just check whether the lists are different
|
117
|
+
if cached_templates.blank? || fresh_templates.blank?
|
118
|
+
return fresh_templates.blank? != cached_templates.blank?
|
119
|
+
end
|
105
120
|
|
106
|
-
|
107
|
-
|
108
|
-
|
121
|
+
cached_templates_max_updated_at = cached_templates.map(&:updated_at).max
|
122
|
+
|
123
|
+
# if a template has changed, it will be now be newer than all the cached templates
|
124
|
+
fresh_templates.any? { |t| t.updated_at > cached_templates_max_updated_at }
|
125
|
+
end
|
109
126
|
end
|
110
127
|
|
111
128
|
cattr_accessor :caching
|
@@ -124,13 +141,13 @@ module ActionView
|
|
124
141
|
end
|
125
142
|
|
126
143
|
# Normalizes the arguments and passes it on to find_templates.
|
127
|
-
def find_all(name, prefix=nil, partial=false, details={}, key=nil, locals=[])
|
144
|
+
def find_all(name, prefix = nil, partial = false, details = {}, key = nil, locals = [])
|
128
145
|
cached(key, [name, prefix, partial], details, locals) do
|
129
146
|
find_templates(name, prefix, partial, details)
|
130
147
|
end
|
131
148
|
end
|
132
149
|
|
133
|
-
def find_all_anywhere(name, prefix, partial=false, details={}, key=nil, locals=[])
|
150
|
+
def find_all_anywhere(name, prefix, partial = false, details = {}, key = nil, locals = [])
|
134
151
|
cached(key, [name, prefix, partial], details, locals) do
|
135
152
|
find_templates(name, prefix, partial, details, true)
|
136
153
|
end
|
@@ -160,7 +177,7 @@ module ActionView
|
|
160
177
|
# always check the cache before hitting the resolver. Otherwise,
|
161
178
|
# it always hits the resolver but if the key is present, check if the
|
162
179
|
# resolver is fresher before returning it.
|
163
|
-
def cached(key, path_info, details, locals)
|
180
|
+
def cached(key, path_info, details, locals)
|
164
181
|
name, prefix, partial = path_info
|
165
182
|
locals = locals.map(&:to_s).sort!
|
166
183
|
|
@@ -174,7 +191,7 @@ module ActionView
|
|
174
191
|
end
|
175
192
|
|
176
193
|
# Ensures all the resolver information is set in the template.
|
177
|
-
def decorate(templates, path_info, details, locals)
|
194
|
+
def decorate(templates, path_info, details, locals)
|
178
195
|
cached = nil
|
179
196
|
templates.each do |t|
|
180
197
|
t.locals = locals
|
@@ -187,103 +204,103 @@ module ActionView
|
|
187
204
|
|
188
205
|
# An abstract class that implements a Resolver with path semantics.
|
189
206
|
class PathResolver < Resolver #:nodoc:
|
190
|
-
EXTENSIONS = { :
|
207
|
+
EXTENSIONS = { locale: ".", formats: ".", variants: "+", handlers: "." }
|
191
208
|
DEFAULT_PATTERN = ":prefix/:action{.:locale,}{.:formats,}{+:variants,}{.:handlers,}"
|
192
209
|
|
193
|
-
def initialize(pattern=nil)
|
210
|
+
def initialize(pattern = nil)
|
194
211
|
@pattern = pattern || DEFAULT_PATTERN
|
195
212
|
super()
|
196
213
|
end
|
197
214
|
|
198
215
|
private
|
199
216
|
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
217
|
+
def find_templates(name, prefix, partial, details, outside_app_allowed = false)
|
218
|
+
path = Path.build(name, prefix, partial)
|
219
|
+
query(path, details, details[:formats], outside_app_allowed)
|
220
|
+
end
|
204
221
|
|
205
|
-
|
206
|
-
|
222
|
+
def query(path, details, formats, outside_app_allowed)
|
223
|
+
query = build_query(path, details)
|
207
224
|
|
208
|
-
|
209
|
-
|
225
|
+
template_paths = find_template_paths(query)
|
226
|
+
template_paths = reject_files_external_to_app(template_paths) unless outside_app_allowed
|
210
227
|
|
211
|
-
|
212
|
-
|
213
|
-
|
228
|
+
template_paths.map do |template|
|
229
|
+
handler, format, variant = extract_handler_and_format_and_variant(template)
|
230
|
+
contents = File.binread(template)
|
214
231
|
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
232
|
+
Template.new(contents, File.expand_path(template), handler,
|
233
|
+
virtual_path: path.virtual,
|
234
|
+
format: format,
|
235
|
+
variant: variant,
|
236
|
+
updated_at: mtime(template)
|
237
|
+
)
|
238
|
+
end
|
221
239
|
end
|
222
|
-
end
|
223
240
|
|
224
|
-
|
225
|
-
|
226
|
-
|
241
|
+
def reject_files_external_to_app(files)
|
242
|
+
files.reject { |filename| !inside_path?(@path, filename) }
|
243
|
+
end
|
227
244
|
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
245
|
+
def find_template_paths(query)
|
246
|
+
Dir[query].uniq.reject do |filename|
|
247
|
+
File.directory?(filename) ||
|
248
|
+
# deals with case-insensitive file systems.
|
249
|
+
!File.fnmatch(query, filename, File::FNM_EXTGLOB)
|
250
|
+
end
|
233
251
|
end
|
234
|
-
end
|
235
252
|
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
253
|
+
def inside_path?(path, filename)
|
254
|
+
filename = File.expand_path(filename)
|
255
|
+
path = File.join(path, "")
|
256
|
+
filename.start_with?(path)
|
257
|
+
end
|
241
258
|
|
242
|
-
|
243
|
-
|
244
|
-
|
259
|
+
# Helper for building query glob string based on resolver's pattern.
|
260
|
+
def build_query(path, details)
|
261
|
+
query = @pattern.dup
|
245
262
|
|
246
|
-
|
247
|
-
|
263
|
+
prefix = path.prefix.empty? ? "" : "#{escape_entry(path.prefix)}\\1"
|
264
|
+
query.gsub!(/:prefix(\/)?/, prefix)
|
248
265
|
|
249
|
-
|
250
|
-
|
266
|
+
partial = escape_entry(path.partial? ? "_#{path.name}" : path.name)
|
267
|
+
query.gsub!(/:action/, partial)
|
251
268
|
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
|
269
|
+
details.each do |ext, candidates|
|
270
|
+
if ext == :variants && candidates == :any
|
271
|
+
query.gsub!(/:#{ext}/, "*")
|
272
|
+
else
|
273
|
+
query.gsub!(/:#{ext}/, "{#{candidates.compact.uniq.join(',')}}")
|
274
|
+
end
|
257
275
|
end
|
258
|
-
end
|
259
276
|
|
260
|
-
|
261
|
-
|
277
|
+
File.expand_path(query, @path)
|
278
|
+
end
|
262
279
|
|
263
|
-
|
264
|
-
|
265
|
-
|
280
|
+
def escape_entry(entry)
|
281
|
+
entry.gsub(/[*?{}\[\]]/, '\\\\\\&'.freeze)
|
282
|
+
end
|
266
283
|
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
284
|
+
# Returns the file mtime from the filesystem.
|
285
|
+
def mtime(p)
|
286
|
+
File.mtime(p)
|
287
|
+
end
|
271
288
|
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
|
289
|
+
# Extract handler, formats and variant from path. If a format cannot be found neither
|
290
|
+
# from the path, or the handler, we should return the array of formats given
|
291
|
+
# to the resolver.
|
292
|
+
def extract_handler_and_format_and_variant(path)
|
293
|
+
pieces = File.basename(path).split(".".freeze)
|
294
|
+
pieces.shift
|
278
295
|
|
279
|
-
|
296
|
+
extension = pieces.pop
|
280
297
|
|
281
|
-
|
282
|
-
|
283
|
-
|
298
|
+
handler = Template.handler_for_extension(extension)
|
299
|
+
format, variant = pieces.last.split(EXTENSIONS[:variants], 2) if pieces.last
|
300
|
+
format &&= Template::Types[format]
|
284
301
|
|
285
|
-
|
286
|
-
|
302
|
+
[handler, format, variant]
|
303
|
+
end
|
287
304
|
end
|
288
305
|
|
289
306
|
# A resolver that loads files from the filesystem. It allows setting your own
|
@@ -325,7 +342,7 @@ module ActionView
|
|
325
342
|
# * <tt>:handlers</tt> - possible handlers (for example erb, haml, builder...)
|
326
343
|
#
|
327
344
|
class FileSystemResolver < PathResolver
|
328
|
-
def initialize(path, pattern=nil)
|
345
|
+
def initialize(path, pattern = nil)
|
329
346
|
raise ArgumentError, "path already is a Resolver class" if path.is_a?(Resolver)
|
330
347
|
super(pattern)
|
331
348
|
@path = File.expand_path(path)
|
@@ -4,19 +4,16 @@ module ActionView #:nodoc:
|
|
4
4
|
class Text #:nodoc:
|
5
5
|
attr_accessor :type
|
6
6
|
|
7
|
-
def initialize(string
|
7
|
+
def initialize(string)
|
8
8
|
@string = string.to_s
|
9
|
-
@type
|
10
|
-
@type ||= Types[:text]
|
9
|
+
@type = Types[:text]
|
11
10
|
end
|
12
11
|
|
13
12
|
def identifier
|
14
|
-
|
13
|
+
"text template"
|
15
14
|
end
|
16
15
|
|
17
|
-
|
18
|
-
'text template'
|
19
|
-
end
|
16
|
+
alias_method :inspect, :identifier
|
20
17
|
|
21
18
|
def to_str
|
22
19
|
@string
|
@@ -27,7 +24,7 @@ module ActionView #:nodoc:
|
|
27
24
|
end
|
28
25
|
|
29
26
|
def formats
|
30
|
-
[@type.
|
27
|
+
[@type.ref]
|
31
28
|
end
|
32
29
|
end
|
33
30
|
end
|
data/lib/action_view/template.rb
CHANGED
@@ -1,6 +1,5 @@
|
|
1
1
|
require "active_support/core_ext/object/try"
|
2
2
|
require "active_support/core_ext/kernel/singleton_class"
|
3
|
-
require "active_support/core_ext/module/delegation"
|
4
3
|
require "thread"
|
5
4
|
|
6
5
|
module ActionView
|
@@ -66,8 +65,7 @@ module ActionView
|
|
66
65
|
# If you want to provide an alternate mechanism for
|
67
66
|
# specifying encodings (like ERB does via <%# encoding: ... %>),
|
68
67
|
# you may indicate that you will handle encodings yourself
|
69
|
-
# by implementing <tt>
|
70
|
-
# on your handler.
|
68
|
+
# by implementing <tt>handles_encoding?</tt> on your handler.
|
71
69
|
#
|
72
70
|
# If you do, Rails will not try to encode the String
|
73
71
|
# into the default_internal, passing you the unaltered
|
@@ -142,7 +140,7 @@ module ActionView
|
|
142
140
|
end
|
143
141
|
|
144
142
|
# Returns whether the underlying handler supports streaming. If so,
|
145
|
-
# a streaming buffer *may* be passed when it
|
143
|
+
# a streaming buffer *may* be passed when it starts rendering.
|
146
144
|
def supports_streaming?
|
147
145
|
handler.respond_to?(:supports_streaming?) && handler.supports_streaming?
|
148
146
|
end
|
@@ -153,8 +151,8 @@ module ActionView
|
|
153
151
|
# This method is instrumented as "!render_template.action_view". Notice that
|
154
152
|
# we use a bang in this instrumentation because you don't want to
|
155
153
|
# consume this in production. This is only slow if it's being listened to.
|
156
|
-
def render(view, locals, buffer=nil, &block)
|
157
|
-
|
154
|
+
def render(view, locals, buffer = nil, &block)
|
155
|
+
instrument_render_template do
|
158
156
|
compile!(view)
|
159
157
|
view.send(method_name, locals, buffer, &block)
|
160
158
|
end
|
@@ -181,12 +179,12 @@ module ActionView
|
|
181
179
|
name = pieces.pop
|
182
180
|
partial = !!name.sub!(/^_/, "")
|
183
181
|
lookup.disable_cache do
|
184
|
-
lookup.find_template(name, [ pieces.join(
|
182
|
+
lookup.find_template(name, [ pieces.join("/") ], partial, @locals)
|
185
183
|
end
|
186
184
|
end
|
187
185
|
|
188
186
|
def inspect
|
189
|
-
@inspect ||= defined?(Rails.root) ? identifier.sub("#{Rails.root}/",
|
187
|
+
@inspect ||= defined?(Rails.root) ? identifier.sub("#{Rails.root}/", "".freeze) : identifier
|
190
188
|
end
|
191
189
|
|
192
190
|
# This method is responsible for properly setting the encoding of the
|
@@ -205,7 +203,7 @@ module ActionView
|
|
205
203
|
# Look for # encoding: *. If we find one, we'll encode the
|
206
204
|
# String in that encoding, otherwise, we'll use the
|
207
205
|
# default external encoding.
|
208
|
-
if source.sub!(/\A#{ENCODING_FLAG}/,
|
206
|
+
if source.sub!(/\A#{ENCODING_FLAG}/, "")
|
209
207
|
encoding = magic_encoding = $1
|
210
208
|
else
|
211
209
|
encoding = Encoding.default_external
|
@@ -233,11 +231,11 @@ module ActionView
|
|
233
231
|
end
|
234
232
|
end
|
235
233
|
|
236
|
-
|
234
|
+
private
|
237
235
|
|
238
236
|
# Compile a template. This method ensures a template is compiled
|
239
237
|
# just once and removes the source after it is compiled.
|
240
|
-
def compile!(view)
|
238
|
+
def compile!(view)
|
241
239
|
return if @compiled
|
242
240
|
|
243
241
|
# Templates can be used concurrently in threaded environments
|
@@ -278,9 +276,8 @@ module ActionView
|
|
278
276
|
# encode the source into <tt>Encoding.default_internal</tt>.
|
279
277
|
# In general, this means that templates will be UTF-8 inside of Rails,
|
280
278
|
# regardless of the original source encoding.
|
281
|
-
def compile(mod)
|
279
|
+
def compile(mod)
|
282
280
|
encode!
|
283
|
-
method_name = self.method_name
|
284
281
|
code = @handler.call(self)
|
285
282
|
|
286
283
|
# Make sure that the resulting String to be eval'd is in the
|
@@ -311,7 +308,7 @@ module ActionView
|
|
311
308
|
ObjectSpace.define_finalizer(self, Finalizer[method_name, mod])
|
312
309
|
end
|
313
310
|
|
314
|
-
def handle_render_error(view, e)
|
311
|
+
def handle_render_error(view, e)
|
315
312
|
if e.is_a?(Template::Error)
|
316
313
|
e.sub_template_of(self)
|
317
314
|
raise e
|
@@ -325,7 +322,7 @@ module ActionView
|
|
325
322
|
end
|
326
323
|
end
|
327
324
|
|
328
|
-
def locals_code
|
325
|
+
def locals_code
|
329
326
|
# Only locals with valid variable names get set directly. Others will
|
330
327
|
# still be available in local_assigns.
|
331
328
|
locals = @locals - Module::RUBY_RESERVED_KEYWORDS
|
@@ -335,26 +332,28 @@ module ActionView
|
|
335
332
|
locals.each_with_object("") { |key, code| code << "#{key} = #{key} = local_assigns[:#{key}];" }
|
336
333
|
end
|
337
334
|
|
338
|
-
def method_name
|
335
|
+
def method_name
|
339
336
|
@method_name ||= begin
|
340
337
|
m = "_#{identifier_method_name}__#{@identifier.hash}_#{__id__}"
|
341
|
-
m.tr!(
|
338
|
+
m.tr!("-".freeze, "_".freeze)
|
342
339
|
m
|
343
340
|
end
|
344
341
|
end
|
345
342
|
|
346
|
-
def identifier_method_name
|
347
|
-
inspect.tr(
|
343
|
+
def identifier_method_name
|
344
|
+
inspect.tr("^a-z_".freeze, "_".freeze)
|
348
345
|
end
|
349
346
|
|
350
|
-
def instrument(action, &block)
|
351
|
-
|
352
|
-
|
353
|
-
|
354
|
-
|
355
|
-
|
356
|
-
|
357
|
-
|
347
|
+
def instrument(action, &block) # :doc:
|
348
|
+
ActiveSupport::Notifications.instrument("#{action}.action_view", instrument_payload, &block)
|
349
|
+
end
|
350
|
+
|
351
|
+
def instrument_render_template(&block)
|
352
|
+
ActiveSupport::Notifications.instrument("!render_template.action_view".freeze, instrument_payload, &block)
|
353
|
+
end
|
354
|
+
|
355
|
+
def instrument_payload
|
356
|
+
{ virtual_path: @virtual_path, identifier: @identifier }
|
358
357
|
end
|
359
358
|
end
|
360
359
|
end
|