@gjsify/iframe 0.36.0 → 0.38.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -2,21 +2,17 @@ import { MessagePort, MessageChannel } from '@gjsify/message-channel';
2
2
  import type { MessagePortTransport } from '@gjsify/message-channel';
3
3
  import type { MessageBridge } from './message-bridge.js';
4
4
  export { MessagePort, MessageChannel };
5
- /** @deprecated Re-exported alias of `MessagePort` from
6
- * `@gjsify/message-channel`. Use the standard name. */
5
+ /** @deprecated Alias of `MessagePort`; use the standard name. */
7
6
  export declare const IFrameMessagePort: typeof MessagePort;
8
7
  export type IFrameMessagePort = MessagePort;
9
- /** @deprecated Re-exported alias of `MessageChannel` from
10
- * `@gjsify/message-channel`. Use the standard name. */
8
+ /** @deprecated Alias of `MessageChannel`; use the standard name. */
11
9
  export declare const IFrameMessageChannel: typeof MessageChannel;
12
10
  export type IFrameMessageChannel = MessageChannel;
13
11
  /**
14
- * MessagePortTransport adapter that routes a port's outbound messages
15
- * through a `MessageBridge` instance. Used internally by the bridge
16
- * when it picks up `MessagePort` instances from a `postMessage`
17
- * transferList — the transferred port's partner is attached to a
18
- * `BridgePortTransport` so its `.postMessage` flows over the WebKit
19
- * IPC instead of the in-process partner (which has been detached).
12
+ * Routes a port's outbound messages through a `MessageBridge`. The bridge attaches one to
13
+ * the PARTNER of every `MessagePort` it takes out of a `postMessage` transferList, so
14
+ * that partner's `.postMessage` flows over the WebKit IPC instead of to the now-detached
15
+ * in-process port.
20
16
  *
21
17
  * @internal
22
18
  */
@@ -2,57 +2,36 @@ import { EventTarget } from '@gjsify/dom-events';
2
2
  import type { MessageBridge } from './message-bridge.js';
3
3
  import type { MessagePort } from '@gjsify/message-channel';
4
4
  /**
5
- * Lightweight Window-like proxy returned by `HTMLIFrameElement.contentWindow`.
6
- *
7
- * Supports the subset of the Window API needed for cross-origin iframe communication:
8
- * - `postMessage()` for sending messages to the iframe content
9
- * - `addEventListener('message', ...)` for receiving messages from the iframe content
10
- * - `location` (read-only) reflecting the current URI
11
- * - `parent` reference to the host window
12
- * - `closed` status
13
- *
14
- * This is intentionally NOT a full BrowserWindow — just enough for standard
15
- * postMessage-based communication patterns.
5
+ * Deliberately NOT a full BrowserWindow: only the subset of the Window API that
6
+ * postMessage-based iframe communication needs.
16
7
  */
17
8
  export declare class IFrameWindowProxy extends EventTarget {
18
9
  private _bridge;
19
10
  private _closed;
20
11
  constructor(bridge: MessageBridge);
21
12
  /**
22
- * Send a message to the iframe content.
13
+ * Send a message to the iframe content. `message` must be JSON-serialisable, plus the
14
+ * binary types `@gjsify/iframe/serialize` can base64-encode.
23
15
  *
24
- * @param message - Data to send (must be JSON-serializable + base64-encodable
25
- * binaries — see @gjsify/iframe/serialize for supported binary types).
26
- * @param targetOrigin - Target origin for the message. Default: '*'.
27
- * @param transfer - Optional list of `MessagePort` instances to
28
- * transfer. Each transferred port is detached locally; its surviving
29
- * partner becomes the GJS-side endpoint of a bidirectional channel
30
- * routed through the bridge. The WebView receives proxy ports under
31
- * `MessageEvent.data` wherever the original ports appeared in `message`.
16
+ * Each port in `transfer` is detached locally and its surviving partner becomes the
17
+ * GJS-side endpoint of a bidirectional channel routed through the bridge; the WebView
18
+ * receives proxy ports wherever the originals appeared in `message`.
32
19
  */
33
20
  postMessage(message: unknown, targetOrigin?: string, transfer?: MessagePort[]): void;
34
- /**
35
- * Read-only location reflecting the current WebView URI.
36
- */
21
+ /** Read-only location reflecting the current WebView URI. */
37
22
  get location(): {
38
23
  href: string;
39
24
  origin: string;
40
25
  };
41
- /**
42
- * Reference to the host (parent) window — in GJS this is globalThis.
43
- */
26
+ /** The host window — `globalThis` on GJS. */
44
27
  get parent(): typeof globalThis;
45
- /**
46
- * Reference to the top-level window — in GJS this is globalThis.
47
- */
28
+ /** The top-level window — `globalThis` on GJS. */
48
29
  get top(): typeof globalThis;
49
- /**
50
- * The window itself (self-reference per spec).
51
- */
30
+ /** Self-reference, per spec. */
52
31
  get self(): IFrameWindowProxy;
53
32
  get window(): IFrameWindowProxy;
54
33
  get closed(): boolean;
55
- /** @internal Mark as closed when the WebView is destroyed */
34
+ /** @internal Called when the WebView is destroyed. */
56
35
  _close(): void;
57
36
  get [Symbol.toStringTag](): string;
58
37
  }
