premailer 1.24.0 → 1.25.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 893f0a35f19920e5a33bbaefc0c1cd2dd8a8fc2f56fc8f11bf7ed3bca2d4d437
4
- data.tar.gz: 7d48ed502bc818064241ea372b4e0bdbffd204a845ff5e36a8da38af94a15202
3
+ metadata.gz: 8d8f189b10e7c9868d3abeae3d057e0b0681bb7798c0fbd7e8fe3aa8bb922aad
4
+ data.tar.gz: e0dbb8d0d65aeb0ec7e463983148b1c54f77fa005fd73766a749ee147a12d240
5
5
  SHA512:
6
- metadata.gz: d2098aec27cdabce93e5dd144be10e6b090105970f415fd32e3e5d6a9b7f65decf7d1968563e0ecb7ea88a2d74895ad526dc0fd1f72a6d7e2a9029548884157f
7
- data.tar.gz: f70007e030983216f7598f387c909cdb0de5c9192f9fe69049ef7da1f307357b9ae79dc2a533b0d2bd5bdbae60de9d1935162ab47b76d8af0c14fa788108e11f
6
+ metadata.gz: 650e617eefd069d1733092612fa4eb434b539564f61f81fcbda4c7a06121fc3d8a71ee440ce5dfee3e0f97f88282e4dcd1da6c33bddcd4008d05f0ebb4aa82a6
7
+ data.tar.gz: c537248adafbc5f6ed58f8825055fe557098c1bea88240c4ec08d5d248268fb3f45db365cf08912a693dd963abe0825f942f5b5937553ceeacd54a51f1f44f21
data/bin/premailer CHANGED
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
2
3
 
3
4
  # This binary used in rubygems environment only as part of installed gem
4
5
 
5
6
  require 'premailer/executor'
6
-
@@ -1,9 +1,11 @@
1
+ # frozen_string_literal: true
1
2
  require 'nokogiri'
2
3
 
3
4
  class Premailer
4
5
  module Adapter
5
6
  # Nokogiri adapter
6
7
  module Nokogiri
8
+ WIDTH_AND_HIGHT = ['width', 'height'].freeze
7
9
 
8
10
  include AdapterHelper::RgbToHex
9
11
  # Merge CSS into the HTML document.
@@ -30,7 +32,7 @@ class Premailer
30
32
  @unmergable_rules.add_rule_set!(CssParser::RuleSet.new(selector, declaration), media_types) unless @options[:preserve_styles]
31
33
  else
32
34
  begin
33
- if selector =~ Premailer::RE_RESET_SELECTORS
35
+ if Premailer::RE_RESET_SELECTORS.match?(selector)
34
36
  # this is in place to preserve the MailChimp CSS reset: http://github.com/mailchimp/Email-Blueprints/
35
37
  # however, this doesn't mean for testing pur
36
38
  @unmergable_rules.add_rule_set!(CssParser::RuleSet.new(selector, declaration)) unless !@options[:preserve_reset]
@@ -90,7 +92,7 @@ class Premailer
90
92
  new_val.gsub!(/;$|\s*!important/, '').strip!
91
93
 
92
94
  # For width and height tags, remove px units
93
- new_val.gsub!(/(\d+)px/, '\1') if %w[width height].include?(html_attr)
95
+ new_val.gsub!(/(\d+)px/, '\1') if WIDTH_AND_HIGHT.include?(html_attr)
94
96
 
95
97
  # For color-related tags, convert RGB to hex if specified by options
96
98
  new_val = ensure_hex(new_val) if css_attr.end_with?('color') && @options[:rgb_to_hex_attributes]
@@ -99,7 +101,7 @@ class Premailer
99
101
  end
100
102
 
101
103
  unless @options[:preserve_style_attribute]
102
- merged.instance_variable_get("@declarations").tap do |declarations|
104
+ merged.instance_variable_get(:@declarations).tap do |declarations|
103
105
  declarations.delete(css_attr)
104
106
  end
105
107
  end
@@ -250,7 +252,7 @@ class Premailer
250
252
  # Fix for removing any CDATA tags from both style and script tags inserted per
251
253
  # https://github.com/sparklemotion/nokogiri/issues/311 and
252
254
  # https://github.com/premailer/premailer/issues/199
253
- %w(style script).each do |tag|
255
+ ['style', 'script'].each do |tag|
254
256
  doc.search(tag).children.each do |child|
