lib/action_view/component/base.rb in actionview-component-1.6.0 vs lib/action_view/component/base.rb in actionview-component-1.6.1
- old
+ new
@@ -1,18 +1,15 @@
# frozen_string_literal: true
-require "active_model"
-require "action_view"
require "active_support/configurable"
-require_relative "preview"
module ActionView
module Component
class Base < ActionView::Base
include ActiveModel::Validations
include ActiveSupport::Configurable
- include ActionView::Component::Previews
+ include ActionView::Component::Previewable
delegate :form_authenticity_token, :protect_against_forgery?, to: :helpers
# Entrypoint for rendering components. Called by ActionView::Base#render.
#
@@ -111,28 +108,42 @@
else
"call"
end
end
+ def has_initializer?
+ self.instance_method(:initialize).owner == self
+ end
+
def source_location
# Require #initialize to be defined so that we can use
# method#source_location to look up the file name
# of the component.
#
# If we were able to only support Ruby 2.7+,
# We could just use Module#const_source_location,
# rendering this unnecessary.
- raise NotImplementedError.new("#{self} must implement #initialize.") unless self.instance_method(:initialize).owner == self
+ raise NotImplementedError.new("#{self} must implement #initialize.") unless has_initializer?
instance_method(:initialize).source_location[0]
end
+ def eager_load!
+ self.descendants.each do |descendant|
+ descendant.compile if descendant.has_initializer?
+ end
+ end
+
+ def compiled?
+ @compiled && ActionView::Base.cache_template_loading
+ end
+
# Compile templates to instance methods, assuming they haven't been compiled already.
# We could in theory do this on app boot, at least in production environments.
# Right now this just compiles the first time the component is rendered.
def compile
- return if @compiled && ActionView::Base.cache_template_loading
+ return if compiled?
validate_templates
templates.each do |template|
class_eval <<-RUBY, __FILE__, __LINE__ + 1
@@ -159,16 +170,22 @@
source_location
end
private
+ def matching_views_in_source_location
+ (Dir["#{source_location.sub(/#{File.extname(source_location)}$/, '')}.*{#{ActionView::Template.template_handler_extensions.join(',')}}"] - [source_location])
+ end
+
def templates
@templates ||=
- (Dir["#{source_location.sub(/#{File.extname(source_location)}$/, '')}.*{#{ActionView::Template.template_handler_extensions.join(',')}}"] - [source_location]).each_with_object([]) do |path, memo|
+ matching_views_in_source_location.each_with_object([]) do |path, memo|
+ pieces = File.basename(path).split(".")
+
memo << {
path: path,
- variant: path.split(".").second.split("+")[1]&.to_sym,
- handler: path.split(".").last
+ variant: pieces.second.split("+")[1]&.to_sym,
+ handler: pieces.last
}
end
end
def validate_templates