actionmailer-instyle4 0.5.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (36) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +20 -0
  3. data/.rspec +1 -0
  4. data/Gemfile +9 -0
  5. data/Guardfile +17 -0
  6. data/LICENSE +22 -0
  7. data/README.md +147 -0
  8. data/Rakefile +7 -0
  9. data/actionmailer-instyle4.gemspec +34 -0
  10. data/config.ru +7 -0
  11. data/lib/action_mailer/in_style.rb +21 -0
  12. data/lib/action_mailer/in_style/premailer.rb +45 -0
  13. data/lib/action_mailer/in_style/processor.rb +90 -0
  14. data/lib/action_mailer/in_style/version.rb +5 -0
  15. data/lib/action_mailer/instyle.rb +1 -0
  16. data/lib/actionmailer-instyle.rb +3 -0
  17. data/spec/internal/app/assets/stylesheets/notification_mailer.css.scss +9 -0
  18. data/spec/internal/app/mailers/notification_mailer.rb +18 -0
  19. data/spec/internal/app/mailers/notification_mailer_no_layout.rb +9 -0
  20. data/spec/internal/app/views/layouts/notification_mailer.html.erb +14 -0
  21. data/spec/internal/app/views/layouts/notification_mailer_without_style.html.erb +11 -0
  22. data/spec/internal/app/views/notification_mailer/email_with_html_only.html.erb +9 -0
  23. data/spec/internal/app/views/notification_mailer/welcome_html_email.html.erb +7 -0
  24. data/spec/internal/app/views/notification_mailer/welcome_html_email.text.erb +1 -0
  25. data/spec/internal/app/views/notification_mailer_no_style/email_with_no_style.html.erb +8 -0
  26. data/spec/internal/config/database.yml +3 -0
  27. data/spec/internal/config/routes.rb +3 -0
  28. data/spec/internal/db/schema.rb +3 -0
  29. data/spec/internal/log/.gitignore +1 -0
  30. data/spec/internal/public/favicon.ico +0 -0
  31. data/spec/lib/action_mailer/inline/css_helper_spec.rb +9 -0
  32. data/spec/lib/action_mailer/inline/premailer_spec.rb +7 -0
  33. data/spec/lib/action_mailer/inline/processor_spec.rb +73 -0
  34. data/spec/lib/action_mailer/inline_spec.rb +48 -0
  35. data/spec/spec_helper.rb +24 -0
  36. metadata +253 -0
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: bed2dc5bf38bccca1043659710f307f347642067
4
+ data.tar.gz: ba60105a79fbd03700368ef8a8fb95fb6730690d
5
+ SHA512:
6
+ metadata.gz: f7c46b94b8aec01280516b0f1140a2e32481948a283fdc943e92b54f234942b577ed12970ca7c535e7341b685fe6d6a9932d7b07c38beb4c8deec21435fe003e
7
+ data.tar.gz: c668ab18ff1412588c9862282eeac6ffec63bc461358172575ba79d2261d32fe2e9b86940392f47efb4d0b774fee7eb19dcea4584e382f93f63eb76f06399687
@@ -0,0 +1,20 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
18
+ .sass-cache
19
+
20
+ spec/internal/db/combustion_test.sqlite
data/.rspec ADDED
@@ -0,0 +1 @@
1
+ --color -f d
data/Gemfile ADDED
@@ -0,0 +1,9 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gemspec
4
+
5
+
6
+ gem 'jruby-openssl', :platform => :jruby
7
+ gem 'jdbc-sqlite3', :platform => :jruby
8
+ gem 'activerecord-jdbcsqlite3-adapter', :platform => :jruby
9
+
@@ -0,0 +1,17 @@
1
+ # A sample Guardfile
2
+ # More info at https://github.com/guard/guard#readme
3
+
4
+ guard 'rspec', :version => 2 do
5
+ watch(%r{^spec/.+_spec\.rb$})
6
+ watch(%r{^lib/(.+)\.rb$}) { |m| "spec/lib/#{m[1]}_spec.rb" }
7
+ watch('spec/spec_helper.rb') { "spec" }
8
+
9
+ # Rails example
10
+ watch(%r{^app/(.+)\.rb$}) { |m| "spec/#{m[1]}_spec.rb" }
11
+ watch(%r{^app/(.*)(\.erb|\.haml)$}) { |m| "spec/#{m[1]}#{m[2]}_spec.rb" }
12
+ watch(%r{^app/controllers/(.+)_(controller)\.rb$}) { |m| ["spec/routing/#{m[1]}_routing_spec.rb", "spec/#{m[2]}s/#{m[1]}_#{m[2]}_spec.rb", "spec/acceptance/#{m[1]}_spec.rb"] }
13
+ watch(%r{^spec/support/(.+)\.rb$}) { "spec" }
14
+ end
15
+
16
+
17
+
data/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2012 Ivan Vanderbyl
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,147 @@
1
+ # ActionMailer::InStyle
2
+
3
+ Forked From [testpilot/actionmailer-instyle](https://github.com/testpilot/actionmailer-instyle). He did most of the hard work.
4
+
5
+ HTML Emails can be a PITN, especially when you want maximum email client compatibility, of which the best way to achieve this is inline CSS. Unfortunately nobody actually wants to be forced into writing crap like that so we've created **InStyle**, it will automatically intercept your emails and look for a `stylesheet` linking to something inside your assets folder, extract all the styles, and convert them to inline styles on the fly.
6
+
7
+ _There are a couple of other projects which do this, some have not been updated for a while and none of them work with the Rails 3.1 asset pipeline._ *InStyle* uses Sprockets to render CSS which means you can use Sass, Compass, and any other CSS hackery you desire, including using stylesheets you would usually only use within your views e.g If you want to email an activity digest and make it look the same as what the user is used to seeing within your application (think Yammer).
8
+
9
+ ## Requirements
10
+
11
+ This gem is built to take advantage of the Rails 3.1 *(and above)* Asset Pipeline, as such you must be using Rails ~>3.1 and have the Asset Pipeline enabled (default)
12
+
13
+ ## Installation
14
+
15
+ Add this line to your application's Gemfile:
16
+
17
+ ```ruby
18
+ gem 'actionmailer-instyle4', :require => 'action_mailer/in_style'
19
+ ```
20
+
21
+ And then execute:
22
+
23
+ ```bash
24
+ $ bundle install
25
+ ```
26
+
27
+ ## Usage
28
+
29
+ Once installed it will add the required hooks out of the box to intercept each email being sent.
30
+
31
+ **Stylesheets**
32
+
33
+ As with all your other stylesheets, put them in `app/assets/stylesheets` and include them into your mailer
34
+ template using `stylesheet_link_tag "account_mailer"`, where `account_mailer` is the filename less the extension of the stylesheet you want to use.
35
+
36
+ Everything runs through the Asset Pipeline so you can use Sass simply by adding the `.scss` extension as you would with all other stylesheets.
37
+
38
+ **Compass**
39
+
40
+ Because Sass works out of the box, you can also include Compass for browser specific mixins and useful CSS3 helpers, keeping in mind that some email clients (Outlook for example) use very dated rendering engines and a lot of CSS properties may have undesired effects or not work at all.
41
+
42
+ For a complete rundown on what is supported, checkout this guide which CampaignMonitor has compiled.
43
+
44
+ [CampaignMonitor's guide to CSS support in email](http://www.campaignmonitor.com/css/)
45
+
46
+ ## Tutorial
47
+
48
+ **1. Generate a Mailer:**
49
+
50
+ rails g mailer account_mailer account_created_email
51
+
52
+ **2. Create a template to be used for emails this Mailer sends:**
53
+
54
+ In `app/views/layouts/account_mailer.html.haml`
55
+
56
+ ```haml
57
+ %html
58
+ %head
59
+ = stylesheet_link_tag "account_mailer"
60
+
61
+ %body
62
+ %table.main
63
+ %tr
64
+ %td= yield
65
+ ```
66
+
67
+ You will notice that we have added a stylesheet link in the `head`, this location is not crucial, but the use of `stylesheet_link_tag` is because it will generate a link which we can process and feed through Sprockets in order to generate the inline styles.
68
+
69
+ **3. The stylesheet.**
70
+
71
+ You can use any style off CSS you like, we're using Sass.
72
+
73
+ `app/assets/stylesheets/account_mailer.css.scss`:
74
+
75
+ ```css
76
+ body {
77
+ font-family: 'Helvetica Neue', Helvetica, sans-serif;
78
+ -webkit-font-smoothing: antialiased;
79
+ width: 100%;
80
+ background: darken(white, 8%);
81
+ }
82
+
83
+ table {
84
+ background: white;
85
+ &.main {
86
+ width: 430px;
87
+ tr td {
88
+ padding: 5px;
89
+ }
90
+ }
91
+ }
92
+ ```
93
+
94
+ **4. Email views.**
95
+
96
+ In order to take advantage of all this fancy work, you must define a html view for your email, and optionally a text version. By default we will automatically generate a text version from the text content of the html view if none is supplied.
97
+
98
+ `app/views/account_mailer/account_created_email.html.haml`:
99
+
100
+ ```haml
101
+ %p Hi #{@user.first_name},
102
+ %p Your account has been successfully created, so don't waste any time, #{link_to "Get started now", get_started_url}
103
+ ```
104
+
105
+ **5. Send**
106
+
107
+ ```ruby
108
+ AccountMailer.account_created_email(@user).deliver
109
+ ```
110
+
111
+ **6. Send awesome emails.**
112
+
113
+ The resulting email will look something like this:
114
+
115
+ ```html
116
+ <html>
117
+ <head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"></head>
118
+ <body style="font-family: 'Helvetica Neue', Helvetica, sans-serif; -webkit-font-smoothing: antialiased; width: 100%; background-color: #ebebeb;" bgcolor="#ebebeb">
119
+ <table style="width: 430px; background-color: white;" bgcolor="white">
120
+ <tr>
121
+ <td style="padding: 5px;">
122
+ <p>Hi Michael,</p>
123
+ <p>Your account has been successfully created, so don't waste any time, <a href="/started">Get started now</a></p>
124
+ </td>
125
+ </tr>
126
+ </table>
127
+ </body>
128
+ </html>
129
+ ```
130
+
131
+ **7. Grab a beer.**
132
+
133
+ As above.
134
+
135
+ ## Contributing
136
+
137
+ 1. Fork it
138
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
139
+ 3. Commit your changes (`git commit -am 'Added some feature'`)
140
+ 4. Push to the branch (`git push origin my-new-feature`)
141
+ 5. Create new Pull Request
142
+
143
+ ## Meta
144
+
145
+ | Author | Twitter |
146
+ |------:|:------------|
147
+ | Robin Joseph | [@robinjoseph08](http://twitter.com/robinjoseph08) |
@@ -0,0 +1,7 @@
1
+ #!/usr/bin/env rake
2
+ require "bundler/gem_tasks"
3
+
4
+ require 'rspec/core/rake_task'
5
+ RSpec::Core::RakeTask.new(:spec)
6
+
7
+ task :default => :spec
@@ -0,0 +1,34 @@
1
+ # -*- encoding: utf-8 -*-
2
+ require File.expand_path('../lib/action_mailer/in_style/version', __FILE__)
3
+
4
+ Gem::Specification.new do |gem|
5
+ gem.authors = ["Robin Joseph", "Ivan Vanderbyl"]
6
+ gem.email = ["robin.joseph@me.com"]
7
+ gem.description = %q{Easily create HTML emails in Rails ~>3.1}
8
+ gem.summary = %q{This gem brings you the power of the premailer gem to Rails 4
9
+ without any configuration needs. Create HTML emails, include a
10
+ CSS file as you do in a normal HTML document and premailer will
11
+ inline the included CSS.}
12
+ gem.homepage = "http://github.com/robinjoseph08/actionmailer-instyle4"
13
+
14
+ gem.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
15
+ gem.files = `git ls-files`.split("\n")
16
+ gem.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
17
+ gem.name = "actionmailer-instyle4"
18
+ gem.require_paths = ["lib"]
19
+ gem.version = ActionMailer::InStyle::VERSION
20
+
21
+ gem.add_dependency("nokogiri", ">= 1.6")
22
+ gem.add_dependency("premailer", ">= 1.7")
23
+ gem.add_dependency("actionmailer", ">= 3.1")
24
+ gem.add_dependency("activesupport", ">= 3.1")
25
+ gem.add_dependency("sprockets", ">= 2.0")
26
+
27
+ gem.add_development_dependency 'rspec-rails', '~> 2.8.0'
28
+ gem.add_development_dependency 'guard-rspec'
29
+ gem.add_development_dependency 'sass', '~> 3.1'
30
+ gem.add_development_dependency 'sqlite3', '>= 1.3.5'
31
+ gem.add_development_dependency 'mail'
32
+ gem.add_development_dependency 'combustion', '~> 0.3.1'
33
+
34
+ end
@@ -0,0 +1,7 @@
1
+ require 'rubygems'
2
+ require 'bundler'
3
+
4
+ Bundler.require :default, :development
5
+
6
+ Combustion.initialize!
7
+ run Combustion::Application
@@ -0,0 +1,21 @@
1
+ require "action_mailer/in_style/version"
2
+ require "action_mailer"
3
+
4
+ module ActionMailer
5
+ module InStyle
6
+ autoload :Processor, 'action_mailer/in_style/processor'
7
+ autoload :Premailer, 'action_mailer/in_style/premailer'
8
+
9
+ # delivering_email hook within Mail
10
+ #
11
+ # This is where the whole process kicks off.
12
+ def self.delivering_email(message)
13
+ # If the email contains a html part or is only html
14
+ if message.html_part || (message.content_type =~ /text\/html/ && message)
15
+ InStyle::Processor.inline!(message)
16
+ end
17
+ end
18
+ end
19
+ end
20
+
21
+ ActionMailer::Base.register_interceptor(ActionMailer::InStyle)
@@ -0,0 +1,45 @@
1
+ require 'premailer'
2
+ module ActionMailer
3
+ module InStyle
4
+ class Premailer < ::Premailer
5
+
6
+ def load_css_from_html!
7
+ load_css_from_asset_pipeline!
8
+ super
9
+ end
10
+
11
+ # Uses sprockets and the Rails ~>3.1 asset pipeline
12
+ # to load the compiled CSS from stylesheet links within the header of the
13
+ # email template.
14
+ def load_css_from_asset_pipeline!
15
+ if tags = @doc.search("link[@rel='stylesheet'], style")
16
+ tags.each do |tag|
17
+ if tag.to_s.strip =~ /^\<link/i && tag.attributes['href'] && media_type_ok?(tag.attributes['media'])
18
+
19
+ # If the stylesheet link begins with /assets we must be using the asset pipeline
20
+ # to generate the css. In this case we should be able to retrieve the css directly
21
+ # from sprockets
22
+ if tag.attributes['href'].to_s =~ /\/assets\//
23
+ link_uri = process_stylesheet_url(tag.attributes['href'])
24
+ asset = Rails.application.assets.find_asset(link_uri)
25
+ @css_parser.add_block!(asset.body) if asset
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
31
+
32
+ def process_stylesheet_url(href)
33
+ # Example stylesheet url: email-1bd4488901bfc2f2ccf4f044fc9154a6.css
34
+ href = href.to_s.sub(/\?[0-9a-zA-Z]+$/, '').sub(/^\/assets\//, '')
35
+
36
+ if href =~ /(\w+)\-(?:[0-9a-zA-Z]{32})\.([a-z]{3})/
37
+ href = href.gsub(/(\w+)\-(?:[0-9a-zA-Z]{32})\.([a-z]{3})/, [$1,$2].join('.'))
38
+ end
39
+
40
+ return href
41
+ end
42
+
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,90 @@
1
+ require "premailer"
2
+
3
+ module ActionMailer
4
+ module InStyle
5
+ class Processor
6
+
7
+ def self.inline!(message)
8
+ new(message).inline!
9
+ end
10
+
11
+ attr_reader :message, :premailer
12
+
13
+ # Initialize
14
+ # Accepts one argument:
15
+ # - ActionMailer message object
16
+ def initialize(message)
17
+ @message = message
18
+
19
+ @existing_html_part = message.html_part || (message.content_type =~ /text\/html/ && message)
20
+ @premailer = ActionMailer::InStyle::Premailer.new(html_part.body.to_s, :with_html_string => true, :remove_classes => true)
21
+ end
22
+
23
+ def html_part
24
+ @existing_html_part
25
+ end
26
+
27
+ # InStyle!
28
+ # Processes the message object, replacing the html part with an inlined
29
+ # html version.
30
+ #
31
+ # If the message contains attachments or text parts, these parts are preserved.
32
+ # If the message does not contain a text part, one will be constructed from the text
33
+ # content available in the html part.
34
+ def inline!
35
+ capture_existing_message_parts
36
+ reset_message_body!
37
+
38
+ add_text_part!
39
+ add_html_part!
40
+ add_attachments!
41
+
42
+ message
43
+ end
44
+
45
+ # Add an HTML part with CSS inlined.
46
+ def add_html_part!
47
+ part = Mail::Part.new
48
+ part.body = premailer.to_inline_css
49
+ part.content_type = "text/html; charset=#{@msg_charset}"
50
+ message.html_part = part
51
+ end
52
+
53
+ # Add a text part with either the pre-existing text part, or one generated with premailer.
54
+ def add_text_part!
55
+ part = Mail::Part.new
56
+ part.body = @existing_text_part || premailer.to_plain_text
57
+ part.content_type = "text/plain; charset=#{@msg_charset}"
58
+ message.text_part = part
59
+ end
60
+
61
+ # Re-add any attachments
62
+ def add_attachments!
63
+ @existing_attachments.each {|a| message.body << a }
64
+ end
65
+
66
+ def capture_existing_message_parts
67
+ @existing_text_part = message.text_part && message.text_part.body.to_s
68
+ @existing_attachments = message.attachments
69
+ @msg_charset = message.charset
70
+ end
71
+
72
+ def original_message_parts
73
+ capture_existing_message_parts
74
+
75
+ {
76
+ :html_part => html_part,
77
+ :text_part => @existing_text_part,
78
+ :attachments => @existing_attachments,
79
+ :charset => @msg_charset
80
+ }
81
+ end
82
+
83
+ def reset_message_body!
84
+ message.body = nil
85
+ message.body.instance_variable_set("@parts", Mail::PartsList.new)
86
+ end
87
+
88
+ end
89
+ end
90
+ end
@@ -0,0 +1,5 @@
1
+ module ActionMailer
2
+ module InStyle
3
+ VERSION = "0.5.4"
4
+ end
5
+ end
@@ -0,0 +1 @@
1
+ require "action_mailer/in_style"
@@ -0,0 +1,3 @@
1
+ require "action_mailer/in_style"
2
+
3
+ # This file serves only one purpose: TO allow bundler to automatically include this gem
@@ -0,0 +1,9 @@
1
+ body {
2
+ font-family: 'Helvetica Neue', Helvetica, Ariel, sans-serif;
3
+ font-size: 13px;
4
+ color: lighten(black, 30%);
5
+ }
6
+
7
+ table.striped {
8
+ width: 100%;
9
+ }
@@ -0,0 +1,18 @@
1
+ class NotificationMailer < ActionMailer::Base
2
+ layout "notification_mailer"
3
+
4
+ default :from => "Johnny Quids<quidlicker@example.com>"
5
+
6
+ def welcome_email
7
+ mail(:to => "archie@example.com", :subject => "We need dry ice")
8
+ end
9
+
10
+ def email_with_html_only
11
+ mail(:to => "archie@example.com", :subject => "We need dry ice")
12
+ end
13
+
14
+ def welcome_html_email
15
+ mail(:to => "archie@example.com", :subject => "We need dry ice")
16
+ end
17
+
18
+ end
@@ -0,0 +1,9 @@
1
+ class NotificationMailerNoStyle < ActionMailer::Base
2
+ layout "notification_mailer_without_style"
3
+
4
+ default :from => "Johnny Quids<quidlicker@example.com>"
5
+
6
+ def email_with_no_style
7
+ mail(:to => "archie@example.com", :subject => "We need dry ice")
8
+ end
9
+ end
@@ -0,0 +1,14 @@
1
+ <html>
2
+ <head>
3
+ <meta http-equiv="content-type" content="text/html; charset=utf-8">
4
+
5
+ <title>Notification_mailer.html</title>
6
+ <%#= stylesheet_link_tag "notification_mailer" %>
7
+ <link rel="stylesheet" href="/assets/notification_mailer-1bd4488901bfc2f2ccf4f044fc9154a6.css" />
8
+ </head>
9
+
10
+ <body>
11
+ <%= yield %>
12
+ </body>
13
+ </html>
14
+
@@ -0,0 +1,11 @@
1
+ <html>
2
+ <head>
3
+ <meta http-equiv="content-type" content="text/html; charset=utf-8">
4
+
5
+ <title>Notification_mailer.html</title>
6
+ </head>
7
+
8
+ <body>
9
+ <%= yield %>
10
+ </body>
11
+ </html>
@@ -0,0 +1,9 @@
1
+ <table class="striped">
2
+ <tr>
3
+ <td>
4
+ <p>Welcome, this is a HTML email</p>
5
+ <p>Another line</p>
6
+ </td>
7
+ </tr>
8
+ </table>
9
+
@@ -0,0 +1,7 @@
1
+ <table class="striped">
2
+ <tr>
3
+ <td>
4
+ Welcome, this is a HTML email
5
+ </td>
6
+ </tr>
7
+ </table>
@@ -0,0 +1,8 @@
1
+ <table class="striped">
2
+ <tr>
3
+ <td>
4
+ Welcome, this is a HTML email
5
+ </td>
6
+ </tr>
7
+ </table>
8
+
@@ -0,0 +1,3 @@
1
+ test:
2
+ adapter: sqlite3
3
+ database: db/combustion_test.sqlite
@@ -0,0 +1,3 @@
1
+ Rails.application.routes.draw do
2
+ #
3
+ end
@@ -0,0 +1,3 @@
1
+ ActiveRecord::Schema.define do
2
+ #
3
+ end
@@ -0,0 +1 @@
1
+ *.log
File without changes
@@ -0,0 +1,9 @@
1
+ require "spec_helper"
2
+
3
+ describe ActionMailer::InStyle do
4
+ describe "CSS" do
5
+ it "Should return a CSS String" do
6
+ Rails.application.assets.find_asset('notification_mailer.css.scss').body.should match /font-family: 'Helvetica Neue', Helvetica, Ariel, sans-serif/
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,7 @@
1
+ require "spec_helper"
2
+
3
+ describe ActionMailer::InStyle::Premailer do
4
+ it 'it should handle stylesheet links containing cache token' do
5
+ ActionMailer::InStyle::Premailer.new('', :with_html_string => true, :remove_classes => true).process_stylesheet_url('/assets/email.css?jf87kjJHj787JHJGH').should == 'email.css'
6
+ end
7
+ end
@@ -0,0 +1,73 @@
1
+ require "spec_helper"
2
+
3
+ describe ActionMailer::InStyle::Processor do
4
+
5
+ before do
6
+ ActionMailer::InStyle.stub(:delivering_email).and_return(message)
7
+ end
8
+
9
+ let(:message) { NotificationMailer.welcome_html_email.deliver }
10
+ let(:processor) { ActionMailer::InStyle::Processor.new(message) }
11
+
12
+ describe :message do
13
+ it "should have a html part" do
14
+ message.html_part.should_not be_nil
15
+ end
16
+ end
17
+
18
+ it "should initialize with a message object" do
19
+ processor.message.should == message
20
+ end
21
+
22
+ it "should reset message body so we can replace it with the processed body" do
23
+ processor.message.should_receive(:body=).with(nil).once
24
+ processor.reset_message_body!
25
+ end
26
+
27
+ it "captures original html part" do
28
+ processor.original_message_parts[:html_part].should be_a Mail::Part
29
+ end
30
+
31
+ it "captures original text part" do
32
+ processor.original_message_parts[:text_part].should be_a String
33
+ end
34
+
35
+ it "captures original attachments" do
36
+ processor.original_message_parts[:attachments].should be_empty
37
+ end
38
+
39
+ it "captures message charset" do
40
+ processor.original_message_parts[:charset].should == 'UTF-8'
41
+ end
42
+
43
+ describe 'message' do
44
+ it 'should have two parts' do
45
+ message.parts.size.should == 2
46
+ end
47
+ end
48
+
49
+ describe 'html part' do
50
+ def parse_html_to_doc(html)
51
+ Nokogiri::HTML(html)
52
+ end
53
+
54
+ it 'should have a html part' do
55
+ processor.html_part.should be_a Mail::Part
56
+ processor.html_part.body.should_not be_nil
57
+ end
58
+
59
+ it 'should include asset path for stylesheet in header' do
60
+ processor.html_part.body.should match /\<link(.+)href\=\"\/assets\/(\w+)\-(?:[0-9a-zA-Z]{32})\.([a-z]{3})\"(.+)\>/
61
+ end
62
+
63
+ it 'should have inlined css version without stylesheet links' do
64
+ processor.premailer.to_inline_css.should_not match /\<link(.+)href\=\"\/assets\/notification_mailer\.css\?(\w+)\"(.+)\>/
65
+ end
66
+
67
+ it 'replaces html body with inlined css version' do
68
+ processor.inline!
69
+ processor.html_part.body.should_not be_nil
70
+ parse_html_to_doc(processor.premailer.to_inline_css).css('body')[0].attributes['style'].to_s.should == "font-family: 'Helvetica Neue', Helvetica, Ariel, sans-serif; font-size: 13px; color: #4d4d4d;"
71
+ end
72
+ end
73
+ end
@@ -0,0 +1,48 @@
1
+ require "spec_helper"
2
+
3
+ describe ActionMailer::InStyle do
4
+ it "is included in Mail interceptors" do
5
+ Mail.class_variable_get("@@delivery_interceptors").should include ActionMailer::InStyle
6
+ end
7
+
8
+ let(:original_message) { NotificationMailer.welcome_html_email.deliver }
9
+ let(:message) { ActionMailer::InStyle.delivering_email(original_message) }
10
+
11
+ it "should keep text version of email if present" do
12
+ original_message.text_part.body.to_s.should == message.text_part.body.to_s
13
+ end
14
+
15
+ it "should have two body parts" do
16
+ message.parts.size.should == 2
17
+ end
18
+
19
+ it "should not have a style tag in original email" do
20
+ ActionMailer::InStyle.should_receive(:delivering_email).once
21
+ original_message = NotificationMailer.welcome_html_email.deliver
22
+ Nokogiri::HTML(original_message.html_part.body.to_s).css('body').first.attributes['style'].should be_nil
23
+ end
24
+
25
+ it "should replace html version with premailer processed inline version" do
26
+ # If it has a style attribue then we have processed it
27
+ Nokogiri::HTML(message.html_part.body.to_s).css('body').first.attributes['style'].should_not be_nil
28
+ end
29
+
30
+ it "should find stylesheet assets" do
31
+
32
+ end
33
+
34
+ it "should not do anything if no stylesheets are present" do
35
+ message_with_no_css = ActionMailer::InStyle.delivering_email(NotificationMailerNoStyle.email_with_no_style.deliver)
36
+ Nokogiri::HTML(message_with_no_css.html_part.body.to_s).css('body').first.attributes['style'].should be_nil
37
+ end
38
+
39
+ it "should inline stylesheets and replace IDs and Classes" do
40
+ # According to the email template the first table usually has a 'striped' class
41
+ Nokogiri::HTML(message.html_part.body.to_s).css('table').first.attributes['class'].should be_nil
42
+ end
43
+
44
+ it "should create a text part from the html part if not present" do
45
+ message = ActionMailer::InStyle.delivering_email(NotificationMailer.email_with_html_only.deliver)
46
+ message.text_part.body.to_s.should == "Welcome, this is a HTML email\n\nAnother line"
47
+ end
48
+ end
@@ -0,0 +1,24 @@
1
+ require 'rubygems'
2
+ require 'bundler'
3
+
4
+ Bundler.require
5
+
6
+ require "rails"
7
+ require "combustion"
8
+
9
+ Combustion.initialize!
10
+
11
+ require 'rspec/rails'
12
+
13
+ require 'nokogiri'
14
+ require "combustion"
15
+
16
+ require 'action_mailer/in_style'
17
+
18
+ RSpec.configure do |config|
19
+ config.mock_with :rspec
20
+
21
+ config.before do
22
+ ActionMailer::Base.delivery_method = :test
23
+ end
24
+ end
metadata ADDED
@@ -0,0 +1,253 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: actionmailer-instyle4
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.5.4
5
+ platform: ruby
6
+ authors:
7
+ - Robin Joseph
8
+ - Ivan Vanderbyl
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2014-07-18 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: nokogiri
16
+ requirement: !ruby/object:Gem::Requirement
17
+ requirements:
18
+ - - ">="
19
+ - !ruby/object:Gem::Version
20
+ version: '1.6'
21
+ type: :runtime
22
+ prerelease: false
23
+ version_requirements: !ruby/object:Gem::Requirement
24
+ requirements:
25
+ - - ">="
26
+ - !ruby/object:Gem::Version
27
+ version: '1.6'
28
+ - !ruby/object:Gem::Dependency
29
+ name: premailer
30
+ requirement: !ruby/object:Gem::Requirement
31
+ requirements:
32
+ - - ">="
33
+ - !ruby/object:Gem::Version
34
+ version: '1.7'
35
+ type: :runtime
36
+ prerelease: false
37
+ version_requirements: !ruby/object:Gem::Requirement
38
+ requirements:
39
+ - - ">="
40
+ - !ruby/object:Gem::Version
41
+ version: '1.7'
42
+ - !ruby/object:Gem::Dependency
43
+ name: actionmailer
44
+ requirement: !ruby/object:Gem::Requirement
45
+ requirements:
46
+ - - ">="
47
+ - !ruby/object:Gem::Version
48
+ version: '3.1'
49
+ type: :runtime
50
+ prerelease: false
51
+ version_requirements: !ruby/object:Gem::Requirement
52
+ requirements:
53
+ - - ">="
54
+ - !ruby/object:Gem::Version
55
+ version: '3.1'
56
+ - !ruby/object:Gem::Dependency
57
+ name: activesupport
58
+ requirement: !ruby/object:Gem::Requirement
59
+ requirements:
60
+ - - ">="
61
+ - !ruby/object:Gem::Version
62
+ version: '3.1'
63
+ type: :runtime
64
+ prerelease: false
65
+ version_requirements: !ruby/object:Gem::Requirement
66
+ requirements:
67
+ - - ">="
68
+ - !ruby/object:Gem::Version
69
+ version: '3.1'
70
+ - !ruby/object:Gem::Dependency
71
+ name: sprockets
72
+ requirement: !ruby/object:Gem::Requirement
73
+ requirements:
74
+ - - ">="
75
+ - !ruby/object:Gem::Version
76
+ version: '2.0'
77
+ type: :runtime
78
+ prerelease: false
79
+ version_requirements: !ruby/object:Gem::Requirement
80
+ requirements:
81
+ - - ">="
82
+ - !ruby/object:Gem::Version
83
+ version: '2.0'
84
+ - !ruby/object:Gem::Dependency
85
+ name: rspec-rails
86
+ requirement: !ruby/object:Gem::Requirement
87
+ requirements:
88
+ - - "~>"
89
+ - !ruby/object:Gem::Version
90
+ version: 2.8.0
91
+ type: :development
92
+ prerelease: false
93
+ version_requirements: !ruby/object:Gem::Requirement
94
+ requirements:
95
+ - - "~>"
96
+ - !ruby/object:Gem::Version
97
+ version: 2.8.0
98
+ - !ruby/object:Gem::Dependency
99
+ name: guard-rspec
100
+ requirement: !ruby/object:Gem::Requirement
101
+ requirements:
102
+ - - ">="
103
+ - !ruby/object:Gem::Version
104
+ version: '0'
105
+ type: :development
106
+ prerelease: false
107
+ version_requirements: !ruby/object:Gem::Requirement
108
+ requirements:
109
+ - - ">="
110
+ - !ruby/object:Gem::Version
111
+ version: '0'
112
+ - !ruby/object:Gem::Dependency
113
+ name: sass
114
+ requirement: !ruby/object:Gem::Requirement
115
+ requirements:
116
+ - - "~>"
117
+ - !ruby/object:Gem::Version
118
+ version: '3.1'
119
+ type: :development
120
+ prerelease: false
121
+ version_requirements: !ruby/object:Gem::Requirement
122
+ requirements:
123
+ - - "~>"
124
+ - !ruby/object:Gem::Version
125
+ version: '3.1'
126
+ - !ruby/object:Gem::Dependency
127
+ name: sqlite3
128
+ requirement: !ruby/object:Gem::Requirement
129
+ requirements:
130
+ - - ">="
131
+ - !ruby/object:Gem::Version
132
+ version: 1.3.5
133
+ type: :development
134
+ prerelease: false
135
+ version_requirements: !ruby/object:Gem::Requirement
136
+ requirements:
137
+ - - ">="
138
+ - !ruby/object:Gem::Version
139
+ version: 1.3.5
140
+ - !ruby/object:Gem::Dependency
141
+ name: mail
142
+ requirement: !ruby/object:Gem::Requirement
143
+ requirements:
144
+ - - ">="
145
+ - !ruby/object:Gem::Version
146
+ version: '0'
147
+ type: :development
148
+ prerelease: false
149
+ version_requirements: !ruby/object:Gem::Requirement
150
+ requirements:
151
+ - - ">="
152
+ - !ruby/object:Gem::Version
153
+ version: '0'
154
+ - !ruby/object:Gem::Dependency
155
+ name: combustion
156
+ requirement: !ruby/object:Gem::Requirement
157
+ requirements:
158
+ - - "~>"
159
+ - !ruby/object:Gem::Version
160
+ version: 0.3.1
161
+ type: :development
162
+ prerelease: false
163
+ version_requirements: !ruby/object:Gem::Requirement
164
+ requirements:
165
+ - - "~>"
166
+ - !ruby/object:Gem::Version
167
+ version: 0.3.1
168
+ description: Easily create HTML emails in Rails ~>3.1
169
+ email:
170
+ - robin.joseph@me.com
171
+ executables: []
172
+ extensions: []
173
+ extra_rdoc_files: []
174
+ files:
175
+ - ".gitignore"
176
+ - ".rspec"
177
+ - Gemfile
178
+ - Guardfile
179
+ - LICENSE
180
+ - README.md
181
+ - Rakefile
182
+ - actionmailer-instyle4.gemspec
183
+ - config.ru
184
+ - lib/action_mailer/in_style.rb
185
+ - lib/action_mailer/in_style/premailer.rb
186
+ - lib/action_mailer/in_style/processor.rb
187
+ - lib/action_mailer/in_style/version.rb
188
+ - lib/action_mailer/instyle.rb
189
+ - lib/actionmailer-instyle.rb
190
+ - spec/internal/app/assets/stylesheets/notification_mailer.css.scss
191
+ - spec/internal/app/mailers/notification_mailer.rb
192
+ - spec/internal/app/mailers/notification_mailer_no_layout.rb
193
+ - spec/internal/app/views/layouts/notification_mailer.html.erb
194
+ - spec/internal/app/views/layouts/notification_mailer_without_style.html.erb
195
+ - spec/internal/app/views/notification_mailer/email_with_html_only.html.erb
196
+ - spec/internal/app/views/notification_mailer/welcome_html_email.html.erb
197
+ - spec/internal/app/views/notification_mailer/welcome_html_email.text.erb
198
+ - spec/internal/app/views/notification_mailer_no_style/email_with_no_style.html.erb
199
+ - spec/internal/config/database.yml
200
+ - spec/internal/config/routes.rb
201
+ - spec/internal/db/schema.rb
202
+ - spec/internal/log/.gitignore
203
+ - spec/internal/public/favicon.ico
204
+ - spec/lib/action_mailer/inline/css_helper_spec.rb
205
+ - spec/lib/action_mailer/inline/premailer_spec.rb
206
+ - spec/lib/action_mailer/inline/processor_spec.rb
207
+ - spec/lib/action_mailer/inline_spec.rb
208
+ - spec/spec_helper.rb
209
+ homepage: http://github.com/robinjoseph08/actionmailer-instyle4
210
+ licenses: []
211
+ metadata: {}
212
+ post_install_message:
213
+ rdoc_options: []
214
+ require_paths:
215
+ - lib
216
+ required_ruby_version: !ruby/object:Gem::Requirement
217
+ requirements:
218
+ - - ">="
219
+ - !ruby/object:Gem::Version
220
+ version: '0'
221
+ required_rubygems_version: !ruby/object:Gem::Requirement
222
+ requirements:
223
+ - - ">="
224
+ - !ruby/object:Gem::Version
225
+ version: '0'
226
+ requirements: []
227
+ rubyforge_project:
228
+ rubygems_version: 2.4.1
229
+ signing_key:
230
+ specification_version: 4
231
+ summary: This gem brings you the power of the premailer gem to Rails 4 without any
232
+ configuration needs. Create HTML emails, include a CSS file as you do in a normal
233
+ HTML document and premailer will inline the included CSS.
234
+ test_files:
235
+ - spec/internal/app/assets/stylesheets/notification_mailer.css.scss
236
+ - spec/internal/app/mailers/notification_mailer.rb
237
+ - spec/internal/app/mailers/notification_mailer_no_layout.rb
238
+ - spec/internal/app/views/layouts/notification_mailer.html.erb
239
+ - spec/internal/app/views/layouts/notification_mailer_without_style.html.erb
240
+ - spec/internal/app/views/notification_mailer/email_with_html_only.html.erb
241
+ - spec/internal/app/views/notification_mailer/welcome_html_email.html.erb
242
+ - spec/internal/app/views/notification_mailer/welcome_html_email.text.erb
243
+ - spec/internal/app/views/notification_mailer_no_style/email_with_no_style.html.erb
244
+ - spec/internal/config/database.yml
245
+ - spec/internal/config/routes.rb
246
+ - spec/internal/db/schema.rb
247
+ - spec/internal/log/.gitignore
248
+ - spec/internal/public/favicon.ico
249
+ - spec/lib/action_mailer/inline/css_helper_spec.rb
250
+ - spec/lib/action_mailer/inline/premailer_spec.rb
251
+ - spec/lib/action_mailer/inline/processor_spec.rb
252
+ - spec/lib/action_mailer/inline_spec.rb
253
+ - spec/spec_helper.rb