From 9c21ff9efebd0fc032bbd0a37556948bd077ea75 Mon Sep 17 00:00:00 2001 From: ramon Date: Thu, 10 Oct 2024 14:59:02 +1100 Subject: [PATCH 1/3] Backporting the current state of https://github.com/WordPress/wordpress-develop/pull/7486 and adding tests. --- lib/class-wp-theme-json-gutenberg.php | 107 ++++++++++++++++---------- phpunit/class-wp-theme-json-test.php | 52 +++++++++++++ 2 files changed, 120 insertions(+), 39 deletions(-) diff --git a/lib/class-wp-theme-json-gutenberg.php b/lib/class-wp-theme-json-gutenberg.php index 756ef06c80aa8..b4c3b0788db32 100644 --- a/lib/class-wp-theme-json-gutenberg.php +++ b/lib/class-wp-theme-json-gutenberg.php @@ -2719,15 +2719,17 @@ private static function update_separator_declarations( $declarations ) { /** * An internal method to get the block nodes from a theme.json file. * - * @since 6.1.0 - * * @param array $theme_json The theme.json converted to an array. * @param array $selectors Optional list of selectors per block. - * @param array $options An array of options to facilitate filtering node generation - * The options currently supported are: - * - `include_block_style_variations` which includes CSS for block style variations. + * @param array $options { + * Optional. An array of options for now used for internal purposes only (may change without notice). + * + * @type bool $include_block_style_variations Includes nodes for block style variations. Default false. + * @type bool $include_node_paths_only Return only block nodes node paths. Default false. + * } * @return array The block nodes in theme.json. */ + private static function get_block_nodes( $theme_json, $selectors = array(), $options = array() ) { $selectors = empty( $selectors ) ? static::get_blocks_metadata() : $selectors; $nodes = array(); @@ -2741,46 +2743,61 @@ private static function get_block_nodes( $theme_json, $selectors = array(), $opt } foreach ( $theme_json['styles']['blocks'] as $name => $node ) { - $selector = null; - if ( isset( $selectors[ $name ]['selector'] ) ) { - $selector = $selectors[ $name ]['selector']; - } - - $duotone_selector = null; - if ( isset( $selectors[ $name ]['duotone'] ) ) { - $duotone_selector = $selectors[ $name ]['duotone']; - } + $include_node_paths_only = $options['include_node_paths_only'] ?? false; + $node_path = array( 'styles', 'blocks', $name ); + if ( $include_node_paths_only ) { + $nodes[] = array( + 'path' => $node_path, + ); + } else { + $selector = null; + if ( isset( $selectors[ $name ]['selector'] ) ) { + $selector = $selectors[ $name ]['selector']; + } - $feature_selectors = null; - if ( isset( $selectors[ $name ]['selectors'] ) ) { - $feature_selectors = $selectors[ $name ]['selectors']; - } + $duotone_selector = null; + if ( isset( $selectors[ $name ]['duotone'] ) ) { + $duotone_selector = $selectors[ $name ]['duotone']; + } - $variation_selectors = array(); - $include_variations = $options['include_block_style_variations'] ?? false; - if ( $include_variations && isset( $node['variations'] ) ) { - foreach ( $node['variations'] as $variation => $node ) { - $variation_selectors[] = array( - 'path' => array( 'styles', 'blocks', $name, 'variations', $variation ), - 'selector' => $selectors[ $name ]['styleVariations'][ $variation ], - ); + $feature_selectors = null; + if ( isset( $selectors[ $name ]['selectors'] ) ) { + $feature_selectors = $selectors[ $name ]['selectors']; } - } - $nodes[] = array( - 'name' => $name, - 'path' => array( 'styles', 'blocks', $name ), - 'selector' => $selector, - 'selectors' => $feature_selectors, - 'duotone' => $duotone_selector, - 'variations' => $variation_selectors, - 'css' => $selector, - ); + $variation_selectors = array(); + $include_variations = $options['include_block_style_variations'] ?? false; + if ( $include_variations && isset( $node['variations'] ) ) { + foreach ( $node['variations'] as $variation => $node ) { + $variation_selectors[] = array( + 'path' => array( 'styles', 'blocks', $name, 'variations', $variation ), + 'selector' => $selectors[ $name ]['styleVariations'][ $variation ], + ); + } + } + $nodes[] = array( + 'name' => $name, + 'path' => $node_path, + 'selector' => $selector, + 'selectors' => $feature_selectors, + 'duotone' => $duotone_selector, + 'variations' => $variation_selectors, + 'css' => $selector, + ); + } if ( isset( $theme_json['styles']['blocks'][ $name ]['elements'] ) ) { foreach ( $theme_json['styles']['blocks'][ $name ]['elements'] as $element => $node ) { + $node_path = array( 'styles', 'blocks', $name, 'elements', $element ); + if ( $include_node_paths_only ) { + $nodes[] = array( + 'path' => $node_path, + ); + continue; + } + $nodes[] = array( - 'path' => array( 'styles', 'blocks', $name, 'elements', $element ), + 'path' => $node_path, 'selector' => $selectors[ $name ]['elements'][ $element ], ); @@ -2788,8 +2805,16 @@ private static function get_block_nodes( $theme_json, $selectors = array(), $opt if ( isset( static::VALID_ELEMENT_PSEUDO_SELECTORS[ $element ] ) ) { foreach ( static::VALID_ELEMENT_PSEUDO_SELECTORS[ $element ] as $pseudo_selector ) { if ( isset( $theme_json['styles']['blocks'][ $name ]['elements'][ $element ][ $pseudo_selector ] ) ) { + $node_path = array( 'styles', 'blocks', $name, 'elements', $element ); + if ( $include_node_paths_only ) { + $nodes[] = array( + 'path' => $node_path, + ); + continue; + } + $nodes[] = array( - 'path' => array( 'styles', 'blocks', $name, 'elements', $element ), + 'path' => $node_path, 'selector' => static::append_to_selector( $selectors[ $name ]['elements'][ $element ], $pseudo_selector ), ); } @@ -3264,7 +3289,11 @@ public function merge( $incoming ) { * some values provide exceptions, namely style values that are * objects and represent unique definitions for the style. */ - $style_nodes = static::get_styles_block_nodes(); + $style_nodes = static::get_block_nodes( + $this->theme_json, + array(), + array( 'include_node_paths_only' => true ) + ); foreach ( $style_nodes as $style_node ) { $path = $style_node['path']; /* diff --git a/phpunit/class-wp-theme-json-test.php b/phpunit/class-wp-theme-json-test.php index 10bb47b87fba8..29d454f6f4f0b 100644 --- a/phpunit/class-wp-theme-json-test.php +++ b/phpunit/class-wp-theme-json-test.php @@ -5726,4 +5726,56 @@ public function test_opt_in_to_block_style_variations() { $this->assertEquals( $expected, $button_variations ); } + + /** + * This test covers `get_block_nodes` with the `$include_node_paths_only` option. + * When `true`, `$include_node_paths_only` should return only the paths of the block nodes. + */ + public function test_return_block_node_paths() { + $theme_json = new ReflectionClass( 'WP_Theme_JSON_Gutenberg' ); + + $func = $theme_json->getMethod( 'get_block_nodes' ); + $func->setAccessible( true ); + + $theme_json = array( + 'version' => WP_Theme_JSON_Gutenberg::LATEST_SCHEMA, + 'styles' => array( + 'typography' => array( + 'fontSize' => '16px', + ), + 'blocks' => array( + 'core/button' => array( + 'color' => array( + 'background' => 'red', + ), + ), + 'core/group' => array( + 'elements' => array( + 'link' => array( + 'color' => array( + 'background' => 'blue', + ), + ), + ), + ), + ), + ), + ); + + $block_nodes = $func->invoke( null, $theme_json, array(), array( 'include_node_paths_only' => true ) ); + + $expected = array( + array( + 'path' => array( 'styles', 'blocks', 'core/button' ), + ), + array( + 'path' => array( 'styles', 'blocks', 'core/group' ), + ), + array( + 'path' => array( 'styles', 'blocks', 'core/group', 'elements', 'link' ), + ), + ); + + $this->assertEquals( $expected, $block_nodes ); + } } From 906f51d3e5fa3e20cb878eecc4ac421c28cd2a68 Mon Sep 17 00:00:00 2001 From: ramon Date: Thu, 10 Oct 2024 17:51:25 +1100 Subject: [PATCH 2/3] Reinstate annotation and remove whitespace --- lib/class-wp-theme-json-gutenberg.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/class-wp-theme-json-gutenberg.php b/lib/class-wp-theme-json-gutenberg.php index b4c3b0788db32..bbdf0d76ac44b 100644 --- a/lib/class-wp-theme-json-gutenberg.php +++ b/lib/class-wp-theme-json-gutenberg.php @@ -2719,6 +2719,8 @@ private static function update_separator_declarations( $declarations ) { /** * An internal method to get the block nodes from a theme.json file. * + * @since 6.1.0 + * * @param array $theme_json The theme.json converted to an array. * @param array $selectors Optional list of selectors per block. * @param array $options { @@ -2729,7 +2731,6 @@ private static function update_separator_declarations( $declarations ) { * } * @return array The block nodes in theme.json. */ - private static function get_block_nodes( $theme_json, $selectors = array(), $options = array() ) { $selectors = empty( $selectors ) ? static::get_blocks_metadata() : $selectors; $nodes = array(); From 7c59449cf2214f68933d9e3d474938d5bf7c103d Mon Sep 17 00:00:00 2001 From: ramon Date: Fri, 11 Oct 2024 09:35:02 +1100 Subject: [PATCH 3/3] Move assignments up outside main loop --- lib/class-wp-theme-json-gutenberg.php | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/lib/class-wp-theme-json-gutenberg.php b/lib/class-wp-theme-json-gutenberg.php index bbdf0d76ac44b..8cd83e007f37c 100644 --- a/lib/class-wp-theme-json-gutenberg.php +++ b/lib/class-wp-theme-json-gutenberg.php @@ -2743,9 +2743,11 @@ private static function get_block_nodes( $theme_json, $selectors = array(), $opt return $nodes; } + $include_variations = $options['include_block_style_variations'] ?? false; + $include_node_paths_only = $options['include_node_paths_only'] ?? false; + foreach ( $theme_json['styles']['blocks'] as $name => $node ) { - $include_node_paths_only = $options['include_node_paths_only'] ?? false; - $node_path = array( 'styles', 'blocks', $name ); + $node_path = array( 'styles', 'blocks', $name ); if ( $include_node_paths_only ) { $nodes[] = array( 'path' => $node_path, @@ -2767,7 +2769,7 @@ private static function get_block_nodes( $theme_json, $selectors = array(), $opt } $variation_selectors = array(); - $include_variations = $options['include_block_style_variations'] ?? false; + if ( $include_variations && isset( $node['variations'] ) ) { foreach ( $node['variations'] as $variation => $node ) { $variation_selectors[] = array(