From 20a1a39fa07ac0c5461eeac769d4689bae149908 Mon Sep 17 00:00:00 2001 From: Jon Surrell Date: Thu, 4 Dec 2025 19:29:41 +0100 Subject: [PATCH 1/8] Capture modules enqueued on enqueue_block_assets --- src/wp-includes/block-editor.php | 36 ++++++++++++++------- src/wp-includes/class-wp-script-modules.php | 8 +++++ 2 files changed, 33 insertions(+), 11 deletions(-) diff --git a/src/wp-includes/block-editor.php b/src/wp-includes/block-editor.php index 6f5720ec21c9d..8e313d25f2a28 100644 --- a/src/wp-includes/block-editor.php +++ b/src/wp-includes/block-editor.php @@ -286,28 +286,33 @@ function get_legacy_widget_block_editor_settings() { * Collect the block editor assets that need to be loaded into the editor's iframe. * * @since 6.0.0 + * @since 7.0.0 Allow enqueuing script modules. * @access private * - * @global WP_Styles $wp_styles The WP_Styles current instance. - * @global WP_Scripts $wp_scripts The WP_Scripts current instance. + * @global WP_Styles $wp_styles The WP_Styles current instance. + * @global WP_Scripts $wp_scripts The WP_Scripts current instance. + * @global WP_Script_Modules $wp_script_modules The WP_Script_Modules current instance. * * @return array { * The block editor assets. * - * @type string|false $styles String containing the HTML for styles. - * @type string|false $scripts String containing the HTML for scripts. + * @type string|false $styles String containing the HTML for styles. + * @type string|false $scripts String containing the HTML for scripts. + * @type string|false $script_modules String containing the HTML for scripts. * } */ function _wp_get_iframed_editor_assets() { - global $wp_styles, $wp_scripts; + global $wp_styles, $wp_scripts, $wp_script_modules; // Keep track of the styles and scripts instance to restore later. - $current_wp_styles = $wp_styles; - $current_wp_scripts = $wp_scripts; + $current_wp_styles = $wp_styles; + $current_wp_scripts = $wp_scripts; + $current_wp_script_modules = $wp_script_modules; // Create new instances to collect the assets. $wp_styles = new WP_Styles(); $wp_scripts = new WP_Scripts(); + $wp_script_modules = $wp_script_modules->clone_without_enqueued_modules(); /* * Register all currently registered styles and scripts. The actions that @@ -379,13 +384,22 @@ function _wp_get_iframed_editor_assets() { wp_print_footer_scripts(); $scripts = ob_get_clean(); + ob_start(); + $wp_script_modules->print_import_map(); + $wp_script_modules->print_head_enqueued_script_modules(); + $wp_script_modules->print_enqueued_script_modules(); + $wp_script_modules->print_script_module_preloads(); + $script_modules = ob_get_clean(); + // Restore the original instances. - $wp_styles = $current_wp_styles; - $wp_scripts = $current_wp_scripts; + $wp_styles = $current_wp_styles; + $wp_scripts = $current_wp_scripts; + $wp_script_modules = $current_wp_script_modules; return array( - 'styles' => $styles, - 'scripts' => $scripts, + 'styles' => $styles, + 'scripts' => $scripts, + 'script_modules' => $script_modules, ); } diff --git a/src/wp-includes/class-wp-script-modules.php b/src/wp-includes/class-wp-script-modules.php index ff3973999581b..c26090e4bc75c 100644 --- a/src/wp-includes/class-wp-script-modules.php +++ b/src/wp-includes/class-wp-script-modules.php @@ -949,4 +949,12 @@ public function print_a11y_script_module_html() { . '
' . ''; } + + public function clone_without_enqueued_modules(): WP_Script_Modules { + $clone = new WP_Script_Modules(); + $clone->registered = $this->registered; + $clone->dependents_map = $this->dependents_map; + $clone->modules_with_missing_dependencies = $this->modules_with_missing_dependencies; + return $clone; + } } From c4612ec1438aaace8c0ca53bf9f0b6ce6984a47f Mon Sep 17 00:00:00 2001 From: Jon Surrell Date: Thu, 11 Dec 2025 11:04:52 +0100 Subject: [PATCH 2/8] Change instance cloning logic Co-authored-by: Weston Ruter --- src/wp-includes/class-wp-script-modules.php | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/wp-includes/class-wp-script-modules.php b/src/wp-includes/class-wp-script-modules.php index c26090e4bc75c..80e7f26316589 100644 --- a/src/wp-includes/class-wp-script-modules.php +++ b/src/wp-includes/class-wp-script-modules.php @@ -951,10 +951,9 @@ public function print_a11y_script_module_html() { } public function clone_without_enqueued_modules(): WP_Script_Modules { - $clone = new WP_Script_Modules(); - $clone->registered = $this->registered; - $clone->dependents_map = $this->dependents_map; - $clone->modules_with_missing_dependencies = $this->modules_with_missing_dependencies; + $clone = clone $this; + $clone->queue = array(); + $clone->done = array(); return $clone; } } From 08fca131d972dcf57ddc89792d2c98ada11f0f8e Mon Sep 17 00:00:00 2001 From: Jon Surrell Date: Thu, 11 Dec 2025 13:51:38 +0100 Subject: [PATCH 3/8] Set a11y_available = false on clone This value is set and accessed in the printing flow and should be reset --- src/wp-includes/class-wp-script-modules.php | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/wp-includes/class-wp-script-modules.php b/src/wp-includes/class-wp-script-modules.php index 80e7f26316589..297684b8f3854 100644 --- a/src/wp-includes/class-wp-script-modules.php +++ b/src/wp-includes/class-wp-script-modules.php @@ -950,10 +950,11 @@ public function print_a11y_script_module_html() { . ''; } - public function clone_without_enqueued_modules(): WP_Script_Modules { - $clone = clone $this; - $clone->queue = array(); - $clone->done = array(); + public function clone_without_enqueued_modules(): self { + $clone = clone $this; + $clone->queue = array(); + $clone->done = array(); + $clone->a11y_available = false; return $clone; } } From 54214b43a8b21a47d5937c8bf570ebcbb183ce03 Mon Sep 17 00:00:00 2001 From: Jon Surrell Date: Thu, 11 Dec 2025 13:58:19 +0100 Subject: [PATCH 4/8] Document new method --- src/wp-includes/class-wp-script-modules.php | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/wp-includes/class-wp-script-modules.php b/src/wp-includes/class-wp-script-modules.php index 297684b8f3854..e4ed47c425fb9 100644 --- a/src/wp-includes/class-wp-script-modules.php +++ b/src/wp-includes/class-wp-script-modules.php @@ -950,6 +950,16 @@ public function print_a11y_script_module_html() { . ''; } + /** + * Creates a clone of the instance without enqueued modules. + * + * This method creates a copy of the current instance without any + * state related to enqueued or printed modules. + * + * @since 7.0.0 + * + * @return WP_Script_Modules A new instance. + */ public function clone_without_enqueued_modules(): self { $clone = clone $this; $clone->queue = array(); From e29ce4b8f1dd87f4cfb74737b85484736b080924 Mon Sep 17 00:00:00 2001 From: Jon Surrell Date: Fri, 12 Dec 2025 13:53:41 +0100 Subject: [PATCH 5/8] Try dedicated action --- src/wp-includes/block-editor.php | 33 +++++++++-------------------- src/wp-includes/default-filters.php | 6 ++++++ 2 files changed, 16 insertions(+), 23 deletions(-) diff --git a/src/wp-includes/block-editor.php b/src/wp-includes/block-editor.php index 8e313d25f2a28..3b7bcf43a774c 100644 --- a/src/wp-includes/block-editor.php +++ b/src/wp-includes/block-editor.php @@ -310,8 +310,8 @@ function _wp_get_iframed_editor_assets() { $current_wp_script_modules = $wp_script_modules; // Create new instances to collect the assets. - $wp_styles = new WP_Styles(); - $wp_scripts = new WP_Scripts(); + $wp_styles = new WP_Styles(); + $wp_scripts = new WP_Scripts(); $wp_script_modules = $wp_script_modules->clone_without_enqueued_modules(); /* @@ -369,38 +369,25 @@ function _wp_get_iframed_editor_assets() { remove_action( 'wp_print_styles', 'print_emoji_styles' ); } + add_action( 'wp_print_iframe_html', array( $wp_script_modules, 'print_import_map' ) ); + add_action( 'wp_print_iframe_html', array( $wp_script_modules, 'print_head_enqueued_script_modules' ) ); + add_action( 'wp_print_iframe_html', array( $wp_script_modules, 'print_enqueued_script_modules' ) ); + add_action( 'wp_print_iframe_html', array( $wp_script_modules, 'print_script_module_preloads' ) ); + ob_start(); - wp_print_styles(); - wp_print_font_faces(); - wp_print_font_faces_from_style_variations(); - $styles = ob_get_clean(); + do_action( 'wp_print_iframe_html' ); + $html = ob_end_clean(); if ( $has_emoji_styles ) { add_action( 'wp_print_styles', 'print_emoji_styles' ); } - ob_start(); - wp_print_head_scripts(); - wp_print_footer_scripts(); - $scripts = ob_get_clean(); - - ob_start(); - $wp_script_modules->print_import_map(); - $wp_script_modules->print_head_enqueued_script_modules(); - $wp_script_modules->print_enqueued_script_modules(); - $wp_script_modules->print_script_module_preloads(); - $script_modules = ob_get_clean(); - // Restore the original instances. $wp_styles = $current_wp_styles; $wp_scripts = $current_wp_scripts; $wp_script_modules = $current_wp_script_modules; - return array( - 'styles' => $styles, - 'scripts' => $scripts, - 'script_modules' => $script_modules, - ); + return array( 'html' => $html ); } /** diff --git a/src/wp-includes/default-filters.php b/src/wp-includes/default-filters.php index 68dccd979f2fe..9251f5bd1b55d 100644 --- a/src/wp-includes/default-filters.php +++ b/src/wp-includes/default-filters.php @@ -373,6 +373,12 @@ add_action( 'wp_enqueue_scripts', 'wp_enqueue_emoji_styles' ); add_action( 'wp_print_styles', 'print_emoji_styles' ); // Retained for backwards-compatibility. Unhooked by wp_enqueue_emoji_styles(). +add_action( 'wp_print_iframe_html', 'wp_print_styles' ); +add_action( 'wp_print_iframe_html', 'wp_print_font_faces' ); +add_action( 'wp_print_iframe_html', 'wp_print_font_faces_from_style_variations' ); +add_action( 'wp_print_iframe_html', 'wp_print_head_scripts' ); +add_action( 'wp_print_iframe_html', 'wp_print_footer_scripts' ); + if ( // Comment reply link. isset( $_GET['replytocom'] ) From 28305f9fff2d80e0f70970fb69e71cde297bd2d4 Mon Sep 17 00:00:00 2001 From: Jon Surrell Date: Fri, 12 Dec 2025 15:00:05 +0100 Subject: [PATCH 6/8] Restore styles to array The editor package prints styles and scripts sequentially. Provide HTML as styles to ensure its printed in legacy editor packages. --- src/wp-includes/block-editor.php | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/wp-includes/block-editor.php b/src/wp-includes/block-editor.php index 3b7bcf43a774c..48652c6b7e4a0 100644 --- a/src/wp-includes/block-editor.php +++ b/src/wp-includes/block-editor.php @@ -387,7 +387,10 @@ function _wp_get_iframed_editor_assets() { $wp_scripts = $current_wp_scripts; $wp_script_modules = $current_wp_script_modules; - return array( 'html' => $html ); + return array( + 'styles' => $html, + 'html' => $html, + ); } /** From 3bef1bb070bf92697beced7a9c53e94a5203dfad Mon Sep 17 00:00:00 2001 From: Jon Surrell Date: Fri, 12 Dec 2025 15:09:35 +0100 Subject: [PATCH 7/8] Update return type --- src/wp-includes/block-editor.php | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/wp-includes/block-editor.php b/src/wp-includes/block-editor.php index 48652c6b7e4a0..d723323f3cda6 100644 --- a/src/wp-includes/block-editor.php +++ b/src/wp-includes/block-editor.php @@ -296,9 +296,7 @@ function get_legacy_widget_block_editor_settings() { * @return array { * The block editor assets. * - * @type string|false $styles String containing the HTML for styles. - * @type string|false $scripts String containing the HTML for scripts. - * @type string|false $script_modules String containing the HTML for scripts. + * @type string|false $html String containing the necessary HTML for the editor iframe. * } */ function _wp_get_iframed_editor_assets() { From 804b4315c6efd9d06eb37d8488c14b1c0799ddab Mon Sep 17 00:00:00 2001 From: Jon Surrell Date: Fri, 12 Dec 2025 15:09:48 +0100 Subject: [PATCH 8/8] Fix ob_end/ob_get error --- src/wp-includes/block-editor.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/wp-includes/block-editor.php b/src/wp-includes/block-editor.php index d723323f3cda6..b971a41304160 100644 --- a/src/wp-includes/block-editor.php +++ b/src/wp-includes/block-editor.php @@ -374,7 +374,7 @@ function _wp_get_iframed_editor_assets() { ob_start(); do_action( 'wp_print_iframe_html' ); - $html = ob_end_clean(); + $html = ob_get_clean(); if ( $has_emoji_styles ) { add_action( 'wp_print_styles', 'print_emoji_styles' );