inline_svg 1.5.1 → 1.7.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml 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