From c01143db07de02ef91f7f8b0f1d1bde117df0a39 Mon Sep 17 00:00:00 2001 From: adamsilverstein Date: Wed, 18 Mar 2026 20:57:11 -0700 Subject: [PATCH] Media: Broaden DIP header to all admin and preview pages Send the Document-Isolation-Policy header on all admin pages and front-end preview pages instead of only specific editor screens. This keeps all admin navigations (site editor, template operations, pattern editing) and preview popups in the same agent cluster, preserving cross-window communication in Chromium 137+. --- src/wp-includes/default-filters.php | 6 +-- src/wp-includes/media.php | 39 ++++++++++++++----- .../tests/media/wpCrossOriginIsolation.php | 35 +++++++++++++++-- 3 files changed, 64 insertions(+), 16 deletions(-) diff --git a/src/wp-includes/default-filters.php b/src/wp-includes/default-filters.php index 24b808bf9cd17..78d956a4509bb 100644 --- a/src/wp-includes/default-filters.php +++ b/src/wp-includes/default-filters.php @@ -682,10 +682,8 @@ // Client-side media processing. add_action( 'admin_init', 'wp_set_client_side_media_processing_flag' ); // Cross-origin isolation for client-side media processing. -add_action( 'load-post.php', 'wp_set_up_cross_origin_isolation' ); -add_action( 'load-post-new.php', 'wp_set_up_cross_origin_isolation' ); -add_action( 'load-site-editor.php', 'wp_set_up_cross_origin_isolation' ); -add_action( 'load-widgets.php', 'wp_set_up_cross_origin_isolation' ); +add_action( 'admin_init', 'wp_set_up_cross_origin_isolation' ); +add_action( 'template_redirect', 'wp_set_up_cross_origin_isolation_for_preview' ); // Nav menu. add_filter( 'nav_menu_item_id', '_nav_menu_item_id_use_once', 10, 2 ); add_filter( 'nav_menu_css_class', 'wp_nav_menu_remove_menu_item_has_children_class', 10, 4 ); diff --git a/src/wp-includes/media.php b/src/wp-includes/media.php index fd215c800f9dc..2161b540139ec 100644 --- a/src/wp-includes/media.php +++ b/src/wp-includes/media.php @@ -6475,12 +6475,17 @@ function wp_get_chromium_major_version(): ?int { } /** - * Enables cross-origin isolation in the block editor. + * Enables cross-origin isolation on admin pages. * * Required for enabling SharedArrayBuffer for WebAssembly-based * media processing in the editor. Uses Document-Isolation-Policy * on supported browsers (Chromium 137+). * + * Applied to all admin pages so that navigations between editor pages + * and other admin screens (site editor, template operations, pattern + * editing) remain in the same agent cluster, preserving cross-window + * communication. + * * Skips setup when a third-party page builder overrides the block * editor via a custom `action` query parameter, as DIP would block * same-origin iframe access that these editors rely on. @@ -6492,13 +6497,8 @@ function wp_set_up_cross_origin_isolation(): void { return; } - $screen = get_current_screen(); - - if ( ! $screen ) { - return; - } - - if ( ! $screen->is_block_editor() && 'site-editor' !== $screen->id && ! ( 'widgets' === $screen->id && wp_use_widgets_block_editor() ) ) { + // Cross-origin isolation is not needed if users can't upload files anyway. + if ( ! current_user_can( 'upload_files' ) ) { return; } @@ -6511,7 +6511,28 @@ function wp_set_up_cross_origin_isolation(): void { return; } - // Cross-origin isolation is not needed if users can't upload files anyway. + wp_start_cross_origin_isolation_output_buffer(); +} + +/** + * Sets up cross-origin isolation for front-end preview pages. + * + * When the block editor sends the Document-Isolation-Policy header and opens + * a preview popup, the preview page must also send the header to remain in + * the same agent cluster. Without this, cross-window communication between + * the editor and preview breaks in Chromium 137+. + * + * @since 7.1.0 + */ +function wp_set_up_cross_origin_isolation_for_preview(): void { + if ( ! is_preview() ) { + return; + } + + if ( ! wp_is_client_side_media_processing_enabled() ) { + return; + } + if ( ! current_user_can( 'upload_files' ) ) { return; } diff --git a/tests/phpunit/tests/media/wpCrossOriginIsolation.php b/tests/phpunit/tests/media/wpCrossOriginIsolation.php index 4fe5723bdc426..142d77bf1be17 100644 --- a/tests/phpunit/tests/media/wpCrossOriginIsolation.php +++ b/tests/phpunit/tests/media/wpCrossOriginIsolation.php @@ -5,6 +5,7 @@ * * @group media * @covers ::wp_set_up_cross_origin_isolation + * @covers ::wp_set_up_cross_origin_isolation_for_preview * @covers ::wp_start_cross_origin_isolation_output_buffer * @covers ::wp_is_client_side_media_processing_enabled */ @@ -89,13 +90,15 @@ public function test_returns_early_when_client_side_processing_disabled() { /** * @ticket 64766 */ - public function test_returns_early_when_no_screen() { - // No screen is set, so it should return early. + public function test_returns_early_when_user_cannot_upload() { + $user_id = self::factory()->user->create( array( 'role' => 'subscriber' ) ); + wp_set_current_user( $user_id ); + $level_before = ob_get_level(); wp_set_up_cross_origin_isolation(); $level_after = ob_get_level(); - $this->assertSame( $level_before, $level_after ); + $this->assertSame( $level_before, $level_after, 'Output buffer should not start for users who cannot upload files.' ); } /** @@ -210,4 +213,30 @@ public function test_output_buffer_adds_crossorigin_attributes() { $this->assertStringContainsString( 'crossorigin="anonymous"', $output ); } + + /** + * @ticket 64766 + */ + public function test_preview_returns_early_when_not_preview() { + add_filter( 'wp_client_side_media_processing_enabled', '__return_true' ); + + $level_before = ob_get_level(); + wp_set_up_cross_origin_isolation_for_preview(); + $level_after = ob_get_level(); + + $this->assertSame( $level_before, $level_after, 'Output buffer should not start on non-preview pages.' ); + } + + /** + * @ticket 64766 + */ + public function test_preview_returns_early_when_processing_disabled() { + add_filter( 'wp_client_side_media_processing_enabled', '__return_false' ); + + $level_before = ob_get_level(); + wp_set_up_cross_origin_isolation_for_preview(); + $level_after = ob_get_level(); + + $this->assertSame( $level_before, $level_after, 'Output buffer should not start when client-side processing is disabled.' ); + } }