inline_svg 0.11.0 → 1.7.2
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 +58 -0
- data/.github/workflows/ruby.yml +20 -0
- data/.rubocop.yml +1 -0
- data/.rubocop_todo.yml +421 -0
- data/CHANGELOG.md +144 -2
- data/README.md +148 -34
- data/Rakefile +7 -0
- data/inline_svg.gemspec +4 -4
- data/lib/inline_svg.rb +41 -9
- data/lib/inline_svg/action_view/helpers.rb +72 -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/railtie.rb +8 -3
- data/lib/inline_svg/static_asset_finder.rb +4 -2
- data/lib/inline_svg/transform_pipeline.rb +0 -1
- data/lib/inline_svg/transform_pipeline/transformations.rb +8 -1
- data/lib/inline_svg/transform_pipeline/transformations/aria_attributes.rb +17 -20
- 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 +10 -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 +5 -2
- 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/width.rb +3 -4
- data/lib/inline_svg/version.rb +1 -1
- data/lib/inline_svg/webpack_asset_finder.rb +50 -0
- 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/helpers/inline_svg_spec.rb +104 -21
- data/spec/id_generator_spec.rb +5 -3
- data/spec/inline_svg_spec.rb +48 -0
- data/spec/transformation_pipeline/transformations/aria_attributes_spec.rb +16 -16
- data/spec/transformation_pipeline/transformations/aria_hidden_attribute_spec.rb +12 -0
- data/spec/transformation_pipeline/transformations/data_attributes_spec.rb +18 -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_spec.rb +5 -1
- metadata +49 -22
- data/circle.yml +0 -3
@@ -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,16 +1,21 @@
|
|
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
|
|
11
|
+
private
|
12
|
+
|
12
13
|
def with_valid_hash_from(hash)
|
13
14
|
Hash.try_convert(hash) || {}
|
14
15
|
end
|
16
|
+
|
17
|
+
def dasherize(string)
|
18
|
+
string.to_s.gsub(/_/, "-")
|
19
|
+
end
|
15
20
|
end
|
16
21
|
end
|
@@ -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,8 +2,11 @@ module InlineSvg::TransformPipeline
|
|
2
2
|
module Transformations
|
3
3
|
class NoComment < Transformation
|
4
4
|
def transform(doc)
|
5
|
-
doc
|
6
|
-
|
5
|
+
with_svg(doc) do |svg|
|
6
|
+
svg.xpath("//comment()").each do |comment|
|
7
|
+
comment.remove
|
8
|
+
end
|
9
|
+
end
|
7
10
|
end
|
8
11
|
end
|
9
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
|
data/lib/inline_svg/version.rb
CHANGED
@@ -0,0 +1,50 @@
|
|
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
|
+
@asset_path = Webpacker.manifest.lookup(@filename)
|
10
|
+
end
|
11
|
+
|
12
|
+
def pathname
|
13
|
+
return if @asset_path.blank?
|
14
|
+
|
15
|
+
if Webpacker.dev_server.running?
|
16
|
+
dev_server_asset(@asset_path)
|
17
|
+
elsif Webpacker.config.public_path.present?
|
18
|
+
File.join(Webpacker.config.public_path, @asset_path)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
private
|
23
|
+
|
24
|
+
def dev_server_asset(file_path)
|
25
|
+
asset = fetch_from_dev_server(file_path)
|
26
|
+
|
27
|
+
begin
|
28
|
+
Tempfile.new(file_path).tap do |file|
|
29
|
+
file.binmode
|
30
|
+
file.write(asset)
|
31
|
+
file.rewind
|
32
|
+
end
|
33
|
+
rescue StandardError => e
|
34
|
+
Rails.logger.error "[inline_svg] Error creating tempfile for #{@filename}: #{e}"
|
35
|
+
raise
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def fetch_from_dev_server(file_path)
|
40
|
+
http = Net::HTTP.new(Webpacker.dev_server.host, Webpacker.dev_server.port)
|
41
|
+
http.use_ssl = Webpacker.dev_server.https?
|
42
|
+
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
|
43
|
+
|
44
|
+
http.request(Net::HTTP::Get.new(file_path)).body
|
45
|
+
rescue StandardError => e
|
46
|
+
Rails.logger.error "[inline_svg] Error fetching #{@filename} from webpack-dev-server: #{e}"
|
47
|
+
raise
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
@@ -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>
|
@@ -0,0 +1 @@
|
|
1
|
+
<svg>interesting content</svg>
|
@@ -0,0 +1 @@
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M3.273 7.151l-2.917-2.916c-.23.665-.356 1.361-.356 2.057 0 1.608.624 3.216 1.851 4.442 1.35 1.351 3.163 1.957 4.928 1.821.933-.072 1.851.268 2.513.93l9.646 9.646c.58.579 1.338.869 2.097.869 1.636 0 2.965-1.326 2.965-2.965 0-.759-.29-1.518-.868-2.097l-9.647-9.646c-.661-.662-1.002-1.581-.93-2.514.136-1.766-.47-3.578-1.821-4.928-.372-.372-.778-.686-1.209-.945l-6.252 6.246zm18.727 13.849c0 .552-.448 1-1 1s-1-.448-1-1 .448-1 1-1 1 .447 1 1zm-12.153-13.396l-3.061 3.061-2.566-2.567 3.062-3.061 2.565 2.567zm-.933.096l-.762.761-1.705-1.705.762-.762 1.705 1.706zm-2.991-.42l-.761.762 1.706 1.705.762-.762-1.707-1.705zm2.484-6.903l-2.893 2.893-2.412-2.412c.953-.556 2.044-.858 3.165-.858.707 0 1.425.12 2.128.373l.012.004z"/></svg>
|
@@ -0,0 +1 @@
|
|
1
|
+
<svg>Another known document</svg>
|
@@ -0,0 +1 @@
|
|
1
|
+
Some file contents.
|
@@ -13,27 +13,86 @@ describe InlineSvg::ActionView::Helpers do
|
|
13
13
|
|
14
14
|
let(:helper) { ( Class.new { include InlineSvg::ActionView::Helpers } ).new }
|
15
15
|
|
16
|
-
|
17
|
-
|
16
|
+
shared_examples "inline_svg helper" do |helper_method:|
|
17
|
+
|
18
18
|
context "when passed the name of an SVG that does not exist" do
|
19
|
+
after(:each) do
|
20
|
+
InlineSvg.reset_configuration!
|
21
|
+
end
|
22
|
+
|
23
|
+
context "and configured to raise" do
|
24
|
+
it "raises an exception" do
|
25
|
+
InlineSvg.configure do |config|
|
26
|
+
config.raise_on_file_not_found = true
|
27
|
+
end
|
28
|
+
|
29
|
+
allow(InlineSvg::AssetFile).to receive(:named).
|
30
|
+
with('some-missing-file.svg').
|
31
|
+
and_raise(InlineSvg::AssetFile::FileNotFound.new)
|
32
|
+
|
33
|
+
expect {
|
34
|
+
helper.send(helper_method, 'some-missing-file.svg')
|
35
|
+
}.to raise_error(InlineSvg::AssetFile::FileNotFound)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
19
39
|
it "returns an empty, html safe, SVG document as a placeholder" do
|
20
40
|
allow(InlineSvg::AssetFile).to receive(:named).
|
21
41
|
with('some-missing-file.svg').
|
22
42
|
and_raise(InlineSvg::AssetFile::FileNotFound.new)
|
23
43
|
|
24
|
-
output = helper.
|
44
|
+
output = helper.send(helper_method, 'some-missing-file.svg')
|
25
45
|
expect(output).to eq "<svg><!-- SVG file not found: 'some-missing-file.svg' --></svg>"
|
26
46
|
expect(output).to be_html_safe
|
27
47
|
end
|
28
48
|
|
49
|
+
it "escapes malicious input" do
|
50
|
+
malicious = "--></svg><script>alert(1)</script><svg>.svg"
|
51
|
+
allow(InlineSvg::AssetFile).to receive(:named).
|
52
|
+
with(malicious).
|
53
|
+
and_raise(InlineSvg::AssetFile::FileNotFound.new)
|
54
|
+
|
55
|
+
output = helper.send(helper_method, malicious)
|
56
|
+
expect(output).to eq "<svg><!-- SVG file not found: '--></svg><script>alert(1)</script><svg>.svg' --></svg>"
|
57
|
+
expect(output).to be_html_safe
|
58
|
+
end
|
59
|
+
|
29
60
|
it "gives a helpful hint when no .svg extension is provided in the filename" do
|
30
61
|
allow(InlineSvg::AssetFile).to receive(:named).
|
31
62
|
with('missing-file-with-no-extension').
|
32
63
|
and_raise(InlineSvg::AssetFile::FileNotFound.new)
|
33
64
|
|
34
|
-
output = helper.
|
65
|
+
output = helper.send(helper_method, 'missing-file-with-no-extension')
|
35
66
|
expect(output).to eq "<svg><!-- SVG file not found: 'missing-file-with-no-extension' (Try adding .svg to your filename) --></svg>"
|
36
67
|
end
|
68
|
+
|
69
|
+
it "allows the CSS class on the empty SVG document to be changed" do
|
70
|
+
InlineSvg.configure do |config|
|
71
|
+
config.svg_not_found_css_class = 'missing-svg'
|
72
|
+
end
|
73
|
+
|
74
|
+
allow(InlineSvg::AssetFile).to receive(:named).
|
75
|
+
with('some-other-missing-file.svg').
|
76
|
+
and_raise(InlineSvg::AssetFile::FileNotFound.new)
|
77
|
+
|
78
|
+
output = helper.send(helper_method, 'some-other-missing-file.svg')
|
79
|
+
expect(output).to eq "<svg class='missing-svg'><!-- SVG file not found: 'some-other-missing-file.svg' --></svg>"
|
80
|
+
expect(output).to be_html_safe
|
81
|
+
end
|
82
|
+
|
83
|
+
context "and a fallback that does exist" do
|
84
|
+
it "displays the fallback" do
|
85
|
+
allow(InlineSvg::AssetFile).to receive(:named).
|
86
|
+
with('missing.svg').
|
87
|
+
and_raise(InlineSvg::AssetFile::FileNotFound.new)
|
88
|
+
|
89
|
+
fallback_file = <<-SVG
|
90
|
+
<svg xmlns="http://www.w3.org/2000/svg" xml:lang="en"><!-- This is a comment --></svg>
|
91
|
+
SVG
|
92
|
+
allow(InlineSvg::AssetFile).to receive(:named).with('fallback.svg').and_return(fallback_file)
|
93
|
+
expect(helper.send(helper_method, 'missing.svg', fallback: 'fallback.svg')).to eq fallback_file
|
94
|
+
end
|
95
|
+
end
|
37
96
|
end
|
38
97
|
|
39
98
|
context "when passed an existing SVG file" do
|
@@ -41,10 +100,10 @@ describe InlineSvg::ActionView::Helpers do
|
|
41
100
|
context "and no options" do
|
42
101
|
it "returns a html safe version of the file's contents" do
|
43
102
|
example_file = <<-SVG
|
44
|
-
<svg xmlns="http://www.w3.org/2000/svg"
|
103
|
+
<svg xmlns="http://www.w3.org/2000/svg" xml:lang="en"><!-- This is a comment --></svg>
|
45
104
|
SVG
|
46
105
|
allow(InlineSvg::AssetFile).to receive(:named).with('some-file').and_return(example_file)
|
47
|
-
expect(helper.
|
106
|
+
expect(helper.send(helper_method, 'some-file')).to eq example_file
|
48
107
|
end
|
49
108
|
end
|
50
109
|
|
@@ -57,7 +116,7 @@ SVG
|
|
57
116
|
<svg xmlns="http://www.w3.org/2000/svg" role="presentation" xml:lang="en"><title>A title</title></svg>
|
58
117
|
SVG
|
59
118
|
allow(InlineSvg::AssetFile).to receive(:named).with('some-file').and_return(input_svg)
|
60
|
-
expect(helper.
|
119
|
+
expect(helper.send(helper_method, 'some-file', title: 'A title')).to eq expected_output
|
61
120
|
end
|
62
121
|
end
|
63
122
|
|
@@ -70,34 +129,46 @@ SVG
|
|
70
129
|
<svg xmlns="http://www.w3.org/2000/svg" role="presentation" xml:lang="en"><desc>A description</desc></svg>
|
71
130
|
SVG
|
72
131
|
allow(InlineSvg::AssetFile).to receive(:named).with('some-file').and_return(input_svg)
|
73
|
-
expect(helper.
|
132
|
+
expect(helper.send(helper_method, 'some-file', desc: 'A description')).to eq expected_output
|
74
133
|
end
|
75
134
|
end
|
76
135
|
|
77
136
|
context "and the 'nocomment' option" do
|
78
137
|
it "strips comments and other unknown/unsafe nodes from the output" do
|
79
138
|
input_svg = <<-SVG
|
80
|
-
<svg xmlns="http://www.w3.org/2000/svg"
|
139
|
+
<svg xmlns="http://www.w3.org/2000/svg" xml:lang="en"><!-- This is a comment --></svg>
|
81
140
|
SVG
|
82
141
|
expected_output = <<-SVG
|
83
142
|
<svg xmlns="http://www.w3.org/2000/svg" xml:lang="en"></svg>
|
84
143
|
SVG
|
85
144
|
allow(InlineSvg::AssetFile).to receive(:named).with('some-file').and_return(input_svg)
|
86
|
-
expect(helper.
|
145
|
+
expect(helper.send(helper_method, 'some-file', nocomment: true)).to eq expected_output
|
146
|
+
end
|
147
|
+
end
|
148
|
+
|
149
|
+
context "and the 'aria_hidden' option" do
|
150
|
+
it "sets 'aria-hidden=true' in the output" do
|
151
|
+
input_svg = <<-SVG
|
152
|
+
<svg xmlns="http://www.w3.org/2000/svg" xml:lang="en"></svg>
|
153
|
+
SVG
|
154
|
+
expected_output = <<-SVG
|
155
|
+
<svg xmlns="http://www.w3.org/2000/svg" xml:lang="en" aria-hidden="true"></svg>
|
156
|
+
SVG
|
157
|
+
allow(InlineSvg::AssetFile).to receive(:named).with('some-file').and_return(input_svg)
|
158
|
+
expect(helper.send(helper_method, 'some-file', aria_hidden: true)).to eq expected_output
|
87
159
|
end
|
88
160
|
end
|
89
161
|
|
90
162
|
context "and all options" do
|
91
163
|
it "applies all expected transformations to the output" do
|
92
164
|
input_svg = <<-SVG
|
93
|
-
<svg xmlns="http://www.w3.org/2000/svg"
|
165
|
+
<svg xmlns="http://www.w3.org/2000/svg" xml:lang="en"><!-- This is a comment --></svg>
|
94
166
|
SVG
|
95
167
|
expected_output = <<-SVG
|
96
|
-
<svg xmlns="http://www.w3.org/2000/svg" xml:lang="en"><title>A title</title>
|
97
|
-
<desc>A description</desc></svg>
|
168
|
+
<svg xmlns="http://www.w3.org/2000/svg" xml:lang="en"><title>A title</title><desc>A description</desc></svg>
|
98
169
|
SVG
|
99
170
|
allow(InlineSvg::AssetFile).to receive(:named).with('some-file').and_return(input_svg)
|
100
|
-
expect(helper.
|
171
|
+
expect(helper.send(helper_method, 'some-file', title: 'A title', desc: 'A description', nocomment: true)).to eq expected_output
|
101
172
|
end
|
102
173
|
end
|
103
174
|
|
@@ -120,7 +191,7 @@ SVG
|
|
120
191
|
<svg custom="some value"></svg>
|
121
192
|
SVG
|
122
193
|
allow(InlineSvg::AssetFile).to receive(:named).with('some-file').and_return(input_svg)
|
123
|
-
expect(helper.
|
194
|
+
expect(helper.send(helper_method, 'some-file', custom: 'some value')).to eq expected_output
|
124
195
|
end
|
125
196
|
end
|
126
197
|
|
@@ -141,7 +212,7 @@ SVG
|
|
141
212
|
|
142
213
|
allow(InlineSvg::AssetFile).to receive(:named).with('some-file').and_return(input_svg)
|
143
214
|
|
144
|
-
expect(helper.
|
215
|
+
expect(helper.send(helper_method, 'some-file')).to eq "<svg custom=\"default value\"></svg>\n"
|
145
216
|
end
|
146
217
|
end
|
147
218
|
|
@@ -151,7 +222,7 @@ SVG
|
|
151
222
|
|
152
223
|
allow(InlineSvg::AssetFile).to receive(:named).with('some-file').and_return(input_svg)
|
153
224
|
|
154
|
-
expect(helper.
|
225
|
+
expect(helper.send(helper_method, 'some-file', custom: 'some value')).to eq "<svg custom=\"some value\"></svg>\n"
|
155
226
|
end
|
156
227
|
end
|
157
228
|
end
|
@@ -163,13 +234,13 @@ SVG
|
|
163
234
|
expect(InlineSvg::IOResource).to receive(:===).with(argument).and_return(true)
|
164
235
|
expect(InlineSvg::IOResource).to receive(:read).with(argument)
|
165
236
|
expect(InlineSvg::AssetFile).to_not receive(:named)
|
166
|
-
helper.
|
237
|
+
helper.send(helper_method, argument)
|
167
238
|
end
|
168
239
|
it 'accept filename' do
|
169
240
|
expect(InlineSvg::IOResource).to receive(:===).with(argument).and_return(false)
|
170
241
|
expect(InlineSvg::IOResource).to_not receive(:read)
|
171
242
|
expect(InlineSvg::AssetFile).to receive(:named).with(argument)
|
172
|
-
helper.
|
243
|
+
helper.send(helper_method, argument)
|
173
244
|
end
|
174
245
|
end
|
175
246
|
context 'when passed IO object argument' do
|
@@ -179,17 +250,29 @@ SVG
|
|
179
250
|
it 'return valid svg' do
|
180
251
|
expect(InlineSvg::IOResource).to receive(:===).with(io_object).and_return(true)
|
181
252
|
expect(InlineSvg::IOResource).to receive(:read).with(io_object).and_return("<svg><!-- Test IO --></svg>")
|
182
|
-
output = helper.
|
253
|
+
output = helper.send(helper_method, io_object)
|
183
254
|
expect(output).to eq "<svg><!-- Test IO --></svg>\n"
|
184
255
|
expect(output).to be_html_safe
|
185
256
|
end
|
186
257
|
|
187
258
|
it 'return valid svg for file' do
|
188
|
-
output = helper.
|
259
|
+
output = helper.send(helper_method, File.new(file_path))
|
189
260
|
expect(output).to eq "<svg xmlns=\"http://www.w3.org/2000/svg\" xml:lang=\"en\" role=\"presentation\"><!-- This is a test comment --></svg>\n"
|
190
261
|
expect(output).to be_html_safe
|
191
262
|
end
|
192
263
|
|
193
264
|
end
|
194
265
|
end
|
266
|
+
|
267
|
+
describe '#inline_svg' do
|
268
|
+
it_behaves_like "inline_svg helper", helper_method: :inline_svg
|
269
|
+
end
|
270
|
+
|
271
|
+
describe '#inline_svg_tag' do
|
272
|
+
it_behaves_like "inline_svg helper", helper_method: :inline_svg_tag
|
273
|
+
end
|
274
|
+
|
275
|
+
describe '#inline_svg_tag' do
|
276
|
+
it_behaves_like "inline_svg helper", helper_method: :inline_svg_pack_tag
|
277
|
+
end
|
195
278
|
end
|