Skip to content

Commit

Permalink
Updated html5 option
Browse files Browse the repository at this point in the history
  • Loading branch information
ankane committed Nov 11, 2024
1 parent 75c07ad commit 1b1a6cc
Show file tree
Hide file tree
Showing 6 changed files with 22 additions and 19 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
## 2.4.0 (unreleased)

- Added `html5` option
- Improved generator for Active Record encryption and MySQL
- Removed support for Ruby < 3.1 and Rails < 7
- Removed support for Mongoid < 8
Expand Down
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -324,11 +324,11 @@ Get stats for a campaign
AhoyEmail.stats("my-campaign")
```

## HTML5 Parsing
## HTML Parsing

By default, this gem uses Nokogiri's HTML 4 parser to rewrite href attributes for the `utm_params` and `track_clicks` features. This can cause link tags to be prematurely closed if they were wrapping table elements, because doing so violates the HTML 4 spec.
By default, this gem uses Nokogiri’s default HTML parser to rewrite `href` attributes for UTM tagging and click analytics. This can cause link tags to be prematurely closed if they wrap `table` elements, because doing so violates the HTML 4 spec.

To use HTML5 parsing instead, set this in an initializer:
To use HTML5 parsing, create `config/initializers/ahoy_email.rb` with:

```ruby
AhoyEmail.html5 = true
Expand Down
2 changes: 1 addition & 1 deletion lib/ahoy_email.rb
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ module AhoyEmail

self.save_token = false

self.html5 = false
self.html5 = nil

self.subscribers = []

Expand Down
13 changes: 8 additions & 5 deletions lib/ahoy_email/processor.rb
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ def track_links
if html_part?
part = message.html_part || message

doc = parse_message(part.body.raw_source)
doc = parser_class.parse(part.body.raw_source)
doc.css("a[href]").each do |link|
uri = parse_uri(link["href"])
next unless trackable?(uri)
Expand Down Expand Up @@ -92,11 +92,14 @@ def track_links
end
end

def parse_message(raw_source)
if AhoyEmail.html5
Nokogiri::HTML5.parse(raw_source)
def parser_class
case AhoyEmail.html5
when true
Nokogiri::HTML5
when false
Nokogiri::HTML4
else
Nokogiri::HTML::Document.parse(raw_source)
Nokogiri::HTML::Document
end
end

Expand Down
4 changes: 2 additions & 2 deletions test/test_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -86,8 +86,8 @@ def with_save_token
end
end

def with_html5
AhoyEmail.stub(:html5, true) do
def with_html5(html5)
AhoyEmail.stub(:html5, html5) do
yield
end
end
Expand Down
15 changes: 7 additions & 8 deletions test/utm_params_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -30,21 +30,20 @@ def test_nested
assert_body '<img src="image.png"></a>', message
end

# When nokogiri parses with html5, it allows an <a> tag to wrap a <table> tag
def test_nested_table_html5
with_html5 do
with_html5(true) do
message = UtmParamsMailer.nested_table.deliver_now
assert_body "utm_medium=email", message
assert_body '<table></table></a>', message
assert_body "<table></table></a>", message
end
end

# When nokogiri parses with html4, it disallows an <a> tag to wrap a <table> tag,
# and closes the <a> tag before the <table> tag
def test_nested_table_html4
message = UtmParamsMailer.nested_table.deliver_now
assert_body "utm_medium=email", message
assert_body '</a><table></table>', message
with_html5(false) do
message = UtmParamsMailer.nested_table.deliver_now
assert_body "utm_medium=email", message
assert_body "</a><table></table>", message
end
end

def test_multiple
Expand Down

0 comments on commit 1b1a6cc

Please sign in to comment.