Skip to content
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

Enqueue block custom CSS only when block renders on the page. #58991

Merged
merged 3 commits into from Feb 28, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
59 changes: 53 additions & 6 deletions lib/class-wp-theme-json-gutenberg.php
Expand Up @@ -1284,21 +1284,68 @@ protected function process_blocks_custom_css( $css, $selector ) {
* @return string The global styles custom CSS.
*/
public function get_custom_css() {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as below: can we deprecate/remove get_custom_css, get_base_custom_css, and get_block_custom_css_nodes, get_block_custom_css, in favor of the generic functions? IMO, it's too much code for a single style property that should behave like any other (and be part of the general algorithm).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's a good point! It would be better if we didn't need as many functions, but I don't know why it was done this way in the first place. I'll look into it as a follow-up, thanks for reviewing!

// Add the global styles root CSS.
$stylesheet = $this->theme_json['styles']['css'] ?? '';
$block_custom_css = '';
$block_nodes = $this->get_block_custom_css_nodes();
foreach ( $block_nodes as $node ) {
$block_custom_css .= $this->get_block_custom_css( $node['css'], $node['selector'] );
}

return $this->get_base_custom_css() . $block_custom_css;
}

/**
* Returns the global styles base custom CSS.
*
* @since 6.6.0
*
* @return string The global styles base custom CSS.
*/
public function get_base_custom_css() {
return isset( $this->theme_json['styles']['css'] ) ? $this->theme_json['styles']['css'] : '';
}

/**
* Returns the block nodes with custom CSS.
*
* @since 6.6.0
*
* @return array The block nodes.
*/
public function get_block_custom_css_nodes() {
$block_nodes = array();

// Add the global styles block CSS.
if ( isset( $this->theme_json['styles']['blocks'] ) ) {
foreach ( $this->theme_json['styles']['blocks'] as $name => $node ) {
$custom_block_css = $this->theme_json['styles']['blocks'][ $name ]['css'] ?? null;
$custom_block_css = isset( $this->theme_json['styles']['blocks'][ $name ]['css'] )
? $this->theme_json['styles']['blocks'][ $name ]['css']
: null;
if ( $custom_block_css ) {
$selector = static::$blocks_metadata[ $name ]['selector'];
$stylesheet .= $this->process_blocks_custom_css( $custom_block_css, $selector );
$block_nodes[] = array(
'name' => $name,
'selector' => static::$blocks_metadata[ $name ]['selector'],
'css' => $custom_block_css,
);
}
}
}

return $stylesheet;
return $block_nodes;
}


Comment on lines +1335 to +1336
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: Double line break

/**
* Returns the global styles custom CSS for a single block.
*
* @since 6.6.0
*
* @param array $css The block css node.
* @param string $selector The block selector.
*
* @return string The global styles custom CSS for the block.
*/
public function get_block_custom_css( $css, $selector ) {
return $this->process_blocks_custom_css( $css, $selector );
}

/**
Expand Down
77 changes: 77 additions & 0 deletions lib/global-styles-and-settings.php
Expand Up @@ -168,6 +168,82 @@ function gutenberg_get_global_styles_custom_css() {
return $stylesheet;
}

/**
* Gets the global styles base custom CSS from theme.json.
*
* @since 6.6.0
*
* @return string The global base custom CSS.
*/
function gutenberg_get_global_styles_base_custom_css() {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we simplify further and remove this function and gutenberg_get_global_styles_custom_css in favor of gutenberg_get_global_stylesheet? The styles.custom property is still the only one that has a dedicated function.

if ( ! wp_theme_has_theme_json() ) {
return '';
}

$can_use_cached = ! WP_DEBUG;

$cache_key = 'gutenberg_get_global_styles_base_custom_css';
$cache_group = 'theme_json';
if ( $can_use_cached ) {
$cached = wp_cache_get( $cache_key, $cache_group );
if ( $cached ) {
return $cached;
}
}

$tree = WP_Theme_JSON_Resolver_Gutenberg::get_merged_data();
$stylesheet = $tree->get_base_custom_css();

if ( $can_use_cached ) {
wp_cache_set( $cache_key, $stylesheet, $cache_group );
}

return $stylesheet;
}

/**
* Adds the global styles per-block custom CSS from theme.json
* to the inline style for each block.
*
* @since 6.6.0
*
* @global WP_Styles $wp_styles
*/
function gutenberg_add_global_styles_block_custom_css() {
global $wp_styles;

if ( ! wp_theme_has_theme_json() || ! wp_should_load_separate_core_block_assets() ) {
return;
}

$tree = WP_Theme_JSON_Resolver_Gutenberg::get_merged_data();
$block_nodes = $tree->get_block_custom_css_nodes();

foreach ( $block_nodes as $metadata ) {
$block_css = $tree->get_block_custom_css( $metadata['css'], $metadata['selector'] );
ramonjd marked this conversation as resolved.
Show resolved Hide resolved

$stylesheet_handle = 'global-styles';

/**
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This needs to be /*.

A double asterisk indicates that comments are a docblock to the various parsers for developer.wordpress.org and elsewhere.

* When `wp_should_load_separate_core_block_assets()` is true, follow a similar
* logic to the one in `gutenberg_add_global_styles_for_blocks` to add the custom
* css only when the block is rendered.
*/
if ( isset( $metadata['name'] ) ) {
if ( str_starts_with( $metadata['name'], 'core/' ) ) {
$block_name = str_replace( 'core/', '', $metadata['name'] );
$block_handle = 'wp-block-' . $block_name;
if ( in_array( $block_handle, $wp_styles->queue, true ) ) {
wp_add_inline_style( $stylesheet_handle, $block_css );
}
} else {
wp_add_inline_style( $stylesheet_handle, $block_css );
}
}
}
}


/**
* Adds global style rules to the inline style for each block.
*
Expand Down Expand Up @@ -238,6 +314,7 @@ function _gutenberg_clean_theme_json_caches() {
wp_cache_delete( 'gutenberg_get_global_settings_custom', 'theme_json' );
wp_cache_delete( 'gutenberg_get_global_settings_theme', 'theme_json' );
wp_cache_delete( 'gutenberg_get_global_custom_css', 'theme_json' );
wp_cache_delete( 'gutenberg_get_global_styles_base_custom_css', 'theme_json' );
WP_Theme_JSON_Resolver_Gutenberg::clean_cached_data();
}
add_action( 'start_previewing_theme', '_gutenberg_clean_theme_json_caches' );
Expand Down
32 changes: 30 additions & 2 deletions lib/script-loader.php
Expand Up @@ -53,6 +53,35 @@ function gutenberg_enqueue_global_styles() {

// Add each block as an inline css.
gutenberg_add_global_styles_for_blocks();

/**
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As above re docblock/comment.

* Add the custom CSS for the global styles.
* Before that, dequeue the Customizer's custom CSS
* and add it before the global styles custom CSS.
*/
// Don't enqueue Customizer's custom CSS separately.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This can be move in to the existing multiline comment

remove_action( 'wp_head', 'wp_custom_css_cb', 101 );

$custom_css = wp_get_custom_css();

if ( ! wp_should_load_separate_core_block_assets() ) {
/**
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

comment v docblock, as above.

* If loading all block assets together, add both
* the base and block custom CSS at once. Else load
* the base custom CSS only, and the block custom CSS
* will be added to the inline CSS for each block in
* gutenberg_add_global_styles_block_custom_css().
*/
$custom_css .= gutenberg_get_global_styles_custom_css();
} else {
$custom_css .= gutenberg_get_global_styles_base_custom_css();
}

if ( ! empty( $custom_css ) ) {
wp_add_inline_style( 'global-styles', $custom_css );
}

gutenberg_add_global_styles_block_custom_css();
}
add_action( 'wp_enqueue_scripts', 'gutenberg_enqueue_global_styles' );
add_action( 'wp_footer', 'gutenberg_enqueue_global_styles', 1 );
Expand All @@ -63,6 +92,7 @@ function gutenberg_enqueue_global_styles() {
* @since 6.2.0
*/
function gutenberg_enqueue_global_styles_custom_css() {
_deprecated_function( __FUNCTION__, 'Gutenberg 17.8.0', 'gutenberg_enqueue_global_styles' );
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I presume we also need to add a @deprecated 6.6 Use wp_enqueue_global_styles instead PHP doc, or something along those lines.

if ( ! wp_is_block_theme() ) {
return;
}
Expand All @@ -77,8 +107,6 @@ function gutenberg_enqueue_global_styles_custom_css() {
wp_add_inline_style( 'global-styles', $custom_css );
}
}
remove_action( 'wp_enqueue_scripts', 'wp_enqueue_global_styles_custom_css' );
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't we still need to remove the wp_enqueue_global_styles_custom_css callback?

The plugin supports the latest two WordPress versions, so, assuming this is backported for 6.6, it's only when WordPress 6.7 is released that we can remove this (at that point, the plugin can assume the minimum version is 6.6, where that function is no longer relevant).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oooh good point, it'll still be in core until 6.6 so yeah, I guess it'll need removing.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually checking the CSS output on the front end, I'd expect any custom CSS styles to be duplicated with this change (because wp_enqueue_global_styles_custom_css is still being enqueued in core) but they're not 🤔 I wonder why?

add_action( 'wp_enqueue_scripts', 'gutenberg_enqueue_global_styles_custom_css' );

/**
* Function that enqueues the CSS Custom Properties coming from theme.json.
Expand Down