diff options
author | Aaron Patterson <tenderlove@github.com> | 2019-02-06 18:08:36 -0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-02-06 18:08:36 -0800 |
commit | 973b62dcddd2db45047d32321e6887c841fc5ccf (patch) | |
tree | 791524f548ebe2b18b4cb7c704962a7a55150e6e /actionview/lib | |
parent | d0037daa3738ac754781ce5e55778a2cf9d3d2f7 (diff) | |
parent | 570bcdaa65987ac2f5cc84fdf83678cd5c0bb7d8 (diff) | |
download | rails-973b62dcddd2db45047d32321e6887c841fc5ccf.tar.gz rails-973b62dcddd2db45047d32321e6887c841fc5ccf.tar.bz2 rails-973b62dcddd2db45047d32321e6887c841fc5ccf.zip |
Merge pull request #35036 from rails/av-base-subclass
Move compiled ERB to an AV::Base subclass
Diffstat (limited to 'actionview/lib')
-rw-r--r-- | actionview/lib/action_view.rb | 1 | ||||
-rw-r--r-- | actionview/lib/action_view/base.rb | 26 | ||||
-rw-r--r-- | actionview/lib/action_view/lookup_context.rb | 5 | ||||
-rw-r--r-- | actionview/lib/action_view/railtie.rb | 11 | ||||
-rw-r--r-- | actionview/lib/action_view/rendering.rb | 42 | ||||
-rw-r--r-- | actionview/lib/action_view/template.rb | 22 |
6 files changed, 67 insertions, 40 deletions
diff --git a/actionview/lib/action_view.rb b/actionview/lib/action_view.rb index 6ff2d70e35..8cb4648a67 100644 --- a/actionview/lib/action_view.rb +++ b/actionview/lib/action_view.rb @@ -35,7 +35,6 @@ module ActionView eager_autoload do autoload :Base autoload :Context - autoload :CompiledTemplates, "action_view/context" autoload :Digestor autoload :Helpers autoload :LookupContext diff --git a/actionview/lib/action_view/base.rb b/actionview/lib/action_view/base.rb index b143e13c96..420136d6de 100644 --- a/actionview/lib/action_view/base.rb +++ b/actionview/lib/action_view/base.rb @@ -11,10 +11,6 @@ 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. @@ -146,8 +142,6 @@ 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 } @@ -186,6 +180,20 @@ module ActionView #:nodoc: def xss_safe? #:nodoc: true end + + def with_empty_template_cache # :nodoc: + subclass = Class.new(self) { + # We can't implement these as self.class because subclasses will + # share the same template cache as superclasses, so "changed?" won't work + # correctly. + define_method(:compiled_method_container) { subclass } + define_singleton_method(:compiled_method_container) { subclass } + } + end + + def changed?(other) # :nodoc: + compiled_method_container != other.compiled_method_container + end end attr_reader :view_renderer @@ -260,7 +268,11 @@ module ActionView #:nodoc: end def compiled_method_container - CompiledTemplates + raise NotImplementedError, <<~msg + Subclasses of ActionView::Base must implement `compiled_method_container` + or use the class method `with_empty_template_cache` for constructing + an ActionView::Base subclass that has an empty cache. + msg end ActiveSupport.run_load_hooks(:action_view, self) diff --git a/actionview/lib/action_view/lookup_context.rb b/actionview/lib/action_view/lookup_context.rb index c2f6439e26..c3bb0a49fc 100644 --- a/actionview/lib/action_view/lookup_context.rb +++ b/actionview/lib/action_view/lookup_context.rb @@ -68,12 +68,17 @@ module ActionView end def self.clear + @view_context_class = nil @details_keys.clear end def self.digest_caches @details_keys.values end + + def self.view_context_class(klass) + @view_context_class ||= klass.with_empty_template_cache + end end # Add caching behavior on top of Details. diff --git a/actionview/lib/action_view/railtie.rb b/actionview/lib/action_view/railtie.rb index 12d06bf376..a25e1d3d02 100644 --- a/actionview/lib/action_view/railtie.rb +++ b/actionview/lib/action_view/railtie.rb @@ -6,11 +6,13 @@ require "rails" module ActionView # = Action View Railtie class Railtie < Rails::Engine # :nodoc: + NULL_OPTION = Object.new + config.action_view = ActiveSupport::OrderedOptions.new config.action_view.embed_authenticity_token_in_remote_forms = nil config.action_view.debug_missing_translation = true config.action_view.default_enforce_utf8 = nil - config.action_view.finalize_compiled_template_methods = true + config.action_view.finalize_compiled_template_methods = NULL_OPTION config.eager_load_namespaces << ActionView @@ -48,8 +50,11 @@ module ActionView initializer "action_view.finalize_compiled_template_methods" do |app| ActiveSupport.on_load(:action_view) do - ActionView::Template.finalize_compiled_template_methods = - app.config.action_view.delete(:finalize_compiled_template_methods) + option = app.config.action_view.delete(:finalize_compiled_template_methods) + + if option != NULL_OPTION + ActiveSupport::Deprecation.warn "action_view.finalize_compiled_template_methods is deprecated and has no effect" + end end end diff --git a/actionview/lib/action_view/rendering.rb b/actionview/lib/action_view/rendering.rb index 205665a8c6..cf7d1105e0 100644 --- a/actionview/lib/action_view/rendering.rb +++ b/actionview/lib/action_view/rendering.rb @@ -35,24 +35,36 @@ module ActionView end module ClassMethods - def view_context_class - @view_context_class ||= begin - supports_path = supports_path? - routes = respond_to?(:_routes) && _routes - helpers = respond_to?(:_helpers) && _helpers - - Class.new(ActionView::Base) do - if routes - include routes.url_helpers(supports_path) - include routes.mounted_helpers - end - - if helpers - include helpers - end + def _routes + end + + def _helpers + end + + def build_view_context_class(klass, supports_path, routes, helpers) + Class.new(klass) do + if routes + include routes.url_helpers(supports_path) + include routes.mounted_helpers + end + + if helpers + include helpers end end end + + def view_context_class + klass = ActionView::LookupContext::DetailsKey.view_context_class(ActionView::Base) + + @view_context_class ||= build_view_context_class(klass, supports_path?, _routes, _helpers) + + if klass.changed?(@view_context_class) + @view_context_class = build_view_context_class(klass, supports_path?, _routes, _helpers) + end + + @view_context_class + end end def view_context_class diff --git a/actionview/lib/action_view/template.rb b/actionview/lib/action_view/template.rb index 8a5407c622..37f476e554 100644 --- a/actionview/lib/action_view/template.rb +++ b/actionview/lib/action_view/template.rb @@ -2,6 +2,7 @@ require "active_support/core_ext/object/try" require "active_support/core_ext/kernel/singleton_class" +require "active_support/deprecation" require "thread" require "delegate" @@ -10,7 +11,13 @@ module ActionView class Template extend ActiveSupport::Autoload - mattr_accessor :finalize_compiled_template_methods, default: true + def self.finalize_compiled_template_methods + ActiveSupport::Deprecation.warn "ActionView::Template.finalize_compiled_template_methods is deprecated and has no effect" + end + + def self.finalize_compiled_template_methods=(_) + ActiveSupport::Deprecation.warn "ActionView::Template.finalize_compiled_template_methods= is deprecated and has no effect" + end # === Encodings in ActionView::Template # @@ -118,16 +125,6 @@ module ActionView attr_reader :source, :identifier, :handler, :original_encoding, :updated_at - # This finalizer is needed (and exactly with a proc inside another proc) - # otherwise templates leak in development. - Finalizer = proc do |method_name, mod| # :nodoc: - proc do - mod.module_eval do - remove_possible_method method_name - end - end - end - attr_reader :variable def initialize(source, identifier, handler, details) @@ -337,9 +334,6 @@ module ActionView end mod.module_eval(source, identifier, 0) - if finalize_compiled_template_methods - ObjectSpace.define_finalizer(self, Finalizer[method_name, mod]) - end end def handle_render_error(view, e) |