@@ -5,60 +5,38 @@ import type { ConsoleCallback, ConsoleLogEntry } from './types/index.js';
5
5
  import type { MessagePort } from '@gjsify/message-channel';
6
6
  /** Options for {@link MessageBridge}. */
7
7
  export interface MessageBridgeOptions {
8
- /** Inject the console-capture UserScript so the page's console.* is
9
- * forwarded to the host. Default: false. */
8
+ /** Forward the page's `console.*` to the host via a UserScript. Default: false. */
10
9
  captureConsole?: boolean;
11
10
  }
12
11
  /**
13
- * Synthetic origin attached to messages travelling FROM the GJS host
14
- * INTO the WebView. The WebView can use this in a targetOrigin filter to
15
- * accept messages only when they originate from its hosting GJS process
16
- * (vs. any other code that might inject script via developer tools).
12
+ * Synthetic origin on messages travelling FROM the GJS host INTO the WebView, so page
13
+ * code can filter on it and accept only what its hosting process sent.
17
14
  *
18
- * Uses the `https://` scheme so WHATWG URL parsing gives a real origin
19
- * string (non-special schemes like `gjsify://` return `null` as origin
20
- * per the URL spec, which would break the equality comparison the
21
- * bridge does on every message). `.local` is the standard RFC 6762
22
- * suffix for non-routable mDNS names, so it can't collide with a real
23
- * site.
15
+ * `https://` because WHATWG URL parsing yields `null` as the origin of a non-special
16
+ * scheme like `gjsify://`, which would break the equality comparison the bridge does on
17
+ * every message. `.local` is RFC 6762's non-routable suffix, so it cannot collide with a
18
+ * real site.
24
19
  */
25
20
  export declare const GJS_HOST_ORIGIN = "https://gjsify.local";
26
21
  /**
27
- * Per HTML spec for window.postMessage:
28
- * - '*' → no origin restriction
29
- * - URL string → only deliver if destination origin matches URL.origin
30
- * - '/' → only deliver if destination origin matches source origin
31
- * - other → throw SyntaxError
32
- *
33
- * Returns the canonical origin string (e.g. 'https://example.com'),
34
- * `'*'`, or `null` if the input is `'/'`. Throws `SyntaxError` for
35
- * malformed input.
22
+ * `targetOrigin` per the HTML spec for window.postMessage: `'*'` is unrestricted, a URL
23
+ * must match the destination origin, `'/'` means "the source's own origin" (returned as
24
+ * `null`), and anything else is a `SyntaxError`.
36
25
  */
37
26
  export declare function normaliseTargetOrigin(targetOrigin: string): string | null;
38
27
  /**
39
- * Bootstrap script injected into every WebView page at document start.
40
- * Provides the `window.parent.postMessage()` bridge from WebView content back to GJS.
41
- *
42
- * The script:
43
- * 1. Gets the WebKit message handler registered under CHANNEL_NAME
44
- * 2. Creates a parent proxy with a postMessage() that sends via the WebKit handler
45
- * 3. Overrides window.parent to point to the proxy
46
- */
47
- /**
48
- * @internal Exposed only for unit testing — verifies the bootstrap
49
- * idempotency guard survives refactors. Not part of the public API.
28
+ * @internal Exposed only so a unit test can check that the bootstrap script's
29
+ * idempotency guard survives a refactor. Not public API.
50
30
  */
51
31
  export declare const BOOTSTRAP_SCRIPT_FOR_TEST: () => string;
52
32
  /**
53
- * Manages bidirectional postMessage communication between GJS and a WebKit.WebView.
33
+ * Bidirectional postMessage between GJS and a WebKit.WebView.
54
34
  *
55
- * Direction 1 — GJS → WebView:
56
- * Uses webView.evaluate_javascript() to dispatch a MessageEvent on the WebView's window.
57
- *
58
- * Direction 2 — WebView → GJS:
59
- * Bootstrap script overrides window.parent.postMessage to call
60
- * webkit.messageHandlers[CHANNEL_NAME].postMessage(), which triggers
61
- * the UserContentManager 'script-message-received' signal in GJS.
35
+ * GJS → WebView goes through `evaluate_javascript()`, which dispatches a MessageEvent on
36
+ * the WebView's window. WebView → GJS goes through the bootstrap script's
37
+ * `window.parent.postMessage` override, which calls
38
+ * `webkit.messageHandlers[CHANNEL_NAME].postMessage()` and raises the
39
+ * UserContentManager 'script-message-received' signal.
62
40
  */
