Skip to content

Commit 61d2fa9

Browse files
westonruterdmsnell
andcommitted
Insert late-printed styles right after wp-block-library via HTML_Tag_Processor
Co-authored-by: Dennis Snell <[email protected]>
1 parent 2a2f97e commit 61d2fa9

File tree

2 files changed

+43
-17
lines changed

2 files changed

+43
-17
lines changed

src/wp-includes/script-loader.php

Lines changed: 42 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -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
}

tests/phpunit/tests/template.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1006,7 +1006,7 @@ public function test_wp_hoist_late_printed_styles( ?Closure $set_up ): void {
10061006
// Simulate wp_head.
10071007
$head_output = get_echo( 'wp_head' );
10081008

1009-
$placeholder_pattern = '/<!--wp_late_styles_placeholder:[a-f0-9-]+-->/';
1009+
$placeholder_pattern = '#/\*wp_late_styles_placeholder:[a-f0-9-]+\*/#';
10101010

10111011
$this->assertMatchesRegularExpression( $placeholder_pattern, $head_output, 'Expected the placeholder to be present' );
10121012
$this->assertStringContainsString( 'early', $head_output, 'Expected the early-enqueued stylesheet to be present.' );

0 commit comments

Comments
 (0)