Changeset 61174 for trunk/src/wp-includes/script-loader.php
- Timestamp:
- 11/07/2025 04:27:45 AM (3 months ago)
- File:
-
- 1 edited
-
trunk/src/wp-includes/script-loader.php (modified) (4 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/wp-includes/script-loader.php
r61142 r61174 2265 2265 * Private, for use in *_footer_scripts hooks 2266 2266 * 2267 * In classic themes, when block styles are loaded on demand via {@see wp_load_classic_theme_block_styles_on_demand()}, 2268 * this function is replaced by a closure in {@see wp_hoist_late_printed_styles()} which will capture the output of 2269 * {@see print_late_styles()} before printing footer scripts as usual. The captured late-printed styles are then hoisted 2270 * to the HEAD by means of the template enhancement output buffer. 2267 * In classic themes, when block styles are loaded on demand via wp_load_classic_theme_block_styles_on_demand(), 2268 * this function is replaced by a closure in wp_hoist_late_printed_styles() which will capture the printing of 2269 * two sets of "late" styles to be hoisted to the HEAD by means of the template enhancement output buffer: 2270 * 2271 * 1. Styles related to blocks are inserted right after the wp-block-library stylesheet. 2272 * 2. All other styles are appended to the end of the HEAD. 2273 * 2274 * The closure calls print_footer_scripts() to print scripts in the footer as usual. 2271 2275 * 2272 2276 * @since 3.3.0 … … 3602 3606 3603 3607 /* 3604 * Load separate block styles so that the large block-library stylesheet is not enqueued unconditionally, 3605 * and so that block-specific styles will only be enqueued when they are used on the page. 3606 * A priority of zero allows for this to be easily overridden by themes which wish to opt out. 3608 * Load separate block styles so that the large block-library stylesheet is not enqueued unconditionally, and so 3609 * that block-specific styles will only be enqueued when they are used on the page. A priority of zero allows for 3610 * this to be easily overridden by themes which wish to opt out. If a site has explicitly opted out of loading 3611 * separate block styles, then abort. 3607 3612 */ 3608 3613 add_filter( 'should_load_separate_core_block_assets', '__return_true', 0 ); 3614 if ( ! wp_should_load_separate_core_block_assets() ) { 3615 return; 3616 } 3609 3617 3610 3618 /* 3611 3619 * Also ensure that block assets are loaded on demand (although the default value is from should_load_separate_core_block_assets). 3612 * As above, a priority of zero allows for this to be easily overridden by themes which wish to opt out. 3620 * As above, a priority of zero allows for this to be easily overridden by themes which wish to opt out. If a site 3621 * has explicitly opted out of loading block styles on demand, then abort. 3613 3622 */ 3614 3623 add_filter( 'should_load_block_assets_on_demand', '__return_true', 0 ); 3615 3616 // If a site has explicitly opted out of loading block styles on demand via filters with priorities higher than above, then abort. 3617 if ( ! wp_should_load_separate_core_block_assets() || ! wp_should_load_block_assets_on_demand() ) { 3624 if ( ! wp_should_load_block_assets_on_demand() ) { 3618 3625 return; 3619 3626 } … … 3638 3645 3639 3646 /* 3640 * While normally late styles are printed, there is a filter to disable prevent this, so this makes sure they are 3641 * printed. Note that this filter was intended to control whether to print the styles queued too late for the HTML 3642 * head. This filter was introduced in <https://core.trac.wordpress.org/ticket/9346>. However, with the template 3643 * enhancement output buffer, essentially no style can be enqueued too late, because an output buffer filter can 3644 * always hoist it to the HEAD. 3645 */ 3646 add_filter( 'print_late_styles', '__return_true', PHP_INT_MAX ); 3647 * Add a placeholder comment into the inline styles for wp-block-library, after which where the late block styles 3648 * can be hoisted from the footer to be printed in the header by means of a filter below on the template enhancement 3649 * output buffer. The `wp_print_styles` action is used to ensure that if the inline style gets replaced at 3650 * `enqueue_block_assets` or `wp_enqueue_scripts` that the placeholder will be sure to be present. 3651 */ 3652 $placeholder = sprintf( '/*%s*/', uniqid( 'wp_block_styles_on_demand_placeholder:' ) ); 3653 add_action( 3654 'wp_print_styles', 3655 static function () use ( $placeholder ) { 3656 wp_add_inline_style( 'wp-block-library', $placeholder ); 3657 } 3658 ); 3647 3659 3648 3660 /* 3649 * Print a placeholder comment where the late styles can be hoisted from the footer to be printed in the header 3650 * by means of a filter below on the template enhancement output buffer. 3651 */ 3652 $placeholder = sprintf( '/*%s*/', uniqid( 'wp_late_styles_placeholder:' ) ); 3653 3654 wp_add_inline_style( 'wp-block-library', $placeholder ); 3655 3656 // Wrap print_late_styles() with a closure that captures the late-printed styles. 3657 $printed_late_styles = ''; 3658 $capture_late_styles = static function () use ( &$printed_late_styles ) { 3661 * Create a substitute for `print_late_styles()` which is aware of block styles. This substitute does not print 3662 * the styles, but it captures what would be printed for block styles and non-block styles so that they can be 3663 * later hoisted to the HEAD in the template enhancement output buffer. This will run at `wp_print_footer_scripts` 3664 * before `print_footer_scripts()` is called. 3665 */ 3666 $printed_block_styles = ''; 3667 $printed_late_styles = ''; 3668 $capture_late_styles = static function () use ( &$printed_block_styles, &$printed_late_styles ) { 3669 // Gather the styles related to on-demand block enqueues. 3670 $all_block_style_handles = array(); 3671 foreach ( WP_Block_Type_Registry::get_instance()->get_all_registered() as $block_type ) { 3672 foreach ( $block_type->style_handles as $style_handle ) { 3673 $all_block_style_handles[] = $style_handle; 3674 } 3675 } 3676 $all_block_style_handles = array_merge( 3677 $all_block_style_handles, 3678 array( 3679 'global-styles', 3680 'block-style-variation-styles', 3681 'core-block-supports', 3682 'core-block-supports-duotone', 3683 ) 3684 ); 3685 3686 /* 3687 * First print all styles related to blocks which should inserted right after the wp-block-library stylesheet 3688 * to preserve the CSS cascade. The logic in this `if` statement is derived from `wp_print_styles()`. 3689 */ 3690 $enqueued_block_styles = array_values( array_intersect( $all_block_style_handles, wp_styles()->queue ) ); 3691 if ( count( $enqueued_block_styles ) > 0 ) { 3692 ob_start(); 3693 wp_styles()->do_items( $enqueued_block_styles ); 3694 $printed_block_styles = ob_get_clean(); 3695 } 3696 3697 /* 3698 * Print all remaining styles not related to blocks. This contains a subset of the logic from 3699 * `print_late_styles()`, without admin-specific logic and the `print_late_styles` filter to control whether 3700 * late styles are printed (since they are being hoisted anyway). 3701 */ 3659 3702 ob_start(); 3660 print_late_styles();3703 wp_styles()->do_footer_items(); 3661 3704 $printed_late_styles = ob_get_clean(); 3662 3705 }; 3663 3706 3664 3707 /* 3665 * If _wp_footer_scripts() was unhooked from the wp_print_footer_scripts action, or if wp_print_footer_scripts()3666 * was unhooked from running at the wp_footer action, then only add a callback to wp_footerwhich will capture the3708 * If `_wp_footer_scripts()` was unhooked from the `wp_print_footer_scripts` action, or if `wp_print_footer_scripts()` 3709 * was unhooked from running at the `wp_footer` action, then only add a callback to `wp_footer` which will capture the 3667 3710 * late-printed styles. 3668 3711 * 3669 * Otherwise, in the normal case where _wp_footer_scripts() will run at the wp_print_footer_scriptsaction, then3670 * swap out _wp_footer_scripts()with an alternative which captures the printed styles (for hoisting to HEAD) before3712 * Otherwise, in the normal case where `_wp_footer_scripts()` will run at the `wp_print_footer_scripts` action, then 3713 * swap out `_wp_footer_scripts()` with an alternative which captures the printed styles (for hoisting to HEAD) before 3671 3714 * proceeding with printing the footer scripts. 3672 3715 */ … … 3690 3733 add_filter( 3691 3734 'wp_template_enhancement_output_buffer', 3692 function ( $buffer ) use ( $placeholder, &$printed_late_styles ) {3735 static function ( $buffer ) use ( $placeholder, &$printed_block_styles, &$printed_late_styles ) { 3693 3736 3694 3737 // Anonymous subclass of WP_HTML_Tag_Processor which exposes underlying bookmark spans. 3695 3738 $processor = new class( $buffer ) extends WP_HTML_Tag_Processor { 3696 public function get_span(): WP_HTML_Span { 3697 $instance = $this; // phpcs:ignore PHPCompatibility.FunctionDeclarations.NewClosure.ThisFoundOutsideClass -- It is inside an anonymous class. 3698 $instance->set_bookmark( 'here' ); 3699 return $instance->bookmarks['here']; 3739 /** 3740 * Gets the span for the current token. 3741 * 3742 * @return WP_HTML_Span Current token span. 3743 */ 3744 private function get_span(): WP_HTML_Span { 3745 // Note: This call will never fail according to the usage of this class, given it is always called after ::next_tag() is true. 3746 $this->set_bookmark( 'here' ); 3747 return $this->bookmarks['here']; 3748 } 3749 3750 /** 3751 * Inserts text before the current token. 3752 * 3753 * @param string $text Text to insert. 3754 */ 3755 public function insert_before( string $text ) { 3756 $this->lexical_updates[] = new WP_HTML_Text_Replacement( $this->get_span()->start, 0, $text ); 3757 } 3758 3759 /** 3760 * Inserts text after the current token. 3761 * 3762 * @param string $text Text to insert. 3763 */ 3764 public function insert_after( string $text ) { 3765 $span = $this->get_span(); 3766 3767 $this->lexical_updates[] = new WP_HTML_Text_Replacement( $span->start + $span->length, 0, $text ); 3768 } 3769 3770 /** 3771 * Removes the current token. 3772 */ 3773 public function remove() { 3774 $span = $this->get_span(); 3775 3776 $this->lexical_updates[] = new WP_HTML_Text_Replacement( $span->start, $span->length, '' ); 3700 3777 } 3701 3778 }; 3702 3779 3703 // Loop over STYLE tags. 3780 /* 3781 * Insert block styles right after wp-block-library (if it is present), and then insert any remaining styles 3782 * at </head> (or else print everything there). The placeholder CSS comment will always be added to the 3783 * wp-block-library inline style since it gets printed at `wp_head` before the blocks are rendered. 3784 * This means that there may not actually be any block styles to hoist from the footer to insert after this 3785 * inline style. The placeholder CSS comment needs to be added so that the inline style gets printed, but 3786 * if the resulting inline style is empty after the placeholder is removed, then the inline style is 3787 * removed. 3788 */ 3704 3789 while ( $processor->next_tag( array( 'tag_closers' => 'visit' ) ) ) { 3705 3706 // We've encountered the inline style for the 'wp-block-library' stylesheet which probably has the placeholder comment.3707 3790 if ( 3708 ! $processor->is_tag_closer() &&3709 3791 'STYLE' === $processor->get_tag() && 3710 3792 'wp-block-library-inline-css' === $processor->get_attribute( 'id' ) 3711 3793 ) { 3712 // If the inline style lacks the placeholder comment, then we have to continue until we get to </HEAD> to append the styles there.3713 3794 $css_text = $processor->get_modifiable_text(); 3714 if ( ! str_contains( $css_text, $placeholder ) ) { 3715 continue; 3795 3796 /* 3797 * A placeholder CSS comment is added to the inline style in order to force an inline STYLE tag to 3798 * be printed. Now that we've located the inline style, the placeholder comment can be removed. If 3799 * there is no CSS left in the STYLE tag after removing the placeholder (aside from the sourceURL 3800 * comment, then remove the STYLE entirely.) 3801 */ 3802 $css_text = str_replace( $placeholder, '', $css_text ); 3803 if ( preg_match( ':^/\*# sourceURL=\S+? \*/$:', trim( $css_text ) ) ) { 3804 $processor->remove(); 3805 } else { 3806 $processor->set_modifiable_text( $css_text ); 3716 3807 } 3717 3808 3718 // Remove the placeholder now that we've located the inline style.3719 $processor->set_modifiable_text( str_replace( $placeholder, '', $css_text ) );3720 $buffer = $processor->get_updated_html();3721 3722 3809 // Insert the $printed_late_styles immediately after the closing inline STYLE tag. This preserves the CSS cascade. 3723 $span = $processor->get_span(); 3724 $buffer = implode( 3725 '', 3726 array( 3727 substr( $buffer, 0, $span->start + $span->length ), 3728 $printed_late_styles, 3729 substr( $buffer, $span->start + $span->length ), 3730 ) 3731 ); 3732 break; 3733 } 3734 3735 // As a fallback, append the hoisted late styles to the end of the HEAD. 3736 if ( $processor->is_tag_closer() && 'HEAD' === $processor->get_tag() ) { 3737 $span = $processor->get_span(); 3738 $buffer = implode( 3739 '', 3740 array( 3741 substr( $buffer, 0, $span->start ), 3742 $printed_late_styles, 3743 substr( $buffer, $span->start ), 3744 ) 3745 ); 3810 if ( '' !== $printed_block_styles ) { 3811 $processor->insert_after( $printed_block_styles ); 3812 3813 // Prevent printing them again at </head>. 3814 $printed_block_styles = ''; 3815 } 3816 3817 // If there aren't any late styles, there's no need to continue to finding </head>. 3818 if ( '' === $printed_late_styles ) { 3819 break; 3820 } 3821 } elseif ( 'HEAD' === $processor->get_tag() && $processor->is_tag_closer() ) { 3822 $processor->insert_before( $printed_block_styles . $printed_late_styles ); 3746 3823 break; 3747 3824 } 3748 3825 } 3749 3826 3750 return $ buffer;3827 return $processor->get_updated_html(); 3751 3828 } 3752 3829 );
Note: See TracChangeset
for help on using the changeset viewer.