diff --git a/actionpack/CHANGELOG.md b/actionpack/CHANGELOG.md
index d213ab057cce5bef31a938796c273a96cfe6b604..0228038b1b84e1ad85129b81f9effe5adcee5df4 100644
--- a/actionpack/CHANGELOG.md
+++ b/actionpack/CHANGELOG.md
@@ -4,6 +4,11 @@
*Vasiliy Ermolovich*
+* Extract support for email address obfuscation via `:encode`, `:replace_at`, and `replace_dot` options
+ from the `mail_to` helper into the `actionview-encoded_mail_to` gem.
+
+ *Nick Reed + DHH*
+
* Clear url helper methods when routes are reloaded. *Andrew White*
* Fix a bug in `ActionDispatch::Request#raw_post` that caused `env['rack.input']`
diff --git a/actionpack/lib/action_view/helpers/url_helper.rb b/actionpack/lib/action_view/helpers/url_helper.rb
index fa516cf91bc6a01268f59c9c0e5ad1a5fb66f692..aeee66207194b09285085735492f05eb81244492 100644
--- a/actionpack/lib/action_view/helpers/url_helper.rb
+++ b/actionpack/lib/action_view/helpers/url_helper.rb
@@ -415,40 +415,26 @@ def link_to_if(condition, name, options = {}, html_options = {}, &block)
# also used as the name of the link unless +name+ is specified. Additional
# HTML attributes for the link can be passed in +html_options+.
#
- # +mail_to+ has several methods for hindering email harvesters and customizing
- # the email itself by passing special keys to +html_options+.
+ # +mail_to+ has several methods for customizing the email itself by
+ # passing special keys to +html_options+.
#
# ==== Options
- # * :encode - This key will accept the strings "javascript" or "hex".
- # Passing "javascript" will dynamically create and encode the mailto link then
- # eval it into the DOM of the page. This method will not show the link on
- # the page if the user has JavaScript disabled. Passing "hex" will hex
- # encode the +email_address+ before outputting the mailto link.
- # * :replace_at - When the link +name+ isn't provided, the
- # +email_address+ is used for the link label. You can use this option to
- # obfuscate the +email_address+ by substituting the @ sign with the string
- # given as the value.
- # * :replace_dot - When the link +name+ isn't provided, the
- # +email_address+ is used for the link label. You can use this option to
- # obfuscate the +email_address+ by substituting the . in the email with the
- # string given as the value.
# * :subject - Preset the subject line of the email.
# * :body - Preset the body of the email.
# * :cc - Carbon Copy additional recipients on the email.
# * :bcc - Blind Carbon Copy additional recipients on the email.
#
+ # ==== Obfuscation
+ # Prior to Rails 4.0, +mail_to+ provided options for encoding the address
+ # in order to hinder email harvesters. To take advantage of these options,
+ # install the +actionview-encoded_mail_to+ gem.
+ #
# ==== Examples
# mail_to "me@domain.com"
# # => me@domain.com
#
- # mail_to "me@domain.com", "My email", encode: "javascript"
- # # =>
- #
- # mail_to "me@domain.com", "My email", encode: "hex"
- # # => My email
- #
- # mail_to "me@domain.com", nil, replace_at: "_at_", replace_dot: "_dot_", class: "email"
- # # => me_at_domain_dot_com
+ # mail_to "me@domain.com", "My email"
+ # # => My email
#
# mail_to "me@domain.com", "My email", cc: "ccaddress@domain.com",
# subject: "This is an example email"
@@ -456,43 +442,15 @@ def link_to_if(condition, name, options = {}, html_options = {}, &block)
def mail_to(email_address, name = nil, html_options = {})
email_address = ERB::Util.html_escape(email_address)
- html_options = html_options.stringify_keys
- encode = html_options.delete("encode").to_s
+ html_options.stringify_keys!
extras = %w{ cc bcc body subject }.map { |item|
option = html_options.delete(item) || next
"#{item}=#{Rack::Utils.escape_path(option)}"
}.compact
extras = extras.empty? ? '' : '?' + ERB::Util.html_escape(extras.join('&'))
-
- email_address_obfuscated = email_address.to_str
- email_address_obfuscated.gsub!(/@/, html_options.delete("replace_at")) if html_options.key?("replace_at")
- email_address_obfuscated.gsub!(/\./, html_options.delete("replace_dot")) if html_options.key?("replace_dot")
- case encode
- when "javascript"
- string = ''
- html = content_tag("a", name || email_address_obfuscated.html_safe, html_options.merge("href" => "mailto:#{email_address}#{extras}".html_safe))
- html = escape_javascript(html.to_str)
- "document.write('#{html}');".each_byte do |c|
- string << sprintf("%%%x", c)
- end
- "".html_safe
- when "hex"
- email_address_encoded = email_address_obfuscated.unpack('C*').map {|c|
- sprintf("%d;", c)
- }.join
-
- string = 'mailto:'.unpack('C*').map { |c|
- sprintf("%d;", c)
- }.join + email_address.unpack('C*').map { |c|
- char = c.chr
- char =~ /\w/ ? sprintf("%%%x", c) : char
- }.join
-
- content_tag "a", name || email_address_encoded.html_safe, html_options.merge("href" => "#{string}#{extras}".html_safe)
- else
- content_tag "a", name || email_address_obfuscated.html_safe, html_options.merge("href" => "mailto:#{email_address}#{extras}".html_safe)
- end
+
+ content_tag "a", name || email_address.html_safe, html_options.merge("href" => "mailto:#{email_address}#{extras}".html_safe)
end
# True if the current request URI was generated by the given +options+.
diff --git a/actionpack/test/template/url_helper_test.rb b/actionpack/test/template/url_helper_test.rb
index 1bb625213dbdcac9e29e0c4a8cb6110039dd851a..ba65349b6ac0105c555779fe7976fb5a1846a6e4 100644
--- a/actionpack/test/template/url_helper_test.rb
+++ b/actionpack/test/template/url_helper_test.rb
@@ -517,16 +517,6 @@ def test_mail_to
mail_to("david@loudthinking.com", "David Heinemeier Hansson", class: "admin")
end
- def test_mail_to_with_javascript
- snippet = mail_to("me@domain.com", "My email", encode: "javascript")
- assert_dom_equal "", snippet
- end
-
- def test_mail_to_with_javascript_unicode
- snippet = mail_to("unicode@example.com", "Ășnicode", encode: "javascript")
- assert_dom_equal "", snippet
- end
-
def test_mail_with_options
assert_dom_equal(
%{My email},
@@ -539,54 +529,8 @@ def test_mail_to_with_img
mail_to('feedback@example.com', ''.html_safe)
end
- def test_mail_to_with_hex
- assert_dom_equal(
- %{My email},
- mail_to("me@domain.com", "My email", encode: "hex")
- )
-
- assert_dom_equal(
- %{me@domain.com},
- mail_to("me@domain.com", nil, encode: "hex")
- )
- end
-
- def test_mail_to_with_replace_options
- assert_dom_equal(
- %{wolfgang(at)stufenlos(dot)net},
- mail_to("wolfgang@stufenlos.net", nil, replace_at: "(at)", replace_dot: "(dot)")
- )
-
- assert_dom_equal(
- %{me(at)domain.com},
- mail_to("me@domain.com", nil, encode: "hex", replace_at: "(at)")
- )
-
- assert_dom_equal(
- %{My email},
- mail_to("me@domain.com", "My email", encode: "hex", replace_at: "(at)")
- )
-
- assert_dom_equal(
- %{me(at)domain(dot)com},
- mail_to("me@domain.com", nil, encode: "hex", replace_at: "(at)", replace_dot: "(dot)")
- )
-
- assert_dom_equal(
- %{},
- mail_to("me@domain.com", "My email", encode: "javascript", replace_at: "(at)", replace_dot: "(dot)")
- )
-
- assert_dom_equal(
- %{},
- mail_to("me@domain.com", nil, encode: "javascript", replace_at: "(at)", replace_dot: "(dot)")
- )
- end
-
def test_mail_to_returns_html_safe_string
assert mail_to("david@loudthinking.com").html_safe?
- assert mail_to("me@domain.com", "My email", encode: "javascript").html_safe?
- assert mail_to("me@domain.com", "My email", encode: "hex").html_safe?
end
def protect_against_forgery?