@@ -3523,12 +3523,6 @@ function wp_hoist_late_printed_styles() {
35233523 return ;
35243524 }
35253525
3526- // Determine priority at which styles are printed at wp_head. Short-circuit if it was unhooked.
3527- $ wp_head_priority = has_action ( 'wp_head ' , 'wp_print_styles ' );
3528- if ( false === $ wp_head_priority ) {
3529- return ;
3530- }
3531-
35323526 /*
35333527 * While normally late styles are printed, there is a filter to disable prevent this, so this makes sure they are
35343528 * printed. Note that this filter was intended to control whether to print the styles queued too late for the HTML
@@ -3542,16 +3536,9 @@ function wp_hoist_late_printed_styles() {
35423536 * Print a placeholder comment where the late styles can be hoisted from the footer to be printed in the header
35433537 * by means of a filter below on the template enhancement output buffer.
35443538 */
3545- $ placeholder = sprintf ( '<!--%s--> ' , uniqid ( 'wp_late_styles_placeholder: ' ) );
3539+ $ placeholder = sprintf ( '/*%s*/ ' , uniqid ( 'wp_late_styles_placeholder: ' ) );
35463540
3547- // Print placeholder comment where the late styles will be moved to.
3548- add_action (
3549- 'wp_head ' ,
3550- static function () use ( $ placeholder ) {
3551- echo $ placeholder ;
3552- },
3553- $ wp_head_priority
3554- );
3541+ wp_add_inline_style ( 'wp-block-library ' , $ placeholder );
35553542
35563543 // Wrap print_late_styles() with a closure that captures the late-printed styles.
35573544 $ printed_late_styles = '' ;
@@ -3590,7 +3577,46 @@ static function () use ( $capture_late_styles ) {
35903577 add_filter (
35913578 'wp_template_enhancement_output_buffer ' ,
35923579 static function ( $ buffer ) use ( $ placeholder , &$ printed_late_styles ) {
3593- return str_replace ( $ placeholder , $ printed_late_styles , $ buffer );
3580+
3581+ // Anonymous subclass of WP_HTML_Tag_Processor which exposes underlying bookmark spans.
3582+ $ processor = new class ( $ buffer ) extends WP_HTML_Tag_Processor {
3583+ public function get_span (): WP_HTML_Span {
3584+ $ this ->set_bookmark ( 'here ' );
3585+ return $ this ->bookmarks ['here ' ];
3586+ }
3587+ };
3588+
3589+ // Loop over STYLE tags.
3590+ while ( $ processor ->next_tag ( array ( 'tag_name ' => 'STYLE ' ) ) ) {
3591+ // Skip to the next if this is not the inline style for the wp-block-library stylesheet (which contains the placeholder).
3592+ if ( 'wp-block-library-inline-css ' !== $ processor ->get_attribute ( 'id ' ) ) {
3593+ continue ;
3594+ }
3595+
3596+ // If the inline style lacks the placeholder comment, then something went wrong and we need to abort.
3597+ $ css_text = $ processor ->get_modifiable_text ();
3598+ if ( ! str_contains ( $ css_text , $ placeholder ) ) {
3599+ break ;
3600+ }
3601+
3602+ // Remove the placeholder now that we've located the inline style.
3603+ $ processor ->set_modifiable_text ( str_replace ( $ placeholder , '' , $ css_text ) );
3604+ $ buffer = $ processor ->get_updated_html ();
3605+
3606+ // Insert the $printed_late_styles immediately after the closing inline STYLE tag. This preserves the CSS cascade.
3607+ $ span = $ processor ->get_span ();
3608+ $ buffer = implode (
3609+ '' ,
3610+ array (
3611+ substr ( $ buffer , 0 , $ span ->start + $ span ->length ),
3612+ $ printed_late_styles ,
3613+ substr ( $ buffer , $ span ->start + $ span ->length ),
3614+ )
3615+ );
3616+ break ;
3617+ }
3618+
3619+ return $ buffer ;
35943620 }
35953621 );
35963622}
0 commit comments