premailer-rails 1.9.7 → 1.11.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (42) hide show
  1. checksums.yaml +5 -5
  2. data/.gitignore +4 -0
  3. data/.travis.yml +3 -2
  4. data/CHANGELOG.md +26 -0
  5. data/Gemfile +8 -4
  6. data/README.md +21 -29
  7. data/VERSION +1 -1
  8. data/lib/premailer/rails/css_helper.rb +30 -11
  9. data/lib/premailer/rails/css_loaders/asset_pipeline_loader.rb +12 -11
  10. data/lib/premailer/rails/css_loaders/network_loader.rb +1 -1
  11. data/lib/premailer/rails/css_loaders.rb +0 -1
  12. data/lib/premailer/rails/customized_premailer.rb +4 -4
  13. data/lib/premailer/rails/hook.rb +2 -6
  14. data/lib/premailer/rails.rb +2 -1
  15. data/premailer-rails.gemspec +1 -2
  16. data/spec/integration/css_helper_spec.rb +170 -139
  17. data/spec/integration/delivery_spec.rb +13 -0
  18. data/spec/integration/hook_spec.rb +36 -11
  19. data/spec/rails_app/app/assets/config/manifest.js +3 -0
  20. data/spec/rails_app/app/assets/stylesheets/application.css +3 -0
  21. data/spec/rails_app/app/mailers/application_mailer.rb +4 -0
  22. data/spec/rails_app/app/mailers/welcome_mailer.rb +6 -0
  23. data/spec/rails_app/app/views/layouts/mailer.html.erb +11 -0
  24. data/spec/rails_app/app/views/welcome_mailer/welcome_email.html.erb +1 -0
  25. data/spec/rails_app/config/application.rb +13 -0
  26. data/spec/rails_app/config/boot.rb +5 -0
  27. data/spec/rails_app/config/environment.rb +2 -0
  28. data/spec/rails_app/config/environments/test.rb +10 -0
  29. data/spec/rails_app/config/initializers/assets.rb +1 -0
  30. data/spec/rails_app/config/routes.rb +3 -0
  31. data/spec/rails_app/config.ru +5 -0
  32. data/spec/rails_app/log/.keep +0 -0
  33. data/spec/rails_app/tmp/.keep +0 -0
  34. data/spec/spec_helper.rb +3 -8
  35. data/spec/support/fixtures/message.rb +40 -0
  36. data/spec/unit/css_loaders/network_loader_spec.rb +1 -1
  37. data/spec/unit/customized_premailer_spec.rb +32 -40
  38. metadata +35 -31
  39. data/lib/premailer/rails/css_loaders/cache_loader.rb +0 -29
  40. data/spec/integration/hook_registration_spec.rb +0 -11
  41. data/spec/support/stubs/action_mailer.rb +0 -5
  42. data/spec/support/stubs/rails.rb +0 -51
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 34449fbe39f5a20061a3f6b389a95c4286b6a2cc
4
- data.tar.gz: 551a7262f0926f02554a6bea9c47eb4446d04d82
2
+ SHA256:
3
+ metadata.gz: 13055f85c556422022c71564c81f5816ecffd482e4514c1481212fab2c942eb7
4
+ data.tar.gz: 8b9093f66f195ac826382329877be7c9b863650c5bcb0c057bae0cc073b8978d
5
5
  SHA512:
6
- metadata.gz: 507c28b394a9ec1fdf24e6a51b45f0cad7ac6b7ad3012f7c5993db164eeb1f100d9a410a10d4d5876f68cf9e8f9a3a2febf8a5cad5cc116823abaa84714ba8e7
7
- data.tar.gz: f3fb70d57c1acf9e196dadc98c53061ed45b2604c9a721e8eff194dd9e42b45243c5c07b4bcaa6b555ae97e5d163ba27c65cb6dcbfab61ed9b4f2168f813f853
6
+ metadata.gz: a861465e80d026c7e221b09f0c395be4d4fb26fa3662a233de5ba8295c41f0861b79958f873830fa4bd6333bd21798298155f8cadf1cf7861f08f5348ee3f901
7
+ data.tar.gz: f4cd1b29b3b1a4ee43fe83971b35b6a43896298ab3c1fec8d4fc91e2fc0d1290b353bba0096e2ae45376e394f6ad00142cf3dda7447a72259c7639c01fbd4231
data/.gitignore CHANGED
@@ -2,3 +2,7 @@
2
2
  doc/
