From d68ca51d8a9edbabf01bcdc08abd5e646a824222 Mon Sep 17 00:00:00 2001 From: Adam Zielinski Date: Mon, 9 Oct 2023 11:14:22 +0200 Subject: [PATCH] [Patch WordPress] Ensure block editor iframe is controlled by a service worker (#668) ## What is this PR doing? Patches the block editor to use a special ControlledIframe component instead of a regular HTML "iframe" element. The goal is to make the iframe use a plain HTTP URL instead of srcDoc, blob URL and other variations. Normally, the patch applied here would be a huge maintenance burden over time. However, @ellatrix explores fixing the issue upstream [in the Gutenberg repo](https://github.com/WordPress/wordpress-playground/issues/646). Once her PR is merged, the patch here will only be needed for a known and limited set of WordPress and Gutenberg versions and will not require ongoing reconciliation with new WP/GB releases. Fixes #646 ## What problem is it solving? In Playground, the editor iframe needs to be controlled by Playground's service worker so it can serve CSS and other static assets. Otherwise all the requests originating in that iframe will yield 404s. However, different WordPress versions use a variety of iframe techniques that result in a non-controlled iframe: * 6.3 uses a binary blob URL and the frame isn't controlled by a service worker * <= 6.2 uses srcdoc had a null origin and the frame isn't controlled by a service worker * Other dynamic techniques, such as using a data URL, also fail to produce a controlled iframe HTTP URL src like src="/doc.html" seems to be the only way to create a controlled iframe. And so, this commit ensures that the block editor iframe uses a plain HTTP URL regardless of the WordPress version. Once https://github.com/WordPress/gutenberg/pull/55152 lands, this will just work in WordPress 6.4 and new Gutenberg releases. ## Testing Instructions Run `npm run dev` Then, confirm the inserter is nicely styled and there are no CSS-related 404s in the network tools. Test the following editors: * Post editor http://localhost:5400/website-server/?url=/wp-admin/post-new.php * Site editor http://localhost:5400/website-server/?url=/wp-admin/site-editor.php * For all supported WordPress versions * With and without the Gutenberg plugin (`&plugin=gutenberg`) ## Related * https://bugs.chromium.org/p/chromium/issues/detail?id=880768 * https://bugzilla.mozilla.org/show_bug.cgi?id=1293277 * https://github.com/w3c/ServiceWorker/issues/765 * https://github.com/WordPress/wordpress-playground/issues/42 * b7ca737 --- .../src/lib/steps/install-plugin.ts | 99 ++++++++++++------- .../playground/compile-wordpress/Dockerfile | 14 ++- .../build-assets/controlled-iframe.js | 56 +++++++++++ .../public/wp-5.9/wp-includes/empty.html | 2 +- .../wp-includes/js/dist/block-editor.js | 47 ++++++++- .../wp-includes/js/dist/block-editor.min.js | 47 ++++++++- .../public/wp-6.0/wp-includes/empty.html | 2 +- .../wp-includes/js/dist/block-editor.js | 49 ++++++++- .../wp-includes/js/dist/block-editor.min.js | 47 ++++++++- .../public/wp-6.1/wp-includes/empty.html | 2 +- .../wp-includes/js/dist/block-editor.js | 49 ++++++++- .../wp-includes/js/dist/block-editor.min.js | 47 ++++++++- .../public/wp-6.2/wp-includes/empty.html | 2 +- .../wp-includes/js/dist/block-editor.js | 49 ++++++++- .../wp-includes/js/dist/block-editor.min.js | 47 ++++++++- .../public/wp-6.3/wp-includes/empty.html | 2 +- .../wp-includes/js/dist/block-editor.js | 47 ++++++++- .../wp-includes/js/dist/block-editor.min.js | 47 ++++++++- .../public/wp-nightly/wp-includes/empty.html | 2 +- .../wp-includes/js/dist/block-editor.js | 47 ++++++++- .../wp-includes/js/dist/block-editor.min.js | 47 ++++++++- .../remote/src/wordpress/wp-5.9.data | 18 ++-- .../remote/src/wordpress/wp-6.0.data | 18 ++-- .../remote/src/wordpress/wp-6.1.data | 18 ++-- .../remote/src/wordpress/wp-6.2.data | 20 ++-- .../playground/remote/src/wordpress/wp-6.2.js | 4 +- .../remote/src/wordpress/wp-6.3.data | 20 ++-- .../remote/src/wordpress/wp-nightly.data | 22 ++--- 28 files changed, 736 insertions(+), 135 deletions(-) create mode 100644 packages/playground/compile-wordpress/build-assets/controlled-iframe.js diff --git a/packages/playground/blueprints/src/lib/steps/install-plugin.ts b/packages/playground/blueprints/src/lib/steps/install-plugin.ts index 036feb8ba6..2b13fda74a 100644 --- a/packages/playground/blueprints/src/lib/steps/install-plugin.ts +++ b/packages/playground/blueprints/src/lib/steps/install-plugin.ts @@ -83,7 +83,7 @@ export const installPlugin: StepHandler> = async ( ); } - await maybeApplyGutenbergPatch(playground); + await applyGutenbergPatchOnce(playground); } catch (error) { console.error( `Proceeding without the ${zipNiceName} plugin. Could not install it in wp-admin. ` + @@ -93,64 +93,87 @@ export const installPlugin: StepHandler> = async ( } }; -async function maybeApplyGutenbergPatch(playground: UniversalPHP) { +async function applyGutenbergPatchOnce(playground: UniversalPHP) { /** - * The patch below is no longer necessary as it's been fixed upstream: + * Ensures the block editor iframe is controlled by the playground + * service worker. Tl;dr it must use a HTTP URL as its src, not a + * data URL, blob URL, or a srcDoc like it does by default. * - * https://github.com/WordPress/gutenberg/pull/50875 + * @see https://github.com/WordPress/wordpress-playground/pull/668 * - * It can be removed in the next few WordPress releases. - * - * --- - * - * Pair the site editor's nested iframe to the Service Worker. - * - * Without the patch below, the site editor initiates network requests that - * aren't routed through the service worker. That's a known browser issue: - * - * * https://bugs.chromium.org/p/chromium/issues/detail?id=880768 - * * https://bugzilla.mozilla.org/show_bug.cgi?id=1293277 - * * https://github.com/w3c/ServiceWorker/issues/765 - * - * The problem with iframes using srcDoc and src="about:blank" as they - * fail to inherit the root site's service worker. - * - * Gutenberg loads the site editor using