awesomemailer 0.1.4 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/VERSION +1 -1
- data/awesomemailer.gemspec +2 -6
- data/lib/awesome_mailer/renderer.rb +61 -41
- metadata +2 -6
- data/Gemfile +0 -14
- data/Gemfile.lock +0 -103
- data/Guardfile +0 -8
- data/Rakefile +0 -15
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.2.0
|
data/awesomemailer.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = "awesomemailer"
|
8
|
-
s.version = "0.
|
8
|
+
s.version = "0.2.0"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Flip Sasser"]
|
12
|
-
s.date = "2013-
|
12
|
+
s.date = "2013-06-13"
|
13
13
|
s.description = "\n AwesomeMailer embeds your e-mail CSS inline, allowing you to write e-mail templates without worrying too much about stylesheets\n "
|
14
14
|
s.email = "flip@x451.com"
|
15
15
|
s.extra_rdoc_files = [
|
@@ -17,11 +17,7 @@ Gem::Specification.new do |s|
|
|
17
17
|
]
|
18
18
|
s.files = [
|
19
19
|
"CHANGELOG",
|
20
|
-
"Gemfile",
|
21
|
-
"Gemfile.lock",
|
22
|
-
"Guardfile",
|
23
20
|
"README.md",
|
24
|
-
"Rakefile",
|
25
21
|
"VERSION",
|
26
22
|
"awesomemailer.gemspec",
|
27
23
|
"lib/awesome_mailer.rb",
|
@@ -12,7 +12,12 @@ module AwesomeMailer
|
|
12
12
|
# Must be intended for digital screens!
|
13
13
|
load_stylesheet(stylesheet) if stylesheet['media'] =~ /^(all|handheld|screen)$/
|
14
14
|
end
|
15
|
-
|
15
|
+
inline_stylesheets = document.search('style')
|
16
|
+
inline_stylesheets.each do |styles|
|
17
|
+
css_parser.add_block!(styles.inner_html)
|
18
|
+
styles.remove
|
19
|
+
end
|
20
|
+
apply_css!
|
16
21
|
end
|
17
22
|
|
18
23
|
def to_html
|
@@ -20,41 +25,51 @@ module AwesomeMailer
|
|
20
25
|
end
|
21
26
|
|
22
27
|
private
|
23
|
-
def
|
24
|
-
|
25
|
-
|
26
|
-
|
28
|
+
def apply_styles_to_body!(selector, properties)
|
29
|
+
rewrite_relative_urls(properties) if host
|
30
|
+
search_selector = selector =~ /^body/ ? selector : "body #{selector}"
|
31
|
+
document.search(search_selector).each do |element|
|
32
|
+
element['style'] = [element['style'], properties].flatten.compact.join('; ')
|
27
33
|
end
|
28
34
|
end
|
29
35
|
|
30
|
-
def
|
31
|
-
|
32
|
-
|
33
|
-
selector_and_declarations = "@media #{media} { #{selector_and_declarations} }"
|
34
|
-
end
|
35
|
-
header_stylesheet.inner_html += "#{selector_and_declarations}\n"
|
36
|
+
def apply_styles_to_head!(selector, properties, indent = 0)
|
37
|
+
rewrite_relative_urls(properties) if host
|
38
|
+
header_stylesheet.inner_html += "#{" " * indent}#{selector} { #{properties.join('; ')} }\n"
|
36
39
|
end
|
37
40
|
|
38
|
-
def apply_css!
|
41
|
+
def apply_css!
|
42
|
+
css_parser.compact!
|
43
|
+
applied_rules = []
|
44
|
+
|
45
|
+
# Apply @media queries to the document head
|
39
46
|
css_parser.rules_by_media_query.each do |media_query, rules|
|
47
|
+
next if media_query == :all
|
48
|
+
header_stylesheet.inner_html += "@media #{media_query} {\n"
|
40
49
|
rules.each do |rule|
|
41
|
-
rule.each_selector do |selector,
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
50
|
+
rule.each_selector do |selector, properties, specificity|
|
51
|
+
properties = properties.split(';').map(&:strip)
|
52
|
+
apply_styles_to_head!(selector, properties, 2)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
header_stylesheet.inner_html += "}\n"
|
56
|
+
applied_rules.push(*rules)
|
57
|
+
end
|
58
|
+
|
59
|
+
# Apply all other styles
|
60
|
+
css_parser.each_rule_set do |rule|
|
61
|
+
next if applied_rules.include? rule
|
62
|
+
rule.each_selector do |selector, properties, specificity|
|
63
|
+
properties = properties.split(';').map(&:strip)
|
64
|
+
if selector =~ /(^@|:(active|checked|disabled|enabled|focus|hover|lang|link|target|visited|:)|moz|webkit)/
|
65
|
+
# Special selectors get sent to the <head> tag
|
66
|
+
apply_styles_to_head!(selector, properties)
|
67
|
+
else
|
68
|
+
vendor_specific_properties = properties.select {|property| property =~ /^-/ }
|
69
|
+
# Special properties get sent to the <head> tag
|
70
|
+
apply_styles_to_head!(selector, vendor_specific_properties) unless vendor_specific_properties.empty?
|
71
|
+
# Everything else winds up inline on the body
|
72
|
+
apply_styles_to_body!(selector, properties - vendor_specific_properties)
|
58
73
|
end
|
59
74
|
end
|
60
75
|
end
|
@@ -69,11 +84,12 @@ module AwesomeMailer
|
|
69
84
|
|
70
85
|
def asset_pipeline_path
|
71
86
|
return false unless sprockets?
|
72
|
-
|
87
|
+
path = File.join('', Rails.configuration.assets[:prefix], '').gsub('//', '/')
|
88
|
+
/^#{Regexp.escape(path)}/
|
73
89
|
end
|
74
90
|
|
75
91
|
def css_parser
|
76
|
-
@css_parser ||= CssParser::Parser.new
|
92
|
+
@css_parser ||= CssParser::Parser.new(absolute_paths: true)
|
77
93
|
end
|
78
94
|
|
79
95
|
def default_host
|
@@ -109,13 +125,15 @@ module AwesomeMailer
|
|
109
125
|
when asset_pipeline_path
|
110
126
|
if asset = read_asset_pipeline_asset(stylesheet_path)
|
111
127
|
css_parser.add_block!(asset.to_s)
|
128
|
+
else
|
129
|
+
Rails.logger.error 'AwesomeMailer error. Could not find: ' + stylesheet_path if rails?
|
112
130
|
end
|
113
131
|
when /^\//
|
114
132
|
local_path = rails? && Rails.root.join('public', stylesheet_path.gsub(/^\//, '')).to_s
|
115
|
-
css_parser.load_file!(local_path) if local_path && File.file?(local_path)
|
133
|
+
css_parser.load_file!(local_path, nil, []) if local_path && File.file?(local_path)
|
116
134
|
else
|
117
135
|
dirname = File.dirname(stylesheet['href'])
|
118
|
-
css_parser.load_uri!(stylesheet['href'], base_uri: dirname)
|
136
|
+
css_parser.load_uri!(stylesheet['href'], base_uri: dirname, media_types: [])
|
119
137
|
end
|
120
138
|
stylesheet.remove
|
121
139
|
end
|
@@ -125,17 +143,19 @@ module AwesomeMailer
|
|
125
143
|
end
|
126
144
|
|
127
145
|
def read_asset_pipeline_asset(path)
|
128
|
-
path = path.gsub(asset_pipeline_path, '')
|
146
|
+
path = path.gsub(asset_pipeline_path, '').gsub(/-[A-Fa-f0-9]{32}/, '')
|
129
147
|
Rails.application.assets[path]
|
130
148
|
end
|
131
149
|
|
132
|
-
def rewrite_relative_urls(
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
150
|
+
def rewrite_relative_urls(properties)
|
151
|
+
properties.each do |property|
|
152
|
+
property.scan(/(url\s*\(?["']+(.[^'"]*)["']\))/i).each do |url_command, item|
|
153
|
+
next if item =~ /^http(s){0,1}:\/\//
|
154
|
+
item_url = host.dup
|
155
|
+
item_url.path = File.join(item_url.path, item)
|
156
|
+
new_url_command = url_command.gsub(item, item_url.to_s)
|
157
|
+
property[url_command] = new_url_command
|
158
|
+
end
|
139
159
|
end
|
140
160
|
end
|
141
161
|
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: awesomemailer
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2013-
|
12
|
+
date: 2013-06-13 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: actionmailer
|
@@ -84,11 +84,7 @@ extra_rdoc_files:
|
|
84
84
|
- README.md
|
85
85
|
files:
|
86
86
|
- CHANGELOG
|
87
|
-
- Gemfile
|
88
|
-
- Gemfile.lock
|
89
|
-
- Guardfile
|
90
87
|
- README.md
|
91
|
-
- Rakefile
|
92
88
|
- VERSION
|
93
89
|
- awesomemailer.gemspec
|
94
90
|
- lib/awesome_mailer.rb
|
data/Gemfile
DELETED
@@ -1,14 +0,0 @@
|
|
1
|
-
source 'http://rubygems.org'
|
2
|
-
|
3
|
-
gem 'actionmailer', '>= 3.2'
|
4
|
-
gem 'addressable'
|
5
|
-
gem 'css_parser', '>= 1.2.5'
|
6
|
-
gem 'nokogiri', '>= 1.5.6'
|
7
|
-
|
8
|
-
group :test do
|
9
|
-
gem 'guard-rspec', require: false
|
10
|
-
gem 'jeweler', require: false
|
11
|
-
gem 'pry'
|
12
|
-
gem 'rspec', require: false
|
13
|
-
gem 'simplecov', require: false
|
14
|
-
end
|
data/Gemfile.lock
DELETED
@@ -1,103 +0,0 @@
|
|
1
|
-
GEM
|
2
|
-
remote: http://rubygems.org/
|
3
|
-
specs:
|
4
|
-
actionmailer (3.2.8)
|
5
|
-
actionpack (= 3.2.8)
|
6
|
-
mail (~> 2.4.4)
|
7
|
-
actionpack (3.2.8)
|
8
|
-
activemodel (= 3.2.8)
|
9
|
-
activesupport (= 3.2.8)
|
10
|
-
builder (~> 3.0.0)
|
11
|
-
erubis (~> 2.7.0)
|
12
|
-
journey (~> 1.0.4)
|
13
|
-
rack (~> 1.4.0)
|
14
|
-
rack-cache (~> 1.2)
|
15
|
-
rack-test (~> 0.6.1)
|
16
|
-
sprockets (~> 2.1.3)
|
17
|
-
activemodel (3.2.8)
|
18
|
-
activesupport (= 3.2.8)
|
19
|
-
builder (~> 3.0.0)
|
20
|
-
activesupport (3.2.8)
|
21
|
-
i18n (~> 0.6)
|
22
|
-
multi_json (~> 1.0)
|
23
|
-
addressable (2.3.2)
|
24
|
-
builder (3.0.4)
|
25
|
-
coderay (1.0.9)
|
26
|
-
css_parser (1.2.6)
|
27
|
-
addressable
|
28
|
-
rdoc
|
29
|
-
diff-lcs (1.1.3)
|
30
|
-
erubis (2.7.0)
|
31
|
-
git (1.2.5)
|
32
|
-
guard (1.4.0)
|
33
|
-
listen (>= 0.4.2)
|
34
|
-
thor (>= 0.14.6)
|
35
|
-
guard-rspec (1.2.1)
|
36
|
-
guard (>= 1.1)
|
37
|
-
hike (1.2.1)
|
38
|
-
i18n (0.6.1)
|
39
|
-
jeweler (1.8.4)
|
40
|
-
bundler (~> 1.0)
|
41
|
-
git (>= 1.2.5)
|
42
|
-
rake
|
43
|
-
rdoc
|
44
|
-
journey (1.0.4)
|
45
|
-
json (1.7.5)
|
46
|
-
listen (0.5.2)
|
47
|
-
mail (2.4.4)
|
48
|
-
i18n (>= 0.4.0)
|
49
|
-
mime-types (~> 1.16)
|
50
|
-
treetop (~> 1.4.8)
|
51
|
-
method_source (0.8.1)
|
52
|
-
mime-types (1.19)
|
53
|
-
multi_json (1.3.7)
|
54
|
-
nokogiri (1.5.6)
|
55
|
-
polyglot (0.3.3)
|
56
|
-
pry (0.9.12)
|
57
|
-
coderay (~> 1.0.5)
|
58
|
-
method_source (~> 0.8)
|
59
|
-
slop (~> 3.4)
|
60
|
-
rack (1.4.1)
|
61
|
-
rack-cache (1.2)
|
62
|
-
rack (>= 0.4)
|
63
|
-
rack-test (0.6.2)
|
64
|
-
rack (>= 1.0)
|
65
|
-
rake (0.9.2.2)
|
66
|
-
rdoc (3.12)
|
67
|
-
json (~> 1.4)
|
68
|
-
rspec (2.11.0)
|
69
|
-
rspec-core (~> 2.11.0)
|
70
|
-
rspec-expectations (~> 2.11.0)
|
71
|
-
rspec-mocks (~> 2.11.0)
|
72
|
-
rspec-core (2.11.1)
|
73
|
-
rspec-expectations (2.11.3)
|
74
|
-
diff-lcs (~> 1.1.3)
|
75
|
-
rspec-mocks (2.11.2)
|
76
|
-
simplecov (0.7.1)
|
77
|
-
multi_json (~> 1.0)
|
78
|
-
simplecov-html (~> 0.7.1)
|
79
|
-
simplecov-html (0.7.1)
|
80
|
-
slop (3.4.4)
|
81
|
-
sprockets (2.1.3)
|
82
|
-
hike (~> 1.2)
|
83
|
-
rack (~> 1.0)
|
84
|
-
tilt (~> 1.1, != 1.3.0)
|
85
|
-
thor (0.16.0)
|
86
|
-
tilt (1.3.3)
|
87
|
-
treetop (1.4.12)
|
88
|
-
polyglot
|
89
|
-
polyglot (>= 0.3.1)
|
90
|
-
|
91
|
-
PLATFORMS
|
92
|
-
ruby
|
93
|
-
|
94
|
-
DEPENDENCIES
|
95
|
-
actionmailer (>= 3.2)
|
96
|
-
addressable
|
97
|
-
css_parser (>= 1.2.5)
|
98
|
-
guard-rspec
|
99
|
-
jeweler
|
100
|
-
nokogiri (>= 1.5.6)
|
101
|
-
pry
|
102
|
-
rspec
|
103
|
-
simplecov
|
data/Guardfile
DELETED
data/Rakefile
DELETED
@@ -1,15 +0,0 @@
|
|
1
|
-
begin
|
2
|
-
require 'jeweler'
|
3
|
-
Jeweler::Tasks.new do |gem|
|
4
|
-
gem.name = "awesomemailer"
|
5
|
-
gem.summary = "An ActionMailer extension that embeds CSS inline in e-mails"
|
6
|
-
gem.description = %{
|
7
|
-
AwesomeMailer embeds your e-mail CSS inline, allowing you to write e-mail templates without worrying too much about stylesheets
|
8
|
-
}
|
9
|
-
gem.email = "flip@x451.com"
|
10
|
-
gem.homepage = "http://github.com/Plinq/awesome_mailer"
|
11
|
-
gem.authors = ["Flip Sasser"]
|
12
|
-
gem.files.exclude '.rspec', '.rvmrc', 'spec/**/*'
|
13
|
-
end
|
14
|
-
rescue LoadError
|
15
|
-
end
|