diff --git a/backport-changelog/6.6/6522.md b/backport-changelog/6.6/6522.md
new file mode 100644
index 00000000000000..172464cf664de9
--- /dev/null
+++ b/backport-changelog/6.6/6522.md
@@ -0,0 +1,5 @@
+https://github.com/WordPress/wordpress-develop/pull/6522
+
+* https://github.com/WordPress/gutenberg/pull/60106
+* https://github.com/WordPress/gutenberg/pull/60228
+* https://github.com/WordPress/gutenberg/pull/61638
diff --git a/backport-changelog/6.6/6656.md b/backport-changelog/6.6/6656.md
new file mode 100644
index 00000000000000..f0bf8900335f49
--- /dev/null
+++ b/backport-changelog/6.6/6656.md
@@ -0,0 +1,3 @@
+https://github.com/WordPress/wordpress-develop/pull/6656
+
+* https://github.com/WordPress/gutenberg/pull/60715
\ No newline at end of file
diff --git a/lib/class-wp-theme-json-gutenberg.php b/lib/class-wp-theme-json-gutenberg.php
index 1dec7b164d880b..b5636ad7c8dc57 100644
--- a/lib/class-wp-theme-json-gutenberg.php
+++ b/lib/class-wp-theme-json-gutenberg.php
@@ -1293,7 +1293,7 @@ protected function process_blocks_custom_css( $css, $selector ) {
$is_root_css = ( ! str_contains( $part, '{' ) );
if ( $is_root_css ) {
// If the part doesn't contain braces, it applies to the root level.
- $processed_css .= trim( $selector ) . '{' . trim( $part ) . '}';
+ $processed_css .= ':root :where(' . trim( $selector ) . '){' . trim( $part ) . '}';
} else {
// If the part contains braces, it's a nested CSS rule.
$part = explode( '{', str_replace( '}', '', $part ) );
@@ -1305,7 +1305,8 @@ protected function process_blocks_custom_css( $css, $selector ) {
$part_selector = str_starts_with( $nested_selector, ' ' )
? static::scope_selector( $selector, $nested_selector )
: static::append_to_selector( $selector, $nested_selector );
- $processed_css .= $part_selector . '{' . trim( $css_value ) . '}';
+ $final_selector = ":root :where($part_selector)";
+ $processed_css .= $final_selector . '{' . trim( $css_value ) . '}';
}
}
return $processed_css;
@@ -1322,6 +1323,7 @@ public function get_custom_css() {
$block_custom_css = '';
$block_nodes = $this->get_block_custom_css_nodes();
foreach ( $block_nodes as $node ) {
+ // The node selector will have its specificity set to 0-1-0 within process_blocks_custom_css.
$block_custom_css .= $this->get_block_custom_css( $node['css'], $node['selector'] );
}
@@ -1564,7 +1566,7 @@ protected function get_layout_styles( $block_metadata, $types = array() ) {
$spacing_rule['selector']
);
} else {
- $format = static::ROOT_BLOCK_SELECTOR === $selector ? ':where(.%2$s) %3$s' : ':where(%1$s-%2$s) %3$s';
+ $format = static::ROOT_BLOCK_SELECTOR === $selector ? '.%2$s %3$s' : '%1$s-%2$s %3$s';
$layout_selector = sprintf(
$format,
$selector,
@@ -2745,7 +2747,7 @@ static function ( $pseudo_selector ) use ( $selector ) {
}
// 2. Generate and append the rules that use the general selector.
- $block_rules .= static::to_ruleset( ":where($selector)", $declarations );
+ $block_rules .= static::to_ruleset( ":root :where($selector)", $declarations );
// 3. Generate and append the rules that use the duotone selector.
if ( isset( $block_metadata['duotone'] ) && ! empty( $declarations_duotone ) ) {
@@ -2762,12 +2764,12 @@ static function ( $pseudo_selector ) use ( $selector ) {
// 5. Generate and append the feature level rulesets.
foreach ( $feature_declarations as $feature_selector => $individual_feature_declarations ) {
- $block_rules .= static::to_ruleset( ":where($feature_selector)", $individual_feature_declarations );
+ $block_rules .= static::to_ruleset( ":root :where($feature_selector)", $individual_feature_declarations );
}
// 6. Generate and append the style variation rulesets.
foreach ( $style_variation_declarations as $style_variation_selector => $individual_style_variation_declarations ) {
- $block_rules .= static::to_ruleset( $style_variation_selector, $individual_style_variation_declarations );
+ $block_rules .= static::to_ruleset( ":root :where($style_variation_selector)", $individual_style_variation_declarations );
}
return $block_rules;
@@ -2816,16 +2818,12 @@ public function get_root_layout_rules( $selector, $block_metadata ) {
$css .= '.wp-site-blocks { padding-top: var(--wp--style--root--padding-top); padding-bottom: var(--wp--style--root--padding-bottom); }';
// Right and left padding are applied to the first container with `.has-global-padding` class.
$css .= '.has-global-padding { padding-right: var(--wp--style--root--padding-right); padding-left: var(--wp--style--root--padding-left); }';
- // Nested containers with `.has-global-padding` class do not get padding.
- $css .= '.has-global-padding :where(.has-global-padding:not(.wp-block-block)) { padding-right: 0; padding-left: 0; }';
// Alignfull children of the container with left and right padding have negative margins so they can still be full width.
$css .= '.has-global-padding > .alignfull { margin-right: calc(var(--wp--style--root--padding-right) * -1); margin-left: calc(var(--wp--style--root--padding-left) * -1); }';
- // The above rule is negated for alignfull children of nested containers.
- $css .= '.has-global-padding :where(.has-global-padding:not(.wp-block-block)) > .alignfull { margin-right: 0; margin-left: 0; }';
- // Some of the children of alignfull blocks without content width should also get padding: text blocks and non-alignfull container blocks.
- $css .= '.has-global-padding > .alignfull:where(:not(.has-global-padding):not(.is-layout-flex):not(.is-layout-grid)) > :where([class*="wp-block-"]:not(.alignfull):not([class*="__"]),.wp-block:not(.alignfull),p,h1,h2,h3,h4,h5,h6,ul,ol) { padding-right: var(--wp--style--root--padding-right); padding-left: var(--wp--style--root--padding-left); }';
- // The above rule also has to be negated for blocks inside nested `.has-global-padding` blocks.
- $css .= '.has-global-padding :where(.has-global-padding) > .alignfull:where(:not(.has-global-padding)) > :where([class*="wp-block-"]:not(.alignfull):not([class*="__"]),.wp-block:not(.alignfull),p,h1,h2,h3,h4,h5,h6,ul,ol) { padding-right: 0; padding-left: 0; }';
+ // Nested children of the container with left and right padding that are not wide or full aligned do not get padding.
+ $css .= '.has-global-padding :where(.has-global-padding:not(.wp-block-block, .alignfull, .alignwide)) { padding-right: 0; padding-left: 0; }';
+ // Nested children of the container with left and right padding that are not wide or full aligned do not get negative margin applied.
+ $css .= '.has-global-padding :where(.has-global-padding:not(.wp-block-block, .alignfull, .alignwide)) > .alignfull { margin-left: 0; margin-right: 0; }';
}
$css .= '.wp-site-blocks > .alignleft { float: left; margin-right: 2em; }';
diff --git a/lib/experimental/full-page-client-side-navigation.php b/lib/experimental/full-page-client-side-navigation.php
index ebfddf4aaf4369..621502912a668a 100644
--- a/lib/experimental/full-page-client-side-navigation.php
+++ b/lib/experimental/full-page-client-side-navigation.php
@@ -33,25 +33,69 @@ function _gutenberg_add_enhanced_pagination_to_query_block( $parsed_block ) {
add_filter( 'render_block_data', '_gutenberg_add_enhanced_pagination_to_query_block' );
/**
- * Add directives to all links.
+ * Adds client-side navigation directives to BODY tag.
*
* Note: This should probably be done per site, not by default when this option is enabled.
*
- * @param array $content The block content.
+ * @param string $response_body The response body.
*
- * @return array The same block content with the directives needed.
+ * @return string The rendered template with modified BODY attributes.
*/
-function _gutenberg_add_client_side_navigation_directives( $content ) {
- $p = new WP_HTML_Tag_Processor( $content );
- // Hack to add the necessary directives to the body tag.
- // TODO: Find a proper way to add directives to the body tag.
- static $body_interactive_added;
- if ( ! $body_interactive_added ) {
- $body_interactive_added = true;
- return (string) $p . '
';
+function _gutenberg_add_client_side_navigation_directives( $response_body ) {
+ $is_html_content_type = false;
+ foreach ( headers_list() as $header ) {
+ $header_parts = preg_split( '/\s*[:;]\s*/', strtolower( $header ) );
+ if ( count( $header_parts ) >= 2 && 'content-type' === $header_parts[0] ) {
+ $is_html_content_type = in_array( $header_parts[1], array( 'text/html', 'application/xhtml+xml' ), true );
+ }
}
- return (string) $p;
+ if ( ! $is_html_content_type ) {
+ return $response_body;
+ }
+
+ $p = new WP_HTML_Tag_Processor( $response_body );
+ if ( $p->next_tag( array( 'tag_name' => 'BODY' ) ) ) {
+ $p->set_attribute( 'data-wp-interactive', 'core/experimental' );
+ $p->set_attribute( 'data-wp-context', '{}' );
+ $response_body = $p->get_updated_html();
+ }
+ return $response_body;
}
// TODO: Explore moving this to the server directive processing.
-add_filter( 'render_block', '_gutenberg_add_client_side_navigation_directives' );
+add_filter( 'gutenberg_template_output_buffer', '_gutenberg_add_client_side_navigation_directives' );
+
+/**
+ * Starts output buffering at the end of the 'template_include' filter.
+ *
+ * This is to implement #43258 in core.
+ *
+ * This is a hack which would eventually be replaced with something like this in wp-includes/template-loader.php:
+ *
+ * $template = apply_filters( 'template_include', $template );
+ * + ob_start( 'wp_template_output_buffer_callback' );
+ * if ( $template ) {
+ * include $template;
+ * } elseif ( current_user_can( 'switch_themes' ) ) {
+ *
+ * @link https://core.trac.wordpress.org/ticket/43258
+ *
+ * @param string $passthrough Value for the template_include filter which is passed through.
+ *
+ * @return string Unmodified value of $passthrough.
+ */
+function _gutenberg_buffer_template_output( string $passthrough ): string {
+ ob_start(
+ static function ( string $output ): string {
+ /**
+ * Filters the template output buffer prior to sending to the client.
+ *
+ * @param string $output Output buffer.
+ * @return string Filtered output buffer.
+ */
+ return (string) apply_filters( 'gutenberg_template_output_buffer', $output );
+ }
+ );
+ return $passthrough;
+}
+add_filter( 'template_include', '_gutenberg_buffer_template_output', PHP_INT_MAX );
diff --git a/lib/theme.json b/lib/theme.json
index 7cd6129923df2a..2f1f723bf75f7f 100644
--- a/lib/theme.json
+++ b/lib/theme.json
@@ -370,6 +370,40 @@
"bottom": "0px",
"left": "0px"
}
+ },
+ "blocks": {
+ "core/button": {
+ "variations": {
+ "outline": {
+ "border": {
+ "width": "2px",
+ "style": "solid",
+ "color": "currentColor"
+ },
+ "color": {
+ "text": "currentColor",
+ "gradient": "transparent none"
+ },
+ "spacing": {
+ "padding": {
+ "top": "0.667em",
+ "right": "1.33em",
+ "bottom": "0.667em",
+ "left": "1.33em"
+ }
+ }
+ }
+ }
+ },
+ "core/site-logo": {
+ "variations": {
+ "rounded": {
+ "border": {
+ "radius": "9999px"
+ }
+ }
+ }
+ }
}
}
}
diff --git a/package.json b/package.json
index ac50b0caf19479..f218f9ca808205 100644
--- a/package.json
+++ b/package.json
@@ -276,7 +276,7 @@
"clean:packages": "rimraf \"./packages/*/@(build|build-module|build-style)\"",
"dev": "npm run build:packages && concurrently \"wp-scripts start\" \"npm run dev:packages\"",
"dev:packages": "concurrently \"node ./bin/packages/watch.js\" \"tsc --build --watch\"",
- "distclean": "rimraf node_modules packages/*/node_modules",
+ "distclean": "git clean --force -d -X",
"docs:api-ref": "node ./bin/api-docs/update-api-docs.js",
"docs:blocks": "node ./bin/api-docs/gen-block-lib-list.js",
"docs:build": "npm-run-all docs:gen docs:blocks docs:api-ref docs:theme-ref",
diff --git a/packages/block-editor/src/components/global-styles/background-panel.js b/packages/block-editor/src/components/global-styles/background-panel.js
index 2e73f52564362e..b7cf7f2bbc493d 100644
--- a/packages/block-editor/src/components/global-styles/background-panel.js
+++ b/packages/block-editor/src/components/global-styles/background-panel.js
@@ -102,7 +102,7 @@ function backgroundSizeHelpText( value ) {
if ( value === 'contain' ) {
return __( 'Image is contained without distortion.' );
}
- return __( 'Specify a fixed width.' );
+ return __( 'Image has a fixed width.' );
}
/**
@@ -174,13 +174,13 @@ function InspectorImagePreview( { label, filename, url: imgUrl } ) {
{ imgLabel }
- { filename
+ { imgUrl
? sprintf(
/* translators: %s: file name */
- __( 'Selected image: %s' ),
- filename
+ __( 'Background image: %s' ),
+ filename || imgLabel
)
- : __( 'No image selected' ) }
+ : __( 'No background image selected' ) }
@@ -321,7 +321,7 @@ function BackgroundImageToolsPanelItem( {
name={
- { currentValueForToggle !== undefined &&
- currentValueForToggle !== 'cover' &&
- currentValueForToggle !== 'contain' ? (
-
- ) : null }
- { currentValueForToggle !== 'cover' && (
-
- ) }
+
+ { currentValueForToggle !== undefined &&
+ currentValueForToggle !== 'cover' &&
+ currentValueForToggle !== 'contain' ? (
+
+ ) : null }
+ { currentValueForToggle !== 'cover' && (
+
+ ) }
+
);
}
diff --git a/packages/block-editor/src/components/global-styles/test/use-global-styles-output.js b/packages/block-editor/src/components/global-styles/test/use-global-styles-output.js
index 95de3d4007079c..b858a2e4140ea9 100644
--- a/packages/block-editor/src/components/global-styles/test/use-global-styles-output.js
+++ b/packages/block-editor/src/components/global-styles/test/use-global-styles-output.js
@@ -480,7 +480,7 @@ describe( 'global styles renderer', () => {
};
expect( toStyles( tree, blockSelectors ) ).toEqual(
- ':where(body) {margin: 0;}.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)) { max-width: var(--wp--style--global--content-size); margin-left: auto !important; margin-right: auto !important; }.is-layout-constrained > .alignwide { max-width: var(--wp--style--global--wide-size); }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; }:where(body){background-color: red;margin: 10px;padding: 10px;}:where(a:where(:not(.wp-element-button))){color: blue;}a:where(:not(.wp-element-button)):hover{color: orange;}a:where(:not(.wp-element-button)):focus{color: orange;}:where(h1){font-size: 42px;}:where(.wp-block-group){margin-top: 10px;margin-right: 20px;margin-bottom: 30px;margin-left: 40px;padding-top: 11px;padding-right: 22px;padding-bottom: 33px;padding-left: 44px;}:where(h1,h2,h3,h4,h5,h6){color: orange;}:where(h1 a:where(:not(.wp-element-button)),h2 a:where(:not(.wp-element-button)),h3 a:where(:not(.wp-element-button)),h4 a:where(:not(.wp-element-button)),h5 a:where(:not(.wp-element-button)),h6 a:where(:not(.wp-element-button))){color: hotpink;}h1 a:where(:not(.wp-element-button)):hover,h2 a:where(:not(.wp-element-button)):hover,h3 a:where(:not(.wp-element-button)):hover,h4 a:where(:not(.wp-element-button)):hover,h5 a:where(:not(.wp-element-button)):hover,h6 a:where(:not(.wp-element-button)):hover{color: red;}h1 a:where(:not(.wp-element-button)):focus,h2 a:where(:not(.wp-element-button)):focus,h3 a:where(:not(.wp-element-button)):focus,h4 a:where(:not(.wp-element-button)):focus,h5 a:where(:not(.wp-element-button)):focus,h6 a:where(:not(.wp-element-button)):focus{color: red;}:where(.wp-block-image img, .wp-block-image .wp-crop-area){border-radius: 9999px;}:where(.wp-block-image){color: red;}.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; }.has-white-color{color: var(--wp--preset--color--white) !important;}.has-white-background-color{background-color: var(--wp--preset--color--white) !important;}.has-white-border-color{border-color: var(--wp--preset--color--white) !important;}.has-black-color{color: var(--wp--preset--color--black) !important;}.has-black-background-color{background-color: var(--wp--preset--color--black) !important;}.has-black-border-color{border-color: var(--wp--preset--color--black) !important;}h1.has-blue-color,h2.has-blue-color,h3.has-blue-color,h4.has-blue-color,h5.has-blue-color,h6.has-blue-color{color: var(--wp--preset--color--blue) !important;}h1.has-blue-background-color,h2.has-blue-background-color,h3.has-blue-background-color,h4.has-blue-background-color,h5.has-blue-background-color,h6.has-blue-background-color{background-color: var(--wp--preset--color--blue) !important;}h1.has-blue-border-color,h2.has-blue-border-color,h3.has-blue-border-color,h4.has-blue-border-color,h5.has-blue-border-color,h6.has-blue-border-color{border-color: var(--wp--preset--color--blue) !important;}'
+ ':where(body) {margin: 0;}.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)) { max-width: var(--wp--style--global--content-size); margin-left: auto !important; margin-right: auto !important; }.is-layout-constrained > .alignwide { max-width: var(--wp--style--global--wide-size); }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; }:root :where(body){background-color: red;margin: 10px;padding: 10px;}:root :where(a:where(:not(.wp-element-button))){color: blue;}a:where(:not(.wp-element-button)):hover{color: orange;}a:where(:not(.wp-element-button)):focus{color: orange;}:root :where(h1){font-size: 42px;}:root :where(.wp-block-group){margin-top: 10px;margin-right: 20px;margin-bottom: 30px;margin-left: 40px;padding-top: 11px;padding-right: 22px;padding-bottom: 33px;padding-left: 44px;}:root :where(h1,h2,h3,h4,h5,h6){color: orange;}:root :where(h1 a:where(:not(.wp-element-button)),h2 a:where(:not(.wp-element-button)),h3 a:where(:not(.wp-element-button)),h4 a:where(:not(.wp-element-button)),h5 a:where(:not(.wp-element-button)),h6 a:where(:not(.wp-element-button))){color: hotpink;}h1 a:where(:not(.wp-element-button)):hover,h2 a:where(:not(.wp-element-button)):hover,h3 a:where(:not(.wp-element-button)):hover,h4 a:where(:not(.wp-element-button)):hover,h5 a:where(:not(.wp-element-button)):hover,h6 a:where(:not(.wp-element-button)):hover{color: red;}h1 a:where(:not(.wp-element-button)):focus,h2 a:where(:not(.wp-element-button)):focus,h3 a:where(:not(.wp-element-button)):focus,h4 a:where(:not(.wp-element-button)):focus,h5 a:where(:not(.wp-element-button)):focus,h6 a:where(:not(.wp-element-button)):focus{color: red;}:root :where(.wp-block-image img, .wp-block-image .wp-crop-area){border-radius: 9999px;}:root :where(.wp-block-image){color: red;}.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; }.has-white-color{color: var(--wp--preset--color--white) !important;}.has-white-background-color{background-color: var(--wp--preset--color--white) !important;}.has-white-border-color{border-color: var(--wp--preset--color--white) !important;}.has-black-color{color: var(--wp--preset--color--black) !important;}.has-black-background-color{background-color: var(--wp--preset--color--black) !important;}.has-black-border-color{border-color: var(--wp--preset--color--black) !important;}h1.has-blue-color,h2.has-blue-color,h3.has-blue-color,h4.has-blue-color,h5.has-blue-color,h6.has-blue-color{color: var(--wp--preset--color--blue) !important;}h1.has-blue-background-color,h2.has-blue-background-color,h3.has-blue-background-color,h4.has-blue-background-color,h5.has-blue-background-color,h6.has-blue-background-color{background-color: var(--wp--preset--color--blue) !important;}h1.has-blue-border-color,h2.has-blue-border-color,h3.has-blue-border-color,h4.has-blue-border-color,h5.has-blue-border-color,h6.has-blue-border-color{border-color: var(--wp--preset--color--blue) !important;}'
);
} );
@@ -520,7 +520,7 @@ describe( 'global styles renderer', () => {
};
expect( toStyles( Object.freeze( tree ), blockSelectors ) ).toEqual(
- ':where(body) {margin: 0;}.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)) { max-width: var(--wp--style--global--content-size); margin-left: auto !important; margin-right: auto !important; }.is-layout-constrained > .alignwide { max-width: var(--wp--style--global--wide-size); }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; }:where(.wp-image-spacing){padding-top: 1px;}:where(.wp-image-border-color){border-color: red;}:where(.wp-image-border){border-radius: 9999px;}:where(.wp-image){color: red;}.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(body) {margin: 0;}.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)) { max-width: var(--wp--style--global--content-size); margin-left: auto !important; margin-right: auto !important; }.is-layout-constrained > .alignwide { max-width: var(--wp--style--global--wide-size); }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; }:root :where(.wp-image-spacing){padding-top: 1px;}:root :where(.wp-image-border-color){border-color: red;}:root :where(.wp-image-border){border-radius: 9999px;}:root :where(.wp-image){color: red;}.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; }'
);
} );
@@ -566,7 +566,8 @@ describe( 'global styles renderer', () => {
};
expect( toStyles( Object.freeze( tree ), blockSelectors ) ).toEqual(
- ':where(body) {margin: 0;}.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)) { max-width: var(--wp--style--global--content-size); margin-left: auto !important; margin-right: auto !important; }.is-layout-constrained > .alignwide { max-width: var(--wp--style--global--wide-size); }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; }.is-style-foo.wp-image.wp-image-spacing{padding-top: 2px;}.is-style-foo.wp-image.wp-image-border-color{border-color: blue;}.is-style-foo.wp-image{color: blue;}.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(body) {margin: 0;}.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)) { max-width: var(--wp--style--global--content-size); margin-left: auto !important; margin-right: auto !important; }.is-layout-constrained > .alignwide { max-width: var(--wp--style--global--wide-size); }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; }' +
+ ':root :where(.is-style-foo.wp-image.wp-image-spacing){padding-top: 2px;}:root :where(.is-style-foo.wp-image.wp-image-border-color){border-color: blue;}:root :where(.is-style-foo.wp-image){color: blue;}.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; }'
);
} );
@@ -725,7 +726,7 @@ describe( 'global styles renderer', () => {
} );
expect( layoutStyles ).toEqual(
- ':where(.is-layout-flow) > * { margin-block-start: 0; margin-block-end: 0; }:where(.is-layout-flow) > * + * { margin-block-start: 0.5em; margin-block-end: 0; }:where(.is-layout-flex) { gap: 0.5em; }:root { --wp--style--block-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; }body .is-layout-flex { display:flex; }.is-layout-flex { flex-wrap: wrap; align-items: center; }.is-layout-flex > * { margin: 0; }'
+ '.is-layout-flow > * { margin-block-start: 0; margin-block-end: 0; }.is-layout-flow > * + * { margin-block-start: 0.5em; margin-block-end: 0; }.is-layout-flex { gap: 0.5em; }:root { --wp--style--block-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; }body .is-layout-flex { display:flex; }.is-layout-flex { flex-wrap: wrap; align-items: center; }.is-layout-flex > * { margin: 0; }'
);
} );
@@ -742,7 +743,7 @@ describe( 'global styles renderer', () => {
} );
expect( layoutStyles ).toEqual(
- ':where(.is-layout-flow) > * { margin-block-start: 0; margin-block-end: 0; }:where(.is-layout-flow) > * + * { margin-block-start: 12px; margin-block-end: 0; }:where(.is-layout-flex) { gap: 12px; }:root { --wp--style--block-gap: 12px; }.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; }body .is-layout-flex { display:flex; }.is-layout-flex { flex-wrap: wrap; align-items: center; }.is-layout-flex > * { margin: 0; }'
+ '.is-layout-flow > * { margin-block-start: 0; margin-block-end: 0; }.is-layout-flow > * + * { margin-block-start: 12px; margin-block-end: 0; }.is-layout-flex { gap: 12px; }:root { --wp--style--block-gap: 12px; }.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; }body .is-layout-flex { display:flex; }.is-layout-flex { flex-wrap: wrap; align-items: center; }.is-layout-flex > * { margin: 0; }'
);
} );
@@ -759,7 +760,7 @@ describe( 'global styles renderer', () => {
} );
expect( layoutStyles ).toEqual(
- ':where(.wp-block-group-is-layout-flow) > * { margin-block-start: 0; margin-block-end: 0; }:where(.wp-block-group-is-layout-flow) > * + * { margin-block-start: 12px; margin-block-end: 0; }:where(.wp-block-group-is-layout-flex) { gap: 12px; }'
+ '.wp-block-group-is-layout-flow > * { margin-block-start: 0; margin-block-end: 0; }.wp-block-group-is-layout-flow > * + * { margin-block-start: 12px; margin-block-end: 0; }.wp-block-group-is-layout-flex { gap: 12px; }'
);
} );
@@ -996,7 +997,7 @@ describe( 'global styles renderer', () => {
it( 'should return processed CSS without any nested selectors', () => {
expect(
processCSSNesting( 'color: red; margin: auto;', '.foo' )
- ).toEqual( '.foo{color: red; margin: auto;}' );
+ ).toEqual( ':root :where(.foo){color: red; margin: auto;}' );
} );
it( 'should return processed CSS with nested selectors', () => {
expect(
@@ -1005,7 +1006,7 @@ describe( 'global styles renderer', () => {
'.foo'
)
).toEqual(
- '.foo{color: red; margin: auto;}.foo.one{color: blue;}.foo .two{color: green;}'
+ ':root :where(.foo){color: red; margin: auto;}:root :where(.foo.one){color: blue;}:root :where(.foo .two){color: green;}'
);
} );
it( 'should return processed CSS with pseudo elements', () => {
@@ -1015,7 +1016,7 @@ describe( 'global styles renderer', () => {
'.foo'
)
).toEqual(
- '.foo{color: red; margin: auto;}.foo::before{color: blue;}.foo ::before{color: green;}.foo.one::before{color: yellow;}.foo .two::before{color: purple;}'
+ ':root :where(.foo){color: red; margin: auto;}:root :where(.foo::before){color: blue;}:root :where(.foo ::before){color: green;}:root :where(.foo.one::before){color: yellow;}:root :where(.foo .two::before){color: purple;}'
);
} );
it( 'should return processed CSS with multiple root selectors', () => {
@@ -1025,7 +1026,7 @@ describe( 'global styles renderer', () => {
'.foo, .bar'
)
).toEqual(
- '.foo, .bar{color: red; margin: auto;}.foo.one, .bar.one{color: blue;}.foo .two, .bar .two{color: green;}.foo::before, .bar::before{color: yellow;}.foo ::before, .bar ::before{color: purple;}.foo.three::before, .bar.three::before{color: orange;}.foo .four::before, .bar .four::before{color: skyblue;}'
+ ':root :where(.foo, .bar){color: red; margin: auto;}:root :where(.foo.one, .bar.one){color: blue;}:root :where(.foo .two, .bar .two){color: green;}:root :where(.foo::before, .bar::before){color: yellow;}:root :where(.foo ::before, .bar ::before){color: purple;}:root :where(.foo.three::before, .bar.three::before){color: orange;}:root :where(.foo .four::before, .bar .four::before){color: skyblue;}'
);
} );
} );
diff --git a/packages/block-editor/src/components/global-styles/use-global-styles-output.js b/packages/block-editor/src/components/global-styles/use-global-styles-output.js
index 981189309f828b..f2eaa50a890a9b 100644
--- a/packages/block-editor/src/components/global-styles/use-global-styles-output.js
+++ b/packages/block-editor/src/components/global-styles/use-global-styles-output.js
@@ -522,10 +522,10 @@ export function getLayoutStyles( {
} else {
combinedSelector =
selector === ROOT_BLOCK_SELECTOR
- ? `:where(.${ className })${
+ ? `.${ className }${
spacingStyle?.selector || ''
}`
- : `:where(${ selector }-${ className })${
+ : `${ selector }-${ className }${
spacingStyle?.selector || ''
}`;
}
@@ -815,23 +815,18 @@ export const toStyles = (
*/
ruleset += ':where(body) {margin: 0;';
- // Root padding styles should only be output for full templates, not patterns or template parts.
- if (
- options.rootPadding &&
- useRootPaddingAlign &&
- ! disableRootPadding
- ) {
+ // Root padding styles should be output for full templates, patterns and template parts.
+ if ( options.rootPadding && useRootPaddingAlign ) {
/*
* These rules reproduce the ones from https://github.com/WordPress/gutenberg/blob/79103f124925d1f457f627e154f52a56228ed5ad/lib/class-wp-theme-json-gutenberg.php#L2508
* almost exactly, but for the selectors that target block wrappers in the front end. This code only runs in the editor, so it doesn't need those selectors.
*/
ruleset += `padding-right: 0; padding-left: 0; padding-top: var(--wp--style--root--padding-top); padding-bottom: var(--wp--style--root--padding-bottom) }
.has-global-padding { padding-right: var(--wp--style--root--padding-right); padding-left: var(--wp--style--root--padding-left); }
- .has-global-padding :where(.has-global-padding:not(.wp-block-block)) { padding-right: 0; padding-left: 0; }
.has-global-padding > .alignfull { margin-right: calc(var(--wp--style--root--padding-right) * -1); margin-left: calc(var(--wp--style--root--padding-left) * -1); }
- .has-global-padding :where(.has-global-padding:not(.wp-block-block)) > .alignfull { margin-right: 0; margin-left: 0; }
- .has-global-padding > .alignfull:where(:not(.has-global-padding):not(.is-layout-flex):not(.is-layout-grid)) > :where(.wp-block:not(.alignfull),p,h1,h2,h3,h4,h5,h6,ul,ol) { padding-right: var(--wp--style--root--padding-right); padding-left: var(--wp--style--root--padding-left); }
- .has-global-padding :where(.has-global-padding) > .alignfull:where(:not(.has-global-padding)) > :where(.wp-block:not(.alignfull),p,h1,h2,h3,h4,h5,h6,ul,ol) { padding-right: 0; padding-left: 0;`;
+ .has-global-padding :where(.has-global-padding:not(.wp-block-block, .alignfull, .alignwide)) { padding-right: 0; padding-left: 0; }
+ .has-global-padding :where(.has-global-padding:not(.wp-block-block, .alignfull, .alignwide)) > .alignfull { margin-left: 0; margin-right: 0; }
+ `;
}
ruleset += '}';
@@ -860,12 +855,56 @@ export const toStyles = (
( [ cssSelector, declarations ] ) => {
if ( declarations.length ) {
const rules = declarations.join( ';' );
- ruleset += `:where(${ cssSelector }){${ rules };}`;
+ ruleset += `:root :where(${ cssSelector }){${ rules };}`;
}
}
);
}
+ // Process duotone styles.
+ if ( duotoneSelector ) {
+ const duotoneStyles = {};
+ if ( styles?.filter ) {
+ duotoneStyles.filter = styles.filter;
+ delete styles.filter;
+ }
+ const duotoneDeclarations =
+ getStylesDeclarations( duotoneStyles );
+ if ( duotoneDeclarations.length ) {
+ ruleset += `${ duotoneSelector }{${ duotoneDeclarations.join(
+ ';'
+ ) };}`;
+ }
+ }
+
+ // Process blockGap and layout styles.
+ if (
+ ! disableLayoutStyles &&
+ ( ROOT_BLOCK_SELECTOR === selector || hasLayoutSupport )
+ ) {
+ ruleset += getLayoutStyles( {
+ style: styles,
+ selector,
+ hasBlockGapSupport,
+ hasFallbackGapSupport,
+ fallbackGapValue,
+ } );
+ }
+
+ // Process the remaining block styles (they use either normal block class or __experimentalSelector).
+ const styleDeclarations = getStylesDeclarations(
+ styles,
+ selector,
+ useRootPaddingAlign,
+ tree,
+ disableRootPadding
+ );
+ if ( styleDeclarations?.length ) {
+ ruleset += `:root :where(${ selector }){${ styleDeclarations.join(
+ ';'
+ ) };}`;
+ }
+
if ( styleVariationSelectors ) {
Object.entries( styleVariationSelectors ).forEach(
( [ styleVariationName, styleVariationSelector ] ) => {
@@ -892,7 +931,7 @@ export const toStyles = (
);
const rules =
declarations.join( ';' );
- ruleset += `${ cssSelector }{${ rules };}`;
+ ruleset += `:root :where(${ cssSelector }){${ rules };}`;
}
}
);
@@ -907,7 +946,7 @@ export const toStyles = (
tree
);
if ( styleVariationDeclarations.length ) {
- ruleset += `${ styleVariationSelector }{${ styleVariationDeclarations.join(
+ ruleset += `:root :where(${ styleVariationSelector }){${ styleVariationDeclarations.join(
';'
) };}`;
}
@@ -916,50 +955,6 @@ export const toStyles = (
);
}
- // Process duotone styles.
- if ( duotoneSelector ) {
- const duotoneStyles = {};
- if ( styles?.filter ) {
- duotoneStyles.filter = styles.filter;
- delete styles.filter;
- }
- const duotoneDeclarations =
- getStylesDeclarations( duotoneStyles );
- if ( duotoneDeclarations.length ) {
- ruleset += `${ duotoneSelector }{${ duotoneDeclarations.join(
- ';'
- ) };}`;
- }
- }
-
- // Process blockGap and layout styles.
- if (
- ! disableLayoutStyles &&
- ( ROOT_BLOCK_SELECTOR === selector || hasLayoutSupport )
- ) {
- ruleset += getLayoutStyles( {
- style: styles,
- selector,
- hasBlockGapSupport,
- hasFallbackGapSupport,
- fallbackGapValue,
- } );
- }
-
- // Process the remaining block styles (they use either normal block class or __experimentalSelector).
- const declarations = getStylesDeclarations(
- styles,
- selector,
- useRootPaddingAlign,
- tree,
- disableRootPadding
- );
- if ( declarations?.length ) {
- ruleset += `:where(${ selector }){${ declarations.join(
- ';'
- ) };}`;
- }
-
// Check for pseudo selector in `styles` and handle separately.
const pseudoSelectorStyles = Object.entries( styles ).filter(
( [ key ] ) => key.startsWith( ':' )
@@ -1018,13 +1013,13 @@ export const toStyles = (
getGapCSSValue( tree?.styles?.spacing?.blockGap ) || '0.5em';
ruleset =
ruleset +
- `:where(.wp-site-blocks) > * { margin-block-start: ${ gapValue }; margin-block-end: 0; }`;
+ `:root :where(.wp-site-blocks) > * { margin-block-start: ${ gapValue }; margin-block-end: 0; }`;
ruleset =
ruleset +
- ':where(.wp-site-blocks) > :first-child { margin-block-start: 0; }';
+ ':root :where(.wp-site-blocks) > :first-child { margin-block-start: 0; }';
ruleset =
ruleset +
- ':where(.wp-site-blocks) > :last-child { margin-block-end: 0; }';
+ ':root :where(.wp-site-blocks) > :last-child { margin-block-end: 0; }';
}
if ( options.presets ) {
@@ -1185,7 +1180,7 @@ export function processCSSNesting( css, blockSelector ) {
const isRootCss = ! part.includes( '{' );
if ( isRootCss ) {
// If the part doesn't contain braces, it applies to the root level.
- processedCSS += `${ blockSelector }{${ part.trim() }}`;
+ processedCSS += `:root :where(${ blockSelector }){${ part.trim() }}`;
} else {
// If the part contains braces, it's a nested CSS rule.
const splittedPart = part.replace( '}', '' ).split( '{' );
@@ -1198,7 +1193,7 @@ export function processCSSNesting( css, blockSelector ) {
? scopeSelector( blockSelector, nestedSelector )
: appendToSelector( blockSelector, nestedSelector );
- processedCSS += `${ combinedSelector }{${ cssValue.trim() }}`;
+ processedCSS += `:root :where(${ combinedSelector }){${ cssValue.trim() }}`;
}
} );
return processedCSS;
diff --git a/packages/block-library/src/audio/theme.scss b/packages/block-library/src/audio/theme.scss
index eda394fd6a3d54..2744d36e74ca62 100644
--- a/packages/block-library/src/audio/theme.scss
+++ b/packages/block-library/src/audio/theme.scss
@@ -2,6 +2,6 @@
@include caption-style-theme();
}
-:where(.wp-block-audio) {
+.wp-block-audio {
margin: 0 0 1em 0;
}
diff --git a/packages/block-library/src/block/editor.scss b/packages/block-library/src/block/editor.scss
deleted file mode 100644
index 318101f7f52dac..00000000000000
--- a/packages/block-library/src/block/editor.scss
+++ /dev/null
@@ -1,35 +0,0 @@
-.edit-post-visual-editor .block-library-block__reusable-block-container {
- // Unset the padding that root containers get when they're actually root containers.
- .is-root-container {
- padding-left: 0;
- padding-right: 0;
- }
-
- // Allow vertical paddings to collapse to better fit the flow.
- .block-editor-writing-flow {
- display: block;
- }
-
- .components-disabled .block-list-appender {
- display: none;
- }
-}
-
-.edit-post-visual-editor .block-editor-block-list__block:not(.remove-outline).is-reusable {
-
- &.is-highlighted::after,
- &.is-selected::after {
- outline-color: var(--wp-block-synced-color);
- }
-
- &.block-editor-block-list__block:not([contenteditable]):focus {
- &::after {
- outline-color: var(--wp-block-synced-color);
-
- // Show a light color for dark themes.
- .is-dark-theme & {
- outline-color: $dark-theme-focus;
- }
- }
- }
-}
diff --git a/packages/block-library/src/button/editor.scss b/packages/block-library/src/button/editor.scss
index c24021d17e38ec..8c879c7e3b7c9e 100644
--- a/packages/block-library/src/button/editor.scss
+++ b/packages/block-library/src/button/editor.scss
@@ -37,38 +37,3 @@ div[data-type="core/button"] {
text-decoration: inherit;
}
-.editor-styles-wrapper .wp-block-button .wp-block-button__link {
- // The following styles ensure a default border is applied when the user selects only a border color or style in the editor,
- // but no width. They override the `border-width: 0;` applied by core's theme.json via the Elements API button.
- &:where(.has-border-color) {
- border-width: initial;
- }
- &:where([style*="border-top-color"]) {
- border-top-width: initial;
- }
- &:where([style*="border-right-color"]) {
- border-right-width: initial;
- }
- &:where([style*="border-bottom-color"]) {
- border-bottom-width: initial;
- }
- &:where([style*="border-left-color"]) {
- border-left-width: initial;
- }
-
- &:where([style*="border-style"]) {
- border-width: initial;
- }
- &:where([style*="border-top-style"]) {
- border-top-width: initial;
- }
- &:where([style*="border-right-style"]) {
- border-right-width: initial;
- }
- &:where([style*="border-bottom-style"]) {
- border-bottom-width: initial;
- }
- &:where([style*="border-left-style"]) {
- border-left-width: initial;
- }
-}
diff --git a/packages/block-library/src/button/style.scss b/packages/block-library/src/button/style.scss
index f441152107973f..42306cba0c984d 100644
--- a/packages/block-library/src/button/style.scss
+++ b/packages/block-library/src/button/style.scss
@@ -86,69 +86,37 @@ $blocks-block__margin: 0.5em;
}
}
-// the first selector is required for old buttons markup
+// The follow block style selectors are required for old buttons markup
+// and do not use the `:root :where()` format to match specificity at
+// the time they were deprecated.
.wp-block-button.is-style-squared,
.wp-block-button__link.wp-block-button.is-style-squared {
border-radius: 0;
}
-
-// the first selector is required for old buttons markup
.wp-block-button.no-border-radius,
.wp-block-button__link.no-border-radius {
border-radius: 0 !important;
}
-.wp-block-button:where(.is-style-outline) > .wp-block-button__link,
-.wp-block-button .wp-block-button__link:where(.is-style-outline) {
- border: 2px solid currentColor;
- padding: 0.667em 1.333em;
-}
-
-.wp-block-button:where(.is-style-outline) > .wp-block-button__link:not(.has-text-color),
-.wp-block-button .wp-block-button__link:where(.is-style-outline):not(.has-text-color) {
- color: currentColor;
-}
-
-.wp-block-button:where(.is-style-outline) > .wp-block-button__link:not(.has-background),
-.wp-block-button .wp-block-button__link:where(.is-style-outline):not(.has-background) {
- background-color: transparent;
- // background-image is required to overwrite a gradient background
- background-image: none;
-}
-
-.wp-block-button .wp-block-button__link {
- // The following styles ensure a default border is applied when the user
- // selects only a border color or style. This overcomes the zero border
- // width applied by core's theme.json via the elements API.
- &:where(.has-border-color) {
- border-width: initial;
- }
- &:where([style*="border-top-color"]) {
- border-top-width: initial;
- }
- &:where([style*="border-right-color"]) {
- border-right-width: initial;
- }
- &:where([style*="border-bottom-color"]) {
- border-bottom-width: initial;
- }
- &:where([style*="border-left-color"]) {
- border-left-width: initial;
+// Selectors here use the `:root :where()` format for maintaining compatibility
+// with global styles and nested block style variations.
+:root {
+ // Outline Block Style Variation.
+ :where(.wp-block-button.is-style-outline > .wp-block-button__link),
+ :where(.wp-block-button .wp-block-button__link.is-style-outline) {
+ border: 2px solid currentColor;
+ padding: 0.667em 1.333em;
}
- &:where([style*="border-style"]) {
- border-width: initial;
- }
- &:where([style*="border-top-style"]) {
- border-top-width: initial;
+ :where(.wp-block-button.is-style-outline > .wp-block-button__link:not(.has-text-color)),
+ :where(.wp-block-button .wp-block-button__link.is-style-outline:not(.has-text-color)) {
+ color: currentColor;
}
- &:where([style*="border-right-style"]) {
- border-right-width: initial;
- }
- &:where([style*="border-bottom-style"]) {
- border-bottom-width: initial;
- }
- &:where([style*="border-left-style"]) {
- border-left-width: initial;
+
+ :where(.wp-block-button.is-style-outline > .wp-block-button__link:not(.has-background)),
+ :where(.wp-block-button .wp-block-button__link.is-style-outline:not(.has-background)) {
+ background-color: transparent;
+ // background-image is required to overwrite a gradient background
+ background-image: none;
}
}
diff --git a/packages/block-library/src/cover/style.scss b/packages/block-library/src/cover/style.scss
index d14f606fc0226a..58f1147f12d279 100644
--- a/packages/block-library/src/cover/style.scss
+++ b/packages/block-library/src/cover/style.scss
@@ -1,11 +1,7 @@
-// Lowest specificity styles are used to ensure that the default styles for the cover block can be overridden by global styles.
-:where(.wp-block-cover-image, .wp-block-cover) {
- min-height: 430px;
- padding: 1em;
-}
-
.wp-block-cover-image,
.wp-block-cover {
+ min-height: 430px;
+ padding: 1em;
position: relative;
background-position: center center;
display: flex;
@@ -120,18 +116,6 @@
/*rtl:raw: direction: rtl; */
}
- p,
- h1,
- h2,
- h3,
- h4,
- h5,
- h6 {
- &:where(:not(.has-text-color)) {
- color: inherit;
- }
- }
-
// Position: Top
&.is-position-top-left {
align-items: flex-start;
@@ -314,3 +298,15 @@ section.wp-block-cover-image > h2,
:where(.wp-block-cover-image.is-light:not(.has-text-color)) {
color: $black;
}
+
+:root {
+ :where(.wp-block-cover p:not(.has-text-color)),
+ :where(.wp-block-cover h1:not(.has-text-color)),
+ :where(.wp-block-cover h2:not(.has-text-color)),
+ :where(.wp-block-cover h3:not(.has-text-color)),
+ :where(.wp-block-cover h4:not(.has-text-color)),
+ :where(.wp-block-cover h5:not(.has-text-color)),
+ :where(.wp-block-cover h6:not(.has-text-color)) {
+ color: inherit;
+ }
+}
diff --git a/packages/block-library/src/editor.scss b/packages/block-library/src/editor.scss
index 0bca3e23028c50..c43137c632b73f 100644
--- a/packages/block-library/src/editor.scss
+++ b/packages/block-library/src/editor.scss
@@ -1,7 +1,6 @@
@import "./archives/editor.scss";
@import "./audio/editor.scss";
@import "./avatar/editor.scss";
-@import "./block/editor.scss";
@import "./button/editor.scss";
@import "./buttons/editor.scss";
@import "./categories/editor.scss";
diff --git a/packages/block-library/src/embed/theme.scss b/packages/block-library/src/embed/theme.scss
index 57ece1dcd43cac..e809a783b9c810 100644
--- a/packages/block-library/src/embed/theme.scss
+++ b/packages/block-library/src/embed/theme.scss
@@ -2,6 +2,6 @@
@include caption-style-theme();
}
-:where(.wp-block-embed) {
+.wp-block-embed {
margin: 0 0 1em 0;
}
diff --git a/packages/block-library/src/gallery/editor.scss b/packages/block-library/src/gallery/editor.scss
index ea6fa8836a3a4b..9efaf88e5acc71 100644
--- a/packages/block-library/src/gallery/editor.scss
+++ b/packages/block-library/src/gallery/editor.scss
@@ -1,4 +1,7 @@
-:where(figure.wp-block-gallery) {
+// Adding `figure` to the selector increases the specificity above the global
+// styles specificity, which is levelled at 0-1-0. We should figure out why
+// `figure` is needed.
+:root :where(figure.wp-block-gallery) {
// Override the default list style type _only in the editor_
// to avoid :not() selector specificity issues.
// See https://github.com/WordPress/gutenberg/pull/10358
diff --git a/packages/block-library/src/image/style.scss b/packages/block-library/src/image/style.scss
index 75c8b839dca37c..40ffe0cd0e61c7 100644
--- a/packages/block-library/src/image/style.scss
+++ b/packages/block-library/src/image/style.scss
@@ -82,16 +82,10 @@
@include caption-style();
}
- // Variations
- &.is-style-rounded img,
- .is-style-rounded img {
- // We use an absolute pixel to prevent the oval shape that a value of 50% would give
- // to rectangular images. A pill-shape is better than otherwise.
- border-radius: 9999px;
- }
-
// The following variation is deprecated.
// The CSS is kept here for the time being, to support blocks using the old variation.
+ // The selector is not scoped with `:root :where()` like global styles are to keep its
+ // specificity the same as it was when it was deprecated.
&.is-style-circle-mask img {
// We use an absolute pixel to prevent the oval shape that a value of 50% would give
// to rectangular images. A pill-shape is better than otherwise.
@@ -108,42 +102,13 @@
border-radius: 0;
}
}
+}
- // The following is required to overcome WP Core applying styles that clear
- // img borders with a higher specificity than those added by the border
- // block support to provide a default border-style of solid when a border
- // color or width has been set.
- :where(.has-border-color) {
- border-style: solid;
- }
- :where([style*="border-top-color"]) {
- border-top-style: solid;
- }
- :where([style*="border-right-color"]) {
- border-right-style: solid;
- }
- :where([style*="border-bottom-color"]) {
- border-bottom-style: solid;
- }
- :where([style*="border-left-color"]) {
- border-left-style: solid;
- }
-
- :where([style*="border-width"]) {
- border-style: solid;
- }
- :where([style*="border-top-width"]) {
- border-top-style: solid;
- }
- :where([style*="border-right-width"]) {
- border-right-style: solid;
- }
- :where([style*="border-bottom-width"]) {
- border-bottom-style: solid;
- }
- :where([style*="border-left-width"]) {
- border-left-style: solid;
- }
+// Variations
+:root :where(.wp-block-image.is-style-rounded img, .wp-block-image .is-style-rounded img) {
+ // We use an absolute pixel to prevent the oval shape that a value of 50% would give
+ // to rectangular images. A pill-shape is better than otherwise.
+ border-radius: 9999px;
}
.wp-block-image figure {
diff --git a/packages/block-library/src/image/theme.scss b/packages/block-library/src/image/theme.scss
index 459036511335a6..c89dd3334dd09a 100644
--- a/packages/block-library/src/image/theme.scss
+++ b/packages/block-library/src/image/theme.scss
@@ -1,7 +1,7 @@
-.wp-block-image figcaption {
+:root :where(.wp-block-image figcaption) {
@include caption-style-theme();
}
-:where(.wp-block-image) {
+.wp-block-image {
margin: 0 0 1em 0;
}
diff --git a/packages/block-library/src/latest-posts/editor.scss b/packages/block-library/src/latest-posts/editor.scss
index 3c2d6a30f1c077..d3f0b5275653e3 100644
--- a/packages/block-library/src/latest-posts/editor.scss
+++ b/packages/block-library/src/latest-posts/editor.scss
@@ -1,9 +1,4 @@
.wp-block-latest-posts {
- padding-left: 2.5em;
- &.is-grid {
- padding-left: 0;
- }
-
// Apply overflow for post items, so any floated featured images won't crop the focus style.
> li {
overflow: hidden;
@@ -14,10 +9,6 @@
display: inline;
}
-.edit-post-visual-editor .wp-block-latest-posts.is-grid li {
- margin-bottom: 20px;
-}
-
.editor-latest-posts-image-alignment-control {
.components-base-control__label {
display: block;
@@ -27,3 +18,13 @@
border-radius: $radius-block-ui;
}
}
+
+:root :where(.wp-block-latest-posts) {
+ padding-left: 2.5em;
+}
+:root {
+ :where(.wp-block-latest-posts.is-grid),
+ :where(.wp-block-latest-posts__list) {
+ padding-left: 0;
+ }
+}
diff --git a/packages/block-library/src/latest-posts/style.scss b/packages/block-library/src/latest-posts/style.scss
index 5d3e360d0804a8..2a01d177ef47c4 100644
--- a/packages/block-library/src/latest-posts/style.scss
+++ b/packages/block-library/src/latest-posts/style.scss
@@ -12,7 +12,6 @@
}
&.wp-block-latest-posts__list {
list-style: none;
- padding-left: 0;
li {
clear: both;
@@ -23,7 +22,6 @@
&.is-grid {
display: flex;
flex-wrap: wrap;
- padding: 0;
li {
margin: 0 1.25em 1.25em 0;
@@ -34,9 +32,9 @@
@include break-small {
@for $i from 2 through 6 {
&.columns-#{ $i } li {
- width: calc((100% / #{ $i }) - 1.25em + (1.25em / #{ $i }));
+ width: calc((100% / #{$i}) - 1.25em + (1.25em / #{$i}));
- &:nth-child( #{ $i }n ) {
+ &:nth-child(#{ $i }n) {
margin-right: 0;
}
}
@@ -44,6 +42,15 @@
}
}
+:root {
+ :where(.wp-block-latest-posts.is-grid) {
+ padding: 0;
+ }
+ :where(.wp-block-latest-posts.wp-block-latest-posts__list) {
+ padding-left: 0;
+ }
+}
+
.wp-block-latest-posts__post-date,
.wp-block-latest-posts__post-author {
display: block;
diff --git a/packages/block-library/src/navigation/index.php b/packages/block-library/src/navigation/index.php
index c5ef8e9204b32d..ba36acf139a626 100644
--- a/packages/block-library/src/navigation/index.php
+++ b/packages/block-library/src/navigation/index.php
@@ -1617,10 +1617,16 @@ function block_core_navigation_update_ignore_hooked_blocks_meta( $post ) {
$rest_insert_wp_navigation_core_callback = 'block_core_navigation_' . 'update_ignore_hooked_blocks_meta'; // phpcs:ignore Generic.Strings.UnnecessaryStringConcat.Found
/*
- * Injection of hooked blocks into the Navigation block relies on some functions present in WP >= 6.5
- * that are not present in Gutenberg's WP 6.5 compatibility layer.
+ * Do not add the `block_core_navigation_update_ignore_hooked_blocks_meta` filter in the following cases:
+ * - If Core has added the `update_ignored_hooked_blocks_postmeta` filter already (WP >= 6.6);
+ * - or if the `set_ignored_hooked_blocks_metadata` function is unavailable (which is required for the filter to work. It was introduced by WP 6.5 but is not present in Gutenberg's WP 6.5 compatibility layer);
+ * - or if the `$rest_insert_wp_navigation_core_callback` filter has already been added.
*/
-if ( function_exists( 'set_ignored_hooked_blocks_metadata' ) && ! has_filter( 'rest_pre_insert_wp_navigation', $rest_insert_wp_navigation_core_callback ) ) {
+if (
+ ! has_filter( 'rest_pre_insert_wp_navigation', 'update_ignored_hooked_blocks_postmeta' ) &&
+ function_exists( 'set_ignored_hooked_blocks_metadata' ) &&
+ ! has_filter( 'rest_pre_insert_wp_navigation', $rest_insert_wp_navigation_core_callback )
+) {
add_filter( 'rest_pre_insert_wp_navigation', 'block_core_navigation_update_ignore_hooked_blocks_meta' );
}
diff --git a/packages/block-library/src/pullquote/editor.scss b/packages/block-library/src/pullquote/editor.scss
index 7b985d8020c9fe..deb325849ebebf 100644
--- a/packages/block-library/src/pullquote/editor.scss
+++ b/packages/block-library/src/pullquote/editor.scss
@@ -1,4 +1,6 @@
// .is-style-solid-color is deprecated.
+// This selector has not been scoped with `:root :where`, as global styles
+// does, to keep its specificity as it was at the time of deprecation.
.wp-block-pullquote.is-style-solid-color {
& blockquote p {
font-size: 32px;
diff --git a/packages/block-library/src/pullquote/style.scss b/packages/block-library/src/pullquote/style.scss
index 07f6366d47617f..b9e28b7cdcfaa6 100644
--- a/packages/block-library/src/pullquote/style.scss
+++ b/packages/block-library/src/pullquote/style.scss
@@ -2,6 +2,8 @@
text-align: center; // Default text-alignment where the `textAlign` attribute value isn't specified.
overflow-wrap: break-word; // Break long strings of text without spaces so they don't overflow the block.
box-sizing: border-box;
+ margin: 0 0 1em 0;
+ padding: 4em 0;
p,
blockquote,
@@ -35,12 +37,6 @@
}
}
-// Lowest specificity to avoid overriding layout and global styles.
-:where(.wp-block-pullquote) {
- margin: 0 0 1em 0;
- padding: 4em 0;
-}
-
// Ensure that we are reasonably specific to override theme defaults.
.wp-block-pullquote.has-text-align-left blockquote {
text-align: left;
@@ -52,6 +48,8 @@
}
// .is-style-solid-color is deprecated.
+// This selector has not been scoped with `:root :where`, as global styles
+// does, to keep its specificity as it was at the time of deprecation.
.wp-block-pullquote.is-style-solid-color {
border: none;
blockquote {
diff --git a/packages/block-library/src/pullquote/theme.scss b/packages/block-library/src/pullquote/theme.scss
index 0dc7943a770512..6b5e8401227f5b 100644
--- a/packages/block-library/src/pullquote/theme.scss
+++ b/packages/block-library/src/pullquote/theme.scss
@@ -1,11 +1,9 @@
-:where(.wp-block-pullquote) {
+.wp-block-pullquote {
border-top: 4px solid currentColor;
border-bottom: 4px solid currentColor;
margin-bottom: 1.75em;
color: currentColor;
-}
-.wp-block-pullquote {
cite,
footer,
&__citation {
diff --git a/packages/block-library/src/quote/theme.scss b/packages/block-library/src/quote/theme.scss
index aaf63b899771b0..5bcccbd60eefc4 100644
--- a/packages/block-library/src/quote/theme.scss
+++ b/packages/block-library/src/quote/theme.scss
@@ -1,4 +1,4 @@
-:where(.wp-block-quote) {
+.wp-block-quote {
border-left: 0.25em solid currentColor;
margin: 0 0 1.75em 0;
padding-left: 1em;
diff --git a/packages/block-library/src/separator/editor.scss b/packages/block-library/src/separator/editor.scss
index 220c6bd9d80e38..24e940684279e8 100644
--- a/packages/block-library/src/separator/editor.scss
+++ b/packages/block-library/src/separator/editor.scss
@@ -2,11 +2,4 @@
// Prevent margin collapsing so the area to select the separator is bigger.
padding-top: 0.1px;
padding-bottom: 0.1px;
-
- // This is also set in style.scss, but needs a higher specificity in editor
- // due to the way that color block supports adds additional background color styles.
- &.wp-block-separator.is-style-dots {
- background: none !important;
- border: none;
- }
}
diff --git a/packages/block-library/src/separator/style.scss b/packages/block-library/src/separator/style.scss
index d40dd2f05844ed..65e463bc513f48 100644
--- a/packages/block-library/src/separator/style.scss
+++ b/packages/block-library/src/separator/style.scss
@@ -1,28 +1,4 @@
.wp-block-separator {
- // Dots style
- &.is-style-dots {
- // Override any background themes often set on the hr tag for this style.
- // also override the color set in the editor since it's intented for normal HR
- background: none !important;
- border: none;
- text-align: center;
- line-height: 1;
- height: auto;
-
- &::before {
- content: "\00b7 \00b7 \00b7";
- color: currentColor;
- font-size: 1.5em;
- letter-spacing: 2em;
- /*rtl:ignore*/
- padding-left: 2em;
- font-family: serif;
- }
- }
-}
-
-// Lowest specificity to avoid overriding global styles.
-:where(.wp-block-separator) {
border-top: 2px solid currentColor;
// Default, thin style, is stored in theme.scss so it can be opted out of
@@ -31,3 +7,31 @@
border-right: none;
border-bottom: none;
}
+
+// Dots block style variation
+:root :where(.wp-block-separator.is-style-dots) {
+ text-align: center;
+ line-height: 1;
+ height: auto;
+
+ &::before {
+ content: "\00b7 \00b7 \00b7";
+ color: currentColor;
+ font-size: 1.5em;
+ letter-spacing: 2em;
+ /*rtl:ignore*/
+ padding-left: 2em;
+ font-family: serif;
+ }
+}
+
+// The following overrides should be enforced regardless of global styles.
+// The dots block style uses a pseudo element to render the dots. Background
+// color and borders would break this aesthetic.
+.wp-block-separator.is-style-dots {
+ // Override any background themes often set on the hr tag for this style.
+ // also override the color set in the editor since it's intended for normal HR
+ background: none !important;
+ // Important required to ensure dots does not get a border.
+ border: none !important;
+}
diff --git a/packages/block-library/src/site-logo/edit.js b/packages/block-library/src/site-logo/edit.js
index 3192f2b000346e..046b5feeb20c99 100644
--- a/packages/block-library/src/site-logo/edit.js
+++ b/packages/block-library/src/site-logo/edit.js
@@ -73,7 +73,6 @@ const SiteLogo = ( {
const [ { naturalWidth, naturalHeight }, setNaturalSize ] = useState( {} );
const [ isEditingImage, setIsEditingImage ] = useState( false );
const { toggleSelection } = useDispatch( blockEditorStore );
- const classes = clsx( 'custom-logo-link' );
const { imageEditing, maxWidth, title } = useSelect( ( select ) => {
const settings = select( blockEditorStore ).getSettings();
const siteEntities = select( coreStore ).getEntityRecord(
@@ -136,7 +135,7 @@ const SiteLogo = ( {
/* eslint-disable jsx-a11y/no-noninteractive-element-interactions, jsx-a11y/click-events-have-key-events */
event.preventDefault() }
diff --git a/packages/block-library/src/site-logo/style.scss b/packages/block-library/src/site-logo/style.scss
index ca9c92539b6760..020b7aab5370b3 100644
--- a/packages/block-library/src/site-logo/style.scss
+++ b/packages/block-library/src/site-logo/style.scss
@@ -31,11 +31,11 @@
margin-right: auto;
text-align: center;
}
+}
- // Style variations
- &.is-style-rounded {
- // We use an absolute pixel to prevent the oval shape that a value of 50% would give
- // to rectangular images. A pill-shape is better than otherwise.
- border-radius: 9999px;
- }
+// Style variations
+:root :where(.wp-block-site-logo.is-style-rounded) {
+ // We use an absolute pixel to prevent the oval shape that a value of 50% would give
+ // to rectangular images. A pill-shape is better than otherwise.
+ border-radius: 9999px;
}
diff --git a/packages/block-library/src/site-title/editor.scss b/packages/block-library/src/site-title/editor.scss
index 173e4570929a51..ce83659170ff6f 100644
--- a/packages/block-library/src/site-title/editor.scss
+++ b/packages/block-library/src/site-title/editor.scss
@@ -3,8 +3,6 @@
border: 1px dashed;
}
-.editor-styles-wrapper .wp-block-site-title {
- a {
- color: inherit;
- }
+.editor-styles-wrapper :where(.wp-block-site-title a) {
+ color: inherit;
}
diff --git a/packages/block-library/src/site-title/style.scss b/packages/block-library/src/site-title/style.scss
index afc6f449f4025b..337c82f79ad354 100644
--- a/packages/block-library/src/site-title/style.scss
+++ b/packages/block-library/src/site-title/style.scss
@@ -1,5 +1,3 @@
-.wp-block-site-title {
- a {
- color: inherit;
- }
+:root :where(.wp-block-site-title a) {
+ color: inherit;
}
diff --git a/packages/block-library/src/social-link/editor.scss b/packages/block-library/src/social-link/editor.scss
index 73211958b48c15..bd93ad9f055fcd 100644
--- a/packages/block-library/src/social-link/editor.scss
+++ b/packages/block-library/src/social-link/editor.scss
@@ -31,11 +31,11 @@
}
}
-.wp-block-social-links.is-style-pill-shape .wp-social-link button {
+:root :where(.wp-block-social-links.is-style-pill-shape .wp-social-link button) {
padding-left: calc((2/3) * 1em);
padding-right: calc((2/3) * 1em);
}
-.wp-block-social-links.is-style-logos-only .wp-social-link button {
+:root :where(.wp-block-social-links.is-style-logos-only .wp-social-link button) {
padding: 0;
}
diff --git a/packages/block-library/src/social-links/editor.scss b/packages/block-library/src/social-links/editor.scss
index b729949c837d80..6f07ea209ecbea 100644
--- a/packages/block-library/src/social-links/editor.scss
+++ b/packages/block-library/src/social-links/editor.scss
@@ -11,9 +11,19 @@
transform: none;
}
-.editor-styles-wrapper .wp-block-social-links {
+// Specificity for the following styles are fixed at 0-1-0 to match and be
+// overridable by global styles.
+:root :where(.wp-block-social-links),
+:root :where(.wp-block-social-links.is-style-logos-only .wp-block-social-links__social-placeholder .wp-social-link) {
padding: 0;
}
+:root :where(.wp-block-social-links__social-placeholder .wp-social-link) {
+ padding: 0.25em;
+}
+:root :where(.wp-block-social-links.is-style-pill-shape .wp-block-social-links__social-placeholder .wp-social-link) {
+ padding-left: calc((2/3) * 1em);
+ padding-right: calc((2/3) * 1em);
+}
// Placeholder/setup state.
.wp-block-social-links__social-placeholder {
@@ -37,19 +47,6 @@
display: flex;
}
- .wp-social-link {
- padding: 0.25em;
-
- .is-style-pill-shape & {
- padding-left: calc((2/3) * 1em);
- padding-right: calc((2/3) * 1em);
- }
-
- .is-style-logos-only & {
- padding: 0;
- }
- }
-
.wp-social-link::before {
content: "";
display: block;
diff --git a/packages/block-library/src/social-links/style.scss b/packages/block-library/src/social-links/style.scss
index 1ad883bbb88840..f04c11ea07acd3 100644
--- a/packages/block-library/src/social-links/style.scss
+++ b/packages/block-library/src/social-links/style.scss
@@ -21,12 +21,6 @@
}
.wp-social-link {
- // By setting the font size, we can scale icons and paddings consistently based on that.
- // This also allows themes to override this, if need be.
- a {
- padding: 0.25em;
- }
-
svg {
width: 1em;
height: 1em;
@@ -119,14 +113,13 @@
}
// Treatment for logos only style.
+// The specificity for this selector has not been reduced to 0-1-0 as per
+// global styles variation selectors as the lack of background should be
+// enforced for this block style.
.wp-block-social-links.is-style-logos-only {
.wp-social-link {
background: none;
- a {
- padding: 0;
- }
-
// Make these bigger.
svg {
width: 1.25em;
@@ -142,11 +135,19 @@
.wp-social-link {
width: auto;
}
+}
- .wp-social-link a {
- padding-left: calc((2/3) * 1em);
- padding-right: calc((2/3) * 1em);
- }
+// The following rules have their selector specificity set to 0-1-0 to
+// facilitate theme.json styling of the inner social-link block padding.
+:root :where(.wp-block-social-links .wp-social-link a) {
+ padding: 0.25em;
+}
+:root :where(.wp-block-social-links.is-style-logos-only .wp-social-link a) {
+ padding: 0;
+}
+:root :where(.wp-block-social-links.is-style-pill-shape .wp-social-link a) {
+ padding-left: calc((2/3) * 1em);
+ padding-right: calc((2/3) * 1em);
}
// Ensure the Snapchat label is visible when no custom
diff --git a/packages/block-library/src/table/style.scss b/packages/block-library/src/table/style.scss
index 4f4271650f50e1..69cd2666e13e20 100644
--- a/packages/block-library/src/table/style.scss
+++ b/packages/block-library/src/table/style.scss
@@ -71,6 +71,9 @@
}
// "Stripes" style variation.
+ // This block style selector does not have 0-1-0 specificity, as per those
+ // generated via global styles, to maintain current styling. Global styles
+ // support for table borders also only applies to the outer `table` element.
&.is-style-stripes {
border-spacing: 0;
border-collapse: inherit;
diff --git a/packages/block-library/src/table/theme.scss b/packages/block-library/src/table/theme.scss
index 19dc71c8857bd7..d42e79b02b4965 100644
--- a/packages/block-library/src/table/theme.scss
+++ b/packages/block-library/src/table/theme.scss
@@ -1,4 +1,6 @@
.wp-block-table {
+ margin: 0 0 1em 0;
+
td,
th {
word-break: normal;
@@ -8,7 +10,3 @@
@include caption-style-theme();
}
}
-
-:where(.wp-block-table) {
- margin: 0 0 1em 0;
-}
diff --git a/packages/block-library/src/tag-cloud/style.scss b/packages/block-library/src/tag-cloud/style.scss
index 5fb04840de1517..dedb5e73ab1a1f 100644
--- a/packages/block-library/src/tag-cloud/style.scss
+++ b/packages/block-library/src/tag-cloud/style.scss
@@ -22,18 +22,20 @@
margin-left: 5px;
text-decoration: none;
}
+}
- &.is-style-outline {
- display: flex;
- flex-wrap: wrap;
- gap: 1ch;
-
- a {
- border: 1px solid currentColor;
- font-size: unset !important; // !important Needed to override the inline styles.
- margin-right: 0;
- padding: 1ch 2ch;
- text-decoration: none !important; // !important needed to override generic post content link decoration.
- }
- }
+// Specificity is set to 0-1-0 to match global styles selectors.
+:root :where(.wp-block-tag-cloud.is-style-outline) {
+ display: flex;
+ flex-wrap: wrap;
+ gap: 1ch;
+}
+// The block support related styles below haven't been replicated in the base theme.json
+// as the block doesn't yet adopt them for its inner links.
+:root :where(.wp-block-tag-cloud.is-style-outline a) {
+ border: 1px solid currentColor;
+ font-size: unset !important; // !important Needed to override the inline styles.
+ margin-right: 0;
+ padding: 1ch 2ch;
+ text-decoration: none !important; // !important needed to override generic post content link decoration.
}
diff --git a/packages/block-library/src/template-part/theme.scss b/packages/block-library/src/template-part/theme.scss
index 2f1d3a0a513cb7..179873b9448b82 100644
--- a/packages/block-library/src/template-part/theme.scss
+++ b/packages/block-library/src/template-part/theme.scss
@@ -1,9 +1,7 @@
// Same as the group block styles.
-:where(.wp-block-template-part) {
- &.has-background {
- // Matches paragraph Block padding
- padding: $block-bg-padding--v $block-bg-padding--h;
- margin-top: 0;
- margin-bottom: 0;
- }
+:root :where(.wp-block-template-part.has-background) {
+ // Matches paragraph Block padding
+ padding: $block-bg-padding--v $block-bg-padding--h;
+ margin-top: 0;
+ margin-bottom: 0;
}
diff --git a/packages/block-library/src/video/theme.scss b/packages/block-library/src/video/theme.scss
index c5399582bbb281..cdc95af0b02c29 100644
--- a/packages/block-library/src/video/theme.scss
+++ b/packages/block-library/src/video/theme.scss
@@ -2,6 +2,6 @@
@include caption-style-theme();
}
-:where(.wp-block-video) {
+.wp-block-video {
margin: 0 0 1em 0;
}
diff --git a/packages/components/src/animate/index.tsx b/packages/components/src/animate/index.tsx
index e7aaf72d243801..e819020447bc9e 100644
--- a/packages/components/src/animate/index.tsx
+++ b/packages/components/src/animate/index.tsx
@@ -23,7 +23,7 @@ function getDefaultOrigin( type?: GetAnimateOptions[ 'type' ] ) {
*/
export function getAnimateClassName( options: GetAnimateOptions ) {
if ( options.type === 'loading' ) {
- return clsx( 'components-animate__loading' );
+ return 'components-animate__loading';
}
const { type, origin = getDefaultOrigin( type ) } = options;
diff --git a/packages/components/src/focal-point-picker/focal-point.tsx b/packages/components/src/focal-point-picker/focal-point.tsx
index 7a401eb4c6870b..a03e41d4809cce 100644
--- a/packages/components/src/focal-point-picker/focal-point.tsx
+++ b/packages/components/src/focal-point-picker/focal-point.tsx
@@ -6,7 +6,6 @@ import { PointerCircle } from './styles/focal-point-style';
/**
* External dependencies
*/
-import clsx from 'clsx';
import type { FocalPointProps } from './types';
import type { WordPressComponentProps } from '../context';
@@ -15,9 +14,13 @@ export default function FocalPoint( {
top = '50%',
...props
}: WordPressComponentProps< FocalPointProps, 'div' > ) {
- const classes = clsx( 'components-focal-point-picker__icon_container' );
-
const style = { left, top };
- return ;
+ return (
+
+ );
}
diff --git a/packages/compose/README.md b/packages/compose/README.md
index 83bde196033a01..c60d202f59aacf 100644
--- a/packages/compose/README.md
+++ b/packages/compose/README.md
@@ -265,11 +265,11 @@ Helper hook for input fields that need to debounce the value before using it.
_Parameters_
-- _defaultValue_ `any`: The default value to use.
+- _defaultValue_ The default value to use.
_Returns_
-- `[string, Function, string]`: The input value, the setter and the debounced input value.
+- `[ string, ( value: string ) => void, string ]`: The input value, the setter and the debounced input value.
### useDisabled
diff --git a/packages/compose/src/hooks/use-debounced-input/index.js b/packages/compose/src/hooks/use-debounced-input/index.ts
similarity index 60%
rename from packages/compose/src/hooks/use-debounced-input/index.js
rename to packages/compose/src/hooks/use-debounced-input/index.ts
index 91a01073fcfee8..643b0ba68026c3 100644
--- a/packages/compose/src/hooks/use-debounced-input/index.js
+++ b/packages/compose/src/hooks/use-debounced-input/index.ts
@@ -11,18 +11,20 @@ import useDebounce from '../use-debounce';
/**
* Helper hook for input fields that need to debounce the value before using it.
*
- * @param {any} defaultValue The default value to use.
- * @return {[string, Function, string]} The input value, the setter and the debounced input value.
+ * @param defaultValue The default value to use.
+ * @return The input value, the setter and the debounced input value.
*/
-export default function useDebouncedInput( defaultValue = '' ) {
- const [ input, setInput ] = useState( defaultValue );
+export default function useDebouncedInput(
+ defaultValue = ''
+): [ string, ( value: string ) => void, string ] {
+ const [ input, setInput ] = useState< string >( defaultValue );
const [ debouncedInput, setDebouncedState ] = useState( defaultValue );
const setDebouncedInput = useDebounce( setDebouncedState, 250 );
useEffect( () => {
setDebouncedInput( input );
- }, [ input ] );
+ }, [ input, setDebouncedInput ] );
return [ input, setInput, debouncedInput ];
}
diff --git a/packages/dataviews/src/bulk-actions-toolbar.tsx b/packages/dataviews/src/bulk-actions-toolbar.tsx
index e7c4a23ff758c9..c2b3644b88bceb 100644
--- a/packages/dataviews/src/bulk-actions-toolbar.tsx
+++ b/packages/dataviews/src/bulk-actions-toolbar.tsx
@@ -31,14 +31,14 @@ interface ToolbarContentProps< Item extends AnyItem > {
selection: string[];
actionsToShow: Action< Item >[];
selectedItems: Item[];
- setSelection: ( selection: Item[] ) => void;
+ onSelectionChange: ( selection: Item[] ) => void;
}
interface BulkActionsToolbarProps< Item extends AnyItem > {
data: Item[];
selection: string[];
actions: Action< Item >[];
- setSelection: ( selection: Item[] ) => void;
+ onSelectionChange: ( selection: Item[] ) => void;
getItemId: ( item: Item ) => string;
}
@@ -123,7 +123,7 @@ function renderToolbarContent< Item extends AnyItem >(
selectedItems: Item[],
actionInProgress: string | null,
setActionInProgress: ( actionId: string | null ) => void,
- setSelection: ( selection: Item[] ) => void
+ onSelectionChange: ( selection: Item[] ) => void
) {
return (
<>
@@ -163,7 +163,7 @@ function renderToolbarContent< Item extends AnyItem >(
label={ __( 'Cancel' ) }
disabled={ !! actionInProgress }
onClick={ () => {
- setSelection( EMPTY_ARRAY );
+ onSelectionChange( EMPTY_ARRAY );
} }
/>
@@ -175,7 +175,7 @@ function ToolbarContent< Item extends AnyItem >( {
selection,
actionsToShow,
selectedItems,
- setSelection,
+ onSelectionChange,
}: ToolbarContentProps< Item > ) {
const [ actionInProgress, setActionInProgress ] = useState< string | null >(
null
@@ -191,7 +191,7 @@ function ToolbarContent< Item extends AnyItem >( {
selectedItems,
actionInProgress,
setActionInProgress,
- setSelection
+ onSelectionChange
);
} else if ( ! buttons.current ) {
buttons.current = renderToolbarContent(
@@ -200,7 +200,7 @@ function ToolbarContent< Item extends AnyItem >( {
selectedItems,
actionInProgress,
setActionInProgress,
- setSelection
+ onSelectionChange
);
}
return buttons.current;
@@ -210,7 +210,7 @@ export default function BulkActionsToolbar< Item extends AnyItem >( {
data,
selection,
actions = EMPTY_ARRAY,
- setSelection,
+ onSelectionChange,
getItemId,
}: BulkActionsToolbarProps< Item > ) {
const isReducedMotion = useReducedMotion();
@@ -258,7 +258,7 @@ export default function BulkActionsToolbar< Item extends AnyItem >( {
selection={ selection }
actionsToShow={ actionsToShow }
selectedItems={ selectedItems }
- setSelection={ setSelection }
+ onSelectionChange={ onSelectionChange }
/>
diff --git a/packages/dataviews/src/dataviews.js b/packages/dataviews/src/dataviews.tsx
similarity index 73%
rename from packages/dataviews/src/dataviews.js
rename to packages/dataviews/src/dataviews.tsx
index 75b672721f0419..875746ceb52c38 100644
--- a/packages/dataviews/src/dataviews.js
+++ b/packages/dataviews/src/dataviews.tsx
@@ -1,3 +1,8 @@
+/**
+ * External dependencies
+ */
+import type { ComponentType } from 'react';
+
/**
* WordPress dependencies
*/
@@ -16,21 +21,46 @@ import { VIEW_LAYOUTS } from './layouts';
import BulkActions from './bulk-actions';
import { normalizeFields } from './normalize-fields';
import BulkActionsToolbar from './bulk-actions-toolbar';
+import type { Action, AnyItem, Field, View, ViewBaseProps } from './types';
+
+interface DataViewsProps< Item extends AnyItem > {
+ view: View;
+ onChangeView: ( view: View ) => void;
+ fields: Field< Item >[];
+ search?: boolean;
+ searchLabel?: string;
+ actions?: Action< Item >[];
+ data: Item[];
+ getItemId?: ( item: Item ) => string;
+ isLoading?: boolean;
+ paginationInfo: {
+ totalItems: number;
+ totalPages: number;
+ };
+ supportedLayouts: string[];
+ onSelectionChange?: ( items: Item[] ) => void;
+}
-const defaultGetItemId = ( item ) => item.id;
+const defaultGetItemId = ( item: AnyItem ) => item.id;
const defaultOnSelectionChange = () => {};
-function useSomeItemHasAPossibleBulkAction( actions, data ) {
+function useSomeItemHasAPossibleBulkAction< Item extends AnyItem >(
+ actions: Action< Item >[],
+ data: Item[]
+) {
return useMemo( () => {
return data.some( ( item ) => {
return actions.some( ( action ) => {
- return action.supportsBulk && action.isEligible( item );
+ return (
+ action.supportsBulk &&
+ ( ! action.isEligible || action.isEligible( item ) )
+ );
} );
} );
}, [ actions, data ] );
}
-export default function DataViews( {
+export default function DataViews< Item extends AnyItem >( {
view,
onChangeView,
fields,
@@ -43,9 +73,9 @@ export default function DataViews( {
paginationInfo,
supportedLayouts,
onSelectionChange = defaultOnSelectionChange,
-} ) {
- const [ selection, setSelection ] = useState( [] );
- const [ openedFilter, setOpenedFilter ] = useState( null );
+}: DataViewsProps< Item > ) {
+ const [ selection, setSelection ] = useState< string[] >( [] );
+ const [ openedFilter, setOpenedFilter ] = useState< string | null >( null );
useEffect( () => {
if (
@@ -67,16 +97,15 @@ export default function DataViews( {
}, [ selection, data, getItemId, onSelectionChange ] );
const onSetSelection = useCallback(
- ( items ) => {
+ ( items: Item[] ) => {
setSelection( items.map( ( item ) => getItemId( item ) ) );
onSelectionChange( items );
},
[ setSelection, getItemId, onSelectionChange ]
);
- const ViewComponent = VIEW_LAYOUTS.find(
- ( v ) => v.type === view.type
- ).component;
+ const ViewComponent = VIEW_LAYOUTS.find( ( v ) => v.type === view.type )
+ ?.component as ComponentType< ViewBaseProps< Item > >;
const _fields = useMemo( () => normalizeFields( fields ), [ fields ] );
const hasPossibleBulkAction = useSomeItemHasAPossibleBulkAction(
@@ -150,7 +179,7 @@ export default function DataViews( {
data={ data }
actions={ actions }
selection={ selection }
- setSelection={ setSelection }
+ onSelectionChange={ onSetSelection }
getItemId={ getItemId }
/>
) }
diff --git a/packages/dataviews/src/filters.tsx b/packages/dataviews/src/filters.tsx
index df7a13b2953f16..0cf017fce191b1 100644
--- a/packages/dataviews/src/filters.tsx
+++ b/packages/dataviews/src/filters.tsx
@@ -22,7 +22,7 @@ interface FiltersProps< Item extends AnyItem > {
setOpenedFilter: ( openedFilter: string | null ) => void;
}
-const Filters = memo( function Filters< Item extends AnyItem >( {
+function _Filters< Item extends AnyItem >( {
fields,
view,
onChangeView,
@@ -117,6 +117,9 @@ const Filters = memo( function Filters< Item extends AnyItem >( {
{ filterComponents }
);
-} );
+}
+
+// A type assertion is used here to keep the type argument.
+const Filters = memo( _Filters ) as typeof _Filters;
export default Filters;
diff --git a/packages/dataviews/src/index.js b/packages/dataviews/src/index.ts
similarity index 100%
rename from packages/dataviews/src/index.js
rename to packages/dataviews/src/index.ts
diff --git a/packages/dataviews/src/search.js b/packages/dataviews/src/search.tsx
similarity index 65%
rename from packages/dataviews/src/search.js
rename to packages/dataviews/src/search.tsx
index 13a828c330575a..7929a9bd0eb3cb 100644
--- a/packages/dataviews/src/search.js
+++ b/packages/dataviews/src/search.tsx
@@ -6,20 +6,37 @@ import { useEffect, useRef, memo } from '@wordpress/element';
import { SearchControl } from '@wordpress/components';
import { useDebouncedInput } from '@wordpress/compose';
-const Search = memo( function Search( { label, view, onChangeView } ) {
+/**
+ * Internal dependencies
+ */
+import type { View } from './types';
+
+interface SearchProps {
+ label?: string;
+ view: View;
+ onChangeView: ( view: View ) => void;
+}
+
+const Search = memo( function Search( {
+ label,
+ view,
+ onChangeView,
+}: SearchProps ) {
const [ search, setSearch, debouncedSearch ] = useDebouncedInput(
view.search
);
useEffect( () => {
- setSearch( view.search );
- }, [ view ] );
+ setSearch( view.search ?? '' );
+ }, [ view.search, setSearch ] );
const onChangeViewRef = useRef( onChangeView );
+ const viewRef = useRef( view );
useEffect( () => {
onChangeViewRef.current = onChangeView;
- }, [ onChangeView ] );
+ viewRef.current = view;
+ }, [ onChangeView, view ] );
useEffect( () => {
onChangeViewRef.current( {
- ...view,
+ ...viewRef.current,
page: 1,
search: debouncedSearch,
} );
diff --git a/packages/dataviews/src/types.ts b/packages/dataviews/src/types.ts
index 58b0bffc922966..f7e6274d83928e 100644
--- a/packages/dataviews/src/types.ts
+++ b/packages/dataviews/src/types.ts
@@ -373,15 +373,35 @@ export type Action< Item extends AnyItem > =
| ActionModal< Item >
| ActionButton< Item >;
-export interface ViewProps< Item extends AnyItem, ViewType extends ViewBase > {
+export interface ViewBaseProps< Item extends AnyItem > {
actions: Action< Item >[];
data: Item[];
fields: NormalizedField< Item >[];
getItemId: ( item: Item ) => string;
isLoading?: boolean;
- onChangeView( view: ViewType ): void;
+ onChangeView( view: View ): void;
onSelectionChange: ( items: Item[] ) => void;
selection: string[];
setOpenedFilter: ( fieldId: string ) => void;
- view: ViewType;
+ view: View;
}
+
+export interface ViewTableProps< Item extends AnyItem >
+ extends ViewBaseProps< Item > {
+ view: ViewTable;
+}
+
+export interface ViewListProps< Item extends AnyItem >
+ extends ViewBaseProps< Item > {
+ view: ViewList;
+}
+
+export interface ViewGridProps< Item extends AnyItem >
+ extends ViewBaseProps< Item > {
+ view: ViewGrid;
+}
+
+export type ViewProps< Item extends AnyItem > =
+ | ViewTableProps< Item >
+ | ViewGridProps< Item >
+ | ViewListProps< Item >;
diff --git a/packages/dataviews/src/view-actions.tsx b/packages/dataviews/src/view-actions.tsx
index 0e041cc070c525..90098417575315 100644
--- a/packages/dataviews/src/view-actions.tsx
+++ b/packages/dataviews/src/view-actions.tsx
@@ -303,7 +303,7 @@ function SortMenu< Item extends AnyItem >( {
);
}
-const ViewActions = memo( function ViewActions< Item extends AnyItem >( {
+function _ViewActions< Item extends AnyItem >( {
fields,
view,
onChangeView,
@@ -339,6 +339,9 @@ const ViewActions = memo( function ViewActions< Item extends AnyItem >( {
);
-} );
+}
+
+// A type assertion is used here to keep the type argument.
+const ViewActions = memo( _ViewActions ) as typeof _ViewActions;
export default ViewActions;
diff --git a/packages/dataviews/src/view-grid.tsx b/packages/dataviews/src/view-grid.tsx
index f42ec215be9d23..5c6b8ba5bc3b50 100644
--- a/packages/dataviews/src/view-grid.tsx
+++ b/packages/dataviews/src/view-grid.tsx
@@ -22,16 +22,7 @@ import { __ } from '@wordpress/i18n';
import ItemActions from './item-actions';
import SingleSelectionCheckbox from './single-selection-checkbox';
import { useHasAPossibleBulkAction } from './bulk-actions';
-import type {
- Action,
- AnyItem,
- NormalizedField,
- ViewGrid as ViewGridType,
- ViewProps,
-} from './types';
-
-interface ViewGridProps< Item extends AnyItem >
- extends ViewProps< Item, ViewGridType > {}
+import type { Action, AnyItem, NormalizedField, ViewGridProps } from './types';
interface GridItemProps< Item extends AnyItem > {
selection: string[];
diff --git a/packages/dataviews/src/view-list.tsx b/packages/dataviews/src/view-list.tsx
index f829b505454b30..1e7a558bbad5eb 100644
--- a/packages/dataviews/src/view-list.tsx
+++ b/packages/dataviews/src/view-list.tsx
@@ -32,19 +32,10 @@ import { moreVertical } from '@wordpress/icons';
* Internal dependencies
*/
import { unlock } from './lock-unlock';
-import type {
- Action,
- AnyItem,
- NormalizedField,
- ViewList as ViewListType,
- ViewProps,
-} from './types';
+import type { Action, AnyItem, NormalizedField, ViewListProps } from './types';
import { ActionsDropdownMenuGroup, ActionModal } from './item-actions';
-interface ViewListProps< Item extends AnyItem >
- extends ViewProps< Item, ViewListType > {}
-
interface ListViewItemProps< Item extends AnyItem > {
actions: Action< Item >[];
id?: string;
diff --git a/packages/dataviews/src/view-table.tsx b/packages/dataviews/src/view-table.tsx
index 9ecfa9c9c0770d..dcfb8a67bf3636 100644
--- a/packages/dataviews/src/view-table.tsx
+++ b/packages/dataviews/src/view-table.tsx
@@ -50,8 +50,8 @@ import type {
AnyItem,
NormalizedField,
SortDirection,
- ViewProps,
ViewTable as ViewTableType,
+ ViewTableProps,
} from './types';
const {
@@ -91,9 +91,6 @@ interface TableRowProps< Item extends AnyItem > {
data: Item[];
}
-interface ViewTableProps< Item extends AnyItem >
- extends ViewProps< Item, ViewTableType > {}
-
function WithDropDownMenuSeparators( { children }: { children: ReactNode } ) {
return Children.toArray( children )
.filter( Boolean )
diff --git a/packages/e2e-tests/plugins/interactive-blocks/namespace/render.php b/packages/e2e-tests/plugins/interactive-blocks/namespace/render.php
index 6fdc2d07e350c8..0b7e40b6c1653b 100644
--- a/packages/e2e-tests/plugins/interactive-blocks/namespace/render.php
+++ b/packages/e2e-tests/plugins/interactive-blocks/namespace/render.php
@@ -18,6 +18,28 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/packages/e2e-tests/plugins/interactive-blocks/namespace/view.js b/packages/e2e-tests/plugins/interactive-blocks/namespace/view.js
index 9225f88ce9d279..5717387395ff24 100644
--- a/packages/e2e-tests/plugins/interactive-blocks/namespace/view.js
+++ b/packages/e2e-tests/plugins/interactive-blocks/namespace/view.js
@@ -3,9 +3,16 @@
*/
import { store } from '@wordpress/interactivity';
+
+store( '', {
+ state: {
+ url: '/empty-string-url',
+ },
+} );
+
store( 'namespace', {
state: {
- url: '/some-url',
+ url: '/namespace-url',
},
} );
@@ -14,3 +21,50 @@ store( 'other', {
url: '/other-store-url',
},
} );
+
+store( 'null', {
+ state: {
+ url: '/null-url',
+ },
+} );
+
+store( '2', {
+ state: {
+ url: '/number-url',
+ },
+} );
+
+store( '{}', {
+ state: {
+ url: '/object-url',
+ },
+} );
+
+store( 'true', {
+ state: {
+ url: '/true-url',
+ },
+} );
+
+store( 'false', {
+ state: {
+ url: '/false-url',
+ },
+} );
+
+store( '[]', {
+ state: {
+ url: '/array-url',
+ },
+} );
+
+store( '"quoted string"', {
+ state: {
+ url: '/quoted-url',
+ },
+} );
+
+
+
+
+
diff --git a/packages/edit-site/src/components/dataviews-actions/index.js b/packages/edit-site/src/components/dataviews-actions/index.js
index ed6522995d3b7b..09b7597c6cb341 100644
--- a/packages/edit-site/src/components/dataviews-actions/index.js
+++ b/packages/edit-site/src/components/dataviews-actions/index.js
@@ -9,6 +9,7 @@ import { privateApis as routerPrivateApis } from '@wordpress/router';
/**
* Internal dependencies
*/
+import { PATTERN_TYPES } from '../../utils/constants';
import { unlock } from '../../lock-unlock';
const { useHistory } = unlock( routerPrivateApis );
@@ -21,8 +22,12 @@ export const useEditPostAction = () => {
label: __( 'Edit' ),
isPrimary: true,
icon: edit,
- isEligible( { status } ) {
- return status !== 'trash';
+ isEligible( post ) {
+ if ( post.status === 'trash' ) {
+ return false;
+ }
+ // It's eligible for all post types except theme patterns.
+ return post.type !== PATTERN_TYPES.theme;
},
callback( items ) {
const post = items[ 0 ];
diff --git a/packages/edit-site/src/components/editor/index.js b/packages/edit-site/src/components/editor/index.js
index ba4d751de5ae08..b7fc350c3eabb9 100644
--- a/packages/edit-site/src/components/editor/index.js
+++ b/packages/edit-site/src/components/editor/index.js
@@ -213,6 +213,7 @@ export default function Editor( { isLoading } ) {
( actionId, items ) => {
switch ( actionId ) {
case 'move-to-trash':
+ case 'delete-post':
{
history.push( {
postType: items[ 0 ].type,
diff --git a/packages/edit-site/src/components/global-styles/background-panel.js b/packages/edit-site/src/components/global-styles/background-panel.js
index 0ad74e0cd0bdd5..8a372587bc66e5 100644
--- a/packages/edit-site/src/components/global-styles/background-panel.js
+++ b/packages/edit-site/src/components/global-styles/background-panel.js
@@ -2,7 +2,6 @@
* WordPress dependencies
*/
import { privateApis as blockEditorPrivateApis } from '@wordpress/block-editor';
-import { __ } from '@wordpress/i18n';
/**
* Internal dependencies
@@ -59,7 +58,6 @@ export default function BackgroundPanel() {
value={ style }
onChange={ setStyle }
settings={ settings }
- headerLabel={ __( 'Background' ) }
defaultValues={ BACKGROUND_DEFAULT_VALUES }
defaultControls={ defaultControls }
themeFileURIs={ _links?.[ 'wp:theme-file' ] }
diff --git a/packages/edit-site/src/components/save-panel/index.js b/packages/edit-site/src/components/save-panel/index.js
index 87621638b233fe..1f784edc52234f 100644
--- a/packages/edit-site/src/components/save-panel/index.js
+++ b/packages/edit-site/src/components/save-panel/index.js
@@ -151,9 +151,7 @@ export default function SavePanel() {
>
@@ -511,7 +622,7 @@ const renamePostAction = {
) {
return true;
}
- // In the case of templates, we can only remove custom templates.
+ // In the case of templates, we can only rename custom templates.
if ( post.type === TEMPLATE_POST_TYPE ) {
return isTemplateRemovable( post ) && post.is_custom;
}
@@ -850,245 +961,6 @@ const resetTemplateAction = {
},
};
-/**
- * Check if a template is removable.
- * Copy from packages/edit-site/src/utils/is-template-removable.js.
- *
- * @param {Object} template The template entity to check.
- * @return {boolean} Whether the template is revertable.
- */
-function isTemplateRemovable( template ) {
- if ( ! template ) {
- return false;
- }
-
- return (
- template.source === TEMPLATE_ORIGINS.custom && ! template.has_theme_file
- );
-}
-
-const deleteTemplateAction = {
- id: 'delete-template',
- label: __( 'Delete' ),
- isEligible: isTemplateRemovable,
- icon: trash,
- supportsBulk: true,
- hideModalHeader: true,
- RenderModal: ( {
- items: templates,
- closeModal,
- onActionStart,
- onActionPerformed,
- } ) => {
- const [ isBusy, setIsBusy ] = useState( false );
- const { removeTemplates } = unlock( useDispatch( editorStore ) );
- return (
-
-
- { templates.length > 1
- ? sprintf(
- // translators: %d: number of items to delete.
- _n(
- 'Delete %d item?',
- 'Delete %d items?',
- templates.length
- ),
- templates.length
- )
- : sprintf(
- // translators: %s: The template or template part's titles
- __( 'Delete "%s"?' ),
- decodeEntities(
- templates?.[ 0 ]?.title?.rendered
- )
- ) }
-
-
-
- { __( 'Cancel' ) }
-
- {
- setIsBusy( true );
- if ( onActionStart ) {
- onActionStart( templates );
- }
- await removeTemplates( templates, {
- allowUndo: false,
- } );
- onActionPerformed?.( templates );
- setIsBusy( false );
- closeModal();
- } }
- isBusy={ isBusy }
- disabled={ isBusy }
- __experimentalIsFocusable
- >
- { __( 'Delete' ) }
-
-
-
- );
- },
-};
-
-const canDeleteOrReset = ( item ) => {
- const isTemplatePart = item.type === TEMPLATE_PART_POST_TYPE;
- const isUserPattern = item.type === PATTERN_TYPES.user;
- return isUserPattern || ( isTemplatePart && item.isCustom );
-};
-
-export const deletePatternAction = {
- id: 'delete-pattern',
- label: __( 'Delete' ),
- isEligible: ( item ) => {
- if ( ! item ) {
- return false;
- }
- const isTemplatePart = item.type === TEMPLATE_PART_POST_TYPE;
- const hasThemeFile =
- isTemplatePart && item.templatePart?.has_theme_file;
- return canDeleteOrReset( item ) && ! hasThemeFile;
- },
- hideModalHeader: true,
- supportsBulk: true,
- RenderModal: ( { items, closeModal, onActionPerformed } ) => {
- const { __experimentalDeleteReusableBlock } =
- useDispatch( reusableBlocksStore );
- const { createErrorNotice, createSuccessNotice } =
- useDispatch( noticesStore );
- const { removeTemplates } = unlock( useDispatch( editorStore ) );
-
- const deletePattern = async () => {
- const promiseResult = await Promise.allSettled(
- items.map( ( item ) => {
- return __experimentalDeleteReusableBlock( item.id );
- } )
- );
- // If all the promises were fulfilled with success.
- if (
- promiseResult.every( ( { status } ) => status === 'fulfilled' )
- ) {
- let successMessage;
- if ( promiseResult.length === 1 ) {
- successMessage = sprintf(
- /* translators: The posts's title. */
- __( '"%s" deleted.' ),
- items[ 0 ].title
- );
- } else {
- successMessage = __( 'The patterns were deleted.' );
- }
- createSuccessNotice( successMessage, {
- type: 'snackbar',
- id: 'edit-site-page-trashed',
- } );
- } else {
- // If there was at lease one failure.
- let errorMessage;
- // If we were trying to delete a single pattern.
- if ( promiseResult.length === 1 ) {
- if ( promiseResult[ 0 ].reason?.message ) {
- errorMessage = promiseResult[ 0 ].reason.message;
- } else {
- errorMessage = __(
- 'An error occurred while deleting the pattern.'
- );
- }
- // If we were trying to delete multiple patterns.
- } else {
- const errorMessages = new Set();
- const failedPromises = promiseResult.filter(
- ( { status } ) => status === 'rejected'
- );
- for ( const failedPromise of failedPromises ) {
- if ( failedPromise.reason?.message ) {
- errorMessages.add( failedPromise.reason.message );
- }
- }
- if ( errorMessages.size === 0 ) {
- errorMessage = __(
- 'An error occurred while deleting the patterns.'
- );
- } else if ( errorMessages.size === 1 ) {
- errorMessage = sprintf(
- /* translators: %s: an error message */
- __(
- 'An error occurred while deleting the patterns: %s'
- ),
- [ ...errorMessages ][ 0 ]
- );
- } else {
- errorMessage = sprintf(
- /* translators: %s: a list of comma separated error messages */
- __(
- 'Some errors occurred while deleting the patterns: %s'
- ),
- [ ...errorMessages ].join( ',' )
- );
- }
- createErrorNotice( errorMessage, {
- type: 'snackbar',
- } );
- }
- }
- };
- const deleteItem = () => {
- if ( items[ 0 ].type === TEMPLATE_PART_POST_TYPE ) {
- removeTemplates( items );
- } else {
- deletePattern();
- }
- if ( onActionPerformed ) {
- onActionPerformed();
- }
- closeModal();
- };
- let questionMessage;
- if ( items.length === 1 ) {
- questionMessage = sprintf(
- // translators: %s: The page's title.
- __( 'Are you sure you want to delete "%s"?' ),
- decodeEntities( items[ 0 ].title || items[ 0 ].name )
- );
- } else if (
- items.length > 1 &&
- items[ 0 ].type === TEMPLATE_PART_POST_TYPE
- ) {
- questionMessage = sprintf(
- // translators: %d: The number of template parts (2 or more).
- __( 'Are you sure you want to delete %d template parts?' ),
- items.length
- );
- } else {
- questionMessage = sprintf(
- // translators: %d: The number of patterns (2 or more).
- __( 'Are you sure you want to delete %d patterns?' ),
- items.length
- );
- }
- return (
-
- { questionMessage }
-
-
- { __( 'Cancel' ) }
-
-
- { __( 'Delete' ) }
-
-
-
- );
- },
-};
-
export function usePostActions( postType, onActionPerformed ) {
const { postTypeObject } = useSelect(
( select ) => {
@@ -1108,6 +980,7 @@ export function usePostActions( postType, onActionPerformed ) {
].includes( postType );
const isPattern = postType === PATTERN_POST_TYPE;
const isLoaded = !! postTypeObject;
+ const supportsRevisions = !! postTypeObject?.supports?.revisions;
return useMemo( () => {
if ( ! isLoaded ) {
return [];
@@ -1115,7 +988,7 @@ export function usePostActions( postType, onActionPerformed ) {
const actions = [
postTypeObject?.viewable && viewPostAction,
- postRevisionsAction,
+ supportsRevisions && postRevisionsAction,
globalThis.IS_GUTENBERG_PLUGIN
? ! isTemplateOrTemplatePart &&
! isPattern &&
@@ -1124,11 +997,10 @@ export function usePostActions( postType, onActionPerformed ) {
renamePostAction,
isPattern && exportPatternAsJSONAction,
isTemplateOrTemplatePart ? resetTemplateAction : restorePostAction,
- isTemplateOrTemplatePart
- ? deleteTemplateAction
- : permanentlyDeletePostAction,
- isPattern && deletePatternAction,
- ! isTemplateOrTemplatePart && trashPostAction,
+ isTemplateOrTemplatePart || isPattern
+ ? deletePostAction
+ : trashPostAction,
+ ! isTemplateOrTemplatePart && permanentlyDeletePostAction,
].filter( Boolean );
if ( onActionPerformed ) {
@@ -1181,5 +1053,6 @@ export function usePostActions( postType, onActionPerformed ) {
restorePostAction,
onActionPerformed,
isLoaded,
+ supportsRevisions,
] );
}
diff --git a/packages/editor/src/components/sidebar/index.js b/packages/editor/src/components/sidebar/index.js
index 30d27a8c5db306..7a6a1d10282731 100644
--- a/packages/editor/src/components/sidebar/index.js
+++ b/packages/editor/src/components/sidebar/index.js
@@ -26,7 +26,6 @@ import PageAttributesPanel from '../page-attributes/panel';
import PatternOverridesPanel from '../pattern-overrides-panel';
import PluginDocumentSettingPanel from '../plugin-document-setting-panel';
import PluginSidebar from '../plugin-sidebar';
-import PostLastRevisionPanel from '../post-last-revision/panel';
import PostSummary from './post-summary';
import PostTaxonomiesPanel from '../post-taxonomies/panel';
import PostTransformPanel from '../post-transform-panel';
@@ -117,7 +116,6 @@ const SidebarContent = ( {
) }
-
diff --git a/packages/editor/src/store/private-actions.js b/packages/editor/src/store/private-actions.js
index c3fca0798e8b70..9304a2fe2c0579 100644
--- a/packages/editor/src/store/private-actions.js
+++ b/packages/editor/src/store/private-actions.js
@@ -15,7 +15,6 @@ import { decodeEntities } from '@wordpress/html-entities';
* Internal dependencies
*/
import isTemplateRevertable from './utils/is-template-revertable';
-import { TEMPLATE_POST_TYPE } from './constants';
/**
* Returns an action object used to set which template is currently being used/edited.
@@ -363,14 +362,13 @@ export const revertTemplate =
};
/**
- * Action that removes an array of templates.
+ * Action that removes an array of templates, template parts or patterns.
*
- * @param {Array} items An array of template or template part objects to remove.
+ * @param {Array} items An array of template,template part or pattern objects to remove.
*/
export const removeTemplates =
( items ) =>
async ( { registry } ) => {
- const isTemplate = items[ 0 ].type === TEMPLATE_POST_TYPE;
const promiseResult = await Promise.allSettled(
items.map( ( item ) => {
return registry
@@ -402,16 +400,14 @@ export const removeTemplates =
decodeEntities( title )
);
} else {
- successMessage = isTemplate
- ? __( 'Templates deleted.' )
- : __( 'Template parts deleted.' );
+ successMessage = __( 'Items deleted.' );
}
registry
.dispatch( noticesStore )
.createSuccessNotice( successMessage, {
type: 'snackbar',
- id: 'site-editor-template-deleted-success',
+ id: 'editor-template-deleted-success',
} );
} else {
// If there was at lease one failure.
@@ -421,11 +417,9 @@ export const removeTemplates =
if ( promiseResult[ 0 ].reason?.message ) {
errorMessage = promiseResult[ 0 ].reason.message;
} else {
- errorMessage = isTemplate
- ? __( 'An error occurred while deleting the template.' )
- : __(
- 'An error occurred while deleting the template part.'
- );
+ errorMessage = __(
+ 'An error occurred while deleting the item.'
+ );
}
// If we were trying to delete a multiple templates
} else {
@@ -439,45 +433,23 @@ export const removeTemplates =
}
}
if ( errorMessages.size === 0 ) {
- errorMessage = isTemplate
- ? __(
- 'An error occurred while deleting the templates.'
- )
- : __(
- 'An error occurred while deleting the template parts.'
- );
+ errorMessage = __(
+ 'An error occurred while deleting the items.'
+ );
} else if ( errorMessages.size === 1 ) {
- errorMessage = isTemplate
- ? sprintf(
- /* translators: %s: an error message */
- __(
- 'An error occurred while deleting the templates: %s'
- ),
- [ ...errorMessages ][ 0 ]
- )
- : sprintf(
- /* translators: %s: an error message */
- __(
- 'An error occurred while deleting the template parts: %s'
- ),
- [ ...errorMessages ][ 0 ]
- );
+ errorMessage = sprintf(
+ /* translators: %s: an error message */
+ __( 'An error occurred while deleting the items: %s' ),
+ [ ...errorMessages ][ 0 ]
+ );
} else {
- errorMessage = isTemplate
- ? sprintf(
- /* translators: %s: a list of comma separated error messages */
- __(
- 'Some errors occurred while deleting the templates: %s'
- ),
- [ ...errorMessages ].join( ',' )
- )
- : sprintf(
- /* translators: %s: a list of comma separated error messages */
- __(
- 'Some errors occurred while deleting the template parts: %s'
- ),
- [ ...errorMessages ].join( ',' )
- );
+ sprintf(
+ /* translators: %s: a list of comma separated error messages */
+ __(
+ 'Some errors occurred while deleting the items: %s'
+ ),
+ [ ...errorMessages ].join( ',' )
+ );
}
}
registry
diff --git a/packages/interactivity/CHANGELOG.md b/packages/interactivity/CHANGELOG.md
index e40c68a50180a2..c3542b914de159 100644
--- a/packages/interactivity/CHANGELOG.md
+++ b/packages/interactivity/CHANGELOG.md
@@ -2,6 +2,10 @@
## Unreleased
+### Bug fixes
+
+- Fix null and number strings as namespaces runtime error. ([#61960](https://github.com/WordPress/gutenberg/pull/61960/))
+
### Breaking Changes
- Variables like `process.env.IS_GUTENBERG_PLUGIN` have been replaced by `globalThis.IS_GUTENBERG_PLUGIN`. Build systems using `process.env` should be updated ([#61486](https://github.com/WordPress/gutenberg/pull/61486)).
diff --git a/packages/interactivity/src/store.ts b/packages/interactivity/src/store.ts
index d173f2cd842dc1..9b35192fe8b132 100644
--- a/packages/interactivity/src/store.ts
+++ b/packages/interactivity/src/store.ts
@@ -15,7 +15,6 @@ import {
setNamespace,
resetNamespace,
} from './hooks';
-
const isObject = ( item: unknown ): item is Record< string, unknown > =>
Boolean( item && typeof item === 'object' && item.constructor === Object );
diff --git a/packages/interactivity/src/vdom.ts b/packages/interactivity/src/vdom.ts
index cc481f89ff772a..98deca656cfa6c 100644
--- a/packages/interactivity/src/vdom.ts
+++ b/packages/interactivity/src/vdom.ts
@@ -13,6 +13,8 @@ const islandAttr = `data-${ p }-interactive`;
const fullPrefix = `data-${ p }-`;
const namespaces: Array< string | null > = [];
const currentNamespace = () => namespaces[ namespaces.length - 1 ] ?? null;
+const isObject = ( item: unknown ): item is Record< string, unknown > =>
+ Boolean( item && typeof item === 'object' && item.constructor === Object );
// Regular expression for directive parsing.
const directiveParser = new RegExp(
@@ -100,8 +102,9 @@ export function toVdom( root: Node ): Array< ComponentChild > {
const namespace = regexResult?.[ 1 ] ?? null;
let value: any = regexResult?.[ 2 ] ?? attributeValue;
try {
- value = value && JSON.parse( value );
- } catch ( e ) {}
+ const parsedValue = JSON.parse( value );
+ value = isObject( parsedValue ) ? parsedValue : value;
+ } catch {}
if ( attributeName === islandAttr ) {
island = true;
const islandNamespace =
diff --git a/phpunit/class-wp-theme-json-test.php b/phpunit/class-wp-theme-json-test.php
index 00799b7ba0b478..28401bb20d484d 100644
--- a/phpunit/class-wp-theme-json-test.php
+++ b/phpunit/class-wp-theme-json-test.php
@@ -547,7 +547,7 @@ public function test_get_stylesheet() {
);
$variables = ':root{--wp--preset--color--grey: grey;--wp--preset--gradient--custom-gradient: linear-gradient(135deg,rgba(0,0,0) 0%,rgb(0,0,0) 100%);--wp--preset--font-size--small: 14px;--wp--preset--font-size--big: 41px;--wp--preset--font-family--arial: Arial, serif;}.wp-block-group{--wp--custom--base-font: 16;--wp--custom--line-height--small: 1.2;--wp--custom--line-height--medium: 1.4;--wp--custom--line-height--large: 1.8;}';
- $styles = static::$base_styles . ':where(body){color: var(--wp--preset--color--grey);}:where(a:where(:not(.wp-element-button))){background-color: #333;color: #111;}:where(.wp-element-button, .wp-block-button__link){box-shadow: 10px 10px 5px 0px rgba(0,0,0,0.66);}:where(.wp-block-cover){min-height: unset;aspect-ratio: 16/9;}:where(.wp-block-group){background: var(--wp--preset--gradient--custom-gradient);border-radius: 10px;min-height: 50vh;padding: 24px;}:where(.wp-block-group a:where(:not(.wp-element-button))){color: #111;}:where(.wp-block-heading){color: #123456;}:where(.wp-block-heading a:where(:not(.wp-element-button))){background-color: #333;color: #111;font-size: 60px;}:where(.wp-block-post-date){color: #123456;}:where(.wp-block-post-date a:where(:not(.wp-element-button))){background-color: #777;color: #555;}:where(.wp-block-post-excerpt){column-count: 2;}:where(.wp-block-image){margin-bottom: 30px;}:where(.wp-block-image img, .wp-block-image .wp-block-image__crop-area, .wp-block-image .components-placeholder){border-top-left-radius: 10px;border-bottom-right-radius: 1em;}:where(.wp-block-image img, .wp-block-image .components-placeholder){filter: var(--wp--preset--duotone--custom-duotone);}';
+ $styles = static::$base_styles . ':root :where(body){color: var(--wp--preset--color--grey);}:root :where(a:where(:not(.wp-element-button))){background-color: #333;color: #111;}:root :where(.wp-element-button, .wp-block-button__link){box-shadow: 10px 10px 5px 0px rgba(0,0,0,0.66);}:root :where(.wp-block-cover){min-height: unset;aspect-ratio: 16/9;}:root :where(.wp-block-group){background: var(--wp--preset--gradient--custom-gradient);border-radius: 10px;min-height: 50vh;padding: 24px;}:root :where(.wp-block-group a:where(:not(.wp-element-button))){color: #111;}:root :where(.wp-block-heading){color: #123456;}:root :where(.wp-block-heading a:where(:not(.wp-element-button))){background-color: #333;color: #111;font-size: 60px;}:root :where(.wp-block-post-date){color: #123456;}:root :where(.wp-block-post-date a:where(:not(.wp-element-button))){background-color: #777;color: #555;}:root :where(.wp-block-post-excerpt){column-count: 2;}:root :where(.wp-block-image){margin-bottom: 30px;}:root :where(.wp-block-image img, .wp-block-image .wp-block-image__crop-area, .wp-block-image .components-placeholder){border-top-left-radius: 10px;border-bottom-right-radius: 1em;}:root :where(.wp-block-image img, .wp-block-image .components-placeholder){filter: var(--wp--preset--duotone--custom-duotone);}';
$presets = '.has-grey-color{color: var(--wp--preset--color--grey) !important;}.has-grey-background-color{background-color: var(--wp--preset--color--grey) !important;}.has-grey-border-color{border-color: var(--wp--preset--color--grey) !important;}.has-custom-gradient-gradient-background{background: var(--wp--preset--gradient--custom-gradient) !important;}.has-small-font-size{font-size: var(--wp--preset--font-size--small) !important;}.has-big-font-size{font-size: var(--wp--preset--font-size--big) !important;}.has-arial-font-family{font-family: var(--wp--preset--font-family--arial) !important;}';
$all = $variables . $styles . $presets;
@@ -593,7 +593,7 @@ public function test_get_stylesheet_support_for_shorthand_and_longhand_values()
)
);
- $styles = static::$base_styles . ':where(.wp-block-group){border-radius: 10px;margin: 1em;padding: 24px;}:where(.wp-block-image){margin-bottom: 30px;padding-top: 15px;}:where(.wp-block-image img, .wp-block-image .wp-block-image__crop-area, .wp-block-image .components-placeholder){border-top-left-radius: 10px;border-bottom-right-radius: 1em;}';
+ $styles = static::$base_styles . ':root :where(.wp-block-group){border-radius: 10px;margin: 1em;padding: 24px;}:root :where(.wp-block-image){margin-bottom: 30px;padding-top: 15px;}:root :where(.wp-block-image img, .wp-block-image .wp-block-image__crop-area, .wp-block-image .components-placeholder){border-top-left-radius: 10px;border-bottom-right-radius: 1em;}';
$this->assertSame( $styles, $theme_json->get_stylesheet() );
$this->assertSame( $styles, $theme_json->get_stylesheet( array( 'styles' ) ) );
}
@@ -644,7 +644,7 @@ public function test_get_stylesheet_renders_enabled_protected_properties() {
)
);
- $expected = ':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(.wp-site-blocks) > * { margin-block-start: 1em; margin-block-end: 0; }:where(.wp-site-blocks) > :first-child { margin-block-start: 0; }:where(.wp-site-blocks) > :last-child { margin-block-end: 0; }:root { --wp--style--block-gap: 1em; }:where(.is-layout-flow) > :first-child{margin-block-start: 0;}:where(.is-layout-flow) > :last-child{margin-block-end: 0;}:where(.is-layout-flow) > *{margin-block-start: 1em;margin-block-end: 0;}:where(.is-layout-constrained) > :first-child{margin-block-start: 0;}:where(.is-layout-constrained) > :last-child{margin-block-end: 0;}:where(.is-layout-constrained) > *{margin-block-start: 1em;margin-block-end: 0;}:where(.is-layout-flex) {gap: 1em;}:where(.is-layout-grid) {gap: 1em;}.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;}';
+ $expected = ':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(.wp-site-blocks) > * { margin-block-start: 1em; margin-block-end: 0; }:where(.wp-site-blocks) > :first-child { margin-block-start: 0; }:where(.wp-site-blocks) > :last-child { margin-block-end: 0; }:root { --wp--style--block-gap: 1em; }.is-layout-flow > :first-child{margin-block-start: 0;}.is-layout-flow > :last-child{margin-block-end: 0;}.is-layout-flow > *{margin-block-start: 1em;margin-block-end: 0;}.is-layout-constrained > :first-child{margin-block-start: 0;}.is-layout-constrained > :last-child{margin-block-end: 0;}.is-layout-constrained > *{margin-block-start: 1em;margin-block-end: 0;}.is-layout-flex {gap: 1em;}.is-layout-grid {gap: 1em;}.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;}';
$this->assertSame( $expected, $theme_json->get_stylesheet() );
$this->assertSame( $expected, $theme_json->get_stylesheet( array( 'styles' ) ) );
}
@@ -706,7 +706,7 @@ public function test_get_stylesheet_preset_rules_come_after_block_rules() {
)
);
- $styles = static::$base_styles . ':where(.wp-block-group){color: red;}';
+ $styles = static::$base_styles . ':root :where(.wp-block-group){color: red;}';
$presets = '.wp-block-group.has-grey-color{color: var(--wp--preset--color--grey) !important;}.wp-block-group.has-grey-background-color{background-color: var(--wp--preset--color--grey) !important;}.wp-block-group.has-grey-border-color{border-color: var(--wp--preset--color--grey) !important;}';
$variables = '.wp-block-group{--wp--preset--color--grey: grey;}';
@@ -793,7 +793,7 @@ public function test_get_stylesheet_preset_values_are_marked_as_important() {
);
$this->assertSame(
- ':root{--wp--preset--color--grey: grey;}' . static::$base_styles . ':where(p){background-color: blue;color: red;font-size: 12px;line-height: 1.3;}.has-grey-color{color: var(--wp--preset--color--grey) !important;}.has-grey-background-color{background-color: var(--wp--preset--color--grey) !important;}.has-grey-border-color{border-color: var(--wp--preset--color--grey) !important;}',
+ ':root{--wp--preset--color--grey: grey;}' . static::$base_styles . ':root :where(p){background-color: blue;color: red;font-size: 12px;line-height: 1.3;}.has-grey-color{color: var(--wp--preset--color--grey) !important;}.has-grey-background-color{background-color: var(--wp--preset--color--grey) !important;}.has-grey-border-color{border-color: var(--wp--preset--color--grey) !important;}',
$theme_json->get_stylesheet()
);
}
@@ -831,7 +831,7 @@ public function test_get_stylesheet_handles_whitelisted_element_pseudo_selectors
)
);
- $element_styles = ':where(a:where(:not(.wp-element-button))){background-color: red;color: green;}:where(a:where(:not(.wp-element-button)):hover){background-color: green;color: red;font-size: 10em;text-transform: uppercase;}:where(a:where(:not(.wp-element-button)):focus){background-color: black;color: yellow;}';
+ $element_styles = ':root :where(a:where(:not(.wp-element-button))){background-color: red;color: green;}:root :where(a:where(:not(.wp-element-button)):hover){background-color: green;color: red;font-size: 10em;text-transform: uppercase;}:root :where(a:where(:not(.wp-element-button)):focus){background-color: black;color: yellow;}';
$expected = static::$base_styles . $element_styles;
@@ -868,7 +868,7 @@ public function test_get_stylesheet_handles_only_pseudo_selector_rules_for_given
)
);
- $element_styles = ':where(a:where(:not(.wp-element-button)):hover){background-color: green;color: red;font-size: 10em;text-transform: uppercase;}:where(a:where(:not(.wp-element-button)):focus){background-color: black;color: yellow;}';
+ $element_styles = ':root :where(a:where(:not(.wp-element-button)):hover){background-color: green;color: red;font-size: 10em;text-transform: uppercase;}:root :where(a:where(:not(.wp-element-button)):focus){background-color: black;color: yellow;}';
$expected = static::$base_styles . $element_styles;
@@ -905,7 +905,7 @@ public function test_get_stylesheet_ignores_pseudo_selectors_on_non_whitelisted_
)
);
- $element_styles = ':where(h4){background-color: red;color: green;}';
+ $element_styles = ':root :where(h4){background-color: red;color: green;}';
$expected = static::$base_styles . $element_styles;
@@ -942,7 +942,7 @@ public function test_get_stylesheet_ignores_non_whitelisted_pseudo_selectors() {
)
);
- $element_styles = ':where(a:where(:not(.wp-element-button))){background-color: red;color: green;}:where(a:where(:not(.wp-element-button)):hover){background-color: green;color: red;}';
+ $element_styles = ':root :where(a:where(:not(.wp-element-button))){background-color: red;color: green;}:root :where(a:where(:not(.wp-element-button)):hover){background-color: green;color: red;}';
$expected = static::$base_styles . $element_styles;
@@ -988,7 +988,7 @@ public function test_get_stylesheet_handles_priority_of_elements_vs_block_elemen
)
);
- $element_styles = ':where(.wp-block-group a:where(:not(.wp-element-button))){background-color: red;color: green;}:where(.wp-block-group a:where(:not(.wp-element-button)):hover){background-color: green;color: red;font-size: 10em;text-transform: uppercase;}:where(.wp-block-group a:where(:not(.wp-element-button)):focus){background-color: black;color: yellow;}';
+ $element_styles = ':root :where(.wp-block-group a:where(:not(.wp-element-button))){background-color: red;color: green;}:root :where(.wp-block-group a:where(:not(.wp-element-button)):hover){background-color: green;color: red;font-size: 10em;text-transform: uppercase;}:root :where(.wp-block-group a:where(:not(.wp-element-button)):focus){background-color: black;color: yellow;}';
$expected = static::$base_styles . $element_styles;
@@ -1033,7 +1033,7 @@ public function test_get_stylesheet_handles_whitelisted_block_level_element_pseu
)
);
- $element_styles = ':where(a:where(:not(.wp-element-button))){background-color: red;color: green;}:where(a:where(:not(.wp-element-button)):hover){background-color: green;color: red;}:where(.wp-block-group a:where(:not(.wp-element-button)):hover){background-color: black;color: yellow;}';
+ $element_styles = ':root :where(a:where(:not(.wp-element-button))){background-color: red;color: green;}:root :where(a:where(:not(.wp-element-button)):hover){background-color: green;color: red;}:root :where(.wp-block-group a:where(:not(.wp-element-button)):hover){background-color: black;color: yellow;}';
$expected = static::$base_styles . $element_styles;
@@ -1095,7 +1095,7 @@ public function test_get_stylesheet_with_deprecated_feature_level_selectors() {
);
$base_styles = ':root{--wp--preset--color--green: green;}' . static::$base_styles;
- $block_styles = ':where(.wp-block-test, .wp-block-test__wrapper){color: green;}:where(.wp-block-test .inner, .wp-block-test__wrapper .inner){border-radius: 9999px;padding: 20px;}:where(.wp-block-test .sub-heading, .wp-block-test__wrapper .sub-heading){font-size: 3em;}';
+ $block_styles = ':root :where(.wp-block-test, .wp-block-test__wrapper){color: green;}:root :where(.wp-block-test .inner, .wp-block-test__wrapper .inner){border-radius: 9999px;padding: 20px;}:root :where(.wp-block-test .sub-heading, .wp-block-test__wrapper .sub-heading){font-size: 3em;}';
$preset_styles = '.has-green-color{color: var(--wp--preset--color--green) !important;}.has-green-background-color{background-color: var(--wp--preset--color--green) !important;}.has-green-border-color{border-color: var(--wp--preset--color--green) !important;}';
$expected = $base_styles . $block_styles . $preset_styles;
@@ -1157,7 +1157,7 @@ public function test_get_stylesheet_with_block_json_selectors() {
);
$base_styles = ':root{--wp--preset--color--green: green;}' . static::$base_styles;
- $block_styles = ':where(.custom-root-selector){background-color: grey;padding: 20px;}:where(.custom-root-selector img){border-radius: 9999px;}:where(.custom-root-selector > figcaption){color: navy;font-size: 3em;}';
+ $block_styles = ':root :where(.custom-root-selector){background-color: grey;padding: 20px;}:root :where(.custom-root-selector img){border-radius: 9999px;}:root :where(.custom-root-selector > figcaption){color: navy;font-size: 3em;}';
$preset_styles = '.has-green-color{color: var(--wp--preset--color--green) !important;}.has-green-background-color{background-color: var(--wp--preset--color--green) !important;}.has-green-border-color{border-color: var(--wp--preset--color--green) !important;}';
$expected = $base_styles . $block_styles . $preset_styles;
@@ -1188,7 +1188,7 @@ public function test_get_stylesheet_generates_layout_styles() {
// Results also include root site blocks styles.
$this->assertSame(
- ':root { --wp--style--global--content-size: 640px;--wp--style--global--wide-size: 1200px; }: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(.wp-site-blocks) > * { margin-block-start: 1em; margin-block-end: 0; }:where(.wp-site-blocks) > :first-child { margin-block-start: 0; }:where(.wp-site-blocks) > :last-child { margin-block-end: 0; }:root { --wp--style--block-gap: 1em; }:where(.is-layout-flow) > :first-child{margin-block-start: 0;}:where(.is-layout-flow) > :last-child{margin-block-end: 0;}:where(.is-layout-flow) > *{margin-block-start: 1em;margin-block-end: 0;}:where(.is-layout-constrained) > :first-child{margin-block-start: 0;}:where(.is-layout-constrained) > :last-child{margin-block-end: 0;}:where(.is-layout-constrained) > *{margin-block-start: 1em;margin-block-end: 0;}:where(.is-layout-flex) {gap: 1em;}:where(.is-layout-grid) {gap: 1em;}.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)){max-width: var(--wp--style--global--content-size);margin-left: auto !important;margin-right: auto !important;}.is-layout-constrained > .alignwide{max-width: var(--wp--style--global--wide-size);}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;}',
+ ':root { --wp--style--global--content-size: 640px;--wp--style--global--wide-size: 1200px; }: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(.wp-site-blocks) > * { margin-block-start: 1em; margin-block-end: 0; }:where(.wp-site-blocks) > :first-child { margin-block-start: 0; }:where(.wp-site-blocks) > :last-child { margin-block-end: 0; }:root { --wp--style--block-gap: 1em; }.is-layout-flow > :first-child{margin-block-start: 0;}.is-layout-flow > :last-child{margin-block-end: 0;}.is-layout-flow > *{margin-block-start: 1em;margin-block-end: 0;}.is-layout-constrained > :first-child{margin-block-start: 0;}.is-layout-constrained > :last-child{margin-block-end: 0;}.is-layout-constrained > *{margin-block-start: 1em;margin-block-end: 0;}.is-layout-flex {gap: 1em;}.is-layout-grid {gap: 1em;}.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)){max-width: var(--wp--style--global--content-size);margin-left: auto !important;margin-right: auto !important;}.is-layout-constrained > .alignwide{max-width: var(--wp--style--global--wide-size);}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;}',
$theme_json->get_stylesheet( array( 'styles' ) )
);
}
@@ -1217,7 +1217,7 @@ public function test_get_stylesheet_generates_layout_styles_with_spacing_presets
// Results also include root site blocks styles.
$this->assertSame(
- ':root { --wp--style--global--content-size: 640px;--wp--style--global--wide-size: 1200px; }: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(.wp-site-blocks) > * { margin-block-start: var(--wp--preset--spacing--60); margin-block-end: 0; }:where(.wp-site-blocks) > :first-child { margin-block-start: 0; }:where(.wp-site-blocks) > :last-child { margin-block-end: 0; }:root { --wp--style--block-gap: var(--wp--preset--spacing--60); }:where(.is-layout-flow) > :first-child{margin-block-start: 0;}:where(.is-layout-flow) > :last-child{margin-block-end: 0;}:where(.is-layout-flow) > *{margin-block-start: var(--wp--preset--spacing--60);margin-block-end: 0;}:where(.is-layout-constrained) > :first-child{margin-block-start: 0;}:where(.is-layout-constrained) > :last-child{margin-block-end: 0;}:where(.is-layout-constrained) > *{margin-block-start: var(--wp--preset--spacing--60);margin-block-end: 0;}:where(.is-layout-flex) {gap: var(--wp--preset--spacing--60);}:where(.is-layout-grid) {gap: var(--wp--preset--spacing--60);}.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)){max-width: var(--wp--style--global--content-size);margin-left: auto !important;margin-right: auto !important;}.is-layout-constrained > .alignwide{max-width: var(--wp--style--global--wide-size);}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;}',
+ ':root { --wp--style--global--content-size: 640px;--wp--style--global--wide-size: 1200px; }: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(.wp-site-blocks) > * { margin-block-start: var(--wp--preset--spacing--60); margin-block-end: 0; }:where(.wp-site-blocks) > :first-child { margin-block-start: 0; }:where(.wp-site-blocks) > :last-child { margin-block-end: 0; }:root { --wp--style--block-gap: var(--wp--preset--spacing--60); }.is-layout-flow > :first-child{margin-block-start: 0;}.is-layout-flow > :last-child{margin-block-end: 0;}.is-layout-flow > *{margin-block-start: var(--wp--preset--spacing--60);margin-block-end: 0;}.is-layout-constrained > :first-child{margin-block-start: 0;}.is-layout-constrained > :last-child{margin-block-end: 0;}.is-layout-constrained > *{margin-block-start: var(--wp--preset--spacing--60);margin-block-end: 0;}.is-layout-flex {gap: var(--wp--preset--spacing--60);}.is-layout-grid {gap: var(--wp--preset--spacing--60);}.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)){max-width: var(--wp--style--global--content-size);margin-left: auto !important;margin-right: auto !important;}.is-layout-constrained > .alignwide{max-width: var(--wp--style--global--wide-size);}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;}',
$theme_json->get_stylesheet( array( 'styles' ) )
);
}
@@ -1345,8 +1345,8 @@ public function test_get_stylesheet_generates_valid_block_gap_values_and_skips_n
);
$this->assertSame(
- ':root { --wp--style--global--content-size: 640px;--wp--style--global--wide-size: 1200px; }: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(.wp-site-blocks) > * { margin-block-start: 1rem; margin-block-end: 0; }:where(.wp-site-blocks) > :first-child { margin-block-start: 0; }:where(.wp-site-blocks) > :last-child { margin-block-end: 0; }:root { --wp--style--block-gap: 1rem; }:where(.is-layout-flow) > :first-child{margin-block-start: 0;}:where(.is-layout-flow) > :last-child{margin-block-end: 0;}:where(.is-layout-flow) > *{margin-block-start: 1rem;margin-block-end: 0;}:where(.is-layout-constrained) > :first-child{margin-block-start: 0;}:where(.is-layout-constrained) > :last-child{margin-block-end: 0;}:where(.is-layout-constrained) > *{margin-block-start: 1rem;margin-block-end: 0;}:where(.is-layout-flex) {gap: 1rem;}:where(.is-layout-grid) {gap: 1rem;}.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)){max-width: var(--wp--style--global--content-size);margin-left: auto !important;margin-right: auto !important;}.is-layout-constrained > .alignwide{max-width: var(--wp--style--global--wide-size);}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;}' .
- ':where(.wp-block-post-content){color: gray;}:where(.wp-block-social-links-is-layout-flow) > :first-child{margin-block-start: 0;}:where(.wp-block-social-links-is-layout-flow) > :last-child{margin-block-end: 0;}:where(.wp-block-social-links-is-layout-flow) > *{margin-block-start: 0;margin-block-end: 0;}:where(.wp-block-social-links-is-layout-constrained) > :first-child{margin-block-start: 0;}:where(.wp-block-social-links-is-layout-constrained) > :last-child{margin-block-end: 0;}:where(.wp-block-social-links-is-layout-constrained) > *{margin-block-start: 0;margin-block-end: 0;}:where(.wp-block-social-links-is-layout-flex) {gap: 0;}:where(.wp-block-social-links-is-layout-grid) {gap: 0;}:where(.wp-block-buttons-is-layout-flow) > :first-child{margin-block-start: 0;}:where(.wp-block-buttons-is-layout-flow) > :last-child{margin-block-end: 0;}:where(.wp-block-buttons-is-layout-flow) > *{margin-block-start: 0;margin-block-end: 0;}:where(.wp-block-buttons-is-layout-constrained) > :first-child{margin-block-start: 0;}:where(.wp-block-buttons-is-layout-constrained) > :last-child{margin-block-end: 0;}:where(.wp-block-buttons-is-layout-constrained) > *{margin-block-start: 0;margin-block-end: 0;}:where(.wp-block-buttons-is-layout-flex) {gap: 0;}:where(.wp-block-buttons-is-layout-grid) {gap: 0;}',
+ ':root { --wp--style--global--content-size: 640px;--wp--style--global--wide-size: 1200px; }: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(.wp-site-blocks) > * { margin-block-start: 1rem; margin-block-end: 0; }:where(.wp-site-blocks) > :first-child { margin-block-start: 0; }:where(.wp-site-blocks) > :last-child { margin-block-end: 0; }:root { --wp--style--block-gap: 1rem; }.is-layout-flow > :first-child{margin-block-start: 0;}.is-layout-flow > :last-child{margin-block-end: 0;}.is-layout-flow > *{margin-block-start: 1rem;margin-block-end: 0;}.is-layout-constrained > :first-child{margin-block-start: 0;}.is-layout-constrained > :last-child{margin-block-end: 0;}.is-layout-constrained > *{margin-block-start: 1rem;margin-block-end: 0;}.is-layout-flex {gap: 1rem;}.is-layout-grid {gap: 1rem;}.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)){max-width: var(--wp--style--global--content-size);margin-left: auto !important;margin-right: auto !important;}.is-layout-constrained > .alignwide{max-width: var(--wp--style--global--wide-size);}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;}' .
+ ':root :where(.wp-block-post-content){color: gray;}.wp-block-social-links-is-layout-flow > :first-child{margin-block-start: 0;}.wp-block-social-links-is-layout-flow > :last-child{margin-block-end: 0;}.wp-block-social-links-is-layout-flow > *{margin-block-start: 0;margin-block-end: 0;}.wp-block-social-links-is-layout-constrained > :first-child{margin-block-start: 0;}.wp-block-social-links-is-layout-constrained > :last-child{margin-block-end: 0;}.wp-block-social-links-is-layout-constrained > *{margin-block-start: 0;margin-block-end: 0;}.wp-block-social-links-is-layout-flex {gap: 0;}.wp-block-social-links-is-layout-grid {gap: 0;}.wp-block-buttons-is-layout-flow > :first-child{margin-block-start: 0;}.wp-block-buttons-is-layout-flow > :last-child{margin-block-end: 0;}.wp-block-buttons-is-layout-flow > *{margin-block-start: 0;margin-block-end: 0;}.wp-block-buttons-is-layout-constrained > :first-child{margin-block-start: 0;}.wp-block-buttons-is-layout-constrained > :last-child{margin-block-end: 0;}.wp-block-buttons-is-layout-constrained > *{margin-block-start: 0;margin-block-end: 0;}.wp-block-buttons-is-layout-flex {gap: 0;}.wp-block-buttons-is-layout-grid {gap: 0;}',
$theme_json->get_stylesheet()
);
}
@@ -1378,7 +1378,7 @@ public function test_get_stylesheet_returns_outline_styles() {
)
);
- $element_styles = ':where(.wp-element-button, .wp-block-button__link){outline-color: red;outline-offset: 3px;outline-style: dashed;outline-width: 3px;}:where(.wp-element-button:hover, .wp-block-button__link:hover){outline-color: blue;outline-offset: 3px;outline-style: solid;outline-width: 3px;}';
+ $element_styles = ':root :where(.wp-element-button, .wp-block-button__link){outline-color: red;outline-offset: 3px;outline-style: dashed;outline-width: 3px;}:root :where(.wp-element-button:hover, .wp-block-button__link:hover){outline-color: blue;outline-offset: 3px;outline-style: solid;outline-width: 3px;}';
$expected = static::$base_styles . $element_styles;
$this->assertSame( $expected, $theme_json->get_stylesheet() );
@@ -1403,7 +1403,7 @@ public function test_get_stylesheet_custom_root_selector() {
// Results also include root site blocks styles which hard code
// `:where(body) { margin: 0; }`.
$this->assertSame(
- ':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(.custom){color: teal;}',
+ ':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; }:root :where(.custom){color: teal;}',
$actual
);
}
@@ -1462,7 +1462,7 @@ public function test_get_stylesheet_generates_fluid_typography_values() {
// Results also include root site blocks styles.
$this->assertSame(
- ':root{--wp--preset--font-size--pickles: clamp(14px, 0.875rem + ((1vw - 3.2px) * 0.156), 16px);--wp--preset--font-size--toast: clamp(14.642px, 0.915rem + ((1vw - 3.2px) * 0.575), 22px);}: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;}:where(body){font-size: clamp(0.875em, 0.875rem + ((1vw - 0.2em) * 0.156), 1em);}:where(h1){font-size: clamp(50.171px, 3.136rem + ((1vw - 3.2px) * 3.893), 100px);}:where(.wp-block-test-clamp-me){font-size: clamp(27.894px, 1.743rem + ((1vw - 3.2px) * 1.571), 48px);}.has-pickles-font-size{font-size: var(--wp--preset--font-size--pickles) !important;}.has-toast-font-size{font-size: var(--wp--preset--font-size--toast) !important;}',
+ ':root{--wp--preset--font-size--pickles: clamp(14px, 0.875rem + ((1vw - 3.2px) * 0.156), 16px);--wp--preset--font-size--toast: clamp(14.642px, 0.915rem + ((1vw - 3.2px) * 0.575), 22px);}: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;}:root :where(body){font-size: clamp(0.875em, 0.875rem + ((1vw - 0.2em) * 0.156), 1em);}:root :where(h1){font-size: clamp(50.171px, 3.136rem + ((1vw - 3.2px) * 3.893), 100px);}:root :where(.wp-block-test-clamp-me){font-size: clamp(27.894px, 1.743rem + ((1vw - 3.2px) * 1.571), 48px);}.has-pickles-font-size{font-size: var(--wp--preset--font-size--pickles) !important;}.has-toast-font-size{font-size: var(--wp--preset--font-size--toast) !important;}',
$theme_json->get_stylesheet()
);
}
@@ -3519,7 +3519,7 @@ public function test_get_property_value_valid() {
)
);
- $color_styles = ':where(body){background-color: #ffffff;color: #000000;}:where(.wp-element-button, .wp-block-button__link){background-color: #000000;color: #ffffff;}';
+ $color_styles = ':root :where(body){background-color: #ffffff;color: #000000;}:root :where(.wp-element-button, .wp-block-button__link){background-color: #000000;color: #ffffff;}';
$expected = static::$base_styles . $color_styles;
$this->assertSame( $expected, $theme_json->get_stylesheet() );
}
@@ -3597,7 +3597,7 @@ public function test_get_property_value_loop() {
)
);
- $color_styles = ':where(body){background-color: #ffffff;}:where(.wp-element-button, .wp-block-button__link){color: #ffffff;}';
+ $color_styles = ':root :where(body){background-color: #ffffff;}:root :where(.wp-element-button, .wp-block-button__link){color: #ffffff;}';
$expected = static::$base_styles . $color_styles;
$this->assertSame( $expected, $theme_json->get_stylesheet() );
}
@@ -3630,7 +3630,7 @@ public function test_get_property_value_recursion() {
)
);
- $color_styles = ':where(body){background-color: #ffffff;color: #ffffff;}:where(.wp-element-button, .wp-block-button__link){color: #ffffff;}';
+ $color_styles = ':root :where(body){background-color: #ffffff;color: #ffffff;}:root :where(.wp-element-button, .wp-block-button__link){color: #ffffff;}';
$expected = static::$base_styles . $color_styles;
$this->assertSame( $expected, $theme_json->get_stylesheet() );
}
@@ -3654,7 +3654,7 @@ public function test_get_property_value_self() {
)
);
- $color_styles = ':where(body){background-color: #ffffff;}';
+ $color_styles = ':root :where(body){background-color: #ffffff;}';
$expected = static::$base_styles . $color_styles;
$this->assertSame( $expected, $theme_json->get_stylesheet() );
}
@@ -3684,7 +3684,7 @@ public function test_get_styles_for_block_with_padding_aware_alignments() {
'selector' => 'body',
);
- $expected = ':where(body) { margin: 0; }.wp-site-blocks { padding-top: var(--wp--style--root--padding-top); padding-bottom: var(--wp--style--root--padding-bottom); }.has-global-padding { padding-right: var(--wp--style--root--padding-right); padding-left: var(--wp--style--root--padding-left); }.has-global-padding :where(.has-global-padding:not(.wp-block-block)) { padding-right: 0; padding-left: 0; }.has-global-padding > .alignfull { margin-right: calc(var(--wp--style--root--padding-right) * -1); margin-left: calc(var(--wp--style--root--padding-left) * -1); }.has-global-padding :where(.has-global-padding:not(.wp-block-block)) > .alignfull { margin-right: 0; margin-left: 0; }.has-global-padding > .alignfull:where(:not(.has-global-padding):not(.is-layout-flex):not(.is-layout-grid)) > :where([class*="wp-block-"]:not(.alignfull):not([class*="__"]),.wp-block:not(.alignfull),p,h1,h2,h3,h4,h5,h6,ul,ol) { padding-right: var(--wp--style--root--padding-right); padding-left: var(--wp--style--root--padding-left); }.has-global-padding :where(.has-global-padding) > .alignfull:where(:not(.has-global-padding)) > :where([class*="wp-block-"]:not(.alignfull):not([class*="__"]),.wp-block:not(.alignfull),p,h1,h2,h3,h4,h5,h6,ul,ol) { padding-right: 0; padding-left: 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;}:where(body){--wp--style--root--padding-top: 10px;--wp--style--root--padding-right: 12px;--wp--style--root--padding-bottom: 10px;--wp--style--root--padding-left: 12px;}';
+ $expected = ':where(body) { margin: 0; }.wp-site-blocks { padding-top: var(--wp--style--root--padding-top); padding-bottom: var(--wp--style--root--padding-bottom); }.has-global-padding { padding-right: var(--wp--style--root--padding-right); padding-left: var(--wp--style--root--padding-left); }.has-global-padding > .alignfull { margin-right: calc(var(--wp--style--root--padding-right) * -1); margin-left: calc(var(--wp--style--root--padding-left) * -1); }.has-global-padding :where(.has-global-padding:not(.wp-block-block, .alignfull, .alignwide)) { padding-right: 0; padding-left: 0; }.has-global-padding :where(.has-global-padding:not(.wp-block-block, .alignfull, .alignwide)) > .alignfull { margin-left: 0; margin-right: 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;}:root :where(body){--wp--style--root--padding-top: 10px;--wp--style--root--padding-right: 12px;--wp--style--root--padding-bottom: 10px;--wp--style--root--padding-left: 12px;}';
$root_rules = $theme_json->get_root_layout_rules( WP_Theme_JSON_Gutenberg::ROOT_BLOCK_SELECTOR, $metadata );
$style_rules = $theme_json->get_styles_for_block( $metadata );
$this->assertSame( $expected, $root_rules . $style_rules );
@@ -3712,7 +3712,7 @@ public function test_get_styles_for_block_without_padding_aware_alignments() {
'selector' => 'body',
);
- $expected = static::$base_styles . ':where(body){padding-top: 10px;padding-right: 12px;padding-bottom: 10px;padding-left: 12px;}';
+ $expected = static::$base_styles . ':root :where(body){padding-top: 10px;padding-right: 12px;padding-bottom: 10px;padding-left: 12px;}';
$root_rules = $theme_json->get_root_layout_rules( WP_Theme_JSON_Gutenberg::ROOT_BLOCK_SELECTOR, $metadata );
$style_rules = $theme_json->get_styles_for_block( $metadata );
$this->assertSame( $expected, $root_rules . $style_rules );
@@ -3757,7 +3757,7 @@ public function test_get_styles_with_appearance_tools() {
'selector' => 'body',
);
- $expected = ':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(.wp-site-blocks) > * { margin-block-start: ; margin-block-end: 0; }:where(.wp-site-blocks) > :first-child { margin-block-start: 0; }:where(.wp-site-blocks) > :last-child { margin-block-end: 0; }:root { --wp--style--block-gap: ; }:where(.is-layout-flow) > :first-child{margin-block-start: 0;}:where(.is-layout-flow) > :last-child{margin-block-end: 0;}:where(.is-layout-flow) > *{margin-block-start: 1;margin-block-end: 0;}:where(.is-layout-constrained) > :first-child{margin-block-start: 0;}:where(.is-layout-constrained) > :last-child{margin-block-end: 0;}:where(.is-layout-constrained) > *{margin-block-start: 1;margin-block-end: 0;}:where(.is-layout-flex) {gap: 1;}:where(.is-layout-grid) {gap: 1;}.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;}';
+ $expected = ':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(.wp-site-blocks) > * { margin-block-start: ; margin-block-end: 0; }:where(.wp-site-blocks) > :first-child { margin-block-start: 0; }:where(.wp-site-blocks) > :last-child { margin-block-end: 0; }:root { --wp--style--block-gap: ; }.is-layout-flow > :first-child{margin-block-start: 0;}.is-layout-flow > :last-child{margin-block-end: 0;}.is-layout-flow > *{margin-block-start: 1;margin-block-end: 0;}.is-layout-constrained > :first-child{margin-block-start: 0;}.is-layout-constrained > :last-child{margin-block-end: 0;}.is-layout-constrained > *{margin-block-start: 1;margin-block-end: 0;}.is-layout-flex {gap: 1;}.is-layout-grid {gap: 1;}.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;}';
$root_rules = $theme_json->get_root_layout_rules( WP_Theme_JSON_Gutenberg::ROOT_BLOCK_SELECTOR, $metadata );
$this->assertSame( $expected, $root_rules );
}
@@ -4146,9 +4146,9 @@ public function data_get_styles_for_block_with_style_variations() {
$plain = array(
'metadata' => array(
'path' => array( 'styles', 'blocks', 'core/quote', 'variations', 'plain' ),
- 'selector' => '.is-style-plain.is-style-plain.wp-block-quote',
+ 'selector' => '.is-style-plain.wp-block-quote',
),
- 'styles' => '.is-style-plain.is-style-plain.wp-block-quote{background-color: hotpink;}',
+ 'styles' => ':root :where(.is-style-plain.wp-block-quote){background-color: hotpink;}',
);
return array(
@@ -4682,7 +4682,7 @@ public function data_update_separator_declarations() {
'background' => 'blue',
),
),
- 'expected_output' => static::$base_styles . ':where(.wp-block-separator){background-color: blue;color: blue;}',
+ 'expected_output' => static::$base_styles . ':root :where(.wp-block-separator){background-color: blue;color: blue;}',
),
// If background and text are defined, do not include border-color, as text color is enough.
'background and text, no border-color' => array(
@@ -4692,7 +4692,7 @@ public function data_update_separator_declarations() {
'text' => 'red',
),
),
- 'expected_output' => static::$base_styles . ':where(.wp-block-separator){background-color: blue;color: red;}',
+ 'expected_output' => static::$base_styles . ':root :where(.wp-block-separator){background-color: blue;color: red;}',
),
// If only text is defined, do not include border-color, as by itself is enough.
'only text' => array(
@@ -4701,7 +4701,7 @@ public function data_update_separator_declarations() {
'text' => 'red',
),
),
- 'expected_output' => static::$base_styles . ':where(.wp-block-separator){color: red;}',
+ 'expected_output' => static::$base_styles . ':root :where(.wp-block-separator){color: red;}',
),
// If background, text, and border-color are defined, include everything, CSS specificity will decide which to apply.
'background, text, and border-color' => array(
@@ -4714,7 +4714,7 @@ public function data_update_separator_declarations() {
'color' => 'pink',
),
),
- 'expected_output' => static::$base_styles . ':where(.wp-block-separator){background-color: blue;border-color: pink;color: red;}',
+ 'expected_output' => static::$base_styles . ':root :where(.wp-block-separator){background-color: blue;border-color: pink;color: red;}',
),
// If background and border color are defined, include everything, CSS specificity will decide which to apply.
'background, and border-color' => array(
@@ -4726,7 +4726,7 @@ public function data_update_separator_declarations() {
'color' => 'pink',
),
),
- 'expected_output' => static::$base_styles . ':where(.wp-block-separator){background-color: blue;border-color: pink;}',
+ 'expected_output' => static::$base_styles . ':root :where(.wp-block-separator){background-color: blue;border-color: pink;}',
),
);
}
@@ -4790,7 +4790,7 @@ public function test_get_shadow_styles_for_blocks() {
);
$global_styles = ':root{--wp--preset--shadow--natural: 5px 5px 0 0 black;}' . static::$base_styles;
- $element_styles = ':where(a:where(:not(.wp-element-button))){box-shadow: var(--wp--preset--shadow--natural);}:where(.wp-element-button, .wp-block-button__link){box-shadow: var(--wp--preset--shadow--natural);}:where(p){box-shadow: var(--wp--preset--shadow--natural);}';
+ $element_styles = ':root :where(a:where(:not(.wp-element-button))){box-shadow: var(--wp--preset--shadow--natural);}:root :where(.wp-element-button, .wp-block-button__link){box-shadow: var(--wp--preset--shadow--natural);}:root :where(p){box-shadow: var(--wp--preset--shadow--natural);}';
$expected_styles = $global_styles . $element_styles;
$this->assertSame( $expected_styles, $theme_json->get_stylesheet() );
}
@@ -4836,7 +4836,7 @@ public function test_get_top_level_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));}:where(body){background-image: url('http://example.org/image.png');background-position: center center;background-repeat: no-repeat;background-size: contain;}";
+ $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 type does not match expectations' );
$theme_json = new WP_Theme_JSON_Gutenberg(
@@ -4853,7 +4853,7 @@ public function test_get_top_level_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));}:where(body){background-image: url('http://example.org/image.png');background-position: center center;background-repeat: no-repeat;background-size: contain;}";
+ $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' );
}
@@ -4872,7 +4872,7 @@ public function test_get_custom_css_handles_global_custom_css() {
)
);
- $custom_css = 'body {color:purple;}p{color:red;}';
+ $custom_css = 'body {color:purple;}:root :where(p){color:red;}';
$this->assertSame( $custom_css, $theme_json->get_custom_css() );
}
@@ -4979,7 +4979,7 @@ public function data_process_blocks_custom_css() {
'selector' => '.foo',
'css' => 'color: red; margin: auto;',
),
- 'expected' => '.foo{color: red; margin: auto;}',
+ 'expected' => ':root :where(.foo){color: red; margin: auto;}',
),
// CSS with nested selectors.
'with nested selector' => array(
@@ -4987,7 +4987,7 @@ public function data_process_blocks_custom_css() {
'selector' => '.foo',
'css' => 'color: red; margin: auto; &.one{color: blue;} & .two{color: green;}',
),
- 'expected' => '.foo{color: red; margin: auto;}.foo.one{color: blue;}.foo .two{color: green;}',
+ 'expected' => ':root :where(.foo){color: red; margin: auto;}:root :where(.foo.one){color: blue;}:root :where(.foo .two){color: green;}',
),
// CSS with pseudo elements.
'with pseudo elements' => array(
@@ -4995,7 +4995,7 @@ public function data_process_blocks_custom_css() {
'selector' => '.foo',
'css' => 'color: red; margin: auto; &::before{color: blue;} & ::before{color: green;} &.one::before{color: yellow;} & .two::before{color: purple;}',
),
- 'expected' => '.foo{color: red; margin: auto;}.foo::before{color: blue;}.foo ::before{color: green;}.foo.one::before{color: yellow;}.foo .two::before{color: purple;}',
+ 'expected' => ':root :where(.foo){color: red; margin: auto;}:root :where(.foo::before){color: blue;}:root :where(.foo ::before){color: green;}:root :where(.foo.one::before){color: yellow;}:root :where(.foo .two::before){color: purple;}',
),
// CSS with multiple root selectors.
'with multiple root selectors' => array(
@@ -5003,7 +5003,7 @@ public function data_process_blocks_custom_css() {
'selector' => '.foo, .bar',
'css' => 'color: red; margin: auto; &.one{color: blue;} & .two{color: green;} &::before{color: yellow;} & ::before{color: purple;} &.three::before{color: orange;} & .four::before{color: skyblue;}',
),
- 'expected' => '.foo, .bar{color: red; margin: auto;}.foo.one, .bar.one{color: blue;}.foo .two, .bar .two{color: green;}.foo::before, .bar::before{color: yellow;}.foo ::before, .bar ::before{color: purple;}.foo.three::before, .bar.three::before{color: orange;}.foo .four::before, .bar .four::before{color: skyblue;}',
+ 'expected' => ':root :where(.foo, .bar){color: red; margin: auto;}:root :where(.foo.one, .bar.one){color: blue;}:root :where(.foo .two, .bar .two){color: green;}:root :where(.foo::before, .bar::before){color: yellow;}:root :where(.foo ::before, .bar ::before){color: purple;}:root :where(.foo.three::before, .bar.three::before){color: orange;}:root :where(.foo .four::before, .bar .four::before){color: skyblue;}',
),
);
}
diff --git a/storybook/decorators/with-global-css.js b/storybook/decorators/with-global-css.js
index 298d841d1c2a5b..d3d283234be1e5 100644
--- a/storybook/decorators/with-global-css.js
+++ b/storybook/decorators/with-global-css.js
@@ -1,8 +1,3 @@
-/**
- * External dependencies
- */
-import clsx from 'clsx';
-
/**
* WordPress dependencies
*/
@@ -14,6 +9,11 @@ import { useEffect } from '@wordpress/element';
import basicStyles from '../global-basic.lazy.scss';
import wordPressStyles from '../global-wordpress.lazy.scss';
+/**
+ * External dependencies
+ */
+import clsx from 'clsx';
+
/**
* A Storybook decorator to inject global CSS.
*
diff --git a/test/e2e/specs/editor/various/change-detection.spec.js b/test/e2e/specs/editor/various/change-detection.spec.js
index a737e4eb94a5fc..4ac262f4c1348d 100644
--- a/test/e2e/specs/editor/various/change-detection.spec.js
+++ b/test/e2e/specs/editor/various/change-detection.spec.js
@@ -420,7 +420,7 @@ test.describe( 'Change detection', () => {
.click();
await page
.getByRole( 'dialog' )
- .getByRole( 'button', { name: 'Delete' } )
+ .getByRole( 'button', { name: 'Trash' } )
.click();
await expect( page ).toHaveURL( '/wp-admin/edit.php?post_type=post' );
diff --git a/test/e2e/specs/editor/various/footnotes.spec.js b/test/e2e/specs/editor/various/footnotes.spec.js
index 01017b2d2ea2e6..e7fd3804706471 100644
--- a/test/e2e/specs/editor/various/footnotes.spec.js
+++ b/test/e2e/specs/editor/various/footnotes.spec.js
@@ -363,11 +363,15 @@ test.describe( 'Footnotes', () => {
// Open revisions.
await editor.openDocumentSettingsSidebar();
+ const editorSettings = page.getByRole( 'region', {
+ name: 'Editor settings',
+ } );
+ await editorSettings.getByRole( 'tab', { name: 'Post' } ).click();
+ await editorSettings.getByRole( 'button', { name: 'Actions' } ).click();
await page
- .getByRole( 'region', { name: 'Editor settings' } )
- .getByRole( 'tab', { name: 'Post' } )
+ .getByRole( 'menu' )
+ .getByRole( 'menuitem', { name: 'View revisions' } )
.click();
- await page.locator( 'a:text("Revisions (2)")' ).click();
await page.locator( '.revisions-controls .ui-slider-handle' ).focus();
await page.keyboard.press( 'ArrowLeft' );
await page.locator( 'input:text("Restore This Revision")' ).click();
diff --git a/test/e2e/specs/editor/various/styles.spec.js b/test/e2e/specs/editor/various/styles.spec.js
new file mode 100644
index 00000000000000..0aa1f3007d2419
--- /dev/null
+++ b/test/e2e/specs/editor/various/styles.spec.js
@@ -0,0 +1,17 @@
+/**
+ * WordPress dependencies
+ */
+const { test, expect } = require( '@wordpress/e2e-test-utils-playwright' );
+
+test.describe( 'Styles', () => {
+ test( 'should override reset styles', async ( { admin, editor } ) => {
+ await admin.createNewPost( { postType: 'page' } );
+ await editor.insertBlock( { name: 'core/social-links' } );
+
+ const block = editor.canvas.getByRole( 'document', {
+ name: 'Block: Social Icons',
+ } );
+
+ await expect( block ).toHaveCSS( 'padding-left', '0px' );
+ } );
+} );
diff --git a/test/e2e/specs/interactivity/namespace.spec.ts b/test/e2e/specs/interactivity/namespace.spec.ts
index fd38a7ecf6ed64..9d0edc997886cb 100644
--- a/test/e2e/specs/interactivity/namespace.spec.ts
+++ b/test/e2e/specs/interactivity/namespace.spec.ts
@@ -20,30 +20,68 @@ test.describe( 'Namespaces', () => {
test( 'Empty string as namespace should not work', async ( { page } ) => {
const el = page.getByTestId( 'empty namespace' );
- await expect( el ).not.toHaveAttribute( 'href', '/some-url' );
+ await expect( el ).not.toHaveAttribute( 'href', '/empty-string-url' );
} );
test( 'A string as namespace should work', async ( { page } ) => {
const el = page.getByTestId( 'correct namespace' );
- await expect( el ).toHaveAttribute( 'href', '/some-url' );
+ await expect( el ).toHaveAttribute( 'href', '/namespace-url' );
} );
- test( 'An empty object as namespace should work', async ( { page } ) => {
+ test( 'An empty object as namespace should not work', async ( {
+ page,
+ } ) => {
const el = page.getByTestId( 'object namespace' );
- await expect( el ).not.toHaveAttribute( 'href', '/some-url' );
+ await expect( el ).not.toHaveAttribute( 'href', '/object-url' );
} );
test( 'A wrong namespace should not break the runtime', async ( {
page,
} ) => {
const el = page.getByTestId( 'object namespace' );
- await expect( el ).not.toHaveAttribute( 'href', '/some-url' );
+ await expect( el ).not.toHaveAttribute( 'href', '/namespace-url' );
const correct = page.getByTestId( 'correct namespace' );
- await expect( correct ).toHaveAttribute( 'href', '/some-url' );
+ await expect( correct ).toHaveAttribute( 'href', '/namespace-url' );
} );
test( 'A different store namespace should work', async ( { page } ) => {
const el = page.getByTestId( 'other namespace' );
await expect( el ).toHaveAttribute( 'href', '/other-store-url' );
} );
+
+ test( 'A number as a string as namespace should work', async ( {
+ page,
+ } ) => {
+ const el = page.getByTestId( 'number namespace' );
+ await expect( el ).toHaveAttribute( 'href', '/number-url' );
+ } );
+
+ test( 'A null as a string as namespace should work', async ( { page } ) => {
+ const el = page.getByTestId( 'null namespace' );
+ await expect( el ).toHaveAttribute( 'href', '/null-url' );
+ } );
+
+ test( 'A true as a string as namespace should work', async ( { page } ) => {
+ const el = page.getByTestId( 'true namespace' );
+ await expect( el ).toHaveAttribute( 'href', '/true-url' );
+ } );
+
+ test( 'A false as a string as namespace should work', async ( {
+ page,
+ } ) => {
+ const el = page.getByTestId( 'false namespace' );
+ await expect( el ).toHaveAttribute( 'href', '/false-url' );
+ } );
+
+ test( 'A [] as a string as namespace should work', async ( { page } ) => {
+ const el = page.getByTestId( '[] namespace' );
+ await expect( el ).toHaveAttribute( 'href', '/array-url' );
+ } );
+
+ test( 'A "quoted string" as a string as namespace should work', async ( {
+ page,
+ } ) => {
+ const el = page.getByTestId( 'quoted namespace' );
+ await expect( el ).toHaveAttribute( 'href', '/quoted-url' );
+ } );
} );
diff --git a/test/e2e/specs/site-editor/styles.spec.js b/test/e2e/specs/site-editor/styles.spec.js
new file mode 100644
index 00000000000000..66ddf0b7faa1b5
--- /dev/null
+++ b/test/e2e/specs/site-editor/styles.spec.js
@@ -0,0 +1,59 @@
+/**
+ * WordPress dependencies
+ */
+const { test, expect } = require( '@wordpress/e2e-test-utils-playwright' );
+
+test.describe( 'Styles', () => {
+ test.beforeAll( async ( { requestUtils } ) => {
+ await requestUtils.activateTheme( 'twentytwentythree' );
+ } );
+
+ test.afterAll( async ( { requestUtils } ) => {
+ await requestUtils.activateTheme( 'twentytwentyone' );
+ } );
+
+ test( 'should override reset styles and library styles', async ( {
+ admin,
+ editor,
+ requestUtils,
+ page,
+ } ) => {
+ const { id } = await requestUtils.createPage( {
+ title: 'Social Icons',
+ content: `
+
+`,
+ status: 'publish',
+ } );
+ await admin.visitSiteEditor( {
+ postId: id,
+ postType: 'page',
+ canvas: 'edit',
+ } );
+
+ const block = editor.canvas.getByRole( 'document', {
+ name: 'Block: Social Icons',
+ } );
+
+ await expect( block ).toHaveCSS( 'padding-left', '0px' );
+
+ const topBar = page.getByRole( 'region', { name: 'Editor top bar' } );
+ // Navigate to Styles -> Blocks -> Heading -> Typography
+ await topBar.getByRole( 'button', { name: 'Styles' } ).click();
+ await page.getByRole( 'button', { name: 'Blocks styles' } ).click();
+ await page
+ .getByRole( 'button', { name: 'Social Icons block styles' } )
+ .click();
+
+ // find the second padding control
+ const paddingControl = page
+ .locator( '[aria-label="padding"]' )
+ .nth( 1 );
+
+ // Change the padding value
+ await paddingControl.fill( '2' );
+
+ // Check the padding value
+ await expect( block ).toHaveCSS( 'padding-left', '35.4644px' );
+ } );
+} );