diff --git a/lib/compat/wordpress-6.1/class-wp-theme-json-6-1.php b/lib/compat/wordpress-6.1/class-wp-theme-json-6-1.php index 82232aaf4121f..b98885a944c72 100644 --- a/lib/compat/wordpress-6.1/class-wp-theme-json-6-1.php +++ b/lib/compat/wordpress-6.1/class-wp-theme-json-6-1.php @@ -430,6 +430,113 @@ protected static function get_blocks_metadata() { return static::$blocks_metadata; } + /** + * Returns a WP_Style_Engine_CSS_Rules_Store_Gutenberg object for the given nodes. + * + * @since 6.1.0 + * + * @param array $setting_nodes Nodes with settings. + * @param array $origins List of origins to process presets from. + * + * @return WP_Style_Engine_CSS_Rules_Store_Gutenberg + */ + protected function get_preset_classes_store( $setting_nodes, $origins ) { + $store = WP_Style_Engine_CSS_Rules_Store_Gutenberg::get_store( 'global-styles/preset-classes' ); + + foreach ( $setting_nodes as $metadata ) { + if ( null === $metadata['selector'] ) { + continue; + } + + $selector = $metadata['selector']; + $node = _wp_array_get( $this->theme_json, $metadata['path'], array() ); + $store->add_store( static::compute_preset_classes_store( $node, $selector, $origins ) ); + } + return $store; + } + + /** + * Creates new rulesets as classes for each preset value such as: + * + * .has-value-color { + * color: value; + * } + * + * .has-value-background-color { + * background-color: value; + * } + * + * .has-value-font-size { + * font-size: value; + * } + * + * .has-value-gradient-background { + * background: value; + * } + * + * p.has-value-gradient-background { + * background: value; + * } + * + * @since 5.9.0 + * + * @param array $setting_nodes Nodes with settings. + * @param array $origins List of origins to process presets from. + * @return string The new stylesheet. + */ + protected function get_preset_classes( $setting_nodes, $origins ) { + return ( new WP_Style_Engine_Processor_Gutenberg( $this->get_preset_classes_store( $setting_nodes, $origins ) ) )->get_css(); + } + + /** + * Returns a WP_Style_Engine_CSS_Rules_Store_Gutenberg object for the given nodes. + * + * @since 6.1.0 + * + * @param array $nodes Nodes with settings. + * @param array $origins List of origins to process. + * + * @return WP_Style_Engine_CSS_Rules_Store_Gutenberg + */ + protected function get_css_variables_store( $nodes, $origins ) { + $store = WP_Style_Engine_CSS_Rules_Store_Gutenberg::get_store( 'global-styles/css-variables' ); + foreach ( $nodes as $metadata ) { + if ( null === $metadata['selector'] ) { + continue; + } + + $node = _wp_array_get( $this->theme_json, $metadata['path'], array() ); + $declarations = array_merge( static::compute_preset_vars( $node, $origins ), static::compute_theme_vars( $node ) ); + $store->add_rule( $metadata['selector'] )->add_declarations( $this->get_plain_declarations_from_pairs( $declarations ) ); + } + return $store; + } + + /** + * Converts each styles section into a list of rulesets + * to be appended to the stylesheet. + * These rulesets contain all the css variables (custom variables and preset variables). + * + * See glossary at https://developer.mozilla.org/en-US/docs/Web/CSS/Syntax + * + * For each section this creates a new ruleset such as: + * + * block-selector { + * --wp--preset--category--slug: value; + * --wp--custom--variable: value; + * } + * + * @since 5.8.0 + * @since 5.9.0 Added the `$origins` parameter. + * + * @param array $nodes Nodes with settings. + * @param array $origins List of origins to process. + * @return string The new stylesheet. + */ + protected function get_css_variables( $nodes, $origins ) { + return ( new WP_Style_Engine_Processor_Gutenberg( $this->get_css_variables_store( $nodes, $origins ) ) )->get_css(); + } + /** * Builds metadata for the style nodes, which returns in the form of: * @@ -581,17 +688,19 @@ private static function get_block_nodes( $theme_json, $selectors = array() ) { } /** - * Returns the stylesheet that results of processing - * the theme.json structure this object represents. + * Returns a WP_Style_Engine_CSS_Rules_Store_Gutenberg object for the given types and origins. + * + * @since 6.1.0 * * @param array $types Types of styles to load. Will load all by default. It accepts: * 'variables': only the CSS Custom Properties for presets & custom ones. * 'styles': only the styles section in theme.json. * 'presets': only the classes for the presets. * @param array $origins A list of origins to include. By default it includes VALID_ORIGINS. - * @return string Stylesheet. + * @return WP_Style_Engine_CSS_Rules_Store_Gutenberg */ - public function get_stylesheet( $types = array( 'variables', 'styles', 'presets' ), $origins = null ) { + public function get_stylesheet_store( $types = array( 'variables', 'styles', 'presets' ), $origins = null ) { + $store = WP_Style_Engine_CSS_Rules_Store_Gutenberg::get_store( 'global-styles' ); if ( null === $origins ) { $origins = static::VALID_ORIGINS; } @@ -612,14 +721,11 @@ public function get_stylesheet( $types = array( 'variables', 'styles', 'presets' $style_nodes = static::get_style_nodes( $this->theme_json, $blocks_metadata ); $setting_nodes = static::get_setting_nodes( $this->theme_json, $blocks_metadata ); - $stylesheet = ''; - if ( in_array( 'variables', $types, true ) ) { - $stylesheet .= $this->get_css_variables( $setting_nodes, $origins ); + $store->add_store( $this->get_css_variables_store( $setting_nodes, $origins ) ); } - if ( in_array( 'styles', $types, true ) ) { - $stylesheet .= $this->get_block_classes( $style_nodes ); + $store->add_store( $this->get_block_classes_store( $style_nodes ) ); } elseif ( in_array( 'base-layout-styles', $types, true ) ) { // Base layout styles are provided as part of `styles`, so only output separately if explicitly requested. // For backwards compatibility, the Columns block is explicitly included, to support a different default gap value. @@ -636,25 +742,41 @@ public function get_stylesheet( $types = array( 'variables', 'styles', 'presets' ); foreach ( $base_styles_nodes as $base_style_node ) { - $stylesheet .= $this->get_layout_styles( $base_style_node ); + $store->add_store( $this->get_layout_styles_store( $base_style_node ) ); } } if ( in_array( 'presets', $types, true ) ) { - $stylesheet .= $this->get_preset_classes( $setting_nodes, $origins ); + $store->add_store( $this->get_preset_classes_store( $setting_nodes, $origins ) ); } - return $stylesheet; + return $store; } /** - * Gets the CSS rules for a particular block from theme.json. + * Returns the stylesheet that results of processing + * the theme.json structure this object represents. + * + * @param array $types Types of styles to load. Will load all by default. It accepts: + * 'variables': only the CSS Custom Properties for presets & custom ones. + * 'styles': only the styles section in theme.json. + * 'presets': only the classes for the presets. + * @param array $origins A list of origins to include. By default it includes VALID_ORIGINS. + * @return string Stylesheet. + */ + public function get_stylesheet( $types = array( 'variables', 'styles', 'presets' ), $origins = null ) { + return ( new WP_Style_Engine_Processor_Gutenberg( $this->get_stylesheet_store( $types, $origins ) ) )->get_css(); + } + + /** + * Returns a WP_Style_Engine_CSS_Rules_Store_Gutenberg object for the given block metadata. * * @param array $block_metadata Metadata about the block to get styles for. * - * @return string Styles for the block. + * @return WP_Style_Engine_CSS_Rules_Store_Gutenberg */ - public function get_styles_for_block( $block_metadata ) { + public function get_block_styles_store( $block_metadata ) { + $store = WP_Style_Engine_CSS_Rules_Store_Gutenberg::get_store( 'global-styles/blocks' ); $node = _wp_array_get( $this->theme_json, $block_metadata['path'], array() ); $use_root_padding = isset( $this->theme_json['settings']['useRootPaddingAwareAlignments'] ) && true === $this->theme_json['settings']['useRootPaddingAwareAlignments']; $selector = $block_metadata['selector']; @@ -723,8 +845,6 @@ function( $pseudo_selector ) use ( $selector ) { $declarations = static::compute_style_properties( $node, $settings, null, $this->theme_json, $selector, $use_root_padding ); } - $block_rules = ''; - // 1. Separate the ones who use the general selector // and the ones who use the duotone selector. $declarations_duotone = array(); @@ -744,16 +864,16 @@ function( $pseudo_selector ) use ( $selector ) { * @link https://github.com/WordPress/gutenberg/issues/36147. */ if ( static::ROOT_BLOCK_SELECTOR === $selector ) { - $block_rules .= 'body { margin: 0; }'; + $store->add_rule( 'body' )->add_declarations( array( 'margin' => '0' ) ); } // 2. Generate and append the rules that use the general selector. - $block_rules .= static::to_ruleset( $selector, $declarations ); + $store->add_rule( $selector )->add_declarations( $this->get_plain_declarations_from_pairs( $declarations ) ); // 3. Generate and append the rules that use the duotone selector. if ( isset( $block_metadata['duotone'] ) && ! empty( $declarations_duotone ) ) { $selector_duotone = static::scope_selector( $block_metadata['selector'], $block_metadata['duotone'] ); - $block_rules .= static::to_ruleset( $selector_duotone, $declarations_duotone ); + $store->add_rule( $selector_duotone )->add_declarations( $this->get_plain_declarations_from_pairs( $declarations_duotone ) ); } // 4. Generate Layout block gap styles. @@ -761,39 +881,110 @@ function( $pseudo_selector ) use ( $selector ) { static::ROOT_BLOCK_SELECTOR !== $selector && ! empty( $block_metadata['name'] ) ) { - $block_rules .= $this->get_layout_styles( $block_metadata ); + $store->add_store( $this->get_layout_styles_store( $block_metadata ) ); } // 5. Generate and append the feature level rulesets. foreach ( $feature_declarations as $feature_selector => $individual_feature_declarations ) { - $block_rules .= static::to_ruleset( $feature_selector, $individual_feature_declarations ); + $store->add_rule( $feature_selector )->add_declarations( $this->get_plain_declarations_from_pairs( $individual_feature_declarations ) ); } if ( static::ROOT_BLOCK_SELECTOR === $selector ) { $block_gap_value = _wp_array_get( $this->theme_json, array( 'styles', 'spacing', 'blockGap' ), '0.5em' ); if ( $use_root_padding ) { - $block_rules .= '.wp-site-blocks { padding-top: var(--wp--style--root--padding-top); padding-bottom: var(--wp--style--root--padding-bottom); }'; - $block_rules .= '.has-global-padding { padding-right: var(--wp--style--root--padding-right); padding-left: var(--wp--style--root--padding-left); }'; - $block_rules .= '.has-global-padding > .alignfull { margin-right: calc(var(--wp--style--root--padding-right) * -1); margin-left: calc(var(--wp--style--root--padding-left) * -1); }'; - $block_rules .= '.has-global-padding > .alignfull > :where([class*="wp-block-"]:not(.alignfull):not(.alignfull):not([class*="__"]),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); }'; + $store->add_rule( '.wp-site-blocks' )->add_declarations( + array( + 'padding-top' => 'var(--wp--style--root--padding-top)', + 'padding-bottom' => 'var(--wp--style--root--padding-bottom)', + ) + ); + $store->add_rule( '.has-global-padding' )->add_declarations( + array( + 'padding-right' => 'var(--wp--style--root--padding-right)', + 'padding-left' => 'var(--wp--style--root--padding-left)', + ) + ); + $store->add_rule( '.has-global-padding > .alignfull' )->add_declarations( + array( + 'margin-right' => 'calc(var(--wp--style--root--padding-right) * -1)', + 'margin-left' => 'calc(var(--wp--style--root--padding-left) * -1)', + ) + ); + $store->add_rule( '.has-global-padding > .alignfull > :where([class*="wp-block-"]:not(.alignfull):not(.alignfull):not([class*="__"]),p,h1,h2,h3,h4,h5,h6,ul,ol)' )->add_declarations( + array( + 'padding-right' => 'var(--wp--style--root--padding-right)', + 'padding-left' => 'var(--wp--style--root--padding-left)', + ) + ); } - $block_rules .= '.wp-site-blocks > .alignleft { float: left; margin-right: 2em; }'; - $block_rules .= '.wp-site-blocks > .alignright { float: right; margin-left: 2em; }'; - $block_rules .= '.wp-site-blocks > .aligncenter { justify-content: center; margin-left: auto; margin-right: auto; }'; + $store->add_rule( '.wp-site-blocks > .alignleft' )->add_declarations( + array( + 'float' => 'left', + 'margin-right' => '2em', + ) + ); + $store->add_rule( '.wp-site-blocks > .alignright' )->add_declarations( + array( + 'float' => 'right', + 'margin-left' => '2em', + ) + ); + $store->add_rule( '.wp-site-blocks > .aligncenter' )->add_declarations( + array( + 'justify-content' => 'center', + 'margin-left' => 'auto', + 'margin-right' => 'auto', + ) + ); $has_block_gap_support = _wp_array_get( $this->theme_json, array( 'settings', 'spacing', 'blockGap' ) ) !== null; if ( $has_block_gap_support ) { - $block_rules .= '.wp-site-blocks > * { margin-block-start: 0; margin-block-end: 0; }'; - $block_rules .= ".wp-site-blocks > * + * { margin-block-start: $block_gap_value; }"; + $store->add_rule( '.wp-site-blocks > *' )->add_declarations( + array( + 'margin-block-start' => '0', + 'margin-block-end' => '0', + ) + ); + $store->add_rule( '.wp-site-blocks > * + *' )->add_declarations( array( 'margin-block-start' => $block_gap_value ) ); // For backwards compatibility, ensure the legacy block gap CSS variable is still available. - $block_rules .= "$selector { --wp--style--block-gap: $block_gap_value; }"; + $store->add_rule( $selector )->add_declarations( array( '--wp--style--block-gap' => $block_gap_value ) ); } - $block_rules .= $this->get_layout_styles( $block_metadata ); + $store->add_store( $this->get_layout_styles_store( $block_metadata ) ); } - return $block_rules; + return $store; + } + + /** + * Gets the CSS rules for a particular block from theme.json. + * + * @param array $block_metadata Metadata about the block to get styles for. + * + * @return string Styles for the block. + */ + public function get_styles_for_block( $block_metadata ) { + return ( new WP_Style_Engine_Processor_Gutenberg( $this->get_block_styles_store( $block_metadata ) ) )->get_css(); + } + + /** + * Returns a WP_Style_Engine_CSS_Rules_Store_Gutenberg object for the given nodes. + * + * @param array $style_nodes Nodes with styles. + * + * @return WP_Style_Engine_CSS_Rules_Store_Gutenberg + */ + protected function get_block_classes_store( $style_nodes ) { + $store = WP_Style_Engine_CSS_Rules_Store_Gutenberg::get_store( 'global-styles/block-classes' ); + foreach ( $style_nodes as $metadata ) { + if ( null === $metadata['selector'] ) { + continue; + } + $store->add_store( $this->get_block_styles_store( $metadata ) ); + } + + return $store; } /** @@ -812,16 +1003,7 @@ function( $pseudo_selector ) use ( $selector ) { * @return string The new stylesheet. */ protected function get_block_classes( $style_nodes ) { - $block_rules = ''; - - foreach ( $style_nodes as $metadata ) { - if ( null === $metadata['selector'] ) { - continue; - } - $block_rules .= static::get_styles_for_block( $metadata ); - } - - return $block_rules; + return ( new WP_Style_Engine_Processor_Gutenberg( $this->get_block_classes_store( $style_nodes ) ) )->get_css(); } /** @@ -1241,25 +1423,27 @@ public function set_spacing_sizes() { } /** - * Get the CSS layout rules for a particular block from theme.json layout definitions. + * Returns a WP_Style_Engine_CSS_Rules_Store_Gutenberg object for the given block metadata. + * + * @since 6.1.0 * * @param array $block_metadata Metadata about the block to get styles for. * - * @return string Layout styles for the block. + * @return WP_Style_Engine_CSS_Rules_Store_Gutenberg */ - protected function get_layout_styles( $block_metadata ) { - $block_rules = ''; - $block_type = null; + protected function get_layout_styles_store( $block_metadata ) { + $store = WP_Style_Engine_CSS_Rules_Store_Gutenberg::get_store( 'global-styles/layout' ); + $block_type = null; // Skip outputting layout styles if explicitly disabled. if ( current_theme_supports( 'disable-layout-styles' ) ) { - return $block_rules; + return $store; } if ( isset( $block_metadata['name'] ) ) { $block_type = WP_Block_Type_Registry::get_instance()->get_registered( $block_metadata['name'] ); if ( ! block_has_support( $block_type, array( '__experimentalLayout' ), false ) ) { - return $block_rules; + return $store; } } @@ -1321,10 +1505,7 @@ protected function get_layout_styles( $block_metadata ) { foreach ( $spacing_rule['rules'] as $css_property => $css_value ) { $current_css_value = is_string( $css_value ) ? $css_value : $block_gap_value; if ( static::is_safe_css_declaration( $css_property, $current_css_value ) ) { - $declarations[] = array( - 'name' => $css_property, - 'value' => $current_css_value, - ); + $declarations[ $css_property ] = $current_css_value; } } @@ -1346,7 +1527,7 @@ protected function get_layout_styles( $block_metadata ) { $spacing_rule['selector'] ); } - $block_rules .= static::to_ruleset( $layout_selector, $declarations ); + $store->add_rule( $layout_selector )->add_declarations( $declarations ); } } } @@ -1378,15 +1559,7 @@ protected function get_layout_styles( $block_metadata ) { $selector, $class_name ); - $block_rules .= static::to_ruleset( - $layout_selector, - array( - array( - 'name' => 'display', - 'value' => $layout_definition['displayMode'], - ), - ) - ); + $store->add_rule( $layout_selector )->add_declarations( array( 'display' => $layout_definition['displayMode'] ) ); } foreach ( $base_style_rules as $base_style_rule ) { @@ -1399,10 +1572,7 @@ protected function get_layout_styles( $block_metadata ) { ) { foreach ( $base_style_rule['rules'] as $css_property => $css_value ) { if ( static::is_safe_css_declaration( $css_property, $css_value ) ) { - $declarations[] = array( - 'name' => $css_property, - 'value' => $css_value, - ); + $declarations[ $css_property ] = $css_value; } } @@ -1412,12 +1582,87 @@ protected function get_layout_styles( $block_metadata ) { $class_name, $base_style_rule['selector'] ); - $block_rules .= static::to_ruleset( $layout_selector, $declarations ); + $store->add_rule( $layout_selector )->add_declarations( $declarations ); } } } } } - return $block_rules; + return $store; + } + + /** + * Get the CSS layout rules for a particular block from theme.json layout definitions. + * + * @param array $block_metadata Metadata about the block to get styles for. + * + * @return string Layout styles for the block. + */ + protected function get_layout_styles( $block_metadata ) { + return ( new WP_Style_Engine_Processor_Gutenberg( $this->get_layout_styles_store( $block_metadata ) ) )->get_css(); + } + + /** + * Converts a declarations array with name/value keys to a plain array with property => value pairs. + * + * @param array $declarations Declarations array. + * + * @return array + */ + protected function get_plain_declarations_from_pairs( $declarations ) { + $plain_declarations = array(); + foreach ( $declarations as $declaration ) { + $plain_declarations[ $declaration['name'] ] = $declaration['value']; + } + return $plain_declarations; + } + + /** + * Given a settings array, it returns the generated rulesets + * for the preset classes. + * + * @since 5.8.0 + * @since 5.9.0 Added the `$origins` parameter. + * + * @param array $settings Settings to process. + * @param string $selector Selector wrapping the classes. + * @param array $origins List of origins to process. + * @return string The result of processing the presets. + */ + protected static function compute_preset_classes_store( $settings, $selector, $origins ) { + $store = WP_Style_Engine_CSS_Rules_Store_Gutenberg::get_store( md5( json_encode( array( $settings, $selector, $origins ) ) ) ); + if ( static::ROOT_BLOCK_SELECTOR === $selector ) { + // Classes at the global level do not need any CSS prefixed, + // and we don't want to increase its specificity. + $selector = ''; + } + + foreach ( static::PRESETS_METADATA as $preset_metadata ) { + $slugs = static::get_settings_slugs( $settings, $preset_metadata, $origins ); + foreach ( $preset_metadata['classes'] as $class => $property ) { + foreach ( $slugs as $slug ) { + $css_var = static::replace_slug_in_string( $preset_metadata['css_vars'], $slug ); + $class_name = static::replace_slug_in_string( $class, $slug ); + $store->add_rule( static::append_to_selector( $selector, $class_name ) )->add_declarations( array( $property => 'var(' . $css_var . ') !important' ) ); + } + } + } + return $store; + } + + /** + * Given a settings array, it returns the generated rulesets + * for the preset classes. + * + * @since 5.8.0 + * @since 5.9.0 Added the `$origins` parameter. + * + * @param array $settings Settings to process. + * @param string $selector Selector wrapping the classes. + * @param array $origins List of origins to process. + * @return string The result of processing the presets. + */ + protected static function compute_preset_classes( $settings, $selector, $origins ) { + return ( new WP_Style_Engine_Processor_Gutenberg( static::compute_preset_classes_store( $settings, $selector, $origins ) ) )->get_css(); } } diff --git a/packages/style-engine/class-wp-style-engine-css-declarations.php b/packages/style-engine/class-wp-style-engine-css-declarations.php index fe686edddaac0..2f90570f2140b 100644 --- a/packages/style-engine/class-wp-style-engine-css-declarations.php +++ b/packages/style-engine/class-wp-style-engine-css-declarations.php @@ -58,7 +58,7 @@ public function add_declaration( $property, $value ) { } // Trim the value. If empty, bail early. - $value = trim( $value ); + $value = $this->sanitize_value( $value ); if ( '' === $value ) { return; } @@ -121,13 +121,19 @@ public function get_declarations() { public function get_declarations_string() { $declarations_array = $this->get_declarations(); $declarations_output = ''; + foreach ( $declarations_array as $property => $value ) { - $filtered_declaration = esc_html( safecss_filter_attr( "{$property}: {$value}" ) ); + // Account for CSS variables. + if ( 0 === strpos( $property, '--' ) || ( 'display' === $property && 'none' !== $value ) ) { + $declarations_output .= "{$property}:{$value};"; + continue; + } + $filtered_declaration = safecss_filter_attr( "{$property}:{$value}" ); if ( $filtered_declaration ) { - $declarations_output .= $filtered_declaration . '; '; + $declarations_output .= $filtered_declaration . ';'; } } - return rtrim( $declarations_output ); + return $declarations_output; } /** @@ -140,4 +146,19 @@ public function get_declarations_string() { protected function sanitize_property( $property ) { return sanitize_key( $property ); } + + /** + * Sanitize values. + * + * @param string $value The CSS value. + * + * @return string The sanitized value. + */ + protected function sanitize_value( $value ) { + // Escape HTML. + $value = esc_html( $value ); + // Fix quotes to account for URLs. + $value = str_replace( array( ''', ''', '"', '"', '"', ''' ), array( "'", "'", '"', '"', '"', "'" ), $value ); + return trim( $value ); + } } diff --git a/packages/style-engine/class-wp-style-engine-css-rule.php b/packages/style-engine/class-wp-style-engine-css-rule.php index 5429b282f328d..b21cef2d65bf0 100644 --- a/packages/style-engine/class-wp-style-engine-css-rule.php +++ b/packages/style-engine/class-wp-style-engine-css-rule.php @@ -110,6 +110,11 @@ public function get_selector() { * @return string */ public function get_css() { - return $this->get_selector() . ' {' . $this->declarations->get_declarations_string() . '}'; + $styles = $this->declarations->get_declarations_string(); + if ( empty( $styles ) ) { + return ''; + } + + return $this->get_selector() . '{' . $styles . '}'; } } diff --git a/packages/style-engine/class-wp-style-engine-css-rules-store.php b/packages/style-engine/class-wp-style-engine-css-rules-store.php index d3cc079afe6e9..7298e45f8c0ab 100644 --- a/packages/style-engine/class-wp-style-engine-css-rules-store.php +++ b/packages/style-engine/class-wp-style-engine-css-rules-store.php @@ -140,4 +140,21 @@ public function add_rule( $selector ) { public function remove_rule( $selector ) { unset( $this->rules[ $selector ] ); } + + /** + * Add a store. This method effectively merges the rules of the defined store into the current store, + * and removes them from the original store to avoid duplication. + * + * @param WP_Style_Engine_CSS_Rules_Store $store The store to merge. + * + * @return WP_Style_Engine_CSS_Rules_Store Returns the merged store. + */ + public function add_store( WP_Style_Engine_CSS_Rules_Store $store ) { + $incoming_rules = $store->get_all_rules(); + foreach ( $incoming_rules as $rule ) { + $this->add_rule( $rule->get_selector() )->add_declarations( $rule->get_declarations() ); + $store->remove_rule( $rule->get_selector() ); + } + return $this; + } } diff --git a/packages/style-engine/phpunit/class-wp-style-engine-css-declarations-test.php b/packages/style-engine/phpunit/class-wp-style-engine-css-declarations-test.php index f093a496d538a..54bacf795d7f4 100644 --- a/packages/style-engine/phpunit/class-wp-style-engine-css-declarations-test.php +++ b/packages/style-engine/phpunit/class-wp-style-engine-css-declarations-test.php @@ -84,7 +84,7 @@ public function test_generate_css_declarations_string() { $css_declarations = new WP_Style_Engine_CSS_Declarations( $input_declarations ); $this->assertSame( - 'color: red; border-top-left-radius: 99px; text-decoration: underline;', + 'color:red;border-top-left-radius:99px;text-decoration:underline;', $css_declarations->get_declarations_string() ); } @@ -101,7 +101,7 @@ public function test_remove_unsafe_properties_and_values() { $css_declarations = new WP_Style_Engine_CSS_Declarations( $input_declarations ); $this->assertSame( - 'color: <red/>; margin-right: 10em;', + 'margin-right:10em;', $css_declarations->get_declarations_string() ); } @@ -118,13 +118,13 @@ public function test_remove_declaration() { $css_declarations = new WP_Style_Engine_CSS_Declarations( $input_declarations ); $this->assertSame( - 'color: tomato; margin: 10em 10em 20em 1px; font-family: Happy Font serif;', + 'color:tomato;margin:10em 10em 20em 1px;font-family:Happy Font serif;', $css_declarations->get_declarations_string() ); $css_declarations->remove_declaration( 'color' ); $this->assertSame( - 'margin: 10em 10em 20em 1px; font-family: Happy Font serif;', + 'margin:10em 10em 20em 1px;font-family:Happy Font serif;', $css_declarations->get_declarations_string() ); } @@ -141,13 +141,13 @@ public function test_remove_declarations() { $css_declarations = new WP_Style_Engine_CSS_Declarations( $input_declarations ); $this->assertSame( - 'color: cucumber; margin: 10em 10em 20em 1px; font-family: Happy Font serif;', + 'color:cucumber;margin:10em 10em 20em 1px;font-family:Happy Font serif;', $css_declarations->get_declarations_string() ); $css_declarations->remove_declarations( array( 'color', 'margin' ) ); $this->assertSame( - 'font-family: Happy Font serif;', + 'font-family:Happy Font serif;', $css_declarations->get_declarations_string() ); } diff --git a/packages/style-engine/phpunit/class-wp-style-engine-css-rule-test.php b/packages/style-engine/phpunit/class-wp-style-engine-css-rule-test.php index 80547d998fb87..7d865e7ee6ab2 100644 --- a/packages/style-engine/phpunit/class-wp-style-engine-css-rule-test.php +++ b/packages/style-engine/phpunit/class-wp-style-engine-css-rule-test.php @@ -27,7 +27,7 @@ public function test_instantiate_with_selector_and_rules() { $this->assertSame( $selector, $css_rule->get_selector() ); - $expected = "$selector {{$css_declarations->get_declarations_string()}}"; + $expected = "$selector{{$css_declarations->get_declarations_string()}}"; $this->assertSame( $expected, $css_rule->get_css() ); } @@ -45,7 +45,7 @@ public function test_dedupe_properties_in_rules() { $css_rule = new WP_Style_Engine_CSS_Rule( $selector, $first_declaration ); $css_rule->add_declarations( new WP_Style_Engine_CSS_Declarations( $overwrite_first_declaration ) ); - $expected = '.taggart {font-size: 4px;}'; + $expected = '.taggart{font-size:4px;}'; $this->assertSame( $expected, $css_rule->get_css() ); } @@ -60,7 +60,7 @@ public function test_add_declarations() { $css_rule = new WP_Style_Engine_CSS_Rule( '.hill-street-blues', $some_css_declarations ); $css_rule->add_declarations( $some_more_css_declarations ); - $expected = '.hill-street-blues {margin-top: 10px; font-size: 1rem;}'; + $expected = '.hill-street-blues{margin-top:10px;font-size:1rem;}'; $this->assertSame( $expected, $css_rule->get_css() ); } @@ -89,7 +89,7 @@ public function test_get_css() { ); $css_declarations = new WP_Style_Engine_CSS_Declarations( $input_declarations ); $css_rule = new WP_Style_Engine_CSS_Rule( $selector, $css_declarations ); - $expected = "$selector {{$css_declarations->get_declarations_string()}}"; + $expected = "$selector{{$css_declarations->get_declarations_string()}}"; $this->assertSame( $expected, $css_rule->get_css() ); } diff --git a/packages/style-engine/phpunit/class-wp-style-engine-css-rules-store-test.php b/packages/style-engine/phpunit/class-wp-style-engine-css-rules-store-test.php index 9fe664752e4bf..5336c4cd92263 100644 --- a/packages/style-engine/phpunit/class-wp-style-engine-css-rules-store-test.php +++ b/packages/style-engine/phpunit/class-wp-style-engine-css-rules-store-test.php @@ -85,19 +85,19 @@ public function test_add_rule() { $new_pie_store = WP_Style_Engine_CSS_Rules_Store::get_store( 'meat-pie' ); $selector = '.wp-block-sauce a:hover'; $store_rule = $new_pie_store->add_rule( $selector ); - $expected = "$selector {}"; - $this->assertEquals( $expected, $store_rule->get_css() ); + $this->assertEquals( '', $store_rule->get_css() ); - $pie_declarations = array( - 'color' => 'brown', - 'border-color' => 'yellow', - 'border-radius' => '10rem', + $css_declarations = new WP_Style_Engine_CSS_Declarations( + array( + 'color' => 'brown', + 'border-color' => 'yellow', + 'border-radius' => '10rem', + ) ); - $css_declarations = new WP_Style_Engine_CSS_Declarations( $pie_declarations ); - $store_rule->add_declarations( $css_declarations ); - $store_rule = $new_pie_store->add_rule( $selector ); - $expected = "$selector {{$css_declarations->get_declarations_string()}}"; + $new_pie_store->add_rule( $selector )->add_declarations( $css_declarations ); + $styles = $css_declarations->get_declarations_string(); + $expected = $selector . '{' . $styles . '}'; $this->assertEquals( $expected, $store_rule->get_css() ); } diff --git a/packages/style-engine/phpunit/class-wp-style-engine-processor-test.php b/packages/style-engine/phpunit/class-wp-style-engine-processor-test.php index ebee00f05ce16..8eb5cb1f9849f 100644 --- a/packages/style-engine/phpunit/class-wp-style-engine-processor-test.php +++ b/packages/style-engine/phpunit/class-wp-style-engine-processor-test.php @@ -58,7 +58,7 @@ public function test_return_store_rules_as_css() { ); $a_nice_renderer = new WP_Style_Engine_Processor_Gutenberg(); $a_nice_renderer->add_store( $a_nice_store ); - $this->assertEquals( '.a-nice-rule {color: var(--nice-color); background-color: purple;}.a-nicer-rule {font-family: Nice sans; font-size: 1em; background-color: purple;}', $a_nice_renderer->get_css() ); + $this->assertEquals( '.a-nice-rule{color:var(--nice-color);background-color:purple;}.a-nicer-rule{font-family:Nice sans;font-size:1em;background-color:purple;}', $a_nice_renderer->get_css() ); } /** @@ -95,7 +95,7 @@ public function test_dedupe_and_merge_css_declarations() { ) ); $an_excellent_processor->add_rules( $yet_another_excellent_rule ); - $this->assertEquals( '.an-excellent-rule {color: var(--excellent-color); border-style: dashed; border-color: brown; border-width: 2px;}', $an_excellent_processor->get_css() ); + $this->assertEquals( '.an-excellent-rule{color:var(--excellent-color);border-style:dashed;border-color:brown;border-width:2px;}', $an_excellent_processor->get_css() ); } /** @@ -121,7 +121,7 @@ public function test_combine_css_rules() { $a_sweet_processor = new WP_Style_Engine_Processor(); $a_sweet_processor->add_rules( array( $a_sweet_rule, $a_sweeter_rule ) ); - $this->assertEquals( '.a-sweet-rule,#an-even-sweeter-rule > marquee {color: var(--sweet-color); background-color: purple;}', $a_sweet_processor->get_css() ); + $this->assertEquals( '.a-sweet-rule,#an-even-sweeter-rule > marquee{color:var(--sweet-color);background-color:purple;}', $a_sweet_processor->get_css() ); } /** * Should combine and store CSS rules. @@ -160,6 +160,6 @@ public function test_combine_previously_added_css_rules() { ); $a_lovely_processor->add_rules( $a_perfectly_lovely_rule ); - $this->assertEquals( '.a-lovely-rule,.a-lovelier-rule,.a-most-lovely-rule,.a-perfectly-lovely-rule {border-color: purple;}', $a_lovely_processor->get_css() ); + $this->assertEquals( '.a-lovely-rule,.a-lovelier-rule,.a-most-lovely-rule,.a-perfectly-lovely-rule{border-color:purple;}', $a_lovely_processor->get_css() ); } } diff --git a/packages/style-engine/phpunit/class-wp-style-engine-test.php b/packages/style-engine/phpunit/class-wp-style-engine-test.php index 14938e075fa26..d3893e092b79c 100644 --- a/packages/style-engine/phpunit/class-wp-style-engine-test.php +++ b/packages/style-engine/phpunit/class-wp-style-engine-test.php @@ -100,7 +100,7 @@ public function data_get_styles_fixtures() { ), 'options' => array( 'convert_vars_to_classnames' => true ), 'expected_output' => array( - 'css' => 'border-style: dotted; border-width: 2rem; padding: 0; margin: 111px;', + 'css' => 'border-style:dotted;border-width:2rem;padding:0;margin:111px;', 'declarations' => array( 'border-style' => 'dotted', 'border-width' => '2rem', @@ -176,7 +176,7 @@ public function data_get_styles_fixtures() { ), 'options' => null, 'expected_output' => array( - 'css' => 'border-top-left-radius: 99px; border-top-right-radius: 98px; border-bottom-left-radius: 97px; border-bottom-right-radius: 96px; padding-top: 42px; padding-left: 2%; padding-bottom: 44px; padding-right: 5rem; margin-top: 12rem; margin-left: 2vh; margin-bottom: 2px; margin-right: 10em;', + 'css' => 'border-top-left-radius:99px;border-top-right-radius:98px;border-bottom-left-radius:97px;border-bottom-right-radius:96px;padding-top:42px;padding-left:2%;padding-bottom:44px;padding-right:5rem;margin-top:12rem;margin-left:2vh;margin-bottom:2px;margin-right:10em;', 'declarations' => array( 'border-top-left-radius' => '99px', 'border-top-right-radius' => '98px', @@ -209,7 +209,7 @@ public function data_get_styles_fixtures() { ), 'options' => null, 'expected_output' => array( - 'css' => 'font-family: Roboto,Oxygen-Sans,Ubuntu,sans-serif; font-style: italic; font-weight: 800; line-height: 1.3; text-decoration: underline; text-transform: uppercase; letter-spacing: 2;', + 'css' => 'font-family:Roboto,Oxygen-Sans,Ubuntu,sans-serif;font-style:italic;font-weight:800;line-height:1.3;text-decoration:underline;text-transform:uppercase;letter-spacing:2;', 'declarations' => array( 'font-size' => 'clamp(2em, 2vw, 4em)', 'font-family' => 'Roboto,Oxygen-Sans,Ubuntu,sans-serif', @@ -302,7 +302,7 @@ public function data_get_styles_fixtures() { ), 'options' => array(), 'expected_output' => array( - 'css' => 'color: var(--wp--preset--color--teal-independents);', + 'css' => 'color:var(--wp--preset--color--teal-independents);', 'declarations' => array( 'color' => 'var(--wp--preset--color--teal-independents)', ), @@ -319,7 +319,7 @@ public function data_get_styles_fixtures() { ), 'options' => array(), 'expected_output' => array( - 'css' => 'color: #fff;', + 'css' => 'color:#fff;', 'declarations' => array( 'color' => '#fff', ), @@ -353,7 +353,7 @@ public function data_get_styles_fixtures() { ), 'options' => array(), 'expected_output' => array( - 'css' => 'padding: var(--wp--preset--spacing--20); margin: var(--wp--preset--spacing--10);', + 'css' => 'padding:var(--wp--preset--spacing--20);margin:var(--wp--preset--spacing--10);', 'declarations' => array( 'padding' => 'var(--wp--preset--spacing--20)', 'margin' => 'var(--wp--preset--spacing--10)', @@ -380,7 +380,7 @@ public function data_get_styles_fixtures() { ), 'options' => array(), 'expected_output' => array( - 'css' => 'padding-left: var(--wp--preset--spacing--30); padding-right: var(--wp--preset--spacing--40); padding-top: 14px; padding-bottom: 14px; margin-left: var(--wp--preset--spacing--10); margin-right: var(--wp--preset--spacing--20); margin-top: 1rem; margin-bottom: 1rem;', + 'css' => 'padding-left:var(--wp--preset--spacing--30);padding-right:var(--wp--preset--spacing--40);padding-top:14px;padding-bottom:14px;margin-left:var(--wp--preset--spacing--10);margin-right:var(--wp--preset--spacing--20);margin-top:1rem;margin-bottom:1rem;', 'declarations' => array( 'padding-left' => 'var(--wp--preset--spacing--30)', 'padding-right' => 'var(--wp--preset--spacing--40)', @@ -407,7 +407,7 @@ public function data_get_styles_fixtures() { ), 'options' => array(), 'expected_output' => array( - 'css' => 'margin-top: 1rem; margin-bottom: 0;', + 'css' => 'margin-top:1rem;margin-bottom:0;', 'declarations' => array( 'margin-top' => '1rem', 'margin-bottom' => '0', @@ -456,7 +456,7 @@ public function data_get_styles_fixtures() { ), 'options' => array(), 'expected_output' => array( - 'css' => 'border-top-color: #fe1; border-top-width: 1.5rem; border-top-style: dashed; border-right-color: #fe2; border-right-width: 1.4rem; border-right-style: solid; border-bottom-color: #fe3; border-bottom-width: 1.3rem; border-left-color: var(--wp--preset--color--swampy-yellow); border-left-width: 0.5rem; border-left-style: dotted;', + 'css' => 'border-top-color:#fe1;border-top-width:1.5rem;border-top-style:dashed;border-right-color:#fe2;border-right-width:1.4rem;border-right-style:solid;border-bottom-color:#fe3;border-bottom-width:1.3rem;border-left-color:var(--wp--preset--color--swampy-yellow);border-left-width:0.5rem;border-left-style:dotted;', 'declarations' => array( 'border-top-color' => '#fe1', 'border-top-width' => '1.5rem', @@ -499,7 +499,7 @@ public function data_get_styles_fixtures() { ), 'options' => array(), 'expected_output' => array( - 'css' => 'border-bottom-color: var(--wp--preset--color--terrible-lizard);', + 'css' => 'border-bottom-color:var(--wp--preset--color--terrible-lizard);', 'declarations' => array( 'border-bottom-color' => 'var(--wp--preset--color--terrible-lizard)', ), diff --git a/phpunit/block-supports/border-test.php b/phpunit/block-supports/border-test.php index a199dd34ad833..dd2b279867aeb 100644 --- a/phpunit/block-supports/border-test.php +++ b/phpunit/block-supports/border-test.php @@ -117,7 +117,7 @@ function test_border_color_slug_with_numbers_is_kebab_cased_properly() { $actual = gutenberg_apply_border_support( $block_type, $block_atts ); $expected = array( 'class' => 'has-border-color has-red-border-color', - 'style' => 'border-radius: 10px; border-style: dashed; border-width: 1px;', + 'style' => 'border-radius:10px;border-style:dashed;border-width:1px;', ); $this->assertSame( $expected, $actual ); @@ -179,7 +179,7 @@ function test_flat_border_with_individual_skipped_serialization() { $actual = gutenberg_apply_border_support( $block_type, $block_atts ); $expected = array( - 'style' => 'border-style: dotted; border-width: 1px;', + 'style' => 'border-style:dotted;border-width:1px;', ); $this->assertSame( $expected, $actual ); @@ -208,7 +208,7 @@ function test_split_border_radius() { ); $actual = gutenberg_apply_border_support( $block_type, $block_attrs ); $expected = array( - 'style' => 'border-top-left-radius: 1em; border-top-right-radius: 2rem; border-bottom-left-radius: 30px; border-bottom-right-radius: 4vh;', + 'style' => 'border-top-left-radius:1em;border-top-right-radius:2rem;border-bottom-left-radius:30px;border-bottom-right-radius:4vh;', ); $this->assertSame( $expected, $actual ); @@ -237,7 +237,7 @@ function test_flat_border_with_custom_color() { $actual = gutenberg_apply_border_support( $block_type, $block_attrs ); $expected = array( 'class' => 'has-border-color', - 'style' => 'border-color: #72aee6; border-style: dashed; border-width: 2px;', + 'style' => 'border-color:#72aee6;border-style:dashed;border-width:2px;', ); $this->assertSame( $expected, $actual ); @@ -282,7 +282,7 @@ function test_split_borders_with_custom_colors() { ); $actual = gutenberg_apply_border_support( $block_type, $block_attrs ); $expected = array( - 'style' => 'border-top-width: 2px; border-top-color: #72aee6; border-top-style: dashed; border-right-width: 0.25rem; border-right-color: #e65054; border-right-style: dotted; border-bottom-width: 0.5em; border-bottom-color: #007017; border-bottom-style: solid; border-left-width: 1px; border-left-color: #f6f7f7; border-left-style: solid;', + 'style' => 'border-top-width:2px;border-top-color:#72aee6;border-top-style:dashed;border-right-width:0.25rem;border-right-color:#e65054;border-right-style:dotted;border-bottom-width:0.5em;border-bottom-color:#007017;border-bottom-style:solid;border-left-width:1px;border-left-color:#f6f7f7;border-left-style:solid;', ); $this->assertSame( $expected, $actual ); @@ -372,7 +372,7 @@ function test_split_borders_with_skipped_individual_feature_serialization() { ); $actual = gutenberg_apply_border_support( $block_type, $block_attrs ); $expected = array( - 'style' => 'border-top-color: #72aee6; border-right-color: #e65054; border-bottom-color: #007017; border-left-color: #f6f7f7;', + 'style' => 'border-top-color:#72aee6;border-right-color:#e65054;border-bottom-color:#007017;border-left-color:#f6f7f7;', ); $this->assertSame( $expected, $actual ); @@ -409,7 +409,7 @@ function test_partial_split_borders() { ); $actual = gutenberg_apply_border_support( $block_type, $block_attrs ); $expected = array( - 'style' => 'border-top-width: 2px; border-top-color: #72aee6; border-top-style: dashed; border-right-width: 0.25rem; border-right-color: #e65054; border-left-style: solid;', + 'style' => 'border-top-width:2px;border-top-color:#72aee6;border-top-style:dashed;border-right-width:0.25rem;border-right-color:#e65054;border-left-style:solid;', ); $this->assertSame( $expected, $actual ); @@ -454,7 +454,7 @@ function test_split_borders_with_named_colors() { ); $actual = gutenberg_apply_border_support( $block_type, $block_attrs ); $expected = array( - 'style' => 'border-top-width: 2px; border-top-color: var(--wp--preset--color--red); border-top-style: dashed; border-right-width: 0.25rem; border-right-color: var(--wp--preset--color--green); border-right-style: dotted; border-bottom-width: 0.5em; border-bottom-color: var(--wp--preset--color--blue); border-bottom-style: solid; border-left-width: 1px; border-left-color: var(--wp--preset--color--yellow); border-left-style: solid;', + 'style' => 'border-top-width:2px;border-top-color:var(--wp--preset--color--red);border-top-style:dashed;border-right-width:0.25rem;border-right-color:var(--wp--preset--color--green);border-right-style:dotted;border-bottom-width:0.5em;border-bottom-color:var(--wp--preset--color--blue);border-bottom-style:solid;border-left-width:1px;border-left-color:var(--wp--preset--color--yellow);border-left-style:solid;', ); $this->assertSame( $expected, $actual ); diff --git a/phpunit/block-supports/colors-test.php b/phpunit/block-supports/colors-test.php index fba82fafb4bec..89b3a9192270e 100644 --- a/phpunit/block-supports/colors-test.php +++ b/phpunit/block-supports/colors-test.php @@ -136,7 +136,7 @@ function test_gradient_with_individual_skipped_serialization_block_supports() { $actual = gutenberg_apply_colors_support( $block_type, $block_atts ); $expected = array( 'class' => 'has-text-color', - 'style' => 'color: #d92828;', + 'style' => 'color:#d92828;', ); $this->assertSame( $expected, $actual ); diff --git a/phpunit/block-supports/spacing-test.php b/phpunit/block-supports/spacing-test.php index 51b537bff4d14..4caaf12911f9a 100644 --- a/phpunit/block-supports/spacing-test.php +++ b/phpunit/block-supports/spacing-test.php @@ -62,7 +62,7 @@ function test_spacing_style_is_applied() { $actual = gutenberg_apply_spacing_support( $block_type, $block_atts ); $expected = array( - 'style' => 'padding: 111px; margin-top: 1px; margin-right: 2px; margin-bottom: 3px; margin-left: 4px;', + 'style' => 'padding:111px;margin-top:1px;margin-right:2px;margin-bottom:3px;margin-left:4px;', ); $this->assertSame( $expected, $actual ); @@ -152,7 +152,7 @@ function test_margin_with_individual_skipped_serialization_block_supports() { $actual = gutenberg_apply_spacing_support( $block_type, $block_atts ); $expected = array( - 'style' => 'padding-top: 1px; padding-right: 2px; padding-bottom: 3px; padding-left: 4px;', + 'style' => 'padding-top:1px;padding-right:2px;padding-bottom:3px;padding-left:4px;', ); $this->assertSame( $expected, $actual ); diff --git a/phpunit/block-supports/typography-test.php b/phpunit/block-supports/typography-test.php index f5b5ac954f9e2..297c90a1bc8a9 100644 --- a/phpunit/block-supports/typography-test.php +++ b/phpunit/block-supports/typography-test.php @@ -75,7 +75,7 @@ function test_font_family_with_legacy_inline_styles_using_a_value() { $block_atts = array( 'style' => array( 'typography' => array( 'fontFamily' => 'serif' ) ) ); $actual = gutenberg_apply_typography_support( $block_type, $block_atts ); - $expected = array( 'style' => 'font-family: serif;' ); + $expected = array( 'style' => 'font-family:serif;' ); $this->assertSame( $expected, $actual ); } @@ -175,7 +175,7 @@ function test_font_family_with_legacy_inline_styles_using_a_css_var() { $block_atts = array( 'style' => array( 'typography' => array( 'fontFamily' => 'var:preset|font-family|h1' ) ) ); $actual = gutenberg_apply_typography_support( $block_type, $block_atts ); - $expected = array( 'style' => 'font-family: var(--wp--preset--font-family--h-1);' ); + $expected = array( 'style' => 'font-family:var(--wp--preset--font-family--h-1);' ); $this->assertSame( $expected, $actual ); } diff --git a/phpunit/class-wp-theme-json-test.php b/phpunit/class-wp-theme-json-test.php index 34d9905743c61..103a6ac211ef8 100644 --- a/phpunit/class-wp-theme-json-test.php +++ b/phpunit/class-wp-theme-json-test.php @@ -7,12 +7,27 @@ */ class WP_Theme_JSON_Gutenberg_Test extends WP_UnitTestCase { + /** + * Reset the Style-Engine stores for global-styles. + */ + public function reset_style_engine_stores() { + $stores = WP_Style_Engine_CSS_Rules_Store_Gutenberg::get_stores(); + foreach ( $stores as $store ) { + $rules = $store->get_all_rules(); + foreach ( array_keys( $rules ) as $selector ) { + $store->remove_rule( $selector ); + } + } + } /** * @dataProvider data_get_layout_definitions * * @param array $layout_definitions Layout definitions as stored in core theme.json. */ public function test_get_stylesheet_generates_layout_styles( $layout_definitions ) { + // Reset the Style-Engine stores for global-styles. + $this->reset_style_engine_stores(); + $theme_json = new WP_Theme_JSON_Gutenberg( array( 'version' => WP_Theme_JSON_Gutenberg::LATEST_SCHEMA, @@ -35,7 +50,7 @@ public function test_get_stylesheet_generates_layout_styles( $layout_definitions // Results also include root site blocks styles. $this->assertEquals( - '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; }.wp-site-blocks > * { margin-block-start: 0; margin-block-end: 0; }.wp-site-blocks > * + * { margin-block-start: 1em; }body { --wp--style--block-gap: 1em; }body .is-layout-flow > *{margin-block-start: 0;margin-block-end: 0;}body .is-layout-flow > * + *{margin-block-start: 1em;margin-block-end: 0;}body .is-layout-flex{gap: 1em;}body .is-layout-flow > .alignleft{float: left;margin-inline-start: 0;margin-inline-end: 2em;}body .is-layout-flow > .alignright{float: right;margin-inline-start: 2em;margin-inline-end: 0;}body .is-layout-flow > .aligncenter{margin-left: auto !important;margin-right: auto !important;}body .is-layout-flex{display: flex;}body .is-layout-flex{flex-wrap: wrap;align-items: center;}', + 'body{margin:0;--wp--style--block-gap:1em;}.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;}.wp-site-blocks > * + *{margin-block-start:1em;}body .is-layout-flow > * + *{margin-block-start:1em;margin-block-end:0;}body .is-layout-flex{gap:1em;display:flex;flex-wrap:wrap;align-items:center;}body .is-layout-flow > .alignleft{float:left;margin-inline-start:0;margin-inline-end:2em;}body .is-layout-flow > .alignright{float:right;margin-inline-start:2em;margin-inline-end:0;}body .is-layout-flow > .aligncenter{margin-left:auto !important;margin-right:auto !important;}.wp-site-blocks > *,body .is-layout-flow > *{margin-block-start:0;margin-block-end:0;}', $theme_json->get_stylesheet( array( 'styles' ) ) ); } @@ -46,6 +61,9 @@ public function test_get_stylesheet_generates_layout_styles( $layout_definitions * @param array $layout_definitions Layout definitions as stored in core theme.json. */ public function test_get_stylesheet_generates_fallback_gap_layout_styles( $layout_definitions ) { + // Reset the Style-Engine stores for global-styles. + $this->reset_style_engine_stores(); + $theme_json = new WP_Theme_JSON_Gutenberg( array( 'version' => WP_Theme_JSON_Gutenberg::LATEST_SCHEMA, @@ -80,6 +98,9 @@ public function test_get_stylesheet_generates_fallback_gap_layout_styles( $layou * @param array $layout_definitions Layout definitions as stored in core theme.json. */ public function test_get_stylesheet_generates_base_fallback_gap_layout_styles( $layout_definitions ) { + // Reset the Style-Engine stores for global-styles. + $this->reset_style_engine_stores(); + $theme_json = new WP_Theme_JSON_Gutenberg( array( 'version' => WP_Theme_JSON_Gutenberg::LATEST_SCHEMA, @@ -217,6 +238,9 @@ public function data_get_layout_definitions() { ); } function test_get_stylesheet_handles_whitelisted_element_pseudo_selectors() { + // Reset the Style-Engine stores for global-styles. + $this->reset_style_engine_stores(); + $theme_json = new WP_Theme_JSON_Gutenberg( array( 'version' => WP_Theme_JSON_Gutenberg::LATEST_SCHEMA, @@ -249,7 +273,7 @@ function test_get_stylesheet_handles_whitelisted_element_pseudo_selectors() { ) ); - $base_styles = '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; }'; + $base_styles = '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;}'; $element_styles = 'a:where(:not(.wp-element-button)){background-color: red;color: green;}a:where(:not(.wp-element-button)):hover{background-color: green;color: red;font-size: 10em;text-transform: uppercase;}a:where(:not(.wp-element-button)):focus{background-color: black;color: yellow;}'; @@ -260,6 +284,9 @@ function test_get_stylesheet_handles_whitelisted_element_pseudo_selectors() { } function test_get_stylesheet_handles_only_pseudo_selector_rules_for_given_property() { + // Reset the Style-Engine stores for global-styles. + $this->reset_style_engine_stores(); + $theme_json = new WP_Theme_JSON_Gutenberg( array( 'version' => WP_Theme_JSON_Gutenberg::LATEST_SCHEMA, @@ -288,7 +315,7 @@ function test_get_stylesheet_handles_only_pseudo_selector_rules_for_given_proper ) ); - $base_styles = '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; }'; + $base_styles = '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;}'; $element_styles = 'a:where(:not(.wp-element-button)):hover{background-color: green;color: red;font-size: 10em;text-transform: uppercase;}a:where(:not(.wp-element-button)):focus{background-color: black;color: yellow;}'; @@ -299,6 +326,9 @@ function test_get_stylesheet_handles_only_pseudo_selector_rules_for_given_proper } function test_get_stylesheet_ignores_pseudo_selectors_on_non_whitelisted_elements() { + // Reset the Style-Engine stores for global-styles. + $this->reset_style_engine_stores(); + $theme_json = new WP_Theme_JSON_Gutenberg( array( 'version' => WP_Theme_JSON_Gutenberg::LATEST_SCHEMA, @@ -327,9 +357,9 @@ function test_get_stylesheet_ignores_pseudo_selectors_on_non_whitelisted_element ) ); - $base_styles = '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; }'; + $base_styles = '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;}'; - $element_styles = 'h4{background-color: red;color: green;}'; + $element_styles = 'h4{background-color:red;color:green;}'; $expected = $base_styles . $element_styles; @@ -338,6 +368,9 @@ function test_get_stylesheet_ignores_pseudo_selectors_on_non_whitelisted_element } function test_get_stylesheet_ignores_non_whitelisted_pseudo_selectors() { + // Reset the Style-Engine stores for global-styles. + $this->reset_style_engine_stores(); + $theme_json = new WP_Theme_JSON_Gutenberg( array( 'version' => WP_Theme_JSON_Gutenberg::LATEST_SCHEMA, @@ -366,7 +399,7 @@ function test_get_stylesheet_ignores_non_whitelisted_pseudo_selectors() { ) ); - $base_styles = '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; }'; + $base_styles = '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;}'; $element_styles = 'a:where(:not(.wp-element-button)){background-color: red;color: green;}a:where(:not(.wp-element-button)):hover{background-color: green;color: red;}'; @@ -378,6 +411,9 @@ function test_get_stylesheet_ignores_non_whitelisted_pseudo_selectors() { } function test_get_stylesheet_handles_priority_of_elements_vs_block_elements_pseudo_selectors() { + // Reset the Style-Engine stores for global-styles. + $this->reset_style_engine_stores(); + $theme_json = new WP_Theme_JSON_Gutenberg( array( 'version' => WP_Theme_JSON_Gutenberg::LATEST_SCHEMA, @@ -414,7 +450,7 @@ function test_get_stylesheet_handles_priority_of_elements_vs_block_elements_pseu ) ); - $base_styles = '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; }'; + $base_styles = '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;}'; $element_styles = '.wp-block-group a:where(:not(.wp-element-button)){background-color: red;color: green;}.wp-block-group a:where(:not(.wp-element-button)):hover{background-color: green;color: red;font-size: 10em;text-transform: uppercase;}.wp-block-group a:where(:not(.wp-element-button)):focus{background-color: black;color: yellow;}'; @@ -425,6 +461,9 @@ function test_get_stylesheet_handles_priority_of_elements_vs_block_elements_pseu } function test_get_stylesheet_handles_whitelisted_block_level_element_pseudo_selectors() { + // Reset the Style-Engine stores for global-styles. + $this->reset_style_engine_stores(); + $theme_json = new WP_Theme_JSON_Gutenberg( array( 'version' => WP_Theme_JSON_Gutenberg::LATEST_SCHEMA, @@ -461,7 +500,7 @@ function test_get_stylesheet_handles_whitelisted_block_level_element_pseudo_sele ) ); - $base_styles = '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; }'; + $base_styles = '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;}'; $element_styles = 'a:where(:not(.wp-element-button)){background-color: red;color: green;}a:where(:not(.wp-element-button)):hover{background-color: green;color: red;}.wp-block-group a:where(:not(.wp-element-button)):hover{background-color: black;color: yellow;}'; @@ -480,6 +519,9 @@ function test_get_stylesheet_handles_whitelisted_block_level_element_pseudo_sele * remove that filter and instead use the core block for the following test. */ function test_get_stylesheet_with_block_support_feature_level_selectors() { + // Reset the Style-Engine stores for global-styles. + $this->reset_style_engine_stores(); + $theme_json = new WP_Theme_JSON_Gutenberg( array( 'version' => WP_Theme_JSON_Gutenberg::LATEST_SCHEMA, @@ -524,9 +566,9 @@ function test_get_stylesheet_with_block_support_feature_level_selectors() { ) ); - $base_styles = 'body{--wp--preset--color--green: green;}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; }'; - $block_styles = '.wp-block-test, .wp-block-test__wrapper{color: green;}.wp-block-test .inner, .wp-block-test__wrapper .inner{border-radius: 9999px;padding: 20px;}.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;}'; + $base_styles = 'body{--wp--preset--color--green:green;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;}'; + $block_styles = '.wp-block-test, .wp-block-test__wrapper{color:green;}.wp-block-test .inner, .wp-block-test__wrapper .inner{border-radius:9999px;padding:20px;}.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; $this->assertEquals( $expected, $theme_json->get_stylesheet() ); @@ -598,6 +640,9 @@ function test_get_element_class_name_invalid() { * array( 'ref' => 'styles.color.background' ) => "#ffffff". */ function test_get_property_value_valid() { + // Reset the Style-Engine stores for global-styles. + $this->reset_style_engine_stores(); + $theme_json = new WP_Theme_JSON_Gutenberg( array( 'version' => 2, @@ -618,7 +663,7 @@ function test_get_property_value_valid() { ) ); - $expected = 'body { margin: 0; }body{background-color: #ffffff;color: #000000;}.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; }.wp-element-button, .wp-block-button__link{background-color: #000000;color: #ffffff;}'; + $expected = 'body{margin:0;background-color:#ffffff;color:#000000;}.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;}.wp-element-button, .wp-block-button__link{background-color:#000000;color:#ffffff;}'; $this->assertEquals( $expected, $theme_json->get_stylesheet() ); } @@ -630,6 +675,9 @@ function test_get_property_value_valid() { * @expectedIncorrectUsage get_property_value */ function test_get_property_value_loop() { + // Reset the Style-Engine stores for global-styles. + $this->reset_style_engine_stores(); + $theme_json = new WP_Theme_JSON_Gutenberg( array( 'version' => 2, @@ -650,7 +698,7 @@ function test_get_property_value_loop() { ) ); - $expected = 'body { margin: 0; }body{background-color: #ffffff;}.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; }.wp-element-button, .wp-block-button__link{color: #ffffff;}'; + $expected = 'body{margin:0;background-color:#ffffff;}.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;}.wp-element-button, .wp-block-button__link{color:#ffffff;}'; $this->assertSame( $expected, $theme_json->get_stylesheet() ); } @@ -661,6 +709,9 @@ function test_get_property_value_loop() { * @expectedIncorrectUsage get_property_value */ function test_get_property_value_recursion() { + // Reset the Style-Engine stores for global-styles. + $this->reset_style_engine_stores(); + $theme_json = new WP_Theme_JSON_Gutenberg( array( 'version' => 2, @@ -681,7 +732,7 @@ function test_get_property_value_recursion() { ) ); - $expected = 'body { margin: 0; }body{background-color: #ffffff;color: #ffffff;}.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; }.wp-element-button, .wp-block-button__link{color: #ffffff;}'; + $expected = 'body{margin:0;background-color:#ffffff;color:#ffffff;}.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;}.wp-element-button, .wp-block-button__link{color:#ffffff;}'; $this->assertEquals( $expected, $theme_json->get_stylesheet() ); } @@ -692,6 +743,9 @@ function test_get_property_value_recursion() { * @expectedIncorrectUsage get_property_value */ function test_get_property_value_self() { + // Reset the Style-Engine stores for global-styles. + $this->reset_style_engine_stores(); + $theme_json = new WP_Theme_JSON_Gutenberg( array( 'version' => 2, @@ -704,7 +758,7 @@ function test_get_property_value_self() { ) ); - $expected = 'body { margin: 0; }body{background-color: #ffffff;}.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; }'; + $expected = 'body{margin:0;background-color:#ffffff;}.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;}'; $this->assertEquals( $expected, $theme_json->get_stylesheet() ); } @@ -1007,6 +1061,9 @@ function data_generate_spacing_scale_fixtures() { } function test_get_styles_for_block_with_padding_aware_alignments() { + // Reset the Style-Engine stores for global-styles. + $this->reset_style_engine_stores(); + $theme_json = new WP_Theme_JSON_Gutenberg( array( 'version' => 2, @@ -1033,11 +1090,14 @@ function test_get_styles_for_block_with_padding_aware_alignments() { 'selector' => 'body', ); - $expected = 'body { margin: 0; }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;}.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 > .alignfull > :where([class*="wp-block-"]:not(.alignfull):not(.alignfull):not([class*="__"]),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); }.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; }'; + $expected = 'body{margin:0;--wp--style--root--padding-top:10px;--wp--style--root--padding-right:12px;--wp--style--root--padding-bottom:10px;--wp--style--root--padding-left:12px;}.wp-site-blocks{padding-top:var(--wp--style--root--padding-top);padding-bottom:var(--wp--style--root--padding-bottom);}.has-global-padding > .alignfull{margin-right:calc(var(--wp--style--root--padding-right) * -1);margin-left:calc(var(--wp--style--root--padding-left) * -1);}.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-global-padding,.has-global-padding > .alignfull > :where([class*="wp-block-"]:not(.alignfull):not(.alignfull):not([class*="__"]),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);}'; $this->assertEquals( $expected, $theme_json->get_styles_for_block( $metadata ) ); } function test_get_styles_for_block_without_padding_aware_alignments() { + // Reset the Style-Engine stores for global-styles. + $this->reset_style_engine_stores(); + $theme_json = new WP_Theme_JSON_Gutenberg( array( 'version' => 2, @@ -1061,7 +1121,7 @@ function test_get_styles_for_block_without_padding_aware_alignments() { 'selector' => 'body', ); - $expected = 'body { margin: 0; }body{padding-top: 10px;padding-right: 12px;padding-bottom: 10px;padding-left: 12px;}.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; }'; + $expected = 'body{margin:0;padding-top:10px;padding-right:12px;padding-bottom:10px;padding-left:12px;}.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;}'; $this->assertEquals( $expected, $theme_json->get_styles_for_block( $metadata ) ); } }