From af901bf9c99ae5c57ecba58808c11e1851aca039 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adam=20Zieli=C5=84ski?= Date: Tue, 5 Mar 2024 17:07:11 +0100 Subject: [PATCH] Set the API context when using Comlink.wrap() Fixes WordPress Playground Block not loading when the Site Editor is wrapped in an iframe. Playground uses Comlink to talk to the remote API via `window.postMessage()`. By default, Comlink binds the `message` event listener to the current global window object. However, when the Site Editor is iframed, the `startPlaygroundWeb` function runs in the global `window` context, but the Playground iframe lives inside of the Editor Canvas iframe context. Playground's `remote.html` would then send a much of messages (via `postMessage`) to its parent window (Editor Canvas), and Comlink would never notice. This PR ensires the `context` argument is always set to Playground's iframe parent window. ## Testing instructions 1. Clone https://github.com/WordPress/playground-tools/tree/trunk/packages/wordpress-playground-block 1. Update the remote URL to `http://localhost:5400/remote.html` 1. Build the `@wp-playground/client` package in this repo and substitute the block's dependency with it (or use npm link) 1. Run the Playground block in the dev mode (as described in its README) 1. Install the Gutenberg plugin to enable iframe-based Canvas 1. Insert the Playground block 1. Confirm Playground loads correctly --- packages/php-wasm/web/src/lib/api.ts | 5 +++-- packages/playground/client/src/index.ts | 6 ++++-- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/packages/php-wasm/web/src/lib/api.ts b/packages/php-wasm/web/src/lib/api.ts index 7875db0ec5..9748a837cc 100644 --- a/packages/php-wasm/web/src/lib/api.ts +++ b/packages/php-wasm/web/src/lib/api.ts @@ -16,7 +16,8 @@ export type WithAPIState = { export type RemoteAPI = Comlink.Remote & WithAPIState; export function consumeAPI( - remote: Worker | Window + remote: Worker | Window, + context: undefined | EventTarget = undefined ): RemoteAPI { setupTransferHandlers(); @@ -32,7 +33,7 @@ export function consumeAPI( * * @TODO: Remove this workaround. */ - const api = Comlink.wrap(endpoint); + const api = Comlink.wrap(endpoint, context); const methods = proxyClone(api); return new Proxy(methods, { get: (target, prop) => { diff --git a/packages/playground/client/src/index.ts b/packages/playground/client/src/index.ts index e5fc712f1f..c4cc41aa09 100644 --- a/packages/playground/client/src/index.ts +++ b/packages/playground/client/src/index.ts @@ -143,7 +143,8 @@ async function doStartPlaygroundWeb( // Connect the Comlink client and wait until the // playground is ready. const playground = consumeAPI( - iframe.contentWindow! + iframe.contentWindow!, + iframe.ownerDocument!.defaultView! ) as PlaygroundClient; await playground.isConnected(); progressTracker.pipe(playground); @@ -208,7 +209,8 @@ export async function connectPlayground( }); } const client = consumeAPI( - iframe.contentWindow! + iframe.contentWindow!, + iframe.ownerDocument!.defaultView! ) as PlaygroundClient; await client.isConnected(); return client;