63
41
  export declare class MessageBridge {
64
42
  private _webView;
@@ -66,9 +44,8 @@ export declare class MessageBridge {
66
44
  private _windowProxy;
67
45
  private _currentUri;
68
46
  private _signalId;
69
- /** GJS-side endpoints of transferred ports, keyed by per-bridge id.
70
- * When the WebView sends a `{__gjsifyPortMessage: id, payload}` envelope,
71
- * we route the payload to `_ports.get(id)._receive(decoded)`. */
47
+ /** GJS-side endpoints of transferred ports, keyed by per-bridge id: a
48
+ * `{__gjsifyPortMessage: id, payload}` envelope routes to `_receive(decoded)`. */
72
49
  private _ports;
73
50
  private _nextPortId;
74
51
  private _transport;
@@ -77,8 +54,7 @@ export declare class MessageBridge {
77
54
  private _consoleBuffer;
78
55
  private _consoleCallbacks;
79
56
  constructor(webView: WebKit.WebView, options?: MessageBridgeOptions);
80
- /** Buffered console entries captured from the page (oldest first). Empty
81
- * unless the bridge was created with `captureConsole`. */
57
+ /** Console entries from the page, oldest first; empty without `captureConsole`. */
82
58
  getConsoleLogs(): ConsoleLogEntry[];
83
59
  /** Drop all buffered console entries. */
84
60
  clearConsoleLogs(): void;
@@ -86,29 +62,25 @@ export declare class MessageBridge {
86
62
  onConsole(cb: ConsoleCallback): void;
87
63
  /** @internal Record a parsed console entry + fan out to subscribers. */
88
64
  private _recordConsole;
89
- /** Connect the IFrameWindowProxy that will receive messages from the WebView */
65
+ /** Connect the IFrameWindowProxy that receives messages from the WebView. */
90
66
  setWindowProxy(proxy: IFrameWindowProxy): void;
91
- /** Update current URI (called by IFrameBridge on load-changed) */
67
+ /** Called by IFrameBridge on load-changed. */
92
68
  updateUri(uri: string): void;
93
- /** Get current location info for the IFrameWindowProxy */
69
+ /** Location info for the IFrameWindowProxy. */
94
70
  getLocation(): {
95
71
  href: string;
96
72
  origin: string;
97
73
  };
98
- /**
99
- * Send a message from GJS to the WebView content.
100
- * Dispatches a standard MessageEvent on the WebView's window object.
101
- */
74
+ /** Dispatches a standard MessageEvent on the WebView's window object. */
102
75
  /**
103
76
  * Register a port pair for cross-bridge transfer. Called by
104
77
  * IFrameWindowProxy.postMessage when it sees a `MessagePort` in the
105
78
  * transferList. Returns the port-id placeholder that should be
106
79
  * substituted into the outgoing payload.
107
80
  *
108
- * Marks the transferred port as detached locally and wires its
109
- * surviving partner with a `BridgePortTransport` so the partner's
110
- * postMessage routes back over the WebKit bridge instead of the
111
- * (now-null) in-process partner.
81
+ * The transferred port is detached locally and its surviving partner gets a
82
+ * `BridgePortTransport`, so the partner's postMessage routes over the WebKit bridge
83
+ * instead of the now-null in-process partner.
112
84
  */
113
85
  _registerTransferredPort(port: MessagePort): number;
114
86
  /** @internal Called by MessagePort.postMessage when its partner
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gjsify/iframe",
3
- "version": "0.36.0",
3
+ "version": "0.38.0",
4
4
  "description": "HTMLIFrameElement for GJS, backed by WebKit.WebView",
5
5
  "type": "module",
6
6
  "module": "lib/esm/index.js",
@@ -46,14 +46,14 @@
46
46
  "@girs/gtk-4.0": "^4.1.0",
47
47
  "@girs/javascriptcore-6.0": "^4.1.0",
48
48
  "@girs/webkit-6.0": "^4.1.0",
49
- "@gjsify/dom-elements": "^0.36.0",
50
- "@gjsify/dom-events": "^0.36.0",
51
- "@gjsify/message-channel": "^0.36.0",
52
- "@gjsify/webkit-native": "^0.36.0"
49
+ "@gjsify/dom-elements": "^0.38.0",
50
+ "@gjsify/dom-events": "^0.38.0",
51
+ "@gjsify/message-channel": "^0.38.0",
52
+ "@gjsify/webkit-native": "^0.38.0"
53
53
  },
54
54
  "devDependencies": {
55
- "@gjsify/cli": "^0.36.0",
56
- "@gjsify/unit": "^0.36.0",
55
+ "@gjsify/cli": "^0.38.0",
56
+ "@gjsify/unit": "^0.38.0",
57
57
  "@types/node": "^25.9.2",
58
58
  "typescript": "^6.0.3"
59
59
  },