roadie 3.5.1 → 5.0.1

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.
Files changed (71) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/main.yml +43 -0
  3. data/.rubocop.yml +5 -0
  4. data/.solargraph.yml +16 -0
  5. data/Changelog.md +30 -4
  6. data/Gemfile +7 -2
  7. data/README.md +12 -14
  8. data/Rakefile +4 -3
  9. data/lib/roadie/asset_provider.rb +5 -1
  10. data/lib/roadie/asset_scanner.rb +8 -6
  11. data/lib/roadie/cached_provider.rb +3 -0
  12. data/lib/roadie/deduplicator.rb +3 -0
  13. data/lib/roadie/document.rb +10 -11
  14. data/lib/roadie/errors.rb +22 -16
  15. data/lib/roadie/filesystem_provider.rb +15 -3
  16. data/lib/roadie/inliner.rb +51 -19
  17. data/lib/roadie/markup_improver.rb +24 -31
  18. data/lib/roadie/net_http_provider.rb +27 -12
  19. data/lib/roadie/null_provider.rb +20 -5
  20. data/lib/roadie/null_url_rewriter.rb +11 -3
  21. data/lib/roadie/path_rewriter_provider.rb +6 -1
  22. data/lib/roadie/provider_list.rb +17 -11
  23. data/lib/roadie/rspec/asset_provider.rb +6 -1
  24. data/lib/roadie/rspec/cache_store.rb +2 -0
  25. data/lib/roadie/rspec.rb +4 -2
  26. data/lib/roadie/selector.rb +18 -5
  27. data/lib/roadie/style_attribute_builder.rb +4 -1
  28. data/lib/roadie/style_block.rb +5 -3
  29. data/lib/roadie/style_property.rb +5 -2
  30. data/lib/roadie/stylesheet.rb +4 -13
  31. data/lib/roadie/url_generator.rb +26 -8
  32. data/lib/roadie/url_rewriter.rb +12 -9
  33. data/lib/roadie/utils.rb +3 -1
  34. data/lib/roadie/version.rb +1 -1
  35. data/lib/roadie.rb +25 -23
  36. data/roadie.gemspec +23 -23
  37. data/spec/hash_as_cache_store_spec.rb +3 -1
  38. data/spec/integration_spec.rb +43 -44
  39. data/spec/lib/roadie/asset_scanner_spec.rb +11 -5
  40. data/spec/lib/roadie/cached_provider_spec.rb +6 -4
  41. data/spec/lib/roadie/css_not_found_spec.rb +10 -5
  42. data/spec/lib/roadie/deduplicator_spec.rb +5 -3
  43. data/spec/lib/roadie/document_spec.rb +47 -28
  44. data/spec/lib/roadie/filesystem_provider_spec.rb +10 -11
  45. data/spec/lib/roadie/inliner_spec.rb +42 -45
  46. data/spec/lib/roadie/markup_improver_spec.rb +19 -26
  47. data/spec/lib/roadie/net_http_provider_spec.rb +16 -14
  48. data/spec/lib/roadie/null_provider_spec.rb +4 -3
  49. data/spec/lib/roadie/null_url_rewriter_spec.rb +4 -3
  50. data/spec/lib/roadie/path_rewriter_provider_spec.rb +6 -4
  51. data/spec/lib/roadie/provider_list_spec.rb +27 -22
  52. data/spec/lib/roadie/selector_spec.rb +7 -5
  53. data/spec/lib/roadie/style_attribute_builder_spec.rb +7 -5
  54. data/spec/lib/roadie/style_block_spec.rb +3 -2
  55. data/spec/lib/roadie/style_property_spec.rb +10 -8
  56. data/spec/lib/roadie/stylesheet_spec.rb +4 -21
  57. data/spec/lib/roadie/test_provider_spec.rb +6 -4
  58. data/spec/lib/roadie/url_generator_spec.rb +3 -2
  59. data/spec/lib/roadie/url_rewriter_spec.rb +10 -7
  60. data/spec/lib/roadie/utils_spec.rb +2 -0
  61. data/spec/shared_examples/asset_provider.rb +2 -0
  62. data/spec/shared_examples/url_rewriter.rb +5 -3
  63. data/spec/spec_helper.rb +10 -8
  64. data/spec/support/have_attribute_matcher.rb +3 -2
  65. data/spec/support/have_node_matcher.rb +5 -3
  66. data/spec/support/have_selector_matcher.rb +4 -3
  67. data/spec/support/have_styling_matcher.rb +12 -11
  68. data/spec/support/have_xpath_matcher.rb +4 -3
  69. data/spec/support/test_provider.rb +2 -0
  70. metadata +24 -8
  71. data/.travis.yml +0 -22
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 19c2bb2df5f06249e20336bee272088f2224749fcb20741c411647428221e20e
4
- data.tar.gz: cd7e290f724bf71fd8b56d8f013ebc2dd246b5594fc730d5899639d1dbdada38
3
+ metadata.gz: 7ac28a4d983148b5e8c799804e754b81d9d7a04b4ef97f97bcc6592d37a74bed
4
+ data.tar.gz: 9dbeb2fb1d41e301bf7d7c4049e476da22604bfc70047f6dc843ab6c1a489048
5
5
  SHA512:
