From e24e3cd8fe5969ab1e61820fe57e683018c1ac9b Mon Sep 17 00:00:00 2001 From: Yuri Pereira Constante Date: Sat, 30 Dec 2023 13:18:29 -0300 Subject: [PATCH 1/3] Call self_closing_tags only once on raw_html --- lib/floki/raw_html.ex | 100 ++++++++++++++++++++++++++++-------------- 1 file changed, 67 insertions(+), 33 deletions(-) diff --git a/lib/floki/raw_html.ex b/lib/floki/raw_html.ex index e40007a5..beaba76a 100644 --- a/lib/floki/raw_html.ex +++ b/lib/floki/raw_html.ex @@ -47,35 +47,59 @@ defmodule Floki.RawHTML do _ -> :noop end - IO.iodata_to_binary(build_raw_html(html_tree, [], encoder, padding)) + self_closing_tags = self_closing_tags() + + IO.iodata_to_binary(build_raw_html(html_tree, [], encoder, padding, self_closing_tags)) end - defp build_raw_html([], html, _encoder, _padding), do: html + defp build_raw_html([], html, _encoder, _padding, _self_closing_tags), do: html - defp build_raw_html(string, _html, encoder, padding) when is_binary(string) do + defp build_raw_html(string, _html, encoder, padding, _self_closing_tags) + when is_binary(string) do leftpad_content(padding, encoder.(string)) end - defp build_raw_html(tuple, html, encoder, padding) when is_tuple(tuple), - do: build_raw_html([tuple], html, encoder, padding) + defp build_raw_html(tuple, html, encoder, padding, self_closing_tags) when is_tuple(tuple), + do: build_raw_html([tuple], html, encoder, padding, self_closing_tags) - defp build_raw_html([string | tail], html, encoder, padding) when is_binary(string) do - build_raw_html(tail, [html, leftpad_content(padding, encoder.(string))], encoder, padding) + defp build_raw_html([string | tail], html, encoder, padding, self_closing_tags) + when is_binary(string) do + build_raw_html( + tail, + [html, leftpad_content(padding, encoder.(string))], + encoder, + padding, + self_closing_tags + ) end - defp build_raw_html([{:comment, comment} | tail], html, encoder, padding), - do: build_raw_html(tail, [html, leftpad(padding), ""], encoder, padding) - - defp build_raw_html([{:pi, tag, attrs} | tail], html, encoder, padding) do + defp build_raw_html([{:comment, comment} | tail], html, encoder, padding, self_closing_tags), + do: + build_raw_html( + tail, + [html, leftpad(padding), ""], + encoder, + padding, + self_closing_tags + ) + + defp build_raw_html([{:pi, tag, attrs} | tail], html, encoder, padding, self_closing_tags) do build_raw_html( tail, [html, leftpad(padding), ""], encoder, - padding + padding, + self_closing_tags ) end - defp build_raw_html([{:doctype, type, public, system} | tail], html, encoder, padding) do + defp build_raw_html( + [{:doctype, type, public, system} | tail], + html, + encoder, + padding, + self_closing_tags + ) do attr = case {public, system} do {"", ""} -> [] @@ -87,16 +111,18 @@ defmodule Floki.RawHTML do tail, [html, leftpad(padding), ""], encoder, - padding + padding, + self_closing_tags ) end - defp build_raw_html([{type, attrs, children} | tail], html, encoder, padding) do + defp build_raw_html([{type, attrs, children} | tail], html, encoder, padding, self_closing_tags) do build_raw_html( tail, - [html | tag_for(type, attrs, children, encoder, padding)], + [html | tag_for(type, attrs, children, encoder, padding, self_closing_tags)], encoder, - padding + padding, + self_closing_tags ) end @@ -104,39 +130,47 @@ defmodule Floki.RawHTML do map_intersperse(attr_list, ?\s, &build_attrs(&1, encoder)) end - defp tag_with_attrs(type, [], children, padding, _encoder), - do: [leftpad(padding), "<", type | close_open_tag(type, children)] + defp tag_with_attrs(type, [], children, padding, _encoder, self_closing_tags), + do: [leftpad(padding), "<", type | close_open_tag(type, children, self_closing_tags)] - defp tag_with_attrs(type, attrs, children, padding, encoder), + defp tag_with_attrs(type, attrs, children, padding, encoder, self_closing_tags), do: [ leftpad(padding), "<", type, ?\s, - tag_attrs(attrs, encoder) | close_open_tag(type, children) + tag_attrs(attrs, encoder) | close_open_tag(type, children, self_closing_tags) ] - defp close_open_tag(type, children) do - case {type in self_closing_tags(), children} do - {true, []} -> "/>" - _ -> ">" + defp close_open_tag(type, [], self_closing_tags) do + if type in self_closing_tags do + "/>" + else + ">" end end - defp close_end_tag(type, children, padding) do - case {type in self_closing_tags(), children} do - {true, []} -> [] - _ -> [leftpad(padding), "", line_ending(padding)] + defp close_open_tag(_type, _children, _self_closing_tags), do: ">" + + defp close_end_tag(type, [], padding, self_closing_tags) do + if type in self_closing_tags do + [] + else + [leftpad(padding), "", line_ending(padding)] end end + defp close_end_tag(type, _children, padding, _self_closing_tags) do + [leftpad(padding), "", line_ending(padding)] + end + defp build_attrs({attr, value}, encoder) do [attr, "=\"", encoder.(value) | "\""] end defp build_attrs(attr, _encoder), do: attr - defp tag_for(type, attrs, children, encoder, padding) do + defp tag_for(type, attrs, children, encoder, padding, self_closing_tags) do encoder = case type do "script" -> & &1 @@ -145,10 +179,10 @@ defmodule Floki.RawHTML do end [ - tag_with_attrs(type, attrs, children, padding, encoder), + tag_with_attrs(type, attrs, children, padding, encoder, self_closing_tags), line_ending(padding), - build_raw_html(children, "", encoder, pad_increase(padding)), - close_end_tag(type, children, padding) + build_raw_html(children, "", encoder, pad_increase(padding), self_closing_tags), + close_end_tag(type, children, padding, self_closing_tags) ] end From 5339fa3708aa72cd9231be3ced7a6a8be62b2d6f Mon Sep 17 00:00:00 2001 From: Yuri Pereira Constante Date: Sat, 30 Dec 2023 13:19:25 -0300 Subject: [PATCH 2/3] Use MapSet for self_closing_tags --- lib/floki/raw_html.ex | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/floki/raw_html.ex b/lib/floki/raw_html.ex index beaba76a..56b74636 100644 --- a/lib/floki/raw_html.ex +++ b/lib/floki/raw_html.ex @@ -47,7 +47,7 @@ defmodule Floki.RawHTML do _ -> :noop end - self_closing_tags = self_closing_tags() + self_closing_tags = MapSet.new(self_closing_tags()) IO.iodata_to_binary(build_raw_html(html_tree, [], encoder, padding, self_closing_tags)) end @@ -143,7 +143,7 @@ defmodule Floki.RawHTML do ] defp close_open_tag(type, [], self_closing_tags) do - if type in self_closing_tags do + if MapSet.member?(self_closing_tags, type) do "/>" else ">" @@ -153,7 +153,7 @@ defmodule Floki.RawHTML do defp close_open_tag(_type, _children, _self_closing_tags), do: ">" defp close_end_tag(type, [], padding, self_closing_tags) do - if type in self_closing_tags do + if MapSet.member?(self_closing_tags, type) do [] else [leftpad(padding), "", line_ending(padding)] From 4d53e0f6e5f646e10a7d58d633015bd002338839 Mon Sep 17 00:00:00 2001 From: Yuri Pereira Constante Date: Thu, 4 Jan 2024 10:56:27 -0300 Subject: [PATCH 3/3] Revert "Use MapSet for self_closing_tags" This reverts commit 5339fa3708aa72cd9231be3ced7a6a8be62b2d6f. --- lib/floki/raw_html.ex | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/floki/raw_html.ex b/lib/floki/raw_html.ex index 56b74636..beaba76a 100644 --- a/lib/floki/raw_html.ex +++ b/lib/floki/raw_html.ex @@ -47,7 +47,7 @@ defmodule Floki.RawHTML do _ -> :noop end - self_closing_tags = MapSet.new(self_closing_tags()) + self_closing_tags = self_closing_tags() IO.iodata_to_binary(build_raw_html(html_tree, [], encoder, padding, self_closing_tags)) end @@ -143,7 +143,7 @@ defmodule Floki.RawHTML do ] defp close_open_tag(type, [], self_closing_tags) do - if MapSet.member?(self_closing_tags, type) do + if type in self_closing_tags do "/>" else ">" @@ -153,7 +153,7 @@ defmodule Floki.RawHTML do defp close_open_tag(_type, _children, _self_closing_tags), do: ">" defp close_end_tag(type, [], padding, self_closing_tags) do - if MapSet.member?(self_closing_tags, type) do + if type in self_closing_tags do [] else [leftpad(padding), "", line_ending(padding)]