diff --git a/lib/inline_svg.rb b/lib/inline_svg.rb index 45aa49e..4fba526 100644 --- a/lib/inline_svg.rb +++ b/lib/inline_svg.rb @@ -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 = {} @@ -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 @@ -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) @@ -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 diff --git a/lib/inline_svg/railtie.rb b/lib/inline_svg/railtie.rb index 6e55db9..c57c71d 100644 --- a/lib/inline_svg/railtie.rb +++ b/lib/inline_svg/railtie.rb @@ -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 diff --git a/spec/inline_svg_spec.rb b/spec/inline_svg_spec.rb index b4fe73d..408f04f 100644 --- a/spec/inline_svg_spec.rb +++ b/spec/inline_svg_spec.rb @@ -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 @@ -29,7 +33,7 @@ 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 @@ -37,6 +41,16 @@ def self.named(filename); 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'