Skip to content

Commit

Permalink
Set asset finder from callable
Browse files Browse the repository at this point in the history
It fixes jamesmartin#151 by allowing the asset finder to be a callable object. This is
useful when the asset pipeline is not ready when the initializer is run, for
example, when using Propshaft.

I don't know if this is the best way to solve this problem. On the one hand,
Propshaft could be done when its initializer is run, but on the other hand,
this gem's railtie assumes the asset pipeline is ready.
  • Loading branch information
xymbol committed Oct 24, 2023
1 parent 8c9e8d9 commit 7d1fc8c
Show file tree
Hide file tree
Showing 3 changed files with 35 additions and 12 deletions.
17 changes: 14 additions & 3 deletions lib/inline_svg.rb
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ module InlineSvg
class Configuration
class Invalid < ArgumentError; end

attr_reader :asset_file, :asset_finder, :custom_transformations, :svg_not_found_css_class
attr_reader :asset_file, :custom_transformations, :svg_not_found_css_class

def initialize
@custom_transformations = {}
Expand All @@ -41,8 +41,15 @@ def asset_file=(custom_asset_file)
end
end

def asset_finder
set_asset_finder_from_callable
@asset_finder
end

def asset_finder=(finder)
@asset_finder = if finder.respond_to?(:find_asset)
@asset_finder = if finder.respond_to?(:call)
finder
elsif finder.respond_to?(:find_asset)
finder
elsif finder.class.name == "Propshaft::Assembly"
InlineSvg::PropshaftAssetFinder
Expand All @@ -52,7 +59,6 @@ def asset_finder=(finder)
# See: https://github.com/jamesmartin/inline_svg/issues/25
InlineSvg::StaticAssetFinder
end
asset_finder
end

def svg_not_found_css_class=(css_class)
Expand Down Expand Up @@ -82,6 +88,11 @@ def incompatible_transformation?(klass)
!klass.is_a?(Class) || !klass.respond_to?(:create_with_value) || !klass.instance_methods.include?(:transform)
end

def set_asset_finder_from_callable
while @asset_finder&.respond_to?(:call)
self.asset_finder = @asset_finder.call
end
end
end

@configuration = InlineSvg::Configuration.new
Expand Down
14 changes: 6 additions & 8 deletions lib/inline_svg/railtie.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,12 @@ class Railtie < ::Rails::Railtie

config.after_initialize do |app|
InlineSvg.configure do |config|
# Configure the asset_finder:
# Only set this when a user-configured asset finder has not been
# configured already.
if config.asset_finder.nil?
# In default Rails apps, this will be a fully operational
# Sprockets::Environment instance
config.asset_finder = app.instance_variable_get(:@assets)
end
# Configure an asset finder for Rails. This will be evaluated when the
# first SVG is rendered, giving time to the asset pipeline to be done
# loading.
config.asset_finder = proc {
app.instance_variable_get(:@assets)
}
end
end
end
Expand Down
16 changes: 15 additions & 1 deletion spec/inline_svg_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,10 @@ def self.named(filename); end

describe InlineSvg do
describe "configuration" do
before do
InlineSvg.reset_configuration!
end

context "when a block is not given" do
it "complains" do
expect do
Expand All @@ -29,14 +33,24 @@ def self.named(filename); end

context "asset finder" do
it "allows an asset finder to be assigned" do
sprockets = double('SomethingLikeSprockets', find_asset: 'some asset')
sprockets = double("Something like sprockets", find_asset: "some asset")
InlineSvg.configure do |config|
config.asset_finder = sprockets
end

expect(InlineSvg.configuration.asset_finder).to eq sprockets
end

it "allows to give a callable object that returns an asset finder" do
propshaft = double("Something like propshaft", class: double(name: "Propshaft::Assembly"))
callable = -> { propshaft }
InlineSvg.configure do |config|
config.asset_finder = callable
end

expect(InlineSvg.configuration.asset_finder).to eq InlineSvg::PropshaftAssetFinder
end

it "falls back to StaticAssetFinder when the provided asset finder does not implement #find_asset" do
InlineSvg.configure do |config|
config.asset_finder = 'Not a real asset finder'
Expand Down

0 comments on commit 7d1fc8c

Please sign in to comment.