255
257
  child.swap(child.text()) if child.cdata?
256
258
  end
@@ -1,9 +1,11 @@
1
+ # frozen_string_literal: true
1
2
  require 'nokogiri'
2
3
 
3
4
  class Premailer
4
5
  module Adapter
5
6
  # NokogiriFast adapter
6
7
  module NokogiriFast
8
+ WIDTH_AND_HEIGHT = ['width', 'height'].freeze
7
9
 
8
10
  include AdapterHelper::RgbToHex
9
11
  # Merge CSS into the HTML document.
@@ -36,7 +38,7 @@ class Premailer
36
38
  @unmergable_rules.add_rule_set!(CssParser::RuleSet.new(selector, declaration), media_types) unless @options[:preserve_styles]
37
39
  else
38
40
  begin
39
- if selector =~ Premailer::RE_RESET_SELECTORS
41
+ if Premailer::RE_RESET_SELECTORS.match?(selector)
40
42
  # this is in place to preserve the MailChimp CSS reset: http://github.com/mailchimp/Email-Blueprints/
41
43
  # however, this doesn't mean for testing pur
42
44
  @unmergable_rules.add_rule_set!(CssParser::RuleSet.new(selector, declaration)) unless !@options[:preserve_reset]
@@ -96,7 +98,7 @@ class Premailer
96
98
  new_val.gsub!(/;$|\s*!important/, '').strip!
97
99
 
98
100
  # For width and height tags, remove px units
99
- new_val.gsub!(/(\d+)px/, '\1') if %w[width height].include?(html_attr)
101
+ new_val.gsub!(/(\d+)px/, '\1') if WIDTH_AND_HEIGHT.include?(html_attr)
100
102
 
101
103
  # For color-related tags, convert RGB to hex if specified by options
102
104
  new_val = ensure_hex(new_val) if css_attr.end_with?('color') && @options[:rgb_to_hex_attributes]
@@ -105,7 +107,7 @@ class Premailer
105
107
  end
106
108
 
107
109
  unless @options[:preserve_style_attribute]
108
- merged.instance_variable_get("@declarations").tap do |declarations|
110
+ merged.instance_variable_get(:@declarations).tap do |declarations|
109
111
  declarations.delete(css_attr)
110
112
  end
111
113
  end
@@ -255,7 +257,7 @@ class Premailer
255
257
  # Fix for removing any CDATA tags from both style and script tags inserted per
256
258
  # https://github.com/sparklemotion/nokogiri/issues/311 and
257
259
  # https://github.com/premailer/premailer/issues/199
258
- %w(style script).each do |tag|
260
+ ['style', 'script'].each do |tag|
259
261
  doc.search(tag).children.each do |child|
260
262
  child.swap(child.text()) if child.cdata?
261
263
  end
@@ -314,7 +316,7 @@ class Premailer
314
316
  index.default = Set.new
315
317
  descendants.default = Set.new
316
318
 
317
- return index, Set.new(all_nodes), descendants
319
+ [index, Set.new(all_nodes), descendants]
318
320
  end
319
321
 
320
322
  # @param doc The top level document
@@ -354,7 +356,7 @@ class Premailer
354
356
  # It will return nil when such a selector is passed, so you can take
355
357
  # action on the falsity of the return value.
356
358
  def match_selector(index, all_nodes, descendants, selector)
