# `Dala.Ui.Embedded.Webview`
[🔗](https://github.com/manhvu/dala/blob/main/lib/dala/ui/embedded/webview.ex#L1)

Bidirectional JS bridge for the native WebView component.

## Overview:

Use `Dala.Ui.Widgets.webview/1` to embed the component, then call these functions
from `handle_info` to communicate with the page.

## JS Side (injected automatically):

    // Send a message to Elixir
    window.dala.send({ event: "clicked", id: 42 })

    // Receive a message from Elixir
    window.dala.onMessage(function(data) { console.log(data) })

## Elixir Side:

    def handle_info({:webview, :message, %{"event" => "clicked", "id" => id}}, socket) do
      {:noreply, socket}
    end

    def handle_info({:webview, :blocked, url}, socket) do
      # A navigation attempt was blocked by the allow: whitelist
      {:noreply, socket}
    end

## Navigation Functions:

- `navigate/2` - Navigate to URL
- `reload/1` - Reload current page
- `stop_loading/1` - Stop loading
- `go_forward/1` - Go forward in history

## Interact Actions:

- `{:tap, selector}` - Tap an element
- `{:type, selector, text}` - Type text
- `{:clear, selector}` - Clear input
- `{:eval, js_code}` - Evaluate JavaScript
- `{:scroll, selector, dx, dy}` - Scroll element
- `{:wait, selector, timeout_ms}` - Wait for element

Results arrive via:
- `{:webview, :eval_result, json}` - JS eval result
- `{:webview, :interact_result, %{"action" => ..., "success" => ...}}`

# `eval_js`

```elixir
@spec eval_js(Dala.Socket.t(), String.t()) :: Dala.Socket.t()
```

Evaluate arbitrary JavaScript in the current WebView and return the result
asynchronously via `handle_info({:webview, :eval_result, result}, socket)`.

The result is JSON-decoded before delivery.

# `go_forward`

```elixir
@spec go_forward(Dala.Socket.t()) :: Dala.Socket.t()
```

Go forward in the WebView history (if possible).

# `interact`

```elixir
@spec interact(Dala.Socket.t(), tuple()) :: Dala.Socket.t()
```

High-level interact API for driving WebView content programmatically.

Actions:
  * `{:tap, selector}` - Tap an element matching CSS selector
  * `{:type, selector, text}` - Type text into an input element
  * `{:clear, selector}` - Clear an input element
  * `{:eval, js_code}` - Evaluate JS and return result via `:eval_result`
  * `{:scroll, selector, dx, dy}` - Scroll an element by delta
  * `{:wait, selector, timeout_ms}` - Wait for element to appear (via polling)

Results arrive as `handle_info({:webview, :interact_result, %{"action" => ..., "success" => ...}}, socket)`.

# `navigate`

```elixir
@spec navigate(Dala.Socket.t(), String.t()) :: Dala.Socket.t()
```

Navigate to a new URL in the WebView.

# `post_message`

```elixir
@spec post_message(Dala.Socket.t(), term()) :: Dala.Socket.t()
```

Push a message from Elixir into the WebView page. Calls `window.dala._dispatch(json)`
in JS, which delivers the data to all `window.dala.onMessage` handlers.

# `reload`

```elixir
@spec reload(Dala.Socket.t()) :: Dala.Socket.t()
```

Reload the current page.

# `screenshot`

```elixir
@spec screenshot(Dala.Socket.t()) :: Dala.Socket.t()
```

Take a screenshot of the WebView content.

Returns the PNG data as a binary via:

    handle_info({:webview, :screenshot, png_data}, socket)

Note: Currently not implemented on all platforms.

# `stop_loading`

```elixir
@spec stop_loading(Dala.Socket.t()) :: Dala.Socket.t()
```

Stop loading the current page.

---

*Consult [api-reference.md](api-reference.md) for complete listing*
