PhoenixTestDatastar.Actions (PhoenixTestDatastar v0.0.2)

Copy Markdown

Parses Datastar action expressions from HTML element attributes.

Datastar actions appear in attributes like data-on:click, data-on:submit, data-on:change, and data-init. They specify HTTP requests to make when events occur.

Examples

iex> PhoenixTestDatastar.Actions.parse("@post('/ds/counter/increment')")
{:ok, [%{method: :post, url: "/ds/counter/increment", raw_url: "'/ds/counter/increment'"}]}

iex> PhoenixTestDatastar.Actions.parse("@get('/ds/items/load')")
{:ok, [%{method: :get, url: "/ds/items/load", raw_url: "'/ds/items/load'"}]}

Summary

Functions

Find a Datastar action expression in HTML for a given selector.

Find all data-init attributes in HTML that contain @post/@get actions.

Parse an action expression string into a list of actions.

Parse a single action expression.

Resolve dynamic URL expressions by replacing $signal references with values.

Types

action()

@type action() :: %{
  method: :get | :post | :put | :patch | :delete,
  url: String.t(),
  raw_url: String.t()
}

Functions

find_action(raw_html, selector)

@spec find_action(String.t(), String.t()) :: {:ok, String.t()} | :none

Find a Datastar action expression in HTML for a given selector.

Checks attributes in order: data-on:click, data-on:submit, data-on:change. Returns the raw expression string or :none if no action is found.

Examples

iex> html = ~s[<button data-on:click="@post('/increment')">Click</button>]
iex> PhoenixTestDatastar.Actions.find_action(html, "button")
{:ok, "@post('/increment')"}

iex> html = ~s[<div class="no-action">Content</div>]
iex> PhoenixTestDatastar.Actions.find_action(html, "div")
:none

find_init_actions(raw_html)

@spec find_init_actions(String.t()) :: [{String.t(), String.t()}]

Find all data-init attributes in HTML that contain @post/@get actions.

Returns a list of {selector_or_id, expression} tuples.

Examples

iex> html = ~s[<div id="counter" data-init="@get('/load')">Content</div>]
iex> PhoenixTestDatastar.Actions.find_init_actions(html)
[{"#counter", "@get('/load')"}]

parse(expression)

@spec parse(String.t()) :: {:ok, [action()]} | {:error, term()}

Parse an action expression string into a list of actions.

Multiple actions can be separated by semicolons or newlines.

Examples

iex> PhoenixTestDatastar.Actions.parse("@post('/path')")
{:ok, [%{method: :post, url: "/path", raw_url: "'/path'"}]}

iex> PhoenixTestDatastar.Actions.parse("@get('/first'); @post('/second')")
{:ok, [
  %{method: :get, url: "/first", raw_url: "'/first'"},
  %{method: :post, url: "/second", raw_url: "'/second'"}
]}

parse_one(expression)

@spec parse_one(String.t()) :: {:ok, action()} | {:error, term()}

Parse a single action expression.

Examples

iex> PhoenixTestDatastar.Actions.parse_one("@post('/path')")
{:ok, %{method: :post, url: "/path", raw_url: "'/path'"}}

iex> PhoenixTestDatastar.Actions.parse_one("@post('/path', {headers: {'x-csrf-token': $_csrfToken}})")
{:ok, %{method: :post, url: "/path", raw_url: "'/path'"}}

iex> PhoenixTestDatastar.Actions.parse_one("@get('/ds/items/load')")
{:ok, %{method: :get, url: "/ds/items/load", raw_url: "'/ds/items/load'"}}

resolve_url(url_expression, signals, current_path \\ nil)

@spec resolve_url(String.t(), map(), String.t() | nil) :: String.t()

Resolve dynamic URL expressions by replacing $signal references with values.

An optional current_path (the session's current path) resolves the location.pathname token emitted by dstar's page-local helpers (Dstar.Page.Helpers.event/2 and connect/1 in dstar >= 0.1.0-alpha.2). A chained .replace(/\/+$/, '') strips trailing slashes from the current path, mirroring what the Datastar JS client computes in the browser. Any query string or fragment in current_path is ignored, like location.pathname in the browser.

Examples

iex> PhoenixTestDatastar.Actions.resolve_url("'/ds/counter/increment'", %{})
"/ds/counter/increment"

iex> PhoenixTestDatastar.Actions.resolve_url("'/ds/' + $_dstar_module + '/increment'", %{"_dstar_module" => "my_app-counter"})
"/ds/my_app-counter/increment"

iex> PhoenixTestDatastar.Actions.resolve_url("'/prefix/' + $mySignal + '/suffix'", %{"mySignal" => "value"})
"/prefix/value/suffix"

iex> PhoenixTestDatastar.Actions.resolve_url("location.pathname", %{}, "/chrismccord")
"/chrismccord"