From e55e9c2f0c7925aea6594ec97ff539075362598b Mon Sep 17 00:00:00 2001 From: Isabel Brison Date: Mon, 26 Jun 2023 23:42:16 +0000 Subject: [PATCH] Editor: add box shadow support to blocks. Adds the ability for blocks to declare support for CSS box-shadow and processing of necessary styles. Props madhudollu, sabernhardt, ramonopoly, spacedmonkey, mukesh27. Fixes #58590. git-svn-id: https://develop.svn.wordpress.org/trunk@56046 602fd350-edb4-49c9-b593-d223f7449a82 --- src/wp-includes/block-supports/shadow.php | 82 +++++++++++++++++ src/wp-includes/kses.php | 2 + .../style-engine/class-wp-style-engine.php | 11 +++ src/wp-settings.php | 1 + tests/phpunit/tests/block-supports/shadow.php | 89 +++++++++++++++++++ .../tests/style-engine/styleEngine.php | 14 +++ 6 files changed, 199 insertions(+) create mode 100644 src/wp-includes/block-supports/shadow.php create mode 100644 tests/phpunit/tests/block-supports/shadow.php diff --git a/src/wp-includes/block-supports/shadow.php b/src/wp-includes/block-supports/shadow.php new file mode 100644 index 0000000000..7a710c5222 --- /dev/null +++ b/src/wp-includes/block-supports/shadow.php @@ -0,0 +1,82 @@ +attributes ) { + $block_type->attributes = array(); + } + + if ( array_key_exists( 'style', $block_type->attributes ) ) { + $block_type->attributes['style'] = array( + 'type' => 'object', + ); + } + + if ( array_key_exists( 'shadow', $block_type->attributes ) ) { + $block_type->attributes['shadow'] = array( + 'type' => 'string', + ); + } +} + +/** + * Add CSS classes and inline styles for shadow features to the incoming attributes array. + * This will be applied to the block markup in the front-end. + * + * @since 6.3.0 + * @access private + * + * @param WP_Block_Type $block_type Block type. + * @param array $block_attributes Block attributes. + * @return array Shadow CSS classes and inline styles. + */ +function wp_apply_shadow_support( $block_type, $block_attributes ) { + $has_shadow_support = block_has_support( $block_type, array( 'shadow' ), false ); + + if ( ! $has_shadow_support ) { + return array(); + } + + $shadow_block_styles = array(); + + $preset_shadow = array_key_exists( 'shadow', $block_attributes ) ? "var:preset|shadow|{$block_attributes['shadow']}" : null; + $custom_shadow = isset( $block_attributes['style']['shadow'] ) ? $block_attributes['style']['shadow'] : null; + $shadow_block_styles['shadow'] = $preset_shadow ? $preset_shadow : $custom_shadow; + + $attributes = array(); + $styles = wp_style_engine_get_styles( $shadow_block_styles ); + + if ( ! empty( $styles['css'] ) ) { + $attributes['style'] = $styles['css']; + } + + return $attributes; +} + +// Register the block support. +WP_Block_Supports::get_instance()->register( + 'shadow', + array( + 'register_attribute' => 'wp_register_shadow_support', + 'apply' => 'wp_apply_shadow_support', + ) +); diff --git a/src/wp-includes/kses.php b/src/wp-includes/kses.php index df9ae74b08..fd0d67dfed 100644 --- a/src/wp-includes/kses.php +++ b/src/wp-includes/kses.php @@ -2280,6 +2280,7 @@ function kses_init() { * @since 6.2.0 Added support for `aspect-ratio`, `position`, `top`, `right`, `bottom`, `left`, * and `z-index` CSS properties. * @since 6.3.0 Extended support for `filter` to accept a URL and added support for repeat(). + * Added support for `box-shadow`. * * @param string $css A string of CSS rules. * @param string $deprecated Not used. @@ -2447,6 +2448,7 @@ function safecss_filter_attr( $css, $deprecated = '' ) { 'bottom', 'left', 'z-index', + 'box-shadow', 'aspect-ratio', // Custom CSS properties. 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 3ec84aba6b..bdaae4a1f7 100644 --- a/src/wp-includes/style-engine/class-wp-style-engine.php +++ b/src/wp-includes/style-engine/class-wp-style-engine.php @@ -148,6 +148,17 @@ final class WP_Style_Engine { ), ), ), + 'shadow' => array( + 'shadow' => array( + 'property_keys' => array( + 'default' => 'box-shadow', + ), + 'path' => array( 'shadow' ), + 'css_vars' => array( + 'shadow' => '--wp--preset--shadow--$slug', + ), + ), + ), 'dimensions' => array( 'minHeight' => array( 'property_keys' => array( diff --git a/src/wp-settings.php b/src/wp-settings.php index f0c6639a46..f1c1e0cd37 100644 --- a/src/wp-settings.php +++ b/src/wp-settings.php @@ -331,6 +331,7 @@ require ABSPATH . WPINC . '/block-supports/colors.php'; require ABSPATH . WPINC . '/block-supports/custom-classname.php'; require ABSPATH . WPINC . '/block-supports/dimensions.php'; require ABSPATH . WPINC . '/block-supports/duotone.php'; +require ABSPATH . WPINC . '/block-supports/shadow.php'; require ABSPATH . WPINC . '/block-supports/elements.php'; require ABSPATH . WPINC . '/block-supports/generated-classname.php'; require ABSPATH . WPINC . '/block-supports/layout.php'; diff --git a/tests/phpunit/tests/block-supports/shadow.php b/tests/phpunit/tests/block-supports/shadow.php new file mode 100644 index 0000000000..b2e9dc80f6 --- /dev/null +++ b/tests/phpunit/tests/block-supports/shadow.php @@ -0,0 +1,89 @@ +test_block_name = null; + } + + public function tear_down() { + unregister_block_type( $this->test_block_name ); + $this->test_block_name = null; + parent::set_up(); + } + + /** + * @ticket 58590 + */ + public function test_shadow_style_is_applied() { + $this->test_block_name = 'test/shadow-style-is-applied'; + register_block_type( + $this->test_block_name, + array( + 'api_version' => 3, + 'attributes' => array( + 'style' => array( + 'type' => 'object', + ), + ), + 'supports' => array( + 'shadow' => true, + ), + ) + ); + $registry = WP_Block_Type_Registry::get_instance(); + $block_type = $registry->get_registered( $this->test_block_name ); + $block_atts = array( + 'style' => array( + 'shadow' => '60px -16px teal', + ), + ); + + $actual = wp_apply_shadow_support( $block_type, $block_atts ); + $expected = array( + 'style' => 'box-shadow:60px -16px teal;', + ); + + $this->assertSame( $expected, $actual ); + } + + /** + * @ticket 58590 + */ + public function test_shadow_without_block_supports() { + $this->test_block_name = 'test/shadow-with-skipped-serialization-block-supports'; + register_block_type( + $this->test_block_name, + array( + 'api_version' => 2, + 'attributes' => array( + 'style' => array( + 'type' => 'object', + ), + ), + 'supports' => array(), + ) + ); + $registry = WP_Block_Type_Registry::get_instance(); + $block_type = $registry->get_registered( $this->test_block_name ); + $block_atts = array( + 'style' => array( + 'shadow' => '60px -16px teal', + ), + ); + + $actual = wp_apply_spacing_support( $block_type, $block_atts ); + $expected = array(); + + $this->assertSame( $expected, $actual ); + } +} diff --git a/tests/phpunit/tests/style-engine/styleEngine.php b/tests/phpunit/tests/style-engine/styleEngine.php index 60335386cb..3d6a47aa94 100644 --- a/tests/phpunit/tests/style-engine/styleEngine.php +++ b/tests/phpunit/tests/style-engine/styleEngine.php @@ -26,6 +26,7 @@ class Tests_wpStyleEngine extends WP_UnitTestCase { * * @ticket 56467 * @ticket 58549 + * @ticket 58590 * * @covers ::wp_style_engine_get_styles * @@ -182,6 +183,19 @@ class Tests_wpStyleEngine extends WP_UnitTestCase { ), ), + 'inline_valid_shadow_style' => array( + 'block_styles' => array( + 'shadow' => 'inset 5em 1em gold', + ), + 'options' => null, + 'expected_output' => array( + 'css' => 'box-shadow:inset 5em 1em gold;', + 'declarations' => array( + 'box-shadow' => 'inset 5em 1em gold', + ), + ), + ), + 'inline_valid_typography_style' => array( 'block_styles' => array( 'typography' => array(