Skip to content

Commit 8fbf05f

Browse files
committed
Use accumulator on raw_html
1 parent 7e50f15 commit 8fbf05f

File tree

1 file changed

+51
-73
lines changed

1 file changed

+51
-73
lines changed

lib/floki/raw_html.ex

+51-73
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ defmodule Floki.RawHTML do
3636

3737
def raw_html(html_tree, opts) do
3838
opts = Keyword.validate!(opts, encode: use_default_encoder?(), pretty: false)
39+
html_tree = List.wrap(html_tree)
3940

4041
encoder =
4142
case opts[:encode] do
@@ -51,53 +52,36 @@ defmodule Floki.RawHTML do
5152

5253
self_closing_tags = self_closing_tags()
5354

54-
IO.iodata_to_binary(build_raw_html(html_tree, [], encoder, padding, self_closing_tags))
55+
html_tree
56+
|> build_raw_html([], encoder, padding, self_closing_tags)
57+
|> Enum.reverse()
58+
|> IO.iodata_to_binary()
5559
end
5660

57-
defp build_raw_html([], html, _encoder, _padding, _self_closing_tags), do: html
61+
defp build_raw_html([], acc, _encoder, _padding, _self_closing_tags), do: acc
5862

59-
defp build_raw_html(string, _html, encoder, padding, _self_closing_tags)
63+
defp build_raw_html([string | tail], acc, encoder, padding, self_closing_tags)
6064
when is_binary(string) do
61-
leftpad_content(padding, encoder.(string))
65+
content = leftpad_content(padding, encoder.(string))
66+
acc = [content | acc]
67+
build_raw_html(tail, acc, encoder, padding, self_closing_tags)
6268
end
6369

64-
defp build_raw_html(tuple, html, encoder, padding, self_closing_tags) when is_tuple(tuple),
65-
do: build_raw_html([tuple], html, encoder, padding, self_closing_tags)
66-
67-
defp build_raw_html([string | tail], html, encoder, padding, self_closing_tags)
68-
when is_binary(string) do
69-
build_raw_html(
70-
tail,
71-
[html, leftpad_content(padding, encoder.(string))],
72-
encoder,
73-
padding,
74-
self_closing_tags
75-
)
70+
defp build_raw_html([{:comment, comment} | tail], acc, encoder, padding, self_closing_tags) do
71+
content = [leftpad(padding), "<!--", comment, "-->"]
72+
acc = [content | acc]
73+
build_raw_html(tail, acc, encoder, padding, self_closing_tags)
7674
end
7775

78-
defp build_raw_html([{:comment, comment} | tail], html, encoder, padding, self_closing_tags),
79-
do:
80-
build_raw_html(
81-
tail,
82-
[html, leftpad(padding), "<!--", comment, "-->"],
83-
encoder,
84-
padding,
85-
self_closing_tags
86-
)
87-
88-
defp build_raw_html([{:pi, tag, attrs} | tail], html, encoder, padding, self_closing_tags) do
89-
build_raw_html(
90-
tail,
91-
[html, leftpad(padding), "<?", tag, tag_attrs(attrs, encoder), "?>"],
92-
encoder,
93-
padding,
94-
self_closing_tags
95-
)
76+
defp build_raw_html([{:pi, tag, attrs} | tail], acc, encoder, padding, self_closing_tags) do
77+
content = [leftpad(padding), "<?", tag, tag_attrs(attrs, encoder), "?>"]
78+
acc = [content | acc]
79+
build_raw_html(tail, acc, encoder, padding, self_closing_tags)
9680
end
9781

9882
defp build_raw_html(
9983
[{:doctype, type, public, system} | tail],
100-
html,
84+
acc,
10185
encoder,
10286
padding,
10387
self_closing_tags
@@ -109,23 +93,40 @@ defmodule Floki.RawHTML do
10993
{public, system} -> [" PUBLIC \"", public, "\" \"", system | "\""]
11094
end
11195

112-
build_raw_html(
113-
tail,
114-
[html, leftpad(padding), "<!DOCTYPE ", type, attr | ">"],
115-
encoder,
116-
padding,
117-
self_closing_tags
118-
)
96+
content = [leftpad(padding), "<!DOCTYPE ", type, attr | ">"]
97+
acc = [content | acc]
98+
build_raw_html(tail, acc, encoder, padding, self_closing_tags)
11999
end
120100

121-
defp build_raw_html([{type, attrs, children} | tail], html, encoder, padding, self_closing_tags) do
122-
build_raw_html(
123-
tail,
124-
[html | tag_for(type, attrs, children, encoder, padding, self_closing_tags)],
125-
encoder,
126-
padding,
127-
self_closing_tags
128-
)
101+
defp build_raw_html([{type, attrs, children} | tail], acc, encoder, padding, self_closing_tags) do
102+
encoder =
103+
case type do
104+
"script" -> @no_encoder
105+
"style" -> @no_encoder
106+
"title" -> @no_encoder
107+
_ -> encoder
108+
end
109+
110+
open_tag_content = [
111+
tag_with_attrs(type, attrs, children, padding, encoder, self_closing_tags),
112+
line_ending(padding)
113+
]
114+
115+
acc = [open_tag_content | acc]
116+
117+
acc =
118+
case children do
119+
[] ->
120+
acc
121+
122+
_ ->
123+
children = List.wrap(children)
124+
build_raw_html(children, acc, encoder, pad_increase(padding), self_closing_tags)
125+
end
126+
127+
close_tag_content = close_end_tag(type, children, padding, self_closing_tags)
128+
acc = [close_tag_content | acc]
129+
build_raw_html(tail, acc, encoder, padding, self_closing_tags)
129130
end
130131

131132
defp tag_attrs(attr_list, encoder) do
@@ -171,29 +172,6 @@ defmodule Floki.RawHTML do
171172

172173
defp build_attrs(attr, _encoder), do: [?\s, attr]
173174

174-
defp tag_for(type, attrs, children, encoder, padding, self_closing_tags) do
175-
encoder =
176-
case type do
177-
"script" -> @no_encoder
178-
"style" -> @no_encoder
179-
"title" -> @no_encoder
180-
_ -> encoder
181-
end
182-
183-
children_content =
184-
case children do
185-
[] -> ""
186-
_ -> build_raw_html(children, "", encoder, pad_increase(padding), self_closing_tags)
187-
end
188-
189-
[
190-
tag_with_attrs(type, attrs, children, padding, encoder, self_closing_tags),
191-
line_ending(padding),
192-
children_content,
193-
close_end_tag(type, children, padding, self_closing_tags)
194-
]
195-
end
196-
197175
defp use_default_encoder? do
198176
Application.get_env(:floki, :encode_raw_html, true)
199177
end

0 commit comments

Comments
 (0)