6
- metadata.gz: 8767e97ed3592ff69e969d646537775b9a0c571d62f54bb02555e102f5acedf5813435d0f4b1b58b52adb4187608cfe33020a7019c98aebd8ad5077ef3e3b4e8
7
- data.tar.gz: 220fdd872e42acea4e4aebe9dc04f34d3a9e996254d5135af4663d98534362ade3b0d1c21368afd6c046282814b4f0d061f8e20f14451d295fb511f0c4888366
6
+ metadata.gz: 5146cfb6152aad59b410670b792788bc84af5a9064c353628fae6cc1a1b2a2854703872990c47788c9369fef4469ee15b0040f192aeda1e32dcd8eef934e6327
7
+ data.tar.gz: 80418199d7ea29608e7997ee4ccfb591dbe8bd1eb3c609b59e8fc857b0d056103fcc9e74fafab6cd32f041ea8051870c41a5e6807b24d4c233e46803ab498750
@@ -0,0 +1,43 @@
1
+ name: Main
2
+ on:
3
+ push:
4
+ branches:
5
+ - main
6
+ - master
7
+
8
+ pull_request:
9
+ types: [opened, synchronize, reopened]
10
+
11
+ jobs:
12
+ base:
13
+ name: Ruby ${{ matrix.ruby }}
14
+ runs-on: ubuntu-20.04
15
+ strategy:
16
+ fail-fast: false
17
+ matrix:
18
+ ruby: ["2.6", "2.7", "3.0", "3.1"]
19
+
20
+ steps:
21
+ - name: Checkout code
22
+ uses: actions/checkout@v2
23
+
24
+ # This setup is not compatible with the way Travis CI was
25
+ # setup, so the cache will only work for the root folder.
26
+ - name: Setup Ruby
27
+ uses: ruby/setup-ruby@v1
28
+ with:
29
+ ruby-version: ${{ matrix.ruby }}
30
+ bundler-cache: true
31
+
32
+ - name: Rake
33
+ run: bundle exec rake
34
+
35
+ - uses: codecov/codecov-action@v2
36
+
37
+ lint:
38
+ runs-on: ubuntu-latest
39
+ steps:
40
+ - name: standardrb
41
+ env:
42
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
43
+ uses: amoeba/standardrb-action@v2
data/.rubocop.yml ADDED
@@ -0,0 +1,5 @@
1
+ AllCops:
2
+ DisabledByDefault: true
3
+
4
+ Style/FrozenStringLiteralComment:
5
+ Enabled: true
data/.solargraph.yml ADDED
@@ -0,0 +1,16 @@
1
+ ---
2
+ include:
3
+ - "**/*.rb"
4
+ exclude:
5
+ - spec/**/*
6
+ - test/**/*
7
+ - vendor/**/*
8
+ - ".bundle/**/*"
9
+ require: []
10
+ domains: []
11
+ plugins:
12
+ - solargraph-standardrb
13
+ reporters:
14
+ - standardrb
15
+ require_paths: []
16
+ max_files: 5000
data/Changelog.md CHANGED
@@ -1,10 +1,37 @@
1
1
  ### dev
