inline_svg 1.5.1 → 1.7.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/workflows/integration_test.yml +58 -0
- data/.github/workflows/ruby.yml +20 -0
- data/CHANGELOG.md +36 -1
- data/README.md +26 -40
- data/lib/inline_svg/action_view/helpers.rb +40 -3
- data/lib/inline_svg/cached_asset_file.rb +2 -11
- data/lib/inline_svg/finds_asset_paths.rb +1 -1
- data/lib/inline_svg/railtie.rb +3 -13
- data/lib/inline_svg/static_asset_finder.rb +4 -2
- data/lib/inline_svg/version.rb +1 -1
- data/lib/inline_svg/webpack_asset_finder.rb +35 -4
- data/spec/helpers/inline_svg_spec.rb +42 -19
- metadata +8 -9
- data/.travis.yml +0 -8
- data/circle.yml +0 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: fd31243686f41f3d2acfc2f7235685baaab23ca967774d6f642e7f5aab7f2fbc
|
4
|
+
data.tar.gz: 1c6bdf6fc08c4a145c5ecefea9aaa2fe60d2f1d0142c78aed17a73d4acaaa9ce
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: baee695644bd79e2561183326818a30f2dd1be7e4262973faacc2fa17ba7970888f9b4beb5cb0ebf2ce9a8c477d99d941f29431bdfaea32d66bd654c244e9545
|
7
|
+
data.tar.gz: 16347bfe873b1f0ab075a43b5f98590a5d2f80cb985849dd7d6c868e4d753a8e5f86209bab55c06e47ea67f89b622132ce3fc88343cbb4a388ae94b798009ca1
|
@@ -0,0 +1,58 @@
|
|
1
|
+
name: Integration Tests
|
2
|
+
|
3
|
+
on: [push]
|
4
|
+
|
5
|
+
jobs:
|
6
|
+
build:
|
7
|
+
|
8
|
+
runs-on: ubuntu-latest
|
9
|
+
strategy:
|
10
|
+
matrix:
|
11
|
+
test-branch: [rails3, rails4, main, rails6, rails6-webpacker]
|
12
|
+
steps:
|
13
|
+
- name: Checkout
|
14
|
+
uses: actions/checkout@v2
|
15
|
+
- name: Checkout test app
|
16
|
+
uses: actions/checkout@v2
|
17
|
+
with:
|
18
|
+
repository: jamesmartin/inline_svg_test_app
|
19
|
+
ref: ${{ matrix.test-branch }}
|
20
|
+
path: test_app
|
21
|
+
- name: Set up Ruby 2.6
|
22
|
+
uses: actions/setup-ruby@v1
|
23
|
+
with:
|
24
|
+
ruby-version: 2.6.x
|
25
|
+
- name: Build local gem
|
26
|
+
run: |
|
27
|
+
gem install bundler
|
28
|
+
bundle install --jobs 4 --retry 3
|
29
|
+
bundle exec rake build
|
30
|
+
- name: Use the local gem in the test App
|
31
|
+
id: uselocalgem
|
32
|
+
uses: jacobtomlinson/gha-find-replace@0.1.1
|
33
|
+
with:
|
34
|
+
find: "gem 'inline_svg'"
|
35
|
+
replace: "gem 'inline_svg', path: '${{github.workspace}}'"
|
36
|
+
- name: Check local gem in use
|
37
|
+
run: |
|
38
|
+
test "${{ steps.uselocalgem.outputs.modifiedFiles }}" != "0"
|
39
|
+
grep "inline_svg" $GITHUB_WORKSPACE/test_app/Gemfile
|
40
|
+
- name: Bundle
|
41
|
+
run: |
|
42
|
+
cd $GITHUB_WORKSPACE/test_app
|
43
|
+
bundle install --jobs 4 --retry 3
|
44
|
+
- name: Set up Node.js 12.x
|
45
|
+
uses: actions/setup-node@v1
|
46
|
+
with:
|
47
|
+
node-version: 12.x
|
48
|
+
if: matrix.test-branch == 'rails6-webpacker'
|
49
|
+
- name: Generate Webpacker config
|
50
|
+
run: |
|
51
|
+
cd $GITHUB_WORKSPACE/test_app
|
52
|
+
yarn install --check-files
|
53
|
+
bundle exec rake webpacker:compile
|
54
|
+
if: matrix.test-branch == 'rails6-webpacker'
|
55
|
+
- name: Test
|
56
|
+
run: |
|
57
|
+
cd $GITHUB_WORKSPACE/test_app
|
58
|
+
bundle exec rake test
|
@@ -0,0 +1,20 @@
|
|
1
|
+
name: Ruby
|
2
|
+
|
3
|
+
on: [push]
|
4
|
+
|
5
|
+
jobs:
|
6
|
+
build:
|
7
|
+
|
8
|
+
runs-on: ubuntu-latest
|
9
|
+
|
10
|
+
steps:
|
11
|
+
- uses: actions/checkout@v2
|
12
|
+
- name: Set up Ruby 2.6
|
13
|
+
uses: actions/setup-ruby@v1
|
14
|
+
with:
|
15
|
+
ruby-version: 2.6.x
|
16
|
+
- name: Build and test with Rake
|
17
|
+
run: |
|
18
|
+
gem install bundler
|
19
|
+
bundle install --jobs 4 --retry 3
|
20
|
+
bundle exec rake
|
data/CHANGELOG.md
CHANGED
@@ -3,8 +3,38 @@ All notable changes to this project will be documented in this file.
|
|
3
3
|
This project adheres to [Semantic Versioning](http://semver.org/).
|
4
4
|
|
5
5
|
## [Unreleased][unreleased]
|
6
|
+
|
6
7
|
- Nothing
|
7
8
|
|
9
|
+
## [1.7.2] - 2020-12-07
|
10
|
+
### Fixed
|
11
|
+
- Improve performance of `CachedAssetFile`. [#118](https://github.com/jamesmartin/inline_svg/pull/118). Thanks [@stevendaniels](https://github.com/stevendaniels)
|
12
|
+
- Avoid XSS by preventing malicious input of filenames. [#117](https://github.com/jamesmartin/inline_svg/pull/117). Thanks [@pbyrne](https://github.com/pbyrne).
|
13
|
+
|
14
|
+
## [1.7.1] - 2020-03-17
|
15
|
+
### Fixed
|
16
|
+
- Static Asset Finder uses pathname for compatibility with Sprockets 4+. [#106](https://github.com/jamesmartin/inline_svg/pull/106). Thanks [@subdigital](https://github.com/subdigital)
|
17
|
+
|
18
|
+
## [1.7.0] - 2020-02-13
|
19
|
+
### Added
|
20
|
+
- WebpackAssetFinder serves files from dev server if one is running. [#111](https://github.com/jamesmartin/inline_svg/pull/111). Thanks, [@connorshea](https://github.com/connorshea)
|
21
|
+
|
22
|
+
### Fixed
|
23
|
+
- Using Webpacker and Asset Pipeline in a single App could result in SVGs not being found because the wrong `AssetFinder` was used. [#114](https://github.com/jamesmartin/inline_svg/pull/114). Thanks, [@kylefox](https://github.com/kylefox)
|
24
|
+
- Prevent "EOFError error" when using webpack dev server over HTTPS [#113](https://github.com/jamesmartin/inline_svg/pull/113). Thanks, [@kylefox](https://github.com/kylefox)
|
25
|
+
|
26
|
+
|
27
|
+
## [1.6.0] - 2019-11-13
|
28
|
+
### Added
|
29
|
+
- Support Webpack via the new `inline_svg_pack_tag` helper and deprecate `inline_svg` helper in preparation for v2.0.
|
30
|
+
[#103](https://github.com/jamesmartin/inline_svg/pull/103)
|
31
|
+
Thanks, [@kylefox](https://github.com/kylefox)
|
32
|
+
|
33
|
+
## [1.5.2] - 2019-06-20
|
34
|
+
### Fixed
|
35
|
+
- Revert automatic Webpack asset finder behavior. Make Webpack "opt-in".
|
36
|
+
[#98](https://github.com/jamesmartin/inline_svg/issues/98)
|
37
|
+
|
8
38
|
## [1.5.1] - 2019-06-18
|
9
39
|
### Fixed
|
10
40
|
- Prevent nil asset finder when neither Sprockets or Webpacker are available
|
@@ -209,7 +239,12 @@ transformations](https://github.com/jamesmartin/inline_svg/blob/master/README.md
|
|
209
239
|
### Added
|
210
240
|
- Basic Railtie and view helper to inline SVG documents to Rails views.
|
211
241
|
|
212
|
-
[unreleased]: https://github.com/jamesmartin/inline_svg/compare/v1.
|
242
|
+
[unreleased]: https://github.com/jamesmartin/inline_svg/compare/v1.7.2...HEAD
|
243
|
+
[1.7.2]: https://github.com/jamesmartin/inline_svg/compare/v1.7.1...v1.7.2
|
244
|
+
[1.7.1]: https://github.com/jamesmartin/inline_svg/compare/v1.7.0...v1.7.1
|
245
|
+
[1.7.0]: https://github.com/jamesmartin/inline_svg/compare/v1.6.0...v1.7.0
|
246
|
+
[1.6.0]: https://github.com/jamesmartin/inline_svg/compare/v1.5.2...v1.6.0
|
247
|
+
[1.5.2]: https://github.com/jamesmartin/inline_svg/compare/v1.5.1...v1.5.2
|
213
248
|
[1.5.1]: https://github.com/jamesmartin/inline_svg/compare/v1.5.0...v1.5.1
|
214
249
|
[1.5.0]: https://github.com/jamesmartin/inline_svg/compare/v1.4.0...v1.5.0
|
215
250
|
[1.4.0]: https://github.com/jamesmartin/inline_svg/compare/v1.3.1...v1.4.0
|
data/README.md
CHANGED
@@ -1,12 +1,13 @@
|
|
1
1
|
# Inline SVG
|
2
2
|
|
3
|
-
|
3
|
+
![Unit tests](https://github.com/jamesmartin/inline_svg/workflows/Ruby/badge.svg)
|
4
|
+
![Integration Tests](https://github.com/jamesmartin/inline_svg/workflows/Integration%20Tests/badge.svg)
|
4
5
|
|
5
6
|
Styling a SVG document with CSS for use on the web is most reliably achieved by
|
6
7
|
[adding classes to the document and
|
7
8
|
embedding](http://css-tricks.com/using-svg/) it inline in the HTML.
|
8
9
|
|
9
|
-
This gem adds
|
10
|
+
This gem adds Rails helper methods (`inline_svg_tag` and `inline_svg_pack_tag`) that read an SVG document (via Sprockets or Webpacker, so works with the Rails Asset Pipeline), applies a CSS class attribute to the root of the document and
|
10
11
|
then embeds it into a view.
|
11
12
|
|
12
13
|
Inline SVG supports:
|
@@ -14,7 +15,7 @@ Inline SVG supports:
|
|
14
15
|
- [Rails 3](http://weblog.rubyonrails.org/2010/8/29/rails-3-0-it-s-done/) (from [v0.12.0](https://github.com/jamesmartin/inline_svg/releases/tag/v0.12.0))
|
15
16
|
- [Rails 4](http://weblog.rubyonrails.org/2013/6/25/Rails-4-0-final/)
|
16
17
|
- [Rails 5](http://weblog.rubyonrails.org/2016/6/30/Rails-5-0-final/) (from [v0.10.0](https://github.com/jamesmartin/inline_svg/releases/tag/v0.10.0))
|
17
|
-
- [Rails 6](https://weblog.rubyonrails.org/2019/4/24/Rails-6-0-rc1-released/) with Sprockets or Webpacker (from [v1.5.
|
18
|
+
- [Rails 6](https://weblog.rubyonrails.org/2019/4/24/Rails-6-0-rc1-released/) with Sprockets or Webpacker (from [v1.5.2](https://github.com/jamesmartin/inline_svg/releases/tag/v1.5.2)).
|
18
19
|
|
19
20
|
## Changelog
|
20
21
|
|
@@ -37,9 +38,15 @@ Or install it yourself as:
|
|
37
38
|
|
38
39
|
## Usage
|
39
40
|
|
41
|
+
```ruby
|
42
|
+
# Sprockets
|
43
|
+
inline_svg_tag(file_name, options={})
|
44
|
+
|
45
|
+
# Webpacker
|
46
|
+
inline_svg_pack_tag(file_name, options={})
|
40
47
|
```
|
41
|
-
|
42
|
-
|
48
|
+
|
49
|
+
_**Note:** The remainder of this README uses `inline_svg_tag` for examples, but the exact same principles work for `inline_svg_pack_tag`._
|
43
50
|
|
44
51
|
The `file_name` can be a full path to a file, the file's basename or an `IO`
|
45
52
|
object. The
|
@@ -57,7 +64,7 @@ Here's an example of embedding an SVG document and applying a 'class' attribute:
|
|
57
64
|
<body>
|
58
65
|
<h1>Embedded SVG Documents</h1>
|
59
66
|
<div>
|
60
|
-
<%=
|
67
|
+
<%= inline_svg_tag "some-document.svg", class: 'some-class' %>
|
61
68
|
</div>
|
62
69
|
</body>
|
63
70
|
</html>
|
@@ -91,11 +98,12 @@ key | description
|
|
91
98
|
`preserve_aspect_ratio` | adds a `preserveAspectRatio` attribute to the SVG
|
92
99
|
`aria` | adds common accessibility attributes to the SVG (see [PR #34](https://github.com/jamesmartin/inline_svg/pull/34#issue-152062674) for details)
|
93
100
|
`aria_hidden` | adds the `aria-hidden=true` attribute to the SVG
|
101
|
+
`fallback` | set fallback SVG document
|
94
102
|
|
95
103
|
Example:
|
96
104
|
|
97
105
|
```ruby
|
98
|
-
|
106
|
+
inline_svg_tag(
|
99
107
|
"some-document.svg",
|
100
108
|
id: 'some-id',
|
101
109
|
class: 'some-class',
|
@@ -106,13 +114,14 @@ inline_svg(
|
|
106
114
|
nocomment: true,
|
107
115
|
preserve_aspect_ratio: 'xMaxYMax meet',
|
108
116
|
aria: true,
|
109
|
-
aria_hidden: true
|
117
|
+
aria_hidden: true,
|
118
|
+
fallback: 'fallback-document.svg'
|
110
119
|
)
|
111
120
|
```
|
112
121
|
|
113
122
|
## Accessibility
|
114
123
|
|
115
|
-
Use the `aria: true` option to make `
|
124
|
+
Use the `aria: true` option to make `inline_svg_tag` add the following
|
116
125
|
accessibility (a11y) attributes to your embedded SVG:
|
117
126
|
|
118
127
|
* Adds a `role="img"` attribute to the root SVG element
|
@@ -123,7 +132,7 @@ Here's an example:
|
|
123
132
|
|
124
133
|
```erb
|
125
134
|
<%=
|
126
|
-
|
135
|
+
inline_svg_tag('iconmonstr-glasses-12-icon.svg',
|
127
136
|
aria: true, title: 'An SVG',
|
128
137
|
desc: 'This is my SVG. There are many like it. You get the picture')
|
129
138
|
%>
|
@@ -137,11 +146,11 @@ Here's an example:
|
|
137
146
|
</svg>
|
138
147
|
```
|
139
148
|
|
140
|
-
***Note:*** The title and desc `id` attributes generated for, and referenced by, `aria-labelled-by` are one-way digests based on the value of the title and desc elements and an optional "salt" value using the SHA1 algorithm. This reduces the chance of `
|
149
|
+
***Note:*** The title and desc `id` attributes generated for, and referenced by, `aria-labelled-by` are one-way digests based on the value of the title and desc elements and an optional "salt" value using the SHA1 algorithm. This reduces the chance of `inline_svg_tag` embedding elements inside the SVG with `id` attributes that clash with other elements elsewhere on the page.
|
141
150
|
|
142
151
|
## Custom Transformations
|
143
152
|
|
144
|
-
The transformation behavior of `
|
153
|
+
The transformation behavior of `inline_svg_tag` can be customized by creating custom transformation classes.
|
145
154
|
|
146
155
|
For example, inherit from `InlineSvg::CustomTransformation` and implement the `#transform` method:
|
147
156
|
|
@@ -170,7 +179,7 @@ end
|
|
170
179
|
The custom transformation can then be called like so:
|
171
180
|
```haml
|
172
181
|
%div
|
173
|
-
=
|
182
|
+
= inline_svg_tag "some-document.svg", my_custom_attribute: 'some value'
|
174
183
|
```
|
175
184
|
|
176
185
|
In this example, the following transformation would be applied to a SVG document:
|
@@ -191,8 +200,8 @@ end
|
|
191
200
|
The custom transformation will be triggered even if you don't pass any attribute value
|
192
201
|
```haml
|
193
202
|
%div
|
194
|
-
=
|
195
|
-
=
|
203
|
+
= inline_svg_tag "some-document.svg"
|
204
|
+
= inline_svg_tag "some-document.svg", my_custom_attribute: 'some value'
|
196
205
|
```
|
197
206
|
|
198
207
|
In this example, the following transformation would be applied to a SVG document:
|
@@ -272,7 +281,7 @@ end
|
|
272
281
|
|
273
282
|
**Note:** Paths are read recursively, so think about keeping your SVG assets
|
274
283
|
restricted to as few paths as possible, and using the filter option to further
|
275
|
-
restrict assets to only those likely to be used by `
|
284
|
+
restrict assets to only those likely to be used by `inline_svg_tag`.
|
276
285
|
|
277
286
|
## Missing SVG Files
|
278
287
|
|
@@ -299,7 +308,7 @@ Which would instead render:
|
|
299
308
|
<svg class='svg-not-found'><!-- SVG file not found: 'some-missing-file.svg' --></svg>
|
300
309
|
```
|
301
310
|
|
302
|
-
Alternatively, `
|
311
|
+
Alternatively, `inline_svg_tag` can be configured to raise an exception when a file
|
303
312
|
is not found:
|
304
313
|
|
305
314
|
```ruby
|
@@ -308,29 +317,6 @@ InlineSvg.configure do |config|
|
|
308
317
|
end
|
309
318
|
```
|
310
319
|
|
311
|
-
## Sprockets and Webpacker
|
312
|
-
|
313
|
-
Inline SVG supports SVGs bundled by either Sprockets or Webpacker, however, be
|
314
|
-
aware that the gem will *always* attempt to find SVGs using Sprockts if it is
|
315
|
-
enabled.
|
316
|
-
|
317
|
-
By default, Inline SVG will use Sprockets to find SVG files if it is enabled in
|
318
|
-
your Rails project.
|
319
|
-
|
320
|
-
If you have upgraded an older Rails project from Sprockets to Webpacker and you
|
321
|
-
no longer want to use Sprockets at all, you should disable the Asset Pipeline
|
322
|
-
and Inline SVG will use Webpacker automatically.
|
323
|
-
|
324
|
-
If you have both Sprockets *and* Webpacker enabled for some reason and you want
|
325
|
-
Inline SVG to use Webpacker to find SVGs then you should configure the
|
326
|
-
`asset_finder` appropriately:
|
327
|
-
|
328
|
-
```ruby
|
329
|
-
InlineSvg.configure do |config|
|
330
|
-
config.asset_finder = InlineSvg::WebpackAssetFinder
|
331
|
-
end
|
332
|
-
```
|
333
|
-
|
334
320
|
## Contributing
|
335
321
|
|
336
322
|
1. Fork it ( [http://github.com/jamesmartin/inline_svg/fork](http://github.com/jamesmartin/inline_svg/fork) )
|
@@ -4,7 +4,38 @@ require 'action_view/context' if defined?(Rails)
|
|
4
4
|
module InlineSvg
|
5
5
|
module ActionView
|
6
6
|
module Helpers
|
7
|
+
def inline_svg_tag(filename, transform_params={})
|
8
|
+
with_asset_finder(InlineSvg.configuration.asset_finder) do
|
9
|
+
render_inline_svg(filename, transform_params)
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
def inline_svg_pack_tag(filename, transform_params={})
|
14
|
+
with_asset_finder(InlineSvg::WebpackAssetFinder) do
|
15
|
+
render_inline_svg(filename, transform_params)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
7
19
|
def inline_svg(filename, transform_params={})
|
20
|
+
ActiveSupport::Deprecation.warn(
|
21
|
+
'`inline_svg` is deprecated and will be removed from inline_svg 2.0 (use `inline_svg_tag` or `inline_svg_pack_tag` instead)'
|
22
|
+
)
|
23
|
+
|
24
|
+
render_inline_svg(filename, transform_params)
|
25
|
+
end
|
26
|
+
|
27
|
+
private
|
28
|
+
|
29
|
+
def backwards_compatible_html_escape(filename)
|
30
|
+
# html_escape_once was introduced in newer versions of Rails.
|
31
|
+
if ERB::Util.respond_to?(:html_escape_once)
|
32
|
+
ERB::Util.html_escape_once(filename)
|
33
|
+
else
|
34
|
+
ERB::Util.html_escape(filename)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def render_inline_svg(filename, transform_params={})
|
8
39
|
begin
|
9
40
|
svg_file = read_svg(filename)
|
10
41
|
rescue InlineSvg::AssetFile::FileNotFound => error
|
@@ -23,8 +54,6 @@ module InlineSvg
|
|
23
54
|
InlineSvg::TransformPipeline.generate_html_from(svg_file, transform_params).html_safe
|
24
55
|
end
|
25
56
|
|
26
|
-
private
|
27
|
-
|
28
57
|
def read_svg(filename)
|
29
58
|
if InlineSvg::IOResource === filename
|
30
59
|
InlineSvg::IOResource.read filename
|
@@ -35,7 +64,7 @@ module InlineSvg
|
|
35
64
|
|
36
65
|
def placeholder(filename)
|
37
66
|
css_class = InlineSvg.configuration.svg_not_found_css_class
|
38
|
-
not_found_message = "'#{filename}' #{extension_hint(filename)}"
|
67
|
+
not_found_message = "'#{backwards_compatible_html_escape(filename)}' #{extension_hint(filename)}"
|
39
68
|
|
40
69
|
if css_class.nil?
|
41
70
|
return "<svg><!-- SVG file not found: #{not_found_message}--></svg>".html_safe
|
@@ -48,6 +77,14 @@ module InlineSvg
|
|
48
77
|
InlineSvg.configuration.asset_file
|
49
78
|
end
|
50
79
|
|
80
|
+
def with_asset_finder(asset_finder)
|
81
|
+
Thread.current[:inline_svg_asset_finder] = asset_finder
|
82
|
+
output = yield
|
83
|
+
Thread.current[:inline_svg_asset_finder] = nil
|
84
|
+
|
85
|
+
output
|
86
|
+
end
|
87
|
+
|
51
88
|
def extension_hint(filename)
|
52
89
|
filename.ends_with?(".svg") ? "" : "(Try adding .svg to your filename) "
|
53
90
|
end
|
@@ -18,6 +18,7 @@ module InlineSvg
|
|
18
18
|
@paths = Array(paths).compact.map { |p| Pathname.new(p) }
|
19
19
|
@filters = Array(filters).map { |f| Regexp.new(f) }
|
20
20
|
@assets = @paths.reduce({}) { |assets, p| assets.merge(read_assets(assets, p)) }
|
21
|
+
@sorted_asset_keys = assets.keys.sort { |a, b| a.size <=> b.size }
|
21
22
|
end
|
22
23
|
|
23
24
|
# Public: Finds the named asset and returns the contents as a string.
|
@@ -39,17 +40,7 @@ module InlineSvg
|
|
39
40
|
# Returns a String representing the key for the named asset or nil if there
|
40
41
|
# is no match.
|
41
42
|
def key_for_asset(asset_name)
|
42
|
-
|
43
|
-
a.string.size <=> b.string.size
|
44
|
-
end.first
|
45
|
-
match && match.string
|
46
|
-
end
|
47
|
-
|
48
|
-
# Internal: Find all potential asset keys matching the given asset name.
|
49
|
-
#
|
50
|
-
# Returns an array of MatchData objects for keys matching the asset name.
|
51
|
-
def all_keys_matching(asset_name)
|
52
|
-
assets.keys.map { |k| /(#{asset_name})/.match(k.to_s) }.compact
|
43
|
+
@sorted_asset_keys.find { |k| k.include?(asset_name) }
|
53
44
|
end
|
54
45
|
|
55
46
|
# Internal: Recursively descends through current_paths reading each file it
|
data/lib/inline_svg/railtie.rb
CHANGED
@@ -14,19 +14,9 @@ module InlineSvg
|
|
14
14
|
# Only set this when a user-configured asset finder has not been
|
15
15
|
# configured already.
|
16
16
|
if config.asset_finder.nil?
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
config.asset_finder = assets
|
21
|
-
elsif defined?(Webpacker)
|
22
|
-
# Use Webpacker when it's available
|
23
|
-
config.asset_finder = InlineSvg::WebpackAssetFinder
|
24
|
-
else
|
25
|
-
# Fallback to the StaticAssetFinder if all else fails.
|
26
|
-
# This will be used in cases where assets are precompiled and other
|
27
|
-
# production settings.
|
28
|
-
config.asset_finder = InlineSvg::StaticAssetFinder
|
29
|
-
end
|
17
|
+
# In default Rails apps, this will be a fully operational
|
18
|
+
# Sprockets::Environment instance
|
19
|
+
config.asset_finder = app.instance_variable_get(:@assets)
|
30
20
|
end
|
31
21
|
end
|
32
22
|
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,7 @@ module InlineSvg
|
|
14
16
|
|
15
17
|
def pathname
|
16
18
|
if ::Rails.application.config.assets.compile
|
17
|
-
::Rails.application.assets[@filename].
|
19
|
+
Pathname.new(::Rails.application.assets[@filename].filename)
|
18
20
|
else
|
19
21
|
manifest = ::Rails.application.assets_manifest
|
20
22
|
asset_path = manifest.assets[@filename]
|
data/lib/inline_svg/version.rb
CHANGED
@@ -6,14 +6,45 @@ module InlineSvg
|
|
6
6
|
|
7
7
|
def initialize(filename)
|
8
8
|
@filename = filename
|
9
|
+
@asset_path = Webpacker.manifest.lookup(@filename)
|
9
10
|
end
|
10
11
|
|
11
12
|
def pathname
|
12
|
-
|
13
|
-
file_path = Webpacker.instance.manifest.lookup(@filename)
|
14
|
-
return unless public_path && file_path
|
13
|
+
return if @asset_path.blank?
|
15
14
|
|
16
|
-
|
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
|
17
48
|
end
|
18
49
|
end
|
19
50
|
end
|
@@ -13,7 +13,7 @@ describe InlineSvg::ActionView::Helpers do
|
|
13
13
|
|
14
14
|
let(:helper) { ( Class.new { include InlineSvg::ActionView::Helpers } ).new }
|
15
15
|
|
16
|
-
|
16
|
+
shared_examples "inline_svg helper" do |helper_method:|
|
17
17
|
|
18
18
|
context "when passed the name of an SVG that does not exist" do
|
19
19
|
after(:each) do
|
@@ -31,7 +31,7 @@ describe InlineSvg::ActionView::Helpers do
|
|
31
31
|
and_raise(InlineSvg::AssetFile::FileNotFound.new)
|
32
32
|
|
33
33
|
expect {
|
34
|
-
helper.
|
34
|
+
helper.send(helper_method, 'some-missing-file.svg')
|
35
35
|
}.to raise_error(InlineSvg::AssetFile::FileNotFound)
|
36
36
|
end
|
37
37
|
end
|
@@ -41,17 +41,28 @@ describe InlineSvg::ActionView::Helpers do
|
|
41
41
|
with('some-missing-file.svg').
|
42
42
|
and_raise(InlineSvg::AssetFile::FileNotFound.new)
|
43
43
|
|
44
|
-
output = helper.
|
44
|
+
output = helper.send(helper_method, 'some-missing-file.svg')
|
45
45
|
expect(output).to eq "<svg><!-- SVG file not found: 'some-missing-file.svg' --></svg>"
|
46
46
|
expect(output).to be_html_safe
|
47
47
|
end
|
48
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
|
+
|
49
60
|
it "gives a helpful hint when no .svg extension is provided in the filename" do
|
50
61
|
allow(InlineSvg::AssetFile).to receive(:named).
|
51
62
|
with('missing-file-with-no-extension').
|
52
63
|
and_raise(InlineSvg::AssetFile::FileNotFound.new)
|
53
64
|
|
54
|
-
output = helper.
|
65
|
+
output = helper.send(helper_method, 'missing-file-with-no-extension')
|
55
66
|
expect(output).to eq "<svg><!-- SVG file not found: 'missing-file-with-no-extension' (Try adding .svg to your filename) --></svg>"
|
56
67
|
end
|
57
68
|
|
@@ -64,7 +75,7 @@ describe InlineSvg::ActionView::Helpers do
|
|
64
75
|
with('some-other-missing-file.svg').
|
65
76
|
and_raise(InlineSvg::AssetFile::FileNotFound.new)
|
66
77
|
|
67
|
-
output = helper.
|
78
|
+
output = helper.send(helper_method, 'some-other-missing-file.svg')
|
68
79
|
expect(output).to eq "<svg class='missing-svg'><!-- SVG file not found: 'some-other-missing-file.svg' --></svg>"
|
69
80
|
expect(output).to be_html_safe
|
70
81
|
end
|
@@ -79,7 +90,7 @@ describe InlineSvg::ActionView::Helpers do
|
|
79
90
|
<svg xmlns="http://www.w3.org/2000/svg" xml:lang="en"><!-- This is a comment --></svg>
|
80
91
|
SVG
|
81
92
|
allow(InlineSvg::AssetFile).to receive(:named).with('fallback.svg').and_return(fallback_file)
|
82
|
-
expect(helper.
|
93
|
+
expect(helper.send(helper_method, 'missing.svg', fallback: 'fallback.svg')).to eq fallback_file
|
83
94
|
end
|
84
95
|
end
|
85
96
|
end
|
@@ -92,7 +103,7 @@ SVG
|
|
92
103
|
<svg xmlns="http://www.w3.org/2000/svg" xml:lang="en"><!-- This is a comment --></svg>
|
93
104
|
SVG
|
94
105
|
allow(InlineSvg::AssetFile).to receive(:named).with('some-file').and_return(example_file)
|
95
|
-
expect(helper.
|
106
|
+
expect(helper.send(helper_method, 'some-file')).to eq example_file
|
96
107
|
end
|
97
108
|
end
|
98
109
|
|
@@ -105,7 +116,7 @@ SVG
|
|
105
116
|
<svg xmlns="http://www.w3.org/2000/svg" role="presentation" xml:lang="en"><title>A title</title></svg>
|
106
117
|
SVG
|
107
118
|
allow(InlineSvg::AssetFile).to receive(:named).with('some-file').and_return(input_svg)
|
108
|
-
expect(helper.
|
119
|
+
expect(helper.send(helper_method, 'some-file', title: 'A title')).to eq expected_output
|
109
120
|
end
|
110
121
|
end
|
111
122
|
|
@@ -118,7 +129,7 @@ SVG
|
|
118
129
|
<svg xmlns="http://www.w3.org/2000/svg" role="presentation" xml:lang="en"><desc>A description</desc></svg>
|
119
130
|
SVG
|
120
131
|
allow(InlineSvg::AssetFile).to receive(:named).with('some-file').and_return(input_svg)
|
121
|
-
expect(helper.
|
132
|
+
expect(helper.send(helper_method, 'some-file', desc: 'A description')).to eq expected_output
|
122
133
|
end
|
123
134
|
end
|
124
135
|
|
@@ -131,7 +142,7 @@ SVG
|
|
131
142
|
<svg xmlns="http://www.w3.org/2000/svg" xml:lang="en"></svg>
|
132
143
|
SVG
|
133
144
|
allow(InlineSvg::AssetFile).to receive(:named).with('some-file').and_return(input_svg)
|
134
|
-
expect(helper.
|
145
|
+
expect(helper.send(helper_method, 'some-file', nocomment: true)).to eq expected_output
|
135
146
|
end
|
136
147
|
end
|
137
148
|
|
@@ -144,7 +155,7 @@ SVG
|
|
144
155
|
<svg xmlns="http://www.w3.org/2000/svg" xml:lang="en" aria-hidden="true"></svg>
|
145
156
|
SVG
|
146
157
|
allow(InlineSvg::AssetFile).to receive(:named).with('some-file').and_return(input_svg)
|
147
|
-
expect(helper.
|
158
|
+
expect(helper.send(helper_method, 'some-file', aria_hidden: true)).to eq expected_output
|
148
159
|
end
|
149
160
|
end
|
150
161
|
|
@@ -157,7 +168,7 @@ SVG
|
|
157
168
|
<svg xmlns="http://www.w3.org/2000/svg" xml:lang="en"><title>A title</title><desc>A description</desc></svg>
|
158
169
|
SVG
|
159
170
|
allow(InlineSvg::AssetFile).to receive(:named).with('some-file').and_return(input_svg)
|
160
|
-
expect(helper.
|
171
|
+
expect(helper.send(helper_method, 'some-file', title: 'A title', desc: 'A description', nocomment: true)).to eq expected_output
|
161
172
|
end
|
162
173
|
end
|
163
174
|
|
@@ -180,7 +191,7 @@ SVG
|
|
180
191
|
<svg custom="some value"></svg>
|
181
192
|
SVG
|
182
193
|
allow(InlineSvg::AssetFile).to receive(:named).with('some-file').and_return(input_svg)
|
183
|
-
expect(helper.
|
194
|
+
expect(helper.send(helper_method, 'some-file', custom: 'some value')).to eq expected_output
|
184
195
|
end
|
185
196
|
end
|
186
197
|
|
@@ -201,7 +212,7 @@ SVG
|
|
201
212
|
|
202
213
|
allow(InlineSvg::AssetFile).to receive(:named).with('some-file').and_return(input_svg)
|
203
214
|
|
204
|
-
expect(helper.
|
215
|
+
expect(helper.send(helper_method, 'some-file')).to eq "<svg custom=\"default value\"></svg>\n"
|
205
216
|
end
|
206
217
|
end
|
207
218
|
|
@@ -211,7 +222,7 @@ SVG
|
|
211
222
|
|
212
223
|
allow(InlineSvg::AssetFile).to receive(:named).with('some-file').and_return(input_svg)
|
213
224
|
|
214
|
-
expect(helper.
|
225
|
+
expect(helper.send(helper_method, 'some-file', custom: 'some value')).to eq "<svg custom=\"some value\"></svg>\n"
|
215
226
|
end
|
216
227
|
end
|
217
228
|
end
|
@@ -223,13 +234,13 @@ SVG
|
|
223
234
|
expect(InlineSvg::IOResource).to receive(:===).with(argument).and_return(true)
|
224
235
|
expect(InlineSvg::IOResource).to receive(:read).with(argument)
|
225
236
|
expect(InlineSvg::AssetFile).to_not receive(:named)
|
226
|
-
helper.
|
237
|
+
helper.send(helper_method, argument)
|
227
238
|
end
|
228
239
|
it 'accept filename' do
|
229
240
|
expect(InlineSvg::IOResource).to receive(:===).with(argument).and_return(false)
|
230
241
|
expect(InlineSvg::IOResource).to_not receive(:read)
|
231
242
|
expect(InlineSvg::AssetFile).to receive(:named).with(argument)
|
232
|
-
helper.
|
243
|
+
helper.send(helper_method, argument)
|
233
244
|
end
|
234
245
|
end
|
235
246
|
context 'when passed IO object argument' do
|
@@ -239,17 +250,29 @@ SVG
|
|
239
250
|
it 'return valid svg' do
|
240
251
|
expect(InlineSvg::IOResource).to receive(:===).with(io_object).and_return(true)
|
241
252
|
expect(InlineSvg::IOResource).to receive(:read).with(io_object).and_return("<svg><!-- Test IO --></svg>")
|
242
|
-
output = helper.
|
253
|
+
output = helper.send(helper_method, io_object)
|
243
254
|
expect(output).to eq "<svg><!-- Test IO --></svg>\n"
|
244
255
|
expect(output).to be_html_safe
|
245
256
|
end
|
246
257
|
|
247
258
|
it 'return valid svg for file' do
|
248
|
-
output = helper.
|
259
|
+
output = helper.send(helper_method, File.new(file_path))
|
249
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"
|
250
261
|
expect(output).to be_html_safe
|
251
262
|
end
|
252
263
|
|
253
264
|
end
|
254
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
|
255
278
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: inline_svg
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.7.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- James Martin
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2020-12-07 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -129,16 +129,16 @@ executables: []
|
|
129
129
|
extensions: []
|
130
130
|
extra_rdoc_files: []
|
131
131
|
files:
|
132
|
+
- ".github/workflows/integration_test.yml"
|
133
|
+
- ".github/workflows/ruby.yml"
|
132
134
|
- ".gitignore"
|
133
135
|
- ".rubocop.yml"
|
134
136
|
- ".rubocop_todo.yml"
|
135
|
-
- ".travis.yml"
|
136
137
|
- CHANGELOG.md
|
137
138
|
- Gemfile
|
138
139
|
- LICENSE.txt
|
139
140
|
- README.md
|
140
141
|
- Rakefile
|
141
|
-
- circle.yml
|
142
142
|
- inline_svg.gemspec
|
143
143
|
- lib/inline_svg.rb
|
144
144
|
- lib/inline_svg/action_view/helpers.rb
|
@@ -200,7 +200,7 @@ homepage: https://github.com/jamesmartin/inline_svg
|
|
200
200
|
licenses:
|
201
201
|
- MIT
|
202
202
|
metadata: {}
|
203
|
-
post_install_message:
|
203
|
+
post_install_message:
|
204
204
|
rdoc_options: []
|
205
205
|
require_paths:
|
206
206
|
- lib
|
@@ -215,9 +215,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
215
215
|
- !ruby/object:Gem::Version
|
216
216
|
version: '0'
|
217
217
|
requirements: []
|
218
|
-
|
219
|
-
|
220
|
-
signing_key:
|
218
|
+
rubygems_version: 3.1.2
|
219
|
+
signing_key:
|
221
220
|
specification_version: 4
|
222
221
|
summary: Embeds an SVG document, inline.
|
223
222
|
test_files:
|
data/.travis.yml
DELETED
data/circle.yml
DELETED