From ac8db41833e0c29be1b0f9b9aeabe735f37e63fb Mon Sep 17 00:00:00 2001 From: Isabel Brison Date: Mon, 18 Sep 2023 06:25:49 +0000 Subject: [PATCH] Editor: add block instance element color support for buttons and headings. Adds support for buttons and headings to the colors and elements block supports, allowing button and heading element colors to be changed on individual blocks. Props aaronrobertshaw. Fixes #59309. git-svn-id: https://develop.svn.wordpress.org/trunk@56604 602fd350-edb4-49c9-b593-d223f7449a82 --- src/wp-includes/block-supports/colors.php | 6 +- src/wp-includes/block-supports/elements.php | 179 ++++++++++++++---- .../style-engine/class-wp-style-engine.php | 6 + .../phpunit/tests/block-supports/elements.php | 64 +++++++ 4 files changed, 213 insertions(+), 42 deletions(-) diff --git a/src/wp-includes/block-supports/colors.php b/src/wp-includes/block-supports/colors.php index 25fe3edd60..ad949a3b5b 100644 --- a/src/wp-includes/block-supports/colors.php +++ b/src/wp-includes/block-supports/colors.php @@ -21,10 +21,14 @@ function wp_register_colors_support( $block_type ) { $has_background_colors_support = true === $color_support || ( is_array( $color_support ) && _wp_array_get( $color_support, array( 'background' ), true ) ); $has_gradients_support = _wp_array_get( $color_support, array( 'gradients' ), false ); $has_link_colors_support = _wp_array_get( $color_support, array( 'link' ), false ); + $has_button_colors_support = _wp_array_get( $color_support, array( 'button' ), false ); + $has_heading_colors_support = _wp_array_get( $color_support, array( 'heading' ), false ); $has_color_support = $has_text_colors_support || $has_background_colors_support || $has_gradients_support || - $has_link_colors_support; + $has_link_colors_support || + $has_button_colors_support || + $has_heading_colors_support; if ( ! $block_type->attributes ) { $block_type->attributes = array(); diff --git a/src/wp-includes/block-supports/elements.php b/src/wp-includes/block-supports/elements.php index fa2536908c..a388ad403f 100644 --- a/src/wp-includes/block-supports/elements.php +++ b/src/wp-includes/block-supports/elements.php @@ -23,6 +23,7 @@ function wp_get_elements_class_name( $block ) { * Updates the block content with elements class names. * * @since 5.8.0 + * @since 6.4.0 Added support for button and heading element styling. * @access private * * @param string $block_content Rendered block content. @@ -30,34 +31,79 @@ function wp_get_elements_class_name( $block ) { * @return string Filtered block content. */ function wp_render_elements_support( $block_content, $block ) { - if ( ! $block_content ) { + if ( ! $block_content || empty( $block['attrs'] ) ) { return $block_content; } - $block_type = WP_Block_Type_Registry::get_instance()->get_registered( $block['blockName'] ); - $skip_link_color_serialization = wp_should_skip_block_supports_serialization( $block_type, 'color', 'link' ); + $block_type = WP_Block_Type_Registry::get_instance()->get_registered( $block['blockName'] ); - if ( $skip_link_color_serialization ) { + $element_color_properties = array( + 'button' => array( + 'skip' => wp_should_skip_block_supports_serialization( $block_type, 'color', 'button' ), + 'paths' => array( + 'style.elements.button.color.text', + 'style.elements.button.color.background', + 'style.elements.button.color.gradient', + ), + ), + 'link' => array( + 'skip' => wp_should_skip_block_supports_serialization( $block_type, 'color', 'link' ), + 'paths' => array( + 'style.elements.link.color.text', + 'style.elements.link.:hover.color.text', + ), + ), + 'heading' => array( + 'skip' => wp_should_skip_block_supports_serialization( $block_type, 'color', 'heading' ), + 'paths' => array( + 'style.elements.heading.color.text', + 'style.elements.heading.color.background', + 'style.elements.heading.color.gradient', + 'style.elements.h1.color.text', + 'style.elements.h1.color.background', + 'style.elements.h1.color.gradient', + 'style.elements.h2.color.text', + 'style.elements.h2.color.background', + 'style.elements.h2.color.gradient', + 'style.elements.h3.color.text', + 'style.elements.h3.color.background', + 'style.elements.h3.color.gradient', + 'style.elements.h4.color.text', + 'style.elements.h4.color.background', + 'style.elements.h4.color.gradient', + 'style.elements.h5.color.text', + 'style.elements.h5.color.background', + 'style.elements.h5.color.gradient', + 'style.elements.h6.color.text', + 'style.elements.h6.color.background', + 'style.elements.h6.color.gradient', + ), + ), + ); + + $skip_all_element_color_serialization = $element_color_properties['button']['skip'] && + $element_color_properties['link']['skip'] && + $element_color_properties['heading']['skip']; + + if ( $skip_all_element_color_serialization ) { return $block_content; } - $link_color = null; - if ( ! empty( $block['attrs'] ) ) { - $link_color = _wp_array_get( $block['attrs'], array( 'style', 'elements', 'link', 'color', 'text' ), null ); + $element_colors_set = 0; + + foreach ( $element_color_properties as $element_config ) { + if ( $element_config['skip'] ) { + continue; + } + + foreach ( $element_config['paths'] as $path ) { + if ( null !== _wp_array_get( $block['attrs'], explode( '.', $path ), null ) ) { + $element_colors_set++; + } + } } - $hover_link_color = null; - if ( ! empty( $block['attrs'] ) ) { - $hover_link_color = _wp_array_get( $block['attrs'], array( 'style', 'elements', 'link', ':hover', 'color', 'text' ), null ); - } - - /* - * For now we only care about link colors. - * This code in the future when we have a public API - * should take advantage of WP_Theme_JSON::compute_style_properties - * and work for any element and style. - */ - if ( null === $link_color && null === $hover_link_color ) { + if ( ! $element_colors_set ) { return $block_content; } @@ -90,33 +136,84 @@ function wp_render_elements_support_styles( $pre_render, $block ) { $block_type = WP_Block_Type_Registry::get_instance()->get_registered( $block['blockName'] ); $element_block_styles = isset( $block['attrs']['style']['elements'] ) ? $block['attrs']['style']['elements'] : null; - /* - * For now we only care about link color. - */ - $skip_link_color_serialization = wp_should_skip_block_supports_serialization( $block_type, 'color', 'link' ); - - if ( $skip_link_color_serialization ) { + if ( ! $element_block_styles ) { return null; } - $class_name = wp_get_elements_class_name( $block ); - $link_block_styles = isset( $element_block_styles['link'] ) ? $element_block_styles['link'] : null; - wp_style_engine_get_styles( - $link_block_styles, - array( - 'selector' => ".$class_name a", - 'context' => 'block-supports', - ) + $skip_link_color_serialization = wp_should_skip_block_supports_serialization( $block_type, 'color', 'link' ); + $skip_heading_color_serialization = wp_should_skip_block_supports_serialization( $block_type, 'color', 'heading' ); + $skip_button_color_serialization = wp_should_skip_block_supports_serialization( $block_type, 'color', 'button' ); + $skips_all_element_color_serialization = $skip_link_color_serialization && + $skip_heading_color_serialization && + $skip_button_color_serialization; + + if ( $skips_all_element_color_serialization ) { + return null; + } + + $class_name = wp_get_elements_class_name( $block ); + + $element_types = array( + 'button' => array( + 'selector' => ".$class_name .wp-element-button, .$class_name .wp-block-button__link", + 'skip' => $skip_button_color_serialization, + ), + 'link' => array( + 'selector' => ".$class_name a", + 'hover_selector' => ".$class_name a:hover", + 'skip' => $skip_link_color_serialization, + ), + 'heading' => array( + 'selector' => ".$class_name h1, .$class_name h2, .$class_name h3, .$class_name h4, .$class_name h5, .$class_name h6", + 'skip' => $skip_heading_color_serialization, + 'elements' => array( 'h1', 'h2', 'h3', 'h4', 'h5', 'h6' ), + ), ); - if ( isset( $link_block_styles[':hover'] ) ) { - wp_style_engine_get_styles( - $link_block_styles[':hover'], - array( - 'selector' => ".$class_name a:hover", - 'context' => 'block-supports', - ) - ); + foreach ( $element_types as $element_type => $element_config ) { + if ( $element_config['skip'] ) { + continue; + } + + $element_style_object = _wp_array_get( $element_block_styles, array( $element_type ), null ); + + // Process primary element type styles. + if ( $element_style_object ) { + wp_style_engine_get_styles( + $element_style_object, + array( + 'selector' => $element_config['selector'], + 'context' => 'block-supports', + ) + ); + + if ( isset( $element_style_object[':hover'] ) ) { + wp_style_engine_get_styles( + $element_style_object[':hover'], + array( + 'selector' => $element_config['hover_selector'], + 'context' => 'block-supports', + ) + ); + } + } + + // Process related elements e.g. h1-h6 for headings. + if ( isset( $element_config['elements'] ) ) { + foreach ( $element_config['elements'] as $element ) { + $element_style_object = _wp_array_get( $element_block_styles, array( $element ), null ); + + if ( $element_style_object ) { + wp_style_engine_get_styles( + $element_style_object, + array( + 'selector' => ".$class_name $element", + 'context' => 'block-supports', + ) + ); + } + } + } } return null; diff --git a/src/wp-includes/style-engine/class-wp-style-engine.php b/src/wp-includes/style-engine/class-wp-style-engine.php index da1afe42ca..6bb03a7070 100644 --- a/src/wp-includes/style-engine/class-wp-style-engine.php +++ b/src/wp-includes/style-engine/class-wp-style-engine.php @@ -70,6 +70,9 @@ final class WP_Style_Engine { 'default' => 'background-color', ), 'path' => array( 'color', 'background' ), + 'css_vars' => array( + 'color' => '--wp--preset--color--$slug', + ), 'classnames' => array( 'has-background' => true, 'has-$slug-background-color' => 'color', @@ -80,6 +83,9 @@ final class WP_Style_Engine { 'default' => 'background', ), 'path' => array( 'color', 'gradient' ), + 'css_vars' => array( + 'gradient' => '--wp--preset--gradient--$slug', + ), 'classnames' => array( 'has-background' => true, 'has-$slug-gradient-background' => 'gradient', diff --git a/tests/phpunit/tests/block-supports/elements.php b/tests/phpunit/tests/block-supports/elements.php index 02c29dd6e6..0b1f720b5a 100644 --- a/tests/phpunit/tests/block-supports/elements.php +++ b/tests/phpunit/tests/block-supports/elements.php @@ -106,4 +106,68 @@ class Tests_Block_Supports_Elements extends WP_UnitTestCase { '

Hello WordPress!

' ); } + + /** + * Test wp_render_elements_support() with a group block that has a button + * element color set. + * + * @ticket 59309 + */ + public function test_group_with_button_element_style() { + $result = self::make_unique_id_one( + wp_render_elements_support( + '
', + array( + 'blockName' => 'core/group', + 'attrs' => array( + 'style' => array( + 'elements' => array( + 'button' => array( + 'color' => array( + 'text' => 'var:preset|color|vivid-red', + ), + ), + ), + ), + ), + ) + ) + ); + $this->assertSame( + $result, + '
' + ); + } + + /** + * Test wp_render_elements_support() with a group block that has a heading + * element color set. + * + * @ticket 59309 + */ + public function test_group_with_heading_element_style() { + $result = self::make_unique_id_one( + wp_render_elements_support( + '

Test

', + array( + 'blockName' => 'core/group', + 'attrs' => array( + 'style' => array( + 'elements' => array( + 'heading' => array( + 'color' => array( + 'text' => 'var:preset|color|vivid-red', + ), + ), + ), + ), + ), + ) + ) + ); + $this->assertSame( + $result, + '

Test

' + ); + } }