From 2c23f896572f88b1f6ab1f68fe110bb6c15dce3e Mon Sep 17 00:00:00 2001 From: Andrew Serong <14988353+andrewserong@users.noreply.github.com> Date: Mon, 23 May 2022 16:27:39 +1000 Subject: [PATCH] Try moving some of the layout definitions to theme.json --- lib/block-supports/layout.php | 16 +- lib/compat/wordpress-6.0/theme.json | 18 ++ .../wordpress-6.1/class-wp-theme-json-6-1.php | 210 ++++++------------ 3 files changed, 100 insertions(+), 144 deletions(-) diff --git a/lib/block-supports/layout.php b/lib/block-supports/layout.php index 0d13dccdaed75f..826b0f2862cf6b 100644 --- a/lib/block-supports/layout.php +++ b/lib/block-supports/layout.php @@ -67,6 +67,7 @@ function gutenberg_get_layout_style( $selector, $layout, $has_block_gap_support $style .= "$selector > .alignleft { float: left; margin-inline-start: 0; margin-inline-end: 2em; }"; $style .= "$selector > .alignright { float: right; margin-inline-start: 2em; margin-inline-end: 0; }"; $style .= "$selector > .aligncenter { margin-left: auto !important; margin-right: auto !important; }"; + if ( $has_block_gap_support ) { if ( is_array( $gap_value ) ) { $gap_value = isset( $gap_value['top'] ) ? $gap_value['top'] : null; @@ -175,14 +176,19 @@ function gutenberg_render_layout_support_flag( $block_content, $block ) { } // TODO: Should we handle the case where a block has opted out of using a classname? (e.g. how paragraph disables classnames) - $block_classname = wp_get_block_default_classname( $block['blockName'] ); - $container_class = wp_unique_id( 'wp-container-' ); - $class_names = array( $block_classname, $container_class ); + $block_classname = wp_get_block_default_classname( $block['blockName'] ); + $container_class = wp_unique_id( 'wp-container-' ); + $layout_classname = ''; + $class_names = array( $block_classname, $container_class ); if ( isset( $used_layout['type'] ) ) { - $class_names[] = 'is-layout-' . sanitize_title( $used_layout['type'] ); + $layout_classname = _wp_array_get( $default_layout, array( 'definitions', $used_layout['type'], 'className' ), '' ); } else { - $class_names[] = 'is-layout-flow'; + $layout_classname = _wp_array_get( $default_layout, array( 'definitions', 'default', 'className' ), '' ); + } + + if ( $layout_classname && is_string( $layout_classname ) ) { + $class_names[] = sanitize_title( $layout_classname ); } $gap_value = _wp_array_get( $block, array( 'attrs', 'style', 'spacing', 'blockGap' ) ); diff --git a/lib/compat/wordpress-6.0/theme.json b/lib/compat/wordpress-6.0/theme.json index 7691aa4a64e6a9..a60222e839fa22 100644 --- a/lib/compat/wordpress-6.0/theme.json +++ b/lib/compat/wordpress-6.0/theme.json @@ -185,6 +185,24 @@ ], "text": true }, + "layout": { + "definitions": { + "default": { + "name": "flow", + "slug": "flow", + "className": "is-layout-flow", + "blockGapSelector": ".is-layout-flow > * + *", + "blockGapProp": "margin-top" + }, + "flex": { + "name": "flex", + "slug": "flex", + "className": "is-layout-flex", + "blockGapSelector": ".is-layout-flex", + "blockGapProp": "gap" + } + } + }, "spacing": { "blockGap": null, "margin": false, 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 d19f4839a7b2f5..bb35e215fcc65d 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 @@ -27,15 +27,57 @@ class WP_Theme_JSON_6_1 extends WP_Theme_JSON_6_0 { 'h6' => 'h6', 'button' => '.wp-element-button, .wp-block-button, button', // We have the .wp-block-button class so that this will target older buttons that have been serialized. ); + /** - * The selectors and CSS properties for layout styles. + * The valid properties under the settings key. * * @var array */ - const LAYOUT_STYLES = array( - '--wp--style--block-gap' => array ( - '.is-layout-flex' => 'gap', - '.is-layout-flow > * + *' => 'margin-top', + const VALID_SETTINGS = array( + 'appearanceTools' => null, + 'border' => array( + 'color' => null, + 'radius' => null, + 'style' => null, + 'width' => null, + ), + 'color' => array( + 'background' => null, + 'custom' => null, + 'customDuotone' => null, + 'customGradient' => null, + 'defaultDuotone' => null, + 'defaultGradients' => null, + 'defaultPalette' => null, + 'duotone' => null, + 'gradients' => null, + 'link' => null, + 'palette' => null, + 'text' => null, + ), + 'custom' => null, + 'layout' => array( + 'contentSize' => null, + 'definitions' => null, + 'wideSize' => null, + ), + 'spacing' => array( + 'blockGap' => null, + 'margin' => null, + 'padding' => null, + 'units' => null, + ), + 'typography' => array( + 'customFontSize' => null, + 'dropCap' => null, + 'fontFamilies' => null, + 'fontSizes' => null, + 'fontStyle' => null, + 'fontWeight' => null, + 'letterSpacing' => null, + 'lineHeight' => null, + 'textDecoration' => null, + 'textTransform' => null, ), ); @@ -66,7 +108,7 @@ class WP_Theme_JSON_6_1 extends WP_Theme_JSON_6_0 { 'spacing' => array( 'margin' => null, 'padding' => null, - 'blockGap' => null, + 'blockGap' => 'top', ), 'typography' => array( 'fontFamily' => null, @@ -140,22 +182,37 @@ protected function get_block_classes( $style_nodes ) { $block_rules .= static::to_ruleset( $selector_duotone, $declarations_duotone ); } + // 4. Generate the rules for layout blockGap. + $has_block_gap_support = _wp_array_get( $this->theme_json, array( 'settings', 'spacing', 'blockGap' ) ) !== null; + if ( $has_block_gap_support ) { + $block_gap_value = _wp_array_get( $node, array( 'spacing', 'blockGap' ), '0.5em' ); + $layout_definitions = _wp_array_get( $this->theme_json, array( 'settings', 'layout', 'definitions' ), array() ); + + if ( $block_gap_value ) { + foreach( $layout_definitions as $layout_key => $layout_definition ) { + $declaration_layouts = array(); + if( ! empty( $layout_definition['blockGapSelector'] ) && ! empty( $layout_definition['blockGapProp'] ) ) { + $declaration_layouts[] = array( + 'name' => $layout_definition['blockGapProp'], + 'value' => $block_gap_value, + ); + $layout_selector = static::ROOT_BLOCK_SELECTOR === $selector ? + $selector . ' ' . $layout_definition['blockGapSelector'] : + $selector . $layout_definition['blockGapSelector']; + $block_rules .= static::to_ruleset( $layout_selector, $declaration_layouts ); + } + } + } + } + if ( static::ROOT_BLOCK_SELECTOR === $selector ) { $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; }'; - $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: var( --wp--style--block-gap ); }'; - - $block_gap_value = _wp_array_get( $node, array( 'spacing', 'blockGap' ), '0.5em' ); - foreach( static::LAYOUT_STYLES as $key => $layout_style_selectors ) { - foreach( $layout_style_selectors as $layout_selector => $css_property ) { - $block_rules .= "$selector $layout_selector { " . $css_property . ': ' . $block_gap_value . " }"; - } - } } } } @@ -363,129 +420,4 @@ public function get_styles_for_block( $block_metadata ) { $block_rules = static::to_ruleset( $selector, $declarations ); return $block_rules; } - - /** - * Given a selector and a declaration list, - * creates the corresponding ruleset. - * - * To help debugging, will add some space - * if SCRIPT_DEBUG is defined and true. - * - * @param string $selector CSS selector. - * @param array $declarations List of declarations. - * - * @return string CSS ruleset. - */ - protected static function to_ruleset( $selector, $declarations ) { - if ( empty( $declarations ) ) { - return ''; - } - $ruleset = ''; - $additional_rules = ''; - - if ( defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ) { - $declaration_block = array_reduce( - $declarations, - function ( $carry, $element ) use( $selector, &$additional_rules ) { - if ( ! empty( $element['selectors'] ) && static::ROOT_BLOCK_SELECTOR !== $selector ) { - foreach( $element['selectors'] as $sub_selector => $property ) { - $additional_rules .= $selector . $sub_selector . " { \n"; - $additional_rules .= "\t" . $property . ': ' . $element['value'] . ";\n"; - $additional_rules .= "}\n"; - } - return $carry; - } - return $carry .= "\t" . $element['name'] . ': ' . $element['value'] . ";\n"; }, - '' - ); - - if ( $declaration_block ) { - $ruleset .= $selector . " {\n" . $declaration_block . "}\n"; - } - } else { - $declaration_block = array_reduce( - $declarations, - function ( $carry, $element ) use( $selector, &$additional_rules ) { - if ( ! empty( $element['selectors'] ) ) { - foreach( $element['selectors'] as $sub_selector => $property ) { - $additional_rules .= $selector . $sub_selector . " { "; - $additional_rules .= $property . ': ' . $element['value'] . ";"; - $additional_rules .= " }"; - } - return $carry; - } - return $carry .= $element['name'] . ': ' . $element['value'] . ';'; }, - '' - ); - - if ( $declaration_block ) { - $ruleset .= $selector . '{' . $declaration_block . '}'; - } - } - - $ruleset .= $additional_rules; - - return $ruleset; - } - - /** - * Given a styles array, it extracts the style properties - * and adds them to the $declarations array following the format: - * - * ```php - * array( - * 'name' => 'property_name', - * 'value' => 'property_value, - * ) - * ``` - * - * @param array $styles Styles to process. - * @param array $settings Theme settings. - * @param array $properties Properties metadata. - * @return array Returns the modified $declarations. - */ - protected static function compute_style_properties( $styles, $settings = array(), $properties = null ) { - if ( null === $properties ) { - $properties = static::PROPERTIES_METADATA; - } - - $declarations = array(); - if ( empty( $styles ) ) { - return $declarations; - } - - foreach ( $properties as $css_property => $value_path ) { - $value = static::get_property_value( $styles, $value_path ); - - // Look up protected properties, keyed by value path. - // Skip protected properties that are explicitly set to `null`. - if ( is_array( $value_path ) ) { - $path_string = implode( '.', $value_path ); - if ( - array_key_exists( $path_string, static::PROTECTED_PROPERTIES ) && - _wp_array_get( $settings, static::PROTECTED_PROPERTIES[ $path_string ], null ) === null - ) { - continue; - } - } - - // Skip if empty and not "0" or value represents array of longhand values. - $has_missing_value = empty( $value ) && ! is_numeric( $value ); - if ( $has_missing_value || is_array( $value ) ) { - continue; - } - - $declaration = array( - 'name' => $css_property, - 'value' => $value, - ); - - if ( isset( static::LAYOUT_STYLES[ $css_property ] ) ) { - $declaration['selectors'] = static::LAYOUT_STYLES[ $css_property ]; - } - $declarations[] = $declaration; - } - - return $declarations; - } }