2
2
 
3
- ### dev
3
+ [full changelog](https://github.com/Mange/roadie/compare/v5.0.1...master)
4
+
5
+ Nothing yet.
6
+
7
+ ### 5.0.1
8
+
9
+ [full changelog](https://github.com/Mange/roadie/compare/v5.0.0...v5.0.1)
10
+
11
+ * Don't try to inline [the `:host`
12
+ pseudo-class](https://developer.mozilla.org/en-US/docs/Web/CSS/:host) -
13
+ [viamin (Bart Agapinan)](https://github.com/viamin). (#170)
4
14
 
5
- [full changelog](https://github.com/Mange/roadie/compare/v3.5.1...master)
15
+ ### 5.0.0
6
16
 
7
- * Nothing yet.
17
+ [full changelog](https://github.com/Mange/roadie/compare/v4.0.0...v5.0.0)
18
+
19
+ * Drop support for Ruby 2.4 and Ruby 2.5
20
+ * Drop support for JRuby and Rubinius
21
+ * Test with Ruby 2.7 - [aried3r (Anton Rieder)](https://github.com/aried3r) (#167)
22
+ * Test with Ruby 3.0 and Ruby 3.1
23
+ * Add standardrb as code formatter
24
+ * Drop support for callbacks that accepts only a single argument.
25
+ * Change signature of `Roadie::CssNotFound` and `Roadie::ProvidersFailed`.
26
+
27
+ ### 4.0.0
28
+
29
+ [full changelog](https://github.com/Mange/roadie/compare/v3.5.1...v4.0.0)
30
+
31
+ * Drop support for Ruby 2.1, 2.2, and 2.3 and
32
+ add support for frozen string literals and Ruby 2.6 - [adamkiczula (Adam
33
+ Kiczula)](https://github.com/adamkiczula) (#164)
34
+ * `Roadie::Stylesheet#each_inlinable_block` is now removed.
8
35
 
9
36
  ### 3.5.1
10
37
 
@@ -380,4 +407,3 @@ Roadie fork!
380
407
  * + some other enhancements
381
408
  * Deprecations:
382
409
  * Removed support for Rails 2.x
383
-
data/Gemfile CHANGED
@@ -1,5 +1,10 @@
1
- source 'https://rubygems.org'
1
+ # frozen_string_literal: true
2
+
3
+ source "https://rubygems.org"
2
4
  gemspec
3
5
 
4
6
  # Added here so it does not show up on the Gemspec; I only want it for CI builds
5
- gem 'codecov', group: :test, require: false
7
+ gem "codecov", group: :test, require: false
8
+ # Not actually required to run the tests for the gem, but a real convenience
9
+ # for local development.
10
+ gem "standard", group: [:test, :development], require: false
data/README.md CHANGED
@@ -1,7 +1,6 @@
1
1
  Roadie
2
2
  ======
3
3
 
4
- [![Build history and status](https://travis-ci.org/Mange/roadie.svg?branch=master)](http://travis-ci.org/#!/Mange/roadie)
5
4
  [![Code Climate](https://codeclimate.com/github/Mange/roadie.png)](https://codeclimate.com/github/Mange/roadie)
6
5
  [![Code coverage status](https://codecov.io/github/Mange/roadie/coverage.svg?branch=master)](https://codecov.io/github/Mange/roadie?branch=master)
7
6
  [![Gem](https://img.shields.io/gem/v/roadie.svg)](https://rubygems.org/gems/roadie)
@@ -55,7 +54,7 @@ Install & Usage
55
54
  [Add this gem to your Gemfile as recommended by Rubygems](http://rubygems.org/gems/roadie) and run `bundle install`.
56
55
 
57
56
  ```ruby
58
- gem 'roadie', '~> 3.5'
57
+ gem 'roadie', '~> 4.0'
59
58
  ```
60
59
 
61
60
  You can then create a new instance of a Roadie document:
@@ -333,7 +332,10 @@ class UserAssetsProvider
333
332
  end
334
333
 
335
334
  def find_stylesheet!(name)
336
- find_stylesheet(name) or raise Roadie::CssNotFound.new(name, "does not match a user stylesheet", self)
335
+ find_stylesheet(name) or
336
+ raise Roadie::CssNotFound.new(
337
+ css_name: name, message: "does not match a user stylesheet", provider: self
338
+ )
337
339
  end
338
340
 
339
341
  # Instead of implementing #find_stylesheet!, you could also:
@@ -444,18 +446,14 @@ Partial documents does not have a `<!DOCTYPE>`.
444
446
  Build Status
445
447
  ------------
446
448
 
447
- Tested with [Travis CI](http://travis-ci.org) using:
449
+ Tested with Github CI using:
448
450
 
449
- * MRI 2.1
450
- * MRI 2.2
451
- * MRI 2.3
452
- * MRI 2.4
453
- * JRuby (latest)
454
- * Rubinius (failures on Rubinius will not fail the build due to a long history of instability in `rbx`)
451
+ * MRI 2.6
452
+ * MRI 2.7
453
+ * MRI 3.0
454
+ * MRI 3.1
455
455
 
456
- [(Build status)](http://travis-ci.org/#!/Mange/roadie)
457
-
458
- Let me know if you want any other VM supported officially.
456
+ Let me know if you want any other runtime supported officially.
459
457
 
460
458
  ### Versioning ###
461
459
 
@@ -565,7 +563,7 @@ License
565
563
 
566
564
  (The MIT License)
567
565
 
568
- Copyright (c) 2009-2018 Magnus Bergmark, Jim Neath / Purify, and contributors.
566
+ Copyright (c) 2009-2022 Magnus Bergmark, Jim Neath / Purify, and contributors.
569
567
 
570
568
  * [Magnus Bergmark](https://github.com/Mange) <magnus.bergmark@gmail.com>
571
569
 
data/Rakefile CHANGED
@@ -1,5 +1,6 @@
1
- # encoding: utf-8
2
- require 'bundler/setup'
1
+ # frozen_string_literal: true
2
+
3
+ require "bundler/setup"
3
4
 
4
5
  Bundler::GemHelper.install_tasks
5
6
 
@@ -9,4 +10,4 @@ task :spec do
9
10
  end
10
11
 
11
12
  desc "Default: Run specs"
12
- task :default => :spec
13
+ task default: :spec
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Roadie
2
4
  # This module can be included in your own code to help you implement the
3
5
  # standard behavior for asset providers.
@@ -5,7 +7,9 @@ module Roadie
5
7
  # It helps you by declaring {#find_stylesheet!} in the terms of #find_stylesheet in your own class.
6
8
  module AssetProvider
7
9
  def find_stylesheet!(name)
8
- find_stylesheet(name) or raise CssNotFound.new(name, nil, self)
10
+ find_stylesheet(name) or raise(
11
+ CssNotFound.new(css_name: name, provider: self)
12
+ )
9
13
  end
10
14
  end
11
15
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Roadie
2
4
  # @api private
3
5
  #
@@ -41,15 +43,15 @@ module Roadie
41
43
  # @see #find_css
42
44
  # @return [Enumerable<Stylesheet>] every extracted stylesheet
43
45
  def extract_css
44
- stylesheets = @dom.css(STYLE_ELEMENT_QUERY).map { |element|
46
+ @dom.css(STYLE_ELEMENT_QUERY).map { |element|
45
47
  stylesheet = read_stylesheet(element)
46
48
  element.remove if stylesheet
47
49
  stylesheet
48
50
  }.compact
49
- stylesheets
50
51
  end
51
52
 
52
53
  private
54
+
53
55
  STYLE_ELEMENT_QUERY = (
54
56
  "style:not([data-roadie-ignore]), " +
55
57
  # TODO: When using Nokogiri 1.6.1 and later; we may use a double :not here
@@ -73,7 +75,7 @@ module Roadie
73
75
  def read_stylesheet(element)
74
76
  if element.name == "style"
75
77
  read_style_element element
76
- elsif element.name == "link" && element['media'] != "print" && element["href"]
78
+ elsif element.name == "link" && element["media"] != "print" && element["href"]
77
79
  read_link_element element
78
80
  end
79
81
  end
@@ -84,14 +86,14 @@ module Roadie
84
86
 
85
87
  def read_link_element(element)
86
88
  if Utils.path_is_absolute?(element["href"])
87
- external_asset_provider.find_stylesheet! element['href'] if should_find_external?
89
+ external_asset_provider.find_stylesheet! element["href"] if should_find_external?
88
90
  else
89
- normal_asset_provider.find_stylesheet! element['href']
91
+ normal_asset_provider.find_stylesheet! element["href"]
90
92
  end
91
93
  end
92
94
 
93
95
  def clean_css(css)
94
- css.gsub(CLEANING_MATCHER, '')
96
+ css.gsub(CLEANING_MATCHER, "")
95
97
  end
96
98
 
97
99
  def should_find_external?
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Roadie
2
4
  # @api public
3
5
  # The {CachedProvider} wraps another provider (or {ProviderList}) and caches
@@ -67,6 +69,7 @@ module Roadie
67
69
  end
68
70
 
69
71
  private
72
+
70
73
  def cache_fetch(name)
71
74
  cache[name] || cache[name] = yield
72
75
  rescue CssNotFound
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Roadie
2
4
  class Deduplicator
3
5
  def self.apply(input)
@@ -24,6 +26,7 @@ module Roadie
24
26
  end
25
27
 
26
28
  private
29
+
27
30
  attr_reader :input, :latest_occurance
28
31
 
29
32
  def has_duplicates?
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Roadie
2
4
  # The main entry point for Roadie. A document represents a working unit and
3
5
  # is built with the input HTML and the configuration options you need.
@@ -50,7 +52,7 @@ module Roadie
50
52
  @html = html
51
53
  @asset_providers = ProviderList.wrap(FilesystemProvider.new)
52
54
  @external_asset_providers = ProviderList.empty
53
- @css = ""
55
+ @css = +""
54
56
  @mode = :html
55
57
  end
56
58
 
@@ -140,6 +142,7 @@ module Roadie
140
142
  # Valid modes:
141
143
  # `:html` (default)
142
144
  # `:xhtml`
145
+ # `:xml`
143
146
  def mode=(mode)
144
147
  if VALID_MODES.include?(mode)
145
148
  @mode = mode
@@ -149,7 +152,8 @@ module Roadie
149
152
  end
150
153
 
151
154
  private
152
- VALID_MODES = %i[html xhtml].freeze
155
+
156
+ VALID_MODES = %i[html xhtml xml].freeze
153
157
  private_constant :VALID_MODES
154
158
 
155
159
  def stylesheet
@@ -166,7 +170,7 @@ module Roadie
166
170
  Inliner.new(dom_stylesheets + [stylesheet], dom).inline(
167
171
  keep_uninlinable_css: keep_uninlinable_css,
168
172
  keep_uninlinable_in: keep_uninlinable_in,
169
- merge_media_queries: merge_media_queries,
173
+ merge_media_queries: merge_media_queries
170
174
  )
171
175
  end
172
176
 
@@ -180,6 +184,7 @@ module Roadie
180
184
  format = {
181
185
  html: save_options::AS_HTML,
182
186
  xhtml: save_options::AS_XHTML,
187
+ xml: save_options::AS_XML
183
188
  }.fetch(mode)
184
189
 
185
190
  dom.dup.to_html(
@@ -187,7 +192,7 @@ module Roadie
187
192
  save_options::NO_DECLARATION |
188
193
  save_options::NO_EMPTY_TAGS |
189
194
  format
190
- ),
195
+ )
191
196
  )
192
197
  end
193
198
 
@@ -201,13 +206,7 @@ module Roadie
201
206
 
202
207
  def callback(callable, dom)
203
208
  if callable.respond_to?(:call)
204
- # Arity checking is to support the API without bumping a major version.
205
- # TODO: Remove on next major version (v4.0)
206
- if !callable.respond_to?(:parameters) || callable.parameters.size == 1
207
- callable.(dom)
208
- else
209
- callable.(dom, self)
210
- end
209
+ callable.call(dom, self)
211
210
  end
212
211
  end
213
212
 
data/lib/roadie/errors.rb CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Roadie
2
4
  # Base class for all Roadie errors. Rescue this if you want to catch errors
3
5
  # from Roadie.
@@ -16,10 +18,10 @@ module Roadie
16
18
 
17
19
  def initialize(given_path, cause = nil)
18
20
  @cause = cause
19
- if cause
20
- cause_message = " Caused by: #{cause}"
21
+ cause_message = if cause
22
+ " Caused by: #{cause}"
21
23
  else
22
- cause_message = ""
24
+ ""
23
25
  end
24
26
  super "Cannot use path \"#{given_path}\" in URL generation.#{cause_message}"
25
27
  end
@@ -41,24 +43,23 @@ module Roadie
41
43
  # Extra message
42
44
  attr_reader :extra_message
43
45
 
44
- # TODO: Change signature in the next major version of Roadie.
45
- def initialize(css_name, extra_message = nil, provider = nil)
46
+ def initialize(css_name:, message: nil, provider: nil)
46
47
  @css_name = css_name
47
48
  @provider = provider
48
- @extra_message = extra_message
49
- super build_message(extra_message)
49
+ @extra_message = message
50
+ super build_message
50
51
  end
51
52
 
52
53
  protected
54
+
53
55
  def error_row
54
- "#{provider || "Unknown provider"}: #{extra_message || message}"
56
+ "#{provider || "Unknown provider"}: #{extra_message}"
55
57
  end
56
58
 
57
59
  private
58
- # Redundant method argument is to keep API compatability without major version bump.
59
- # TODO: Remove argument on version 4.0.
60
- def build_message(extra_message = @extra_message)
61
- message = %(Could not find stylesheet "#{css_name}")
60
+
61
+ def build_message
62
+ message = +%(Could not find stylesheet "#{css_name}")
62
63
  message << ": #{extra_message}" if extra_message
63
64
  message << "\nUsed provider:\n#{provider}" if provider
64
65
  message
@@ -68,14 +69,19 @@ module Roadie
68
69
  class ProvidersFailed < CssNotFound
69
70
  attr_reader :errors
70
71
 
71
- def initialize(css_name, provider_list, errors)
72
+ def initialize(css_name:, providers:, errors:)
72
73
  @errors = errors
73
- super(css_name, "All providers failed", provider_list)
74
+ super(
75
+ css_name: css_name,
76
+ message: "All providers failed",
77
+ provider: providers
78
+ )
74
79
  end
75
80
 
76
81
  private
77
- def build_message(extra_message)
78
- message = %(Could not find stylesheet "#{css_name}": #{extra_message}\nUsed providers:\n)
82
+
83
+ def build_message
84
+ message = +%(Could not find stylesheet "#{css_name}": #{extra_message}\nUsed providers:\n)
79
85
  each_error_row(errors) do |row|
80
86
  message << "\t" << row << "\n"
81
87
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Roadie
2
4
  # Asset provider that looks for files on your local filesystem.
3
5
  #
@@ -30,14 +32,24 @@ module Roadie
30
32
  Stylesheet.new file_path, File.read(file_path)
31
33
  else
32
34
  basename = File.basename file_path
33
- raise CssNotFound.new(basename, %{#{file_path} does not exist. (Original name was "#{name}")}, self)
35
+ raise CssNotFound.new(
36
+ css_name: basename,
37
+ message: %{#{file_path} does not exist. (Original name was "#{name}")},
38
+ provider: self
39
+ )
34
40
  end
35
41
  end
36
42
 
37
- def to_s() inspect end
38
- def inspect() "#<#{self.class} #@path>" end
43
+ def to_s
44
+ inspect
45
+ end
46
+
47
+ def inspect
48
+ "#<#{self.class} #{@path}>"
49
+ end
39
50
 
40
51
  private
52
+
41
53
  def build_file_path(name)
42
54
  raise InsecurePathError, name if name.include?("..")
43
55
  File.join(@path, name[/^([^?]+)/])
@@ -1,19 +1,28 @@
1
- require 'set'
2
- require 'nokogiri'
3
- require 'uri'
4
- require 'css_parser'
1
+ # frozen_string_literal: true
2
+
3
+ require "set"
4
+ require "nokogiri"
5
+ require "uri"
6
+ require "css_parser"
5
7
 
6
8
  module Roadie
7
9
  # @api private
8
10
  # The Inliner inlines stylesheets to the elements of the DOM.
9
11
  #
10
12
  # Inlining means that {StyleBlock}s and a DOM tree are combined:
11
- # a { color: red; } # StyleBlock
12
- # <a href="/"></a> # DOM
13
+ #
14
+ # ```css
15
+ # a { color: red; } # StyleBlock
16
+ # ```
17
+ # ```html
18
+ # <a href="/"></a> # DOM
19
+ # ```
13
20
  #
14
21
  # becomes
15
22
  #
16
- # <a href="/" style="color:red"></a>
23
+ # ```html
24
+ # <a href="/" style="color:red"></a>
25
+ # ```
17
26
  class Inliner
18
27
  # @param [Array<Stylesheet>] stylesheets the stylesheets to use in the inlining
19
28
  # @param [Nokogiri::HTML::Document] dom
@@ -45,9 +54,11 @@ module Roadie
45
54
  end
46
55
 
47
56
  protected
57
+
48
58
  attr_reader :stylesheets, :dom
49
59
 
50
60
  private
61
+
51
62
  def consume_stylesheets
52
63
  style_map = StyleMap.new
53
64
  extra_blocks = []
@@ -89,12 +100,18 @@ module Roadie
89
100
  # with having to rescue errors.
90
101
  # Pseudo selectors that are known to be bad are skipped automatically but
91
102
  # this will catch the rest.
92
- rescue Nokogiri::XML::XPath::SyntaxError, Nokogiri::CSS::SyntaxError => error
93
- Utils.warn "Cannot inline #{selector.inspect} from \"#{stylesheet.name}\" stylesheet. If this is valid CSS, please report a bug."
103
+ rescue Nokogiri::XML::XPath::SyntaxError, Nokogiri::CSS::SyntaxError
104
+ Utils.warn(
105
+ "Cannot inline #{selector.inspect} from \"#{stylesheet.name}\" " \
106
+ "stylesheet. If this is valid CSS, please report a bug."
107
+ )
94
108
  nil
95
109
  rescue => error
96
- Utils.warn "Got error when looking for #{selector.inspect} (from \"#{stylesheet.name}\" stylesheet): #{error}"
97
- raise unless error.message.include?('XPath')
110
+ Utils.warn(
111
+ "Got error when looking for #{selector.inspect} " \
112
+ "(from \"#{stylesheet.name}\" stylesheet): #{error}"
113
+ )
114
+ raise unless error.message.include?("XPath")
98
115
  nil
99
116
  end
100
117
 
@@ -120,12 +137,12 @@ module Roadie
120
137
  end
121
138
 
122
139
  def find_head
123
- dom.at_xpath('html/head')
140
+ dom.at_xpath("html/head")
124
141
  end
125
142
 
126
143
  def create_style_element(style_blocks, parent, merge_media_queries)
127
144
  return unless parent
128
- element = Nokogiri::XML::Node.new('style', parent.document)
145
+ element = Nokogiri::XML::Node.new("style", parent.document)
129
146
 
130
147
  element.content =
131
148
  if merge_media_queries
@@ -139,17 +156,23 @@ module Roadie
139
156
  # For performance reasons, we should group styles with the same media types within
140
157
  # one media query instead of creating thousands of media queries.
141
158
  # https://github.com/artifex404/media-queries-benchmark
142
- # Example result: ["@media(max-width: 600px) { .col-12 { display: block; } }"]
159
+ #
160
+ # Example result:
161
+ #
162
+ # ```ruby
163
+ # ["@media(max-width: 600px) { .col-12 { display: block; } }"]
164
+ # ```
165
+ #
143
166
  # @param {Array<StyleBlock>} style_blocks Style blocks that could not be inlined
144
167
  # @return {Array<String>}
145
168
  def styles_in_shared_media_queries(style_blocks)
146
169
  style_blocks.group_by(&:media).map do |media_types, blocks|
147
170
  css_rules = blocks.map(&:to_s).join("\n")
148
171
 
149
- if media_types == ['all']
172
+ if media_types == ["all"]
150
173
  css_rules
151
174
  else
152
- "@media #{media_types.join(', ')} {\n#{css_rules}\n}"
175
+ "@media #{media_types.join(", ")} {\n#{css_rules}\n}"
153
176
  end
154
177
  end
155
178
  end
@@ -157,27 +180,36 @@ module Roadie
157
180
  # Some users might prefer to not group rules within media queries because
158
181
  # it will result in rules getting reordered.
159
182
  # e.g.
183
+ #
184
+ # ```css
160
185
  # @media(max-width: 600px) { .col-6 { display: block; } }
161
186
  # @media(max-width: 400px) { .col-12 { display: inline-block; } }
162
187
  # @media(max-width: 600px) { .col-12 { display: block; } }
188
+ # ````
189
+ #
163
190
  # will become
191
+ #
192
+ # ```css
164
193
  # @media(max-width: 600px) { .col-6 { display: block; } .col-12 { display: block; } }
165
194
  # @media(max-width: 400px) { .col-12 { display: inline-block; } }
195
+ # ```
196
+ #
197
+ #
166
198
  # which would change the styling on the page
167
199
  # (before it would've yielded display: block; for .col-12 at max-width: 600px
168
200
  # and now it yields inline-block;)
169
201
  #
170
202
  # If merge_media_queries is set to false,
171
- # we will generate #{style_blocks.size} media queries, potentially
203
+ # we will generate `style_blocks.size` media queries, potentially
172
204
  # causing performance issues.
173
205
  # @param {Array<StyleBlock>} style_blocks All style blocks
174
206
  # @return {Array<String>}
175
207
  def styles_in_individual_media_queries(style_blocks)
176
208
  style_blocks.map do |css_rule|
177
- if css_rule.media == ['all']
209
+ if css_rule.media == ["all"]
178
210
  css_rule
179
211
  else
180
- "@media #{css_rule.media.join(', ')} {\n#{css_rule}\n}"
212
+ "@media #{css_rule.media.join(", ")} {\n#{css_rule}\n}"
181
213
  end
182
214
  end
183
215
  end