Refactor ActionView::Template::Types to avoid delegation

The `Type` class was introduced in https://github.com/rails/rails/pull/23085
for the sole purpose of breaking the dependency of Action View on Action Dispatch.

Unless you are somehow running Action View standalone, this is actually
never used.

So instead of delegating, we can use constant swapping, this saves us
a useless layer.

Ultimately we could consider moving `Mime::Types` into Active Support
but it requires some more thoughts.
This commit is contained in:
Jean Boussier 2023-05-08 10:10:27 +09:00
parent 4ea4a98234
commit 06d2c2d15b
6 changed files with 44 additions and 43 deletions

@ -73,6 +73,6 @@ def self.eager_load!
ActiveSupport.on_load(:action_view) do
ActionView::Base.default_formats ||= Mime::SET.symbols
ActionView::Template::Types.delegate_to Mime
ActionView::Template.mime_types_implementation = Mime
ActionView::LookupContext::DetailsKey.clear
end

@ -147,6 +147,6 @@ def eager_load!
ActiveSupport.on_load(:action_view) do
ActionView::Base.default_formats ||= Mime::SET.symbols
ActionView::Template::Types.delegate_to Mime
ActionView::Template.mime_types_implementation = Mime
ActionView::LookupContext::DetailsKey.clear
end

@ -42,6 +42,10 @@ def [](type)
Type.lookup_by_extension(type)
end
def symbols
SET.symbols
end
def fetch(type, &block)
return type if type.is_a?(Type)
EXTENSION_LOOKUP.fetch(type.to_s, &block)

@ -109,6 +109,7 @@ class Template
autoload :Handlers
autoload :HTML
autoload :Inline
autoload :Types
autoload :Sources
autoload :Text
autoload :Types
@ -119,6 +120,17 @@ class Template
singleton_class.attr_accessor :frozen_string_literal
@frozen_string_literal = false
class << self # :nodoc:
def mime_types_implementation=(implementation)
# This method isn't thread-safe, but it's not supposed
# to be called after initialization
if self::Types != implementation
remove_const(:Types)
const_set(:Types, implementation)
end
end
end
attr_reader :identifier, :handler
attr_reader :variable, :format, :variant, :virtual_path

@ -4,53 +4,38 @@
module ActionView
class Template # :nodoc:
module Types
class Type
SET = Struct.new(:symbols).new([ :html, :text, :js, :css, :xml, :json ])
class SimpleType # :nodoc:
SET = Struct.new(:symbols).new([ :html, :text, :js, :css, :xml, :json ])
def self.[](type)
if type.is_a?(self)
type
else
new(type)
end
end
attr_reader :symbol
def initialize(symbol)
@symbol = symbol.to_sym
end
def to_s
@symbol.to_s
end
alias to_str to_s
def ref
@symbol
end
alias to_sym ref
def ==(type)
@symbol == type.to_sym unless type.blank?
def self.[](type)
if type.is_a?(self)
type
else
new(type)
end
end
class << self
attr_reader :symbols
attr_reader :symbol
def delegate_to(klass)
@symbols = klass::SET.symbols
@type_klass = klass
end
def [](type)
@type_klass[type]
end
def initialize(symbol)
@symbol = symbol.to_sym
end
delegate_to Type
def to_s
@symbol.to_s
end
alias to_str to_s
def ref
@symbol
end
alias to_sym ref
def ==(type)
@symbol == type.to_sym unless type.blank?
end
end
Types = SimpleType # :nodoc:
end
end

@ -4,7 +4,7 @@
require "active_support/ordered_options"
require "action_dispatch"
ActionView::Template::Types.delegate_to Mime
ActionView::Template.mime_types_implementation = Mime
module AssetTagHelperTestHelpers
def with_preload_links_header(new_preload_links_header = true)