premailer 1.11.1 → 1.18.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
- SHA1:
3
- metadata.gz: 2e98876ae79a7e20d9a4ce73747f40099d4f19a1
4
- data.tar.gz: f9f95d0fbc0b3304db6cd772069729a5801c388d
2
+ SHA256:
3
+ metadata.gz: b4a7dce51bfedaef59c17b84a78c74af9dbd6af2a32ae2e64bbb8105346a152e
4
+ data.tar.gz: cc17465063476f728e4dd1308909dfd0c240b32f53d250dafa307da7b1fde01a
5
5
  SHA512:
6
- metadata.gz: 88f3f5d7ba2f1e4ca8e0afdb33b2514352b80914ed98629bab52d9b92450dfa0b133994d08f0f3f3b42f33d10f0e90253432592ebcb0a931bbb7b1f54465dcfe
7
- data.tar.gz: 3d61952d50bfc6ea280fa9f36da8da0a8e7df1af5967c9e742334a26bc916bbe0db463efb69e70f62b77e6770b18cc52b821b2d36d0f9d37c56bd36b803af037
6
+ metadata.gz: a402ccb956b7c663190ac6adffdfe56ed38352e58a1dd599d5f1999f7417aeae4e3f820bc1745b32c937be5334b3046fb6fd64be9b42d6dd362b847c49f0ac12
7
+ data.tar.gz: f9ce454c789ad0082b98bc246cfd055a27d24e2dad37edf95921595ae30c377151f713877c346573a55ac13236fcadfa8912035d3e7efd4cd525b07df5959745
data/README.md CHANGED
@@ -1,4 +1,4 @@
1
- # Premailer README [![Build Status](https://travis-ci.org/premailer/premailer.png?branch=master)](https://travis-ci.org/premailer/premailer) [![Gem Version](https://badge.fury.io/rb/premailer.svg)](https://badge.fury.io/rb/premailer)
1
+ # Premailer README [![CI](https://github.com/premailer/premailer/actions/workflows/actions.yml/badge.svg)](https://github.com/premailer/premailer/actions/workflows/actions.yml) [![Gem Version](https://badge.fury.io/rb/premailer.svg)](https://badge.fury.io/rb/premailer)
2
2
 
3
3
  ## What is this?
4
4
 
@@ -12,7 +12,7 @@ script is my solution.
12
12
  - Checks links in `href`, `src` and CSS `url('')`
13
13
  * CSS properties are checked against e-mail client capabilities
14
14
  - Based on the Email Standards Project's guides
