inline_svg 1.5.1 → 1.7.2

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