357
- if /[^-a-zA-Z0-9_\s.#]/.match(selector) then
359
+ if /[^-a-zA-Z0-9_\s.#]/.match?(selector) then
358
360
  return nil
359
361
  end
360
362
 
@@ -1,7 +1,9 @@
1
+ # frozen_string_literal: true
1
2
  class Premailer
2
3
  module Adapter
3
4
  # Nokogiri adapter
4
5
  module Nokogumbo
6
+ WIDTH_AND_HEIGHT = ['width', 'height'].freeze
5
7
 
6
8
  include AdapterHelper::RgbToHex
7
9
  # Merge CSS into the HTML document.
@@ -28,7 +30,7 @@ class Premailer
28
30
  @unmergable_rules.add_rule_set!(CssParser::RuleSet.new(selector, declaration), media_types) unless @options[:preserve_styles]
29
31
  else
30
32
  begin
31
- if selector =~ Premailer::RE_RESET_SELECTORS
33
+ if Premailer::RE_RESET_SELECTORS.match?(selector)
32
34
  # this is in place to preserve the MailChimp CSS reset: http://github.com/mailchimp/Email-Blueprints/
33
35
  # however, this doesn't mean for testing pur
34
36
  @unmergable_rules.add_rule_set!(CssParser::RuleSet.new(selector, declaration)) unless !@options[:preserve_reset]
@@ -90,7 +92,7 @@ class Premailer
90
92
  new_val.gsub!(/;$|\s*!important/, '').strip!
91
93
 
92
94
  # For width and height tags, remove px units
93
- new_val.gsub!(/(\d+)px/, '\1') if %w[width height].include?(html_attr)
95
+ new_val.gsub!(/(\d+)px/, '\1') if WIDTH_AND_HEIGHT.include?(html_attr)
94
96
 
95
97
  # For color-related tags, convert RGB to hex if specified by options
96
98
  new_val = ensure_hex(new_val) if css_attr.end_with?('color') && @options[:rgb_to_hex_attributes]
@@ -99,7 +101,7 @@ class Premailer
99
101
  end
100
102
 
101
103
  unless @options[:preserve_style_attribute]
102
- merged.instance_variable_get("@declarations").tap do |declarations|
104
+ merged.instance_variable_get(:@declarations).tap do |declarations|
103
105
  declarations.delete(css_attr)
104
106
  end
105
107
  end
@@ -248,7 +250,7 @@ class Premailer
248
250
  # Fix for removing any CDATA tags from both style and script tags inserted per
249
251
  # https://github.com/sparklemotion/nokogiri/issues/311 and
250
252
  # https://github.com/premailer/premailer/issues/199
251
- %w(style script).each do |tag|
253
+ ['style', 'script'].each do |tag|
252
254
  doc.search(tag).children.each do |child|
253
255
  child.swap(child.text()) if child.cdata?
254
256
  end
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  # RGB helper for adapters, currently only nokogiri supported
2
3
 
3
4
  module AdapterHelper
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  class Premailer
2
3
  # Manages the adapter classes. Currently supports:
3
4
  #
@@ -14,7 +15,7 @@ class Premailer
14
15
  REQUIREMENT_MAP = [
15
16
  ["nokogiri", :nokogiri],
16
17
  ["nokogiri", :nokogiri_fast],
17
- ["nokogumbo", :nokogumbo],
18
+ ["nokogumbo", :nokogumbo]
18
19
  ]
19
20
 
20
21
  # Returns the adapter to use.
@@ -42,7 +43,7 @@ class Premailer
42
43
  end
43
44
  end
44
45
 
45
- raise RuntimeError.new("No suitable adapter for Premailer was found, please install nokogiri or nokogumbo")
46
+ raise "No suitable adapter for Premailer was found, please install nokogiri or nokogumbo"
46
47
  end
47
48
 
48
49
  # Sets the adapter to use.
@@ -56,7 +57,7 @@ class Premailer
56
57
  def self.find(adapter)
57
58
  return adapter if adapter.is_a?(Module)
58
59
 
59
- Premailer::Adapter.const_get("#{adapter.to_s.split('_').map{|s| s.capitalize}.join('')}")
60
+ Premailer::Adapter.const_get("#{adapter.to_s.split('_').map{|s| s.capitalize}.join}")
60
61
  rescue NameError
61
62
  raise ArgumentError, "Invalid adapter: #{adapter}"
62
63
  end
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  class Premailer
2
3
  class CachedRuleSet < CssParser::RuleSet
3
4
  # we call this early to find errors but css-parser calls it in .merge again
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  require 'optparse'
2
3
  require 'premailer'
3
4
 
@@ -8,12 +9,12 @@ options = {
8
9
  :remove_classes => false,
9
10
  :verbose => false,
10
11
  :line_length => 65,
11
- :adapter => :nokogiri,
12
+ :adapter => :nokogiri
12
13
  }
13
14
 
14
15
  mode = :html
15
16
 
16
- opts = OptionParser.new do |opts|
17
+ parser = OptionParser.new do |opts|
17
18
  opts.banner = "Improve the rendering of HTML emails by making CSS inline among other things. Takes a path to a local file, a URL or a pipe as input.\n\n"
18
19
  opts.define_head "Usage: premailer <optional uri|optional path> [options]"
19
20
  opts.separator ""
@@ -79,7 +80,7 @@ opts = OptionParser.new do |opts|
79
80
  exit
80
81
  end
81
82
  end
82
- opts.parse!
83
+ parser.parse!
83
84
 
84
85
  $stderr.puts "Processing in #{mode} mode with options #{options.inspect}" if options[:verbose]
85
86
 
@@ -98,7 +99,7 @@ end
98
99
  if input
99
100
  premailer = Premailer.new(input, options)
100
101
  else
101
- puts opts
102
+ puts parser
102
103
  exit 1
103
104
  end
104
105
 
@@ -1,4 +1,5 @@
1
1
  # coding: utf-8
2
+ # frozen_string_literal: true
2
3
  require 'htmlentities'
3
4
 
4
5
  # Support functions for Premailer
@@ -13,7 +14,7 @@ module HtmlToPlainText
13
14
  #
14
15
  # TODO: add support for DL, OL
15
16
  # TODO: this is not safe and needs a real html parser to work
16
- def convert_to_text(html, line_length = 65, from_charset = 'UTF-8')
17
+ def convert_to_text(html, line_length = 65, _from_charset = 'UTF-8')
17
18
  txt = +html
18
19
 
19
20
  # strip text ignored html. Useful for removing
@@ -50,7 +51,7 @@ module HtmlToPlainText
50
51
 
51
52
  if text.empty?
52
53
  ''
53
- elsif href.nil? || text.strip.downcase == href.strip.downcase
54
+ elsif href.nil? || text.strip.casecmp(href.strip) == 0
54
55
  text.strip
55
56
  else
56
57
  text.strip + ' ( ' + href.strip + ' )'
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  # Premailer processes HTML and CSS to improve e-mail deliverability.
2
3
  #
3
4
  # Premailer's main function is to render all CSS as inline <tt>style</tt>
@@ -141,7 +142,7 @@ class Premailer
141
142
  include Warnings
142
143
 
143
144
  # Waning level names
144
- WARN_LABEL = %w(NONE SAFE POOR RISKY)
145
+ WARN_LABEL = ['NONE', 'SAFE', 'POOR', 'RISKY']
145
146
 
146
147
  # Create a new Premailer object.
147
148
  #
@@ -212,8 +213,7 @@ class Premailer
212
213
  :create_shorthands => true,
213
214
  :html_fragment => false,
214
215
  :adapter => Adapter.use,
215
- :drop_unmergeable_css_rules => false
216
- }.merge(options)
216
+ :drop_unmergeable_css_rules => false}.merge(options)
217
217
 
