diff options
Diffstat (limited to 'actionview/lib/action_view')
-rw-r--r-- | actionview/lib/action_view/base.rb | 18 | ||||
-rw-r--r-- | actionview/lib/action_view/context.rb | 5 | ||||
-rw-r--r-- | actionview/lib/action_view/helpers/asset_tag_helper.rb | 10 | ||||
-rw-r--r-- | actionview/lib/action_view/renderer/partial_renderer.rb | 2 | ||||
-rw-r--r-- | actionview/lib/action_view/renderer/streaming_template_renderer.rb | 4 | ||||
-rw-r--r-- | actionview/lib/action_view/renderer/template_renderer.rb | 12 | ||||
-rw-r--r-- | actionview/lib/action_view/rendering.rb | 4 | ||||
-rw-r--r-- | actionview/lib/action_view/template.rb | 14 | ||||
-rw-r--r-- | actionview/lib/action_view/template/handlers/erb/erubi.rb | 10 |
9 files changed, 43 insertions, 36 deletions
diff --git a/actionview/lib/action_view/base.rb b/actionview/lib/action_view/base.rb index d41fe2a608..6cb342a0a9 100644 --- a/actionview/lib/action_view/base.rb +++ b/actionview/lib/action_view/base.rb @@ -10,6 +10,10 @@ require "action_view/template" require "action_view/lookup_context" module ActionView #:nodoc: + module CompiledTemplates #:nodoc: + # holds compiled template code + end + # = Action View Base # # Action View templates can be written in several ways. @@ -141,6 +145,8 @@ module ActionView #:nodoc: class Base include Helpers, ::ERB::Util, Context + include CompiledTemplates + # Specify the proc used to decorate input tags that refer to attributes with errors. cattr_accessor :field_error_proc, default: Proc.new { |html_tag, instance| "<div class=\"field_with_errors\">#{html_tag}</div>".html_safe } @@ -210,6 +216,18 @@ module ActionView #:nodoc: _prepare_context end + def run(method, locals, buffer, &block) + _old_output_buffer, _old_virtual_path = @output_buffer, @virtual_path + @output_buffer = buffer + send(method, locals, buffer, &block) + ensure + @output_buffer, @virtual_path = _old_output_buffer, _old_virtual_path + end + + def compiled_method_container + CompiledTemplates + end + ActiveSupport.run_load_hooks(:action_view, self) end end diff --git a/actionview/lib/action_view/context.rb b/actionview/lib/action_view/context.rb index 3c605c3ee3..2b22c30a3a 100644 --- a/actionview/lib/action_view/context.rb +++ b/actionview/lib/action_view/context.rb @@ -1,10 +1,6 @@ # frozen_string_literal: true module ActionView - module CompiledTemplates #:nodoc: - # holds compiled template code - end - # = Action View Context # # Action View contexts are supplied to Action Controller to render a template. @@ -16,7 +12,6 @@ module ActionView # object that includes this module (although you can call _prepare_context # defined below). module Context - include CompiledTemplates attr_accessor :output_buffer, :view_flow # Prepares the context by setting the appropriate instance variables. diff --git a/actionview/lib/action_view/helpers/asset_tag_helper.rb b/actionview/lib/action_view/helpers/asset_tag_helper.rb index c186cb8422..59d70a1dc4 100644 --- a/actionview/lib/action_view/helpers/asset_tag_helper.rb +++ b/actionview/lib/action_view/helpers/asset_tag_helper.rb @@ -329,14 +329,14 @@ module ActionView # image_tag("pic.jpg", srcset: [["pic_1024.jpg", "1024w"], ["pic_1980.jpg", "1980w"]], sizes: "100vw") # # => <img src="/assets/pic.jpg" srcset="/assets/pic_1024.jpg 1024w, /assets/pic_1980.jpg 1980w" sizes="100vw"> # - # Active Storage (images that are uploaded by the users of your app): + # Active Storage blobs (images that are uploaded by the users of your app): # # image_tag(user.avatar) # # => <img src="/rails/active_storage/blobs/.../tiger.jpg" /> - # image_tag(user.avatar.variant(resize_to_fit: [100, 100])) - # # => <img src="/rails/active_storage/variants/.../tiger.jpg" /> - # image_tag(user.avatar.variant(resize_to_fit: [100, 100]), size: '100') - # # => <img width="100" height="100" src="/rails/active_storage/variants/.../tiger.jpg" /> + # image_tag(user.avatar.variant(resize_to_limit: [100, 100])) + # # => <img src="/rails/active_storage/representations/.../tiger.jpg" /> + # image_tag(user.avatar.variant(resize_to_limit: [100, 100]), size: '100') + # # => <img width="100" height="100" src="/rails/active_storage/representations/.../tiger.jpg" /> def image_tag(source, options = {}) options = options.symbolize_keys check_for_image_tag_errors(options) diff --git a/actionview/lib/action_view/renderer/partial_renderer.rb b/actionview/lib/action_view/renderer/partial_renderer.rb index cb850d75ee..f175c30aa1 100644 --- a/actionview/lib/action_view/renderer/partial_renderer.rb +++ b/actionview/lib/action_view/renderer/partial_renderer.rb @@ -363,7 +363,7 @@ module ActionView @options = options @block = block - @locals = options[:locals] ? options[:locals].symbolize_keys : {} + @locals = options[:locals] || {} @details = extract_details(options) prepend_formats(options[:formats]) diff --git a/actionview/lib/action_view/renderer/streaming_template_renderer.rb b/actionview/lib/action_view/renderer/streaming_template_renderer.rb index bb9db21e32..f414620923 100644 --- a/actionview/lib/action_view/renderer/streaming_template_renderer.rb +++ b/actionview/lib/action_view/renderer/streaming_template_renderer.rb @@ -43,14 +43,14 @@ module ActionView # For streaming, instead of rendering a given a template, we return a Body # object that responds to each. This object is initialized with a block # that knows how to render the template. - def render_template(template, layout_name = nil, locals = {}) #:nodoc: + def render_template(view, template, layout_name = nil, locals = {}) #:nodoc: return [super] unless layout_name && template.supports_streaming? locals ||= {} layout = layout_name && find_layout(layout_name, locals.keys, [formats.first]) Body.new do |buffer| - delayed_render(buffer, template, layout, @view, locals) + delayed_render(buffer, template, layout, view, locals) end end diff --git a/actionview/lib/action_view/renderer/template_renderer.rb b/actionview/lib/action_view/renderer/template_renderer.rb index ce8908924a..fb5539e0db 100644 --- a/actionview/lib/action_view/renderer/template_renderer.rb +++ b/actionview/lib/action_view/renderer/template_renderer.rb @@ -5,7 +5,6 @@ require "active_support/core_ext/object/try" module ActionView class TemplateRenderer < AbstractRenderer #:nodoc: def render(context, options) - @view = context @details = extract_details(options) template = determine_template(options) @@ -13,7 +12,7 @@ module ActionView @lookup_context.rendered_format ||= (template.formats.first || formats.first) - render_template(template, options[:layout], options[:locals]) + render_template(context, template, options[:layout], options[:locals]) end private @@ -46,22 +45,21 @@ module ActionView # Renders the given template. A string representing the layout can be # supplied as well. - def render_template(template, layout_name = nil, locals = nil) - view, locals = @view, locals || {} + def render_template(view, template, layout_name = nil, locals = nil) + locals ||= {} - render_with_layout(layout_name, locals) do |layout| + render_with_layout(view, layout_name, locals) do |layout| instrument(:template, identifier: template.identifier, layout: layout.try(:virtual_path)) do template.render(view, locals) { |*name| view._layout_for(*name) } end end end - def render_with_layout(path, locals) + def render_with_layout(view, path, locals) layout = path && find_layout(path, locals.keys, [formats.first]) content = yield(layout) if layout - view = @view view.view_flow.set(:layout, content) layout.render(view, locals) { |*name| view._layout_for(*name) } else diff --git a/actionview/lib/action_view/rendering.rb b/actionview/lib/action_view/rendering.rb index cb4327cf16..205665a8c6 100644 --- a/actionview/lib/action_view/rendering.rb +++ b/actionview/lib/action_view/rendering.rb @@ -55,10 +55,8 @@ module ActionView end end - attr_internal_writer :view_context_class - def view_context_class - @_view_context_class ||= self.class.view_context_class + self.class.view_context_class end # An instance of a view class. The default view class is ActionView::Base. diff --git a/actionview/lib/action_view/template.rb b/actionview/lib/action_view/template.rb index 070d82cf17..8ce8053011 100644 --- a/actionview/lib/action_view/template.rb +++ b/actionview/lib/action_view/template.rb @@ -155,10 +155,10 @@ module ActionView # This method is instrumented as "!render_template.action_view". Notice that # we use a bang in this instrumentation because you don't want to # consume this in production. This is only slow if it's being listened to. - def render(view, locals, buffer = nil, &block) + def render(view, locals, buffer = ActionView::OutputBuffer.new, &block) instrument_render_template do compile!(view) - view.send(method_name, locals, buffer, &block) + view.run(method_name, locals, buffer, &block) end rescue => e handle_render_error(view, e) @@ -264,11 +264,7 @@ module ActionView # re-compilation return if @compiled - if view.is_a?(ActionView::CompiledTemplates) - mod = ActionView::CompiledTemplates - else - mod = view.singleton_class - end + mod = view.compiled_method_container instrument("!compile_template") do compile(mod) @@ -301,9 +297,7 @@ module ActionView # encoding of the code source = +<<-end_src def #{method_name}(local_assigns, output_buffer) - _old_virtual_path, @virtual_path = @virtual_path, #{@virtual_path.inspect};_old_output_buffer = @output_buffer;#{locals_code};#{code} - ensure - @virtual_path, @output_buffer = _old_virtual_path, _old_output_buffer + @virtual_path = #{@virtual_path.inspect};#{locals_code};#{code} end end_src diff --git a/actionview/lib/action_view/template/handlers/erb/erubi.rb b/actionview/lib/action_view/template/handlers/erb/erubi.rb index db75f028ed..e155bae89d 100644 --- a/actionview/lib/action_view/template/handlers/erb/erubi.rb +++ b/actionview/lib/action_view/template/handlers/erb/erubi.rb @@ -13,7 +13,7 @@ module ActionView # Dup properties so that we don't modify argument properties = Hash[properties] - properties[:preamble] = "@output_buffer = output_buffer || ActionView::OutputBuffer.new;" + properties[:preamble] = "" properties[:postamble] = "@output_buffer.to_s" properties[:bufvar] = "@output_buffer" properties[:escapefunc] = "" @@ -22,8 +22,12 @@ module ActionView end def evaluate(action_view_erb_handler_context) - pr = eval("proc { #{@src} }", binding, @filename || "(erubi)") - action_view_erb_handler_context.instance_eval(&pr) + src = @src + view = Class.new(ActionView::Base) { + include action_view_erb_handler_context._routes.url_helpers + class_eval("define_method(:_template) { |local_assigns, output_buffer| #{src} }", @filename || "(erubi)", 0) + }.new(action_view_erb_handler_context) + view.run(:_template, {}, ActionView::OutputBuffer.new) end private |