Packages

A simplicity-first web framework for Elixir, designed to make building web applications easy and enjoyable.

Current section

Files

Jump to
tamnoon lib DOM node.ex
Raw

lib/DOM/node.ex

defmodule Tamnoon.DOM.Node do
@moduledoc """
Represents a DOM node. Accepts two parameters for how to select the node,
`:selector_type` and `:selector_value`. For example, when `:selector_type` is `:id` and
`:selector_value` is `"id-to-select"`, it will be equivalent to using
`document.getElementById("id-to-select")` in JS.
`:selector_type` can be set as `:iteration_placeholder`, which is a special value intended for use
with `m:Tamnoon.DOM.Actions.ForEach`, and will represent the argument that will be each node
of the collection.
## Fields
* `:selector_type` – an atom indicating the type of selector.
- Expected values: `:id`, `:xpath`, `:from_string`, `:first_element`, `:last_element`, `:iteration_placeholder`.
* `:selector_value` – the value associated with the selector.
- `:id`: a `t:String.t/0` of the id to select.
- `:xpath`: a `t:String.t/0` of the node's xpath.
- `:from_string`: a `t:String.t/0` representing the HTML element.
- `:first_element` and `:last_element`: a `t:Tamnoon.DOM.NodeCollection.t/0` representing the collection to query.
- `:iteration_placeholder`: `nil`.
"""
alias Tamnoon.DOM
import DOM
use DOM.JsonEncoder, type: :node
@enforce_keys [:selector_type, :selector_value]
defstruct [:selector_type, :selector_value]
@placeholder_selector_types [:iteration_placeholder]
@single_selector_types [:id, :xpath, :from_string]
@collection_selector_types [:first_element, :last_element]
@type t :: %__MODULE__{
selector_type: :id | :xpath | :from_string | :first_element | :last_element | :iteration_placeholder,
selector_value: String.t() | DOM.NodeCollection.t() | nil
}
@spec is_node?(node :: any()) :: boolean()
def is_node?(node)
def is_node?(%DOM.Node{}), do: true
def is_node?(%{selector_type: type, selector_value: value})
when type in @placeholder_selector_types and is_nil(value),
do: true
def is_node?(%{selector_type: type, selector_value: value})
when type in @single_selector_types and is_binary(value),
do: true
def is_node?(%{selector_type: type, selector_value: value})
when type in @collection_selector_types and is_struct(value, DOM.NodeCollection),
do: true
def is_node?(_), do: false
@spec new!(node :: term()) :: %DOM.Node{}
def new!(%DOM.Node{} = node), do: node
def new!(node) do
validate_type!(node, &is_node?/1, DOM.Node)
struct(DOM.Node, node)
end
end