Changeset 61945
- Timestamp:
- 03/11/2026 08:56:01 PM (3 weeks ago)
- Location:
- trunk
- Files:
-
- 2 edited
-
src/wp-includes/script-loader.php (modified) (15 diffs)
-
tests/phpunit/tests/template.php (modified) (33 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/wp-includes/script-loader.php
r61703 r61945 2552 2552 $is_classic_theme = ! $is_block_theme; 2553 2553 2554 /* 2555 * Global styles should be printed in the head for block themes, or for classic themes when loading assets on 2556 * demand is disabled, which is the default. 2557 * The footer should only be used for classic themes when loading assets on demand is enabled. 2554 /** 2555 * Global styles should be printed in the HEAD for block themes, or for classic themes when loading assets on 2556 * demand is disabled (which is no longer the default since WordPress 6.9). 2558 2557 * 2559 * See https://core.trac.wordpress.org/ticket/53494 and https://core.trac.wordpress.org/ticket/61965. 2558 * @link https://core.trac.wordpress.org/ticket/53494 2559 * @link https://core.trac.wordpress.org/ticket/61965 2560 2560 */ 2561 2561 if ( 2562 ( $is_block_theme && doing_action( 'wp_footer' ) ) || 2563 ( $is_classic_theme && doing_action( 'wp_footer' ) && ! $assets_on_demand ) || 2564 ( $is_classic_theme && doing_action( 'wp_enqueue_scripts' ) && $assets_on_demand ) 2562 doing_action( 'wp_footer' ) && 2563 ( 2564 $is_block_theme || 2565 ( $is_classic_theme && ! $assets_on_demand ) 2566 ) 2565 2567 ) { 2568 return; 2569 } 2570 2571 /** 2572 * The footer should only be used for classic themes when loading assets on demand is enabled. In WP 6.9 this is the 2573 * default with the introduction of hoisting late-printed styles (via {@see wp_load_classic_theme_block_styles_on_demand()}). 2574 * So even though the main global styles are not printed here in the HEAD for classic themes with on-demand asset 2575 * loading, a placeholder for the global styles is still enqueued. Then when {@see wp_hoist_late_printed_styles()} 2576 * processes the output buffer, it can locate the placeholder and inject the global styles from the footer into the 2577 * HEAD, replacing the placeholder. 2578 * 2579 * @link https://core.trac.wordpress.org/ticket/64099 2580 */ 2581 if ( $is_classic_theme && doing_action( 'wp_enqueue_scripts' ) && $assets_on_demand ) { 2582 if ( has_action( 'wp_template_enhancement_output_buffer_started', 'wp_hoist_late_printed_styles' ) ) { 2583 wp_register_style( 'wp-global-styles-placeholder', false ); 2584 wp_add_inline_style( 'wp-global-styles-placeholder', ':root { --wp-internal-comment: "Placeholder for wp_hoist_late_printed_styles() to replace with the global-styles printed at wp_footer." }' ); 2585 wp_enqueue_style( 'wp-global-styles-placeholder' ); 2586 } 2566 2587 return; 2567 2588 } … … 2742 2763 function wp_enqueue_registered_block_scripts_and_styles() { 2743 2764 if ( wp_should_load_block_assets_on_demand() ) { 2765 /** 2766 * Add placeholder for where block styles would historically get enqueued in a classic theme when block assets 2767 * are not loaded on demand. This happens right after {@see wp_common_block_scripts_and_styles()} is called 2768 * at which time wp-block-library is enqueued. 2769 */ 2770 if ( ! wp_is_block_theme() && has_action( 'wp_template_enhancement_output_buffer_started', 'wp_hoist_late_printed_styles' ) ) { 2771 wp_register_style( 'wp-block-styles-placeholder', false ); 2772 wp_add_inline_style( 'wp-block-styles-placeholder', ':root { --wp-internal-comment: "Placeholder for wp_hoist_late_printed_styles() to replace with the block styles printed at wp_footer." }' ); 2773 wp_enqueue_style( 'wp-block-styles-placeholder' ); 2774 } 2744 2775 return; 2745 2776 } … … 3701 3732 * @see _wp_footer_scripts() 3702 3733 */ 3703 function wp_hoist_late_printed_styles() {3734 function wp_hoist_late_printed_styles(): void { 3704 3735 // Skip the embed template on-demand styles aren't relevant, and there is no wp_head action. 3705 3736 if ( is_embed() ) { … … 3707 3738 } 3708 3739 3709 // Capture the styles enqueued at the enqueue_block_assets action, so that non-core block styles and global styles can be inserted afterwards during hoisting.3710 $style_handles_at_enqueue_block_assets = array();3711 add_action(3712 'enqueue_block_assets',3713 static function () use ( &$style_handles_at_enqueue_block_assets ) {3714 $style_handles_at_enqueue_block_assets = wp_styles()->queue;3715 },3716 PHP_INT_MIN3717 );3718 add_action(3719 'enqueue_block_assets',3720 static function () use ( &$style_handles_at_enqueue_block_assets ) {3721 $style_handles_at_enqueue_block_assets = array_values( array_diff( wp_styles()->queue, $style_handles_at_enqueue_block_assets ) );3722 },3723 PHP_INT_MAX3724 );3725 3726 3740 /* 3727 3741 * Add a placeholder comment into the inline styles for wp-block-library, after which the late block styles 3728 3742 * can be hoisted from the footer to be printed in the header by means of a filter below on the template enhancement 3729 * output buffer. The `wp_print_styles` action is used to ensure that if the inline style gets replaced at 3730 * `enqueue_block_assets` or `wp_enqueue_scripts` that the placeholder will be sure to be present. 3743 * output buffer. 3744 * 3745 * Note that wp_maybe_inline_styles() prepends the inlined style to the extra 'after' array, which happens after 3746 * this code runs. This ensures that the placeholder appears right after any inlined wp-block-library styles, 3747 * which would be common.css. 3731 3748 */ 3732 3749 $placeholder = sprintf( '/*%s*/', uniqid( 'wp_block_styles_on_demand_placeholder:' ) ); 3733 add_action(3734 'wp_print_styles',3735 static function () use ( $placeholder) {3750 $dependency = wp_styles()->query( 'wp-block-library', 'registered' ); 3751 if ( $dependency ) { 3752 if ( ! isset( $dependency->extra['after'] ) ) { 3736 3753 wp_add_inline_style( 'wp-block-library', $placeholder ); 3737 } 3738 ); 3754 } else { 3755 array_unshift( $dependency->extra['after'], $placeholder ); 3756 } 3757 } 3739 3758 3740 3759 /* … … 3766 3785 3767 3786 /* 3768 * First print all styles related to blocks which should be inserted right after the wp-block-library stylesheet3787 * First print all styles related to core blocks which should be inserted right after the wp-block-library stylesheet 3769 3788 * to preserve the CSS cascade. The logic in this `if` statement is derived from `wp_print_styles()`. 3770 3789 */ … … 3773 3792 ob_start(); 3774 3793 wp_styles()->do_items( $enqueued_core_block_styles ); 3775 $printed_core_block_styles = ob_get_clean();3776 } 3777 3778 // Non-core block styles get printed after the classic-theme-styles stylesheet.3794 $printed_core_block_styles = (string) ob_get_clean(); 3795 } 3796 3797 // Capture non-core block styles so they can get printed at the point where wp_enqueue_registered_block_scripts_and_styles() runs. 3779 3798 $enqueued_other_block_styles = array_values( array_intersect( $all_other_block_style_handles, wp_styles()->queue ) ); 3780 3799 if ( count( $enqueued_other_block_styles ) > 0 ) { 3781 3800 ob_start(); 3782 3801 wp_styles()->do_items( $enqueued_other_block_styles ); 3783 $printed_other_block_styles = ob_get_clean();3784 } 3785 3786 // Capture the global-styles so that it can be printed separately after classic-theme-styles and other styles enqueued at enqueue_block_assets.3802 $printed_other_block_styles = (string) ob_get_clean(); 3803 } 3804 3805 // Capture the global-styles so that it can be printed at the point where wp_enqueue_global_styles() runs. 3787 3806 if ( wp_style_is( 'global-styles' ) ) { 3788 3807 ob_start(); 3789 3808 wp_styles()->do_items( array( 'global-styles' ) ); 3790 $printed_global_styles = ob_get_clean();3809 $printed_global_styles = (string) ob_get_clean(); 3791 3810 } 3792 3811 … … 3798 3817 ob_start(); 3799 3818 wp_styles()->do_footer_items(); 3800 $printed_late_styles = ob_get_clean();3819 $printed_late_styles = (string) ob_get_clean(); 3801 3820 }; 3802 3821 … … 3829 3848 add_filter( 3830 3849 'wp_template_enhancement_output_buffer', 3831 static function ( $buffer ) use ( $placeholder, &$ style_handles_at_enqueue_block_assets, &$printed_core_block_styles, &$printed_other_block_styles, &$printed_global_styles, &$printed_late_styles ) {3850 static function ( $buffer ) use ( $placeholder, &$printed_core_block_styles, &$printed_other_block_styles, &$printed_global_styles, &$printed_late_styles ) { 3832 3851 3833 3852 // Anonymous subclass of WP_HTML_Tag_Processor which exposes underlying bookmark spans. … … 3849 3868 * @param string $text Text to insert. 3850 3869 */ 3851 public function insert_before( string $text ) {3870 public function insert_before( string $text ): void { 3852 3871 $this->lexical_updates[] = new WP_HTML_Text_Replacement( $this->get_span()->start, 0, $text ); 3853 3872 } … … 3858 3877 * @param string $text Text to insert. 3859 3878 */ 3860 public function insert_after( string $text ) {3879 public function insert_after( string $text ): void { 3861 3880 $span = $this->get_span(); 3862 3881 … … 3867 3886 * Removes the current token. 3868 3887 */ 3869 public function remove() {3888 public function remove(): void { 3870 3889 $span = $this->get_span(); 3871 3890 3872 3891 $this->lexical_updates[] = new WP_HTML_Text_Replacement( $span->start, $span->length, '' ); 3892 } 3893 3894 /** 3895 * Replaces the current token. 3896 * 3897 * @param string $text Text to replace with. 3898 */ 3899 public function replace( string $text ): void { 3900 $span = $this->get_span(); 3901 3902 $this->lexical_updates[] = new WP_HTML_Text_Replacement( $span->start, $span->length, $text ); 3873 3903 } 3874 3904 }; … … 3878 3908 if ( 3879 3909 'STYLE' === $processor->get_tag() && 3910 'wp-global-styles-placeholder-inline-css' === $processor->get_attribute( 'id' ) 3911 ) { 3912 /** This is added in {@see wp_enqueue_global_styles()} */ 3913 $processor->set_bookmark( 'wp_global_styles_placeholder' ); 3914 } elseif ( 3915 'STYLE' === $processor->get_tag() && 3916 'wp-block-styles-placeholder-inline-css' === $processor->get_attribute( 'id' ) 3917 ) { 3918 /** This is added in {@see wp_enqueue_registered_block_scripts_and_styles()} */ 3919 $processor->set_bookmark( 'wp_block_styles_placeholder' ); 3920 } elseif ( 3921 'STYLE' === $processor->get_tag() && 3880 3922 'wp-block-library-inline-css' === $processor->get_attribute( 'id' ) 3881 3923 ) { 3924 /** This is added here in {@see wp_hoist_late_printed_styles()} */ 3882 3925 $processor->set_bookmark( 'wp_block_library' ); 3883 3926 } elseif ( 'HEAD' === $processor->get_tag() && $processor->is_tag_closer() ) { 3884 3927 $processor->set_bookmark( 'head_end' ); 3885 3928 break; 3886 } elseif ( ( 'STYLE' === $processor->get_tag() || 'LINK' === $processor->get_tag() ) && $processor->get_attribute( 'id' ) ) {3887 $id = $processor->get_attribute( 'id' );3888 $handle = null;3889 if ( 'STYLE' === $processor->get_tag() ) {3890 if ( preg_match( '/^(.+)-inline-css$/', $id, $matches ) ) {3891 $handle = $matches[1];3892 }3893 } elseif ( preg_match( '/^(.+)-css$/', $id, $matches ) ) {3894 $handle = $matches[1];3895 }3896 3897 if ( 'classic-theme-styles' === $handle ) {3898 $processor->set_bookmark( 'classic_theme_styles' );3899 }3900 3901 if ( $handle && in_array( $handle, $style_handles_at_enqueue_block_assets, true ) ) {3902 if ( ! $processor->has_bookmark( 'first_style_at_enqueue_block_assets' ) ) {3903 $processor->set_bookmark( 'first_style_at_enqueue_block_assets' );3904 }3905 $processor->set_bookmark( 'last_style_at_enqueue_block_assets' );3906 }3907 3929 } 3930 } 3931 3932 /** 3933 * Replace the placeholder for global styles enqueued during {@see wp_enqueue_global_styles()}. This is done 3934 * even if $printed_global_styles is empty. 3935 */ 3936 if ( $processor->has_bookmark( 'wp_global_styles_placeholder' ) ) { 3937 $processor->seek( 'wp_global_styles_placeholder' ); 3938 $processor->replace( $printed_global_styles ); 3939 $printed_global_styles = ''; 3908 3940 } 3909 3941 … … 3922 3954 3923 3955 /* 3924 * A placeholder CSS comment is added to the inline style in order to force an inline STYLE tag to 3925 * be printed. Now that we've located the inline style, the placeholder comment can be removed. If 3926 * there is no CSS left in the STYLE tag after removing the placeholder (aside from the sourceURL 3927 * comment), then remove the STYLE entirely. 3956 * Split the block library inline style by the placeholder to identify the original inlined CSS, which 3957 * likely would be common.css, followed by any inline styles which had been added by the theme or 3958 * plugins via `wp_add_inline_style( 'wp-block-library', '...' )`. The separate block styles loaded on 3959 * demand will get inserted after the inlined common.css and before the extra inline styles added by the 3960 * user. 3928 3961 */ 3929 $css_text = str_replace( $placeholder, '', $css_text ); 3930 if ( preg_match( ':^/\*# sourceURL=\S+? \*/$:', trim( $css_text ) ) ) { 3962 $css_text_around_placeholder = explode( $placeholder, $css_text, 2 ); 3963 $extra_inline_styles = ''; 3964 if ( count( $css_text_around_placeholder ) === 2 ) { 3965 $css_text = $css_text_around_placeholder[0]; 3966 if ( '' !== trim( $css_text ) ) { 3967 $inlined_src = wp_styles()->get_data( 'wp-block-library', 'inlined_src' ); 3968 if ( $inlined_src ) { 3969 $css_text .= sprintf( 3970 "\n/*# sourceURL=%s */\n", 3971 esc_url_raw( $inlined_src ) 3972 ); 3973 } 3974 } 3975 $extra_inline_styles = $css_text_around_placeholder[1]; 3976 } 3977 3978 /* 3979 * The placeholder CSS comment was added to the inline style in order to force an inline STYLE tag to 3980 * be printed. Now that the inline style has been located and the placeholder comment has been removed, if 3981 * there is no CSS left in the STYLE tag after removal, then remove the STYLE tag entirely. 3982 */ 3983 if ( '' === trim( $css_text ) ) { 3931 3984 $processor->remove(); 3932 3985 } else { … … 3937 3990 $printed_core_block_styles = ''; 3938 3991 3939 // If the classic-theme-styles is absent, then the third-party block styles cannot be inserted after it, so they get inserted here. 3940 if ( ! $processor->has_bookmark( 'classic_theme_styles' ) ) { 3941 if ( '' !== $printed_other_block_styles ) { 3942 $inserted_after .= $printed_other_block_styles; 3943 } 3944 $printed_other_block_styles = ''; 3945 3946 // If there aren't any other styles printed at enqueue_block_assets either, then the global styles need to also be printed here. 3947 if ( ! $processor->has_bookmark( 'last_style_at_enqueue_block_assets' ) ) { 3948 if ( '' !== $printed_global_styles ) { 3949 $inserted_after .= $printed_global_styles; 3950 } 3951 $printed_global_styles = ''; 3952 } 3992 /* 3993 * Add a new inline style for any user styles added via wp_add_inline_style( 'wp-block-library', '...' ). 3994 * This must be added here after $printed_core_block_styles to preserve the original CSS cascade when 3995 * the combined block library stylesheet was used. The pattern here is checking to see if it is not just 3996 * a sourceURL comment after the placeholder above is removed. 3997 */ 3998 if ( ! preg_match( ':^\s*(/\*# sourceURL=\S+? \*/\s*)?$:s', $extra_inline_styles ) ) { 3999 $style_processor = new WP_HTML_Tag_Processor( '<style></style>' ); 4000 $style_processor->next_tag(); 4001 $style_processor->set_attribute( 'id', 'wp-block-library-inline-css-extra' ); 4002 $style_processor->set_modifiable_text( $extra_inline_styles ); 4003 $inserted_after .= "{$style_processor->get_updated_html()}\n"; 3953 4004 } 3954 4005 … … 3958 4009 } 3959 4010 3960 // Insert global-styles after the styles enqueued at enqueue_block_assets. 3961 if ( '' !== $printed_global_styles && $processor->has_bookmark( 'last_style_at_enqueue_block_assets' ) ) { 3962 $processor->seek( 'last_style_at_enqueue_block_assets' ); 3963 3964 $processor->insert_after( "\n" . $printed_global_styles ); 3965 $printed_global_styles = ''; 3966 3967 if ( ! $processor->has_bookmark( 'classic_theme_styles' ) && '' !== $printed_other_block_styles ) { 3968 $processor->insert_after( "\n" . $printed_other_block_styles ); 3969 $printed_other_block_styles = ''; 4011 // Insert block styles at the point where wp_enqueue_registered_block_scripts_and_styles() normally enqueues styles. 4012 if ( $processor->has_bookmark( 'wp_block_styles_placeholder' ) ) { 4013 $processor->seek( 'wp_block_styles_placeholder' ); 4014 if ( '' !== $printed_other_block_styles ) { 4015 $processor->replace( "\n" . $printed_other_block_styles ); 4016 } else { 4017 $processor->remove(); 3970 4018 } 3971 }3972 3973 // Insert third-party block styles right after the classic-theme-styles.3974 if ( '' !== $printed_other_block_styles && $processor->has_bookmark( 'classic_theme_styles' ) ) {3975 $processor->seek( 'classic_theme_styles' );3976 $processor->insert_after( "\n" . $printed_other_block_styles );3977 4019 $printed_other_block_styles = ''; 3978 4020 } -
trunk/tests/phpunit/tests/template.php
r61668 r61945 152 152 } 153 153 154 unset( $GLOBALS['_wp_tests_development_mode'] ); 154 155 parent::tear_down(); 155 156 } … … 1478 1479 * Data provider. 1479 1480 * 1480 * @return array<string, array{set_up: Closure|null, inline_size_limit: int, expected_styles: array{ HEAD: string[], BODY: string[] }}> 1481 * @return array<string, array{ 1482 * set_up: Closure|null, 1483 * content: string, 1484 * inline_size_limit: int, 1485 * expected_styles: array{ HEAD: string[], BODY: string[] }, 1486 * assert?: Closure( string, string ): void, 1487 * }> 1481 1488 */ 1482 1489 public function data_wp_hoist_late_printed_styles(): array { 1490 $blocks_content = '<!-- wp:separator --><hr class="wp-block-separator has-alpha-channel-opacity"/><!-- /wp:separator --><!-- wp:third-party/test --><div>This is only a test!</div><!-- /wp:third-party/test -->'; 1491 1483 1492 $early_common_styles = array( 1484 1493 'wp-img-auto-sizes-contain-inline-css', … … 1488 1497 ); 1489 1498 1490 $common_late_in_head = array(1491 // Styles enqueued at wp_enqueue_scripts (priority 10).1499 // Styles enqueued at wp_enqueue_scripts (priority 10). 1500 $common_at_wp_enqueue_scripts = array( 1492 1501 'normal-css', 1493 1502 'normal-inline-css', 1494 1495 // Styles printed at wp_head priority 10. 1503 ); 1504 1505 $common_late_in_head = array( 1506 // Styles printed at wp_head priority 101. 1496 1507 'wp-custom-css', 1497 1508 ); … … 1522 1533 'global-styles-inline-css', 1523 1534 ), 1535 $common_at_wp_enqueue_scripts, 1524 1536 $common_late_in_head, 1525 1537 $common_late_in_body … … 1529 1541 'standard_classic_theme_config_with_min_styles_inlined' => array( 1530 1542 'set_up' => null, 1543 'content' => $blocks_content, 1531 1544 'inline_size_limit' => 0, 1532 1545 'expected_styles' => array( … … 1535 1548 ), 1536 1549 ), 1550 1537 1551 'standard_classic_theme_config_with_max_styles_inlined' => array( 1538 1552 'set_up' => null, 1553 'content' => $blocks_content, 1539 1554 'inline_size_limit' => PHP_INT_MAX, 1540 1555 'expected_styles' => array( … … 1549 1564 'global-styles-inline-css', 1550 1565 ), 1566 $common_at_wp_enqueue_scripts, 1551 1567 $common_late_in_head, 1552 1568 $common_late_in_body … … 1555 1571 ), 1556 1572 ), 1573 1557 1574 'classic_theme_styles_omitted' => array( 1558 1575 'set_up' => static function () { … … 1566 1583 ); 1567 1584 }, 1585 'content' => $blocks_content, 1568 1586 'inline_size_limit' => PHP_INT_MAX, 1569 1587 'expected_styles' => array( … … 1577 1595 'global-styles-inline-css', 1578 1596 ), 1597 $common_at_wp_enqueue_scripts, 1579 1598 $common_late_in_head, 1580 1599 $common_late_in_body … … 1583 1602 ), 1584 1603 ), 1604 1585 1605 'no_styles_at_enqueued_block_assets' => array( 1586 1606 'set_up' => static function () { … … 1594 1614 ); 1595 1615 }, 1616 'content' => $blocks_content, 1596 1617 'inline_size_limit' => PHP_INT_MAX, 1597 1618 'expected_styles' => array( … … 1604 1625 'global-styles-inline-css', 1605 1626 ), 1627 $common_at_wp_enqueue_scripts, 1606 1628 $common_late_in_head, 1607 1629 $common_late_in_body … … 1610 1632 ), 1611 1633 ), 1634 1612 1635 'no_global_styles' => array( 1613 1636 'set_up' => static function () { 1614 add_filter(1615 'print_styles_array',1616 static function ( $handles ) {1617 return array_values( array_diff( $handles, array( 'global-styles' ) ));1618 }1619 );1620 },1637 $dequeue = static function () { 1638 wp_dequeue_style( 'global-styles' ); 1639 }; 1640 add_action( 'wp_enqueue_scripts', $dequeue, 1000 ); 1641 add_action( 'wp_footer', $dequeue, 2 ); 1642 }, 1643 'content' => $blocks_content, 1621 1644 'inline_size_limit' => PHP_INT_MAX, 1622 1645 'expected_styles' => array( … … 1630 1653 'custom-block-styles-css', 1631 1654 ), 1655 $common_at_wp_enqueue_scripts, 1632 1656 $common_late_in_head, 1633 1657 $common_late_in_body … … 1636 1660 ), 1637 1661 ), 1638 'standard_classic_theme_config_extra_block_library_inline_style' => array( 1662 1663 'standard_classic_theme_config_extra_block_library_inline_style_none_inlined' => array( 1639 1664 'set_up' => static function () { 1640 1665 add_action( 1641 1666 'enqueue_block_assets', 1642 1667 static function () { 1643 wp_add_inline_style( 'wp-block-library', '/* Extra CSS which prevents empty inline style containing placeholder from being removed. */' ); 1668 // Extra CSS which prevents empty inline style containing placeholder from being removed. 1669 wp_add_inline_style( 'wp-block-library', '.wp-block-separator{ outline:solid 1px lime; }' ); 1644 1670 } 1645 1671 ); 1646 1672 }, 1673 'content' => $blocks_content, 1647 1674 'inline_size_limit' => 0, 1648 1675 'expected_styles' => array( 1649 'HEAD' => ( function ( $expected_styles ) { 1650 // Insert 'wp-block-library-inline-css' right after 'wp-block-library-css'. 1651 $i = array_search( 'wp-block-library-css', $expected_styles, true ); 1652 $this->assertIsInt( $i, 'Expected wp-block-library-css to be among the styles.' ); 1653 array_splice( $expected_styles, $i + 1, 0, 'wp-block-library-inline-css' ); 1654 return $expected_styles; 1655 } )( $common_expected_head_styles ), 1676 'HEAD' => array_merge( 1677 $early_common_styles, 1678 array( 1679 'wp-block-library-css', 1680 'wp-block-separator-css', 1681 'wp-block-library-inline-css-extra', 1682 'classic-theme-styles-css', 1683 'third-party-test-block-css', 1684 'custom-block-styles-css', 1685 'global-styles-inline-css', 1686 ), 1687 $common_at_wp_enqueue_scripts, 1688 $common_late_in_head, 1689 $common_late_in_body 1690 ), 1656 1691 'BODY' => array(), 1657 1692 ), 1658 ), 1693 'assert' => function ( string $buffer, string $filtered_buffer ) { 1694 $block_separator_core_style_span = null; 1695 $block_separator_custom_style_span = null; 1696 $processor = new class( $filtered_buffer ) extends WP_HTML_Tag_Processor { 1697 public function get_span(): WP_HTML_Span { 1698 $this->set_bookmark( 'here' ); 1699 return $this->bookmarks['here']; 1700 } 1701 }; 1702 while ( $processor->next_tag() ) { 1703 if ( 1704 $processor->get_tag() === 'LINK' && 1705 $processor->get_attribute( 'rel' ) === 'stylesheet' && 1706 $processor->get_attribute( 'id' ) === 'wp-block-separator-css' 1707 ) { 1708 $block_separator_core_style_span = $processor->get_span(); 1709 } elseif ( 1710 $processor->get_tag() === 'STYLE' && 1711 $processor->get_attribute( 'id' ) === 'wp-block-library-inline-css-extra' && 1712 str_contains( $processor->get_modifiable_text(), '.wp-block-separator{ outline:solid 1px lime; }' ) 1713 ) { 1714 $block_separator_custom_style_span = $processor->get_span(); 1715 } 1716 } 1717 1718 $this->assertInstanceOf( WP_HTML_Span::class, $block_separator_core_style_span, 'Expected the block separator core style to be present.' ); 1719 $this->assertInstanceOf( WP_HTML_Span::class, $block_separator_custom_style_span, 'Expected the block separator custom style to be present.' ); 1720 $this->assertGreaterThan( $block_separator_core_style_span->start, $block_separator_custom_style_span->start, 'Expected the block separator custom style to appear after the block separator stylesheet.' ); 1721 }, 1722 ), 1723 1724 'standard_classic_theme_config_extra_block_library_inline_style_all_inlined' => array( 1725 'set_up' => static function () { 1726 add_action( 1727 'enqueue_block_assets', 1728 static function () { 1729 // Extra CSS which prevents empty inline style containing placeholder from being removed. 1730 wp_add_inline_style( 'wp-block-library', '.wp-block-separator{ outline:solid 1px lime; }' ); 1731 } 1732 ); 1733 }, 1734 'content' => $blocks_content, 1735 'inline_size_limit' => PHP_INT_MAX, 1736 'expected_styles' => array( 1737 'HEAD' => array_merge( 1738 $early_common_styles, 1739 array( 1740 'wp-block-library-inline-css', 1741 'wp-block-separator-inline-css', 1742 'wp-block-library-inline-css-extra', 1743 'classic-theme-styles-inline-css', 1744 'third-party-test-block-css', 1745 'custom-block-styles-css', 1746 'global-styles-inline-css', 1747 ), 1748 $common_at_wp_enqueue_scripts, 1749 $common_late_in_head, 1750 $common_late_in_body 1751 ), 1752 'BODY' => array(), 1753 ), 1754 'assert' => function ( string $buffer, string $filtered_buffer ) { 1755 $block_separator_inline_style_start_tag = '<style id="wp-block-separator-inline-css">'; 1756 $block_separator_custom_style = '.wp-block-separator{ outline:solid 1px lime; }'; 1757 $this->assertStringContainsString( $block_separator_inline_style_start_tag, $filtered_buffer ); 1758 $this->assertStringContainsString( $block_separator_custom_style, $filtered_buffer ); 1759 $block_separator_inline_style_position = strpos( $filtered_buffer, $block_separator_inline_style_start_tag ); 1760 $block_separator_custom_style_position = strpos( $filtered_buffer, $block_separator_custom_style ); 1761 $this->assertTrue( $block_separator_custom_style_position > $block_separator_inline_style_position, 'Expected the block separator custom style to appear after the block separator stylesheet.' ); 1762 }, 1763 ), 1764 1659 1765 'classic_theme_opt_out_separate_block_styles' => array( 1660 1766 'set_up' => static function () { 1661 1767 add_filter( 'should_load_separate_core_block_assets', '__return_false' ); 1662 1768 }, 1769 'content' => $blocks_content, 1663 1770 'inline_size_limit' => 0, 1664 1771 'expected_styles' => array( … … 1672 1779 'global-styles-inline-css', 1673 1780 ), 1781 $common_at_wp_enqueue_scripts, 1674 1782 $common_late_in_head 1675 1783 ), … … 1677 1785 ), 1678 1786 ), 1787 1679 1788 '_wp_footer_scripts_removed' => array( 1680 1789 'set_up' => static function () { 1681 1790 remove_action( 'wp_print_footer_scripts', '_wp_footer_scripts' ); 1682 1791 }, 1792 'content' => $blocks_content, 1683 1793 'inline_size_limit' => 0, 1684 1794 'expected_styles' => array( … … 1687 1797 ), 1688 1798 ), 1799 1689 1800 'wp_print_footer_scripts_removed' => array( 1690 1801 'set_up' => static function () { 1691 1802 remove_action( 'wp_footer', 'wp_print_footer_scripts', 20 ); 1692 1803 }, 1804 'content' => $blocks_content, 1693 1805 'inline_size_limit' => 0, 1694 1806 'expected_styles' => array( … … 1697 1809 ), 1698 1810 ), 1811 1699 1812 'both_actions_removed' => array( 1700 1813 'set_up' => static function () { … … 1702 1815 remove_action( 'wp_footer', 'wp_print_footer_scripts' ); 1703 1816 }, 1817 'content' => $blocks_content, 1704 1818 'inline_size_limit' => 0, 1705 1819 'expected_styles' => array( … … 1708 1822 ), 1709 1823 ), 1710 'disable_block_library' => array( 1824 1825 'disable_block_library_and_load_combined' => array( 1711 1826 'set_up' => static function () { 1712 1827 add_action( … … 1719 1834 add_filter( 'should_load_separate_core_block_assets', '__return_false' ); 1720 1835 }, 1836 'content' => $blocks_content, 1721 1837 'inline_size_limit' => 0, 1722 1838 'expected_styles' => array( … … 1729 1845 'global-styles-inline-css', 1730 1846 ), 1847 $common_at_wp_enqueue_scripts, 1731 1848 $common_late_in_head 1732 1849 ), … … 1734 1851 ), 1735 1852 ), 1736 'override_block_library_inline_style_late' => array( 1853 1854 // This tests the Elementor scenario (e.g. Hello Elementor). 1855 'dequeue_block_library_but_with_theme_json_and_no_block_content' => array( 1737 1856 'set_up' => static function () { 1738 1857 add_action( 1739 'enqueue_block_assets', 1740 function (): void { 1741 // This tests what happens when the placeholder comment gets replaced unexpectedly. 1742 wp_styles()->registered['wp-block-library']->extra['after'] = array( '/* OVERRIDDEN! */' ); 1743 } 1858 'wp_enqueue_scripts', 1859 static function () { 1860 wp_dequeue_style( 'wp-block-library' ); 1861 wp_dequeue_style( 'wp-block-library-theme' ); 1862 wp_dequeue_style( 'custom-block-styles' ); 1863 }, 1864 999 1744 1865 ); 1745 }, 1866 1867 /* 1868 * Simulate the theme having a theme.json so that 'classic-theme-styles' is not enqueued. Note that 1869 * when 'classic-theme-styles' is present, then 'global-styles' gets inserted after it by 1870 * wp_hoist_late_printed_styles(). So by omitting 'classic-theme-styles', this can verify that 1871 * 'global-styles' is still printed before other styles. 1872 */ 1873 $GLOBALS['_wp_tests_development_mode'] = 'theme'; 1874 add_filter( 1875 'theme_file_path', 1876 static function ( $path, $file ) { 1877 if ( 'theme.json' === $file ) { 1878 $path = __DIR__ . '/../data/themedir1/block-theme/theme.json'; 1879 } 1880 return $path; 1881 }, 1882 10, 1883 2 1884 ); 1885 }, 1886 'content' => 'Hello World!', 1746 1887 'inline_size_limit' => 0, 1747 1888 'expected_styles' => array( … … 1749 1890 $early_common_styles, 1750 1891 array( 1751 'wp-block-library-css',1752 'wp-block-library-inline-css', // This contains the "OVERRIDDEN" text.1753 'wp-block-separator-css',1754 'classic-theme-styles-css',1755 'third-party-test-block-css',1756 'custom-block-styles-css',1757 1892 'global-styles-inline-css', 1758 1893 ), 1894 $common_at_wp_enqueue_scripts, 1759 1895 $common_late_in_head, 1760 1896 $common_late_in_body … … 1763 1899 ), 1764 1900 ), 1901 1902 // This tests the Elementor scenario but a theme.json is not present. 1903 'dequeue_block_library_but_without_theme_json_and_no_block_content' => array( 1904 'set_up' => static function () { 1905 add_action( 1906 'wp_enqueue_scripts', 1907 static function () { 1908 wp_dequeue_style( 'wp-block-library' ); 1909 wp_dequeue_style( 'wp-block-library-theme' ); 1910 wp_dequeue_style( 'custom-block-styles' ); 1911 }, 1912 999 1913 ); 1914 1915 /* 1916 * Simulate the theme NOT having a theme.json so that 'classic-theme-styles' is enqueued. 1917 */ 1918 $GLOBALS['_wp_tests_development_mode'] = 'theme'; 1919 add_filter( 1920 'theme_file_path', 1921 static function ( $path, $file ) { 1922 if ( 'theme.json' === $file ) { 1923 $path = __DIR__ . '/does-not-exist.json'; 1924 } 1925 return $path; 1926 }, 1927 10, 1928 2 1929 ); 1930 }, 1931 'content' => 'Hello World!', 1932 'inline_size_limit' => 0, 1933 'expected_styles' => array( 1934 'HEAD' => array_merge( 1935 $early_common_styles, 1936 array( 1937 'classic-theme-styles-css', 1938 'global-styles-inline-css', 1939 ), 1940 $common_at_wp_enqueue_scripts, 1941 $common_late_in_head, 1942 $common_late_in_body 1943 ), 1944 'BODY' => array(), 1945 ), 1946 ), 1765 1947 ); 1766 1948 } … … 1775 1957 * 1776 1958 * @dataProvider data_wp_hoist_late_printed_styles 1777 */ 1778 public function test_wp_hoist_late_printed_styles( ?Closure $set_up, int $inline_size_limit, array $expected_styles ): void { 1959 * 1960 * @phpstan-param array{ HEAD: string[], BODY: string[] } $expected_styles 1961 */ 1962 public function test_wp_hoist_late_printed_styles( ?Closure $set_up, string $content, int $inline_size_limit, array $expected_styles, ?Closure $assert = null ): void { 1779 1963 // `_print_emoji_detection_script()` assumes `wp-includes/js/wp-emoji-loader.js` is present: 1780 1964 self::touch( ABSPATH . WPINC . '/js/wp-emoji-loader.js' ); … … 1868 2052 1869 2053 // Simulate the_content(). 1870 $content = apply_filters( 1871 'the_content', 1872 '<!-- wp:separator --><hr class="wp-block-separator has-alpha-channel-opacity"/><!-- /wp:separator -->' . 1873 '<!-- wp:third-party/test --><div>This is only a test!</div><!-- /wp:third-party/test -->' 1874 ); 2054 $content = apply_filters( 'the_content', $content ); 1875 2055 1876 2056 // Simulate footer scripts. … … 1880 2060 $buffer = '<html lang="en"><head><meta charset="utf-8">' . $head_output . '</head><body><main>' . $content . '</main>' . $footer_output . '</body></html>'; 1881 2061 1882 $placeholder_regexp = '#/\*wp_block_styles_on_demand_placeholder:[a-f0-9]+\*/#'; 2062 $global_styles_placeholder_regexp = '#<style id="wp-global-styles-placeholder-inline-css">#'; 2063 $block_library_placeholder_regexp = '#/\*wp_block_styles_on_demand_placeholder:[a-f0-9]+\*/#'; 1883 2064 if ( has_action( 'wp_template_enhancement_output_buffer_started', 'wp_hoist_late_printed_styles' ) ) { 1884 $this->assertMatchesRegularExpression( $placeholder_regexp, $buffer, 'Expected the placeholder to be present in the buffer.' ); 2065 if ( wp_style_is( 'global-styles', 'enqueued' ) ) { 2066 $this->assertMatchesRegularExpression( $global_styles_placeholder_regexp, $buffer, 'Expected the global-styles placeholder to be present in the buffer.' ); 2067 } 2068 if ( wp_style_is( 'wp-block-library', 'enqueued' ) ) { 2069 $this->assertMatchesRegularExpression( $block_library_placeholder_regexp, $buffer, 'Expected the wp-block-library placeholder to be present in the buffer.' ); 2070 } 1885 2071 } 1886 2072 … … 1890 2076 $this->assertStringContainsString( '</head>', $filtered_buffer, 'Expected the closing HEAD tag to be in the response.' ); 1891 2077 1892 $this->assertDoesNotMatchRegularExpression( $placeholder_regexp, $filtered_buffer, 'Expected the placeholder to be removed.' ); 2078 $this->assertDoesNotMatchRegularExpression( $global_styles_placeholder_regexp, $filtered_buffer, 'Expected the global-styles placeholder to be removed.' ); 2079 $this->assertDoesNotMatchRegularExpression( $block_library_placeholder_regexp, $filtered_buffer, 'Expected the wp-block-library placeholder to be removed.' ); 1893 2080 $found_styles = array( 1894 2081 'HEAD' => array(), … … 1896 2083 ); 1897 2084 $processor = WP_HTML_Processor::create_full_parser( $filtered_buffer ); 2085 $this->assertInstanceOf( WP_HTML_Processor::class, $processor ); 1898 2086 while ( $processor->next_tag() ) { 1899 2087 $group = in_array( 'HEAD', $processor->get_breadcrumbs(), true ) ? 'HEAD' : 'BODY'; … … 1931 2119 'Expected the same styles. Snapshot: ' . self::get_array_snapshot_export( $found_subset_styles ) 1932 2120 ); 2121 2122 if ( $assert ) { 2123 $assert( $buffer, $filtered_buffer ); 2124 } 1933 2125 } 1934 2126
Note: See TracChangeset
for help on using the changeset viewer.