inline_svg 1.5.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 +4 -4
- 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/CHANGELOG.md +73 -2
- data/README.md +34 -40
- data/lib/inline_svg/action_view/helpers.rb +36 -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/propshaft_asset_finder.rb +16 -0
- data/lib/inline_svg/railtie.rb +4 -7
- data/lib/inline_svg/static_asset_finder.rb +5 -2
- data/lib/inline_svg/transform_pipeline/transformations/view_box.rb +9 -0
- data/lib/inline_svg/transform_pipeline/transformations.rb +4 -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 +45 -4
- data/lib/inline_svg.rb +5 -0
- data/spec/finds_asset_paths_spec.rb +45 -0
- data/spec/helpers/inline_svg_spec.rb +68 -63
- data/spec/inline_svg_spec.rb +1 -1
- data/spec/propshaft_asset_finder_spec.rb +23 -0
- data/spec/static_asset_finder_spec.rb +25 -0
- data/spec/transformation_pipeline/transformations/view_box_spec.rb +13 -0
- data/spec/transformation_pipeline/transformations_spec.rb +2 -0
- data/spec/webpack_asset_finder_spec.rb +23 -0
- metadata +19 -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: 66214539304b60e87e9263afb26531212492ca77957e9ce8cf89d015cef86239
|
4
|
+
data.tar.gz: 6ab9cb3d75a9f268728600edb48bf27b3503145c80f1addabe8bc484c88af545
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1f8d4642dff97eb5bfc358fd1ce2257d5113a6f232c02f4ecd847007ee861b2537748539c689e5e2e67297951fdd158594740a754d49469cbd8c13c72002c290
|
7
|
+
data.tar.gz: 1b5cb2dfd5e7067d64ec0cc3449c2aeeead3a39cab42f8d51db33609a296478511fa9a24a965e32b10d7f01c98e5cb4b2ef8a6268fb055a7ad968068499eccd6
|
@@ -0,0 +1,47 @@
|
|
1
|
+
name: Integration Tests
|
2
|
+
|
3
|
+
on: [push]
|
4
|
+
|
5
|
+
jobs:
|
6
|
+
build:
|
7
|
+
runs-on: ubuntu-latest
|
8
|
+
strategy:
|
9
|
+
matrix:
|
10
|
+
test-branch: [rails5, rails6, rails7]
|
11
|
+
timeout-minutes: 20
|
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.7
|
22
|
+
uses: ruby/setup-ruby@v1
|
23
|
+
with:
|
24
|
+
ruby-version: 2.7.7
|
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: Test
|
45
|
+
run: |
|
46
|
+
cd $GITHUB_WORKSPACE/test_app
|
47
|
+
bundle exec rake test
|
@@ -0,0 +1,62 @@
|
|
1
|
+
name: Rails 6 Webpacker Integration Tests (unreliable)
|
2
|
+
|
3
|
+
on: [push]
|
4
|
+
|
5
|
+
jobs:
|
6
|
+
build:
|
7
|
+
|
8
|
+
runs-on: ubuntu-latest
|
9
|
+
strategy:
|
10
|
+
matrix:
|
11
|
+
test-branch: [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 3.1
|
22
|
+
uses: ruby/setup-ruby@v1
|
23
|
+
with:
|
24
|
+
ruby-version: 3.1
|
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 16.x
|
45
|
+
uses: actions/setup-node@v2
|
46
|
+
with:
|
47
|
+
node-version: 16
|
48
|
+
if: matrix.test-branch == 'rails6-webpacker'
|
49
|
+
- name: Set up Python 2.7
|
50
|
+
uses: actions/setup-python@v4
|
51
|
+
with:
|
52
|
+
python-version: '2.7'
|
53
|
+
- name: Generate Webpacker config
|
54
|
+
run: |
|
55
|
+
cd $GITHUB_WORKSPACE/test_app
|
56
|
+
CXXFLAGS="--std=c++17" yarn install --check-files
|
57
|
+
bundle exec rake webpacker:compile
|
58
|
+
if: matrix.test-branch == 'rails6-webpacker'
|
59
|
+
- name: Test
|
60
|
+
run: |
|
61
|
+
cd $GITHUB_WORKSPACE/test_app
|
62
|
+
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.7
|
13
|
+
uses: ruby/setup-ruby@v1
|
14
|
+
with:
|
15
|
+
ruby-version: 2.7.7
|
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,6 +3,67 @@ 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
|
+
|
7
|
+
Nothing.
|
8
|
+
|
9
|
+
## [1.10.0] - 2024-09-03
|
10
|
+
### Added
|
11
|
+
- Support for Shakapacker. [#158](https://github.com/jamesmartin/inline_svg/pull/158). Thanks, [@tagliala](https://github.com/tagliala)
|
12
|
+
|
13
|
+
### Fixed
|
14
|
+
- Fixed documentation typos. [#157](https://github.com/jamesmartin/inline_svg/pull/157). Thanks, [@tagliala](https://github.com/tagliala)
|
15
|
+
- Fixed missing ActiveSupport require. [#152](https://github.com/jamesmartin/inline_svg/pull/152). Thanks, [@xymbol](https://github.com/xymbol)
|
16
|
+
- Remove wrapping whitespace from SVG tags. [#150](https://github.com/jamesmartin/inline_svg/pull/150). Thanks, [@fredboyle](https://github.com/fredboyle)
|
17
|
+
|
18
|
+
## [1.9.0] - 2023-03-29
|
19
|
+
### Added
|
20
|
+
- A new option: `view_box` adds a `viewBox` attribute to the SVG. [#142](https://github.com/jamesmartin/inline_svg/pull/142). Thanks [@sunny](https://github.com/sunny)
|
21
|
+
|
22
|
+
### Fixed
|
23
|
+
- Allow Propshaft assets to use fallbacks. [#140](https://github.com/jamesmartin/inline_svg/pull/140). Thanks, [@ohrite](https://github.com/ohrite)
|
24
|
+
- Handling missing file when using static assets. [#141](https://github.com/jamesmartin/inline_svg/pull/141). Thanks, [@leighhalliday](https://github.com/leighhalliday)
|
25
|
+
- Handle missing file when using Webpacker assets.
|
26
|
+
|
27
|
+
## [1.8.0] - 2022-01-09
|
28
|
+
### Added
|
29
|
+
- Remove deprecation warning for `inline_svg`, as we intend to keep it in 2.0. [#131](https://github.com/jamesmartin/inline_svg/pull/131). Thanks [@DanielJackson-Oslo](https://github.com/DanielJackson-Oslo)
|
30
|
+
- Add support for Webpacker 6 beta. [#129](https://github.com/jamesmartin/inline_svg/pull/129). Thanks [@Intrepidd](https://github.com/Intrepidd) and [@tessi](https://github.com/tessi)
|
31
|
+
- Add support for Propshaft assets in Rails 7. [#134](https://github.com/jamesmartin/inline_svg/pull/134). Thanks, [@martinzamuner](https://github.com/martinzamuner)
|
32
|
+
|
33
|
+
## [1.7.2] - 2020-12-07
|
34
|
+
### Fixed
|
35
|
+
- Improve performance of `CachedAssetFile`. [#118](https://github.com/jamesmartin/inline_svg/pull/118). Thanks [@stevendaniels](https://github.com/stevendaniels)
|
36
|
+
- Avoid XSS by preventing malicious input of filenames. [#117](https://github.com/jamesmartin/inline_svg/pull/117). Thanks [@pbyrne](https://github.com/pbyrne).
|
37
|
+
|
38
|
+
## [1.7.1] - 2020-03-17
|
39
|
+
### Fixed
|
40
|
+
- 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)
|
41
|
+
|
42
|
+
## [1.7.0] - 2020-02-13
|
43
|
+
### Added
|
44
|
+
- 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)
|
45
|
+
|
46
|
+
### Fixed
|
47
|
+
- 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)
|
48
|
+
- 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)
|
49
|
+
|
50
|
+
## [1.6.0] - 2019-11-13
|
51
|
+
### Added
|
52
|
+
- Support Webpack via the new `inline_svg_pack_tag` helper and deprecate `inline_svg` helper in preparation for v2.0.
|
53
|
+
[#103](https://github.com/jamesmartin/inline_svg/pull/103)
|
54
|
+
Thanks, [@kylefox](https://github.com/kylefox)
|
55
|
+
|
56
|
+
## [1.5.2] - 2019-06-20
|
57
|
+
### Fixed
|
58
|
+
- Revert automatic Webpack asset finder behavior. Make Webpack "opt-in".
|
59
|
+
[#98](https://github.com/jamesmartin/inline_svg/issues/98)
|
60
|
+
|
61
|
+
## [1.5.1] - 2019-06-18
|
62
|
+
### Fixed
|
63
|
+
- Prevent nil asset finder when neither Sprockets or Webpacker are available
|
64
|
+
[#97](https://github.com/jamesmartin/inline_svg/issues/97)
|
65
|
+
|
66
|
+
## [1.5.0] - 2019-06-17
|
6
67
|
### Added
|
7
68
|
- Support for finding assets bundled by Webpacker
|
8
69
|
[#96](https://github.com/jamesmartin/inline_svg/pull/96)
|
@@ -160,7 +221,7 @@ transformations](https://github.com/jamesmartin/inline_svg/blob/master/README.md
|
|
160
221
|
|
161
222
|
## [0.5.1] - 2015-03-30
|
162
223
|
### Warning
|
163
|
-
** This version is NOT
|
224
|
+
** This version is NOT compatible with Sprockets >= 3. **
|
164
225
|
|
165
226
|
### Fixed
|
166
227
|
- Support for ActiveSupport (and hence, Rails) 4.2.x. Thanks, @jmarceli.
|
@@ -201,7 +262,17 @@ transformations](https://github.com/jamesmartin/inline_svg/blob/master/README.md
|
|
201
262
|
### Added
|
202
263
|
- Basic Railtie and view helper to inline SVG documents to Rails views.
|
203
264
|
|
204
|
-
[unreleased]: https://github.com/jamesmartin/inline_svg/compare/v1.
|
265
|
+
[unreleased]: https://github.com/jamesmartin/inline_svg/compare/v1.9.0...HEAD
|
266
|
+
[1.9.0]: https://github.com/jamesmartin/inline_svg/compare/v1.8.0...v1.9.0
|
267
|
+
[1.8.0]: https://github.com/jamesmartin/inline_svg/compare/v1.7.2...v1.8.0
|
268
|
+
[1.7.2]: https://github.com/jamesmartin/inline_svg/compare/v1.7.1...v1.7.2
|
269
|
+
[1.7.1]: https://github.com/jamesmartin/inline_svg/compare/v1.7.0...v1.7.1
|
270
|
+
[1.7.0]: https://github.com/jamesmartin/inline_svg/compare/v1.6.0...v1.7.0
|
271
|
+
[1.6.0]: https://github.com/jamesmartin/inline_svg/compare/v1.5.2...v1.6.0
|
272
|
+
[1.5.2]: https://github.com/jamesmartin/inline_svg/compare/v1.5.1...v1.5.2
|
273
|
+
[1.5.1]: https://github.com/jamesmartin/inline_svg/compare/v1.5.0...v1.5.1
|
274
|
+
[1.5.0]: https://github.com/jamesmartin/inline_svg/compare/v1.4.0...v1.5.0
|
275
|
+
[1.4.0]: https://github.com/jamesmartin/inline_svg/compare/v1.3.1...v1.4.0
|
205
276
|
[1.3.1]: https://github.com/jamesmartin/inline_svg/compare/v1.3.0...v1.3.1
|
206
277
|
[1.3.0]: https://github.com/jamesmartin/inline_svg/compare/v1.2.3...v1.3.0
|
207
278
|
[1.2.3]: https://github.com/jamesmartin/inline_svg/compare/v1.2.2...v1.2.3
|
data/README.md
CHANGED
@@ -1,15 +1,22 @@
|
|
1
1
|
# Inline SVG
|
2
2
|
|
3
|
-
|
3
|
+

|
4
|
+

|
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
|
-
Inline SVG supports
|
13
|
+
Inline SVG supports:
|
14
|
+
|
15
|
+
- [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))
|
16
|
+
- [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)).
|
17
|
+
- [Rails 7](https://weblog.rubyonrails.org/2021/12/6/Rails-7-0-rc-1-released/)
|
18
|
+
|
19
|
+
Inline SVG no longer officially supports Rails 3 or Rails 4 (although they may still work). In order to reduce the maintenance cost of this project we now follow the [Rails Maintenance Policy](https://guides.rubyonrails.org/maintenance_policy.html).
|
13
20
|
|
14
21
|
## Changelog
|
15
22
|
|
@@ -32,9 +39,15 @@ Or install it yourself as:
|
|
32
39
|
|
33
40
|
## Usage
|
34
41
|
|
42
|
+
```ruby
|
43
|
+
# Sprockets
|
44
|
+
inline_svg_tag(file_name, options={})
|
45
|
+
|
46
|
+
# Webpacker
|
47
|
+
inline_svg_pack_tag(file_name, options={})
|
35
48
|
```
|
36
|
-
|
37
|
-
|
49
|
+
|
50
|
+
_**Note:** The remainder of this README uses `inline_svg_tag` for examples, but the exact same principles work for `inline_svg_pack_tag`._
|
38
51
|
|
39
52
|
The `file_name` can be a full path to a file, the file's basename or an `IO`
|
40
53
|
object. The
|
@@ -52,7 +65,7 @@ Here's an example of embedding an SVG document and applying a 'class' attribute:
|
|
52
65
|
<body>
|
53
66
|
<h1>Embedded SVG Documents</h1>
|
54
67
|
<div>
|
55
|
-
<%=
|
68
|
+
<%= inline_svg_tag "some-document.svg", class: 'some-class' %>
|
56
69
|
</div>
|
57
70
|
</body>
|
58
71
|
</html>
|
@@ -84,13 +97,15 @@ key | description
|
|
84
97
|
`desc` | add a \<desc\> node inside the top level of the SVG document
|
85
98
|
`nocomment` | remove comment tags from the SVG document
|
86
99
|
`preserve_aspect_ratio` | adds a `preserveAspectRatio` attribute to the SVG
|
100
|
+
`view_box` | adds a `viewBox` attribute to the SVG
|
87
101
|
`aria` | adds common accessibility attributes to the SVG (see [PR #34](https://github.com/jamesmartin/inline_svg/pull/34#issue-152062674) for details)
|
88
102
|
`aria_hidden` | adds the `aria-hidden=true` attribute to the SVG
|
103
|
+
`fallback` | set fallback SVG document
|
89
104
|
|
90
105
|
Example:
|
91
106
|
|
92
107
|
```ruby
|
93
|
-
|
108
|
+
inline_svg_tag(
|
94
109
|
"some-document.svg",
|
95
110
|
id: 'some-id',
|
96
111
|
class: 'some-class',
|
@@ -100,14 +115,16 @@ inline_svg(
|
|
100
115
|
desc: 'Some description',
|
101
116
|
nocomment: true,
|
102
117
|
preserve_aspect_ratio: 'xMaxYMax meet',
|
118
|
+
view_box: '0 0 100 100',
|
103
119
|
aria: true,
|
104
|
-
aria_hidden: true
|
120
|
+
aria_hidden: true,
|
121
|
+
fallback: 'fallback-document.svg'
|
105
122
|
)
|
106
123
|
```
|
107
124
|
|
108
125
|
## Accessibility
|
109
126
|
|
110
|
-
Use the `aria: true` option to make `
|
127
|
+
Use the `aria: true` option to make `inline_svg_tag` add the following
|
111
128
|
accessibility (a11y) attributes to your embedded SVG:
|
112
129
|
|
113
130
|
* Adds a `role="img"` attribute to the root SVG element
|
@@ -118,7 +135,7 @@ Here's an example:
|
|
118
135
|
|
119
136
|
```erb
|
120
137
|
<%=
|
121
|
-
|
138
|
+
inline_svg_tag('iconmonstr-glasses-12-icon.svg',
|
122
139
|
aria: true, title: 'An SVG',
|
123
140
|
desc: 'This is my SVG. There are many like it. You get the picture')
|
124
141
|
%>
|
@@ -132,11 +149,11 @@ Here's an example:
|
|
132
149
|
</svg>
|
133
150
|
```
|
134
151
|
|
135
|
-
***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 `
|
152
|
+
***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.
|
136
153
|
|
137
154
|
## Custom Transformations
|
138
155
|
|
139
|
-
The transformation behavior of `
|
156
|
+
The transformation behavior of `inline_svg_tag` can be customized by creating custom transformation classes.
|
140
157
|
|
141
158
|
For example, inherit from `InlineSvg::CustomTransformation` and implement the `#transform` method:
|
142
159
|
|
@@ -165,7 +182,7 @@ end
|
|
165
182
|
The custom transformation can then be called like so:
|
166
183
|
```haml
|
167
184
|
%div
|
168
|
-
=
|
185
|
+
= inline_svg_tag "some-document.svg", my_custom_attribute: 'some value'
|
169
186
|
```
|
170
187
|
|
171
188
|
In this example, the following transformation would be applied to a SVG document:
|
@@ -186,8 +203,8 @@ end
|
|
186
203
|
The custom transformation will be triggered even if you don't pass any attribute value
|
187
204
|
```haml
|
188
205
|
%div
|
189
|
-
=
|
190
|
-
=
|
206
|
+
= inline_svg_tag "some-document.svg"
|
207
|
+
= inline_svg_tag "some-document.svg", my_custom_attribute: 'some value'
|
191
208
|
```
|
192
209
|
|
193
210
|
In this example, the following transformation would be applied to a SVG document:
|
@@ -267,7 +284,7 @@ end
|
|
267
284
|
|
268
285
|
**Note:** Paths are read recursively, so think about keeping your SVG assets
|
269
286
|
restricted to as few paths as possible, and using the filter option to further
|
270
|
-
restrict assets to only those likely to be used by `
|
287
|
+
restrict assets to only those likely to be used by `inline_svg_tag`.
|
271
288
|
|
272
289
|
## Missing SVG Files
|
273
290
|
|
@@ -294,7 +311,7 @@ Which would instead render:
|
|
294
311
|
<svg class='svg-not-found'><!-- SVG file not found: 'some-missing-file.svg' --></svg>
|
295
312
|
```
|
296
313
|
|
297
|
-
Alternatively, `
|
314
|
+
Alternatively, `inline_svg_tag` can be configured to raise an exception when a file
|
298
315
|
is not found:
|
299
316
|
|
300
317
|
```ruby
|
@@ -303,29 +320,6 @@ InlineSvg.configure do |config|
|
|
303
320
|
end
|
304
321
|
```
|
305
322
|
|
306
|
-
## Sprockets and Webpacker
|
307
|
-
|
308
|
-
Inline SVG supports SVGs bundled by either Sprockets or Webpacker, however, be
|
309
|
-
aware that the gem will *always* attempt to find SVGs using Sprockts if it is
|
310
|
-
enabled.
|
311
|
-
|
312
|
-
By default, Inline SVG will use Sprockets to find SVG files if it is enabled in
|
313
|
-
your Rails project.
|
314
|
-
|
315
|
-
If you have upgraded an older Rails project from Sprockets to Webpacker and you
|
316
|
-
no longer want to use Sprockets at all, you should disable the Asset Pipeline
|
317
|
-
and Inline SVG will use Webpacker automatically.
|
318
|
-
|
319
|
-
If you have both Sprockets *and* Webpacker enabled for some reason and you want
|
320
|
-
Inline SVG to use Webpacker to find SVGs then you should configure the
|
321
|
-
`asset_finder` appropriately:
|
322
|
-
|
323
|
-
```ruby
|
324
|
-
InlineSvg.configure do |config|
|
325
|
-
config.asset_finder = InlineSvg::WebpackAssetFinder
|
326
|
-
end
|
327
|
-
```
|
328
|
-
|
329
323
|
## Contributing
|
330
324
|
|
331
325
|
1. Fork it ( [http://github.com/jamesmartin/inline_svg/fork](http://github.com/jamesmartin/inline_svg/fork) )
|
@@ -4,7 +4,34 @@ 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
|
+
render_inline_svg(filename, transform_params)
|
21
|
+
end
|
22
|
+
|
23
|
+
private
|
24
|
+
|
25
|
+
def backwards_compatible_html_escape(filename)
|
26
|
+
# html_escape_once was introduced in newer versions of Rails.
|
27
|
+
if ERB::Util.respond_to?(:html_escape_once)
|
28
|
+
ERB::Util.html_escape_once(filename)
|
29
|
+
else
|
30
|
+
ERB::Util.html_escape(filename)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def render_inline_svg(filename, transform_params={})
|
8
35
|
begin
|
9
36
|
svg_file = read_svg(filename)
|
10
37
|
rescue InlineSvg::AssetFile::FileNotFound => error
|
@@ -23,8 +50,6 @@ module InlineSvg
|
|
23
50
|
InlineSvg::TransformPipeline.generate_html_from(svg_file, transform_params).html_safe
|
24
51
|
end
|
25
52
|
|
26
|
-
private
|
27
|
-
|
28
53
|
def read_svg(filename)
|
29
54
|
if InlineSvg::IOResource === filename
|
30
55
|
InlineSvg::IOResource.read filename
|
@@ -35,7 +60,7 @@ module InlineSvg
|
|
35
60
|
|
36
61
|
def placeholder(filename)
|
37
62
|
css_class = InlineSvg.configuration.svg_not_found_css_class
|
38
|
-
not_found_message = "'#{filename}' #{extension_hint(filename)}"
|
63
|
+
not_found_message = "'#{backwards_compatible_html_escape(filename)}' #{extension_hint(filename)}"
|
39
64
|
|
40
65
|
if css_class.nil?
|
41
66
|
return "<svg><!-- SVG file not found: #{not_found_message}--></svg>".html_safe
|
@@ -48,6 +73,14 @@ module InlineSvg
|
|
48
73
|
InlineSvg.configuration.asset_file
|
49
74
|
end
|
50
75
|
|
76
|
+
def with_asset_finder(asset_finder)
|
77
|
+
Thread.current[:inline_svg_asset_finder] = asset_finder
|
78
|
+
output = yield
|
79
|
+
Thread.current[:inline_svg_asset_finder] = nil
|
80
|
+
|
81
|
+
output
|
82
|
+
end
|
83
|
+
|
51
84
|
def extension_hint(filename)
|
52
85
|
filename.ends_with?(".svg") ? "" : "(Try adding .svg to your filename) "
|
53
86
|
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
|
@@ -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,16 +10,13 @@ module InlineSvg
|
|
10
10
|
|
11
11
|
config.after_initialize do |app|
|
12
12
|
InlineSvg.configure do |config|
|
13
|
-
#
|
14
|
-
# Sprockets::Environment instance
|
13
|
+
# Configure the asset_finder:
|
15
14
|
# Only set this when a user-configured asset finder has not been
|
16
15
|
# configured already.
|
17
16
|
if config.asset_finder.nil?
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
config.asset_finder = InlineSvg::WebpackAssetFinder
|
22
|
-
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)
|
23
20
|
end
|
24
21
|
end
|
25
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,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]
|
@@ -10,11 +10,12 @@ module InlineSvg::TransformPipeline::Transformations
|
|
10
10
|
class: { transform: ClassAttribute },
|
11
11
|
style: { transform: StyleAttribute },
|
12
12
|
data: { transform: DataAttributes },
|
13
|
-
height: { transform: Height },
|
14
13
|
nocomment: { transform: NoComment },
|
15
14
|
preserve_aspect_ratio: { transform: PreserveAspectRatio },
|
16
15
|
size: { transform: Size },
|
17
16
|
width: { transform: Width },
|
17
|
+
height: { transform: Height },
|
18
|
+
view_box: { transform: ViewBox },
|
18
19
|
}
|
19
20
|
end
|
20
21
|
|
@@ -83,8 +84,9 @@ require 'inline_svg/transform_pipeline/transformations/description'
|
|
83
84
|
require 'inline_svg/transform_pipeline/transformations/size'
|
84
85
|
require 'inline_svg/transform_pipeline/transformations/height'
|
85
86
|
require 'inline_svg/transform_pipeline/transformations/width'
|
87
|
+
require 'inline_svg/transform_pipeline/transformations/view_box'
|
86
88
|
require 'inline_svg/transform_pipeline/transformations/id_attribute'
|
87
89
|
require 'inline_svg/transform_pipeline/transformations/data_attributes'
|
88
90
|
require 'inline_svg/transform_pipeline/transformations/preserve_aspect_ratio'
|
89
91
|
require 'inline_svg/transform_pipeline/transformations/aria_attributes'
|
90
|
-
require "inline_svg/transform_pipeline/transformations/aria_hidden_attribute"
|
92
|
+
require "inline_svg/transform_pipeline/transformations/aria_hidden_attribute"
|
data/lib/inline_svg/version.rb
CHANGED
@@ -6,14 +6,55 @@ module InlineSvg
|
|
6
6
|
|
7
7
|
def initialize(filename)
|
8
8
|
@filename = filename
|
9
|
+
manifest_lookup = asset_helper.manifest.lookup(@filename)
|
10
|
+
@asset_path = manifest_lookup.present? ? URI(manifest_lookup).path : ""
|
9
11
|
end
|
10
12
|
|
11
13
|
def pathname
|
12
|
-
|
13
|
-
file_path = Webpacker.instance.manifest.lookup(@filename)
|
14
|
-
return unless public_path && file_path
|
14
|
+
return if @asset_path.blank?
|
15
15
|
|
16
|
-
|
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
|
17
58
|
end
|
18
59
|
end
|
19
60
|
end
|
data/lib/inline_svg.rb
CHANGED
@@ -3,12 +3,15 @@ require "inline_svg/action_view/helpers"
|
|
3
3
|
require "inline_svg/asset_file"
|
4
4
|
require "inline_svg/cached_asset_file"
|
5
5
|
require "inline_svg/finds_asset_paths"
|
6
|
+
require "inline_svg/propshaft_asset_finder"
|
6
7
|
require "inline_svg/static_asset_finder"
|
7
8
|
require "inline_svg/webpack_asset_finder"
|
8
9
|
require "inline_svg/transform_pipeline"
|
9
10
|
require "inline_svg/io_resource"
|
10
11
|
|
11
12
|
require "inline_svg/railtie" if defined?(Rails)
|
13
|
+
require 'active_support'
|
14
|
+
require 'active_support/core_ext/object/blank'
|
12
15
|
require 'active_support/core_ext/string'
|
13
16
|
require 'nokogiri'
|
14
17
|
|
@@ -41,6 +44,8 @@ module InlineSvg
|
|
41
44
|
def asset_finder=(finder)
|
42
45
|
@asset_finder = if finder.respond_to?(:find_asset)
|
43
46
|
finder
|
47
|
+
elsif finder.class.name == "Propshaft::Assembly"
|
48
|
+
InlineSvg::PropshaftAssetFinder
|
44
49
|
else
|
45
50
|
# fallback to a naive static asset finder
|
46
51
|
# (sprokects >= 3.0 && config.assets.precompile = false
|
@@ -45,4 +45,49 @@ describe InlineSvg::FindsAssetPaths do
|
|
45
45
|
expect(InlineSvg::FindsAssetPaths.by_filename('some-file')).to be_nil
|
46
46
|
end
|
47
47
|
end
|
48
|
+
|
49
|
+
context "when propshaft finder returns an object which supports only the pathname method" do
|
50
|
+
it "returns fully qualified file paths from Propshaft" do
|
51
|
+
propshaft = double('PropshaftDouble')
|
52
|
+
|
53
|
+
expect(propshaft).to receive(:find_asset).with('some-file').
|
54
|
+
and_return(double(pathname: Pathname('/full/path/to/some-file')))
|
55
|
+
|
56
|
+
InlineSvg.configure do |config|
|
57
|
+
config.asset_finder = propshaft
|
58
|
+
end
|
59
|
+
|
60
|
+
expect(InlineSvg::FindsAssetPaths.by_filename('some-file')).to eq Pathname('/full/path/to/some-file')
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
context "when webpack finder returns an object with a relative asset path" do
|
65
|
+
it "returns the fully qualified file path" do
|
66
|
+
webpacker = double('WebpackerDouble')
|
67
|
+
|
68
|
+
expect(webpacker).to receive(:find_asset).with('some-file').
|
69
|
+
and_return(double(filename: Pathname('/full/path/to/some-file')))
|
70
|
+
|
71
|
+
InlineSvg.configure do |config|
|
72
|
+
config.asset_finder = webpacker
|
73
|
+
end
|
74
|
+
|
75
|
+
expect(InlineSvg::FindsAssetPaths.by_filename('some-file')).to eq Pathname('/full/path/to/some-file')
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
context "when webpack finder returns an object with an absolute http asset path" do
|
80
|
+
it "returns the fully qualified file path" do
|
81
|
+
webpacker = double('WebpackerDouble')
|
82
|
+
|
83
|
+
expect(webpacker).to receive(:find_asset).with('some-file').
|
84
|
+
and_return(double(filename: Pathname('https://my-fancy-domain.test/full/path/to/some-file')))
|
85
|
+
|
86
|
+
InlineSvg.configure do |config|
|
87
|
+
config.asset_finder = webpacker
|
88
|
+
end
|
89
|
+
|
90
|
+
expect(InlineSvg::FindsAssetPaths.by_filename('some-file')).to eq Pathname('https://my-fancy-domain.test/full/path/to/some-file')
|
91
|
+
end
|
92
|
+
end
|
48
93
|
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
|
@@ -75,11 +86,9 @@ describe InlineSvg::ActionView::Helpers do
|
|
75
86
|
with('missing.svg').
|
76
87
|
and_raise(InlineSvg::AssetFile::FileNotFound.new)
|
77
88
|
|
78
|
-
fallback_file =
|
79
|
-
<svg xmlns="http://www.w3.org/2000/svg" xml:lang="en"><!-- This is a comment --></svg>
|
80
|
-
SVG
|
89
|
+
fallback_file = '<svg xmlns="http://www.w3.org/2000/svg" xml:lang="en"><!-- This is a comment --></svg>'
|
81
90
|
allow(InlineSvg::AssetFile).to receive(:named).with('fallback.svg').and_return(fallback_file)
|
82
|
-
expect(helper.
|
91
|
+
expect(helper.send(helper_method, 'missing.svg', fallback: 'fallback.svg')).to eq fallback_file
|
83
92
|
end
|
84
93
|
end
|
85
94
|
end
|
@@ -88,76 +97,54 @@ SVG
|
|
88
97
|
|
89
98
|
context "and no options" do
|
90
99
|
it "returns a html safe version of the file's contents" do
|
91
|
-
example_file =
|
92
|
-
<svg xmlns="http://www.w3.org/2000/svg" xml:lang="en"><!-- This is a comment --></svg>
|
93
|
-
SVG
|
100
|
+
example_file = '<svg xmlns="http://www.w3.org/2000/svg" xml:lang="en"><!-- This is a comment --></svg>'
|
94
101
|
allow(InlineSvg::AssetFile).to receive(:named).with('some-file').and_return(example_file)
|
95
|
-
expect(helper.
|
102
|
+
expect(helper.send(helper_method, 'some-file')).to eq example_file
|
96
103
|
end
|
97
104
|
end
|
98
105
|
|
99
106
|
context "and the 'title' option" do
|
100
107
|
it "adds the title node to the SVG output" do
|
101
|
-
input_svg =
|
102
|
-
<svg xmlns="http://www.w3.org/2000/svg" role="presentation" xml:lang="en"></svg>
|
103
|
-
SVG
|
104
|
-
expected_output = <<-SVG
|
105
|
-
<svg xmlns="http://www.w3.org/2000/svg" role="presentation" xml:lang="en"><title>A title</title></svg>
|
106
|
-
SVG
|
108
|
+
input_svg = '<svg xmlns="http://www.w3.org/2000/svg" role="presentation" xml:lang="en"></svg>'
|
109
|
+
expected_output = '<svg xmlns="http://www.w3.org/2000/svg" role="presentation" xml:lang="en"><title>A title</title></svg>'
|
107
110
|
allow(InlineSvg::AssetFile).to receive(:named).with('some-file').and_return(input_svg)
|
108
|
-
expect(helper.
|
111
|
+
expect(helper.send(helper_method, 'some-file', title: 'A title')).to eq expected_output
|
109
112
|
end
|
110
113
|
end
|
111
114
|
|
112
115
|
context "and the 'desc' option" do
|
113
116
|
it "adds the description node to the SVG output" do
|
114
|
-
input_svg =
|
115
|
-
<svg xmlns="http://www.w3.org/2000/svg" role="presentation" xml:lang="en"></svg>
|
116
|
-
SVG
|
117
|
-
expected_output = <<-SVG
|
118
|
-
<svg xmlns="http://www.w3.org/2000/svg" role="presentation" xml:lang="en"><desc>A description</desc></svg>
|
119
|
-
SVG
|
117
|
+
input_svg = '<svg xmlns="http://www.w3.org/2000/svg" role="presentation" xml:lang="en"></svg>'
|
118
|
+
expected_output = '<svg xmlns="http://www.w3.org/2000/svg" role="presentation" xml:lang="en"><desc>A description</desc></svg>'
|
120
119
|
allow(InlineSvg::AssetFile).to receive(:named).with('some-file').and_return(input_svg)
|
121
|
-
expect(helper.
|
120
|
+
expect(helper.send(helper_method, 'some-file', desc: 'A description')).to eq expected_output
|
122
121
|
end
|
123
122
|
end
|
124
123
|
|
125
124
|
context "and the 'nocomment' option" do
|
126
125
|
it "strips comments and other unknown/unsafe nodes from the output" do
|
127
|
-
input_svg =
|
128
|
-
<svg xmlns="http://www.w3.org/2000/svg" xml:lang="en"
|
129
|
-
SVG
|
130
|
-
expected_output = <<-SVG
|
131
|
-
<svg xmlns="http://www.w3.org/2000/svg" xml:lang="en"></svg>
|
132
|
-
SVG
|
126
|
+
input_svg = '<svg xmlns="http://www.w3.org/2000/svg" xml:lang="en"><!-- This is a comment --></svg>'
|
127
|
+
expected_output = '<svg xmlns="http://www.w3.org/2000/svg" xml:lang="en"></svg>'
|
133
128
|
allow(InlineSvg::AssetFile).to receive(:named).with('some-file').and_return(input_svg)
|
134
|
-
expect(helper.
|
129
|
+
expect(helper.send(helper_method, 'some-file', nocomment: true)).to eq expected_output
|
135
130
|
end
|
136
131
|
end
|
137
132
|
|
138
133
|
context "and the 'aria_hidden' option" do
|
139
134
|
it "sets 'aria-hidden=true' in the output" do
|
140
|
-
input_svg =
|
141
|
-
<svg xmlns="http://www.w3.org/2000/svg" xml:lang="en"></svg>
|
142
|
-
SVG
|
143
|
-
expected_output = <<-SVG
|
144
|
-
<svg xmlns="http://www.w3.org/2000/svg" xml:lang="en" aria-hidden="true"></svg>
|
145
|
-
SVG
|
135
|
+
input_svg = '<svg xmlns="http://www.w3.org/2000/svg" xml:lang="en"></svg>'
|
136
|
+
expected_output = '<svg xmlns="http://www.w3.org/2000/svg" xml:lang="en" aria-hidden="true"></svg>'
|
146
137
|
allow(InlineSvg::AssetFile).to receive(:named).with('some-file').and_return(input_svg)
|
147
|
-
expect(helper.
|
138
|
+
expect(helper.send(helper_method, 'some-file', aria_hidden: true)).to eq expected_output
|
148
139
|
end
|
149
140
|
end
|
150
141
|
|
151
142
|
context "and all options" do
|
152
143
|
it "applies all expected transformations to the output" do
|
153
|
-
input_svg =
|
154
|
-
<svg xmlns="http://www.w3.org/2000/svg" xml:lang="en"
|
155
|
-
SVG
|
156
|
-
expected_output = <<-SVG
|
157
|
-
<svg xmlns="http://www.w3.org/2000/svg" xml:lang="en"><title>A title</title><desc>A description</desc></svg>
|
158
|
-
SVG
|
144
|
+
input_svg = '<svg xmlns="http://www.w3.org/2000/svg" xml:lang="en"><!-- This is a comment --></svg>'
|
145
|
+
expected_output = '<svg xmlns="http://www.w3.org/2000/svg" xml:lang="en"><title>A title</title><desc>A description</desc></svg>'
|
159
146
|
allow(InlineSvg::AssetFile).to receive(:named).with('some-file').and_return(input_svg)
|
160
|
-
expect(helper.
|
147
|
+
expect(helper.send(helper_method, 'some-file', title: 'A title', desc: 'A description', nocomment: true)).to eq expected_output
|
161
148
|
end
|
162
149
|
end
|
163
150
|
|
@@ -173,14 +160,10 @@ SVG
|
|
173
160
|
end
|
174
161
|
|
175
162
|
it "applies custm transformations to the output" do
|
176
|
-
input_svg =
|
177
|
-
<svg></svg>
|
178
|
-
SVG
|
179
|
-
expected_output = <<-SVG
|
180
|
-
<svg custom="some value"></svg>
|
181
|
-
SVG
|
163
|
+
input_svg = '<svg></svg>'
|
164
|
+
expected_output = '<svg custom="some value"></svg>'
|
182
165
|
allow(InlineSvg::AssetFile).to receive(:named).with('some-file').and_return(input_svg)
|
183
|
-
expect(helper.
|
166
|
+
expect(helper.send(helper_method, 'some-file', custom: 'some value')).to eq expected_output
|
184
167
|
end
|
185
168
|
end
|
186
169
|
|
@@ -201,7 +184,7 @@ SVG
|
|
201
184
|
|
202
185
|
allow(InlineSvg::AssetFile).to receive(:named).with('some-file').and_return(input_svg)
|
203
186
|
|
204
|
-
expect(helper.
|
187
|
+
expect(helper.send(helper_method, 'some-file')).to eq "<svg custom=\"default value\"></svg>"
|
205
188
|
end
|
206
189
|
end
|
207
190
|
|
@@ -211,7 +194,7 @@ SVG
|
|
211
194
|
|
212
195
|
allow(InlineSvg::AssetFile).to receive(:named).with('some-file').and_return(input_svg)
|
213
196
|
|
214
|
-
expect(helper.
|
197
|
+
expect(helper.send(helper_method, 'some-file', custom: 'some value')).to eq "<svg custom=\"some value\"></svg>"
|
215
198
|
end
|
216
199
|
end
|
217
200
|
end
|
@@ -223,13 +206,13 @@ SVG
|
|
223
206
|
expect(InlineSvg::IOResource).to receive(:===).with(argument).and_return(true)
|
224
207
|
expect(InlineSvg::IOResource).to receive(:read).with(argument)
|
225
208
|
expect(InlineSvg::AssetFile).to_not receive(:named)
|
226
|
-
helper.
|
209
|
+
helper.send(helper_method, argument)
|
227
210
|
end
|
228
211
|
it 'accept filename' do
|
229
212
|
expect(InlineSvg::IOResource).to receive(:===).with(argument).and_return(false)
|
230
213
|
expect(InlineSvg::IOResource).to_not receive(:read)
|
231
214
|
expect(InlineSvg::AssetFile).to receive(:named).with(argument)
|
232
|
-
helper.
|
215
|
+
helper.send(helper_method, argument)
|
233
216
|
end
|
234
217
|
end
|
235
218
|
context 'when passed IO object argument' do
|
@@ -239,17 +222,39 @@ SVG
|
|
239
222
|
it 'return valid svg' do
|
240
223
|
expect(InlineSvg::IOResource).to receive(:===).with(io_object).and_return(true)
|
241
224
|
expect(InlineSvg::IOResource).to receive(:read).with(io_object).and_return("<svg><!-- Test IO --></svg>")
|
242
|
-
output = helper.
|
243
|
-
expect(output).to eq "<svg><!-- Test IO --></svg
|
225
|
+
output = helper.send(helper_method, io_object)
|
226
|
+
expect(output).to eq "<svg><!-- Test IO --></svg>"
|
244
227
|
expect(output).to be_html_safe
|
245
228
|
end
|
246
229
|
|
247
230
|
it 'return valid svg for file' do
|
248
|
-
output = helper.
|
249
|
-
expect(output).to eq "<svg xmlns=\"http://www.w3.org/2000/svg\" xml:lang=\"en\" role=\"presentation\"><!-- This is a test comment --></svg
|
231
|
+
output = helper.send(helper_method, File.new(file_path))
|
232
|
+
expect(output).to eq "<svg xmlns=\"http://www.w3.org/2000/svg\" xml:lang=\"en\" role=\"presentation\"><!-- This is a test comment --></svg>"
|
250
233
|
expect(output).to be_html_safe
|
251
234
|
end
|
252
235
|
|
253
236
|
end
|
237
|
+
|
238
|
+
context 'default output' do
|
239
|
+
it "returns an SVG tag without any pre or post whitespace characters" do
|
240
|
+
input_svg = '<svg></svg>'
|
241
|
+
|
242
|
+
allow(InlineSvg::AssetFile).to receive(:named).with('some-file').and_return(input_svg)
|
243
|
+
|
244
|
+
expect(helper.send(helper_method, 'some-file')).to eq "<svg></svg>"
|
245
|
+
end
|
246
|
+
end
|
247
|
+
end
|
248
|
+
|
249
|
+
describe '#inline_svg' do
|
250
|
+
it_behaves_like "inline_svg helper", helper_method: :inline_svg
|
251
|
+
end
|
252
|
+
|
253
|
+
describe '#inline_svg_tag' do
|
254
|
+
it_behaves_like "inline_svg helper", helper_method: :inline_svg_tag
|
255
|
+
end
|
256
|
+
|
257
|
+
describe '#inline_svg_tag' do
|
258
|
+
it_behaves_like "inline_svg helper", helper_method: :inline_svg_pack_tag
|
254
259
|
end
|
255
260
|
end
|
data/spec/inline_svg_spec.rb
CHANGED
@@ -47,7 +47,7 @@ describe InlineSvg do
|
|
47
47
|
end
|
48
48
|
|
49
49
|
context "configuring a custom asset file" do
|
50
|
-
it "falls back to the built-in asset file implementation by
|
50
|
+
it "falls back to the built-in asset file implementation by default" do
|
51
51
|
expect(InlineSvg.configuration.asset_file).to eq(InlineSvg::AssetFile)
|
52
52
|
end
|
53
53
|
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require_relative '../lib/inline_svg'
|
2
|
+
|
3
|
+
describe InlineSvg::PropshaftAssetFinder do
|
4
|
+
context "when the file is not found" do
|
5
|
+
it "returns nil" do
|
6
|
+
stub_const('Rails', double('Rails').as_null_object)
|
7
|
+
expect(::Rails.application.assets.load_path).to receive(:find).with('some-file').and_return(nil)
|
8
|
+
|
9
|
+
expect(InlineSvg::PropshaftAssetFinder.find_asset('some-file').pathname).to be_nil
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
context "when the file is found" do
|
14
|
+
it "returns fully qualified file paths from Propshaft" do
|
15
|
+
stub_const('Rails', double('Rails').as_null_object)
|
16
|
+
asset = double('Asset')
|
17
|
+
expect(asset).to receive(:path).and_return(Pathname.new('/full/path/to/some-file'))
|
18
|
+
expect(::Rails.application.assets.load_path).to receive(:find).with('some-file').and_return(asset)
|
19
|
+
|
20
|
+
expect(InlineSvg::PropshaftAssetFinder.find_asset('some-file').pathname).to eq Pathname('/full/path/to/some-file')
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
require_relative '../lib/inline_svg'
|
2
|
+
|
3
|
+
describe InlineSvg::StaticAssetFinder do
|
4
|
+
context "when the file is not found" do
|
5
|
+
it "returns nil" do
|
6
|
+
stub_const('Rails', double('Rails').as_null_object)
|
7
|
+
expect(::Rails.application.config.assets).to receive(:compile).and_return(true)
|
8
|
+
|
9
|
+
expect(described_class.find_asset('some-file').pathname).to be_nil
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
context "when the file is found" do
|
14
|
+
it "returns fully qualified file path from Sprockets" do
|
15
|
+
stub_const('Rails', double('Rails').as_null_object)
|
16
|
+
expect(::Rails.application.config.assets).to receive(:compile).and_return(true)
|
17
|
+
pathname = Pathname.new('/full/path/to/some-file')
|
18
|
+
asset = double('Asset')
|
19
|
+
expect(asset).to receive(:filename).and_return(pathname)
|
20
|
+
expect(::Rails.application.assets).to receive(:[]).with('some-file').and_return(asset)
|
21
|
+
|
22
|
+
expect(described_class.find_asset('some-file').pathname).to eq(pathname)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
require 'inline_svg/transform_pipeline'
|
2
|
+
|
3
|
+
describe InlineSvg::TransformPipeline::Transformations::ViewBox do
|
4
|
+
it "adds viewBox attribute to a SVG document" do
|
5
|
+
document = Nokogiri::XML::Document.parse('<svg>Some document</svg>')
|
6
|
+
transformation =
|
7
|
+
InlineSvg::TransformPipeline::Transformations::ViewBox
|
8
|
+
.create_with_value("0 0 100 100")
|
9
|
+
expect(transformation.transform(document).to_html).to eq(
|
10
|
+
"<svg viewBox=\"0 0 100 100\">Some document</svg>\n"
|
11
|
+
)
|
12
|
+
end
|
13
|
+
end
|
@@ -21,6 +21,7 @@ describe InlineSvg::TransformPipeline::Transformations do
|
|
21
21
|
size: 'irrelevant',
|
22
22
|
height: 'irrelevant',
|
23
23
|
width: 'irrelevant',
|
24
|
+
view_box: 'irrelevant',
|
24
25
|
id: 'irrelevant',
|
25
26
|
data: 'irrelevant',
|
26
27
|
preserve_aspect_ratio: 'irrelevant',
|
@@ -37,6 +38,7 @@ describe InlineSvg::TransformPipeline::Transformations do
|
|
37
38
|
InlineSvg::TransformPipeline::Transformations::Size,
|
38
39
|
InlineSvg::TransformPipeline::Transformations::Height,
|
39
40
|
InlineSvg::TransformPipeline::Transformations::Width,
|
41
|
+
InlineSvg::TransformPipeline::Transformations::ViewBox,
|
40
42
|
InlineSvg::TransformPipeline::Transformations::IdAttribute,
|
41
43
|
InlineSvg::TransformPipeline::Transformations::DataAttributes,
|
42
44
|
InlineSvg::TransformPipeline::Transformations::PreserveAspectRatio,
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require_relative '../lib/inline_svg'
|
2
|
+
|
3
|
+
describe InlineSvg::WebpackAssetFinder do
|
4
|
+
context "when the file is not found" do
|
5
|
+
it "returns nil" do
|
6
|
+
stub_const('Rails', double('Rails').as_null_object)
|
7
|
+
stub_const('Webpacker', double('Webpacker').as_null_object)
|
8
|
+
expect(::Webpacker.manifest).to receive(:lookup).with('some-file').and_return(nil)
|
9
|
+
|
10
|
+
expect(described_class.find_asset('some-file').pathname).to be_nil
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
context "when Shakapacker is defined" do
|
15
|
+
it "uses the new spelling" do
|
16
|
+
stub_const('Rails', double('Rails').as_null_object)
|
17
|
+
stub_const('Shakapacker', double('Shakapacker').as_null_object)
|
18
|
+
expect(::Shakapacker.manifest).to receive(:lookup).with('some-file').and_return(nil)
|
19
|
+
|
20
|
+
expect(described_class.find_asset('some-file').pathname).to be_nil
|
21
|
+
end
|
22
|
+
end
|
23
|
+
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.10.0
|
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: 2024-09-03 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -129,16 +129,17 @@ executables: []
|
|
129
129
|
extensions: []
|
130
130
|
extra_rdoc_files: []
|
131
131
|
files:
|
132
|
+
- ".github/workflows/integration_test.yml"
|
133
|
+
- ".github/workflows/rails_6_webpacker_integration_tests.yaml"
|
134
|
+
- ".github/workflows/ruby.yml"
|
132
135
|
- ".gitignore"
|
133
136
|
- ".rubocop.yml"
|
134
137
|
- ".rubocop_todo.yml"
|
135
|
-
- ".travis.yml"
|
136
138
|
- CHANGELOG.md
|
137
139
|
- Gemfile
|
138
140
|
- LICENSE.txt
|
139
141
|
- README.md
|
140
142
|
- Rakefile
|
141
|
-
- circle.yml
|
142
143
|
- inline_svg.gemspec
|
143
144
|
- lib/inline_svg.rb
|
144
145
|
- lib/inline_svg/action_view/helpers.rb
|
@@ -147,6 +148,7 @@ files:
|
|
147
148
|
- lib/inline_svg/finds_asset_paths.rb
|
148
149
|
- lib/inline_svg/id_generator.rb
|
149
150
|
- lib/inline_svg/io_resource.rb
|
151
|
+
- lib/inline_svg/propshaft_asset_finder.rb
|
150
152
|
- lib/inline_svg/railtie.rb
|
151
153
|
- lib/inline_svg/static_asset_finder.rb
|
152
154
|
- lib/inline_svg/transform_pipeline.rb
|
@@ -165,6 +167,7 @@ files:
|
|
165
167
|
- lib/inline_svg/transform_pipeline/transformations/style_attribute.rb
|
166
168
|
- lib/inline_svg/transform_pipeline/transformations/title.rb
|
167
169
|
- lib/inline_svg/transform_pipeline/transformations/transformation.rb
|
170
|
+
- lib/inline_svg/transform_pipeline/transformations/view_box.rb
|
168
171
|
- lib/inline_svg/transform_pipeline/transformations/width.rb
|
169
172
|
- lib/inline_svg/version.rb
|
170
173
|
- lib/inline_svg/webpack_asset_finder.rb
|
@@ -182,6 +185,8 @@ files:
|
|
182
185
|
- spec/id_generator_spec.rb
|
183
186
|
- spec/inline_svg_spec.rb
|
184
187
|
- spec/io_resource_spec.rb
|
188
|
+
- spec/propshaft_asset_finder_spec.rb
|
189
|
+
- spec/static_asset_finder_spec.rb
|
185
190
|
- spec/transformation_pipeline/transformations/aria_attributes_spec.rb
|
186
191
|
- spec/transformation_pipeline/transformations/aria_hidden_attribute_spec.rb
|
187
192
|
- spec/transformation_pipeline/transformations/class_attribute_spec.rb
|
@@ -194,13 +199,15 @@ files:
|
|
194
199
|
- spec/transformation_pipeline/transformations/style_attribute_spec.rb
|
195
200
|
- spec/transformation_pipeline/transformations/title_spec.rb
|
196
201
|
- spec/transformation_pipeline/transformations/transformation_spec.rb
|
202
|
+
- spec/transformation_pipeline/transformations/view_box_spec.rb
|
197
203
|
- spec/transformation_pipeline/transformations/width_spec.rb
|
198
204
|
- spec/transformation_pipeline/transformations_spec.rb
|
205
|
+
- spec/webpack_asset_finder_spec.rb
|
199
206
|
homepage: https://github.com/jamesmartin/inline_svg
|
200
207
|
licenses:
|
201
208
|
- MIT
|
202
209
|
metadata: {}
|
203
|
-
post_install_message:
|
210
|
+
post_install_message:
|
204
211
|
rdoc_options: []
|
205
212
|
require_paths:
|
206
213
|
- lib
|
@@ -215,9 +222,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
215
222
|
- !ruby/object:Gem::Version
|
216
223
|
version: '0'
|
217
224
|
requirements: []
|
218
|
-
|
219
|
-
|
220
|
-
signing_key:
|
225
|
+
rubygems_version: 3.1.6
|
226
|
+
signing_key:
|
221
227
|
specification_version: 4
|
222
228
|
summary: Embeds an SVG document, inline.
|
223
229
|
test_files:
|
@@ -235,6 +241,8 @@ test_files:
|
|
235
241
|
- spec/id_generator_spec.rb
|
236
242
|
- spec/inline_svg_spec.rb
|
237
243
|
- spec/io_resource_spec.rb
|
244
|
+
- spec/propshaft_asset_finder_spec.rb
|
245
|
+
- spec/static_asset_finder_spec.rb
|
238
246
|
- spec/transformation_pipeline/transformations/aria_attributes_spec.rb
|
239
247
|
- spec/transformation_pipeline/transformations/aria_hidden_attribute_spec.rb
|
240
248
|
- spec/transformation_pipeline/transformations/class_attribute_spec.rb
|
@@ -247,5 +255,7 @@ test_files:
|
|
247
255
|
- spec/transformation_pipeline/transformations/style_attribute_spec.rb
|
248
256
|
- spec/transformation_pipeline/transformations/title_spec.rb
|
249
257
|
- spec/transformation_pipeline/transformations/transformation_spec.rb
|
258
|
+
- spec/transformation_pipeline/transformations/view_box_spec.rb
|
250
259
|
- spec/transformation_pipeline/transformations/width_spec.rb
|
251
260
|
- spec/transformation_pipeline/transformations_spec.rb
|
261
|
+
- spec/webpack_asset_finder_spec.rb
|
data/.travis.yml
DELETED
data/circle.yml
DELETED