@@ -3634,7 +3634,7 @@ function wp_hoist_late_printed_styles() {
36343634 * enhancement output buffer, essentially no style can be enqueued too late, because an output buffer filter can
36353635 * always hoist it to the HEAD.
36363636 */
3637- add_filter ( 'print_late_styles ' , '__return_true ' , PHP_INT_MAX );
3637+ add_filter ( 'print_late_styles ' , '__return_true ' , PHP_INT_MAX ); // TODO: Remove.
36383638
36393639 /*
36403640 * Print a placeholder comment where the late styles can be hoisted from the footer to be printed in the header
@@ -3645,11 +3645,44 @@ function wp_hoist_late_printed_styles() {
36453645 wp_add_inline_style ( 'wp-block-library ' , $ placeholder );
36463646
36473647 // Wrap print_late_styles() with a closure that captures the late-printed styles.
3648- $ printed_late_styles = '' ;
3649- $ capture_late_styles = static function () use ( &$ printed_late_styles ) {
3648+ $ printed_block_styles = '' ;
3649+ $ printed_late_styles = '' ;
3650+ $ capture_late_styles = static function () use ( &$ printed_block_styles , &$ printed_late_styles ) {
3651+ global $ concatenate_scripts ;
3652+ script_concat_settings ();
3653+
3654+ // Print the styles related to on-demand block enqueues.
3655+ $ all_block_style_handles = array ();
3656+ foreach ( WP_Block_Type_Registry::get_instance ()->get_all_registered () as $ block_type ) {
3657+ foreach ( $ block_type ->style_handles as $ style_handle ) {
3658+ $ all_block_style_handles [] = $ style_handle ;
3659+ }
3660+ }
3661+ $ all_block_style_handles = array_merge (
3662+ $ all_block_style_handles ,
3663+ array ( 'global-styles ' , 'core-block-supports ' , 'block-style-variation-styles ' ) // TODO: What else?
3664+ );
3665+
3666+ $ enqueued_block_styles = array_values ( array_intersect ( $ all_block_style_handles , wp_styles ()->queue ) );
3667+ if ( count ( $ enqueued_block_styles ) > 0 ) {
3668+ wp_styles ()->do_concat = $ concatenate_scripts ;
3669+ ob_start ();
3670+ wp_styles ()->do_items ( $ enqueued_block_styles );
3671+ _print_styles ();
3672+ $ printed_block_styles = ob_get_clean ();
3673+ wp_styles ()->reset ();
3674+ }
3675+
3676+ /*
3677+ * Print remaining styles not related to blocks. This is the same logic as in print_late_styles(), but without
3678+ * the filter to control whether late styles are printed (since they are being hoisted anyway).
3679+ */
3680+ wp_styles ()->do_concat = $ concatenate_scripts ;
36503681 ob_start ();
3651- print_late_styles ();
3682+ wp_styles ()->do_footer_items ();
3683+ _print_styles ();
36523684 $ printed_late_styles = ob_get_clean ();
3685+ wp_styles ()->reset ();
36533686 };
36543687
36553688 /*
@@ -3680,7 +3713,7 @@ static function () use ( $capture_late_styles ) {
36803713 // Replace placeholder with the captured late styles.
36813714 add_filter (
36823715 'wp_template_enhancement_output_buffer ' ,
3683- function ( $ buffer ) use ( $ placeholder , &$ printed_late_styles ) {
3716+ function ( $ buffer ) use ( $ placeholder , &$ printed_block_styles , & $ printed_late_styles ) {
36843717
36853718 // Anonymous subclass of WP_HTML_Tag_Processor which exposes underlying bookmark spans.
36863719 $ processor = new class ( $ buffer ) extends WP_HTML_Tag_Processor {
@@ -3690,19 +3723,18 @@ public function get_span(): WP_HTML_Span {
36903723 }
36913724 };
36923725
3693- // Loop over STYLE tags.
3694- while ( $ processor ->next_tag ( array ( 'tag_closers ' => 'visit ' ) ) ) {
3695-
3696- // We've encountered the inline style for the 'wp-block-library' stylesheet which probably has the placeholder comment.
3726+ // TODO: If there are no block styles to print, it would be nice to not have to replace the placehoolder comment.
3727+ // Locate the inline style for the 'wp-block-library' stylesheet which probably has the placeholder comment.
3728+ while ( $ processor ->next_tag ( array ( 'tag_name ' => 'STYLE ' ) ) ) {
36973729 if (
36983730 ! $ processor ->is_tag_closer () &&
36993731 'STYLE ' === $ processor ->get_tag () &&
37003732 'wp-block-library-inline-css ' === $ processor ->get_attribute ( 'id ' )
37013733 ) {
3702- // If the inline style lacks the placeholder comment, then we have to continue until we get to </HEAD> to append the styles there .
3734+ // If the inline style lacks the placeholder comment, then all the styles will be inserted below before </HEAD>.
37033735 $ css_text = $ processor ->get_modifiable_text ();
37043736 if ( ! str_contains ( $ css_text , $ placeholder ) ) {
3705- continue ;
3737+ break ;
37063738 }
37073739
37083740 // Remove the placeholder now that we've located the inline style.
@@ -3715,25 +3747,47 @@ public function get_span(): WP_HTML_Span {
37153747 '' ,
37163748 array (
37173749 substr ( $ buffer , 0 , $ span ->start + $ span ->length ),
3718- $ printed_late_styles ,
3750+ $ printed_block_styles ,
37193751 substr ( $ buffer , $ span ->start + $ span ->length ),
37203752 )
37213753 );
3754+
3755+ // Prevent printing them again.
3756+ $ printed_block_styles = '' ;
37223757 break ;
37233758 }
3759+ }
3760+
3761+ // If there are remaining styles to hoist, either because
3762+ if ( $ printed_block_styles || $ printed_late_styles ) {
3763+
3764+ // Anonymous subclass of WP_HTML_Tag_Processor which exposes underlying bookmark spans.
3765+ $ processor = new class ( $ buffer ) extends WP_HTML_Tag_Processor {
3766+ public function get_span (): WP_HTML_Span {
3767+ $ this ->set_bookmark ( 'here ' );
3768+ return $ this ->bookmarks ['here ' ];
3769+ }
3770+ };
37243771
37253772 // As a fallback, append the hoisted late styles to the end of the HEAD.
3726- if ( $ processor ->is_tag_closer () && 'HEAD ' === $ processor ->get_tag () ) {
3727- $ span = $ processor ->get_span ();
3728- $ buffer = implode (
3729- '' ,
3730- array (
3731- substr ( $ buffer , 0 , $ span ->start ),
3732- $ printed_late_styles ,
3733- substr ( $ buffer , $ span ->start ),
3734- )
3735- );
3736- break ;
3773+ while ( $ processor ->next_tag (
3774+ array (
3775+ 'tag_name ' => 'HEAD ' ,
3776+ 'tag_closers ' => 'visit ' ,
3777+ )
3778+ ) ) {
3779+ if ( $ processor ->is_tag_closer () ) {
3780+ $ span = $ processor ->get_span ();
3781+ $ buffer = implode (
3782+ '' ,
3783+ array (
3784+ substr ( $ buffer , 0 , $ span ->start ),
3785+ $ printed_block_styles . $ printed_late_styles ,
3786+ substr ( $ buffer , $ span ->start ),
3787+ )
3788+ );
3789+ break ;
3790+ }
37373791 }
37383792 }
37393793
0 commit comments