-
Notifications
You must be signed in to change notification settings - Fork 3.3k
#64099: Improve hoisted stylesheet ordering #10436
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Closed
westonruter
wants to merge
56
commits into
WordPress:trunk
from
westonruter:trac-64099-improve-hoisted-stylesheet-ordering
Closed
Changes from 19 commits
Commits
Show all changes
56 commits
Select commit
Hold shift + click to select a range
137e732
Use well-formed HTML in tests
westonruter f5d49cd
Use HTTPS and fix late inline style contents
westonruter cccb1ef
Add separate test case specifically for filtering print_late_styles
westonruter 137b9de
Add comment for PHPCompatibility issue
westonruter 8975233
Use more specific return type for WP_Block_Type_Registry::get_all_reg…
westonruter 6308437
Remove PHPCompatibility.FunctionDeclarations.NewClosure.ThisFoundOuts…
westonruter 2d94ec6
Add a rendered block to the output
westonruter 2d537f7
Add failing test cases for test_wp_hoist_late_printed_styles
westonruter 92cd33c
Exclude PHPCompatibility.FunctionDeclarations.NewClosure.ThisFoundOut…
westonruter d5a964b
Merge branch 'trunk' of https://github.com/WordPress/wordpress-develo…
westonruter 53d21e6
Print block styles after wp-block-library and everything else at end …
westonruter 9d8bd27
Merge branch 'trunk' of https://github.com/WordPress/wordpress-develo…
westonruter 156c6f5
Add example for get_array_snapshot_export
westonruter 16d3f54
Prevent enabling should_load_block_assets_on_demand if should_load_se…
westonruter 99b1b42
Improve tests
westonruter 28faf6d
Remove obsolete print_late_styles override
westonruter d305804
Update tests
westonruter e8482a0
Add todo comments
westonruter 54b2474
Refactor HTML Tag Processor logic
westonruter d93e767
Fix missing use of footer in assertion
westonruter ec25a5f
Use correct variable in assertion
westonruter 53ef0c6
Remove unhelpful test cases since print_late_styles filter seems to h…
westonruter ead1aa2
Set styles_inline_size_limit to unlimited for test
westonruter d2afb80
Merge branch 'trunk' of https://github.com/WordPress/wordpress-develo…
westonruter 27f5e33
Opt to set styles_inline_size_limit to zero for test
westonruter 3c77325
Test that non-empty wp-block-library inline style is not removed
westonruter 12d4ae7
Consolidate assertions
westonruter 1e5797c
Fix classic_theme_with_should_load_separate_core_block_assets_opt_out…
westonruter 08f4809
Empty out added theme supports before running tests
westonruter a9a54ca
Add core-block-supports-duotone to the list of styles to print after …
westonruter c7a4c64
Improve formatting of empty array in export
westonruter a8fe022
Restore original block type registry after test
westonruter 0ad3084
Fix tests when run as part of enture test suite
westonruter e3e5b3b
Revert unrelated WP_Block_Type_Registry change
westonruter 9cc527e
Restore original_ini_config
westonruter dac85df
Remove admin-specific style printing logic
westonruter 0d65fca
Carify comments
westonruter 5d22771
Add test for when styles_inline_size_limit is unlimited
westonruter 56c35c8
Remove obsolete wp_block_styles_not_supported test
westonruter 73c5b07
Remove test for test which is not worthwhile
westonruter 2fed203
Merge branch 'trunk' of https://github.com/WordPress/wordpress-develo…
westonruter 18691a4
Replace todo with explanation of why set_bookmark will never return f…
westonruter 3f0ac52
Restore comment to _wp_footer_scripts()
westonruter 34d7573
Restore and update comment for _wp_footer_scripts()
westonruter 2524386
Add assertion to ensure wp-block-separator style is registered
westonruter fd0c402
Debug
westonruter c2fd29f
Undebug
westonruter 4447f46
Merge branch 'trunk' of https://github.com/WordPress/wordpress-develo…
westonruter 9607f0e
Opt for ignore list rather than ack list
westonruter 9b86cde
Only use placeholder comment for ensuring wp-block-library inline sty…
westonruter 9f816a3
Improve ensure_style_asset_file_created helper
westonruter b8f8d37
Merge branch 'trunk' of https://github.com/WordPress/wordpress-develo…
westonruter 0a6564e
Remove see wrappers of auto-linked function names in dev docs.
peterwilsoncc 885bddd
Add missing static to closure
westonruter 2216f14
Unimprove ensure_style_asset_file_created helper
westonruter 732b28e
Update phpcs exclusion after 885bdddd720f45ad13c920f83f1a7a19a3c7acca
westonruter File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -3607,20 +3607,23 @@ function wp_load_classic_theme_block_styles_on_demand() { | |
| // The following two filters are added by default for block themes in _add_default_theme_supports(). | ||
|
|
||
| /* | ||
| * Load separate block styles so that the large block-library stylesheet is not enqueued unconditionally, | ||
| * and so that block-specific styles will only be enqueued when they are used on the page. | ||
| * A priority of zero allows for this to be easily overridden by themes which wish to opt out. | ||
| * Load separate block styles so that the large block-library stylesheet is not enqueued unconditionally, and so | ||
| * that block-specific styles will only be enqueued when they are used on the page. A priority of zero allows for | ||
| * this to be easily overridden by themes which wish to opt out. If a site has explicitly opted out of loading | ||
| * separate block styles, then abort. | ||
| */ | ||
| add_filter( 'should_load_separate_core_block_assets', '__return_true', 0 ); | ||
| if ( ! wp_should_load_separate_core_block_assets() ) { | ||
| return; | ||
| } | ||
|
|
||
| /* | ||
| * Also ensure that block assets are loaded on demand (although the default value is from should_load_separate_core_block_assets). | ||
| * As above, a priority of zero allows for this to be easily overridden by themes which wish to opt out. | ||
| * As above, a priority of zero allows for this to be easily overridden by themes which wish to opt out. If a site | ||
| * has explicitly opted out of loading block styles on demand, then abort. | ||
| */ | ||
| add_filter( 'should_load_block_assets_on_demand', '__return_true', 0 ); | ||
|
|
||
| // If a site has explicitly opted out of loading block styles on demand via filters with priorities higher than above, then abort. | ||
| if ( ! wp_should_load_separate_core_block_assets() || ! wp_should_load_block_assets_on_demand() ) { | ||
| if ( ! wp_should_load_block_assets_on_demand() ) { | ||
| return; | ||
| } | ||
|
|
||
|
|
@@ -3642,15 +3645,6 @@ function wp_hoist_late_printed_styles() { | |
| return; | ||
| } | ||
|
|
||
| /* | ||
| * While normally late styles are printed, there is a filter to disable prevent this, so this makes sure they are | ||
| * printed. Note that this filter was intended to control whether to print the styles queued too late for the HTML | ||
| * head. This filter was introduced in <https://core.trac.wordpress.org/ticket/9346>. However, with the template | ||
| * enhancement output buffer, essentially no style can be enqueued too late, because an output buffer filter can | ||
| * always hoist it to the HEAD. | ||
| */ | ||
| add_filter( 'print_late_styles', '__return_true', PHP_INT_MAX ); | ||
|
|
||
| /* | ||
| * Print a placeholder comment where the late styles can be hoisted from the footer to be printed in the header | ||
| * by means of a filter below on the template enhancement output buffer. | ||
|
|
@@ -3660,11 +3654,44 @@ function wp_hoist_late_printed_styles() { | |
| wp_add_inline_style( 'wp-block-library', $placeholder ); | ||
|
|
||
| // Wrap print_late_styles() with a closure that captures the late-printed styles. | ||
| $printed_late_styles = ''; | ||
| $capture_late_styles = static function () use ( &$printed_late_styles ) { | ||
| $printed_block_styles = ''; | ||
| $printed_late_styles = ''; | ||
| $capture_late_styles = static function () use ( &$printed_block_styles, &$printed_late_styles ) { | ||
| global $concatenate_scripts; | ||
| script_concat_settings(); | ||
|
|
||
| // Print the styles related to on-demand block enqueues. | ||
| $all_block_style_handles = array(); | ||
| foreach ( WP_Block_Type_Registry::get_instance()->get_all_registered() as $block_type ) { | ||
| foreach ( $block_type->style_handles as $style_handle ) { | ||
| $all_block_style_handles[] = $style_handle; | ||
| } | ||
| } | ||
| $all_block_style_handles = array_merge( | ||
| $all_block_style_handles, | ||
| array( 'global-styles', 'core-block-supports', 'block-style-variation-styles' ) // TODO: What else? | ||
| ); | ||
|
|
||
| $enqueued_block_styles = array_values( array_intersect( $all_block_style_handles, wp_styles()->queue ) ); | ||
| if ( count( $enqueued_block_styles ) > 0 ) { | ||
| wp_styles()->do_concat = $concatenate_scripts; | ||
| ob_start(); | ||
| wp_styles()->do_items( $enqueued_block_styles ); | ||
| _print_styles(); // TODO: Is this needed? | ||
| $printed_block_styles = ob_get_clean(); | ||
| wp_styles()->reset(); | ||
| } | ||
|
|
||
| /* | ||
| * Print remaining styles not related to blocks. This is the same logic as in print_late_styles(), but without | ||
| * the filter to control whether late styles are printed (since they are being hoisted anyway). | ||
| */ | ||
| wp_styles()->do_concat = $concatenate_scripts; | ||
| ob_start(); | ||
| print_late_styles(); | ||
| wp_styles()->do_footer_items(); | ||
| _print_styles(); // TODO: Is this needed? | ||
| $printed_late_styles = ob_get_clean(); | ||
| wp_styles()->reset(); | ||
| }; | ||
|
|
||
| /* | ||
|
|
@@ -3695,65 +3722,76 @@ static function () use ( $capture_late_styles ) { | |
| // Replace placeholder with the captured late styles. | ||
| add_filter( | ||
| 'wp_template_enhancement_output_buffer', | ||
| function ( $buffer ) use ( $placeholder, &$printed_late_styles ) { | ||
| function ( $buffer ) use ( $placeholder, &$printed_block_styles, &$printed_late_styles ) { | ||
|
|
||
| // Anonymous subclass of WP_HTML_Tag_Processor which exposes underlying bookmark spans. | ||
| $processor = new class( $buffer ) extends WP_HTML_Tag_Processor { | ||
| public function get_span(): WP_HTML_Span { | ||
| $instance = $this; // phpcs:ignore PHPCompatibility.FunctionDeclarations.NewClosure.ThisFoundOutsideClass -- It is inside an anonymous class. | ||
| $instance->set_bookmark( 'here' ); | ||
| return $instance->bookmarks['here']; | ||
| /** | ||
| * Gets the span for the current token. | ||
| * | ||
| * @return WP_HTML_Span Current token span. | ||
| */ | ||
| private function get_span(): WP_HTML_Span { | ||
| $this->set_bookmark( 'here' ); // TODO: What if this fails? | ||
| return $this->bookmarks['here']; | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. so much better with the removal of the additional surprising complexity! |
||
| } | ||
|
|
||
| /** | ||
| * Inserts text before the current token. | ||
| * | ||
| * @param string $text Text to insert. | ||
| */ | ||
| public function insert_before( string $text ) { | ||
| $this->lexical_updates[] = new WP_HTML_Text_Replacement( $this->get_span()->start, 0, $text ); | ||
| } | ||
|
|
||
| /** | ||
| * Inserts text after the current token. | ||
| * | ||
| * @param string $text Text to insert. | ||
| */ | ||
| public function insert_after( string $text ) { | ||
| $span = $this->get_span(); | ||
|
|
||
| $this->lexical_updates[] = new WP_HTML_Text_Replacement( $span->start + $span->length, 0, $text ); | ||
| } | ||
| }; | ||
|
|
||
| // Loop over STYLE tags. | ||
| // TODO: If there are no block styles to print, it would be nice to not have to replace the placeholder comment. | ||
| // Insert block styles right after wp-block-library (if it is present), and then insert any remaining styles at </head>. | ||
| while ( $processor->next_tag( array( 'tag_closers' => 'visit' ) ) ) { | ||
|
|
||
| // We've encountered the inline style for the 'wp-block-library' stylesheet which probably has the placeholder comment. | ||
| if ( | ||
| ! $processor->is_tag_closer() && | ||
| 'STYLE' === $processor->get_tag() && | ||
| 'wp-block-library-inline-css' === $processor->get_attribute( 'id' ) | ||
| ) { | ||
| // If the inline style lacks the placeholder comment, then we have to continue until we get to </HEAD> to append the styles there. | ||
| // If the inline style lacks the placeholder comment, then all the styles will be inserted below at </head>. | ||
| $css_text = $processor->get_modifiable_text(); | ||
| if ( ! str_contains( $css_text, $placeholder ) ) { | ||
| continue; | ||
| } | ||
|
|
||
| // Remove the placeholder now that we've located the inline style. | ||
| $processor->set_modifiable_text( str_replace( $placeholder, '', $css_text ) ); | ||
| $buffer = $processor->get_updated_html(); | ||
|
|
||
| // Insert the $printed_late_styles immediately after the closing inline STYLE tag. This preserves the CSS cascade. | ||
| $span = $processor->get_span(); | ||
| $buffer = implode( | ||
| '', | ||
| array( | ||
| substr( $buffer, 0, $span->start + $span->length ), | ||
| $printed_late_styles, | ||
| substr( $buffer, $span->start + $span->length ), | ||
| ) | ||
| ); | ||
| break; | ||
| } | ||
| if ( '' !== $printed_block_styles ) { | ||
| $processor->insert_after( $printed_block_styles ); | ||
|
|
||
| // As a fallback, append the hoisted late styles to the end of the HEAD. | ||
| if ( $processor->is_tag_closer() && 'HEAD' === $processor->get_tag() ) { | ||
| $span = $processor->get_span(); | ||
| $buffer = implode( | ||
| '', | ||
| array( | ||
| substr( $buffer, 0, $span->start ), | ||
| $printed_late_styles, | ||
| substr( $buffer, $span->start ), | ||
| ) | ||
| ); | ||
| // Prevent printing them again at </head>. | ||
| $printed_block_styles = ''; | ||
| } | ||
|
|
||
| // If there aren't any late styles, there's no need to continue to finding </head>. | ||
| if ( '' === $printed_late_styles ) { | ||
| break; | ||
| } | ||
| } elseif ( 'HEAD' === $processor->get_tag() && $processor->is_tag_closer() ) { | ||
| $processor->insert_before( $printed_block_styles . $printed_late_styles ); | ||
| break; | ||
| } | ||
| } | ||
|
|
||
| return $buffer; | ||
| return $processor->get_updated_html(); | ||
| } | ||
| ); | ||
| } | ||
|
|
||
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@dmsnell How does this updated
WP_HTML_Tag_Processorextension look here? Note theinsert_beforeandinsert_aftermethods.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
And now a
reviewmethod as well.