actionview 5.0.7.2 → 5.1.0.beta1
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 +5 -5
- data/CHANGELOG.md +92 -384
- data/MIT-LICENSE +1 -1
- data/README.rdoc +1 -1
- data/lib/action_view.rb +5 -5
- 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 +6 -7
- data/lib/action_view/flows.rb +5 -6
- data/lib/action_view/gem_version.rb +3 -3
- data/lib/action_view/helpers.rb +1 -1
- 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 +34 -20
- data/lib/action_view/helpers/capture_helper.rb +2 -2
- data/lib/action_view/helpers/controller_helper.rb +3 -11
- data/lib/action_view/helpers/csrf_helper.rb +3 -3
- data/lib/action_view/helpers/date_helper.rb +109 -107
- data/lib/action_view/helpers/debug_helper.rb +2 -3
- data/lib/action_view/helpers/form_helper.rb +406 -31
- data/lib/action_view/helpers/form_options_helper.rb +12 -12
- data/lib/action_view/helpers/form_tag_helper.rb +19 -18
- 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/rendering_helper.rb +2 -2
- data/lib/action_view/helpers/sanitize_helper.rb +6 -8
- 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 +8 -8
- data/lib/action_view/helpers/tags/collection_helpers.rb +60 -60
- data/lib/action_view/helpers/tags/collection_radio_buttons.rb +2 -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 +42 -38
- data/lib/action_view/layouts.rb +51 -47
- data/lib/action_view/log_subscriber.rb +24 -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 +3 -3
- 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.rb +188 -187
- data/lib/action_view/renderer/partial_renderer/collection_caching.rb +7 -1
- 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.rb +26 -27
- data/lib/action_view/template/error.rb +5 -15
- data/lib/action_view/template/handlers.rb +4 -4
- data/lib/action_view/template/handlers/builder.rb +7 -7
- data/lib/action_view/template/handlers/erb.rb +9 -76
- 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/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/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/assets/compiled/rails-ujs.js +648 -0
- metadata +19 -14
@@ -25,9 +25,15 @@ module ActionView
|
|
25
25
|
end
|
26
26
|
end
|
27
27
|
|
28
|
+
def callable_cache_key?
|
29
|
+
@options[:cached].respond_to?(:call)
|
30
|
+
end
|
31
|
+
|
28
32
|
def collection_by_cache_keys
|
33
|
+
seed = callable_cache_key? ? @options[:cached] : ->(i) { i }
|
34
|
+
|
29
35
|
@collection.each_with_object({}) do |item, hash|
|
30
|
-
hash[expanded_cache_key(item)] = item
|
36
|
+
hash[expanded_cache_key(seed.call(item))] = item
|
31
37
|
end
|
32
38
|
end
|
33
39
|
|
@@ -1,10 +1,9 @@
|
|
1
|
-
require
|
1
|
+
require "fiber"
|
2
2
|
|
3
3
|
module ActionView
|
4
4
|
# == TODO
|
5
5
|
#
|
6
6
|
# * Support streaming from child templates, partials and so on.
|
7
|
-
# * Integrate exceptions with exceptron
|
8
7
|
# * Rack::Cache needs to support streaming bodies
|
9
8
|
class StreamingTemplateRenderer < TemplateRenderer #:nodoc:
|
10
9
|
# A valid Rack::Body (i.e. it responds to each).
|
@@ -27,17 +26,16 @@ module ActionView
|
|
27
26
|
|
28
27
|
private
|
29
28
|
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
return unless logger
|
29
|
+
# This is the same logging logic as in ShowExceptions middleware.
|
30
|
+
def log_error(exception)
|
31
|
+
logger = ActionView::Base.logger
|
32
|
+
return unless logger
|
35
33
|
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
34
|
+
message = "\n#{exception.class} (#{exception.message}):\n"
|
35
|
+
message << exception.annoted_source_code.to_s if exception.respond_to?(:annoted_source_code)
|
36
|
+
message << " " << exception.backtrace.join("\n ")
|
37
|
+
logger.fatal("#{message}\n\n")
|
38
|
+
end
|
41
39
|
end
|
42
40
|
|
43
41
|
# For streaming, instead of rendering a given a template, we return a Body
|
@@ -56,48 +54,48 @@ module ActionView
|
|
56
54
|
|
57
55
|
private
|
58
56
|
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
57
|
+
def delayed_render(buffer, template, layout, view, locals)
|
58
|
+
# Wrap the given buffer in the StreamingBuffer and pass it to the
|
59
|
+
# underlying template handler. Now, every time something is concatenated
|
60
|
+
# to the buffer, it is not appended to an array, but streamed straight
|
61
|
+
# to the client.
|
62
|
+
output = ActionView::StreamingBuffer.new(buffer)
|
63
|
+
yielder = lambda { |*name| view._layout_for(*name) }
|
64
|
+
|
65
|
+
instrument(:template, identifier: template.identifier, layout: layout.try(:virtual_path)) do
|
66
|
+
fiber = Fiber.new do
|
67
|
+
if layout
|
68
|
+
layout.render(view, locals, output, &yielder)
|
69
|
+
else
|
70
|
+
# If you don't have a layout, just render the thing
|
71
|
+
# and concatenate the final result. This is the same
|
72
|
+
# as a layout with just <%= yield %>
|
73
|
+
output.safe_concat view._layout_for
|
74
|
+
end
|
76
75
|
end
|
77
|
-
end
|
78
76
|
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
77
|
+
# Set the view flow to support streaming. It will be aware
|
78
|
+
# when to stop rendering the layout because it needs to search
|
79
|
+
# something in the template and vice-versa.
|
80
|
+
view.view_flow = StreamingFlow.new(view, fiber)
|
83
81
|
|
84
|
-
|
85
|
-
|
82
|
+
# Yo! Start the fiber!
|
83
|
+
fiber.resume
|
86
84
|
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
85
|
+
# If the fiber is still alive, it means we need something
|
86
|
+
# from the template, so start rendering it. If not, it means
|
87
|
+
# the layout exited without requiring anything from the template.
|
88
|
+
if fiber.alive?
|
89
|
+
content = template.render(view, locals, &yielder)
|
92
90
|
|
93
|
-
|
94
|
-
|
91
|
+
# Once rendering the template is done, sets its content in the :layout key.
|
92
|
+
view.view_flow.set(:layout, content)
|
95
93
|
|
96
|
-
|
97
|
-
|
98
|
-
|
94
|
+
# In case the layout continues yielding, we need to resume
|
95
|
+
# the fiber until all yields are handled.
|
96
|
+
fiber.resume while fiber.alive?
|
97
|
+
end
|
99
98
|
end
|
100
99
|
end
|
101
|
-
end
|
102
100
|
end
|
103
101
|
end
|
@@ -1,4 +1,4 @@
|
|
1
|
-
require
|
1
|
+
require "active_support/core_ext/object/try"
|
2
2
|
|
3
3
|
module ActionView
|
4
4
|
class TemplateRenderer < AbstractRenderer #:nodoc:
|
@@ -16,87 +16,85 @@ module ActionView
|
|
16
16
|
|
17
17
|
private
|
18
18
|
|
19
|
-
|
20
|
-
|
21
|
-
|
19
|
+
# Determine the template to be rendered using the given options.
|
20
|
+
def determine_template(options)
|
21
|
+
keys = options.has_key?(:locals) ? options[:locals].keys : []
|
22
22
|
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
23
|
+
if options.key?(:body)
|
24
|
+
Template::Text.new(options[:body])
|
25
|
+
elsif options.key?(:plain)
|
26
|
+
Template::Text.new(options[:plain])
|
27
|
+
elsif options.key?(:html)
|
28
|
+
Template::HTML.new(options[:html], formats.first)
|
29
|
+
elsif options.key?(:file)
|
30
|
+
with_fallbacks { find_file(options[:file], nil, false, keys, @details) }
|
31
|
+
elsif options.key?(:inline)
|
32
|
+
handler = Template.handler_for_extension(options[:type] || "erb")
|
33
|
+
Template.new(options[:inline], "inline template", handler, locals: keys)
|
34
|
+
elsif options.key?(:template)
|
35
|
+
if options[:template].respond_to?(:render)
|
36
|
+
options[:template]
|
37
|
+
else
|
38
|
+
find_template(options[:template], options[:prefixes], false, keys, @details)
|
39
|
+
end
|
39
40
|
else
|
40
|
-
|
41
|
+
raise ArgumentError, "You invoked render but did not give any of :partial, :template, :inline, :file, :plain, :html or :body option."
|
41
42
|
end
|
42
|
-
else
|
43
|
-
raise ArgumentError, "You invoked render but did not give any of :partial, :template, :inline, :file, :plain, :html, :text or :body option."
|
44
43
|
end
|
45
|
-
end
|
46
44
|
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
45
|
+
# Renders the given template. A string representing the layout can be
|
46
|
+
# supplied as well.
|
47
|
+
def render_template(template, layout_name = nil, locals = nil)
|
48
|
+
view, locals = @view, locals || {}
|
51
49
|
|
52
|
-
|
53
|
-
|
54
|
-
|
50
|
+
render_with_layout(layout_name, locals) do |layout|
|
51
|
+
instrument(:template, identifier: template.identifier, layout: layout.try(:virtual_path)) do
|
52
|
+
template.render(view, locals) { |*name| view._layout_for(*name) }
|
53
|
+
end
|
55
54
|
end
|
56
55
|
end
|
57
|
-
end
|
58
56
|
|
59
|
-
|
60
|
-
|
61
|
-
|
57
|
+
def render_with_layout(path, locals)
|
58
|
+
layout = path && find_layout(path, locals.keys, [formats.first])
|
59
|
+
content = yield(layout)
|
62
60
|
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
61
|
+
if layout
|
62
|
+
view = @view
|
63
|
+
view.view_flow.set(:layout, content)
|
64
|
+
layout.render(view, locals) { |*name| view._layout_for(*name) }
|
65
|
+
else
|
66
|
+
content
|
67
|
+
end
|
69
68
|
end
|
70
|
-
end
|
71
69
|
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
70
|
+
# This is the method which actually finds the layout using details in the lookup
|
71
|
+
# context object. If no layout is found, it checks if at least a layout with
|
72
|
+
# the given name exists across all details before raising the error.
|
73
|
+
def find_layout(layout, keys, formats)
|
74
|
+
resolve_layout(layout, keys, formats)
|
75
|
+
end
|
78
76
|
|
79
|
-
|
80
|
-
|
81
|
-
|
77
|
+
def resolve_layout(layout, keys, formats)
|
78
|
+
details = @details.dup
|
79
|
+
details[:formats] = formats
|
82
80
|
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
81
|
+
case layout
|
82
|
+
when String
|
83
|
+
begin
|
84
|
+
if layout.start_with?("/")
|
85
|
+
with_fallbacks { find_template(layout, nil, false, [], details) }
|
86
|
+
else
|
87
|
+
find_template(layout, nil, false, [], details)
|
88
|
+
end
|
89
|
+
rescue ActionView::MissingTemplate
|
90
|
+
all_details = @details.merge(formats: @lookup_context.default_formats)
|
91
|
+
raise unless template_exists?(layout, nil, false, [], all_details)
|
90
92
|
end
|
91
|
-
|
92
|
-
|
93
|
-
|
93
|
+
when Proc
|
94
|
+
resolve_layout(layout.call(formats), keys, formats)
|
95
|
+
else
|
96
|
+
layout
|
94
97
|
end
|
95
|
-
when Proc
|
96
|
-
resolve_layout(layout.call(formats), keys, formats)
|
97
|
-
else
|
98
|
-
layout
|
99
98
|
end
|
100
|
-
end
|
101
99
|
end
|
102
100
|
end
|
@@ -84,15 +84,14 @@ module ActionView
|
|
84
84
|
end
|
85
85
|
|
86
86
|
def rendered_format
|
87
|
-
|
88
|
-
Template::Types[format] || format
|
87
|
+
Template::Types[lookup_context.rendered_format]
|
89
88
|
end
|
90
89
|
|
91
90
|
private
|
92
91
|
|
93
92
|
# Find and render a template based on the options given.
|
94
93
|
# :api: private
|
95
|
-
def _render_template(options)
|
94
|
+
def _render_template(options)
|
96
95
|
variant = options.delete(:variant)
|
97
96
|
assigns = options.delete(:assigns)
|
98
97
|
context = view_context
|
@@ -105,7 +104,7 @@ module ActionView
|
|
105
104
|
end
|
106
105
|
|
107
106
|
# Assign the rendered format to look up context.
|
108
|
-
def _process_format(format)
|
107
|
+
def _process_format(format)
|
109
108
|
super
|
110
109
|
lookup_context.formats = [format.to_sym]
|
111
110
|
lookup_context.rendered_format = lookup_context.formats.first
|
@@ -114,7 +113,7 @@ module ActionView
|
|
114
113
|
# Normalize args by converting render "foo" to render :action => "foo" and
|
115
114
|
# render "foo/bar" to render :template => "foo/bar".
|
116
115
|
# :api: private
|
117
|
-
def _normalize_args(action=nil, options={})
|
116
|
+
def _normalize_args(action = nil, options = {})
|
118
117
|
options = super(action, options)
|
119
118
|
case action
|
120
119
|
when NilClass
|
@@ -1,8 +1,7 @@
|
|
1
|
-
require
|
1
|
+
require "action_dispatch/routing/polymorphic_routes"
|
2
2
|
|
3
3
|
module ActionView
|
4
4
|
module RoutingUrlFor
|
5
|
-
|
6
5
|
# Returns the URL for the set of +options+ provided. This takes the
|
7
6
|
# same options as +url_for+ in Action Controller (see the
|
8
7
|
# documentation for <tt>ActionController::Base#url_for</tt>). Note that by default
|
@@ -123,18 +122,15 @@ module ActionView
|
|
123
122
|
controller.url_options
|
124
123
|
end
|
125
124
|
|
126
|
-
def _routes_context #:nodoc:
|
127
|
-
controller
|
128
|
-
end
|
129
|
-
protected :_routes_context
|
130
|
-
|
131
|
-
def optimize_routes_generation? #:nodoc:
|
132
|
-
controller.respond_to?(:optimize_routes_generation?, true) ?
|
133
|
-
controller.optimize_routes_generation? : super
|
134
|
-
end
|
135
|
-
protected :optimize_routes_generation?
|
136
|
-
|
137
125
|
private
|
126
|
+
def _routes_context
|
127
|
+
controller
|
128
|
+
end
|
129
|
+
|
130
|
+
def optimize_routes_generation?
|
131
|
+
controller.respond_to?(:optimize_routes_generation?, true) ?
|
132
|
+
controller.optimize_routes_generation? : super
|
133
|
+
end
|
138
134
|
|
139
135
|
def _generate_paths_by_default
|
140
136
|
true
|
@@ -1,19 +1,19 @@
|
|
1
1
|
namespace :cache_digests do
|
2
|
-
desc
|
3
|
-
task :
|
4
|
-
abort
|
2
|
+
desc "Lookup nested dependencies for TEMPLATE (like messages/show or comments/_comment.html)"
|
3
|
+
task nested_dependencies: :environment do
|
4
|
+
abort "You must provide TEMPLATE for the task to run" unless ENV["TEMPLATE"].present?
|
5
5
|
puts JSON.pretty_generate ActionView::Digestor.tree(CacheDigests.template_name, CacheDigests.finder).children.map(&:to_dep_map)
|
6
6
|
end
|
7
7
|
|
8
|
-
desc
|
9
|
-
task :
|
10
|
-
abort
|
8
|
+
desc "Lookup first-level dependencies for TEMPLATE (like messages/show or comments/_comment.html)"
|
9
|
+
task dependencies: :environment do
|
10
|
+
abort "You must provide TEMPLATE for the task to run" unless ENV["TEMPLATE"].present?
|
11
11
|
puts JSON.pretty_generate ActionView::Digestor.tree(CacheDigests.template_name, CacheDigests.finder).children.map(&:name)
|
12
12
|
end
|
13
13
|
|
14
14
|
class CacheDigests
|
15
15
|
def self.template_name
|
16
|
-
ENV[
|
16
|
+
ENV["TEMPLATE"].split(".", 2).first
|
17
17
|
end
|
18
18
|
|
19
19
|
def self.finder
|
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
|