inline_svg 0.11.0 → 1.7.2
Sign up to get free protection for your applications and to get access to all the features.
- 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
|