218
218
  @html_file = html
219
219
  @is_local_file = @options[:with_html_string] || Premailer.local_data?(html)
@@ -265,10 +265,10 @@ class Premailer
265
265
  protected
266
266
  def load_css_from_local_file!(path)
267
267
  css_block = +''
268
- path.gsub!(/\Afile:/, '')
268
+ path.delete_prefix!('file:')
269
269
  begin
270
270
  File.open(path, "r") do |file|
271
- while line = file.gets
271
+ while (line = file.gets)
272
272
  css_block << line
273
273
  end
274
274
  end
@@ -355,12 +355,12 @@ public
355
355
  media_types.split(/[\s]+|,/).any? { |media_type| media_type.strip =~ /screen|handheld|all/i }
356
356
  end
357
357
 
358
- def append_query_string(doc, qs)
359
- return doc if qs.nil?
358
+ def append_query_string(doc, queries)
359
+ return doc if queries.nil?
360
360
 
361
- qs = +qs
362
- qs.to_s.gsub!(/^[\?]*/, '').strip!
363
- return doc if qs.empty?
361
+ queries = +queries
362
+ queries.to_s.gsub!(/^[\?]*/, '').strip!
363
+ return doc if queries.empty?
364
364
 
365
365
  begin
366
366
  current_host = @base_url.host
@@ -368,18 +368,18 @@ public
368
368
  current_host = nil
369
369
  end
370
370
 
371
- $stderr.puts "Attempting to append_query_string: #{qs}" if @options[:verbose]
371
+ $stderr.puts "Attempting to append_query_string: #{queries}" if @options[:verbose]
372
372
 
373
- doc.search('a').each do|el|
373
+ doc.search('a').each do |el|
374
374
  href = el.attributes['href'].to_s.strip
375
375
  next if href.nil? or href.empty?
376
376
 
