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 +5 -5
- data/README.md +17 -3
- data/lib/premailer/adapter/nokogiri.rb +31 -14
- data/lib/premailer/adapter/nokogiri_fast.rb +24 -9
- data/lib/premailer/adapter/nokogumbo.rb +27 -16
- data/lib/premailer/html_to_plain_text.rb +29 -13
- data/lib/premailer/premailer.rb +17 -17
- data/lib/premailer/version.rb +1 -1
- data/lib/premailer.rb +1 -1
- metadata +11 -25
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: b4a7dce51bfedaef59c17b84a78c74af9dbd6af2a32ae2e64bbb8105346a152e
|
4
|
+
data.tar.gz: cc17465063476f728e4dd1308909dfd0c240b32f53d250dafa307da7b1fde01a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a402ccb956b7c663190ac6adffdfe56ed38352e58a1dd599d5f1999f7417aeae4e3f820bc1745b32c937be5334b3046fb6fd64be9b42d6dd362b847c49f0ac12
|
7
|
+
data.tar.gz: f9ce454c789ad0082b98bc246cfd055a27d24e2dad37edf95921595ae30c377151f713877c346573a55ac13236fcadfa8912035d3e7efd4cd525b07df5959745
|
data/README.md
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# Premailer README [](https://github.com/premailer/premailer/actions/workflows/actions.yml) [](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
|
-
|
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
|
-
|
69
|
-
|
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 |
|
79
|
-
if el[
|
80
|
-
|
81
|
-
|
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
|
-
|
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::
|
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::
|
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 |
|
81
|
-
if el[
|
82
|
-
|
83
|
-
|
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
|
-
|
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::
|
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::
|
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 |
|
79
|
-
if el[
|
80
|
-
|
81
|
-
|
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
|
-
|
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::
|
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::
|
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
|
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
|
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
|
35
|
-
|
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
|
38
|
-
|
53
|
+
elsif href.nil? || text.strip.downcase == href.strip.downcase
|
54
|
+
text.strip
|
39
55
|
else
|
40
|
-
|
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
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
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"
|
data/lib/premailer/premailer.rb
CHANGED
@@ -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
|
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.
|
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.
|
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.
|
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
|
-
|
501
|
-
|
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
|
-
|
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 = []
|
data/lib/premailer/version.rb
CHANGED
data/lib/premailer.rb
CHANGED
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.
|
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:
|
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.
|
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.
|
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.
|
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.
|
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:
|
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.
|
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
|
-
|
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.
|