premailer-rails 1.3.2
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 +7 -0
- data/.gitignore +3 -0
- data/.rspec +2 -0
- data/.travis.yml +10 -0
- data/CHANGELOG.md +16 -0
- data/Gemfile +8 -0
- data/LICENSE +14 -0
- data/README.md +86 -0
- data/Rakefile +7 -0
- data/VERSION +1 -0
- data/lib/premailer/rails.rb +23 -0
- data/lib/premailer/rails/css_helper.rb +58 -0
- data/lib/premailer/rails/css_loaders.rb +66 -0
- data/lib/premailer/rails/customized_premailer.rb +20 -0
- data/lib/premailer/rails/hook.rb +45 -0
- data/lib/premailer/rails/nokogiri_fix.rb +13 -0
- data/lib/premailer/rails/premailer.rb +20 -0
- data/lib/premailer/rails/version.rb +7 -0
- data/lib/premailer/rails3.rb +23 -0
- data/premailer-rails.gemspec +32 -0
- data/spec/fixtures/html.rb +42 -0
- data/spec/fixtures/message.rb +86 -0
- data/spec/lib/css_helper_spec.rb +160 -0
- data/spec/lib/customized_premailer_spec.rb +62 -0
- data/spec/lib/hook_registration_spec.rb +10 -0
- data/spec/lib/hook_spec.rb +105 -0
- data/spec/lib/premailer_rails_3_spec.rb +11 -0
- data/spec/spec_helper.rb +13 -0
- data/spec/stubs/action_mailer.rb +5 -0
- data/spec/stubs/dummy.rb +5 -0
- data/spec/stubs/rails.rb +65 -0
- metadata +201 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: b7fe7ad5147d3f2fc55adfb214b582cf36cb6e8d
|
4
|
+
data.tar.gz: c89ed93ba60d97da47d9052a4021ec9464ca6f61
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 51cfbedc2689258c5bf481d573365b25c7116ebccdad4be79115d68e10515cfe5651c77e9d34fd31f70c5b0170f7e86b0b02c3fa5a887627be81157bf9c8f479
|
7
|
+
data.tar.gz: f39cd91e3c94347be787f47a2aa6487a27c046d007981a164ad30d394924d0f64b38743bd708e2b5d56c3f14dce07de3bd5caefc06a4a3d41ec993fd0019bceb
|
data/.gitignore
ADDED
data/.rspec
ADDED
data/.travis.yml
ADDED
data/CHANGELOG.md
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
# Changelog
|
2
|
+
|
3
|
+
## v1.1.0
|
4
|
+
|
5
|
+
- Fixed several bugs
|
6
|
+
|
7
|
+
- Strip asset digest from CSS path
|
8
|
+
|
9
|
+
- Improve nokogiri support
|
10
|
+
|
11
|
+
- Request CSS file if asset is not found locally
|
12
|
+
|
13
|
+
This allows you to host all your assets on a CDN and deploy the
|
14
|
+
app without the `app/assets` folder.
|
15
|
+
|
16
|
+
Thanks to everyone who contributed!
|
data/Gemfile
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
Copyright (C) 2011-2012 Philipe Fatio (fphilipe)
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
|
4
|
+
documentation files (the "Software"), to deal in the Software without restriction, including without limitation the
|
5
|
+
rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit
|
6
|
+
persons to whom the Software is furnished to do so, subject to the following conditions:
|
7
|
+
|
8
|
+
The above copyright notice and this permission notice shall be included in all copies or substantial portions of
|
9
|
+
the Software.
|
10
|
+
|
11
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
|
12
|
+
WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
13
|
+
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
14
|
+
OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,86 @@
|
|
1
|
+
# premailer-rails
|
2
|
+
|
3
|
+
[](https://travis-ci.org/fphilipe/premailer-rails)
|
4
|
+
[](http://badge.fury.io/rb/premailer-rails)
|
5
|
+
[](https://gemnasium.com/fphilipe/premailer-rails)
|
6
|
+
[](https://codeclimate.com/github/fphilipe/premailer-rails)
|
7
|
+
|
8
|
+
This gem is a no config solution for the wonderful
|
9
|
+
[Premailer gem](https://github.com/alexdunae/premailer) to be used with Rails.
|
10
|
+
It uses interceptors which were introduced in Rails 3 and tweaks all mails which
|
11
|
+
are `deliver`ed and adds a plain text part to them and inlines all CSS rules
|
12
|
+
into the HTML part.
|
13
|
+
|
14
|
+
By default it inlines all the CSS files that are linked to in the HTML:
|
15
|
+
|
16
|
+
```html
|
17
|
+
<link type='text/css' ... />
|
18
|
+
```
|
19
|
+
|
20
|
+
Don't worry about the host in the CSS URL since this will be ignored.
|
21
|
+
|
22
|
+
Every CSS file is loaded from within the app.
|
23
|
+
The retrieval of the file depends on your assets configuration:
|
24
|
+
|
25
|
+
* Rails 3.1 asset pipeline: It will load the compiled version of the CSS asset
|
26
|
+
which is normally located in `app/assets/stylesheets/`. If the asset can't be
|
27
|
+
found (e.g. it is only available on a CDN and not locally), it will be
|
28
|
+
HTTP requested.
|
29
|
+
|
30
|
+
* Classic static assets: It will try to load the CSS file located in
|
31
|
+
`public/stylesheets/`
|
32
|
+
|
33
|
+
* [Hassle](https://github.com/pedro/hassle): It will try to load the
|
34
|
+
compiled CSS file located in the default Hassle location
|
35
|
+
`tmp/hassle/stylesheets/`
|
36
|
+
|
37
|
+
## Installation
|
38
|
+
|
39
|
+
Simply add the gem to your Gemfile in your Rails project:
|
40
|
+
|
41
|
+
gem 'premailer-rails'
|
42
|
+
|
43
|
+
premailer-rails requires either nokogiri or hpricot. It doesn't list them as a
|
44
|
+
dependency so you can choose which one to use.
|
45
|
+
|
46
|
+
gem 'nokogiri'
|
47
|
+
# or
|
48
|
+
gem 'hpricot'
|
49
|
+
|
50
|
+
If both are loaded for some reason, premailer chooses hpricot.
|
51
|
+
|
52
|
+
That's it!
|
53
|
+
|
54
|
+
## Configuration
|
55
|
+
|
56
|
+
Premailer itself accepts a number of options. In order for premailer-rails to
|
57
|
+
pass these options on to the underlying premailer instance, specify them in an
|
58
|
+
initializer:
|
59
|
+
|
60
|
+
```ruby
|
61
|
+
Premailer::Rails.config.merge!(:preserve_styles => true,
|
62
|
+
:remove_ids => true)
|
63
|
+
```
|
64
|
+
|
65
|
+
For a list of options, refer to the [Premailer documentation](http://rubydoc.info/gems/premailer/1.7.3/Premailer:initialize)
|
66
|
+
|
67
|
+
The default configs are:
|
68
|
+
|
69
|
+
```ruby
|
70
|
+
{
|
71
|
+
:input_encoding => 'UTF-8',
|
72
|
+
:inputencoding => 'UTF-8',
|
73
|
+
:generate_text_part => true
|
74
|
+
}
|
75
|
+
```
|
76
|
+
|
77
|
+
The input encoding option [changed](https://github.com/alexdunae/premailer/commit/5f5cbb4ac181299a7e73d3eca11f3cf546585364)
|
78
|
+
at some point. To make sure this option works regardless of the premailer
|
79
|
+
version, the old and new setting is specified. If you want to use another
|
80
|
+
encoding make sure to specify the right one or both.
|
81
|
+
|
82
|
+
If you don't want to generate a text part from the html part, set the config
|
83
|
+
`:generate_text_part` to false.
|
84
|
+
|
85
|
+
Note that the options `:with_html_string` and `:css_string` are used to make
|
86
|
+
this gem work and will thus be overridden.
|
data/Rakefile
ADDED
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
1.3.2
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'premailer'
|
2
|
+
require 'action_mailer'
|
3
|
+
|
4
|
+
require 'premailer/rails/css_loaders'
|
5
|
+
require 'premailer/rails/css_helper'
|
6
|
+
require 'premailer/rails/customized_premailer'
|
7
|
+
require 'premailer/rails/hook'
|
8
|
+
require 'premailer/rails/nokogiri_fix'
|
9
|
+
|
10
|
+
class Premailer
|
11
|
+
module Rails
|
12
|
+
@config = {
|
13
|
+
:input_encoding => 'UTF-8',
|
14
|
+
:inputencoding => 'UTF-8',
|
15
|
+
:generate_text_part => true
|
16
|
+
}
|
17
|
+
class << self
|
18
|
+
attr_accessor :config
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
ActionMailer::Base.register_interceptor(Premailer::Rails::Hook)
|
@@ -0,0 +1,58 @@
|
|
1
|
+
require 'open-uri'
|
2
|
+
require 'zlib'
|
3
|
+
|
4
|
+
class Premailer
|
5
|
+
module Rails
|
6
|
+
module CSSHelper
|
7
|
+
extend self
|
8
|
+
|
9
|
+
@cache = {}
|
10
|
+
attr :cache
|
11
|
+
|
12
|
+
STRATEGIES = [
|
13
|
+
CSSLoaders::CacheLoader,
|
14
|
+
CSSLoaders::AssetPipelineLoader,
|
15
|
+
CSSLoaders::FileSystemLoader
|
16
|
+
]
|
17
|
+
|
18
|
+
# Returns all linked CSS files concatenated as string.
|
19
|
+
def css_for_doc(doc)
|
20
|
+
urls = css_urls_in_doc(doc)
|
21
|
+
urls.map { |url| load_css(url) }.join("\n")
|
22
|
+
end
|
23
|
+
|
24
|
+
private
|
25
|
+
|
26
|
+
def css_urls_in_doc(doc)
|
27
|
+
doc.search('link[@type="text/css"]').map do |link|
|
28
|
+
link.attributes['href'].to_s
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def has_inline_css?(doc)
|
33
|
+
not doc.search('style[@type="text/css"]').empty?
|
34
|
+
end
|
35
|
+
|
36
|
+
def load_css(url)
|
37
|
+
path = extract_path(url)
|
38
|
+
|
39
|
+
@cache[path] = STRATEGIES.each do |strategy|
|
40
|
+
css = strategy.load(path)
|
41
|
+
break css if css
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
# Extracts the path of a url.
|
46
|
+
def extract_path(url)
|
47
|
+
if url.is_a? String
|
48
|
+
# Remove everything after ? including ?
|
49
|
+
url = url[0..(url.index('?') - 1)] if url.include? '?'
|
50
|
+
# Remove the host
|
51
|
+
url = url.sub(/^https?\:\/\/[^\/]*/, '') if url.index('http') == 0
|
52
|
+
end
|
53
|
+
|
54
|
+
url
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
@@ -0,0 +1,66 @@
|
|
1
|
+
class Premailer
|
2
|
+
module Rails
|
3
|
+
module CSSLoaders
|
4
|
+
# Loads the CSS from cache when not in development env.
|
5
|
+
module CacheLoader
|
6
|
+
extend self
|
7
|
+
|
8
|
+
def load(path)
|
9
|
+
unless ::Rails.env.development?
|
10
|
+
CSSHelper.cache[path]
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
# Loads the CSS from the asset pipeline.
|
16
|
+
module AssetPipelineLoader
|
17
|
+
extend self
|
18
|
+
|
19
|
+
def load(path)
|
20
|
+
if assets_enabled?
|
21
|
+
file = file_name(path)
|
22
|
+
if asset = ::Rails.application.assets.find_asset(file)
|
23
|
+
asset.to_s
|
24
|
+
else
|
25
|
+
request_and_unzip(file)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def assets_enabled?
|
31
|
+
::Rails.configuration.assets.enabled rescue false
|
32
|
+
end
|
33
|
+
|
34
|
+
def file_name(path)
|
35
|
+
path.sub("#{::Rails.configuration.assets.prefix}/", '') \
|
36
|
+
.sub(/-.*\.css$/, '.css')
|
37
|
+
end
|
38
|
+
|
39
|
+
def request_and_unzip(file)
|
40
|
+
url = [
|
41
|
+
::Rails.configuration.action_controller.asset_host,
|
42
|
+
::Rails.configuration.assets.prefix.sub(/^\//, ''),
|
43
|
+
::Rails.configuration.assets.digests[file]
|
44
|
+
].join('/')
|
45
|
+
response = Kernel.open(url)
|
46
|
+
|
47
|
+
begin
|
48
|
+
Zlib::GzipReader.new(response).read
|
49
|
+
rescue Zlib::GzipFile::Error, Zlib::Error
|
50
|
+
response.rewind
|
51
|
+
response.read
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
# Loads the CSS from the file system.
|
57
|
+
module FileSystemLoader
|
58
|
+
extend self
|
59
|
+
|
60
|
+
def load(path)
|
61
|
+
File.read("#{::Rails.root}/public#{path}")
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
class Premailer
|
2
|
+
module Rails
|
3
|
+
class CustomizedPremailer < ::Premailer
|
4
|
+
def initialize(html)
|
5
|
+
# In order to pass the CSS as string to super it is necessary to access
|
6
|
+
# the parsed HTML beforehand. To do so, the adapter needs to be
|
7
|
+
# initialized. The ::Premailer::Adaptor handles the discovery of a
|
8
|
+
# suitable adaptor (Nokogiri or Hpricot). To make load_html work, an
|
9
|
+
# adaptor needs to be included and @options[:with_html_string] needs to
|
10
|
+
# be set. For further information, refer to ::Premailer#initialize.
|
11
|
+
@options = Rails.config.merge(:with_html_string => true)
|
12
|
+
Premailer.send(:include, Adapter.find(Adapter.use))
|
13
|
+
doc = load_html(html)
|
14
|
+
|
15
|
+
options = @options.merge(:css_string => CSSHelper.css_for_doc(doc))
|
16
|
+
super(html, options)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
class Premailer
|
2
|
+
module Rails
|
3
|
+
class Hook
|
4
|
+
def self.delivering_email(message)
|
5
|
+
# If the mail only has one part, it may be stored in message.body. In that
|
6
|
+
# case, if the mail content type is text/html, the body part will be the
|
7
|
+
# html body.
|
8
|
+
if message.html_part
|
9
|
+
html_body = message.html_part.body.to_s
|
10
|
+
needs_multipart = true
|
11
|
+
message.parts.delete(message.html_part)
|
12
|
+
elsif message.content_type =~ /text\/html/
|
13
|
+
html_body = message.body.to_s
|
14
|
+
message.body = nil
|
15
|
+
needs_multipart = Rails.config[:generate_text_part]
|
16
|
+
end
|
17
|
+
|
18
|
+
if html_body
|
19
|
+
premailer = CustomizedPremailer.new(html_body)
|
20
|
+
charset = message.charset
|
21
|
+
|
22
|
+
if needs_multipart
|
23
|
+
# IMPORTANT: Plain text part must be generated before CSS is inlined.
|
24
|
+
# Not doing so results in CSS declarations visible in the plain text
|
25
|
+
# part.
|
26
|
+
if Rails.config[:generate_text_part] \
|
27
|
+
and not message.text_part
|
28
|
+
message.text_part do
|
29
|
+
content_type "text/plain; charset=#{charset}"
|
30
|
+
body premailer.to_plain_text
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
message.html_part do
|
35
|
+
content_type "text/html; charset=#{charset}"
|
36
|
+
body premailer.to_inline_css
|
37
|
+
end
|
38
|
+
else
|
39
|
+
message.body = premailer.to_inline_css
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
require 'premailer/adapter/nokogiri'
|
2
|
+
|
3
|
+
Premailer::Adapter::Nokogiri.module_eval do
|
4
|
+
# Patch load_html method to fix character encoding issues.
|
5
|
+
def load_html(html)
|
6
|
+
if RUBY_VERSION.to_f >= 1.9
|
7
|
+
html = html.force_encoding('UTF-8').encode!
|
8
|
+
::Nokogiri::HTML(html) {|c| c.recover }
|
9
|
+
else
|
10
|
+
::Nokogiri::HTML(html, nil, 'UTF-8') {|c| c.recover }
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
class Premailer
|
2
|
+
module Rails
|
3
|
+
class CustomizedPremailer < ::Premailer
|
4
|
+
def initialize(html)
|
5
|
+
# In order to pass the CSS as string to super it is necessary to access
|
6
|
+
# the parsed HTML beforehand. To do so, the adapter needs to be
|
7
|
+
# initialized. The ::Premailer::Adaptor handles the discovery of a
|
8
|
+
# suitable adaptor (Nokogiri or Hpricot). To make load_html work, an
|
9
|
+
# adaptor needs to be included and @options[:with_html_string] needs to
|
10
|
+
# be set. For further information, refer to ::Premailer#initialize.
|
11
|
+
@options = Rails.config.merge(:with_html_string => true)
|
12
|
+
Premailer.send(:include, Adapter.find(Adapter.use))
|
13
|
+
doc = load_html(html)
|
14
|
+
|
15
|
+
options = @options.merge(:css_string => CSSHelper.css_for_doc(doc))
|
16
|
+
super(html, options)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'premailer'
|
2
|
+
require 'action_mailer'
|
3
|
+
|
4
|
+
require 'premailer/rails/css_loaders'
|
5
|
+
require 'premailer/rails/css_helper'
|
6
|
+
require 'premailer/rails/customized_premailer'
|
7
|
+
require 'premailer/rails/hook'
|
8
|
+
require 'premailer/rails/nokogiri_fix'
|
9
|
+
|
10
|
+
class Premailer
|
11
|
+
module Rails
|
12
|
+
@config = {
|
13
|
+
:input_encoding => 'UTF-8',
|
14
|
+
:inputencoding => 'UTF-8',
|
15
|
+
:generate_text_part => true
|
16
|
+
}
|
17
|
+
class << self
|
18
|
+
attr_accessor :config
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
ActionMailer::Base.register_interceptor(Premailer::Rails::Hook)
|
@@ -0,0 +1,32 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
3
|
+
require "premailer/rails/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.name = "premailer-rails"
|
7
|
+
s.version = Premailer::Rails::VERSION
|
8
|
+
s.platform = Gem::Platform::RUBY
|
9
|
+
s.authors = ["Philipe Fatio"]
|
10
|
+
s.email = ["philipe.fatio@gmail.com"]
|
11
|
+
s.homepage = "https://github.com/fphilipe/premailer-rails"
|
12
|
+
s.summary = %q{Easily create styled HTML emails in Rails.}
|
13
|
+
s.description = %q{This gem brings you the power of the premailer gem to Rails
|
14
|
+
without any configuration needs. Create HTML emails,
|
15
|
+
include a CSS file as you do in a normal HTML document and
|
16
|
+
premailer will inline the included CSS.}
|
17
|
+
|
18
|
+
s.files = `git ls-files`.split("\n")
|
19
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
20
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
21
|
+
s.require_paths = ["lib"]
|
22
|
+
|
23
|
+
s.add_dependency("premailer", ["~> 1.7"])
|
24
|
+
s.add_dependency("rails", [">= 3"])
|
25
|
+
|
26
|
+
s.add_development_dependency 'rspec-core'
|
27
|
+
s.add_development_dependency 'rspec-expectations'
|
28
|
+
s.add_development_dependency 'mocha'
|
29
|
+
s.add_development_dependency 'mail'
|
30
|
+
s.add_development_dependency 'nokogiri'
|
31
|
+
s.add_development_dependency 'hpricot'
|
32
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
module Fixtures
|
2
|
+
module HTML
|
3
|
+
extend self
|
4
|
+
|
5
|
+
TEMPLATE = <<-HTML
|
6
|
+
<html>
|
7
|
+
<head>
|
8
|
+
%s
|
9
|
+
</head>
|
10
|
+
<body>
|
11
|
+
<p>
|
12
|
+
Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod
|
13
|
+
tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim
|
14
|
+
veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea
|
15
|
+
commodo consequat.
|
16
|
+
</p>
|
17
|
+
</body>
|
18
|
+
</html>
|
19
|
+
HTML
|
20
|
+
|
21
|
+
LINK = <<-LINK
|
22
|
+
<link rel='stylesheet' type='text/css' href='%s' />
|
23
|
+
LINK
|
24
|
+
|
25
|
+
def with_css_links(*files)
|
26
|
+
links = []
|
27
|
+
files.each do |file|
|
28
|
+
links << LINK % "http://example.com/#{file}"
|
29
|
+
end
|
30
|
+
|
31
|
+
TEMPLATE % links.join
|
32
|
+
end
|
33
|
+
|
34
|
+
def with_no_css_link
|
35
|
+
with_css_links
|
36
|
+
end
|
37
|
+
|
38
|
+
def with_style_block
|
39
|
+
TEMPLATE % '<style type="text/css">p { color: red; }</style>'
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,86 @@
|
|
1
|
+
require 'mail'
|
2
|
+
|
3
|
+
module Fixtures
|
4
|
+
module Message
|
5
|
+
extend self
|
6
|
+
|
7
|
+
HTML_PART = <<-HTML
|
8
|
+
<html>
|
9
|
+
<head>
|
10
|
+
</head>
|
11
|
+
<body>
|
12
|
+
<p>
|
13
|
+
Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod
|
14
|
+
tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim
|
15
|
+
veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea
|
16
|
+
commodo consequat.
|
17
|
+
</p>
|
18
|
+
</body>
|
19
|
+
</html>
|
20
|
+
HTML
|
21
|
+
|
22
|
+
HTML_PART_WITH_CSS = <<-HTML
|
23
|
+
<html>
|
24
|
+
<head>
|
25
|
+
<style type="text/css">
|
26
|
+
p { color: red; }
|
27
|
+
</style>
|
28
|
+
</head>
|
29
|
+
<body>
|
30
|
+
<p>
|
31
|
+
Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod
|
32
|
+
tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim
|
33
|
+
veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea
|
34
|
+
commodo consequat.
|
35
|
+
</p>
|
36
|
+
</body>
|
37
|
+
</html>
|
38
|
+
HTML
|
39
|
+
|
40
|
+
TEXT_PART = <<-TEXT
|
41
|
+
Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor
|
42
|
+
incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis
|
43
|
+
nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.
|
44
|
+
TEXT
|
45
|
+
|
46
|
+
def with_parts(*part_types)
|
47
|
+
message = base_message
|
48
|
+
|
49
|
+
message.html_part do
|
50
|
+
body HTML_PART
|
51
|
+
content_type 'text/html; charset=UTF-8'
|
52
|
+
end if part_types.include? :html
|
53
|
+
|
54
|
+
message.text_part do
|
55
|
+
body TEXT_PART
|
56
|
+
content_type 'text/plain; charset=UTF-8'
|
57
|
+
end if part_types.include? :text
|
58
|
+
|
59
|
+
message
|
60
|
+
end
|
61
|
+
|
62
|
+
def with_body(body_type)
|
63
|
+
message = base_message
|
64
|
+
|
65
|
+
case body_type
|
66
|
+
when :html
|
67
|
+
message.body = HTML_PART
|
68
|
+
message.content_type 'text/html; charset=UTF-8'
|
69
|
+
when :text
|
70
|
+
message.body = TEXT_PART
|
71
|
+
message.content_type 'text/plain; charset=UTF-8'
|
72
|
+
end
|
73
|
+
|
74
|
+
message
|
75
|
+
end
|
76
|
+
|
77
|
+
private
|
78
|
+
|
79
|
+
def base_message
|
80
|
+
Mail.new do
|
81
|
+
to 'some@email.com'
|
82
|
+
subject 'testing premailer-rails3'
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
@@ -0,0 +1,160 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Premailer::Rails::CSSHelper do
|
4
|
+
# Reset the CSS cache
|
5
|
+
after { Premailer::Rails::CSSHelper.send(:instance_variable_set, '@cache', {}) }
|
6
|
+
|
7
|
+
def load_css(path)
|
8
|
+
Premailer::Rails::CSSHelper.send(:load_css, path)
|
9
|
+
end
|
10
|
+
|
11
|
+
def css_for_doc(doc)
|
12
|
+
Premailer::Rails::CSSHelper.css_for_doc(doc)
|
13
|
+
end
|
14
|
+
|
15
|
+
describe '#css_for_doc' do
|
16
|
+
let(:html) { Fixtures::HTML.with_css_links(*files) }
|
17
|
+
let(:doc) { Hpricot(html) }
|
18
|
+
|
19
|
+
context 'when HTML contains linked CSS files' do
|
20
|
+
let(:files) { %w[ stylesheets/base.css stylesheets/font.css ] }
|
21
|
+
|
22
|
+
it 'should return the content of both files concatenated' do
|
23
|
+
Premailer::Rails::CSSHelper \
|
24
|
+
.expects(:load_css) \
|
25
|
+
.with('http://example.com/stylesheets/base.css') \
|
26
|
+
.returns('content of base.css')
|
27
|
+
Premailer::Rails::CSSHelper \
|
28
|
+
.expects(:load_css) \
|
29
|
+
.with('http://example.com/stylesheets/font.css') \
|
30
|
+
.returns('content of font.css')
|
31
|
+
|
32
|
+
css_for_doc(doc).should == "content of base.css\ncontent of font.css"
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
describe '#load_css' do
|
38
|
+
context 'when path is a url' do
|
39
|
+
it 'should load the CSS at the local path' do
|
40
|
+
File.expects(:read).with('RAILS_ROOT/public/stylesheets/base.css')
|
41
|
+
|
42
|
+
load_css('http://example.com/stylesheets/base.css?test')
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
context 'when path is a relative url' do
|
47
|
+
it 'should load the CSS at the local path' do
|
48
|
+
File.expects(:read).with('RAILS_ROOT/public/stylesheets/base.css')
|
49
|
+
|
50
|
+
load_css('/stylesheets/base.css?test')
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
context 'when file is cached' do
|
55
|
+
it 'should return the cached value' do
|
56
|
+
cache =
|
57
|
+
Premailer::Rails::CSSHelper.send(:instance_variable_get, '@cache')
|
58
|
+
cache['/stylesheets/base.css'] = 'content of base.css'
|
59
|
+
|
60
|
+
load_css('http://example.com/stylesheets/base.css') \
|
61
|
+
.should == 'content of base.css'
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
context 'when in development mode' do
|
66
|
+
it 'should not return cached values' do
|
67
|
+
cache =
|
68
|
+
Premailer::Rails::CSSHelper.send(:instance_variable_get, '@cache')
|
69
|
+
cache['/stylesheets/base.css'] = 'cached content of base.css'
|
70
|
+
File.expects(:read) \
|
71
|
+
.with('RAILS_ROOT/public/stylesheets/base.css') \
|
72
|
+
.returns('new content of base.css')
|
73
|
+
Rails.env.stubs(:development?).returns(true)
|
74
|
+
|
75
|
+
load_css('http://example.com/stylesheets/base.css') \
|
76
|
+
.should == 'new content of base.css'
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
context 'when Rails asset pipeline is used' do
|
81
|
+
before {
|
82
|
+
Rails.configuration.stubs(:assets).returns(
|
83
|
+
stub(
|
84
|
+
:enabled => true,
|
85
|
+
:prefix => '/assets'
|
86
|
+
)
|
87
|
+
)
|
88
|
+
}
|
89
|
+
|
90
|
+
it 'should return the content of the file compiled by Rails' do
|
91
|
+
Rails.application.assets.expects(:find_asset) \
|
92
|
+
.with('base.css') \
|
93
|
+
.returns(mock(:to_s => 'content of base.css'))
|
94
|
+
|
95
|
+
load_css('http://example.com/assets/base.css') \
|
96
|
+
.should == 'content of base.css'
|
97
|
+
end
|
98
|
+
|
99
|
+
it 'should return same file when path contains file fingerprint' do
|
100
|
+
Rails.application.assets \
|
101
|
+
.expects(:find_asset) \
|
102
|
+
.with('base.css') \
|
103
|
+
.returns(mock(:to_s => 'content of base.css'))
|
104
|
+
|
105
|
+
load_css(
|
106
|
+
'http://example.com/assets/base-089e35bd5d84297b8d31ad552e433275.css'
|
107
|
+
).should == 'content of base.css'
|
108
|
+
end
|
109
|
+
|
110
|
+
context 'when asset can not be found' do
|
111
|
+
before {
|
112
|
+
Rails.application.assets.stubs(:find_asset).returns(nil)
|
113
|
+
Rails.configuration.stubs(:action_controller).returns(
|
114
|
+
stub(:asset_host => 'http://example.com')
|
115
|
+
)
|
116
|
+
Rails.configuration.stubs(:assets).returns(
|
117
|
+
stub(
|
118
|
+
:enabled => true,
|
119
|
+
:prefix => '/assets',
|
120
|
+
:digests => {
|
121
|
+
'base.css' => 'base-089e35bd5d84297b8d31ad552e433275.css'
|
122
|
+
}
|
123
|
+
)
|
124
|
+
)
|
125
|
+
}
|
126
|
+
let(:string_io) { StringIO.new('content of base.css') }
|
127
|
+
let(:url) {
|
128
|
+
'http://example.com/assets/base-089e35bd5d84297b8d31ad552e433275.css'
|
129
|
+
}
|
130
|
+
|
131
|
+
it 'should request the file' do
|
132
|
+
Kernel.expects(:open).with(url).returns(string_io)
|
133
|
+
|
134
|
+
load_css(
|
135
|
+
'http://example.com/assets/base.css'
|
136
|
+
).should == 'content of base.css'
|
137
|
+
end
|
138
|
+
|
139
|
+
it 'should request the same file when path contains file fingerprint' do
|
140
|
+
Kernel.expects(:open).with(url).returns(string_io)
|
141
|
+
|
142
|
+
load_css(
|
143
|
+
'http://example.com/assets/base-089e35bd5d84297b8d31ad552e433275.css'
|
144
|
+
).should == 'content of base.css'
|
145
|
+
end
|
146
|
+
end
|
147
|
+
end
|
148
|
+
|
149
|
+
context 'when static stylesheets are used' do
|
150
|
+
it 'should return the content of the static file' do
|
151
|
+
File.expects(:read) \
|
152
|
+
.with('RAILS_ROOT/public/stylesheets/base.css') \
|
153
|
+
.returns('content of base.css')
|
154
|
+
|
155
|
+
load_css('http://example.com/stylesheets/base.css') \
|
156
|
+
.should == 'content of base.css'
|
157
|
+
end
|
158
|
+
end
|
159
|
+
end
|
160
|
+
end
|
@@ -0,0 +1,62 @@
|
|
1
|
+
# coding: UTF-8
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
describe Premailer::Rails::CustomizedPremailer do
|
6
|
+
[ :nokogiri, :hpricot ].each do |adapter|
|
7
|
+
context "when adapter is #{adapter}" do
|
8
|
+
before { Premailer::Adapter.stubs(:use).returns(adapter) }
|
9
|
+
|
10
|
+
describe '#to_plain_text' do
|
11
|
+
it 'should include the text from the HTML part' do
|
12
|
+
premailer =
|
13
|
+
Premailer::Rails::CustomizedPremailer \
|
14
|
+
.new(Fixtures::Message::HTML_PART)
|
15
|
+
premailer.to_plain_text.gsub(/\s/, ' ').strip \
|
16
|
+
.should == Fixtures::Message::TEXT_PART.gsub(/\s/, ' ').strip
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
describe '#to_inline_css' do
|
21
|
+
context 'when inline CSS block present' do
|
22
|
+
it 'should return the HTML with the CSS inlined' do
|
23
|
+
Premailer::Rails::CSSHelper \
|
24
|
+
.stubs(:css_for_doc) \
|
25
|
+
.returns('p { color: red; }')
|
26
|
+
html = Fixtures::Message::HTML_PART
|
27
|
+
premailer = Premailer::Rails::CustomizedPremailer.new(html)
|
28
|
+
premailer.to_inline_css.should include '<p style="color: red;">'
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
context 'when CSS is loaded externally' do
|
33
|
+
it 'should return the HTML with the CSS inlined' do
|
34
|
+
html = Fixtures::Message::HTML_PART_WITH_CSS
|
35
|
+
premailer = Premailer::Rails::CustomizedPremailer.new(html)
|
36
|
+
premailer.to_inline_css.should include '<p style="color: red;">'
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
describe '.new' do
|
44
|
+
it 'should extract the CSS' do
|
45
|
+
Premailer::Rails::CSSHelper.expects(:css_for_doc)
|
46
|
+
Premailer::Rails::CustomizedPremailer.new('some html')
|
47
|
+
end
|
48
|
+
|
49
|
+
it 'should pass on the configs' do
|
50
|
+
Premailer::Rails.config = { :foo => :bar }
|
51
|
+
premailer = Premailer::Rails::CustomizedPremailer.new('some html')
|
52
|
+
premailer.instance_variable_get(:'@options')[:foo].should == :bar
|
53
|
+
end
|
54
|
+
|
55
|
+
it 'should not allow to override with_html_string' do
|
56
|
+
Premailer::Rails.config = { :with_html_string => false }
|
57
|
+
premailer = Premailer::Rails::CustomizedPremailer.new('some html')
|
58
|
+
options = premailer.instance_variable_get(:'@options')
|
59
|
+
options[:with_html_string].should == true
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
@@ -0,0 +1,10 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe 'ActionMailer::Base.register_interceptor' do
|
4
|
+
it 'should register interceptor Premailer::Rails::Hook' do
|
5
|
+
ActionMailer::Base \
|
6
|
+
.expects(:register_interceptor) \
|
7
|
+
.with(Premailer::Rails::Hook)
|
8
|
+
load 'premailer/rails3.rb'
|
9
|
+
end
|
10
|
+
end
|
@@ -0,0 +1,105 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Premailer::Rails::Hook do
|
4
|
+
describe '.delivering_email' do
|
5
|
+
before { File.stubs(:read).returns('') }
|
6
|
+
def run_hook(message)
|
7
|
+
Premailer::Rails::Hook.delivering_email(message)
|
8
|
+
end
|
9
|
+
|
10
|
+
context 'when message contains html part' do
|
11
|
+
let(:message) { Fixtures::Message.with_parts :html }
|
12
|
+
|
13
|
+
it 'should create a text part from the html part' do
|
14
|
+
Premailer::Rails::CustomizedPremailer \
|
15
|
+
.any_instance.expects(:to_plain_text)
|
16
|
+
run_hook(message)
|
17
|
+
message.text_part.should be_a Mail::Part
|
18
|
+
end
|
19
|
+
|
20
|
+
it 'should inline the css in the html part' do
|
21
|
+
Premailer::Rails::CustomizedPremailer \
|
22
|
+
.any_instance.expects(:to_inline_css)
|
23
|
+
run_hook(message)
|
24
|
+
end
|
25
|
+
|
26
|
+
it 'should not create a text part if disabled' do
|
27
|
+
Premailer::Rails::CustomizedPremailer \
|
28
|
+
.any_instance.expects(:to_plain_text).never
|
29
|
+
Premailer::Rails.config[:generate_text_part] = false
|
30
|
+
run_hook(message)
|
31
|
+
Premailer::Rails.config[:generate_text_part] = true
|
32
|
+
message.text_part.should be_nil
|
33
|
+
message.html_part.should be_a Mail::Part
|
34
|
+
end
|
35
|
+
|
36
|
+
it 'should not create an additional html part' do
|
37
|
+
run_hook(message)
|
38
|
+
message.parts.count { |i| i.content_type =~ /text\/html/ }.should == 1
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
context 'when message contains text part' do
|
43
|
+
let(:message) { Fixtures::Message.with_parts :text }
|
44
|
+
|
45
|
+
it 'should not modify the message' do
|
46
|
+
Premailer.expects(:new).never
|
47
|
+
run_hook(message)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
context 'when message contains html and text part' do
|
52
|
+
let(:message) { Fixtures::Message.with_parts :html, :text }
|
53
|
+
|
54
|
+
it 'should not create a text part from the html part' do
|
55
|
+
Premailer::Rails::CustomizedPremailer \
|
56
|
+
.any_instance.expects(:to_plain_text).never
|
57
|
+
run_hook(message)
|
58
|
+
message.text_part.should be_a Mail::Part
|
59
|
+
end
|
60
|
+
|
61
|
+
it 'should inline the css in the html part' do
|
62
|
+
Premailer::Rails::CustomizedPremailer \
|
63
|
+
.any_instance.expects(:to_inline_css)
|
64
|
+
run_hook(message)
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
context 'when message contains html body' do
|
69
|
+
let(:message) { Fixtures::Message.with_body :html }
|
70
|
+
|
71
|
+
it 'should create a text part from the html part' do
|
72
|
+
Premailer::Rails::CustomizedPremailer \
|
73
|
+
.any_instance.expects(:to_plain_text)
|
74
|
+
run_hook(message)
|
75
|
+
end
|
76
|
+
|
77
|
+
it 'should create a html part and inline the css' do
|
78
|
+
Premailer::Rails::CustomizedPremailer \
|
79
|
+
.any_instance.expects(:to_inline_css)
|
80
|
+
run_hook(message)
|
81
|
+
message.html_part.should be_a Mail::Part
|
82
|
+
end
|
83
|
+
|
84
|
+
it 'should not create a text part if disabled' do
|
85
|
+
Premailer::Rails::CustomizedPremailer \
|
86
|
+
.any_instance.expects(:to_plain_text).never
|
87
|
+
Premailer::Rails.config[:generate_text_part] = false
|
88
|
+
run_hook(message)
|
89
|
+
Premailer::Rails.config[:generate_text_part] = true
|
90
|
+
message.text_part.should be_nil
|
91
|
+
message.html_part.should be_nil
|
92
|
+
message.body.should_not be_empty
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
context 'when message contains text body' do
|
97
|
+
let(:message) { Fixtures::Message.with_body :text }
|
98
|
+
|
99
|
+
it 'should not modify the message' do
|
100
|
+
Premailer.expects(:new).never
|
101
|
+
run_hook(message)
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
data/spec/spec_helper.rb
ADDED
data/spec/stubs/dummy.rb
ADDED
data/spec/stubs/rails.rb
ADDED
@@ -0,0 +1,65 @@
|
|
1
|
+
require 'stubs/dummy'
|
2
|
+
|
3
|
+
class Logger
|
4
|
+
def self.try(*args); end
|
5
|
+
end
|
6
|
+
|
7
|
+
module Rails
|
8
|
+
extend self
|
9
|
+
|
10
|
+
module Configuration
|
11
|
+
extend self
|
12
|
+
|
13
|
+
module Middleware
|
14
|
+
extend self
|
15
|
+
|
16
|
+
def include?(what)
|
17
|
+
false
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def middleware
|
22
|
+
Middleware
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
module Env
|
27
|
+
extend self
|
28
|
+
|
29
|
+
def development?
|
30
|
+
false
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
module Application
|
35
|
+
extend self
|
36
|
+
|
37
|
+
module Assets
|
38
|
+
extend self
|
39
|
+
end
|
40
|
+
|
41
|
+
def assets
|
42
|
+
Assets
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
def env
|
47
|
+
Env
|
48
|
+
end
|
49
|
+
|
50
|
+
def configuration
|
51
|
+
Configuration
|
52
|
+
end
|
53
|
+
|
54
|
+
def logger
|
55
|
+
Logger
|
56
|
+
end
|
57
|
+
|
58
|
+
def root
|
59
|
+
'RAILS_ROOT'
|
60
|
+
end
|
61
|
+
|
62
|
+
def application
|
63
|
+
Application
|
64
|
+
end
|
65
|
+
end
|
metadata
ADDED
@@ -0,0 +1,201 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: premailer-rails
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.3.2
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Philipe Fatio
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2013-03-12 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: premailer
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ~>
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.7'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ~>
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.7'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rails
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - '>='
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '3'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - '>='
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '3'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rspec-core
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - '>='
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - '>='
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: rspec-expectations
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - '>='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - '>='
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: mocha
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - '>='
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - '>='
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: mail
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - '>='
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - '>='
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0'
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: nokogiri
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - '>='
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '0'
|
104
|
+
type: :development
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - '>='
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '0'
|
111
|
+
- !ruby/object:Gem::Dependency
|
112
|
+
name: hpricot
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
114
|
+
requirements:
|
115
|
+
- - '>='
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: '0'
|
118
|
+
type: :development
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
requirements:
|
122
|
+
- - '>='
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: '0'
|
125
|
+
description: |-
|
126
|
+
This gem brings you the power of the premailer gem to Rails
|
127
|
+
without any configuration needs. Create HTML emails,
|
128
|
+
include a CSS file as you do in a normal HTML document and
|
129
|
+
premailer will inline the included CSS.
|
130
|
+
email:
|
131
|
+
- philipe.fatio@gmail.com
|
132
|
+
executables: []
|
133
|
+
extensions: []
|
134
|
+
extra_rdoc_files: []
|
135
|
+
files:
|
136
|
+
- .gitignore
|
137
|
+
- .rspec
|
138
|
+
- .travis.yml
|
139
|
+
- CHANGELOG.md
|
140
|
+
- Gemfile
|
141
|
+
- LICENSE
|
142
|
+
- README.md
|
143
|
+
- Rakefile
|
144
|
+
- VERSION
|
145
|
+
- lib/premailer/rails.rb
|
146
|
+
- lib/premailer/rails/css_helper.rb
|
147
|
+
- lib/premailer/rails/css_loaders.rb
|
148
|
+
- lib/premailer/rails/customized_premailer.rb
|
149
|
+
- lib/premailer/rails/hook.rb
|
150
|
+
- lib/premailer/rails/nokogiri_fix.rb
|
151
|
+
- lib/premailer/rails/premailer.rb
|
152
|
+
- lib/premailer/rails/version.rb
|
153
|
+
- lib/premailer/rails3.rb
|
154
|
+
- premailer-rails.gemspec
|
155
|
+
- spec/fixtures/html.rb
|
156
|
+
- spec/fixtures/message.rb
|
157
|
+
- spec/lib/css_helper_spec.rb
|
158
|
+
- spec/lib/customized_premailer_spec.rb
|
159
|
+
- spec/lib/hook_registration_spec.rb
|
160
|
+
- spec/lib/hook_spec.rb
|
161
|
+
- spec/lib/premailer_rails_3_spec.rb
|
162
|
+
- spec/spec_helper.rb
|
163
|
+
- spec/stubs/action_mailer.rb
|
164
|
+
- spec/stubs/dummy.rb
|
165
|
+
- spec/stubs/rails.rb
|
166
|
+
homepage: https://github.com/fphilipe/premailer-rails
|
167
|
+
licenses: []
|
168
|
+
metadata: {}
|
169
|
+
post_install_message:
|
170
|
+
rdoc_options: []
|
171
|
+
require_paths:
|
172
|
+
- lib
|
173
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
174
|
+
requirements:
|
175
|
+
- - '>='
|
176
|
+
- !ruby/object:Gem::Version
|
177
|
+
version: '0'
|
178
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
179
|
+
requirements:
|
180
|
+
- - '>='
|
181
|
+
- !ruby/object:Gem::Version
|
182
|
+
version: '0'
|
183
|
+
requirements: []
|
184
|
+
rubyforge_project:
|
185
|
+
rubygems_version: 2.0.0
|
186
|
+
signing_key:
|
187
|
+
specification_version: 4
|
188
|
+
summary: Easily create styled HTML emails in Rails.
|
189
|
+
test_files:
|
190
|
+
- spec/fixtures/html.rb
|
191
|
+
- spec/fixtures/message.rb
|
192
|
+
- spec/lib/css_helper_spec.rb
|
193
|
+
- spec/lib/customized_premailer_spec.rb
|
194
|
+
- spec/lib/hook_registration_spec.rb
|
195
|
+
- spec/lib/hook_spec.rb
|
196
|
+
- spec/lib/premailer_rails_3_spec.rb
|
197
|
+
- spec/spec_helper.rb
|
198
|
+
- spec/stubs/action_mailer.rb
|
199
|
+
- spec/stubs/dummy.rb
|
200
|
+
- spec/stubs/rails.rb
|
201
|
+
has_rdoc:
|