From ad88c5995409070bb252cca5f0f818b695abd535 Mon Sep 17 00:00:00 2001 From: inoas Date: Sat, 3 Sep 2022 11:39:33 +0200 Subject: [PATCH 1/2] allow configuration of self-closing tags --- lib/floki/raw_html.ex | 31 ++++++++++++++++++----- test/floki_test.exs | 59 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 83 insertions(+), 7 deletions(-) diff --git a/lib/floki/raw_html.ex b/lib/floki/raw_html.ex index c21c9747..5129341a 100644 --- a/lib/floki/raw_html.ex +++ b/lib/floki/raw_html.ex @@ -1,7 +1,7 @@ defmodule Floki.RawHTML do @moduledoc false - @self_closing_tags [ + @default_self_closing_tags [ "area", "base", "br", @@ -13,6 +13,7 @@ defmodule Floki.RawHTML do "input", "keygen", "link", + "menuitem", "meta", "param", "source", @@ -20,6 +21,16 @@ defmodule Floki.RawHTML do "wbr" ] + def default_self_closing_tags(), do: @default_self_closing_tags + + def self_closing_tags do + custom_self_closing_tags = Application.get_env(:floki, :self_closing_tags) + + if is_list(custom_self_closing_tags), + do: custom_self_closing_tags, + else: @default_self_closing_tags + end + @encoder &HtmlEntities.encode/1 def raw_html(html_tree, options) do @@ -99,13 +110,19 @@ defmodule Floki.RawHTML do defp tag_with_attrs(type, attrs, children, padding), do: [leftpad(padding), "<", type, ?\s, tag_attrs(attrs) | close_open_tag(type, children)] - defp close_open_tag(type, []) when type in @self_closing_tags, do: "/>" - defp close_open_tag(_type, _), do: ">" - - defp close_end_tag(type, [], _padding) when type in @self_closing_tags, do: "" + defp close_open_tag(type, children) do + case {type in self_closing_tags(), children} do + {true, []} -> "/>" + _ -> ">" + end + end - defp close_end_tag(type, _, padding), - do: [leftpad(padding), "", line_ending(padding)] + defp close_end_tag(type, children, padding) do + case {type in self_closing_tags(), children} do + {true, []} -> "" + _ -> [leftpad(padding), "", line_ending(padding)] + end + end defp build_attrs({attr, value}), do: [attr, "=\"", html_escape(value) | "\""] defp build_attrs(attr), do: attr diff --git a/test/floki_test.exs b/test/floki_test.exs index c0c1c5a2..66f7c76a 100644 --- a/test/floki_test.exs +++ b/test/floki_test.exs @@ -250,6 +250,65 @@ defmodule FlokiTest do assert raw_html == "www.example.com" end + test "raw_html (with custom self closing tag without content and without attributes)" do + original_self_closing_tags = Application.get_env(:floki, :self_closing_tags) + Application.put_env(:floki, :self_closing_tags, ["shy"]) + + raw_html = Floki.raw_html({"shy", [], []}) + + assert raw_html == "" + + Application.put_env(:floki, :self_closing_tags, original_self_closing_tags) + end + + test "raw_html (with custom self closing tag without content)" do + original_self_closing_tags = Application.get_env(:floki, :self_closing_tags) + Application.put_env(:floki, :self_closing_tags, ["download"]) + + raw_html = Floki.raw_html({"download", [{"href", "//www.example.com/file.zip"}], []}) + + assert raw_html == "" + + Application.put_env(:floki, :self_closing_tags, original_self_closing_tags) + end + + test "raw_html (with custom self closing tag with content and with attribute)" do + original_self_closing_tags = Application.get_env(:floki, :self_closing_tags) + Application.put_env(:floki, :self_closing_tags, ["download"]) + + raw_html = + Floki.raw_html( + {"download", [{"href", "//www.example.com/file.zip"}], ["Download file.zip"]} + ) + + assert raw_html == + "Download file.zip" + + Application.put_env(:floki, :self_closing_tags, original_self_closing_tags) + end + + test "raw_html (with custom self closing tag with content and without attribute)" do + original_self_closing_tags = Application.get_env(:floki, :self_closing_tags) + Application.put_env(:floki, :self_closing_tags, ["strike"]) + + raw_html = Floki.raw_html({"strike", [], ["stroke text"]}) + + assert raw_html == "stroke text" + + Application.put_env(:floki, :self_closing_tags, original_self_closing_tags) + end + + test "raw_html (with default self closing tag that isn't set while custom self closing tags are set must fail)" do + original_self_closing_tags = Application.get_env(:floki, :self_closing_tags) + Application.put_env(:floki, :self_closing_tags, ["page"]) + + raw_html = Floki.raw_html({"br", [], []}) + + assert raw_html != "
" + + Application.put_env(:floki, :self_closing_tags, original_self_closing_tags) + end + test "raw_html (with script and style tags)" do tree = { "body", From 71790fec65c4222968fc0666017802e11a126534 Mon Sep 17 00:00:00 2001 From: Philip Sampaio Date: Tue, 6 Sep 2022 21:44:30 +0100 Subject: [PATCH 2/2] Update lib/floki/raw_html.ex --- lib/floki/raw_html.ex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/floki/raw_html.ex b/lib/floki/raw_html.ex index 5129341a..0e553141 100644 --- a/lib/floki/raw_html.ex +++ b/lib/floki/raw_html.ex @@ -119,7 +119,7 @@ defmodule Floki.RawHTML do defp close_end_tag(type, children, padding) do case {type in self_closing_tags(), children} do - {true, []} -> "" + {true, []} -> [] _ -> [leftpad(padding), "", line_ending(padding)] end end