377
- next if href[0,1] =~ /[\#\{\[\<\%]/ # don't bother with anchors or special-looking links
377
+ next if /[\#\{\[\<\%]/.match?(href[0,1]) # don't bother with anchors or special-looking links
378
378
 
379
379
  begin
380
380
  href = Addressable::URI.parse(href)
381
381
 
382
- if current_host and href.host != nil and href.host != current_host
382
+ if current_host and !href.host.nil? and href.host != current_host
383
383
  $stderr.puts "Skipping append_query_string for: #{href.to_s} because host is no good" if @options[:verbose]
384
384
  next
385
385
  end
@@ -391,9 +391,9 @@ public
391
391
 
392
392
  if href.query and not href.query.empty?
393
393
  amp = @options[:unescaped_ampersand] ? '&' : '&amp;'
394
- href.query = href.query + amp + qs
394
+ href.query = href.query + amp + queries
395
395
  else
396
- href.query = qs
396
+ href.query = queries
397
397
  end
398
398
 
399
399
  el['href'] = href.to_s
@@ -436,11 +436,11 @@ public
436
436
  tags.each do |tag|
437
437
  # skip links that look like they have merge tags
438
438
  # and mailto, ftp, etc...
439
- if tag.attributes[attribute].to_s =~ /^([\%\<\{\#\[]|data:|tel:|file:|sms:|callto:|facetime:|mailto:|ftp:|gopher:|cid:)/i
439
+ if /^([\%\<\{\#\[]|data:|tel:|file:|sms:|callto:|facetime:|mailto:|ftp:|gopher:|cid:)/i.match?(tag.attributes[attribute].to_s)
440
440
  next
441
441
  end
442
442
 
443
- if tag.attributes[attribute].to_s =~ /^http/i
443
+ if /^http/i.match?(tag.attributes[attribute].to_s)
444
444
  begin
445
445
  merged = Addressable::URI.parse(tag.attributes[attribute])
446
446
  rescue; next; end
@@ -477,7 +477,7 @@ public
477
477
  path = +path
478
478
  path.strip!
479
479
  resolved = nil
480
- if path =~ /\A(?:(https?|ftp|file):)\/\//i
480
+ if /\A(?:(https?|ftp|file):)\/\//i.match?(path)
481
481
  resolved = path
482
482
  Premailer.canonicalize(resolved)
483
483
  elsif base_path.kind_of?(Addressable::URI)
@@ -1,4 +1,5 @@
1
+ # frozen_string_literal: true
1
2
  class Premailer
2
3
  # Premailer version.
3
- VERSION = '1.24.0'.freeze
4
+ VERSION = '1.25.0'
4
5
  end
data/lib/premailer.rb CHANGED
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  require 'yaml'
2
3
  require 'open-uri'
3
4
  require 'digest/sha2'
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: premailer
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.24.0
4
+ version: 1.25.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Alex Dunae
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-08-15 00:00:00.000000000 Z
11
+ date: 2024-08-21 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: css_parser
@@ -129,7 +129,7 @@ dependencies:
129
129
  - !ruby/object:Gem::Version
130
130
  version: '0'
131
131
  - !ruby/object:Gem::Dependency
132
- name: coveralls
132
+ name: webmock
133
133
  requirement: !ruby/object:Gem::Requirement
134
134
  requirements:
135
135
  - - ">="
@@ -143,7 +143,7 @@ dependencies:
143
143
  - !ruby/object:Gem::Version
144
144
  version: '0'
145
145
  - !ruby/object:Gem::Dependency
146
- name: webmock
146
+ name: bump
147
147
  requirement: !ruby/object:Gem::Requirement
148
148
  requirements:
149
149
  - - ">="
@@ -157,7 +157,21 @@ dependencies:
157
157
  - !ruby/object:Gem::Version
158
158
  version: '0'
159
159
  - !ruby/object:Gem::Dependency
160
- name: bump
160
+ name: rubocop
161
+ requirement: !ruby/object:Gem::Requirement
162
+ requirements:
163
+ - - "~>"
164
+ - !ruby/object:Gem::Version
165
+ version: 1.62.1
166
+ type: :development
167
+ prerelease: false
168
+ version_requirements: !ruby/object:Gem::Requirement
169
+ requirements:
170
+ - - "~>"
171
+ - !ruby/object:Gem::Version
172
+ version: 1.62.1
173
+ - !ruby/object:Gem::Dependency
174
+ name: rubocop-performance
161
175
  requirement: !ruby/object:Gem::Requirement
162
176
  requirements:
163
177
  - - ">="