Skip to content

Commit

Permalink
This commit checks for theme block styles in the block supports hook …
Browse files Browse the repository at this point in the history
…so a background block control can determine whether it has an inherited value. If there is an inherited value, the block control will provide an option to "remove" the theme style.

This commit also sends resolved theme asset URI via the _links property so that these images can be used in block control previews.

Added resolver tests for blocks

Use `get_styles_for_block` in unit tests when testing block nodes

Use `get_styles_for_block` in unit tests when testing block nodes

Add since annotation

backport changelog
  • Loading branch information
ramonjd committed Jun 17, 2024
1 parent 7d3155d commit 8d21b43
Show file tree
Hide file tree
Showing 8 changed files with 159 additions and 35 deletions.
3 changes: 3 additions & 0 deletions backport-changelog/6.7/6836.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
https://github.com/WordPress/wordpress-develop/pull/6836

* https://github.com/WordPress/gutenberg/pull/60100
1 change: 1 addition & 0 deletions lib/class-wp-theme-json-resolver-gutenberg.php
Original file line number Diff line number Diff line change
Expand Up @@ -781,6 +781,7 @@ public static function get_style_variations( $scope = 'theme' ) {
* as the value of `_link` object in REST API responses.
*
* @since 6.6.0
* @since 6.7.0 Added support for resolving block styles.
*
* @param WP_Theme_JSON_Gutenberg $theme_json A theme json instance.
* @return array An array of resolved paths.
Expand Down
29 changes: 25 additions & 4 deletions packages/block-editor/src/hooks/background.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,10 @@ import {
useHasBackgroundPanel,
hasBackgroundImageValue,
} from '../components/global-styles/background-panel';
import {
globalStylesDataKey,
globalStylesLinksDataKey,
} from '../store/private-keys';

export const BACKGROUND_SUPPORT_KEY = 'background';

Expand Down Expand Up @@ -134,10 +138,25 @@ export function BackgroundImagePanel( {
setAttributes,
settings,
} ) {
const style = useSelect(
( select ) =>
select( blockEditorStore ).getBlockAttributes( clientId )?.style,
[ clientId ]
const { style, inheritedValue, _links } = useSelect(
( select ) => {
const { getBlockAttributes, getSettings } =
select( blockEditorStore );
const _settings = getSettings();
return {
style: getBlockAttributes( clientId )?.style,
_links: _settings[ globalStylesLinksDataKey ],
/*
* @TODO 1. Pass inherited value down to all block style controls,
* See: packages/block-editor/src/hooks/style.js
* @TODO 2. Add support for block style variations,
* See implementation: packages/block-editor/src/hooks/block-style-variation.js
*/
inheritedValue:
_settings[ globalStylesDataKey ]?.blocks?.[ name ],
};
},
[ clientId, name ]
);

if (
Expand Down Expand Up @@ -170,13 +189,15 @@ export function BackgroundImagePanel( {

return (
<StylesBackgroundPanel
inheritedValue={ inheritedValue }
as={ BackgroundInspectorControl }
panelId={ clientId }
defaultControls={ defaultControls }
defaultValues={ BACKGROUND_DEFAULT_VALUES }
settings={ updatedSettings }
onChange={ onChange }
value={ style }
themeFileURIs={ _links?.[ 'wp:theme-file' ] }
/>
);
}
Expand Down
2 changes: 2 additions & 0 deletions packages/block-editor/src/private-apis.js
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ import {
selectBlockPatternsKey,
reusableBlocksSelectKey,
globalStylesDataKey,
globalStylesLinksDataKey,
} from './store/private-keys';
import { requiresWrapperOnCopy } from './components/writing-flow/utils';
import { PrivateRichText } from './components/rich-text/';
Expand Down Expand Up @@ -83,6 +84,7 @@ lock( privateApis, {
usesContextKey,
useFlashEditableBlocks,
globalStylesDataKey,
globalStylesLinksDataKey,
selectBlockPatternsKey,
requiresWrapperOnCopy,
PrivateRichText,
Expand Down
1 change: 1 addition & 0 deletions packages/block-editor/src/store/private-keys.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
export const globalStylesDataKey = Symbol( 'globalStylesDataKey' );
export const globalStylesLinksDataKey = Symbol( 'globalStylesLinks' );
export const selectBlockPatternsKey = Symbol( 'selectBlockPatternsKey' );
export const reusableBlocksSelectKey = Symbol( 'reusableBlocksSelect' );
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ import { lock, unlock } from '../../lock-unlock';
import { useGlobalStylesContext } from '../global-styles-provider';

const EMPTY_BLOCKS_LIST = [];
const DEFAULT_STYLES = {};
const EMPTY_OBJECT = {};

function __experimentalReusableBlocksSelect( select ) {
return (
Expand Down Expand Up @@ -88,8 +88,12 @@ const BLOCK_EDITOR_SETTINGS = [
'__experimentalArchiveTitleNameLabel',
];

const { globalStylesDataKey, selectBlockPatternsKey, reusableBlocksSelectKey } =
unlock( privateApis );
const {
globalStylesDataKey,
globalStylesLinksDataKey,
selectBlockPatternsKey,
reusableBlocksSelectKey,
} = unlock( privateApis );

/**
* React hook used to compute the block editor settings to use for the post editor.
Expand Down Expand Up @@ -179,7 +183,8 @@ function useBlockEditorSettings( settings, postType, postId, renderingMode ) {
);

const { merged: mergedGlobalStyles } = useGlobalStylesContext();
const globalStylesData = mergedGlobalStyles.styles ?? DEFAULT_STYLES;
const globalStylesData = mergedGlobalStyles.styles ?? EMPTY_OBJECT;
const globalStylesLinksData = mergedGlobalStyles._links ?? EMPTY_OBJECT;

const settingsBlockPatterns =
settings.__experimentalAdditionalBlockPatterns ?? // WP 6.0
Expand Down Expand Up @@ -268,6 +273,7 @@ function useBlockEditorSettings( settings, postType, postId, renderingMode ) {
)
),
[ globalStylesDataKey ]: globalStylesData,
[ globalStylesLinksDataKey ]: globalStylesLinksData,
allowedBlockTypes,
allowRightClickOverrides,
focusMode: focusMode && ! forceDisableFocusMode,
Expand Down
60 changes: 60 additions & 0 deletions phpunit/class-wp-theme-json-resolver-test.php
Original file line number Diff line number Diff line change
Expand Up @@ -1204,6 +1204,22 @@ public function test_resolve_theme_file_uris() {
'url' => 'file:./example/img/image.png',
),
),
'blocks' => array(
'core/quote' => array(
'background' => array(
'backgroundImage' => array(
'url' => 'file:./example/img/quote.png',
),
),
),
'core/verse' => array(
'background' => array(
'backgroundImage' => array(
'url' => 'file:./example/img/verse.png',
),
),
),
),
),
)
);
Expand All @@ -1216,6 +1232,22 @@ public function test_resolve_theme_file_uris() {
'url' => 'https://example.org/wp-content/themes/example-theme/example/img/image.png',
),
),
'blocks' => array(
'core/quote' => array(
'background' => array(
'backgroundImage' => array(
'url' => 'https://example.org/wp-content/themes/example-theme/example/img/quote.png',
),
),
),
'core/verse' => array(
'background' => array(
'backgroundImage' => array(
'url' => 'https://example.org/wp-content/themes/example-theme/example/img/verse.png',
),
),
),
),
),
);

Expand Down Expand Up @@ -1249,6 +1281,22 @@ public function test_get_resolved_theme_uris() {
'url' => 'file:./example/img/image.png',
),
),
'blocks' => array(
'core/quote' => array(
'background' => array(
'backgroundImage' => array(
'url' => 'file:./example/img/quote.jpg',
),
),
),
'core/verse' => array(
'background' => array(
'backgroundImage' => array(
'url' => 'file:./example/img/verse.gif',
),
),
),
),
),
)
);
Expand All @@ -1260,6 +1308,18 @@ public function test_get_resolved_theme_uris() {
'target' => 'styles.background.backgroundImage.url',
'type' => 'image/png',
),
array(
'name' => 'file:./example/img/quote.jpg',
'href' => 'https://example.org/wp-content/themes/example-theme/example/img/quote.jpg',
'target' => 'styles.blocks.core/quote.background.backgroundImage.url',
'type' => 'image/jpeg',
),
array(
'name' => 'file:./example/img/verse.gif',
'href' => 'https://example.org/wp-content/themes/example-theme/example/img/verse.gif',
'target' => 'styles.blocks.core/verse.background.backgroundImage.url',
'type' => 'image/gif',
),
);

/*
Expand Down
84 changes: 57 additions & 27 deletions phpunit/class-wp-theme-json-test.php
Original file line number Diff line number Diff line change
Expand Up @@ -4788,36 +4788,62 @@ public function test_get_shadow_styles_for_blocks() {
$this->assertSame( $expected_styles, $theme_json->get_stylesheet() );
}

public function test_get_top_level_and_block_background_image_styles() {
public function test_get_top_level_background_image_styles() {
$theme_json = new WP_Theme_JSON_Gutenberg(
array(
'version' => WP_Theme_JSON_Gutenberg::LATEST_SCHEMA,
'styles' => array(
'background' => array(
'backgroundImage' => array(
'url' => 'http://example.org/body.png',
'url' => 'http://example.org/image.png',
),
'backgroundSize' => 'contain',
'backgroundRepeat' => 'no-repeat',
'backgroundPosition' => 'center center',
),
'blocks' => array(
'core/paragraph' => array(
),
)
);

$expected_styles = ":where(body) { margin: 0; }.wp-site-blocks > .alignleft { float: left; margin-right: 2em; }.wp-site-blocks > .alignright { float: right; margin-left: 2em; }.wp-site-blocks > .aligncenter { justify-content: center; margin-left: auto; margin-right: auto; }:where(.is-layout-flex){gap: 0.5em;}:where(.is-layout-grid){gap: 0.5em;}.is-layout-flow > .alignleft{float: left;margin-inline-start: 0;margin-inline-end: 2em;}.is-layout-flow > .alignright{float: right;margin-inline-start: 2em;margin-inline-end: 0;}.is-layout-flow > .aligncenter{margin-left: auto !important;margin-right: auto !important;}.is-layout-constrained > .alignleft{float: left;margin-inline-start: 0;margin-inline-end: 2em;}.is-layout-constrained > .alignright{float: right;margin-inline-start: 2em;margin-inline-end: 0;}.is-layout-constrained > .aligncenter{margin-left: auto !important;margin-right: auto !important;}.is-layout-constrained > :where(:not(.alignleft):not(.alignright):not(.alignfull)){margin-left: auto !important;margin-right: auto !important;}body .is-layout-flex{display: flex;}.is-layout-flex{flex-wrap: wrap;align-items: center;}.is-layout-flex > :is(*, div){margin: 0;}body .is-layout-grid{display: grid;}.is-layout-grid > :is(*, div){margin: 0;}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_stylesheet(), 'Styles returned from "::get_stylesheet()" with top-level background styles does not match expectations' );

$theme_json = new WP_Theme_JSON_Gutenberg(
array(
'version' => WP_Theme_JSON_Gutenberg::LATEST_SCHEMA,
'styles' => array(
'background' => array(
'backgroundImage' => "url('http://example.org/image.png')",
'backgroundSize' => 'contain',
'backgroundRepeat' => 'no-repeat',
'backgroundPosition' => 'center center',
),
),
)
);

$expected_styles = ":where(body) { margin: 0; }.wp-site-blocks > .alignleft { float: left; margin-right: 2em; }.wp-site-blocks > .alignright { float: right; margin-left: 2em; }.wp-site-blocks > .aligncenter { justify-content: center; margin-left: auto; margin-right: auto; }:where(.is-layout-flex){gap: 0.5em;}:where(.is-layout-grid){gap: 0.5em;}.is-layout-flow > .alignleft{float: left;margin-inline-start: 0;margin-inline-end: 2em;}.is-layout-flow > .alignright{float: right;margin-inline-start: 2em;margin-inline-end: 0;}.is-layout-flow > .aligncenter{margin-left: auto !important;margin-right: auto !important;}.is-layout-constrained > .alignleft{float: left;margin-inline-start: 0;margin-inline-end: 2em;}.is-layout-constrained > .alignright{float: right;margin-inline-start: 2em;margin-inline-end: 0;}.is-layout-constrained > .aligncenter{margin-left: auto !important;margin-right: auto !important;}.is-layout-constrained > :where(:not(.alignleft):not(.alignright):not(.alignfull)){margin-left: auto !important;margin-right: auto !important;}body .is-layout-flex{display: flex;}.is-layout-flex{flex-wrap: wrap;align-items: center;}.is-layout-flex > :is(*, div){margin: 0;}body .is-layout-grid{display: grid;}.is-layout-grid > :is(*, div){margin: 0;}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_stylesheet(), 'Styles returned from "::get_stylesheet()" with top-level background image as string type does not match expectations' );
}

public function test_get_block_background_image_styles() {
$theme_json = new WP_Theme_JSON_Gutenberg(
array(
'version' => WP_Theme_JSON_Gutenberg::LATEST_SCHEMA,
'styles' => array(
'blocks' => array(
'core/group' => array(
'background' => array(
'backgroundImage' => array(
'url' => 'http://example.org/paragraph.png',
),
'backgroundImage' => "url('http://example.org/group.png')",
'backgroundSize' => 'cover',
'backgroundRepeat' => 'no-repeat',
'backgroundPosition' => 'center center',
),
),
),
'elements' => array(
'button' => array(
'core/quote' => array(
'background' => array(
'backgroundImage' => array(
'url' => 'http://example.org/button.png',
'url' => 'http://example.org/quote.png',
),
'backgroundSize' => 'cover',
'backgroundRepeat' => 'no-repeat',
Expand All @@ -4829,25 +4855,29 @@ public function test_get_top_level_and_block_background_image_styles() {
)
);

$expected_styles = ":where(body) { margin: 0; }.wp-site-blocks > .alignleft { float: left; margin-right: 2em; }.wp-site-blocks > .alignright { float: right; margin-left: 2em; }.wp-site-blocks > .aligncenter { justify-content: center; margin-left: auto; margin-right: auto; }:where(.is-layout-flex){gap: 0.5em;}:where(.is-layout-grid){gap: 0.5em;}.is-layout-flow > .alignleft{float: left;margin-inline-start: 0;margin-inline-end: 2em;}.is-layout-flow > .alignright{float: right;margin-inline-start: 2em;margin-inline-end: 0;}.is-layout-flow > .aligncenter{margin-left: auto !important;margin-right: auto !important;}.is-layout-constrained > .alignleft{float: left;margin-inline-start: 0;margin-inline-end: 2em;}.is-layout-constrained > .alignright{float: right;margin-inline-start: 2em;margin-inline-end: 0;}.is-layout-constrained > .aligncenter{margin-left: auto !important;margin-right: auto !important;}.is-layout-constrained > :where(:not(.alignleft):not(.alignright):not(.alignfull)){margin-left: auto !important;margin-right: auto !important;}body .is-layout-flex{display: flex;}.is-layout-flex{flex-wrap: wrap;align-items: center;}.is-layout-flex > :is(*, div){margin: 0;}body .is-layout-grid{display: grid;}.is-layout-grid > :is(*, div){margin: 0;}html{min-height: calc(100% - var(--wp-admin--admin-bar--height, 0px));}:root :where(body){background-image: url('http://example.org/body.png');background-position: center center;background-repeat: no-repeat;background-size: contain;}:root :where(.wp-element-button, .wp-block-button__link){background-image: url('http://example.org/button.png');background-position: center center;background-repeat: no-repeat;background-size: cover;}:root :where(p){background-image: url('http://example.org/paragraph.png');background-position: center center;background-repeat: no-repeat;background-size: cover;}";
$this->assertSame( $expected_styles, $theme_json->get_stylesheet(), 'Styles returned from "::get_stylesheet()" with top-level background styles type does not match expectations' );
$quote_node = array(
'name' => 'core/quote',
'path' => array( 'styles', 'blocks', 'core/quote' ),
'selector' => '.wp-block-quote',
'selectors' => array(
'root' => '.wp-block-quote',
),
);

$theme_json = new WP_Theme_JSON_Gutenberg(
array(
'version' => WP_Theme_JSON_Gutenberg::LATEST_SCHEMA,
'styles' => array(
'background' => array(
'backgroundImage' => "url('http://example.org/image.png')",
'backgroundSize' => 'contain',
'backgroundRepeat' => 'no-repeat',
'backgroundPosition' => 'center center',
),
),
)
$quote_styles = ":root :where(.wp-block-quote){background-image: url('http://example.org/quote.png');background-position: center center;background-repeat: no-repeat;background-size: cover;}";
$this->assertSame( $quote_styles, $theme_json->get_styles_for_block( $quote_node ), 'Styles returned from "::get_stylesheet()" with block-level background styles does not match expectations' );

$group_node = array(
'name' => 'core/group',
'path' => array( 'styles', 'blocks', 'core/group' ),
'selector' => '.wp-block-group',
'selectors' => array(
'root' => '.wp-block-group',
),
);

$expected_styles = ":where(body) { margin: 0; }.wp-site-blocks > .alignleft { float: left; margin-right: 2em; }.wp-site-blocks > .alignright { float: right; margin-left: 2em; }.wp-site-blocks > .aligncenter { justify-content: center; margin-left: auto; margin-right: auto; }:where(.is-layout-flex){gap: 0.5em;}:where(.is-layout-grid){gap: 0.5em;}.is-layout-flow > .alignleft{float: left;margin-inline-start: 0;margin-inline-end: 2em;}.is-layout-flow > .alignright{float: right;margin-inline-start: 2em;margin-inline-end: 0;}.is-layout-flow > .aligncenter{margin-left: auto !important;margin-right: auto !important;}.is-layout-constrained > .alignleft{float: left;margin-inline-start: 0;margin-inline-end: 2em;}.is-layout-constrained > .alignright{float: right;margin-inline-start: 2em;margin-inline-end: 0;}.is-layout-constrained > .aligncenter{margin-left: auto !important;margin-right: auto !important;}.is-layout-constrained > :where(:not(.alignleft):not(.alignright):not(.alignfull)){margin-left: auto !important;margin-right: auto !important;}body .is-layout-flex{display: flex;}.is-layout-flex{flex-wrap: wrap;align-items: center;}.is-layout-flex > :is(*, div){margin: 0;}body .is-layout-grid{display: grid;}.is-layout-grid > :is(*, div){margin: 0;}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_stylesheet(), 'Styles returned from "::get_stylesheet()" with top-level background image as string type does not match expectations' );
$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;}";
$this->assertSame( $group_styles, $theme_json->get_styles_for_block( $group_node ), 'Styles returned from "::get_stylesheet()" with block-level background styles as string type does not match expectations' );
}

/**
Expand Down

0 comments on commit 8d21b43

Please sign in to comment.