roadie 3.4.0 → 5.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (71) hide show
  1. checksums.yaml +5 -5
  2. data/.github/workflows/main.yml +43 -0
  3. data/.rubocop.yml +5 -0
  4. data/.solargraph.yml +16 -0
  5. data/Changelog.md +37 -3
  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 +27 -27
  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 +17 -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 +3 -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 +20 -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 +6 -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 +26 -11
  71. data/.travis.yml +0 -23
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: a2c4863b0337cfe2129ee5e1184bb3ffdd422ea9
4
- data.tar.gz: ccd82152f99fe3131773f9070ef39c07952027d2
2
+ SHA256:
3
+ metadata.gz: 5ba6c121fdd1072479afeee70b785db020df45cbe3b45350a20f9cfd4f8d0164
4
+ data.tar.gz: bfd6faa52b576fba65b8d2281b213ceabf137f08551749dc842b9a9477566fd2
5
5
  SHA512:
6
- metadata.gz: 8acd0f1029e3b40c94fe11e465b6604f6f16aca3d6a33375f14e3c2ea8ded36ca45edbf29e09fe3408c1ac21632875e92093fd8bce17f72658c3a9d9112b8087
7
- data.tar.gz: e66923f904d221f10731bf92058390106ebcbf16be9a9053c149c41919252862285e53d86eec93fc4ececaef894b4ec9df019ad5c23678fa3eabed7ab3676d27
6
+ metadata.gz: 0b897b87d20fdd739110788a21f2b16c5c4a86726b876cfe2a1c815bc671341a02172eaca5bb65729e14cc10e06b7baa076832bd55cb36db927fb4c548eb117e
7
+ data.tar.gz: 290845f661cf1d913fcf01b3c66eeb6e6ec096667a64c21b81fa912950e42a0d1a8294532e28b01f283cf9215a5da028c3559e2fa6cac54860d9c006bce7f401
@@ -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,45 @@
1
1
  ### dev
2
2
 
3
- [full changelog](https://github.com/Mange/roadie/compare/v3.4.0...master)
3
+ [full changelog](https://github.com/Mange/roadie/compare/v5.0.0...master)
4
4
 
5
5
  Nothing yet.
6
6
 
7
- ### 3.3.0
7
+ ### 5.0.0
8
+
9
+ [full changelog](https://github.com/Mange/roadie/compare/v4.0.0...v5.0.0)
10
+
11
+ * Drop support for Ruby 2.4 and Ruby 2.5
12
+ * Drop support for JRuby and Rubinius
13
+ * Test with Ruby 2.7 - [aried3r (Anton Rieder)](https://github.com/aried3r) (#167)
14
+ * Test with Ruby 3.0 and Ruby 3.1
15
+ * Add standardrb as code formatter
16
+ * Drop support for callbacks that accepts only a single argument.
17
+ * Change signature of `Roadie::CssNotFound` and `Roadie::ProvidersFailed`.
18
+
19
+ ### 4.0.0
20
+
21
+ [full changelog](https://github.com/Mange/roadie/compare/v3.5.1...v4.0.0)
22
+
23
+ * Drop support for Ruby 2.1, 2.2, and 2.3 and
24
+ add support for frozen string literals and Ruby 2.6 - [adamkiczula (Adam
25
+ Kiczula)](https://github.com/adamkiczula) (#164)
26
+ * `Roadie::Stylesheet#each_inlinable_block` is now removed.
27
+
28
+ ### 3.5.1
29
+
30
+ [full changelog](https://github.com/Mange/roadie/compare/v3.5.0...v3.5.1)
31
+
32
+ * Gracefully handle empty string email body, such as those provided by
33
+ `ActionMailer::Base::NullMail` objects - [adamkiczula (Adam
34
+ Kiczula)](https://github.com/adamkiczula) (#163).
35
+
36
+ ### 3.5.0
37
+
38
+ [full changelog](https://github.com/Mange/roadie/compare/v3.4.0...v3.5.0)
39
+
40
+ * Drop support for Nokogiri before 1.8.
41
+
42
+ ### 3.4.0
8
43
 
9
44
  [full changelog](https://github.com/Mange/roadie/compare/v3.3.0...v3.4.0)
10
45
 
@@ -364,4 +399,3 @@ Roadie fork!
364
399
  * + some other enhancements
365
400
  * Deprecations:
366
401
  * Removed support for Rails 2.x
367
-
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.4'
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