3
3
  Gemfile.lock
4
4
  coverage/
5
+ spec/rails_app/log/*
6
+ spec/rails_app/tmp/*
7
+ .ruby-version
8
+ /.bundle
data/.travis.yml CHANGED
@@ -3,11 +3,12 @@ language: ruby
3
3
  cache: bundler
4
4
  script: bundle exec rspec
5
5
  rvm:
6
- - 2.4.1
6
+ - 2.6.5
7
+ - 2.7.0
7
8
  env:
8
9
  matrix:
9
- - ACTION_MAILER_VERSION=4
10
10
  - ACTION_MAILER_VERSION=5
11
+ - ACTION_MAILER_VERSION=6
11
12
  - ACTION_MAILER_VERSION=master
12
13
  matrix:
13
14
  fast_finish: true
data/CHANGELOG.md CHANGED
@@ -1,5 +1,31 @@
1
1
  # Changelog
2
2
 
3
+ ## v1.11.1
4
+
5
+ - Check if `Rails.application` is defined (@pabloh, #250)
6
+
7
+ ## v1.11.0
8
+
9
+ - Remove `force_encoding!`
10
+
11
+ ## v1.10.3
12
+
13
+ - Remove upper version constraint for actionmailer
14
+
15
+ ## v1.10.2
16
+
17
+ - Explicitly check for assets_manifest (@derekwheel, #214)
18
+
19
+ ## v1.10.1
20
+
21
+ - Catch error when sprockets can't find asset (@kirs, #209)
22
+
23
+ ## v1.10.0
24
+
25
+ - Drop support for hpricot now that premailer-rails also doesn't support it
26
+ - Use `Rails.application.assets_manifest` instead of `Rails.application.assets` in Asset Pipeline loader (@kirs, #201)
27
+ - Introduce `:strategies` config option that allows to control CSS fetching stragies
28
+
3
29
  ## v1.9.7
4
30
 
5
31
  - Use `Rails.root` in `FileSystemLoader` (@stanhu, #195)
data/Gemfile CHANGED
@@ -2,16 +2,20 @@ source 'https://rubygems.org'
2
2
 
3
3
  gemspec
4
4
 
5
- action_mailer_version = ENV.fetch('ACTION_MAILER_VERSION', '5')
5
+ rails_version = ENV.fetch('ACTION_MAILER_VERSION', '5')
6
6
 
7
- if action_mailer_version == 'master'
7
+ if rails_version == 'master'
8
8
  git 'git://github.com/rails/rails.git' do
9
- gem 'actionmailer'
9
+ gem 'rails'
10
10
  end
11
+ gem 'sprockets-rails', github: 'rails/sprockets-rails'
12
+ gem 'arel', github: 'rails/arel'
11
13
  else
12
- gem 'actionmailer', "~> #{action_mailer_version}"
14
+ gem 'rails', "~> #{rails_version}"
13
15
  end
14
16
 
17
+ gem 'byebug'
18
+
15
19
  platforms :rbx do
16
20
  gem 'rubysl'
17
21
  gem 'racc'
data/README.md CHANGED
@@ -39,34 +39,34 @@ styled emails without having to set anything up.
39
39
  Whenever premailer-rails processes an email, it collects the URLs of all linked
40
40
  stylesheets (`<link rel="stylesheet" href="css_url">`). Then, for each of these
41
41
  URLs, it tries to get the content through a couple of strategies. As long as
42
- a strategy does not return anything, the next one is used. The strategies and
43
- their order are as follows:
42
+ a strategy does not return anything, the next one is used. The strategies
43
+ available are:
44
44
 
45
- 1. **Cache:** If there's a file in cache matching that URL, the cache content
46
- is returned. The cache right now is rather rudimentary. Whenever a CSS file
47
- is retrieved, it is stored in memory such that subsequent requests to the
48
- same file are faster. The caching is disabled inside Rails in the
49
- development environment.
50
-
51
- 2. **File System:** If there's a file inside `public/` with the same path as in
45
+ - `:filesystem`: If there's a file inside `public/` with the same path as in
52
46
  the URL, it is read from disk. E.g. if the URL is
53
47
  `http://cdn.example.com/assets/email.css` the contents of the file located
54
48
  at `public/assets/email.css` gets returned if it exists.
55
49
 
56
- 3. **Asset Pipeline:** If Rails is available and the asset pipeline is enabled,
50
+ - `:asset_pipeline`: If Rails is available and the asset pipeline is enabled,
57
51
  the file is retrieved through the asset pipeline. E.g. if the URL is
58
52
  `http://cdn.example.com/assets/email-fingerprint123.css`, the file
59
53
  `email.css` is requested from the asset pipeline. That is, the fingerprint
60
54
  and the prefix (in this case `assets` is the prefix) are stripped before
61
55
  requesting it from the asset pipeline.
62
56
 
63
- 4. **Network:** As a last resort, the URL is simply requested and the response
64
- body is used. This is usefull when the assets are not bundled in the
57
+ - `:network`: As a last resort, the URL is simply requested and the response
58
+ body is used. This is useful when the assets are not bundled in the
65
59
  application and only available on a CDN. On Heroku e.g. you can add assets
66
60
  to your `.slugignore` causing your assets to not be available to the app
67
61
  (and thus resulting in a smaller app) and deploy the assets to a CDN such
68
62
  as S3/CloudFront.
69
63
 
64
+ You can configure which strategies you want to use as well as specify their
65
+ order. Refer to the *Configuration* section for more on this.
66
+
67
+ Note that the retrieved CSS is cached when the gem is running with Rails in
68
+ production.
69
+
70
70
  ## Installation
71
71
 
72
72
  Simply add the gem to your `Gemfile`:
@@ -75,20 +75,12 @@ Simply add the gem to your `Gemfile`:
75
75
  gem 'premailer-rails'
76
76
  ```
77
77
 
78
- premailer-rails requires either [nokogiri] or [hpricot]. It doesn't list them as
79
- a dependency so you can choose which one to use. Since hpricot is no longer
80
- maintained, I suggest you to go with nokogiri. Add either one to your `Gemfile`:
81
-
82
- ```ruby
83
- gem 'nokogiri'
84
- # or
85
- gem 'hpricot'
86
- ```
87
-
88
- If both gems are loaded for some reason, premailer chooses hpricot.
89
-
90
- You can also explicitly configure the apapter as documented
91
- [here](https://github.com/premailer/premailer#adapters).
78
+ premailer-rails and premailer require a gem that is used to parse the email's
79
+ HTML. For a list of supported gems and how to select which one to use, please
80
+ refer to the [*Adapter*
81
+ section](https://github.com/premailer/premailer#adapters) of premailer. Note
82
+ that there is no hard dependency from either gem so you should add one yourself.
83
+ Also note that this gem is only tested with [nokogiri].
92
84
 
93
85
  ## Configuration
94
86
 
@@ -107,7 +99,8 @@ configs are:
107
99
  ```ruby
108
100
  {
109
101
  input_encoding: 'UTF-8',
110
- generate_text_part: true
102
+ generate_text_part: true,
103
+ strategies: [:filesystem, :asset_pipeline, :network]
111
104
  }
112
105
  ```
113
106
 
@@ -185,9 +178,8 @@ premailer-rails is released under the MIT license. See the [license file].
185
178
  [premailer]: https://github.com/premailer/premailer
186
179
  [actionmailer]: https://github.com/rails/rails/tree/master/actionmailer
187
180
  [nokogiri]: https://github.com/sparklemotion/nokogiri
188
- [hpricot]: https://github.com/hpricot/hpricot
189
181
 
190
- [premailer documentation]: http://rubydoc.info/gems/premailer/1.7.3/Premailer:initialize
182
+ [premailer documentation]: https://www.rubydoc.info/gems/premailer/Premailer:initialize
191
183
 
192
184
  [fphilipe twitter]: https://twitter.com/fphilipe
193
185
  [license file]: LICENSE
data/VERSION CHANGED
@@ -1 +1 @@
1
- 1.9.7
1
+ 1.11.1
@@ -5,12 +5,8 @@ class Premailer
5
5
 
6
6
  FileNotFound = Class.new(StandardError)
7
7
 
8
- STRATEGIES = [
9
- CSSLoaders::CacheLoader,
10
- CSSLoaders::FileSystemLoader,
11
- CSSLoaders::AssetPipelineLoader,
12
- CSSLoaders::NetworkLoader
13
- ]
8
+ attr_accessor :cache
9
+ self.cache = {}
14
10
 
15
11
  # Returns all linked CSS files concatenated as string.
16
12
  def css_for_doc(doc)
@@ -18,8 +14,10 @@ class Premailer
18
14
  end
19
15
 
20
16
  def css_for_url(url)
21
- load_css(url).tap do |content|
22
- CSSLoaders::CacheLoader.store(url, content)
17
+ if cache_enabled?
18
+ load_css_with_cache(url)
19
+ else
20
+ load_css(url)
23
21
  end
24
22
  end
25
23
 
@@ -36,14 +34,35 @@ class Premailer
36
34
  end
37
35
  end
38
36
 
37
+ def load_css_with_cache(url)
38
+ self.cache[url] ||= load_css(url)
39
+ end
40
+
41
+ def cache_enabled?
42
+ defined?(::Rails.env) && ::Rails.env.production?
43
+ end
44
+
39
45
  def load_css(url)
40
- STRATEGIES.each do |strategy|
41
- css = strategy.load(url)
42
- return css.force_encoding('UTF-8') if css
46
+ Premailer::Rails.config.fetch(:strategies).each do |strategy|
47
+ css = find_strategy(strategy).load(url)
48
+ return css if css
43
49
  end
44
50
 
45
51
  raise FileNotFound, %{File with URL "#{url}" could not be loaded by any strategy.}
46
52
  end
53
+
54
+ def find_strategy(key)
55
+ case key
56
+ when :filesystem
57
+ CSSLoaders::FileSystemLoader
58
+ when :asset_pipeline
59
+ CSSLoaders::AssetPipelineLoader
60
+ when :network
61
+ CSSLoaders::NetworkLoader
62
+ else
63
+ key
64
+ end
65
+ end
47
66
  end
48
67
  end
49
68
  end
@@ -5,18 +5,11 @@ class Premailer
5
5
  extend self
6
6
 
7
7
  def load(url)
8
- if asset_pipeline_present?
9
- file = file_name(url)
10
- asset = ::Rails.application.assets.find_asset(file)
11
- asset.to_s if asset
12
- end
13
- end
8
+ return unless asset_pipeline_present?
14
9
 
15
- def asset_pipeline_present?
16
- defined?(::Rails) &&
17
- ::Rails.respond_to?(:application) &&
18
- ::Rails.application.respond_to?(:assets) &&
19
- ::Rails.application.assets
10
+ file = file_name(url)
11
+ ::Rails.application.assets_manifest.find_sources(file).first
12
+ rescue Errno::ENOENT, TypeError => _error
20
13
  end
21
14
 
22
15
  def file_name(url)
@@ -29,6 +22,14 @@ class Premailer
29
22
  .sub(/\A#{prefix}/, '')
30
23
  .sub(/-(\h{32}|\h{64})\.css\z/, '.css')
31
24
  end
25
+
26
+ def asset_pipeline_present?
27
+ defined?(::Rails) &&
28
+ ::Rails.respond_to?(:application) &&
29
+ ::Rails.application &&
30
+ ::Rails.application.respond_to?(:assets_manifest) &&
31
+ ::Rails.application.assets_manifest
32
+ end
32
33
  end
33
34
  end
34
35
  end
@@ -14,7 +14,7 @@ class Premailer
14
14
 
15
15
  if uri.host.present?
16
16
  return uri if uri.scheme.present?
17
- URI("http://#{uri.to_s}")
17
+ URI("http:#{uri}")
18
18
  elsif asset_host_present?
19
19
  scheme, host = asset_host(url).split(%r{:?//})
20
20
  scheme, host = host, scheme if host.nil?
@@ -1,6 +1,5 @@
1
1
  require 'uri'
2
2
 
3
- require 'premailer/rails/css_loaders/cache_loader'
4
3
  require 'premailer/rails/css_loaders/file_system_loader'
5
4
  require 'premailer/rails/css_loaders/asset_pipeline_loader'
6
5
  require 'premailer/rails/css_loaders/network_loader'
@@ -4,10 +4,10 @@ class Premailer
4
4
  def initialize(html)
5
5
  # In order to pass the CSS as string to super it is necessary to access
6
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.
7
+ # initialized. The ::Premailer::Adapter handles the discovery of
8
+ # a suitable adapter. To make load_html work, an adapter needs to be
9
+ # included and @options[:with_html_string] needs to be set. For further
10
+ # information, refer to ::Premailer#initialize.
11
11
  @options = Rails.config.merge(with_html_string: true)
12
12
  Premailer.send(:include, Adapter.find(Adapter.use))
13
13
  doc = load_html(html)
@@ -73,10 +73,8 @@ class Premailer
73
73
  part = html_part
74
74
  html = premailer.to_inline_css
75
75
  Mail::Part.new do
76
- content_transfer_encoding part.content_transfer_encoding
77
- content_type "text/html; charset=#{part.charset}"
76
+ content_type "text/html; charset=#{html.encoding}"
78
77
  body html
79
- body_encoding part.body.encoding
80
78
  end
81
79
  end
82
80
 
@@ -85,10 +83,8 @@ class Premailer
85
83
  part = html_part
86
84
  text = premailer.to_plain_text
87
85
  Mail::Part.new do
88
- content_transfer_encoding part.content_transfer_encoding
89
- content_type "text/plain; charset=#{part.charset}"
86
+ content_type "text/plain; charset=#{text.encoding}"
90
87
  body text
91
- body_encoding part.body.encoding
92
88
  end
93
89
  end
94
90
  end
@@ -11,7 +11,8 @@ class Premailer
11
11
  module Rails
12
12
  @config = {
13
13
  input_encoding: 'UTF-8',
14
- generate_text_part: true
14
+ generate_text_part: true,
15
+ strategies: [:filesystem, :asset_pipeline, :network]
15
16
  }
16
17
  class << self
17
18
  attr_accessor :config
@@ -22,10 +22,9 @@ Gem::Specification.new do |s|
22
22
  s.require_paths = ["lib"]
23
23
 
24
24
  s.add_dependency 'premailer', '~> 1.7', '>= 1.7.9'
25
- s.add_dependency 'actionmailer', '>= 3', '< 6'
25
+ s.add_dependency 'actionmailer', '>= 3'
26
26
 
27
27
  s.add_development_dependency 'rspec', '~> 3.3'
28
28
  s.add_development_dependency 'nokogiri'
29
- s.add_development_dependency 'hpricot' unless RUBY_PLATFORM == 'java'
30
29
  s.add_development_dependency 'coveralls' if RUBY_ENGINE == 'ruby'
31
30
  end