aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndrew White <andyw@pixeltrix.co.uk>2015-05-04 19:46:51 +0100
committerAndrew White <andyw@pixeltrix.co.uk>2015-05-04 19:46:51 +0100
commitfaaed863dd374b6c3c3ee0e317ed213edce1dd4d (patch)
treeadf226d62861d1a546895843c867939cfc9c854c
parentfcc46833a88cb287e92dbfec76091a0fa29d3948 (diff)
downloadrails-faaed863dd374b6c3c3ee0e317ed213edce1dd4d.tar.gz
rails-faaed863dd374b6c3c3ee0e317ed213edce1dd4d.tar.bz2
rails-faaed863dd374b6c3c3ee0e317ed213edce1dd4d.zip
Document inline image mailer preview interceptor
Explain what the interceptor is used for and how to remove it.
-rw-r--r--actionmailer/lib/action_mailer.rb1
-rw-r--r--actionmailer/lib/action_mailer/inline_preview_interceptor.rb61
-rw-r--r--actionmailer/lib/action_mailer/preview.rb50
-rw-r--r--railties/test/application/configuration_test.rb17
-rw-r--r--railties/test/application/mailer_previews_test.rb10
5 files changed, 83 insertions, 56 deletions
diff --git a/actionmailer/lib/action_mailer.rb b/actionmailer/lib/action_mailer.rb
index 17d8dcc208..291a8c1e34 100644
--- a/actionmailer/lib/action_mailer.rb
+++ b/actionmailer/lib/action_mailer.rb
@@ -40,6 +40,7 @@ module ActionMailer
autoload :Base
autoload :DeliveryMethods
+ autoload :InlinePreviewInterceptor
autoload :MailHelper
autoload :Preview
autoload :Previews, 'action_mailer/preview'
diff --git a/actionmailer/lib/action_mailer/inline_preview_interceptor.rb b/actionmailer/lib/action_mailer/inline_preview_interceptor.rb
new file mode 100644
index 0000000000..dea5e52f0c
--- /dev/null
+++ b/actionmailer/lib/action_mailer/inline_preview_interceptor.rb
@@ -0,0 +1,61 @@
+require 'base64'
+
+module ActionMailer
+ # Implements a mailer preview interceptor that converts image tag src attributes
+ # that use inline cid: style urls to data: style urls so that they are visible
+ # when previewing a HTML email in a web browser.
+ #
+ # This interceptor is enabled by default, to remove it delete it from the
+ # <tt>ActionMailer::Base.preview_interceptors</tt> array:
+ #
+ # ActionMailer::Base.preview_interceptors.delete(ActionMailer::InlinePreviewInterceptor)
+ #
+ class InlinePreviewInterceptor
+ PATTERN = /src=(?:"cid:[^"]+"|'cid:[^']+')/i
+
+ include Base64
+
+ def self.previewing_email(message) #:nodoc:
+ new(message).transform!
+ end
+
+ def initialize(message) #:nodoc:
+ @message = message
+ end
+
+ def transform! #:nodoc:
+ return message if html_part.blank?
+
+ html_source.gsub!(PATTERN) do |match|
+ if part = find_part(match[9..-2])
+ %[src="#{data_url(part)}"]
+ else
+ match
+ end
+ end
+
+ message
+ end
+
+ private
+ def message
+ @message
+ end
+
+ def html_part
+ @html_part ||= message.html_part
+ end
+
+ def html_source
+ html_part.body.raw_source
+ end
+
+ def data_url(part)
+ "data:#{part.mime_type};base64,#{strict_encode64(part.body.raw_source)}"
+ end
+
+ def find_part(cid)
+ message.all_parts.find{ |p| p.attachment? && p.cid == cid }
+ end
+ end
+end
diff --git a/actionmailer/lib/action_mailer/preview.rb b/actionmailer/lib/action_mailer/preview.rb
index 4888eac345..25ad7ee721 100644
--- a/actionmailer/lib/action_mailer/preview.rb
+++ b/actionmailer/lib/action_mailer/preview.rb
@@ -1,57 +1,9 @@
require 'active_support/descendants_tracker'
-require 'base64'
module ActionMailer
module Previews #:nodoc:
extend ActiveSupport::Concern
- class InlineAttachments #:nodoc:
- PATTERN = /src=(?:"cid:[^"]+"|'cid:[^']+')/i
-
- include Base64
-
- attr_reader :message
-
- def self.previewing_email(message)
- new(message).transform!
- end
-
- def initialize(message)
- @message = message
- end
-
- def transform!
- return message if html_part.blank?
-
- html_source.gsub!(PATTERN) do |match|
- if part = find_part(match[9..-2])
- %[src="#{data_url(part)}"]
- else
- match
- end
- end
-
- message
- end
-
- private
- def html_part
- @html_part ||= message.html_part
- end
-
- def html_source
- html_part.body.raw_source
- end
-
- def data_url(part)
- "data:#{part.mime_type};base64,#{urlsafe_encode64(part.body.raw_source)}"
- end
-
- def find_part(cid)
- message.all_parts.find{ |p| p.attachment? && p.cid == cid }
- end
- end
-
included do
# Set the location of mailer previews through app configuration:
#
@@ -69,7 +21,7 @@ module ActionMailer
# :nodoc:
mattr_accessor :preview_interceptors, instance_writer: false
- self.preview_interceptors = [ActionMailer::Previews::InlineAttachments]
+ self.preview_interceptors = [ActionMailer::InlinePreviewInterceptor]
end
module ClassMethods
diff --git a/railties/test/application/configuration_test.rb b/railties/test/application/configuration_test.rb
index 14912326fc..38516a1c1a 100644
--- a/railties/test/application/configuration_test.rb
+++ b/railties/test/application/configuration_test.rb
@@ -690,7 +690,7 @@ module ApplicationTests
_ = ActionMailer::Base
- assert_equal [ActionMailer::Previews::InlineAttachments, ::MyPreviewMailInterceptor], ActionMailer::Base.preview_interceptors
+ assert_equal [ActionMailer::InlinePreviewInterceptor, ::MyPreviewMailInterceptor], ActionMailer::Base.preview_interceptors
end
test "registers multiple preview interceptors with ActionMailer" do
@@ -703,7 +703,20 @@ module ApplicationTests
_ = ActionMailer::Base
- assert_equal [ActionMailer::Previews::InlineAttachments, MyPreviewMailInterceptor, MyOtherPreviewMailInterceptor], ActionMailer::Base.preview_interceptors
+ assert_equal [ActionMailer::InlinePreviewInterceptor, MyPreviewMailInterceptor, MyOtherPreviewMailInterceptor], ActionMailer::Base.preview_interceptors
+ end
+
+ test "default preview interceptor can be removed" do
+ app_file 'config/initializers/preview_interceptors.rb', <<-RUBY
+ ActionMailer::Base.preview_interceptors.delete(ActionMailer::InlinePreviewInterceptor)
+ RUBY
+
+ require "#{app_path}/config/environment"
+ require "mail"
+
+ _ = ActionMailer::Base
+
+ assert_equal [], ActionMailer::Base.preview_interceptors
end
test "registers observers with ActionMailer" do
diff --git a/railties/test/application/mailer_previews_test.rb b/railties/test/application/mailer_previews_test.rb
index 3c9de0115f..e462d2c15e 100644
--- a/railties/test/application/mailer_previews_test.rb
+++ b/railties/test/application/mailer_previews_test.rb
@@ -487,7 +487,7 @@ module ApplicationTests
end
test "plain text mailer preview with attachment" do
- image_file "pixel.png", "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABAQMAAAAl21bKAAAAA1BMVEWzIioca_JlAAAACklEQVQI12NgAAAAAgAB4iG8MwAAAABJRU5ErkJgggo="
+ image_file "pixel.png", "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABAQMAAAAl21bKAAAAA1BMVEWzIioca/JlAAAACklEQVQI12NgAAAAAgAB4iG8MwAAAABJRU5ErkJgggo="
mailer 'notifier', <<-RUBY
class Notifier < ActionMailer::Base
@@ -524,7 +524,7 @@ module ApplicationTests
end
test "multipart mailer preview with attachment" do
- image_file "pixel.png", "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABAQMAAAAl21bKAAAAA1BMVEWzIioca_JlAAAACklEQVQI12NgAAAAAgAB4iG8MwAAAABJRU5ErkJgggo="
+ image_file "pixel.png", "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABAQMAAAAl21bKAAAAA1BMVEWzIioca/JlAAAACklEQVQI12NgAAAAAgAB4iG8MwAAAABJRU5ErkJgggo="
mailer 'notifier', <<-RUBY
class Notifier < ActionMailer::Base
@@ -569,7 +569,7 @@ module ApplicationTests
end
test "multipart mailer preview with inline attachment" do
- image_file "pixel.png", "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABAQMAAAAl21bKAAAAA1BMVEWzIioca_JlAAAACklEQVQI12NgAAAAAgAB4iG8MwAAAABJRU5ErkJgggo="
+ image_file "pixel.png", "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABAQMAAAAl21bKAAAAA1BMVEWzIioca/JlAAAACklEQVQI12NgAAAAAgAB4iG8MwAAAABJRU5ErkJgggo="
mailer 'notifier', <<-RUBY
class Notifier < ActionMailer::Base
@@ -612,7 +612,7 @@ module ApplicationTests
get "/rails/mailers/notifier/foo?part=text/html"
assert_equal 200, last_response.status
assert_match %r[<p>Hello, World!</p>], last_response.body
- assert_match %r[src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABAQMAAAAl21bKAAAAA1BMVEWzIioca_JlAAAACklEQVQI12NgAAAAAgAB4iG8MwAAAABJRU5ErkJgggo="], last_response.body
+ assert_match %r[src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABAQMAAAAl21bKAAAAA1BMVEWzIioca/JlAAAACklEQVQI12NgAAAAAgAB4iG8MwAAAABJRU5ErkJgggo="], last_response.body
end
test "multipart mailer preview with attached email" do
@@ -695,7 +695,7 @@ module ApplicationTests
end
def image_file(name, contents)
- app_file("public/images/#{name}", Base64.urlsafe_decode64(contents), 'wb')
+ app_file("public/images/#{name}", Base64.strict_decode64(contents), 'wb')
end
end
end