From c3e1d3a8b8c2393ce8d6d50cededbea479516b8e Mon Sep 17 00:00:00 2001 From: ramonopoly Date: Wed, 31 Jul 2024 02:39:46 +0000 Subject: [PATCH] Background: add background attachment support to theme.json styles Introduces the ability to specify a value for `background.backgroundAttachment` in theme.json styles. The theme.json value determines the CSS value for the `background-attachment` property. This feature was introduced into the Gutenberg plugin in version 18.9. Props andrewserong, mukesh27, noisysocks, ramonopoly. Fixes #61720 git-svn-id: https://develop.svn.wordpress.org/trunk@58834 602fd350-edb4-49c9-b593-d223f7449a82 --- src/wp-includes/block-supports/background.php | 12 ++++--- src/wp-includes/class-wp-theme-json.php | 11 +++--- .../style-engine/class-wp-style-engine.php | 14 +++++--- .../wpRenderBackgroundSupport.php | 12 ++++--- .../tests/style-engine/styleEngine.php | 21 +++++++----- tests/phpunit/tests/theme/wpThemeJson.php | 34 +++++++++++-------- 6 files changed, 62 insertions(+), 42 deletions(-) diff --git a/src/wp-includes/block-supports/background.php b/src/wp-includes/block-supports/background.php index b7b501a44aca1..4e7995f53f92f 100644 --- a/src/wp-includes/block-supports/background.php +++ b/src/wp-includes/block-supports/background.php @@ -42,6 +42,7 @@ function wp_register_background_support( $block_type ) { * @since 6.4.0 * @since 6.5.0 Added support for `backgroundPosition` and `backgroundRepeat` output. * @since 6.6.0 Removed requirement for `backgroundImage.source`. A file/url is the default. + * @since 6.7.0 Added support for `backgroundAttachment` output. * * @access private * @@ -62,11 +63,12 @@ function wp_render_background_support( $block_content, $block ) { return $block_content; } - $background_styles = array(); - $background_styles['backgroundImage'] = $block_attributes['style']['background']['backgroundImage'] ?? null; - $background_styles['backgroundSize'] = $block_attributes['style']['background']['backgroundSize'] ?? null; - $background_styles['backgroundPosition'] = $block_attributes['style']['background']['backgroundPosition'] ?? null; - $background_styles['backgroundRepeat'] = $block_attributes['style']['background']['backgroundRepeat'] ?? null; + $background_styles = array(); + $background_styles['backgroundImage'] = $block_attributes['style']['background']['backgroundImage'] ?? null; + $background_styles['backgroundSize'] = $block_attributes['style']['background']['backgroundSize'] ?? null; + $background_styles['backgroundPosition'] = $block_attributes['style']['background']['backgroundPosition'] ?? null; + $background_styles['backgroundRepeat'] = $block_attributes['style']['background']['backgroundRepeat'] ?? null; + $background_styles['backgroundAttachment'] = $block_attributes['style']['background']['backgroundAttachment'] ?? null; if ( ! empty( $background_styles['backgroundImage'] ) ) { $background_styles['backgroundSize'] = $background_styles['backgroundSize'] ?? 'cover'; diff --git a/src/wp-includes/class-wp-theme-json.php b/src/wp-includes/class-wp-theme-json.php index 631dd1f703e67..e6ca23bff310d 100644 --- a/src/wp-includes/class-wp-theme-json.php +++ b/src/wp-includes/class-wp-theme-json.php @@ -226,6 +226,7 @@ class WP_Theme_JSON { * @since 6.4.0 Added `writing-mode` property. * @since 6.5.0 Added `aspect-ratio` property. * @since 6.6.0 Added `background-[image|position|repeat|size]` properties. + * @since 6.7.0 Added `background-attachment` property. * * @var array */ @@ -237,6 +238,7 @@ class WP_Theme_JSON { 'background-position' => array( 'background', 'backgroundPosition' ), 'background-repeat' => array( 'background', 'backgroundRepeat' ), 'background-size' => array( 'background', 'backgroundSize' ), + 'background-attachment' => array( 'background', 'backgroundAttachment' ), 'border-radius' => array( 'border', 'radius' ), 'border-top-left-radius' => array( 'border', 'radius', 'topLeft' ), 'border-top-right-radius' => array( 'border', 'radius', 'topRight' ), @@ -520,10 +522,11 @@ class WP_Theme_JSON { */ const VALID_STYLES = array( 'background' => array( - 'backgroundImage' => null, - 'backgroundPosition' => null, - 'backgroundRepeat' => null, - 'backgroundSize' => null, + 'backgroundImage' => null, + 'backgroundPosition' => null, + 'backgroundRepeat' => null, + 'backgroundSize' => null, + 'backgroundAttachment' => null, ), 'border' => array( 'color' => 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 1ba813ed65b14..3012ca3eefd30 100644 --- a/src/wp-includes/style-engine/class-wp-style-engine.php +++ b/src/wp-includes/style-engine/class-wp-style-engine.php @@ -50,31 +50,37 @@ final class WP_Style_Engine { */ const BLOCK_STYLE_DEFINITIONS_METADATA = array( 'background' => array( - 'backgroundImage' => array( + 'backgroundImage' => array( 'property_keys' => array( 'default' => 'background-image', ), 'value_func' => array( self::class, 'get_url_or_value_css_declaration' ), 'path' => array( 'background', 'backgroundImage' ), ), - 'backgroundPosition' => array( + 'backgroundPosition' => array( 'property_keys' => array( 'default' => 'background-position', ), 'path' => array( 'background', 'backgroundPosition' ), ), - 'backgroundRepeat' => array( + 'backgroundRepeat' => array( 'property_keys' => array( 'default' => 'background-repeat', ), 'path' => array( 'background', 'backgroundRepeat' ), ), - 'backgroundSize' => array( + 'backgroundSize' => array( 'property_keys' => array( 'default' => 'background-size', ), 'path' => array( 'background', 'backgroundSize' ), ), + 'backgroundAttachment' => array( + 'property_keys' => array( + 'default' => 'background-attachment', + ), + 'path' => array( 'background', 'backgroundAttachment' ), + ), ), 'color' => array( 'text' => array( diff --git a/tests/phpunit/tests/block-supports/wpRenderBackgroundSupport.php b/tests/phpunit/tests/block-supports/wpRenderBackgroundSupport.php index 3fa7da28908a3..1f965cdc3f323 100644 --- a/tests/phpunit/tests/block-supports/wpRenderBackgroundSupport.php +++ b/tests/phpunit/tests/block-supports/wpRenderBackgroundSupport.php @@ -69,6 +69,7 @@ public function filter_set_theme_root() { * @ticket 59357 * @ticket 60175 * @ticket 61123 + * @ticket 61720 * * @covers ::wp_render_background_support * @@ -139,20 +140,21 @@ public function data_background_block_support() { 'expected_wrapper' => '
Content
', 'wrapper' => '
Content
', ), - 'background image style with contain, position, and repeat is applied' => array( + 'background image style with contain, position, attachment, and repeat is applied' => array( 'theme_name' => 'block-theme-child-with-fluid-typography', 'block_name' => 'test/background-rules-are-output', 'background_settings' => array( 'backgroundImage' => true, ), 'background_style' => array( - 'backgroundImage' => array( + 'backgroundImage' => array( 'url' => 'https://example.com/image.jpg', ), - 'backgroundRepeat' => 'no-repeat', - 'backgroundSize' => 'contain', + 'backgroundRepeat' => 'no-repeat', + 'backgroundSize' => 'contain', + 'backgroundAttachment' => 'fixed', ), - 'expected_wrapper' => '
Content
', + 'expected_wrapper' => '
Content
', 'wrapper' => '
Content
', ), 'background image style is appended if a style attribute already exists' => array( diff --git a/tests/phpunit/tests/style-engine/styleEngine.php b/tests/phpunit/tests/style-engine/styleEngine.php index 9092ce5b6df03..686865c6803ab 100644 --- a/tests/phpunit/tests/style-engine/styleEngine.php +++ b/tests/phpunit/tests/style-engine/styleEngine.php @@ -28,6 +28,7 @@ public function tear_down() { * @ticket 58549 * @ticket 58590 * @ticket 60175 + * @ticket 61720 * * @covers ::wp_style_engine_get_styles * @@ -539,22 +540,24 @@ public function data_wp_style_engine_get_styles() { 'inline_background_image_url_with_background_size' => array( 'block_styles' => array( 'background' => array( - 'backgroundImage' => array( + 'backgroundImage' => array( 'url' => 'https://example.com/image.jpg', ), - 'backgroundPosition' => 'center', - 'backgroundRepeat' => 'no-repeat', - 'backgroundSize' => 'cover', + 'backgroundPosition' => 'center', + 'backgroundRepeat' => 'no-repeat', + 'backgroundSize' => 'cover', + 'backgroundAttachment' => 'fixed', ), ), 'options' => array(), 'expected_output' => array( - 'css' => "background-image:url('https://example.com/image.jpg');background-position:center;background-repeat:no-repeat;background-size:cover;", + 'css' => "background-image:url('https://example.com/image.jpg');background-position:center;background-repeat:no-repeat;background-size:cover;background-attachment:fixed;", 'declarations' => array( - 'background-image' => "url('https://example.com/image.jpg')", - 'background-position' => 'center', - 'background-repeat' => 'no-repeat', - 'background-size' => 'cover', + 'background-image' => "url('https://example.com/image.jpg')", + 'background-position' => 'center', + 'background-repeat' => 'no-repeat', + 'background-size' => 'cover', + 'background-attachment' => 'fixed', ), ), ), diff --git a/tests/phpunit/tests/theme/wpThemeJson.php b/tests/phpunit/tests/theme/wpThemeJson.php index bc8ef8121ddd0..57d25ab8e6f03 100644 --- a/tests/phpunit/tests/theme/wpThemeJson.php +++ b/tests/phpunit/tests/theme/wpThemeJson.php @@ -4997,6 +4997,7 @@ public function test_get_shadow_styles_for_blocks() { * * @ticket 61123 * @ticket 61165 + * @ticket 61720 */ public function test_get_top_level_background_image_styles() { $theme_json = new WP_Theme_JSON( @@ -5004,12 +5005,13 @@ public function test_get_top_level_background_image_styles() { 'version' => WP_Theme_JSON::LATEST_SCHEMA, 'styles' => array( 'background' => array( - 'backgroundImage' => array( + 'backgroundImage' => array( 'url' => 'http://example.org/image.png', ), - 'backgroundSize' => 'contain', - 'backgroundRepeat' => 'no-repeat', - 'backgroundPosition' => 'center center', + 'backgroundSize' => 'contain', + 'backgroundRepeat' => 'no-repeat', + 'backgroundPosition' => 'center center', + 'backgroundAttachment' => 'fixed', ), ), ) @@ -5020,7 +5022,7 @@ public function test_get_top_level_background_image_styles() { 'selector' => 'body', ); - $expected_styles = "html{min-height: calc(100% - var(--wp-admin--admin-bar--height, 0px));}:root :where(body){background-image: url('http://example.org/image.png');background-position: center center;background-repeat: no-repeat;background-size: contain;}"; + $expected_styles = "html{min-height: calc(100% - var(--wp-admin--admin-bar--height, 0px));}:root :where(body){background-image: url('http://example.org/image.png');background-position: center center;background-repeat: no-repeat;background-size: contain;background-attachment: fixed;}"; $this->assertSame( $expected_styles, $theme_json->get_styles_for_block( $body_node ), 'Styles returned from "::get_stylesheet()" with top-level background styles type do not match expectations' ); $theme_json = new WP_Theme_JSON( @@ -5028,21 +5030,22 @@ public function test_get_top_level_background_image_styles() { 'version' => WP_Theme_JSON::LATEST_SCHEMA, 'styles' => array( 'background' => array( - 'backgroundImage' => "url('http://example.org/image.png')", - 'backgroundSize' => 'contain', - 'backgroundRepeat' => 'no-repeat', - 'backgroundPosition' => 'center center', + 'backgroundImage' => "url('http://example.org/image.png')", + 'backgroundSize' => 'contain', + 'backgroundRepeat' => 'no-repeat', + 'backgroundPosition' => 'center center', + 'backgroundAttachment' => 'fixed', ), ), ) ); - $expected_styles = "html{min-height: calc(100% - var(--wp-admin--admin-bar--height, 0px));}:root :where(body){background-image: url('http://example.org/image.png');background-position: center center;background-repeat: no-repeat;background-size: contain;}"; $this->assertSame( $expected_styles, $theme_json->get_styles_for_block( $body_node ), 'Styles returned from "::get_stylesheet()" with top-level background image as string type do not match expectations' ); } /** * @ticket 61588 + * @ticket 61720 */ public function test_get_block_background_image_styles() { $theme_json = new WP_Theme_JSON( @@ -5052,10 +5055,11 @@ public function test_get_block_background_image_styles() { 'blocks' => array( 'core/group' => array( 'background' => array( - 'backgroundImage' => "url('http://example.org/group.png')", - 'backgroundSize' => 'cover', - 'backgroundRepeat' => 'no-repeat', - 'backgroundPosition' => 'center center', + 'backgroundImage' => "url('http://example.org/group.png')", + 'backgroundSize' => 'cover', + 'backgroundRepeat' => 'no-repeat', + 'backgroundPosition' => 'center center', + 'backgroundAttachment' => 'fixed', ), ), 'core/quote' => array( @@ -5094,7 +5098,7 @@ public function test_get_block_background_image_styles() { ), ); - $group_styles = ":root :where(.wp-block-group){background-image: url('http://example.org/group.png');background-position: center center;background-repeat: no-repeat;background-size: cover;}"; + $group_styles = ":root :where(.wp-block-group){background-image: url('http://example.org/group.png');background-position: center center;background-repeat: no-repeat;background-size: cover;background-attachment: fixed;}"; $this->assertSame( $group_styles, $theme_json->get_styles_for_block( $group_node ), 'Styles returned from "::get_styles_for_block()" with block-level background styles as string type do not match expectations' ); }