aboutsummaryrefslogtreecommitdiffstats
path: root/actionview/lib
diff options
context:
space:
mode:
authorAaron Patterson <tenderlove@github.com>2019-02-06 18:08:36 -0800
committerGitHub <noreply@github.com>2019-02-06 18:08:36 -0800
commit973b62dcddd2db45047d32321e6887c841fc5ccf (patch)
tree791524f548ebe2b18b4cb7c704962a7a55150e6e /actionview/lib
parentd0037daa3738ac754781ce5e55778a2cf9d3d2f7 (diff)
parent570bcdaa65987ac2f5cc84fdf83678cd5c0bb7d8 (diff)
downloadrails-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.rb1
-rw-r--r--actionview/lib/action_view/base.rb26
-rw-r--r--actionview/lib/action_view/lookup_context.rb5
-rw-r--r--actionview/lib/action_view/railtie.rb11
-rw-r--r--actionview/lib/action_view/rendering.rb42
-rw-r--r--actionview/lib/action_view/template.rb22
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)