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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: c7e8c4d03d15f0fdd876912e329fca61646c3dc917c3745a0f862dde2490ea2e
4
- data.tar.gz: 606861334da0b46952d84ea19b3779405e26f411cedad03bf9dbe1973e387b3a
3
+ metadata.gz: 66214539304b60e87e9263afb26531212492ca77957e9ce8cf89d015cef86239
4
+ data.tar.gz: 6ab9cb3d75a9f268728600edb48bf27b3503145c80f1addabe8bc484c88af545
5
5
  SHA512:
6
- metadata.gz: 05bb315a0a78041729e04f1860b0399e38acfcdec6729b49646b52c2a532721484b23ec6f005ade488570e057987f0761eee31d9fca541a09c712e073a4ae2c6
7
- data.tar.gz: 0da8510891479fd88bf32e6f4a46fe001c861b64fba136609e5756b893fb86d4ebaaef40c048b132a745c954d9ddcb7f938ba218d7d94277ee61140b6d5529f6
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 comaptible with Sprockets >= 3. **
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.3.1...HEAD
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
- [![Build Status](https://travis-ci.org/jamesmartin/inline_svg.svg?branch=master)](https://travis-ci.org/jamesmartin/inline_svg)
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 a Rails helper method (`inline_svg`) that reads 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
+ 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 [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)), [Rails 4](http://weblog.rubyonrails.org/2013/6/25/Rails-4-0-final/) and [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)).
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
- inline_svg(file_name, options={})
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
- <%= inline_svg "some-document.svg", class: 'some-class' %>
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
- inline_svg(
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 `inline_svg` add the following
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
- inline_svg('iconmonstr-glasses-12-icon.svg',
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 `inline_svg` embedding elements inside the SVG with `id` attributes that clash with other elements elsewhere on the page.
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 `inline_svg` can be customized by creating custom transformation classes.
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
- = inline_svg "some-document.svg", my_custom_attribute: 'some value'
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
- = inline_svg "some-document.svg"
190
- = inline_svg "some-document.svg", my_custom_attribute: 'some value'
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 `inline_svg`.
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, `inline_svg` can be configured to raise an exception when a file
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
- match = all_keys_matching(asset_name).sort do |a, b|
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
@@ -6,7 +6,7 @@ module InlineSvg
6
6
  end
7
7
 
8
8
  def self.configured_asset_finder
9
- InlineSvg.configuration.asset_finder
9
+ Thread.current[:inline_svg_asset_finder] || InlineSvg.configuration.asset_finder
10
10
  end
11
11
  end
12
12
  end
@@ -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
@@ -10,16 +10,13 @@ module InlineSvg
10
10
 
11
11
  config.after_initialize do |app|
12
12
  InlineSvg.configure do |config|
13
- # In default Rails apps, this will be a fully operational
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
- if assets = app.instance_variable_get(:@assets)
19
- config.asset_finder = assets
20
- elsif defined?(Webpacker)
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/AbleHealth/inline_svg/commit/661bbb3bef7d1b4bd6ccd63f5f018305797b9509
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].pathname
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]
@@ -0,0 +1,9 @@
1
+ module InlineSvg::TransformPipeline::Transformations
2
+ class ViewBox < Transformation
3
+ def transform(doc)
4
+ with_svg(doc) do |svg|
5
+ svg["viewBox"] = value
6
+ end
7
+ end
8
+ end
9
+ end
@@ -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"
@@ -4,7 +4,7 @@ module InlineSvg
4
4
  document = Nokogiri::XML::Document.parse(svg_file)
5
5
  Transformations.lookup(transform_params).reduce(document) do |doc, transformer|
6
6
  transformer.transform(doc)
7
- end.to_html
7
+ end.to_html.strip
8
8
  end
9
9
  end
10
10
  end
@@ -1,3 +1,3 @@
1
1
  module InlineSvg
2
- VERSION = "1.5.0"
2
+ VERSION = "1.10.0"
3
3
  end
@@ -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
- public_path = Webpacker.config.public_path
13
- file_path = Webpacker.instance.manifest.lookup(@filename)
14
- return unless public_path && file_path
14
+ return if @asset_path.blank?
15
15
 
16
- File.join(public_path, file_path)
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
- describe "#inline_svg" do
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.inline_svg('some-missing-file.svg')
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.inline_svg('some-missing-file.svg')
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: '--&gt;&lt;/svg&gt;&lt;script&gt;alert(1)&lt;/script&gt;&lt;svg&gt;.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.inline_svg('missing-file-with-no-extension')
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.inline_svg('some-other-missing-file.svg')
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 = <<-SVG
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.inline_svg('missing.svg', fallback: 'fallback.svg')).to eq fallback_file
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 = <<-SVG
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.inline_svg('some-file')).to eq example_file
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 = <<-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.inline_svg('some-file', title: 'A title')).to eq expected_output
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 = <<-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.inline_svg('some-file', desc: 'A description')).to eq expected_output
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 = <<-SVG
128
- <svg xmlns="http://www.w3.org/2000/svg" xml:lang="en"><!-- This is a comment --></svg>
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.inline_svg('some-file', nocomment: true)).to eq expected_output
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 = <<-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.inline_svg('some-file', aria_hidden: true)).to eq expected_output
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 = <<-SVG
154
- <svg xmlns="http://www.w3.org/2000/svg" xml:lang="en"><!-- This is a comment --></svg>
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.inline_svg('some-file', title: 'A title', desc: 'A description', nocomment: true)).to eq expected_output
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 = <<-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.inline_svg('some-file', custom: 'some value')).to eq expected_output
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.inline_svg('some-file')).to eq "<svg custom=\"default value\"></svg>\n"
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.inline_svg('some-file', custom: 'some value')).to eq "<svg custom=\"some value\"></svg>\n"
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.inline_svg(argument)
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.inline_svg(argument)
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.inline_svg(io_object)
243
- expect(output).to eq "<svg><!-- Test IO --></svg>\n"
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.inline_svg(File.new(file_path))
249
- expect(output).to eq "<svg xmlns=\"http://www.w3.org/2000/svg\" xml:lang=\"en\" role=\"presentation\"><!-- This is a test comment --></svg>\n"
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
@@ -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 deafult" do
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.5.0
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: 2019-06-16 00:00:00.000000000 Z
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
- rubyforge_project:
219
- rubygems_version: 2.7.6
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
@@ -1,8 +0,0 @@
1
- language: ruby
2
- rvm:
3
- - 2.3
4
- - 2.4
5
- - 2.5
6
- before_install:
7
- - gem install -v 2.0.1 bundler --no-rdoc --no-ri
8
- script: bundle exec rspec
data/circle.yml DELETED
@@ -1,3 +0,0 @@
1
- machine:
2
- ruby:
3
- version: 2.5.0