DOM manipulation.
Supports the following pseudo-classes: :first-child, :last-child, :only-child, :first-of-type, :last-of-type, :only-of-type, :empty, :root, :nth-child, :nth-of-type, :nth-last-child, :nth-last-of-type.
Functional pseudo-classes that take arguments (e.g. :nth-child) support
the An+B syntax.
Selector support limitations
Pseudo-classes that are not supported will never match and will emit a debug log.
Functional pseudo-classes that take arguments do not support the
of <complex-selector-list>clause; the entire expression is treated as invalid and the rule is ignored.The column combinator (
||) parses but never matches and emits a debug log.
Summary
Types
A selector item is a map that contains a :selector key.
Functions
Returns a list of HTML elements matching the selector.
Filters HTML elements matching the selector from the tree, collapsing redundant whitespace text nodes left behind.
Traverses HTML elements searching for needles and calls the provided function on each match.
Traverses HTML elements until the first match of a needle.
Extracts and concatenates the text content from HTML elements.
Traverses HTML elements, calling the provided function on each element matching one or more selector items and replacing it with the function's return value.
Types
@type needle() :: Premailex.html_element() | tag_name() | :comment
@type selector() :: String.t()
A selector item is a map that contains a :selector key.
Any additional keys attached by the caller are preserved during traversal
and returned as part of the matched selector items in the
traverse_with_matching_items/3 callback.
@type tag_name() :: String.t()
Functions
@spec all(Premailex.html_tree() | Premailex.html_element(), selector()) :: [ Premailex.html_element() ]
Returns a list of HTML elements matching the selector.
Examples
iex> Premailex.DOM.all([{"html", [], [{"head", [], []}, {"body", [], [{"h1", [], ["Title"]}]}]}], "h1")
[{"h1", [], ["Title"]}]
iex> Premailex.DOM.all({"div", [], [{"p", [], ["a"]}, {"p", [], ["b"]}]}, "p")
[{"p", [], ["a"]}, {"p", [], ["b"]}]
@spec reject(Premailex.html_tree() | Premailex.html_element(), selector()) :: Premailex.html_tree()
Filters HTML elements matching the selector from the tree, collapsing redundant whitespace text nodes left behind.
Always returns a Premailex.html_tree/0, even when a single element is
passed in; if that element matches the selector, the result is [].
Examples
iex> Premailex.DOM.reject([{"html", [], [{"head", [], []}, {"body", [], [{"h1", [], ["Title"]}]}]}], "h1")
[{"html", [], [{"head", [], []}, {"body", [], []}]}]
iex> Premailex.DOM.reject({"div", [], [{"p", [], ["a"]}, {"h1", [], ["b"]}]}, "h1")
[{"div", [], [{"p", [], ["a"]}]}]
iex> Premailex.DOM.reject({"h1", [], ["Title"]}, "h1")
[]
@spec replace_all_matches( Premailex.html_tree() | Premailex.html_element(), needle() | [needle()], (Premailex.html_node() -> Premailex.html_node()) ) :: Premailex.html_tree() | Premailex.html_element()
Traverses HTML elements searching for needles and calls the provided function on each match.
The elements are traversed depth-first, replacing each matching node with the function's return value.
Examples
iex> Premailex.DOM.replace_all_matches([{"div", [], [{"p", [], ["First paragraph"]}, {"p", [], ["Second paragraph"]}]}], "p", fn {name, attrs, _children} -> {name, attrs, ["Updated"]} end)
[{"div", [], [{"p", [], ["Updated"]}, {"p", [], ["Updated"]}]}]
iex> Premailex.DOM.replace_all_matches({"div", [], [{"p", [], ["First paragraph"]}, {"p", [], ["Second paragraph"]}]}, {"p", [], ["Second paragraph"]}, fn {name, attrs, _children} -> {name, attrs, ["Updated"]} end)
{"div", [], [{"p", [], ["First paragraph"]}, {"p", [], ["Updated"]}]}
iex> Premailex.DOM.replace_all_matches([{"div", [], [{:comment, "This is a comment"}, {"p", [], ["Paragraph"]}]}], :comment, fn {:comment, _comment} -> {:comment, "Updated"} end)
[{"div", [], [{:comment, "Updated"}, {"p", [], ["Paragraph"]}]}]
@spec replace_first_match( Premailex.html_tree() | Premailex.html_element(), needle(), (Premailex.html_node() -> Premailex.html_node()) ) :: Premailex.html_tree() | Premailex.html_element()
Traverses HTML elements until the first match of a needle.
The elements are traversed depth-first, and the first matching node is replaced with the function's return value.
Examples
iex> Premailex.DOM.replace_first_match([{"div", [], [{"p", [], ["First paragraph"]}, {"p", [], ["Second paragraph"]}]}], "p", fn {name, attrs, _children} -> {name, attrs, ["Updated"]} end)
[{"div", [], [{"p", [], ["Updated"]}, {"p", [], ["Second paragraph"]}]}]
@spec text_content(Premailex.html_tree() | Premailex.html_element()) :: String.t()
Extracts and concatenates the text content from HTML elements.
Examples
iex> Premailex.DOM.text_content([{"html", [], [{"head", [], []}, {"body", [], [{"h1", [], ["Title"]}]}]}])
"Title"
@spec traverse_with_matching_items( Premailex.html_tree() | Premailex.html_element(), [selector_item()], (Premailex.html_element(), [selector_item(), ...] -> Premailex.html_element()) ) :: Premailex.html_tree() | Premailex.html_element()
Traverses HTML elements, calling the provided function on each element matching one or more selector items and replacing it with the function's return value.
Examples
iex> Premailex.DOM.traverse_with_matching_items(
...> {"div", [], [{"p", [], ["Hi"]}]},
...> [%{selector: "p"}],
...> fn {tag, attrs, children}, _matched ->
...> {tag, [{"matched", ""} | attrs], children}
...> end)
{"div", [], [{"p", [{"matched", ""}], ["Hi"]}]}