Dala.Ui.Embedded.Webview (dala v0.1.3)

Copy Markdown View Source

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:

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" => ...}}

Summary

Functions

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

Go forward in the WebView history (if possible).

High-level interact API for driving WebView content programmatically.

Navigate to a new URL in the WebView.

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 the current page.

Take a screenshot of the WebView content.

Stop loading the current page.

Functions

eval_js(socket, code)

@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(socket)

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

Go forward in the WebView history (if possible).

interact(socket, action)

@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).

post_message(socket, data)

@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(socket)

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

Reload the current page.

screenshot(socket)

@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(socket)

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

Stop loading the current page.