inline_svg 1.0.0 → 1.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +5 -5
- data/.github/workflows/integration_test.yml +47 -0
- data/.github/workflows/rails_6_webpacker_integration_tests.yaml +62 -0
- data/.github/workflows/ruby.yml +20 -0
- data/.rubocop.yml +1 -0
- data/.rubocop_todo.yml +421 -0
- data/CHANGELOG.md +143 -3
- data/README.md +149 -30
- data/Rakefile +7 -0
- data/inline_svg.gemspec +2 -1
- data/lib/inline_svg/action_view/helpers.rb +68 -7
- data/lib/inline_svg/cached_asset_file.rb +71 -0
- data/lib/inline_svg/finds_asset_paths.rb +1 -1
- data/lib/inline_svg/id_generator.rb +12 -3
- data/lib/inline_svg/io_resource.rb +4 -3
- data/lib/inline_svg/propshaft_asset_finder.rb +16 -0
- data/lib/inline_svg/railtie.rb +8 -3
- data/lib/inline_svg/static_asset_finder.rb +5 -2
- data/lib/inline_svg/transform_pipeline/transformations/aria_attributes.rb +16 -19
- data/lib/inline_svg/transform_pipeline/transformations/aria_hidden.rb +9 -0
- data/lib/inline_svg/transform_pipeline/transformations/aria_hidden_attribute.rb +9 -0
- data/lib/inline_svg/transform_pipeline/transformations/class_attribute.rb +5 -6
- data/lib/inline_svg/transform_pipeline/transformations/data_attributes.rb +4 -5
- data/lib/inline_svg/transform_pipeline/transformations/description.rb +7 -6
- data/lib/inline_svg/transform_pipeline/transformations/height.rb +3 -4
- data/lib/inline_svg/transform_pipeline/transformations/id_attribute.rb +3 -4
- data/lib/inline_svg/transform_pipeline/transformations/no_comment.rb +4 -4
- data/lib/inline_svg/transform_pipeline/transformations/preserve_aspect_ratio.rb +3 -4
- data/lib/inline_svg/transform_pipeline/transformations/size.rb +4 -5
- data/lib/inline_svg/transform_pipeline/transformations/style_attribute.rb +11 -0
- data/lib/inline_svg/transform_pipeline/transformations/title.rb +7 -6
- data/lib/inline_svg/transform_pipeline/transformations/transformation.rb +13 -0
- data/lib/inline_svg/transform_pipeline/transformations/view_box.rb +9 -0
- data/lib/inline_svg/transform_pipeline/transformations/width.rb +3 -4
- data/lib/inline_svg/transform_pipeline/transformations.rb +11 -2
- data/lib/inline_svg/transform_pipeline.rb +1 -1
- data/lib/inline_svg/version.rb +1 -1
- data/lib/inline_svg/webpack_asset_finder.rb +60 -0
- data/lib/inline_svg.rb +46 -9
- data/spec/cached_asset_file_spec.rb +73 -0
- data/spec/files/static_assets/assets0/known-document-two.svg +1 -0
- data/spec/files/static_assets/assets0/known-document.svg +1 -0
- data/spec/files/static_assets/assets0/some-document.svg +1 -0
- data/spec/files/static_assets/assets1/known-document.svg +1 -0
- data/spec/files/static_assets/assets1/other-document.svg +3 -0
- data/spec/files/static_assets/assets1/some-file.txt +1 -0
- data/spec/finds_asset_paths_spec.rb +45 -0
- data/spec/helpers/inline_svg_spec.rb +117 -51
- data/spec/id_generator_spec.rb +5 -3
- data/spec/inline_svg_spec.rb +48 -0
- data/spec/propshaft_asset_finder_spec.rb +23 -0
- data/spec/static_asset_finder_spec.rb +25 -0
- data/spec/transformation_pipeline/transformations/aria_attributes_spec.rb +6 -6
- data/spec/transformation_pipeline/transformations/aria_hidden_attribute_spec.rb +12 -0
- data/spec/transformation_pipeline/transformations/height_spec.rb +9 -0
- data/spec/transformation_pipeline/transformations/style_attribute_spec.rb +26 -0
- data/spec/transformation_pipeline/transformations/title_spec.rb +9 -0
- data/spec/transformation_pipeline/transformations/transformation_spec.rb +39 -0
- data/spec/transformation_pipeline/transformations/view_box_spec.rb +13 -0
- data/spec/transformation_pipeline/transformations_spec.rb +7 -1
- data/spec/webpack_asset_finder_spec.rb +23 -0
- metadata +62 -10
- data/circle.yml +0 -3
@@ -1,16 +1,17 @@
|
|
1
1
|
module InlineSvg
|
2
2
|
module IOResource
|
3
|
-
def self.===
|
3
|
+
def self.===(object)
|
4
4
|
object.is_a?(IO) || object.is_a?(StringIO)
|
5
5
|
end
|
6
6
|
|
7
|
-
def self.default_for
|
7
|
+
def self.default_for(object)
|
8
8
|
case object
|
9
9
|
when StringIO then ''
|
10
10
|
when IO then 1
|
11
11
|
end
|
12
12
|
end
|
13
|
-
|
13
|
+
|
14
|
+
def self.read(object)
|
14
15
|
start = object.pos
|
15
16
|
str = object.read
|
16
17
|
object.seek start
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module InlineSvg
|
2
|
+
class PropshaftAssetFinder
|
3
|
+
def self.find_asset(filename)
|
4
|
+
new(filename)
|
5
|
+
end
|
6
|
+
|
7
|
+
def initialize(filename)
|
8
|
+
@filename = filename
|
9
|
+
end
|
10
|
+
|
11
|
+
def pathname
|
12
|
+
asset_path = ::Rails.application.assets.load_path.find(@filename)
|
13
|
+
asset_path.path unless asset_path.nil?
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
data/lib/inline_svg/railtie.rb
CHANGED
@@ -10,9 +10,14 @@ module InlineSvg
|
|
10
10
|
|
11
11
|
config.after_initialize do |app|
|
12
12
|
InlineSvg.configure do |config|
|
13
|
-
#
|
14
|
-
#
|
15
|
-
|
13
|
+
# Configure the asset_finder:
|
14
|
+
# Only set this when a user-configured asset finder has not been
|
15
|
+
# configured already.
|
16
|
+
if config.asset_finder.nil?
|
17
|
+
# In default Rails apps, this will be a fully operational
|
18
|
+
# Sprockets::Environment instance
|
19
|
+
config.asset_finder = app.instance_variable_get(:@assets)
|
20
|
+
end
|
16
21
|
end
|
17
22
|
end
|
18
23
|
end
|
@@ -1,7 +1,9 @@
|
|
1
|
+
require "pathname"
|
2
|
+
|
1
3
|
# Naive fallback asset finder for when sprockets >= 3.0 &&
|
2
4
|
# config.assets.precompile = false
|
3
5
|
# Thanks to @ryanswood for the original code:
|
4
|
-
# https://github.com/
|
6
|
+
# https://github.com/jamesmartin/inline_svg/commit/661bbb3bef7d1b4bd6ccd63f5f018305797b9509
|
5
7
|
module InlineSvg
|
6
8
|
class StaticAssetFinder
|
7
9
|
def self.find_asset(filename)
|
@@ -14,7 +16,8 @@ module InlineSvg
|
|
14
16
|
|
15
17
|
def pathname
|
16
18
|
if ::Rails.application.config.assets.compile
|
17
|
-
::Rails.application.assets[@filename]
|
19
|
+
asset = ::Rails.application.assets[@filename]
|
20
|
+
Pathname.new(asset.filename) if asset.present?
|
18
21
|
else
|
19
22
|
manifest = ::Rails.application.assets_manifest
|
20
23
|
asset_path = manifest.assets[@filename]
|
@@ -1,34 +1,31 @@
|
|
1
1
|
module InlineSvg::TransformPipeline::Transformations
|
2
2
|
class AriaAttributes < Transformation
|
3
3
|
def transform(doc)
|
4
|
-
doc
|
5
|
-
|
4
|
+
with_svg(doc) do |svg|
|
5
|
+
# Add role
|
6
|
+
svg["role"] = "img"
|
6
7
|
|
7
|
-
|
8
|
-
|
8
|
+
# Build aria-labelledby string
|
9
|
+
aria_elements = []
|
10
|
+
svg.search("title").each do |element|
|
11
|
+
aria_elements << element["id"] = element_id_for("title", element)
|
12
|
+
end
|
9
13
|
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
aria_elements << element['id'] = element_id_for("title", element)
|
14
|
-
end
|
15
|
-
|
16
|
-
doc.search("svg desc").each do |element|
|
17
|
-
aria_elements << element['id'] = element_id_for("desc", element)
|
18
|
-
end
|
14
|
+
svg.search("desc").each do |element|
|
15
|
+
aria_elements << element["id"] = element_id_for("desc", element)
|
16
|
+
end
|
19
17
|
|
20
|
-
|
21
|
-
|
18
|
+
if aria_elements.any?
|
19
|
+
svg["aria-labelledby"] = aria_elements.join(" ")
|
20
|
+
end
|
22
21
|
end
|
23
|
-
|
24
|
-
doc
|
25
22
|
end
|
26
23
|
|
27
24
|
def element_id_for(base, element)
|
28
|
-
if element[
|
25
|
+
if element["id"].nil?
|
29
26
|
InlineSvg::IdGenerator.generate(base, element.text)
|
30
27
|
else
|
31
|
-
InlineSvg::IdGenerator.generate(element[
|
28
|
+
InlineSvg::IdGenerator.generate(element["id"], element.text)
|
32
29
|
end
|
33
30
|
end
|
34
31
|
end
|
@@ -1,12 +1,11 @@
|
|
1
1
|
module InlineSvg::TransformPipeline::Transformations
|
2
2
|
class ClassAttribute < Transformation
|
3
3
|
def transform(doc)
|
4
|
-
doc
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
doc
|
4
|
+
with_svg(doc) do |svg|
|
5
|
+
classes = (svg["class"] || "").split(" ")
|
6
|
+
classes << value
|
7
|
+
svg["class"] = classes.join(" ")
|
8
|
+
end
|
10
9
|
end
|
11
10
|
end
|
12
11
|
end
|
@@ -1,12 +1,11 @@
|
|
1
1
|
module InlineSvg::TransformPipeline::Transformations
|
2
2
|
class DataAttributes < Transformation
|
3
3
|
def transform(doc)
|
4
|
-
doc
|
5
|
-
|
6
|
-
|
7
|
-
|
4
|
+
with_svg(doc) do |svg|
|
5
|
+
with_valid_hash_from(self.value).each_pair do |name, data|
|
6
|
+
svg["data-#{dasherize(name)}"] = data
|
7
|
+
end
|
8
8
|
end
|
9
|
-
doc
|
10
9
|
end
|
11
10
|
|
12
11
|
private
|
@@ -1,12 +1,13 @@
|
|
1
1
|
module InlineSvg::TransformPipeline::Transformations
|
2
2
|
class Description < Transformation
|
3
3
|
def transform(doc)
|
4
|
-
doc
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
4
|
+
with_svg(doc) do |svg|
|
5
|
+
node = Nokogiri::XML::Node.new("desc", doc)
|
6
|
+
node.content = value
|
7
|
+
|
8
|
+
svg.search("desc").each { |node| node.remove }
|
9
|
+
svg.prepend_child(node)
|
10
|
+
end
|
10
11
|
end
|
11
12
|
end
|
12
13
|
end
|
@@ -1,10 +1,9 @@
|
|
1
1
|
module InlineSvg::TransformPipeline::Transformations
|
2
2
|
class Height < Transformation
|
3
3
|
def transform(doc)
|
4
|
-
doc
|
5
|
-
|
6
|
-
|
7
|
-
doc
|
4
|
+
with_svg(doc) do |svg|
|
5
|
+
svg["height"] = self.value
|
6
|
+
end
|
8
7
|
end
|
9
8
|
end
|
10
9
|
end
|
@@ -1,10 +1,9 @@
|
|
1
1
|
module InlineSvg::TransformPipeline::Transformations
|
2
2
|
class IdAttribute < Transformation
|
3
3
|
def transform(doc)
|
4
|
-
doc
|
5
|
-
|
6
|
-
|
7
|
-
doc
|
4
|
+
with_svg(doc) do |svg|
|
5
|
+
svg["id"] = self.value
|
6
|
+
end
|
8
7
|
end
|
9
8
|
end
|
10
9
|
end
|
@@ -2,11 +2,11 @@ module InlineSvg::TransformPipeline
|
|
2
2
|
module Transformations
|
3
3
|
class NoComment < Transformation
|
4
4
|
def transform(doc)
|
5
|
-
doc
|
6
|
-
|
7
|
-
|
5
|
+
with_svg(doc) do |svg|
|
6
|
+
svg.xpath("//comment()").each do |comment|
|
7
|
+
comment.remove
|
8
|
+
end
|
8
9
|
end
|
9
|
-
doc
|
10
10
|
end
|
11
11
|
end
|
12
12
|
end
|
@@ -1,10 +1,9 @@
|
|
1
1
|
module InlineSvg::TransformPipeline::Transformations
|
2
2
|
class PreserveAspectRatio < Transformation
|
3
3
|
def transform(doc)
|
4
|
-
doc
|
5
|
-
|
6
|
-
|
7
|
-
doc
|
4
|
+
with_svg(doc) do |svg|
|
5
|
+
svg["preserveAspectRatio"] = self.value
|
6
|
+
end
|
8
7
|
end
|
9
8
|
end
|
10
9
|
end
|
@@ -1,11 +1,10 @@
|
|
1
1
|
module InlineSvg::TransformPipeline::Transformations
|
2
2
|
class Size < Transformation
|
3
3
|
def transform(doc)
|
4
|
-
doc
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
doc
|
4
|
+
with_svg(doc) do |svg|
|
5
|
+
svg["width"] = width_of(self.value)
|
6
|
+
svg["height"] = height_of(self.value)
|
7
|
+
end
|
9
8
|
end
|
10
9
|
|
11
10
|
def width_of(value)
|
@@ -1,12 +1,13 @@
|
|
1
1
|
module InlineSvg::TransformPipeline::Transformations
|
2
2
|
class Title < Transformation
|
3
3
|
def transform(doc)
|
4
|
-
doc
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
4
|
+
with_svg(doc) do |svg|
|
5
|
+
node = Nokogiri::XML::Node.new("title", doc)
|
6
|
+
node.content = value
|
7
|
+
|
8
|
+
svg.search("title").each { |node| node.remove }
|
9
|
+
svg.prepend_child(node)
|
10
|
+
end
|
10
11
|
end
|
11
12
|
end
|
12
13
|
end
|
@@ -13,6 +13,19 @@ module InlineSvg::TransformPipeline::Transformations
|
|
13
13
|
def transform(*)
|
14
14
|
raise "#transform should be implemented by subclasses of Transformation"
|
15
15
|
end
|
16
|
+
|
17
|
+
# Parses a document and yields the contained SVG nodeset to the given block
|
18
|
+
# if it exists.
|
19
|
+
#
|
20
|
+
# Returns a Nokogiri::XML::Document.
|
21
|
+
def with_svg(doc)
|
22
|
+
doc = Nokogiri::XML::Document.parse(
|
23
|
+
doc.to_html(encoding: "UTF-8"), nil, "UTF-8"
|
24
|
+
)
|
25
|
+
svg = doc.at_css "svg"
|
26
|
+
yield svg if svg && block_given?
|
27
|
+
doc
|
28
|
+
end
|
16
29
|
end
|
17
30
|
|
18
31
|
class NullTransformation < Transformation
|
@@ -1,10 +1,9 @@
|
|
1
1
|
module InlineSvg::TransformPipeline::Transformations
|
2
2
|
class Width < Transformation
|
3
3
|
def transform(doc)
|
4
|
-
doc
|
5
|
-
|
6
|
-
|
7
|
-
doc
|
4
|
+
with_svg(doc) do |svg|
|
5
|
+
svg["width"] = self.value
|
6
|
+
end
|
8
7
|
end
|
9
8
|
end
|
10
9
|
end
|
@@ -6,13 +6,16 @@ module InlineSvg::TransformPipeline::Transformations
|
|
6
6
|
desc: { transform: Description, priority: 2 },
|
7
7
|
title: { transform: Title, priority: 3 },
|
8
8
|
aria: { transform: AriaAttributes },
|
9
|
+
aria_hidden: { transform: AriaHiddenAttribute },
|
9
10
|
class: { transform: ClassAttribute },
|
11
|
+
style: { transform: StyleAttribute },
|
10
12
|
data: { transform: DataAttributes },
|
11
|
-
height: { transform: Height },
|
12
13
|
nocomment: { transform: NoComment },
|
13
14
|
preserve_aspect_ratio: { transform: PreserveAspectRatio },
|
14
15
|
size: { transform: Size },
|
15
16
|
width: { transform: Width },
|
17
|
+
height: { transform: Height },
|
18
|
+
view_box: { transform: ViewBox },
|
16
19
|
}
|
17
20
|
end
|
18
21
|
|
@@ -38,8 +41,11 @@ module InlineSvg::TransformPipeline::Transformations
|
|
38
41
|
end
|
39
42
|
|
40
43
|
def self.lookup(transform_params)
|
44
|
+
return [] unless transform_params.any? || custom_transformations.any?
|
45
|
+
|
46
|
+
transform_params_with_defaults = params_with_defaults(transform_params)
|
41
47
|
all_transformations.map { |name, definition|
|
42
|
-
value =
|
48
|
+
value = transform_params_with_defaults[name]
|
43
49
|
definition.fetch(:transform, no_transform).create_with_value(value) if value
|
44
50
|
}.compact
|
45
51
|
end
|
@@ -72,12 +78,15 @@ end
|
|
72
78
|
require 'inline_svg/transform_pipeline/transformations/transformation'
|
73
79
|
require 'inline_svg/transform_pipeline/transformations/no_comment'
|
74
80
|
require 'inline_svg/transform_pipeline/transformations/class_attribute'
|
81
|
+
require 'inline_svg/transform_pipeline/transformations/style_attribute'
|
75
82
|
require 'inline_svg/transform_pipeline/transformations/title'
|
76
83
|
require 'inline_svg/transform_pipeline/transformations/description'
|
77
84
|
require 'inline_svg/transform_pipeline/transformations/size'
|
78
85
|
require 'inline_svg/transform_pipeline/transformations/height'
|
79
86
|
require 'inline_svg/transform_pipeline/transformations/width'
|
87
|
+
require 'inline_svg/transform_pipeline/transformations/view_box'
|
80
88
|
require 'inline_svg/transform_pipeline/transformations/id_attribute'
|
81
89
|
require 'inline_svg/transform_pipeline/transformations/data_attributes'
|
82
90
|
require 'inline_svg/transform_pipeline/transformations/preserve_aspect_ratio'
|
83
91
|
require 'inline_svg/transform_pipeline/transformations/aria_attributes'
|
92
|
+
require "inline_svg/transform_pipeline/transformations/aria_hidden_attribute"
|
data/lib/inline_svg/version.rb
CHANGED
@@ -0,0 +1,60 @@
|
|
1
|
+
module InlineSvg
|
2
|
+
class WebpackAssetFinder
|
3
|
+
def self.find_asset(filename)
|
4
|
+
new(filename)
|
5
|
+
end
|
6
|
+
|
7
|
+
def initialize(filename)
|
8
|
+
@filename = filename
|
9
|
+
manifest_lookup = asset_helper.manifest.lookup(@filename)
|
10
|
+
@asset_path = manifest_lookup.present? ? URI(manifest_lookup).path : ""
|
11
|
+
end
|
12
|
+
|
13
|
+
def pathname
|
14
|
+
return if @asset_path.blank?
|
15
|
+
|
16
|
+
if asset_helper.dev_server.running?
|
17
|
+
dev_server_asset(@asset_path)
|
18
|
+
elsif asset_helper.config.public_path.present?
|
19
|
+
File.join(asset_helper.config.public_path, @asset_path)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
private
|
24
|
+
|
25
|
+
def asset_helper
|
26
|
+
@asset_helper ||=
|
27
|
+
if defined?(::Shakapacker)
|
28
|
+
::Shakapacker
|
29
|
+
else
|
30
|
+
::Webpacker
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def dev_server_asset(file_path)
|
35
|
+
asset = fetch_from_dev_server(file_path)
|
36
|
+
|
37
|
+
begin
|
38
|
+
Tempfile.new(file_path).tap do |file|
|
39
|
+
file.binmode
|
40
|
+
file.write(asset)
|
41
|
+
file.rewind
|
42
|
+
end
|
43
|
+
rescue StandardError => e
|
44
|
+
Rails.logger.error "[inline_svg] Error creating tempfile for #{@filename}: #{e}"
|
45
|
+
raise
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def fetch_from_dev_server(file_path)
|
50
|
+
http = Net::HTTP.new(asset_helper.dev_server.host, asset_helper.dev_server.port)
|
51
|
+
http.use_ssl = asset_helper.dev_server.protocol == "https"
|
52
|
+
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
|
53
|
+
|
54
|
+
http.request(Net::HTTP::Get.new(file_path)).body
|
55
|
+
rescue StandardError => e
|
56
|
+
Rails.logger.error "[inline_svg] Error fetching #{@filename} from webpack-dev-server: #{e}"
|
57
|
+
raise
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
data/lib/inline_svg.rb
CHANGED
@@ -1,12 +1,17 @@
|
|
1
1
|
require "inline_svg/version"
|
2
2
|
require "inline_svg/action_view/helpers"
|
3
3
|
require "inline_svg/asset_file"
|
4
|
+
require "inline_svg/cached_asset_file"
|
4
5
|
require "inline_svg/finds_asset_paths"
|
6
|
+
require "inline_svg/propshaft_asset_finder"
|
5
7
|
require "inline_svg/static_asset_finder"
|
8
|
+
require "inline_svg/webpack_asset_finder"
|
6
9
|
require "inline_svg/transform_pipeline"
|
7
10
|
require "inline_svg/io_resource"
|
8
11
|
|
9
12
|
require "inline_svg/railtie" if defined?(Rails)
|
13
|
+
require 'active_support'
|
14
|
+
require 'active_support/core_ext/object/blank'
|
10
15
|
require 'active_support/core_ext/string'
|
11
16
|
require 'nokogiri'
|
12
17
|
|
@@ -14,24 +19,48 @@ module InlineSvg
|
|
14
19
|
class Configuration
|
15
20
|
class Invalid < ArgumentError; end
|
16
21
|
|
17
|
-
attr_reader :asset_finder, :custom_transformations
|
22
|
+
attr_reader :asset_file, :asset_finder, :custom_transformations, :svg_not_found_css_class
|
18
23
|
|
19
24
|
def initialize
|
20
25
|
@custom_transformations = {}
|
26
|
+
@asset_file = InlineSvg::AssetFile
|
27
|
+
@svg_not_found_css_class = nil
|
28
|
+
@raise_on_file_not_found = false
|
21
29
|
end
|
22
30
|
|
23
|
-
def
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
+
def asset_file=(custom_asset_file)
|
32
|
+
begin
|
33
|
+
method = custom_asset_file.method(:named)
|
34
|
+
if method.arity == 1
|
35
|
+
@asset_file = custom_asset_file
|
36
|
+
else
|
37
|
+
raise InlineSvg::Configuration::Invalid.new("asset_file should implement the #named method with arity 1")
|
38
|
+
end
|
39
|
+
rescue NameError
|
40
|
+
raise InlineSvg::Configuration::Invalid.new("asset_file should implement the #named method")
|
31
41
|
end
|
42
|
+
end
|
43
|
+
|
44
|
+
def asset_finder=(finder)
|
45
|
+
@asset_finder = if finder.respond_to?(:find_asset)
|
46
|
+
finder
|
47
|
+
elsif finder.class.name == "Propshaft::Assembly"
|
48
|
+
InlineSvg::PropshaftAssetFinder
|
49
|
+
else
|
50
|
+
# fallback to a naive static asset finder
|
51
|
+
# (sprokects >= 3.0 && config.assets.precompile = false
|
52
|
+
# See: https://github.com/jamesmartin/inline_svg/issues/25
|
53
|
+
InlineSvg::StaticAssetFinder
|
54
|
+
end
|
32
55
|
asset_finder
|
33
56
|
end
|
34
57
|
|
58
|
+
def svg_not_found_css_class=(css_class)
|
59
|
+
if css_class.present? && css_class.is_a?(String)
|
60
|
+
@svg_not_found_css_class = css_class
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
35
64
|
def add_custom_transformation(options)
|
36
65
|
if incompatible_transformation?(options.fetch(:transform))
|
37
66
|
raise InlineSvg::Configuration::Invalid.new("#{options.fetch(:transform)} should implement the .create_with_value and #transform methods")
|
@@ -39,6 +68,14 @@ module InlineSvg
|
|
39
68
|
@custom_transformations.merge!(Hash[ *[options.fetch(:attribute, :no_attribute), options] ])
|
40
69
|
end
|
41
70
|
|
71
|
+
def raise_on_file_not_found=(value)
|
72
|
+
@raise_on_file_not_found = value
|
73
|
+
end
|
74
|
+
|
75
|
+
def raise_on_file_not_found?
|
76
|
+
!!@raise_on_file_not_found
|
77
|
+
end
|
78
|
+
|
42
79
|
private
|
43
80
|
|
44
81
|
def incompatible_transformation?(klass)
|
@@ -0,0 +1,73 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
require 'pathname'
|
3
|
+
require_relative '../lib/inline_svg'
|
4
|
+
|
5
|
+
describe InlineSvg::CachedAssetFile do
|
6
|
+
let(:fixture_path) { Pathname.new(File.expand_path("../files/static_assets", __FILE__)) }
|
7
|
+
|
8
|
+
it "loads assets under configured paths" do
|
9
|
+
known_document = File.read(fixture_path.join("assets0", "known-document.svg"))
|
10
|
+
|
11
|
+
asset_loader = InlineSvg::CachedAssetFile.new(paths: fixture_path.join("assets0"))
|
12
|
+
|
13
|
+
expect(asset_loader.named("known-document.svg")).to eq(known_document)
|
14
|
+
end
|
15
|
+
|
16
|
+
it "does not include assets outside of configured paths" do
|
17
|
+
asset_loader = InlineSvg::CachedAssetFile.new(paths: fixture_path.join("assets0"))
|
18
|
+
|
19
|
+
expect(fixture_path.join("assets1", "other-document.svg")).to be_file
|
20
|
+
expect do
|
21
|
+
asset_loader.named("other-document.svg")
|
22
|
+
end.to raise_error InlineSvg::AssetFile::FileNotFound
|
23
|
+
end
|
24
|
+
|
25
|
+
it "differentiates two files with the same name" do
|
26
|
+
known_document_0 = File.read(fixture_path.join("assets0", "known-document.svg"))
|
27
|
+
known_document_1 = File.read(fixture_path.join("assets1", "known-document.svg"))
|
28
|
+
|
29
|
+
expect(known_document_0).not_to eq(known_document_1)
|
30
|
+
|
31
|
+
asset_loader = InlineSvg::CachedAssetFile.new(paths: fixture_path)
|
32
|
+
|
33
|
+
expect(known_document_0).to eq(asset_loader.named("assets0/known-document.svg"))
|
34
|
+
expect(known_document_1).to eq(asset_loader.named("assets1/known-document.svg"))
|
35
|
+
end
|
36
|
+
|
37
|
+
it "chooses the closest exact matching file when similar files exist in the same path" do
|
38
|
+
known_document = File.read(fixture_path.join("assets0", "known-document.svg"))
|
39
|
+
known_document_2 = File.read(fixture_path.join("assets0", "known-document-two.svg"))
|
40
|
+
|
41
|
+
expect(known_document).not_to eq(known_document_2)
|
42
|
+
|
43
|
+
asset_loader = InlineSvg::CachedAssetFile.new(paths: fixture_path.join("assets0"), filters: /\.svg/)
|
44
|
+
|
45
|
+
expect(asset_loader.named("known-document")).to eq(known_document)
|
46
|
+
expect(asset_loader.named("known-document-two")).to eq(known_document_2)
|
47
|
+
end
|
48
|
+
|
49
|
+
it "filters wanted files by simple string matching" do
|
50
|
+
known_document_0 = File.read(fixture_path.join("assets0", "known-document.svg"))
|
51
|
+
known_document_1 = File.read(fixture_path.join("assets1", "known-document.svg"))
|
52
|
+
|
53
|
+
asset_loader = InlineSvg::CachedAssetFile.new(paths: fixture_path, filters: "assets1")
|
54
|
+
|
55
|
+
expect do
|
56
|
+
asset_loader.named("assets0/known-document.svg")
|
57
|
+
end.to raise_error InlineSvg::AssetFile::FileNotFound
|
58
|
+
|
59
|
+
expect(known_document_1).to eq(asset_loader.named("assets1/known-document.svg"))
|
60
|
+
end
|
61
|
+
|
62
|
+
it "filters wanted files by regex matching" do
|
63
|
+
known_document_1 = File.read(fixture_path.join("assets1", "known-document.svg"))
|
64
|
+
|
65
|
+
asset_loader = InlineSvg::CachedAssetFile.new(paths: fixture_path, filters: ["assets1", /\.svg/])
|
66
|
+
|
67
|
+
expect do
|
68
|
+
asset_loader.named("assets1/some-file.txt")
|
69
|
+
end.to raise_error InlineSvg::AssetFile::FileNotFound
|
70
|
+
|
71
|
+
expect(known_document_1).to eq(asset_loader.named("assets1/known-document.svg"))
|
72
|
+
end
|
73
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
<svg>other interesting content</svg>
|