15
- * A plain text version is created (optional)
15
+ * A [plain text version](https://premailer.github.io/premailer/HtmlToPlainText.html) is created (optional)
16
16
 
17
17
  ## Installation
18
18
 
@@ -68,7 +68,7 @@ Premailer::Adapter.use = :nokogiri_fast
68
68
 
69
69
  ## Ruby Compatibility
70
70
 
71
- Premailer is tested on Ruby 2.1 and above. JRuby support is close; contributors are welcome. Checkout the latest build status on the [Travis CI dashboard](https://travis-ci.org/#!/premailer/premailer).
71
+ See .github/workflows/actions.yml for which ruby versions are tested. JRuby support is close, contributors are welcome.
72
72
 
73
73
  ## Premailer-specific CSS
74
74
 
@@ -80,6 +80,7 @@ Premailer looks for a few CSS attributes that make working with tables a bit eas
80
80
  | -premailer-height | Available on `table`, `tr`, `th` and `td` elements |
81
81
  | -premailer-cellpadding | Available on `table` elements |
82
82
  | -premailer-cellspacing | Available on `table` elements |
83
+ | -premailer-align | Available on `table` elements |
83
84
  | data-premailer="ignore" | Available on `link` and `style` elements. Premailer will ignore these elements entirely. |
84
85
 
85
86
  Each of these CSS declarations will be copied to appropriate element's attribute.
@@ -96,6 +97,19 @@ will result in
96
97
  <table cellspacing='5' width='500'>
97
98
  ```
98
99
 
100
+ ## Configuration options
101
+
102
+ The behavior of Premailer can be configured by passing options in the initializer.
103
+
104
+ For example, the following will accept HTML from a string and will exclude unmergeable css from being added to the `<head>` of the output document.
105
+
106
+ ```ruby
107
+ premailer = Premailer.new(html_string, with_html_string: true, drop_unmergeable_css_rules: true)
108
+ ```
109
+
110
+ [See here for a full list of the available options](https://premailer.github.io/premailer/Premailer.html#initialize-instance_method).
111
+
112
+
99
113
  ## Contributions
100
114
 
101
115
  Contributions are most welcome. Premailer was rotting away in a private SVN repository for too long and could use some TLC. Fork and patch to your heart's content. Please don't increment the version numbers, though.
@@ -55,9 +55,7 @@ class Premailer
55
55
  end
56
56
 
57
57
  # Remove script tags
58
- if @options[:remove_scripts]
59
- doc.search("script").remove
60
- end
58
+ doc.search("script").remove if @options[:remove_scripts]
61
59
 
62
60
  # Read STYLE attributes and perform folding
63
61
  doc.search("*[@style]").each do |el|
@@ -65,8 +63,12 @@ class Premailer
65
63
 
66
64
  declarations = []
67
65
  style.scan(/\[SPEC\=([\d]+)\[(.[^\]\]]*)\]\]/).each do |declaration|
68
- rs = CssParser::RuleSet.new(nil, declaration[1].to_s, declaration[0].to_i)
69
- declarations << rs
66
+ begin
67
+ rs = CssParser::RuleSet.new(nil, declaration[1].to_s, declaration[0].to_i)
68
+ declarations << rs
69
+ rescue ArgumentError => e
70
+ raise e if @options[:rule_set_exceptions]
71
+ end
70
72
  end
71
73
 
72
74
  # Perform style folding
@@ -75,18 +77,33 @@ class Premailer
75
77
 
76
78
  # Duplicate CSS attributes as HTML attributes
77
79
  if Premailer::RELATED_ATTRIBUTES.has_key?(el.name) && @options[:css_to_attributes]
78
- Premailer::RELATED_ATTRIBUTES[el.name].each do |css_att, html_att|
79
- if el[html_att].nil? and not merged[css_att].empty?
80
- new_html_att = merged[css_att].gsub(/url\(['"](.*)['"]\)/, '\1').gsub(/;$|\s*!important/, '').strip
81
- el[html_att] = css_att.end_with?('color') && @options[:rgb_to_hex_attributes] ? ensure_hex(new_html_att) : new_html_att
80
+ Premailer::RELATED_ATTRIBUTES[el.name].each do |css_attr, html_attr|
81
+ if el[html_attr].nil? and not merged[css_attr].empty?
82
+ new_val = merged[css_attr].dup
83
+
84
+ # Remove url() function wrapper
85
+ new_val.gsub!(/url\((['"])(.*?)\1\)/, '\2')
86
+
87
+ # Remove !important, trailing semi-colon, and leading/trailing whitespace
88
+ new_val.gsub!(/;$|\s*!important/, '').strip!
89
+
90
+ # For width and height tags, remove px units
91
+ new_val.gsub!(/(\d+)px/, '\1') if %w[width height].include?(html_attr)
92
+
93
+ # For color-related tags, convert RGB to hex if specified by options
94
+ new_val = ensure_hex(new_val) if css_attr.end_with?('color') && @options[:rgb_to_hex_attributes]
95
+
96
+ el[html_attr] = new_val
82
97
  end
98
+
83
99
  unless @options[:preserve_style_attribute]
84
100
  merged.instance_variable_get("@declarations").tap do |declarations|
85
- declarations.delete(css_att)
101
+ declarations.delete(css_attr)
86
102
  end
87
103
  end
88
104
  end
89
105
  end
106
+
90
107
  # Collapse multiple rules into one as much as possible.
91
108
  merged.create_shorthand! if @options[:create_shorthands]
92
109
 
@@ -94,7 +111,7 @@ class Premailer
94
111
  el['style'] = merged.declarations_to_s
95
112
  end
96
113
 
97
- doc = write_unmergable_css_rules(doc, @unmergable_rules)
114
+ doc = write_unmergable_css_rules(doc, @unmergable_rules) unless @options[:drop_unmergeable_css_rules]
98
115
 
99
116
  if @options[:remove_classes] or @options[:remove_comments]
100
117
  doc.traverse do |el|
@@ -112,13 +129,13 @@ class Premailer
112
129
  doc.search("a[@href^='#']").each do |el|
113
130
  target = el.get_attribute('href')[1..-1]
114
131
  targets << target
115
- el.set_attribute('href', "#" + Digest::MD5.hexdigest(target))
132
+ el.set_attribute('href', "#" + Digest::SHA256.hexdigest(target))
116
133
  end
117
134
  # hash ids that are links target, delete others
118
135
  doc.search("*[@id]").each do |el|
119
136
  id = el.get_attribute('id')
120
137
  if targets.include?(id)
121
- el.set_attribute('id', Digest::MD5.hexdigest(id))
138
+ el.set_attribute('id', Digest::SHA256.hexdigest(id))
122
139
  else
123
140
  el.remove_attribute('id')
124
141
  end
@@ -204,7 +221,7 @@ class Premailer
204
221
  @base_dir = File.dirname(input)
205
222
  thing = File.open(input, 'r')
206
223
  else
207
- thing = open(input)
224
+ thing = URI.open(input)
208
225
  end
209
226
 
210
227
  if thing.respond_to?(:read)
@@ -77,18 +77,33 @@ class Premailer
77
77
 
78
78
  # Duplicate CSS attributes as HTML attributes
79
79
  if Premailer::RELATED_ATTRIBUTES.has_key?(el.name) && @options[:css_to_attributes]
80
- Premailer::RELATED_ATTRIBUTES[el.name].each do |css_att, html_att|
81
- if el[html_att].nil? and not merged[css_att].empty?
82
- new_html_att = merged[css_att].gsub(/url\(['"](.*)['"]\)/, '\1').gsub(/;$|\s*!important/, '').strip
83
- el[html_att] = css_att.end_with?('color') && @options[:rgb_to_hex_attributes] ? ensure_hex(new_html_att) : new_html_att
80
+ Premailer::RELATED_ATTRIBUTES[el.name].each do |css_attr, html_attr|
81
+ if el[html_attr].nil? and not merged[css_attr].empty?
82
+ new_val = merged[css_attr].dup
83
+
84
+ # Remove url() function wrapper
85
+ new_val.gsub!(/url\((['"])(.*?)\1\)/, '\2')
86
+
87
+ # Remove !important, trailing semi-colon, and leading/trailing whitespace
88
+ new_val.gsub!(/;$|\s*!important/, '').strip!
89
+
90
+ # For width and height tags, remove px units
91
+ new_val.gsub!(/(\d+)px/, '\1') if %w[width height].include?(html_attr)
92
+
93
+ # For color-related tags, convert RGB to hex if specified by options
94
+ new_val = ensure_hex(new_val) if css_attr.end_with?('color') && @options[:rgb_to_hex_attributes]
95
+
96
+ el[html_attr] = new_val
84
97
  end
98
+
85
99
  unless @options[:preserve_style_attribute]
86
100
  merged.instance_variable_get("@declarations").tap do |declarations|
87
- declarations.delete(css_att)
101
+ declarations.delete(css_attr)
88
102
  end
89
103
  end
90
104
  end
91
105
  end
106
+
92
107
  # Collapse multiple rules into one as much as possible.
93
108
  merged.create_shorthand! if @options[:create_shorthands]
94
109
 
@@ -96,7 +111,7 @@ class Premailer
96
111
  el['style'] = merged.declarations_to_s
97
112
  end
98
113
 
99
- doc = write_unmergable_css_rules(doc, @unmergable_rules)
114
+ doc = write_unmergable_css_rules(doc, @unmergable_rules) unless @options[:drop_unmergeable_css_rules]
100
115
 
101
116
  if @options[:remove_classes] or @options[:remove_comments]
102
117
  doc.traverse do |el|
@@ -114,13 +129,13 @@ class Premailer
114
129
  doc.search("a[@href^='#']").each do |el|
115
130
  target = el.get_attribute('href')[1..-1]
116
131
  targets << target
117
- el.set_attribute('href', "#" + Digest::MD5.hexdigest(target))
132
+ el.set_attribute('href', "#" + Digest::SHA256.hexdigest(target))
118
133
  end
119
134
  # hash ids that are links target, delete others
120
135
  doc.search("*[@id]").each do |el|
121
136
  id = el.get_attribute('id')
122
137
  if targets.include?(id)
123
- el.set_attribute('id', Digest::MD5.hexdigest(id))
138
+ el.set_attribute('id', Digest::SHA256.hexdigest(id))
124
139
  else
125
140
  el.remove_attribute('id')
126
141
  end
@@ -206,7 +221,7 @@ class Premailer
206
221
  @base_dir = File.dirname(input)
207
222
  thing = File.open(input, 'r')
208
223
  else
209
- thing = open(input)
224
+ thing = URI.open(input)
210
225
  end
211
226
 
212
227
  if thing.respond_to?(:read)
@@ -1,5 +1,3 @@
1
- require 'nokogumbo'
2
-
3
1
  class Premailer
4
2
  module Adapter
5
3
  # Nokogiri adapter
@@ -55,9 +53,7 @@ class Premailer
55
53
  end
56
54
 
57
55
  # Remove script tags
58
- if @options[:remove_scripts]
59
- doc.search("script").remove
60
- end
56
+ doc.search("script").remove if @options[:remove_scripts]
61
57
 
62
58
  # Read STYLE attributes and perform folding
63
59
  doc.search("*[@style]").each do |el|
@@ -75,18 +71,33 @@ class Premailer
75
71
 
76
72
  # Duplicate CSS attributes as HTML attributes
77
73
  if Premailer::RELATED_ATTRIBUTES.has_key?(el.name) && @options[:css_to_attributes]
78
- Premailer::RELATED_ATTRIBUTES[el.name].each do |css_att, html_att|
79
- if el[html_att].nil? and not merged[css_att].empty?
80
- new_html_att = merged[css_att].gsub(/url\(['"](.*)['"]\)/, '\1').gsub(/;$|\s*!important/, '').strip
81
- el[html_att] = css_att.end_with?('color') && @options[:rgb_to_hex_attributes] ? ensure_hex(new_html_att) : new_html_att
74
+ Premailer::RELATED_ATTRIBUTES[el.name].each do |css_attr, html_attr|
75
+ if el[html_attr].nil? and not merged[css_attr].empty?
76
+ new_val = merged[css_attr].dup
77
+
78
+ # Remove url() function wrapper
79
+ new_val.gsub!(/url\((['"])(.*?)\1\)/, '\2')
80
+
81
+ # Remove !important, trailing semi-colon, and leading/trailing whitespace
82
+ new_val.gsub!(/;$|\s*!important/, '').strip!
83
+
84
+ # For width and height tags, remove px units
85
+ new_val.gsub!(/(\d+)px/, '\1') if %w[width height].include?(html_attr)
86
+
87
+ # For color-related tags, convert RGB to hex if specified by options
88
+ new_val = ensure_hex(new_val) if css_attr.end_with?('color') && @options[:rgb_to_hex_attributes]
89
+
90
+ el[html_attr] = new_val
82
91
  end
92
+
83
93
  unless @options[:preserve_style_attribute]
84
94
  merged.instance_variable_get("@declarations").tap do |declarations|
85
- declarations.delete(css_att)
95
+ declarations.delete(css_attr)
86
96
  end
87
97
  end
88
98
  end
89
99
  end
100
+
90
101
  # Collapse multiple rules into one as much as possible.
91
102
  merged.create_shorthand! if @options[:create_shorthands]
92
103
 
@@ -94,7 +105,7 @@ class Premailer
94
105
  el['style'] = merged.declarations_to_s
95
106
  end
96
107
 
97
- doc = write_unmergable_css_rules(doc, @unmergable_rules)
108
+ doc = write_unmergable_css_rules(doc, @unmergable_rules) unless @options[:drop_unmergeable_css_rules]
98
109
 
99
110
  if @options[:remove_classes] or @options[:remove_comments]
100
111
  doc.traverse do |el|
@@ -112,13 +123,13 @@ class Premailer
112
123
  doc.search("a[@href^='#']").each do |el|
113
124
  target = el.get_attribute('href')[1..-1]
114
125
  targets << target
115
- el.set_attribute('href', "#" + Digest::MD5.hexdigest(target))
126
+ el.set_attribute('href', "#" + Digest::SHA256.hexdigest(target))
116
127
  end
117
128
  # hash ids that are links target, delete others
118
129
  doc.search("*[@id]").each do |el|
119
130
  id = el.get_attribute('id')
120
131
  if targets.include?(id)
121
- el.set_attribute('id', Digest::MD5.hexdigest(id))
132
+ el.set_attribute('id', Digest::SHA256.hexdigest(id))
122
133
  else
123
134
  el.remove_attribute('id')
124
135
  end
@@ -204,7 +215,7 @@ class Premailer
204
215
  @base_dir = File.dirname(input)
205
216
  thing = File.open(input, 'r')
206
217
  else
207
- thing = open(input)
218
+ thing = URI.open(input)
208
219
  end
209
220
 
210
221
  if thing.respond_to?(:read)
@@ -226,9 +237,9 @@ class Premailer
226
237
  thing = thing.force_encoding(@options[:input_encoding]).encode!
227
238
  end
228
239
  doc = if @options[:html_fragment]
229
- ::Nokogiri::HTML5(thing)
230
- else
231
240
  ::Nokogiri::HTML5.fragment(thing)
241
+ else
242
+ ::Nokogiri::HTML5(thing)
232
243
  end
233
244
 
234
245
  # Fix for removing any CDATA tags from both style and script tags inserted per
@@ -6,7 +6,13 @@ module HtmlToPlainText
6
6
 
7
7
  # Returns the text in UTF-8 format with all HTML tags removed
8
8
  #
9
+ # HTML content can be omitted from the output by surrounding it in the following comments:
10
+ #
11
+ # <!-- start text/html -->
12
+ # <!-- end text/html -->
13
+ #
9
14
  # TODO: add support for DL, OL
15
+ # TODO: this is not safe and needs a real html parser to work
10
16
  def convert_to_text(html, line_length = 65, from_charset = 'UTF-8')
11
17
  txt = html
12
18
 
@@ -21,23 +27,33 @@ module HtmlToPlainText
21
27
  # eg. the following formats:
22
28
  # <img alt="" />
23
29
  # <img alt="">
24
- txt.gsub!(/<img.+?alt=\"([^\"]*)\"[^>]*\>/i, '\1')
30
+ txt.gsub!(/<img[^>]+?alt="([^"]*)"[^>]*>/i, '\1')
25
31
 
26
32
  # for img tags with '' for attribute quotes
27
33
  # with or without closing tag
28
34
  # eg. the following formats:
29
35
  # <img alt='' />
30
36
  # <img alt=''>
31
- txt.gsub!(/<img.+?alt=\'([^\']*)\'[^>]*\>/i, '\1')
37
+ txt.gsub!(/<img[^>]+?alt='([^']*)'[^>]*>/i, '\1')
38
+
39
+ # remove script tags and content
40
+ txt.gsub!(/<script.*?\/script>/m, '')
32
41
 
33
42
  # links
34
- txt.gsub!(/<a\s[^\n]*?href=["'](mailto:)?([^"']*)["'][^>]*>(.*?)<\/a>/im) do |s|
35
- if $3.empty?
43
+ txt.gsub!(/<a\s+([^>]+)>(.*?)<\/a>/im) do |s|
44
+ text = $2.strip
45
+
46
+ match = /href=(['"])(?:mailto:)?(.+?)\1/.match(s)
47
+ if match
48
+ href = match[2]
49
+ end
50
+
51
+ if text.empty?
36
52
  ''
37
- elsif $3.strip.downcase == $2.strip.downcase
38
- $3.strip
53
+ elsif href.nil? || text.strip.downcase == href.strip.downcase
54
+ text.strip
39
55
  else
40
- $3.strip + ' ( ' + $2.strip + ' )'
56
+ text.strip + ' ( ' + href.strip + ' )'
41
57
  end
42
58
  end
43
59
 
@@ -56,12 +72,12 @@ module HtmlToPlainText
56
72
  hlength = line_length if hlength > line_length
57
73
 
58
74
  case hlevel
59
- when 1 # H1, asterisks above and below
60
- htext = ('*' * hlength) + "\n" + htext + "\n" + ('*' * hlength)
61
- when 2 # H1, dashes above and below
62
- htext = ('-' * hlength) + "\n" + htext + "\n" + ('-' * hlength)
63
- else # H3-H6, dashes below
64
- htext = htext + "\n" + ('-' * hlength)
75
+ when 1 # H1, asterisks above and below
76
+ htext = ('*' * hlength) + "\n" + htext + "\n" + ('*' * hlength)
77
+ when 2 # H1, dashes above and below
78
+ htext = ('-' * hlength) + "\n" + htext + "\n" + ('-' * hlength)
79
+ else # H3-H6, dashes below
80
+ htext = htext + "\n" + ('-' * hlength)
65
81
  end
66
82
 
67
83
  "\n\n" + htext + "\n\n"
@@ -151,14 +151,14 @@ class Premailer
151
151
  #
152
152
  # @param [Hash] options the options to handle html with.
153
153
  # @option options [Fixnum] :line_length Line length used by to_plain_text. Default is 65.
154
- # @option options [Fixnum] :warn_level What level of CSS compatibility warnings to show (see {Premailer::Warnings}).
154
+ # @option options [Fixnum] :warn_level What level of CSS compatibility warnings to show (see {Premailer::Warnings}, default is Warnings::SAFE).
155
155
  # @option options [String] :link_query_string A string to append to every <tt>a href=""</tt> link. Do not include the initial <tt>?</tt>.
156
156
  # @option options [String] :base_url Used to calculate absolute URLs for local files.
157
157
  # @option options [Array(String)] :css Manually specify CSS stylesheets.
158
- # @option options [Boolean] :css_to_attributes Copy related CSS attributes into HTML attributes (e.g. background-color to bgcolor)
158
+ # @option options [Boolean] :css_to_attributes Copy related CSS attributes into HTML attributes (e.g. background-color to bgcolor). Default is true.
159
159
  # @option options [Boolean] :preserve_style_attribute Preserve original style attribute
160
160
  # @option options [String] :css_string Pass CSS as a string
161
- # @option options [Boolean] :rgb_to_hex_attributes Convert RBG to Hex colors, default false
161
+ # @option options [Boolean] :rgb_to_hex_attributes Convert RBG to Hex colors. Default is false.
162
162
  # @option options [Boolean] :remove_ids Remove ID attributes whenever possible and convert IDs used as anchors to hashed to avoid collisions in webmail programs. Default is false.
163
163
  # @option options [Boolean] :remove_classes Remove class attributes. Default is false.
164
164
  # @option options [Boolean] :remove_comments Remove html comments. Default is false.
@@ -168,7 +168,8 @@ class Premailer
168
168
  # @option options [Boolean] :preserve_reset Whether to preserve styles associated with the MailChimp reset code. Default is true.
169
169
  # @option options [Boolean] :with_html_string Whether the html param should be treated as a raw string. Default is false.
170
170
  # @option options [Boolean] :verbose Whether to print errors and warnings to <tt>$stderr</tt>. Default is false.
171
- # @option options [Boolean] :io_exceptions Throws exceptions on I/O errors.
171
+ # @option options [Boolean] :io_exceptions Throws exceptions on I/O errors. Default is false.
172
+ # @option options [Boolean] :rule_set_exceptions Throws exceptions on invalid values in CSS Parser rule sets. Default is true.
172
173
  # @option options [Boolean] :include_link_tags Whether to include css from <tt>link rel=stylesheet</tt> tags. Default is true.
173
174
  # @option options [Boolean] :include_style_tags Whether to include css from <tt>style</tt> tags. Default is true.
174
175
  # @option options [String] :input_encoding Manually specify the source documents encoding. This is a good idea. Default is ASCII-8BIT.
@@ -178,6 +179,7 @@ class Premailer
178
179
  # @option options [String] :output_encoding Output encoding option for Nokogiri adapter. Should be set to "US-ASCII" to output HTML entities instead of Unicode characters.
179
180
  # @option options [Boolean] :create_shorthands Combine several properties into a shorthand one, e.g. font: style weight size. Default is true.
180
181
  # @option options [Boolean] :html_fragment Handle HTML fragment without any HTML content wrappers. Default is false.
182
+ # @option options [Boolean] :drop_unmergeable_css_rules Do not include unmergeable css rules in a <tt><style><tt> tag. Default is false.
181
183
  def initialize(html, options = {})
182
184
  @options = {:warn_level => Warnings::SAFE,
183
185
  :line_length => 65,
@@ -199,6 +201,7 @@ class Premailer
199
201
  :verbose => false,
200
202
  :debug => false,
201
203
  :io_exceptions => false,
204
+ :rule_set_exceptions => true,
202
205
  :include_link_tags => true,
203
206
  :include_style_tags => true,
204
207
  :input_encoding => 'ASCII-8BIT',
@@ -209,6 +212,7 @@ class Premailer
209
212
  :create_shorthands => true,
210
213
  :html_fragment => false,
211
214
  :adapter => Adapter.use,
215
+ :drop_unmergeable_css_rules => false
212
216
  }.merge(options)
213
217
 
214
218
  @html_file = html
@@ -231,12 +235,13 @@ class Premailer
231
235
  @css_parser = CssParser::Parser.new({
232
236
  :absolute_paths => true,
233
237
  :import => true,
234
- :io_exceptions => @options[:io_exceptions]
238
+ :io_exceptions => @options[:io_exceptions],
239
+ :rule_set_exceptions => @options[:rule_set_exceptions]
235
240
  })
236
241
 
237
242
  @adapter_class = Adapter.find @options[:adapter]
238
243
 
239
- self.class.send(:include, @adapter_class)
244
+ self.extend(@adapter_class)
240
245
 
241
246
  @doc = load_html(@html_file)
242
247
 
@@ -307,7 +312,7 @@ protected
307
312
  link_uri = File.join(File.dirname(@html_file), tag.attributes['href'].to_s.sub!(@base_url.to_s, ''))
308
313
  end
309
314
  # if the file does not exist locally, try to grab the remote reference
310
- unless File.exists?(link_uri)
315
+ unless File.exist?(link_uri)
311
316
  link_uri = Premailer.resolve_link(tag.attributes['href'].to_s, @html_file)
312
317
  end
313
318
  else
@@ -402,7 +407,7 @@ public
402
407
 
403
408
  # Check for an XHTML doctype
404
409
  def is_xhtml?
405
- intro = @doc.to_html.strip.split("\n")[0..2].join(' ')
410
+ intro = @doc.to_xhtml.strip.split("\n")[0..2].join(' ')
406
411
  is_xhtml = !!(intro =~ /w3c\/\/[\s]*dtd[\s]+xhtml/i)
407
412
  $stderr.puts "Is XHTML? #{is_xhtml.inspect}\nChecked:\n#{intro}" if @options[:debug]
408
413
  is_xhtml
@@ -497,18 +502,13 @@ public
497
502
  def self.canonicalize(uri) # :nodoc:
498
503
  u = uri.kind_of?(Addressable::URI) ? uri : Addressable::URI.parse(uri.to_s)
499
504
  u.normalize!
500
- newpath = u.path
501
- while newpath.gsub!(%r{([^/]+)/\.\./?}) { |match|
502
- $1 == '..' ? match : ''
503
- } do end
504
- newpath = newpath.gsub(%r{/\./}, '/').sub(%r{/\.\z}, '/')
505
- u.path = newpath
506
- u.to_s
507
- end
505
+ u.to_s
506
+ end
508
507
 
509
508
  # Check <tt>CLIENT_SUPPORT_FILE</tt> for any CSS warnings
510
509
  def check_client_support # :nodoc:
511
- @client_support ||= YAML::load(File.open(CLIENT_SUPPORT_FILE))
510
+ kwargs = RUBY_VERSION >= "3.1.0" ? { aliases: true } : {}
511
+ @client_support ||= YAML::load(File.open(CLIENT_SUPPORT_FILE), **kwargs)
512
512
 
513
513
  warnings = []
514
514
  properties = []
@@ -1,4 +1,4 @@
1
1
  class Premailer
2
2
  # Premailer version.
3
- VERSION = '1.11.1'.freeze
3
+ VERSION = '1.18.0'.freeze
4
4
  end
data/lib/premailer.rb CHANGED
@@ -1,6 +1,6 @@
1
1
  require 'yaml'
2
2
  require 'open-uri'
3
- require 'digest/md5'
3
+ require 'digest/sha2'
4
4
  require 'cgi'
5
5
  require 'addressable/uri'
6
6
  require 'css_parser'
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.11.1
4
+ version: 1.18.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: 2017-11-14 00:00:00.000000000 Z
11
+ date: 2022-10-07 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: css_parser
@@ -16,14 +16,14 @@ dependencies:
16
16
  requirements:
17
17
  - - ">="
18
18
  - !ruby/object:Gem::Version
19
- version: 1.6.0
19
+ version: 1.12.0
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - ">="
25
25
  - !ruby/object:Gem::Version
26
- version: 1.6.0
26
+ version: 1.12.0
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: htmlentities
29
29
  requirement: !ruby/object:Gem::Requirement
@@ -92,28 +92,14 @@ dependencies:
92
92
  requirements:
93
93
  - - "~>"
94
94
  - !ruby/object:Gem::Version
95
- version: '1.7'
95
+ version: '1.13'
96
96
  type: :development
97
97
  prerelease: false
98
98
  version_requirements: !ruby/object:Gem::Requirement
99
99
  requirements:
100
100
  - - "~>"
101
101
  - !ruby/object:Gem::Version
102
- version: '1.7'
103
- - !ruby/object:Gem::Dependency
104
- name: yard
105
- requirement: !ruby/object:Gem::Requirement
106
- requirements:
107
- - - ">="
108
- - !ruby/object:Gem::Version
109
- version: '0'
110
- type: :development
111
- prerelease: false
112
- version_requirements: !ruby/object:Gem::Requirement
113
- requirements:
114
- - - ">="
115
- - !ruby/object:Gem::Version
116
- version: '0'
102
+ version: '1.13'
117
103
  - !ruby/object:Gem::Dependency
118
104
  name: redcarpet
119
105
  requirement: !ruby/object:Gem::Requirement
@@ -171,7 +157,7 @@ dependencies:
171
157
  - !ruby/object:Gem::Version
172
158
  version: '0'
173
159
  - !ruby/object:Gem::Dependency
174
- name: nokogumbo
160
+ name: bump
175
161
  requirement: !ruby/object:Gem::Requirement
176
162
  requirements:
177
163
  - - ">="
@@ -207,7 +193,8 @@ files:
207
193
  - lib/premailer/version.rb
208
194
  - misc/client_support.yaml
209
195
  homepage: https://github.com/premailer/premailer
210
- licenses: []
196
+ licenses:
197
+ - BSD-3-Clause
211
198
  metadata:
212
199
  yard.run: yri
213
200
  post_install_message:
@@ -218,15 +205,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
218
205
  requirements:
219
206
  - - ">="
220
207
  - !ruby/object:Gem::Version
221
- version: 2.1.0
208
+ version: 2.7.0
222
209
  required_rubygems_version: !ruby/object:Gem::Requirement
223
210
  requirements:
224
211
  - - ">="
225
212
  - !ruby/object:Gem::Version
226
213
  version: '0'
227
214
  requirements: []
228
- rubyforge_project:
229
- rubygems_version: 2.6.12
215
+ rubygems_version: 3.1.6
230
216
  signing_key:
231
217
  specification_version: 4
232
218
  summary: Preflight for HTML e-mail.