Farol.Node (Farol v0.2.0)

Copy Markdown View Source

The normalized element every rule sees.

Adapters (HTML today, HEEx tomorrow) parse their input into this struct so rules are written once and run against any source. A node is an element: a tag name, its attributes, and its children. Text content stays as plain binaries inside children, so nothing from the original document is lost.

The struct mirrors the classic {tag, attributes, children} HTML tree triple, with attributes as a map for cheap lookups.

Static sources (HEEx templates) also carry line/column of the opening tag, and mark attributes written as Elixir expressions (alt={@alt}) in dynamic_attrs: the attr map holds the expression source for those, and rules treat them as "present but unknowable" rather than as literal text.

Summary

Functions

Returns the value of an attribute, or nil when absent.

All attribute names starting with a prefix (think aria-, phx-).

True when the attribute was written as an Elixir expression in a template (role={@role}). The value in attrs is the expression source; rules that compare against a fixed vocabulary must skip dynamic values instead of flagging them.

All elements in document order matching pred.

Flattens a forest into a list of elements in document order. Text binaries are dropped; only %Farol.Node{} elements remain.

Builds a node from a LazyHTML.Tree tuple, keeping text children as binaries. Comments, doctypes and other non-element entries become nil so callers can reject them.

True when the attribute exists, even with an empty value (<img alt="">).

A short rendering of the opening tag, for finding messages. Truncated so a wall of attributes never floods the report.

All text inside the node, recursively, concatenated.

Types

t()

@type t() :: %Farol.Node{
  attrs: %{required(String.t()) => String.t()},
  children: [t() | String.t()],
  column: pos_integer() | nil,
  dynamic_attrs: [String.t()],
  line: pos_integer() | nil,
  tag: String.t()
}

Functions

attr(node, name)

Returns the value of an attribute, or nil when absent.

attrs_with_prefix(node, prefix)

All attribute names starting with a prefix (think aria-, phx-).

dynamic?(node, name)

True when the attribute was written as an Elixir expression in a template (role={@role}). The value in attrs is the expression source; rules that compare against a fixed vocabulary must skip dynamic values instead of flagging them.

find(nodes, pred)

All elements in document order matching pred.

flatten(nodes)

Flattens a forest into a list of elements in document order. Text binaries are dropped; only %Farol.Node{} elements remain.

from_tree(text)

Builds a node from a LazyHTML.Tree tuple, keeping text children as binaries. Comments, doctypes and other non-element entries become nil so callers can reject them.

has_attr?(node, name)

True when the attribute exists, even with an empty value (<img alt="">).

snippet(node)

A short rendering of the opening tag, for finding messages. Truncated so a wall of attributes never floods the report.

text(node)

All text inside the node, recursively, concatenated.