diff --git a/.vitepress/config.mts b/.vitepress/config.mts index 09933ea..a179d2a 100644 --- a/.vitepress/config.mts +++ b/.vitepress/config.mts @@ -328,6 +328,10 @@ export default defineConfig({ text: "Intent", link: "/docs/advanced-apis/intent", }, + { + text: "WebView", + link: "/docs/advanced-apis/webview", + }, ], }, ], diff --git a/docs/advanced-apis/webview.md b/docs/advanced-apis/webview.md new file mode 100644 index 0000000..feba94c --- /dev/null +++ b/docs/advanced-apis/webview.md @@ -0,0 +1,169 @@ +# WebView + +The `webview` module exposes Acode's native WebView API. Require it with `acode.require('webview')` to display web content in a fullscreen view or run a headless (hidden) WebView in the background, and communicate with the loaded page over a two-way messaging bridge. + +## Import + +```js +const webview = acode.require('webview'); +``` + +## API Overview + +The module exposes a single method: + +- `create(options)`: Creates a new WebView instance. Resolves to a WebView instance object. + +Each instance exposes these methods: + +- `loadURL(url)`: Loads a URL. Only `http://` and `https://` URLs are allowed; input without a scheme (e.g. `example.com`) is loaded over `https`. +- `loadHTML(html)`: Loads an HTML string directly. +- `evaluate(js)`: Evaluates JavaScript in the page and resolves with the result. +- `postMessage(message)`: Sends a message to the page. Non-string values are JSON-stringified. +- `onMessage(callback)`: Registers a callback for messages sent from the page. +- `offMessage(callback)`: Removes a previously registered message callback. +- `on(event, callback)`: Registers a listener for lifecycle events (see Events). +- `off(event, callback)`: Removes a previously registered event listener. +- `show()`: Shows a fullscreen WebView (or brings it back to the front after `hide()`). +- `hide()`: Moves a fullscreen WebView to the background, keeping its page state intact. +- `reload()`: Reloads the current page. +- `destroy()`: Destroys the instance and releases its resources. **You must call this when the WebView is no longer needed.** + +> [!Warning] +> Always call `destroy()` once the WebView is no longer required. Every instance holds a native WebView, so leaving instances alive leaks memory and keeps pages (and their scripts/timers/network activity) running in the background. + +> [!Note] +> After an instance is destroyed (via `destroy()` or by the user closing a fullscreen WebView), calling any method on it throws `WebView has been destroyed`. + +## Create + +```js +// Fullscreen WebView shown immediately +const view = await webview.create({ + mode: 'fullscreen', + title: 'My Page', +}); +await view.loadURL('https://example.com'); + +// Hidden (headless) WebView running in the background +const headless = await webview.create({ mode: 'hidden' }); +await headless.loadURL('https://example.com'); +const title = await headless.evaluate('document.title'); + +// Fullscreen, but only shown when you call show() +const deferred = await webview.create({ mode: 'fullscreen', visible: false }); +await deferred.loadURL('https://example.com'); +await deferred.show(); +``` + +### WebViewOptions + +Options accepted by `create()`: + +- `mode`: `'fullscreen'` or `'hidden'` (default `'hidden'`). Fullscreen opens the WebView in its own activity; hidden creates a headless WebView that is never displayed. +- `title`: Title shown in the fullscreen activity. +- `allowNavigation`: Boolean, whether the page is allowed to navigate (default `true`). When `false`, all in-page navigation is blocked. +- `allowDownloads`: Boolean, enables downloads (default `false`). Downloads are confirmed with a dialog and saved via the system DownloadManager into the public Downloads directory. +- `visible`: Boolean, whether a fullscreen WebView is shown immediately (default `true`). When `false`, the launch is deferred until `show()` is called. + +### Return Value + +`create()` resolves to an instance object with: + +- `id`: Unique id (e.g. `wv_1a2b3c4d5e6f`). +- Plus the instance methods listed in API Overview. + +## Manage + +```js +// Load content +await view.loadURL('https://example.com'); +await view.loadHTML('