From 71759fcd740a195fc955ffc65a351eea82d87f75 Mon Sep 17 00:00:00 2001 From: Jonny Harris Date: Tue, 11 Jul 2023 21:07:35 +0100 Subject: [PATCH 01/20] Lazily load properties. --- src/wp-includes/block-supports/duotone.php | 4 -- src/wp-includes/class-wp-duotone.php | 55 +++++++++++++++++----- 2 files changed, 44 insertions(+), 15 deletions(-) diff --git a/src/wp-includes/block-supports/duotone.php b/src/wp-includes/block-supports/duotone.php index b7964aa47809b..8ec08f08d9f84 100644 --- a/src/wp-includes/block-supports/duotone.php +++ b/src/wp-includes/block-supports/duotone.php @@ -40,10 +40,6 @@ ) ); -// Set up metadata prior to rendering any blocks. -add_action( 'wp_loaded', array( 'WP_Duotone', 'set_global_styles_presets' ), 10 ); -add_action( 'wp_loaded', array( 'WP_Duotone', 'set_global_style_block_names' ), 10 ); - // Add classnames to blocks using duotone support. add_filter( 'render_block', array( 'WP_Duotone', 'render_duotone_support' ), 10, 2 ); diff --git a/src/wp-includes/class-wp-duotone.php b/src/wp-includes/class-wp-duotone.php index 99da521f06619..ded772d0c319c 100644 --- a/src/wp-includes/class-wp-duotone.php +++ b/src/wp-includes/class-wp-duotone.php @@ -54,7 +54,7 @@ class WP_Duotone { * * @var array */ - private static $global_styles_block_names = array(); + private static $global_styles_block_names; /** * An array of duotone filter data from global, theme, and custom presets. @@ -78,7 +78,7 @@ class WP_Duotone { * * @var array */ - private static $global_styles_presets = array(); + private static $global_styles_presets; /** * All of the duotone filter data from presets for CSS custom properties on @@ -575,7 +575,7 @@ private static function is_preset( $duotone_attr ) { $slug = self::get_slug_from_attribute( $duotone_attr ); $filter_id = self::get_filter_id( $slug ); - return array_key_exists( $filter_id, self::$global_styles_presets ); + return array_key_exists( $filter_id, self::_get_global_styles_presets() ); } /** @@ -897,7 +897,8 @@ private static function enqueue_custom_filter( $filter_id, $duotone_selector, $f * @param string $filter_value The filter CSS value. e.g. 'url(#wp-duotone-blue-orange)' or 'unset'. */ private static function enqueue_global_styles_preset( $filter_id, $duotone_selector, $filter_value ) { - if ( ! array_key_exists( $filter_id, self::$global_styles_presets ) ) { + $global_styles_presets = self::_get_global_styles_presets(); + if ( ! array_key_exists( $filter_id, $global_styles_presets ) ) { $error_message = sprintf( /* translators: %s: duotone filter ID */ __( 'The duotone id "%s" is not registered in theme.json settings' ), @@ -906,8 +907,8 @@ private static function enqueue_global_styles_preset( $filter_id, $duotone_selec _doing_it_wrong( __METHOD__, $error_message, '6.3.0' ); return; } - self::$used_global_styles_presets[ $filter_id ] = self::$global_styles_presets[ $filter_id ]; - self::enqueue_custom_filter( $filter_id, $duotone_selector, $filter_value, self::$global_styles_presets[ $filter_id ] ); + self::$used_global_styles_presets[ $filter_id ] = $global_styles_presets[ $filter_id ]; + self::enqueue_custom_filter( $filter_id, $duotone_selector, $filter_value, $global_styles_presets[ $filter_id ] ); } /** @@ -1012,6 +1013,21 @@ public static function set_global_styles_presets() { } } + /** + * Get global styles presets. + * + * @since 6.3.0 + * + * @return array + */ + private static function _get_global_styles_presets() { + if ( ! isset( self::$global_styles_presets ) ) { + self::set_global_styles_presets(); + } + + return self::$global_styles_presets; + } + /** * Scrape all block names from global styles and store in self::$global_styles_block_names. * @@ -1048,6 +1064,20 @@ public static function set_global_style_block_names() { } } + /** + * Get global style block names. + * + * @since 6.3.0 + * + * @return array + */ + private static function _get_global_style_block_names() { + if ( ! isset( self::$global_styles_block_names ) ) { + self::set_global_style_block_names(); + } + return self::$global_styles_block_names; + } + /** * Render out the duotone CSS styles and SVG. * @@ -1063,9 +1093,11 @@ public static function set_global_style_block_names() { public static function render_duotone_support( $block_content, $block ) { $duotone_selector = self::get_selector( $block['blockName'] ); + $global_styles_block_names = self::_get_global_style_block_names(); + // The block should have a duotone attribute or have duotone defined in its theme.json to be processed. $has_duotone_attribute = isset( $block['attrs']['style']['color']['duotone'] ); - $has_global_styles_duotone = array_key_exists( $block['blockName'], self::$global_styles_block_names ); + $has_global_styles_duotone = array_key_exists( $block['blockName'], $global_styles_block_names ); if ( empty( $block_content ) || @@ -1119,7 +1151,7 @@ public static function render_duotone_support( $block_content, $block ) { self::enqueue_custom_filter( $filter_id, $duotone_selector, $filter_value, $filter_data ); } } elseif ( $has_global_styles_duotone ) { - $slug = self::$global_styles_block_names[ $block['blockName'] ]; // e.g. 'blue-orange'. + $slug = $global_styles_block_names[ $block['blockName'] ]; // e.g. 'blue-orange'. $filter_id = self::get_filter_id( $slug ); // e.g. 'wp-duotone-filter-blue-orange'. $filter_value = self::get_css_var( $slug ); // e.g. 'var(--wp--preset--duotone--blue-orange)'. @@ -1198,14 +1230,15 @@ public static function output_footer_assets() { * @return array The editor settings with duotone SVGs and CSS custom properties. */ public static function add_editor_settings( $settings ) { - if ( ! empty( self::$global_styles_presets ) ) { + $global_styles_presets = self::_get_global_styles_presets(); + if ( ! empty( $global_styles_presets ) ) { if ( ! isset( $settings['styles'] ) ) { $settings['styles'] = array(); } $settings['styles'][] = array( // For the editor we can add all of the presets by default. - 'assets' => self::get_svg_definitions( self::$global_styles_presets ), + 'assets' => self::get_svg_definitions( $global_styles_presets ), // The 'svgs' type is new in 6.3 and requires the corresponding JS changes in the EditorStyles component to work. '__unstableType' => 'svgs', // These styles not generated by global styles, so this must be false or they will be stripped out in wp_get_block_editor_settings. @@ -1214,7 +1247,7 @@ public static function add_editor_settings( $settings ) { $settings['styles'][] = array( // For the editor we can add all of the presets by default. - 'css' => self::get_global_styles_presets( self::$global_styles_presets ), + 'css' => self::get_global_styles_presets( $global_styles_presets ), // This must be set and must be something other than 'theme' or they will be stripped out in the post editor component. '__unstableType' => 'presets', // These styles are no longer generated by global styles, so this must be false or they will be stripped out in wp_get_block_editor_settings. From ffbf037a546e2ac6333214deafa1465f02f98bbe Mon Sep 17 00:00:00 2001 From: Jonny Harris Date: Tue, 11 Jul 2023 21:19:05 +0100 Subject: [PATCH 02/20] More refactors. --- src/wp-includes/class-wp-duotone.php | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/src/wp-includes/class-wp-duotone.php b/src/wp-includes/class-wp-duotone.php index ded772d0c319c..801b81fc21aa4 100644 --- a/src/wp-includes/class-wp-duotone.php +++ b/src/wp-includes/class-wp-duotone.php @@ -1004,6 +1004,7 @@ public static function set_global_styles_presets() { $tree = wp_get_global_settings(); $presets_by_origin = _wp_array_get( $tree, array( 'color', 'duotone' ), array() ); + self::$global_styles_presets = array(); foreach ( $presets_by_origin as $presets ) { foreach ( $presets as $preset ) { $filter_id = self::get_filter_id( _wp_to_kebab_case( $preset['slug'] ) ); @@ -1042,6 +1043,8 @@ public static function set_global_style_block_names() { $block_nodes = $tree->get_styles_block_nodes(); $theme_json = $tree->get_raw_data(); + self::$global_styles_block_names = array(); + foreach ( $block_nodes as $block_node ) { // This block definition doesn't include any duotone settings. Skip it. if ( empty( $block_node['duotone'] ) ) { @@ -1091,19 +1094,22 @@ private static function _get_global_style_block_names() { * @return string Filtered block content. */ public static function render_duotone_support( $block_content, $block ) { + if ( empty( $block_content ) ) { + return $block_content; + } $duotone_selector = self::get_selector( $block['blockName'] ); + if ( ! $duotone_selector ) { + return $block_content; + } + $global_styles_block_names = self::_get_global_style_block_names(); // The block should have a duotone attribute or have duotone defined in its theme.json to be processed. $has_duotone_attribute = isset( $block['attrs']['style']['color']['duotone'] ); $has_global_styles_duotone = array_key_exists( $block['blockName'], $global_styles_block_names ); - if ( - empty( $block_content ) || - ! $duotone_selector || - ( ! $has_duotone_attribute && ! $has_global_styles_duotone ) - ) { + if ( ! $has_duotone_attribute && ! $has_global_styles_duotone ) { return $block_content; } From 68871ff0d38912245a2e0a79e93acaf650d39e7a Mon Sep 17 00:00:00 2001 From: Jonny Harris Date: Wed, 12 Jul 2023 01:06:57 +0100 Subject: [PATCH 03/20] Change method names to make things cleaner. --- src/wp-includes/class-wp-duotone.php | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/wp-includes/class-wp-duotone.php b/src/wp-includes/class-wp-duotone.php index 801b81fc21aa4..1bd1fb923397b 100644 --- a/src/wp-includes/class-wp-duotone.php +++ b/src/wp-includes/class-wp-duotone.php @@ -575,7 +575,7 @@ private static function is_preset( $duotone_attr ) { $slug = self::get_slug_from_attribute( $duotone_attr ); $filter_id = self::get_filter_id( $slug ); - return array_key_exists( $filter_id, self::_get_global_styles_presets() ); + return array_key_exists( $filter_id, self::get_all_global_styles_presets() ); } /** @@ -897,7 +897,7 @@ private static function enqueue_custom_filter( $filter_id, $duotone_selector, $f * @param string $filter_value The filter CSS value. e.g. 'url(#wp-duotone-blue-orange)' or 'unset'. */ private static function enqueue_global_styles_preset( $filter_id, $duotone_selector, $filter_value ) { - $global_styles_presets = self::_get_global_styles_presets(); + $global_styles_presets = self::get_all_global_styles_presets(); if ( ! array_key_exists( $filter_id, $global_styles_presets ) ) { $error_message = sprintf( /* translators: %s: duotone filter ID */ @@ -999,7 +999,7 @@ private static function get_selector( $block_name ) { * * @since 6.3.0 */ - public static function set_global_styles_presets() { + public static function load_global_styles_presets() { // Get the per block settings from the theme.json. $tree = wp_get_global_settings(); $presets_by_origin = _wp_array_get( $tree, array( 'color', 'duotone' ), array() ); @@ -1021,9 +1021,9 @@ public static function set_global_styles_presets() { * * @return array */ - private static function _get_global_styles_presets() { + private static function get_all_global_styles_presets() { if ( ! isset( self::$global_styles_presets ) ) { - self::set_global_styles_presets(); + self::load_global_styles_presets(); } return self::$global_styles_presets; @@ -1037,7 +1037,7 @@ private static function _get_global_styles_presets() { * * @since 6.3.0 */ - public static function set_global_style_block_names() { + public static function load_global_style_block_names() { // Get the per block settings from the theme.json. $tree = WP_Theme_JSON_Resolver::get_merged_data(); $block_nodes = $tree->get_styles_block_nodes(); @@ -1074,9 +1074,9 @@ public static function set_global_style_block_names() { * * @return array */ - private static function _get_global_style_block_names() { + private static function get_all_global_style_block_names() { if ( ! isset( self::$global_styles_block_names ) ) { - self::set_global_style_block_names(); + self::load_global_style_block_names(); } return self::$global_styles_block_names; } @@ -1103,7 +1103,7 @@ public static function render_duotone_support( $block_content, $block ) { return $block_content; } - $global_styles_block_names = self::_get_global_style_block_names(); + $global_styles_block_names = self::get_all_global_style_block_names(); // The block should have a duotone attribute or have duotone defined in its theme.json to be processed. $has_duotone_attribute = isset( $block['attrs']['style']['color']['duotone'] ); @@ -1236,7 +1236,7 @@ public static function output_footer_assets() { * @return array The editor settings with duotone SVGs and CSS custom properties. */ public static function add_editor_settings( $settings ) { - $global_styles_presets = self::_get_global_styles_presets(); + $global_styles_presets = self::get_all_global_styles_presets(); if ( ! empty( $global_styles_presets ) ) { if ( ! isset( $settings['styles'] ) ) { $settings['styles'] = array(); From 7d647cd9b6761bea3df315911ab1a140a00646aa Mon Sep 17 00:00:00 2001 From: Jonny Harris Date: Wed, 12 Jul 2023 10:33:17 +0100 Subject: [PATCH 04/20] More tweaks for performance. --- src/wp-includes/class-wp-duotone.php | 65 +++++++++++++--------------- 1 file changed, 29 insertions(+), 36 deletions(-) diff --git a/src/wp-includes/class-wp-duotone.php b/src/wp-includes/class-wp-duotone.php index 1bd1fb923397b..ad673832ba6ab 100644 --- a/src/wp-includes/class-wp-duotone.php +++ b/src/wp-includes/class-wp-duotone.php @@ -921,16 +921,7 @@ private static function enqueue_global_styles_preset( $filter_id, $duotone_selec * @param WP_Block_Type $block_type Block Type. */ public static function register_duotone_support( $block_type ) { - $has_duotone_support = false; - if ( property_exists( $block_type, 'supports' ) ) { - /* - * Previous `color.__experimentalDuotone` support flag is migrated - * to `filter.duotone` via `block_type_metadata_settings` filter. - */ - $has_duotone_support = _wp_array_get( $block_type->supports, array( 'filter', 'duotone' ), null ); - } - - if ( $has_duotone_support ) { + if ( block_has_support( $block_type, array( 'filter', 'duotone' ) ) ) { if ( ! $block_type->attributes ) { $block_type->attributes = array(); } @@ -960,34 +951,36 @@ public static function register_duotone_support( $block_type ) { private static function get_selector( $block_name ) { $block_type = WP_Block_Type_Registry::get_instance()->get_registered( $block_name ); - if ( $block_type && property_exists( $block_type, 'supports' ) ) { - /* - * Backwards compatibility with `supports.color.__experimentalDuotone` - * is provided via the `block_type_metadata_settings` filter. If - * `supports.filter.duotone` has not been set and the experimental - * property has been, the experimental property value is copied into - * `supports.filter.duotone`. - */ - $duotone_support = _wp_array_get( $block_type->supports, array( 'filter', 'duotone' ), false ); - if ( ! $duotone_support ) { - return null; - } + if ( ! $block_type ) { + return null; + } - /* - * If the experimental duotone support was set, that value is to be - * treated as a selector and requires scoping. - */ - $experimental_duotone = _wp_array_get( $block_type->supports, array( 'color', '__experimentalDuotone' ), false ); - if ( $experimental_duotone ) { - $root_selector = wp_get_block_css_selector( $block_type ); - return is_string( $experimental_duotone ) - ? WP_Theme_JSON::scope_selector( $root_selector, $experimental_duotone ) - : $root_selector; - } + /* + * Backwards compatibility with `supports.color.__experimentalDuotone` + * is provided via the `block_type_metadata_settings` filter. If + * `supports.filter.duotone` has not been set and the experimental + * property has been, the experimental property value is copied into + * `supports.filter.duotone`. + */ + $duotone_support = block_has_support( $block_type, array( 'filter', 'duotone' ) ); + if ( ! $duotone_support ) { + return null; + } - // Regular filter.duotone support uses filter.duotone selectors with fallbacks. - return wp_get_block_css_selector( $block_type, array( 'filter', 'duotone' ), true ); + /* + * If the experimental duotone support was set, that value is to be + * treated as a selector and requires scoping. + */ + $experimental_duotone = block_has_support( $block_type, array( 'color', '__experimentalDuotone' ) ); + if ( $experimental_duotone ) { + $root_selector = wp_get_block_css_selector( $block_type ); + return is_string( $experimental_duotone ) + ? WP_Theme_JSON::scope_selector( $root_selector, $experimental_duotone ) + : $root_selector; } + + // Regular filter.duotone support uses filter.duotone selectors with fallbacks. + return wp_get_block_css_selector( $block_type, array( 'filter', 'duotone' ), true ); } /** @@ -1094,7 +1087,7 @@ private static function get_all_global_style_block_names() { * @return string Filtered block content. */ public static function render_duotone_support( $block_content, $block ) { - if ( empty( $block_content ) ) { + if ( empty( $block_content ) || ! $block['blockName'] ) { return $block_content; } $duotone_selector = self::get_selector( $block['blockName'] ); From 27c9a69651ec89e883a2d7a228148876a376e57f Mon Sep 17 00:00:00 2001 From: Jonny Harris Date: Wed, 12 Jul 2023 10:52:16 +0100 Subject: [PATCH 05/20] More refactored --- src/wp-includes/block-supports/duotone.php | 2 +- src/wp-includes/class-wp-duotone.php | 15 +++++---------- 2 files changed, 6 insertions(+), 11 deletions(-) diff --git a/src/wp-includes/block-supports/duotone.php b/src/wp-includes/block-supports/duotone.php index 8ec08f08d9f84..a90eb762ba8f0 100644 --- a/src/wp-includes/block-supports/duotone.php +++ b/src/wp-includes/block-supports/duotone.php @@ -41,7 +41,7 @@ ); // Add classnames to blocks using duotone support. -add_filter( 'render_block', array( 'WP_Duotone', 'render_duotone_support' ), 10, 2 ); +add_filter( 'render_block', array( 'WP_Duotone', 'render_duotone_support' ), 10, 3 ); // Enqueue styles. // Block styles (core-block-supports-inline-css) before the style engine (wp_enqueue_stored_styles). diff --git a/src/wp-includes/class-wp-duotone.php b/src/wp-includes/class-wp-duotone.php index ad673832ba6ab..28bd34af840c2 100644 --- a/src/wp-includes/class-wp-duotone.php +++ b/src/wp-includes/class-wp-duotone.php @@ -940,7 +940,7 @@ public static function register_duotone_support( $block_type ) { * This handles selectors defined in `color.__experimentalDuotone` support * if `filter.duotone` support is not defined. * - * @param string $block_name The block name. + * @param WP_Block_Type $block_type Block type to check for support. * * @internal * @@ -948,13 +948,7 @@ public static function register_duotone_support( $block_type ) { * * @return string The CSS selector or null if there is no support. */ - private static function get_selector( $block_name ) { - $block_type = WP_Block_Type_Registry::get_instance()->get_registered( $block_name ); - - if ( ! $block_type ) { - return null; - } - + private static function get_selector( $block_type ) { /* * Backwards compatibility with `supports.color.__experimentalDuotone` * is provided via the `block_type_metadata_settings` filter. If @@ -1084,13 +1078,14 @@ private static function get_all_global_style_block_names() { * * @param string $block_content Rendered block content. * @param array $block Block object. + * @param WP_Block $wp_block The block instance. * @return string Filtered block content. */ - public static function render_duotone_support( $block_content, $block ) { + public static function render_duotone_support( $block_content, $block, $wp_block ) { if ( empty( $block_content ) || ! $block['blockName'] ) { return $block_content; } - $duotone_selector = self::get_selector( $block['blockName'] ); + $duotone_selector = self::get_selector( $wp_block->block_type ); if ( ! $duotone_selector ) { return $block_content; From 9c16d50fddfebe8963c79ebb1d56baa4dfe2ce64 Mon Sep 17 00:00:00 2001 From: Jonny Harris Date: Wed, 12 Jul 2023 12:18:00 +0100 Subject: [PATCH 06/20] Fix tests. --- tests/phpunit/tests/block-supports/duotone.php | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/tests/phpunit/tests/block-supports/duotone.php b/tests/phpunit/tests/block-supports/duotone.php index 672e91c00bc6a..2077ef705b19a 100644 --- a/tests/phpunit/tests/block-supports/duotone.php +++ b/tests/phpunit/tests/block-supports/duotone.php @@ -27,9 +27,10 @@ public function test_render_duotone_support_preset() { 'blockName' => 'core/image', 'attrs' => array( 'style' => array( 'color' => array( 'duotone' => 'var:preset|duotone|blue-orange' ) ) ), ); + $wp_block = new WP_Block( $block ); $block_content = '
'; $expected = '
'; - $this->assertSame( $expected, WP_Duotone::render_duotone_support( $block_content, $block ) ); + $this->assertSame( $expected, WP_Duotone::render_duotone_support( $block_content, $block, $wp_block ) ); } /** @@ -44,9 +45,10 @@ public function test_render_duotone_support_css() { 'blockName' => 'core/image', 'attrs' => array( 'style' => array( 'color' => array( 'duotone' => 'unset' ) ) ), ); + $wp_block = new WP_Block( $block ); $block_content = '
'; $expected = '/
<\\/figure>/'; - $this->assertMatchesRegularExpression( $expected, WP_Duotone::render_duotone_support( $block_content, $block ) ); + $this->assertMatchesRegularExpression( $expected, WP_Duotone::render_duotone_support( $block_content, $block, $wp_block ) ); } /** @@ -59,9 +61,10 @@ public function test_render_duotone_support_custom() { 'blockName' => 'core/image', 'attrs' => array( 'style' => array( 'color' => array( 'duotone' => array( '#FFFFFF', '#000000' ) ) ) ), ); + $wp_block = new WP_Block( $block ); $block_content = '
'; $expected = '/
<\\/figure>/'; - $this->assertMatchesRegularExpression( $expected, WP_Duotone::render_duotone_support( $block_content, $block ) ); + $this->assertMatchesRegularExpression( $expected, WP_Duotone::render_duotone_support( $block_content, $block, $wp_block ) ); } /** From a8fc72ed5a42ca085e591495b1694eeefadd1449 Mon Sep 17 00:00:00 2001 From: Jonny Harris Date: Wed, 12 Jul 2023 12:29:37 +0100 Subject: [PATCH 07/20] Fix test again. --- tests/phpunit/tests/blocks/supportedStyles.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/tests/phpunit/tests/blocks/supportedStyles.php b/tests/phpunit/tests/blocks/supportedStyles.php index d3b1a191de242..95c5326b4542f 100644 --- a/tests/phpunit/tests/blocks/supportedStyles.php +++ b/tests/phpunit/tests/blocks/supportedStyles.php @@ -695,13 +695,14 @@ public function test_render_block_suppresses_warnings_without_at_suppression() { ); $this->register_block_type( 'core/example', $block_type_settings ); - $block = array( + $block = array( 'blockName' => 'core/example', 'attrs' => array(), 'innerBlock' => array(), 'innerContent' => array(), 'innerHTML' => array(), ); + $wp_block = new WP_Block( $block ); // Custom error handler's see Warnings even if they are suppressed by the @ symbol. $errors = array(); @@ -714,7 +715,7 @@ static function ( $errno = 0, $errstr = '' ) use ( &$errors ) { // HTML5 elements like