Skip to content

Commit

Permalink
Implement webview IPC support (#51)
Browse files Browse the repository at this point in the history
* Add IPC support

* Prepare 0.0.10 (0.1.9)
  • Loading branch information
zephraph authored Sep 23, 2024
1 parent 9bc2406 commit 6999db7
Show file tree
Hide file tree
Showing 10 changed files with 81 additions and 15 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
# Changelog

## 0.0.10 (binary 0.1.9) -- 2024-09-23

- Adds an `ipc` flag to enable sending messages from the webview back to the host deno process.
- Adds an IPC example
- Updates notifications to pass message bodies through

## 0.0.9 (binary 0.1.8) -- 2024-09-23

- Adds a `getVersion` method to `Webview` that returns the binary version.
Expand Down
2 changes: 1 addition & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "deno-webview"
version = "0.1.8"
version = "0.1.9"
edition = "2021"

[profile.release]
Expand Down
7 changes: 4 additions & 3 deletions deno.json
Original file line number Diff line number Diff line change
@@ -1,15 +1,16 @@
{
"name": "@justbe/webview",
"exports": "./src/lib.ts",
"version": "0.0.9",
"version": "0.0.10",
"tasks": {
"dev": "deno run --watch main.ts",
"gen": "deno task gen:rust && deno task gen:deno",
"gen:rust": "cargo test",
"gen:deno": "deno run -A scripts/generate-schema.ts && deno run -A scripts/sync-versions.ts",
"build": "deno task gen && cargo build -F transparent",
"build": "deno task gen && cargo build -F transparent -F devtools",
"run": "export WEBVIEW_BIN=./target/debug/deno-webview && deno run -E=WEBVIEW_BIN --allow-run=$WEBVIEW_BIN",
"example:simple": "deno task run examples/simple.ts"
"example:simple": "deno task run examples/simple.ts",
"example:ipc": "deno task run examples/ipc.ts"
},
"publish": {
"include": ["README.md", "LICENSE", "src/**/*.ts"]
Expand Down
15 changes: 15 additions & 0 deletions examples/ipc.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { createWebView } from "../src/lib.ts";

using webview = await createWebView({
title: "Simple",
html:
'<button onclick="window.ipc.postMessage(`button clicked ${Date.now()}`)">Click me</button>',
ipc: true,
});

// @ts-expect-error event emitter types still need to be corrected
webview.on("ipc", ({ message }) => {
console.log(message);
});

await webview.waitUntilClosed();
18 changes: 18 additions & 0 deletions schemas/WebViewMessage.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions schemas/WebViewOptions.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

12 changes: 6 additions & 6 deletions src/lib.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ export type { WebViewOptions } from "./schemas.ts";

// Should match the cargo package version
/** The version of the webview binary that's expected */
export const BIN_VERSION = "0.1.8";
export const BIN_VERSION = "0.1.9";

type JSON =
| string
Expand Down Expand Up @@ -296,17 +296,17 @@ export class WebView implements Disposable {
const { $type, data } = result;

if ($type === "notification") {
const notification = data;
this.#externalEvent.emit(notification.$type);
if (notification.$type === "started") {
const version = notification.version;
const { $type, ...body } = data;
this.#externalEvent.emit($type, body);
if (data.$type === "started") {
const version = data.version;
if (version !== BIN_VERSION) {
console.warn(
`Expected webview to be version ${BIN_VERSION} but got ${version}. Some features may not work as expected.`,
);
}
}
if (notification.$type === "closed") {
if ($type === "closed") {
return;
}
}
Expand Down
22 changes: 18 additions & 4 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,9 @@ struct WebViewOptions {
/// Sets whether clicking an inactive window also clicks through to the webview. Default is false.
#[serde(default)]
accept_first_mouse: bool,
/// Sets whether host should be able to receive messages from the webview via `window.ipc.postMessage`.
#[serde(default)]
ipc: bool,
}

fn default_true() -> bool {
Expand Down Expand Up @@ -78,6 +81,7 @@ enum Message {
#[serde(tag = "$type")]
enum Notification {
Started { version: String },
Ipc { message: String },
Closed,
}

Expand Down Expand Up @@ -139,6 +143,9 @@ fn main() -> wry::Result<()> {
};
use wry::WebViewBuilder;

let (tx, to_deno) = mpsc::channel::<Message>();
let (from_deno, rx) = mpsc::channel::<Request>();

let event_loop = EventLoop::new();
let mut window_builder = WindowBuilder::new()
.with_title(webview_options.title)
Expand All @@ -149,7 +156,7 @@ fn main() -> wry::Result<()> {
}
let window = window_builder.build(&event_loop).unwrap();

let webview_builder = match webview_options.target {
let mut webview_builder = match webview_options.target {
WebViewTarget::Url(url) => WebViewBuilder::new(&window).with_url(url),
WebViewTarget::Html(html) => WebViewBuilder::new(&window).with_html(html),
}
Expand All @@ -160,11 +167,18 @@ fn main() -> wry::Result<()> {
.with_focused(webview_options.focused)
.with_devtools(webview_options.devtools)
.with_accept_first_mouse(webview_options.accept_first_mouse);
let ipc_tx = tx.clone();
if webview_options.ipc {
webview_builder = webview_builder.with_ipc_handler(move |message| {
ipc_tx
.send(Message::Notification(Notification::Ipc {
message: message.body().to_string(),
}))
.unwrap()
})
}
let webview = webview_builder.build()?;

let (tx, to_deno) = mpsc::channel::<Message>();
let (from_deno, rx) = mpsc::channel::<Request>();

let notify_tx = tx.clone();
let notify = move |notification: Notification| {
notify_tx.send(Message::Notification(notification)).unwrap();
Expand Down
7 changes: 7 additions & 0 deletions src/schemas.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ export type WebViewOptions =
focused?: boolean;
fullscreen?: boolean;
incognito?: boolean;
ipc?: boolean;
title: string;
transparent?: boolean;
}
Expand All @@ -32,6 +33,7 @@ export const WebViewOptions: z.ZodType<WebViewOptions> = z.intersection(
focused: z.boolean().optional(),
fullscreen: z.boolean().optional(),
incognito: z.boolean().optional(),
ipc: z.boolean().optional(),
title: z.string(),
transparent: z.boolean().optional(),
}),
Expand Down Expand Up @@ -143,6 +145,10 @@ export type WebViewMessage =
$type: "started";
version: string;
}
| {
$type: "ipc";
message: string;
}
| {
$type: "closed";
};
Expand Down Expand Up @@ -184,6 +190,7 @@ export const WebViewMessage: z.ZodType<WebViewMessage> = z.discriminatedUnion(
$type: z.literal("notification"),
data: z.discriminatedUnion("$type", [
z.object({ $type: z.literal("started"), version: z.string() }),
z.object({ $type: z.literal("ipc"), message: z.string() }),
z.object({ $type: z.literal("closed") }),
]),
}),
Expand Down

0 comments on commit 6999db7

Please sign in to comment.