From 63dbefbb6f8089118fc800ec851fd667b662d627 Mon Sep 17 00:00:00 2001 From: Glen Davies Date: Mon, 27 Jun 2022 14:36:36 +1200 Subject: [PATCH 01/43] Add spacing presets --- .../wordpress-6.1/class-wp-theme-json-6-1.php | 111 ++++++++++++++++++ .../class-wp-theme-json-resolver-6-1.php | 19 +++ lib/compat/wordpress-6.1/theme-i18n.json | 86 ++++++++++++++ lib/compat/wordpress-6.1/theme.json | 24 +++- ...-rest-block-editor-settings-controller.php | 5 + .../src/components/use-setting/index.js | 6 + 6 files changed, 250 insertions(+), 1 deletion(-) create mode 100644 lib/compat/wordpress-6.1/theme-i18n.json 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 d093480e924e44..6761b140e34295 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 @@ -674,4 +674,115 @@ protected static function get_property_value( $styles, $path, $theme_json = null return $value; } + + /* + * Presets are a set of values that serve + * to bootstrap some styles: colors, font sizes, etc. + * + * They are a unkeyed array of values such as: + * + * ```php + * array( + * array( + * 'slug' => 'unique-name-within-the-set', + * 'name' => 'Name for the UI', + * => 'value' + * ), + * ) + * ``` + * + * This contains the necessary metadata to process them: + * + * - path => Where to find the preset within the settings section. + * - prevent_override => Disables override of default presets by theme presets. + * The relationship between whether to override the defaults + * and whether the defaults are enabled is inverse: + * - If defaults are enabled => theme presets should not be overriden + * - If defaults are disabled => theme presets should be overriden + * For example, a theme sets defaultPalette to false, + * making the default palette hidden from the user. + * In that case, we want all the theme presets to be present, + * so they should override the defaults by setting this false. + * - use_default_names => whether to use the default names + * - value_key => the key that represents the value + * - value_func => optionally, instead of value_key, a function to generate + * the value that takes a preset as an argument + * (either value_key or value_func should be present) + * - css_vars => template string to use in generating the CSS Custom Property. + * Example output: "--wp--preset--duotone--blue: " will generate as many CSS Custom Properties as presets defined + * substituting the $slug for the slug's value for each preset value. + * - classes => array containing a structure with the classes to + * generate for the presets, where for each array item + * the key is the class name and the value the property name. + * The "$slug" substring will be replaced by the slug of each preset. + * For example: + * 'classes' => array( + * '.has-$slug-color' => 'color', + * '.has-$slug-background-color' => 'background-color', + * '.has-$slug-border-color' => 'border-color', + * ) + * - properties => array of CSS properties to be used by kses to + * validate the content of each preset + * by means of the remove_insecure_properties method. + */ + const PRESETS_METADATA = array( + array( + 'path' => array( 'color', 'palette' ), + 'prevent_override' => array( 'color', 'defaultPalette' ), + 'use_default_names' => false, + 'value_key' => 'color', + 'css_vars' => '--wp--preset--color--$slug', + 'classes' => array( + '.has-$slug-color' => 'color', + '.has-$slug-background-color' => 'background-color', + '.has-$slug-border-color' => 'border-color', + ), + 'properties' => array( 'color', 'background-color', 'border-color' ), + ), + array( + 'path' => array( 'color', 'gradients' ), + 'prevent_override' => array( 'color', 'defaultGradients' ), + 'use_default_names' => false, + 'value_key' => 'gradient', + 'css_vars' => '--wp--preset--gradient--$slug', + 'classes' => array( '.has-$slug-gradient-background' => 'background' ), + 'properties' => array( 'background' ), + ), + array( + 'path' => array( 'color', 'duotone' ), + 'prevent_override' => array( 'color', 'defaultDuotone' ), + 'use_default_names' => false, + 'value_func' => 'gutenberg_get_duotone_filter_property', + 'css_vars' => '--wp--preset--duotone--$slug', + 'classes' => array(), + 'properties' => array( 'filter' ), + ), + array( + 'path' => array( 'typography', 'fontSizes' ), + 'prevent_override' => false, + 'use_default_names' => true, + 'value_key' => 'size', + 'css_vars' => '--wp--preset--font-size--$slug', + 'classes' => array( '.has-$slug-font-size' => 'font-size' ), + 'properties' => array( 'font-size' ), + ), + array( + 'path' => array( 'typography', 'fontFamilies' ), + 'prevent_override' => false, + 'use_default_names' => false, + 'value_key' => 'fontFamily', + 'css_vars' => '--wp--preset--font-family--$slug', + 'classes' => array( '.has-$slug-font-family' => 'font-family' ), + 'properties' => array( 'font-family' ), + ), + array( + 'path' => array( 'spacing', 'spacingSizes' ), + 'prevent_override' => false, + 'use_default_names' => true, + 'value_key' => 'size', + 'css_vars' => '--wp--preset--spacing-size--$slug', + 'classes' => array( '.has-$slug-spacing-size' => 'spacing-size' ), + 'properties' => array( 'padding', 'margin' ), + ), + ); } diff --git a/lib/compat/wordpress-6.1/class-wp-theme-json-resolver-6-1.php b/lib/compat/wordpress-6.1/class-wp-theme-json-resolver-6-1.php index 58abcc27c04ec5..efb2025d6f4ddb 100644 --- a/lib/compat/wordpress-6.1/class-wp-theme-json-resolver-6-1.php +++ b/lib/compat/wordpress-6.1/class-wp-theme-json-resolver-6-1.php @@ -16,6 +16,25 @@ * @access private */ class WP_Theme_JSON_Resolver_6_1 extends WP_Theme_JSON_Resolver_6_0 { + /** + * Given a theme.json structure modifies it in place + * to update certain values by its translated strings + * according to the language set by the user. + * + * @param array $theme_json The theme.json to translate. + * @param string $domain Optional. Text domain. Unique identifier for retrieving translated strings. + * Default 'default'. + * @return array Returns the modified $theme_json_structure. + */ + protected static function translate( $theme_json, $domain = 'default' ) { + if ( null === static::$i18n_schema ) { + $i18n_schema = wp_json_file_decode( __DIR__ . '/theme-i18n.json' ); + static::$i18n_schema = null === $i18n_schema ? array() : $i18n_schema; + } + + return translate_settings_using_i18n_schema( static::$i18n_schema, $theme_json, $domain ); + } + /** * Return core's origin config. * diff --git a/lib/compat/wordpress-6.1/theme-i18n.json b/lib/compat/wordpress-6.1/theme-i18n.json new file mode 100644 index 00000000000000..469783409c891c --- /dev/null +++ b/lib/compat/wordpress-6.1/theme-i18n.json @@ -0,0 +1,86 @@ +{ + "title": "Style variation name", + "settings": { + "typography": { + "fontSizes": [ + { + "name": "Font size name" + } + ], + "fontFamilies": [ + { + "name": "Font family name" + } + ] + }, + "color": { + "palette": [ + { + "name": "Color name" + } + ], + "gradients": [ + { + "name": "Gradient name" + } + ], + "duotone": [ + { + "name": "Duotone name" + } + ] + }, + "spacing": { + "spacingSizes": [ + { + "name": "Space size name" + } + ] + }, + "blocks": { + "*": { + "typography": { + "fontSizes": [ + { + "name": "Font size name" + } + ], + "fontFamilies": [ + { + "name": "Font family name" + } + ] + }, + "color": { + "palette": [ + { + "name": "Color name" + } + ], + "gradients": [ + { + "name": "Gradient name" + } + ] + }, + "spacing": { + "spacingSizes": [ + { + "name": "Space size name" + } + ] + } + } + } + }, + "customTemplates": [ + { + "title": "Custom template name" + } + ], + "templateParts": [ + { + "title": "Template part name" + } + ] +} diff --git a/lib/compat/wordpress-6.1/theme.json b/lib/compat/wordpress-6.1/theme.json index d036c158d2f8ea..b75c6cc1a5a8cc 100644 --- a/lib/compat/wordpress-6.1/theme.json +++ b/lib/compat/wordpress-6.1/theme.json @@ -189,7 +189,29 @@ "blockGap": null, "margin": false, "padding": false, - "units": [ "px", "em", "rem", "vh", "vw", "%" ] + "units": [ "px", "em", "rem", "vh", "vw", "%" ], + "spacingSizes": [ + { + "name": "Small", + "slug": "small", + "size": "4px" + }, + { + "name": "Medium", + "slug": "medium", + "size": "8px" + }, + { + "name": "Large", + "slug": "large", + "size": "16px" + }, + { + "name": "Extra Large", + "slug": "x-large", + "size": "32px" + } + ] }, "typography": { "customFontSize": true, diff --git a/lib/experimental/class-wp-rest-block-editor-settings-controller.php b/lib/experimental/class-wp-rest-block-editor-settings-controller.php index 0d1aa47fb2b02b..19031fd3d3dfea 100644 --- a/lib/experimental/class-wp-rest-block-editor-settings-controller.php +++ b/lib/experimental/class-wp-rest-block-editor-settings-controller.php @@ -275,6 +275,11 @@ public function get_item_schema() { 'type' => 'array', 'context' => array( 'post-editor', 'site-editor', 'widgets-editor' ), ), + 'spacingSizesSizes' => array( + 'description' => __( 'Active theme spacing sizes.', 'gutenberg' ), + 'type' => 'array', + 'context' => array( 'post-editor', 'site-editor', 'widgets-editor' ), + ), ), ); diff --git a/packages/block-editor/src/components/use-setting/index.js b/packages/block-editor/src/components/use-setting/index.js index 3d37a85de16934..2c955b069cd8f6 100644 --- a/packages/block-editor/src/components/use-setting/index.js +++ b/packages/block-editor/src/components/use-setting/index.js @@ -40,6 +40,12 @@ const deprecatedFlags = { ? undefined : ! settings.disableCustomFontSizes, 'typography.lineHeight': ( settings ) => settings.enableCustomLineHeight, + 'spacing.spacingSizes': ( settings ) => + settings.spacingSizes === undefined ? undefined : settings.spacingSizes, + 'spacing.customSpaceSize': ( settings ) => + settings.disableCustomSpaceSizes === undefined + ? undefined + : ! settings.disableCustomSpaceSizes, 'spacing.units': ( settings ) => { if ( settings.enableCustomUnits === undefined ) { return; From ebc0118bdf519fa1cc5bd7e492b76da58e25fd1d Mon Sep 17 00:00:00 2001 From: Glen Davies Date: Thu, 23 Jun 2022 17:19:41 +1200 Subject: [PATCH 02/43] Update theme.json schema --- lib/compat/wordpress-6.1/theme.json | 1 + schemas/json/theme.json | 27 +++++++++++++++++++++++++++ 2 files changed, 28 insertions(+) diff --git a/lib/compat/wordpress-6.1/theme.json b/lib/compat/wordpress-6.1/theme.json index b75c6cc1a5a8cc..f6fb499dd8f1fb 100644 --- a/lib/compat/wordpress-6.1/theme.json +++ b/lib/compat/wordpress-6.1/theme.json @@ -189,6 +189,7 @@ "blockGap": null, "margin": false, "padding": false, + "customSpacingSizes": true, "units": [ "px", "em", "rem", "vh", "vw", "%" ], "spacingSizes": [ { diff --git a/schemas/json/theme.json b/schemas/json/theme.json index 661de26ad91ebe..f294cf9d57c436 100644 --- a/schemas/json/theme.json +++ b/schemas/json/theme.json @@ -226,6 +226,33 @@ "type": "string" }, "default": [ "px", "em", "rem", "vh", "vw", "%" ] + }, + "customSpacingSizes": { + "description": "Allow users to set custom space sizes.", + "type": "boolean", + "default": true + }, + "spacingSizes": { + "description": "Space size presets for the space size selector.\nGenerates a single class (`.has-{slug}-space-size`) and custom property (`--wp--preset--space-size--{slug}`) per preset value.", + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "description": "Name of the space size preset, translatable.", + "type": "string" + }, + "slug": { + "description": "Kebab-case unique identifier for the space size preset.", + "type": "string" + }, + "size": { + "description": "CSS space-size value, including units.", + "type": "string" + } + }, + "additionalProperties": false + } } }, "additionalProperties": false From f0eb259e02d0e5c9667f9355dca6c07ab5853e37 Mon Sep 17 00:00:00 2001 From: Glen Davies Date: Tue, 7 Jun 2022 11:25:55 +1200 Subject: [PATCH 03/43] Remove invalid deprecated settings --- packages/block-editor/src/components/use-setting/index.js | 6 ------ 1 file changed, 6 deletions(-) diff --git a/packages/block-editor/src/components/use-setting/index.js b/packages/block-editor/src/components/use-setting/index.js index 2c955b069cd8f6..3d37a85de16934 100644 --- a/packages/block-editor/src/components/use-setting/index.js +++ b/packages/block-editor/src/components/use-setting/index.js @@ -40,12 +40,6 @@ const deprecatedFlags = { ? undefined : ! settings.disableCustomFontSizes, 'typography.lineHeight': ( settings ) => settings.enableCustomLineHeight, - 'spacing.spacingSizes': ( settings ) => - settings.spacingSizes === undefined ? undefined : settings.spacingSizes, - 'spacing.customSpaceSize': ( settings ) => - settings.disableCustomSpaceSizes === undefined - ? undefined - : ! settings.disableCustomSpaceSizes, 'spacing.units': ( settings ) => { if ( settings.enableCustomUnits === undefined ) { return; From 320d176978a37c61878f4f562a38bab6a7dcc769 Mon Sep 17 00:00:00 2001 From: Glen Davies Date: Thu, 23 Jun 2022 17:20:30 +1200 Subject: [PATCH 04/43] More theme.json changes --- .../wordpress-6.0/block-editor-settings.php | 146 --------------- .../wordpress-6.1/block-editor-settings.php | 166 ++++++++++++++++++ .../wordpress-6.1/class-wp-theme-json-6-1.php | 53 ++++++ lib/load.php | 1 + schemas/json/theme.json | 2 +- 5 files changed, 221 insertions(+), 147 deletions(-) create mode 100644 lib/compat/wordpress-6.1/block-editor-settings.php diff --git a/lib/compat/wordpress-6.0/block-editor-settings.php b/lib/compat/wordpress-6.0/block-editor-settings.php index 9030998aed250f..21f1f05bb45f1f 100644 --- a/lib/compat/wordpress-6.0/block-editor-settings.php +++ b/lib/compat/wordpress-6.0/block-editor-settings.php @@ -47,149 +47,3 @@ function gutenberg_is_global_styles_in_5_9( $style ) { return false; } - -/** - * Adds styles and __experimentalFeatures to the block editor settings. - * - * @param array $settings Existing block editor settings. - * - * @return array New block editor settings. - */ -function gutenberg_get_block_editor_settings( $settings ) { - // Set what is the context for this data request. - $context = 'other'; - if ( - defined( 'REST_REQUEST' ) && - REST_REQUEST && - isset( $_GET['context'] ) && - 'mobile' === $_GET['context'] - ) { - $context = 'mobile'; - } - - if ( 'other' === $context ) { - global $wp_version; - $is_wp_5_8 = version_compare( $wp_version, '5.8', '>=' ) && version_compare( $wp_version, '5.9', '<' ); - $is_wp_5_9 = version_compare( $wp_version, '5.9', '>=' ) && version_compare( $wp_version, '6.0-beta1', '<' ); - $is_wp_6_0 = version_compare( $wp_version, '6.0-beta1', '>=' ); - - // Make sure the styles array exists. - // In some contexts, like the navigation editor, it doesn't. - if ( ! isset( $settings['styles'] ) ) { - $settings['styles'] = array(); - } - - // Remove existing global styles provided by core. - $styles_without_existing_global_styles = array(); - foreach ( $settings['styles'] as $style ) { - if ( - ( $is_wp_5_8 && ! gutenberg_is_global_styles_in_5_8( $style ) ) || // Can be removed when plugin minimum version is 5.9. - ( $is_wp_5_9 && ! gutenberg_is_global_styles_in_5_9( $style ) ) || // Can be removed when plugin minimum version is 6.0. - ( $is_wp_6_0 && ( ! isset( $style['isGlobalStyles'] ) || ! $style['isGlobalStyles'] ) ) - ) { - $styles_without_existing_global_styles[] = $style; - } - } - - // Recreate global styles. - $new_global_styles = array(); - $presets = array( - array( - 'css' => 'variables', - '__unstableType' => 'presets', - 'isGlobalStyles' => true, - ), - array( - 'css' => 'presets', - '__unstableType' => 'presets', - 'isGlobalStyles' => true, - ), - ); - foreach ( $presets as $preset_style ) { - $actual_css = gutenberg_get_global_stylesheet( array( $preset_style['css'] ) ); - if ( '' !== $actual_css ) { - $preset_style['css'] = $actual_css; - $new_global_styles[] = $preset_style; - } - } - - if ( WP_Theme_JSON_Resolver::theme_has_support() ) { - $block_classes = array( - 'css' => 'styles', - '__unstableType' => 'theme', - 'isGlobalStyles' => true, - ); - $actual_css = gutenberg_get_global_stylesheet( array( $block_classes['css'] ) ); - if ( '' !== $actual_css ) { - $block_classes['css'] = $actual_css; - $new_global_styles[] = $block_classes; - } - } - - $settings['styles'] = array_merge( $new_global_styles, $styles_without_existing_global_styles ); - } - - // Copied from get_block_editor_settings() at wordpress-develop/block-editor.php. - $settings['__experimentalFeatures'] = gutenberg_get_global_settings(); - - if ( isset( $settings['__experimentalFeatures']['color']['palette'] ) ) { - $colors_by_origin = $settings['__experimentalFeatures']['color']['palette']; - $settings['colors'] = isset( $colors_by_origin['custom'] ) ? - $colors_by_origin['custom'] : ( - isset( $colors_by_origin['theme'] ) ? - $colors_by_origin['theme'] : - $colors_by_origin['default'] - ); - } - - if ( isset( $settings['__experimentalFeatures']['color']['gradients'] ) ) { - $gradients_by_origin = $settings['__experimentalFeatures']['color']['gradients']; - $settings['gradients'] = isset( $gradients_by_origin['custom'] ) ? - $gradients_by_origin['custom'] : ( - isset( $gradients_by_origin['theme'] ) ? - $gradients_by_origin['theme'] : - $gradients_by_origin['default'] - ); - } - - if ( isset( $settings['__experimentalFeatures']['typography']['fontSizes'] ) ) { - $font_sizes_by_origin = $settings['__experimentalFeatures']['typography']['fontSizes']; - $settings['fontSizes'] = isset( $font_sizes_by_origin['custom'] ) ? - $font_sizes_by_origin['custom'] : ( - isset( $font_sizes_by_origin['theme'] ) ? - $font_sizes_by_origin['theme'] : - $font_sizes_by_origin['default'] - ); - } - - if ( isset( $settings['__experimentalFeatures']['color']['custom'] ) ) { - $settings['disableCustomColors'] = ! $settings['__experimentalFeatures']['color']['custom']; - unset( $settings['__experimentalFeatures']['color']['custom'] ); - } - if ( isset( $settings['__experimentalFeatures']['color']['customGradient'] ) ) { - $settings['disableCustomGradients'] = ! $settings['__experimentalFeatures']['color']['customGradient']; - unset( $settings['__experimentalFeatures']['color']['customGradient'] ); - } - if ( isset( $settings['__experimentalFeatures']['typography']['customFontSize'] ) ) { - $settings['disableCustomFontSizes'] = ! $settings['__experimentalFeatures']['typography']['customFontSize']; - unset( $settings['__experimentalFeatures']['typography']['customFontSize'] ); - } - if ( isset( $settings['__experimentalFeatures']['typography']['lineHeight'] ) ) { - $settings['enableCustomLineHeight'] = $settings['__experimentalFeatures']['typography']['lineHeight']; - unset( $settings['__experimentalFeatures']['typography']['lineHeight'] ); - } - if ( isset( $settings['__experimentalFeatures']['spacing']['units'] ) ) { - $settings['enableCustomUnits'] = $settings['__experimentalFeatures']['spacing']['units']; - unset( $settings['__experimentalFeatures']['spacing']['units'] ); - } - if ( isset( $settings['__experimentalFeatures']['spacing']['padding'] ) ) { - $settings['enableCustomSpacing'] = $settings['__experimentalFeatures']['spacing']['padding']; - unset( $settings['__experimentalFeatures']['spacing']['padding'] ); - } - - $settings['localAutosaveInterval'] = 15; - - return $settings; -} - -add_filter( 'block_editor_settings_all', 'gutenberg_get_block_editor_settings', PHP_INT_MAX ); diff --git a/lib/compat/wordpress-6.1/block-editor-settings.php b/lib/compat/wordpress-6.1/block-editor-settings.php new file mode 100644 index 00000000000000..ed591cf60196ae --- /dev/null +++ b/lib/compat/wordpress-6.1/block-editor-settings.php @@ -0,0 +1,166 @@ +=' ) && version_compare( $wp_version, '5.9', '<' ); + $is_wp_5_9 = version_compare( $wp_version, '5.9', '>=' ) && version_compare( $wp_version, '6.0-beta1', '<' ); + $is_wp_6_0 = version_compare( $wp_version, '6.0-beta1', '>=' ); + + // Make sure the styles array exists. + // In some contexts, like the navigation editor, it doesn't. + if ( ! isset( $settings['styles'] ) ) { + $settings['styles'] = array(); + } + + // Remove existing global styles provided by core. + $styles_without_existing_global_styles = array(); + foreach ( $settings['styles'] as $style ) { + if ( + ( $is_wp_5_8 && ! gutenberg_is_global_styles_in_5_8( $style ) ) || // Can be removed when plugin minimum version is 5.9. + ( $is_wp_5_9 && ! gutenberg_is_global_styles_in_5_9( $style ) ) || // Can be removed when plugin minimum version is 6.0. + ( $is_wp_6_0 && ( ! isset( $style['isGlobalStyles'] ) || ! $style['isGlobalStyles'] ) ) + ) { + $styles_without_existing_global_styles[] = $style; + } + } + + // Recreate global styles. + $new_global_styles = array(); + $presets = array( + array( + 'css' => 'variables', + '__unstableType' => 'presets', + 'isGlobalStyles' => true, + ), + array( + 'css' => 'presets', + '__unstableType' => 'presets', + 'isGlobalStyles' => true, + ), + ); + foreach ( $presets as $preset_style ) { + $actual_css = gutenberg_get_global_stylesheet( array( $preset_style['css'] ) ); + if ( '' !== $actual_css ) { + $preset_style['css'] = $actual_css; + $new_global_styles[] = $preset_style; + } + } + + if ( WP_Theme_JSON_Resolver::theme_has_support() ) { + $block_classes = array( + 'css' => 'styles', + '__unstableType' => 'theme', + 'isGlobalStyles' => true, + ); + $actual_css = gutenberg_get_global_stylesheet( array( $block_classes['css'] ) ); + if ( '' !== $actual_css ) { + $block_classes['css'] = $actual_css; + $new_global_styles[] = $block_classes; + } + } + + $settings['styles'] = array_merge( $new_global_styles, $styles_without_existing_global_styles ); + } + + // Copied from get_block_editor_settings() at wordpress-develop/block-editor.php. + $settings['__experimentalFeatures'] = gutenberg_get_global_settings(); + + if ( isset( $settings['__experimentalFeatures']['color']['palette'] ) ) { + $colors_by_origin = $settings['__experimentalFeatures']['color']['palette']; + $settings['colors'] = isset( $colors_by_origin['custom'] ) ? + $colors_by_origin['custom'] : ( + isset( $colors_by_origin['theme'] ) ? + $colors_by_origin['theme'] : + $colors_by_origin['default'] + ); + } + + if ( isset( $settings['__experimentalFeatures']['color']['gradients'] ) ) { + $gradients_by_origin = $settings['__experimentalFeatures']['color']['gradients']; + $settings['gradients'] = isset( $gradients_by_origin['custom'] ) ? + $gradients_by_origin['custom'] : ( + isset( $gradients_by_origin['theme'] ) ? + $gradients_by_origin['theme'] : + $gradients_by_origin['default'] + ); + } + + if ( isset( $settings['__experimentalFeatures']['typography']['fontSizes'] ) ) { + $font_sizes_by_origin = $settings['__experimentalFeatures']['typography']['fontSizes']; + $settings['fontSizes'] = isset( $font_sizes_by_origin['custom'] ) ? + $font_sizes_by_origin['custom'] : ( + isset( $font_sizes_by_origin['theme'] ) ? + $font_sizes_by_origin['theme'] : + $font_sizes_by_origin['default'] + ); + } + + if ( isset( $settings['__experimentalFeatures']['color']['custom'] ) ) { + $settings['disableCustomColors'] = ! $settings['__experimentalFeatures']['color']['custom']; + unset( $settings['__experimentalFeatures']['color']['custom'] ); + } + if ( isset( $settings['__experimentalFeatures']['color']['customGradient'] ) ) { + $settings['disableCustomGradients'] = ! $settings['__experimentalFeatures']['color']['customGradient']; + unset( $settings['__experimentalFeatures']['color']['customGradient'] ); + } + if ( isset( $settings['__experimentalFeatures']['typography']['customFontSize'] ) ) { + $settings['disableCustomFontSizes'] = ! $settings['__experimentalFeatures']['typography']['customFontSize']; + unset( $settings['__experimentalFeatures']['typography']['customFontSize'] ); + } + if ( isset( $settings['__experimentalFeatures']['typography']['lineHeight'] ) ) { + $settings['enableCustomLineHeight'] = $settings['__experimentalFeatures']['typography']['lineHeight']; + unset( $settings['__experimentalFeatures']['typography']['lineHeight'] ); + } + if ( isset( $settings['__experimentalFeatures']['spacing']['units'] ) ) { + $settings['enableCustomUnits'] = $settings['__experimentalFeatures']['spacing']['units']; + unset( $settings['__experimentalFeatures']['spacing']['units'] ); + } + if ( isset( $settings['__experimentalFeatures']['spacing']['padding'] ) ) { + $settings['enableCustomSpacing'] = $settings['__experimentalFeatures']['spacing']['padding']; + unset( $settings['__experimentalFeatures']['spacing']['padding'] ); + } + if ( isset( $settings['__experimentalFeatures']['spacing']['customSpacingSize'] ) ) { + $settings['disableCustomSpacingSize'] = ! $settings['__experimentalFeatures']['spacing']['customSpacingSize']; + unset( $settings['__experimentalFeatures']['spacing']['customSpacingSize'] ); + } + + if ( isset( $settings['__experimentalFeatures']['spacing']['spacingSizes'] ) ) { + $spacing_sizes_by_origin = $settings['__experimentalFeatures']['spacing']['spacingSizes']; + $settings['spacingSizes'] = isset( $spacing_sizes_by_origin['custom'] ) ? + $spacing_sizes_by_origin['custom'] : ( + isset( $spacing_sizes_by_origin['theme'] ) ? + $spacing_sizes_by_origin['theme'] : + $spacing_sizes_by_origin['default'] + ); + } + + $settings['localAutosaveInterval'] = 15; + + return $settings; +} + +add_filter( 'block_editor_settings_all', 'gutenberg_get_block_editor_settings', PHP_INT_MAX ); 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 6761b140e34295..671a253981e44c 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 @@ -785,4 +785,57 @@ protected static function get_property_value( $styles, $path, $theme_json = null 'properties' => array( 'padding', 'margin' ), ), ); + + /** + * The valid properties under the settings key. + * + * @var array + */ + 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, + 'defaultGradients' => null, + 'defaultPalette' => null, + 'duotone' => null, + 'gradients' => null, + 'link' => null, + 'palette' => null, + 'text' => null, + ), + 'custom' => null, + 'layout' => array( + 'contentSize' => null, + 'wideSize' => null, + ), + 'spacing' => array( + 'customSpacingSize' => null, + 'spacingSizes' => null, + '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, + ), + ); } diff --git a/lib/load.php b/lib/load.php index 5504e8bd3fc3d0..d16096e03dabcc 100644 --- a/lib/load.php +++ b/lib/load.php @@ -122,6 +122,7 @@ function gutenberg_is_experiment_enabled( $name ) { // WordPress 6.1 compat. require __DIR__ . '/compat/wordpress-6.1/blocks.php'; +require __DIR__ . '/compat/wordpress-6.1/block-editor-settings.php'; require __DIR__ . '/compat/wordpress-6.1/persisted-preferences.php'; require __DIR__ . '/compat/wordpress-6.1/get-global-styles-and-settings.php'; require __DIR__ . '/compat/wordpress-6.1/class-wp-theme-json-6-1.php'; diff --git a/schemas/json/theme.json b/schemas/json/theme.json index f294cf9d57c436..ce94520c935dc5 100644 --- a/schemas/json/theme.json +++ b/schemas/json/theme.json @@ -227,7 +227,7 @@ }, "default": [ "px", "em", "rem", "vh", "vw", "%" ] }, - "customSpacingSizes": { + "customSpacingSize": { "description": "Allow users to set custom space sizes.", "type": "boolean", "default": true From 4e44fee09f6ad1650c65680da5709b652b561f35 Mon Sep 17 00:00:00 2001 From: Glen Davies Date: Tue, 7 Jun 2022 13:37:20 +1200 Subject: [PATCH 05/43] Change size-slug to numbers to make it easier for theme authors to insert additional options --- lib/compat/wordpress-6.1/theme.json | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/lib/compat/wordpress-6.1/theme.json b/lib/compat/wordpress-6.1/theme.json index f6fb499dd8f1fb..f507e8518740b6 100644 --- a/lib/compat/wordpress-6.1/theme.json +++ b/lib/compat/wordpress-6.1/theme.json @@ -193,24 +193,29 @@ "units": [ "px", "em", "rem", "vh", "vw", "%" ], "spacingSizes": [ { - "name": "Small", - "slug": "small", + "name": "S", + "slug": "10", "size": "4px" }, { - "name": "Medium", - "slug": "medium", + "name": "M", + "slug": "20", "size": "8px" }, { - "name": "Large", - "slug": "large", + "name": "L", + "slug": "30", "size": "16px" }, { - "name": "Extra Large", - "slug": "x-large", + "name": "XL", + "slug": "40", "size": "32px" + }, + { + "name": "2XL", + "slug": "50", + "size": "64px" } ] }, From 0977a7705749062fb7bcb7e4460b14f563b804b4 Mon Sep 17 00:00:00 2001 From: Glen Davies Date: Wed, 8 Jun 2022 09:46:53 +1200 Subject: [PATCH 06/43] Change naming from t-shirt sizes to full word --- lib/compat/wordpress-6.1/theme.json | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/lib/compat/wordpress-6.1/theme.json b/lib/compat/wordpress-6.1/theme.json index f507e8518740b6..216733160e6075 100644 --- a/lib/compat/wordpress-6.1/theme.json +++ b/lib/compat/wordpress-6.1/theme.json @@ -193,27 +193,27 @@ "units": [ "px", "em", "rem", "vh", "vw", "%" ], "spacingSizes": [ { - "name": "S", + "name": "Extra small", "slug": "10", "size": "4px" }, { - "name": "M", + "name": "Small", "slug": "20", "size": "8px" }, { - "name": "L", + "name": "Medium", "slug": "30", "size": "16px" }, { - "name": "XL", + "name": "Large", "slug": "40", "size": "32px" }, { - "name": "2XL", + "name": "Extra large", "slug": "50", "size": "64px" } From d6739926aefc4347bf23a6d8d2a0ef050fb3887d Mon Sep 17 00:00:00 2001 From: Glen Davies Date: Wed, 8 Jun 2022 10:40:03 +1200 Subject: [PATCH 07/43] Update docs --- docs/reference-guides/theme-json-reference/theme-json-living.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/reference-guides/theme-json-reference/theme-json-living.md b/docs/reference-guides/theme-json-reference/theme-json-living.md index d0376ef0006eca..4416bd276dc853 100644 --- a/docs/reference-guides/theme-json-reference/theme-json-living.md +++ b/docs/reference-guides/theme-json-reference/theme-json-living.md @@ -83,6 +83,8 @@ Settings related to spacing. | margin | boolean | false | | | padding | boolean | false | | | units | array | px,em,rem,vh,vw,% | | +| customSpacingSize | boolean | true | | +| spacingSizes | array | | name, size, slug | --- From 144f2e0306980ed9b3804b0229a164238f5a845a Mon Sep 17 00:00:00 2001 From: Glen Davies Date: Wed, 8 Jun 2022 13:59:16 +1200 Subject: [PATCH 08/43] Remove class generation for now as possibly not needed. --- lib/compat/wordpress-6.1/class-wp-theme-json-6-1.php | 1 - 1 file changed, 1 deletion(-) 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 671a253981e44c..e016a7d8dfbdfb 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 @@ -781,7 +781,6 @@ protected static function get_property_value( $styles, $path, $theme_json = null 'use_default_names' => true, 'value_key' => 'size', 'css_vars' => '--wp--preset--spacing-size--$slug', - 'classes' => array( '.has-$slug-spacing-size' => 'spacing-size' ), 'properties' => array( 'padding', 'margin' ), ), ); From c3242d8335df232729afbf1cdc4b8801e51f2b01 Mon Sep 17 00:00:00 2001 From: Glen Davies Date: Wed, 8 Jun 2022 14:09:39 +1200 Subject: [PATCH 09/43] switch to empty array to match duotone --- lib/compat/wordpress-6.1/class-wp-theme-json-6-1.php | 1 + 1 file changed, 1 insertion(+) 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 e016a7d8dfbdfb..c4de751a183051 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 @@ -781,6 +781,7 @@ protected static function get_property_value( $styles, $path, $theme_json = null 'use_default_names' => true, 'value_key' => 'size', 'css_vars' => '--wp--preset--spacing-size--$slug', + 'classes' => array(), 'properties' => array( 'padding', 'margin' ), ), ); From c7a24d321bf58b9b753aaf9abc091b42e089047e Mon Sep 17 00:00:00 2001 From: Glen Davies Date: Fri, 10 Jun 2022 12:07:35 +1200 Subject: [PATCH 10/43] Add a spacing scale option --- .../wordpress-6.1/class-wp-theme-json-6-1.php | 80 +++++++++++++++++++ lib/compat/wordpress-6.1/theme.json | 27 ++++--- 2 files changed, 97 insertions(+), 10 deletions(-) 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 c4de751a183051..48acd7533d4e26 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 @@ -784,6 +784,15 @@ protected static function get_property_value( $styles, $path, $theme_json = null 'classes' => array(), 'properties' => array( 'padding', 'margin' ), ), + array( + 'path' => array( 'spacing', 'spacingScale' ), + 'prevent_override' => false, + 'use_default_names' => true, + 'value_key' => 'size', + 'css_vars' => '--wp--preset--spacing-size--$slug', + 'classes' => array(), + 'properties' => array( 'padding', 'margin' ), + ), ); /** @@ -820,6 +829,7 @@ protected static function get_property_value( $styles, $path, $theme_json = null 'spacing' => array( 'customSpacingSize' => null, 'spacingSizes' => null, + 'spacingScale' => null, 'blockGap' => null, 'margin' => null, 'padding' => null, @@ -838,4 +848,74 @@ protected static function get_property_value( $styles, $path, $theme_json = null 'textTransform' => null, ), ); + + /** + * Given the block settings, it extracts the CSS Custom Properties + * for the presets and adds them to the $declarations array + * following the format: + * + * ```php + * array( + * 'name' => 'property_name', + * 'value' => 'property_value, + * ) + * ``` + * + * @param array $settings Settings to process. + * @param array $origins List of origins to process. + * @return array Returns the modified $declarations. + */ + protected static function compute_preset_vars( $settings, $origins ) { + $declarations = array(); + + // Theme.json can specify either a spacingScale to autogenerate spacing size presets, or a fixed array of spacingSizes. + // The spaceScale takes presidence so will replace the spacingSizes array if present. + if ( isset( $settings['spacing']['spacingScale'] ) ) { + $settings['spacing']['spacingSizes'] = array( 'default' => static::get_spacing_sizes( $settings['spacing']['spacingScale'] ) ); + } + + foreach ( static::PRESETS_METADATA as $preset_metadata ) { + + $values_by_slug = static::get_settings_values_by_slug( $settings, $preset_metadata, $origins ); + + foreach ( $values_by_slug as $slug => $value ) { + $declarations[] = array( + 'name' => static::replace_slug_in_string( $preset_metadata['css_vars'], $slug ), + 'value' => $value, + ); + } + } + + return $declarations; + } + + /** + * Transform the spacing scale values into an array of spacing scale presets. + * + * @param array $spacing_scale scale Array of values used to create the scale of spacing presets. + * @return array An array of spacing preset sizes. + */ + protected static function get_spacing_sizes( $spacing_scale ) { + $spacing_sizes = array(); + $spacing_sizes[0] = array( + 'name' => 1, + 'slug' => 1, + 'size' => $spacing_scale['firstStep'] . $spacing_scale['units'], + ); + $current_step = $spacing_scale['firstStep']; + + for ( $x = 1; $x <= $spacing_scale['steps'] - 1; $x++ ) { + $current_step = '+' === $spacing_scale['operator'] + ? $current_step + $spacing_scale['increment'] . $spacing_scale['units'] + : $current_step * $spacing_scale['increment'] . $spacing_scale['units']; + + $spacing_sizes[ $x + 1 ] = array( + 'name' => $x + 1, + 'slug' => $x + 1, + 'size' => $current_step, + ); + } + + return $spacing_sizes; + } } diff --git a/lib/compat/wordpress-6.1/theme.json b/lib/compat/wordpress-6.1/theme.json index 216733160e6075..7574771a3b5c6c 100644 --- a/lib/compat/wordpress-6.1/theme.json +++ b/lib/compat/wordpress-6.1/theme.json @@ -191,31 +191,38 @@ "padding": false, "customSpacingSizes": true, "units": [ "px", "em", "rem", "vh", "vw", "%" ], + "spacingScale": { + "operator": "+", + "increment": 0.5, + "steps": 5, + "firstStep": 0.5, + "units": "rem" + }, "spacingSizes": [ { "name": "Extra small", - "slug": "10", - "size": "4px" + "slug": "1", + "size": "0.5rem" }, { "name": "Small", - "slug": "20", - "size": "8px" + "slug": "2", + "size": "1rem" }, { "name": "Medium", - "slug": "30", - "size": "16px" + "slug": "3", + "size": "1.5rem" }, { "name": "Large", - "slug": "40", - "size": "32px" + "slug": "4", + "size": "2rem" }, { "name": "Extra large", - "slug": "50", - "size": "64px" + "slug": "5", + "size": "2.5rem" } ] }, From 4ad45acb253f45f07a9df613c6097ad3510378f2 Mon Sep 17 00:00:00 2001 From: Glen Davies Date: Fri, 10 Jun 2022 14:05:21 +1200 Subject: [PATCH 11/43] An a 0 space option --- .../wordpress-6.1/class-wp-theme-json-6-1.php | 14 ++++++++++---- lib/compat/wordpress-6.1/theme.json | 5 +++++ 2 files changed, 15 insertions(+), 4 deletions(-) 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 48acd7533d4e26..a1737b714352b8 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 @@ -896,20 +896,26 @@ protected static function compute_preset_vars( $settings, $origins ) { * @return array An array of spacing preset sizes. */ protected static function get_spacing_sizes( $spacing_scale ) { - $spacing_sizes = array(); - $spacing_sizes[0] = array( + $spacing_sizes = array(); + $spacing_sizes[] = array( + 'name' => 0, + 'slug' => 0, + 'size' => 0, + ); + $spacing_sizes[] = array( 'name' => 1, 'slug' => 1, 'size' => $spacing_scale['firstStep'] . $spacing_scale['units'], ); - $current_step = $spacing_scale['firstStep']; + + $current_step = $spacing_scale['firstStep']; for ( $x = 1; $x <= $spacing_scale['steps'] - 1; $x++ ) { $current_step = '+' === $spacing_scale['operator'] ? $current_step + $spacing_scale['increment'] . $spacing_scale['units'] : $current_step * $spacing_scale['increment'] . $spacing_scale['units']; - $spacing_sizes[ $x + 1 ] = array( + $spacing_sizes[] = array( 'name' => $x + 1, 'slug' => $x + 1, 'size' => $current_step, diff --git a/lib/compat/wordpress-6.1/theme.json b/lib/compat/wordpress-6.1/theme.json index 7574771a3b5c6c..160eb4d1263e82 100644 --- a/lib/compat/wordpress-6.1/theme.json +++ b/lib/compat/wordpress-6.1/theme.json @@ -199,6 +199,11 @@ "units": "rem" }, "spacingSizes": [ + { + "name": "None", + "slug": "0", + "size": "0" + }, { "name": "Extra small", "slug": "1", From 3b5233a8faaca8a6a1064c18392b329c53883bd9 Mon Sep 17 00:00:00 2001 From: Glen Davies Date: Fri, 10 Jun 2022 15:41:25 +1200 Subject: [PATCH 12/43] Switch back to slugs as multiples of ten to make it is for themes to add additional values between core defaults --- lib/compat/wordpress-6.1/class-wp-theme-json-6-1.php | 4 ++-- lib/compat/wordpress-6.1/theme.json | 10 +++++----- 2 files changed, 7 insertions(+), 7 deletions(-) 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 a1737b714352b8..b7d6fb219ec355 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 @@ -904,7 +904,7 @@ protected static function get_spacing_sizes( $spacing_scale ) { ); $spacing_sizes[] = array( 'name' => 1, - 'slug' => 1, + 'slug' => 10, 'size' => $spacing_scale['firstStep'] . $spacing_scale['units'], ); @@ -917,7 +917,7 @@ protected static function get_spacing_sizes( $spacing_scale ) { $spacing_sizes[] = array( 'name' => $x + 1, - 'slug' => $x + 1, + 'slug' => ( $x + 1 ) * 10, 'size' => $current_step, ); } diff --git a/lib/compat/wordpress-6.1/theme.json b/lib/compat/wordpress-6.1/theme.json index 160eb4d1263e82..c1a318e9c94435 100644 --- a/lib/compat/wordpress-6.1/theme.json +++ b/lib/compat/wordpress-6.1/theme.json @@ -206,27 +206,27 @@ }, { "name": "Extra small", - "slug": "1", + "slug": "10", "size": "0.5rem" }, { "name": "Small", - "slug": "2", + "slug": "20", "size": "1rem" }, { "name": "Medium", - "slug": "3", + "slug": "30", "size": "1.5rem" }, { "name": "Large", - "slug": "4", + "slug": "40", "size": "2rem" }, { "name": "Extra large", - "slug": "5", + "slug": "50", "size": "2.5rem" } ] From 94a1dda94f2014cd575f8c85738a94f5c8e2dcd7 Mon Sep 17 00:00:00 2001 From: Glen Davies Date: Mon, 13 Jun 2022 12:13:42 +1200 Subject: [PATCH 13/43] Give a theme's spacingSizes setting priority over core spacingScale --- .../wordpress-6.1/class-wp-theme-json-6-1.php | 2 +- lib/compat/wordpress-6.1/theme.json | 34 +------------------ ...-rest-block-editor-settings-controller.php | 7 +++- schemas/json/theme.json | 27 +++++++++++++++ 4 files changed, 35 insertions(+), 35 deletions(-) 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 b7d6fb219ec355..30b90eb9a02d80 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 @@ -870,7 +870,7 @@ protected static function compute_preset_vars( $settings, $origins ) { // Theme.json can specify either a spacingScale to autogenerate spacing size presets, or a fixed array of spacingSizes. // The spaceScale takes presidence so will replace the spacingSizes array if present. - if ( isset( $settings['spacing']['spacingScale'] ) ) { + if ( ! isset( $settings['spacing']['spacingSizes']['theme'] ) ) { $settings['spacing']['spacingSizes'] = array( 'default' => static::get_spacing_sizes( $settings['spacing']['spacingScale'] ) ); } diff --git a/lib/compat/wordpress-6.1/theme.json b/lib/compat/wordpress-6.1/theme.json index c1a318e9c94435..0e2201eff290a3 100644 --- a/lib/compat/wordpress-6.1/theme.json +++ b/lib/compat/wordpress-6.1/theme.json @@ -197,39 +197,7 @@ "steps": 5, "firstStep": 0.5, "units": "rem" - }, - "spacingSizes": [ - { - "name": "None", - "slug": "0", - "size": "0" - }, - { - "name": "Extra small", - "slug": "10", - "size": "0.5rem" - }, - { - "name": "Small", - "slug": "20", - "size": "1rem" - }, - { - "name": "Medium", - "slug": "30", - "size": "1.5rem" - }, - { - "name": "Large", - "slug": "40", - "size": "2rem" - }, - { - "name": "Extra large", - "slug": "50", - "size": "2.5rem" - } - ] + } }, "typography": { "customFontSize": true, diff --git a/lib/experimental/class-wp-rest-block-editor-settings-controller.php b/lib/experimental/class-wp-rest-block-editor-settings-controller.php index 19031fd3d3dfea..34a6debf30bce4 100644 --- a/lib/experimental/class-wp-rest-block-editor-settings-controller.php +++ b/lib/experimental/class-wp-rest-block-editor-settings-controller.php @@ -275,11 +275,16 @@ public function get_item_schema() { 'type' => 'array', 'context' => array( 'post-editor', 'site-editor', 'widgets-editor' ), ), - 'spacingSizesSizes' => array( + 'spacingSizes' => array( 'description' => __( 'Active theme spacing sizes.', 'gutenberg' ), 'type' => 'array', 'context' => array( 'post-editor', 'site-editor', 'widgets-editor' ), ), + 'spacingScale' => array( + 'description' => __( 'Active theme spacing scale.', 'gutenberg' ), + 'type' => 'array', + 'context' => array( 'post-editor', 'site-editor', 'widgets-editor' ), + ), ), ); diff --git a/schemas/json/theme.json b/schemas/json/theme.json index ce94520c935dc5..96b36728d8b182 100644 --- a/schemas/json/theme.json +++ b/schemas/json/theme.json @@ -253,6 +253,33 @@ }, "additionalProperties": false } + }, + "spacingScale": { + "description": "Space size presets for the space size selector.\nGenerates a single class (`.has-{slug}-space-size`) and custom property (`--wp--preset--space-size--{slug}`) per preset value.", + "type": "object", + "properties": { + "operator": { + "description": "With + or * depending on whether scale is generated by increment or mulitplier.", + "type": "string" + }, + "increment": { + "description": "The amouunt to increment each step by", + "type": "number" + }, + "steps": { + "description": "Number of steps to generate in scale", + "type": "number" + }, + "firstStep": { + "description": "The value to starr scale from", + "type": "number" + }, + "units": { + "description": "Units that the scale uses, eg. rem, em, px", + "type": "string" + } + }, + "additionalProperties": false } }, "additionalProperties": false From af251886f05168210045e2901ddf5acfba9f7c49 Mon Sep 17 00:00:00 2001 From: Glen Davies Date: Mon, 13 Jun 2022 12:17:03 +1200 Subject: [PATCH 14/43] Update comment --- lib/compat/wordpress-6.1/class-wp-theme-json-6-1.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 30b90eb9a02d80..8ee4ff3dbb8611 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 @@ -869,7 +869,7 @@ protected static function compute_preset_vars( $settings, $origins ) { $declarations = array(); // Theme.json can specify either a spacingScale to autogenerate spacing size presets, or a fixed array of spacingSizes. - // The spaceScale takes presidence so will replace the spacingSizes array if present. + // A theme's spaceSizes array takes presidence so will replace the auto generated spacingSizes from core spacingScale if present. if ( ! isset( $settings['spacing']['spacingSizes']['theme'] ) ) { $settings['spacing']['spacingSizes'] = array( 'default' => static::get_spacing_sizes( $settings['spacing']['spacingScale'] ) ); } From 2d6e41336c928cde33a40e3f69ebb659c88221ce Mon Sep 17 00:00:00 2001 From: Glen Davies Date: Mon, 13 Jun 2022 14:49:20 +1200 Subject: [PATCH 15/43] Move setting of spacing presets into theme json merge method --- .../wordpress-6.1/class-wp-theme-json-6-1.php | 94 +++++++++++++++++-- 1 file changed, 87 insertions(+), 7 deletions(-) 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 8ee4ff3dbb8611..7a07a252fcad04 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 @@ -868,14 +868,7 @@ protected static function get_property_value( $styles, $path, $theme_json = null protected static function compute_preset_vars( $settings, $origins ) { $declarations = array(); - // Theme.json can specify either a spacingScale to autogenerate spacing size presets, or a fixed array of spacingSizes. - // A theme's spaceSizes array takes presidence so will replace the auto generated spacingSizes from core spacingScale if present. - if ( ! isset( $settings['spacing']['spacingSizes']['theme'] ) ) { - $settings['spacing']['spacingSizes'] = array( 'default' => static::get_spacing_sizes( $settings['spacing']['spacingScale'] ) ); - } - foreach ( static::PRESETS_METADATA as $preset_metadata ) { - $values_by_slug = static::get_settings_values_by_slug( $settings, $preset_metadata, $origins ); foreach ( $values_by_slug as $slug => $value ) { @@ -924,4 +917,91 @@ protected static function get_spacing_sizes( $spacing_scale ) { return $spacing_sizes; } + + /** + * Merge new incoming data. + * + * @param WP_Theme_JSON $incoming Data to merge. + */ + public function merge( $incoming ) { + $incoming_data = $incoming->get_raw_data(); + $this->theme_json = array_replace_recursive( $this->theme_json, $incoming_data ); + + /* + * The array_replace_recursive algorithm merges at the leaf level, + * but we don't want leaf arrays to be merged, so we overwrite it. + * + * For leaf values that are sequential arrays it will use the numeric indexes for replacement. + * We rather replace the existing with the incoming value, if it exists. + * This is the case of spacing.units. + * + * For leaf values that are associative arrays it will merge them as expected. + * This is also not the behavior we want for the current associative arrays (presets). + * We rather replace the existing with the incoming value, if it exists. + * This happens, for example, when we merge data from theme.json upon existing + * theme supports or when we merge anything coming from the same source twice. + * This is the case of color.palette, color.gradients, color.duotone, + * typography.fontSizes, or typography.fontFamilies. + * + * Additionally, for some preset types, we also want to make sure the + * values they introduce don't conflict with default values. We do so + * by checking the incoming slugs for theme presets and compare them + * with the equivalent default presets: if a slug is present as a default + * we remove it from the theme presets. + */ + $nodes = static::get_setting_nodes( $incoming_data ); + $slugs_global = static::get_default_slugs( $this->theme_json, array( 'settings' ) ); + foreach ( $nodes as $node ) { + $slugs_node = static::get_default_slugs( $this->theme_json, $node['path'] ); + $slugs = array_merge_recursive( $slugs_global, $slugs_node ); + + // Replace the spacing.units. + $path = array_merge( $node['path'], array( 'spacing', 'units' ) ); + $content = _wp_array_get( $incoming_data, $path, null ); + if ( isset( $content ) ) { + _wp_array_set( $this->theme_json, $path, $content ); + } + + // Replace the presets. + foreach ( static::PRESETS_METADATA as $preset ) { + $override_preset = ! static::get_metadata_boolean( $this->theme_json['settings'], $preset['prevent_override'], true ); + + foreach ( static::VALID_ORIGINS as $origin ) { + $base_path = array_merge( $node['path'], $preset['path'] ); + $path = array_merge( $base_path, array( $origin ) ); + $content = _wp_array_get( $incoming_data, $path, null ); + if ( ! isset( $content ) ) { + continue; + } + + if ( 'theme' === $origin && $preset['use_default_names'] ) { + foreach ( $content as &$item ) { + if ( ! array_key_exists( 'name', $item ) ) { + $name = static::get_name_from_defaults( $item['slug'], $base_path ); + if ( null !== $name ) { + $item['name'] = $name; + } + } + } + } + + if ( + ( 'theme' !== $origin ) || + ( 'theme' === $origin && $override_preset ) + ) { + _wp_array_set( $this->theme_json, $path, $content ); + } else { + $slugs_for_preset = _wp_array_get( $slugs, $preset['path'], array() ); + $content = static::filter_slugs( $content, $slugs_for_preset ); + _wp_array_set( $this->theme_json, $path, $content ); + } + } + } + + // Generate the default spacing sizes presets. + $spacing_size_defaults = static::get_spacing_sizes( _wp_array_get( $this->theme_json, array( 'settings', 'spacing', 'spacingScale' ), array() ) ); + _wp_array_set( $this->theme_json, array( 'settings', 'spacing', 'spacingSizes', 'default' ), $spacing_size_defaults ); + } + + } } From b0f1af3305feb2f0ef2071590eaa84fb90e835b6 Mon Sep 17 00:00:00 2001 From: Glen Davies Date: Thu, 16 Jun 2022 10:35:29 +1200 Subject: [PATCH 16/43] Remove unchanged method from 6.1 compat file --- .../wordpress-6.1/class-wp-theme-json-6-1.php | 33 ------------------- 1 file changed, 33 deletions(-) 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 7a07a252fcad04..8ef18bfc07654c 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 @@ -849,39 +849,6 @@ protected static function get_property_value( $styles, $path, $theme_json = null ), ); - /** - * Given the block settings, it extracts the CSS Custom Properties - * for the presets and adds them to the $declarations array - * following the format: - * - * ```php - * array( - * 'name' => 'property_name', - * 'value' => 'property_value, - * ) - * ``` - * - * @param array $settings Settings to process. - * @param array $origins List of origins to process. - * @return array Returns the modified $declarations. - */ - protected static function compute_preset_vars( $settings, $origins ) { - $declarations = array(); - - foreach ( static::PRESETS_METADATA as $preset_metadata ) { - $values_by_slug = static::get_settings_values_by_slug( $settings, $preset_metadata, $origins ); - - foreach ( $values_by_slug as $slug => $value ) { - $declarations[] = array( - 'name' => static::replace_slug_in_string( $preset_metadata['css_vars'], $slug ), - 'value' => $value, - ); - } - } - - return $declarations; - } - /** * Transform the spacing scale values into an array of spacing scale presets. * From 22b8423224d375815736b3e0c670eb5c97977f35 Mon Sep 17 00:00:00 2001 From: Glen Davies Date: Thu, 16 Jun 2022 12:08:31 +1200 Subject: [PATCH 17/43] Check for valid spacing.spacingScale values before generating spacing scale --- .../wordpress-6.1/class-wp-theme-json-6-1.php | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) 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 8ef18bfc07654c..87e52aaee7b11b 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 @@ -856,6 +856,18 @@ protected static function get_property_value( $styles, $path, $theme_json = null * @return array An array of spacing preset sizes. */ protected static function get_spacing_sizes( $spacing_scale ) { + if ( ! isset( $spacing_scale['firstStep'] ) + || ! isset( $spacing_scale['units'] ) + || ! isset( $spacing_scale['operator'] ) + || ! isset( $spacing_scale['increment'] ) + || ! isset( $spacing_scale['steps'] ) + || ! is_numeric( $spacing_scale['increment'] ) + || ! is_numeric( $spacing_scale['steps'] ) + || ! is_numeric( $spacing_scale['firstStep'] ) + || ( '+' !== $spacing_scale['operator'] && '*' !== $spacing_scale['operator'] ) ) { + return null; + } + $spacing_sizes = array(); $spacing_sizes[] = array( 'name' => 0, @@ -967,7 +979,9 @@ public function merge( $incoming ) { // Generate the default spacing sizes presets. $spacing_size_defaults = static::get_spacing_sizes( _wp_array_get( $this->theme_json, array( 'settings', 'spacing', 'spacingScale' ), array() ) ); - _wp_array_set( $this->theme_json, array( 'settings', 'spacing', 'spacingSizes', 'default' ), $spacing_size_defaults ); + if ( $spacing_size_defaults ) { + _wp_array_set( $this->theme_json, array( 'settings', 'spacing', 'spacingSizes', 'default' ), $spacing_size_defaults ); + } } } From 4f57479eb56e3a93af03d4085922e556a6ca0139 Mon Sep 17 00:00:00 2001 From: Glen Davies Date: Thu, 16 Jun 2022 12:14:08 +1200 Subject: [PATCH 18/43] Add warning message if spacingScale values invalid --- lib/compat/wordpress-6.1/class-wp-theme-json-6-1.php | 1 + 1 file changed, 1 insertion(+) 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 87e52aaee7b11b..8b1fe41eb18441 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 @@ -865,6 +865,7 @@ protected static function get_spacing_sizes( $spacing_scale ) { || ! is_numeric( $spacing_scale['steps'] ) || ! is_numeric( $spacing_scale['firstStep'] ) || ( '+' !== $spacing_scale['operator'] && '*' !== $spacing_scale['operator'] ) ) { + trigger_error( __( 'Some of the theme.json settings.spacing.spacingScale values are invalid' ), E_USER_NOTICE ); return null; } From 5d86d32f51021f1b1eb1537602cee9e1039eb2c9 Mon Sep 17 00:00:00 2001 From: Glen Davies Date: Thu, 16 Jun 2022 12:24:45 +1200 Subject: [PATCH 19/43] Fixing issue with current_step not numeric --- lib/compat/wordpress-6.1/class-wp-theme-json-6-1.php | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) 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 8b1fe41eb18441..f59e98deb4ebaf 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 @@ -865,8 +865,10 @@ protected static function get_spacing_sizes( $spacing_scale ) { || ! is_numeric( $spacing_scale['steps'] ) || ! is_numeric( $spacing_scale['firstStep'] ) || ( '+' !== $spacing_scale['operator'] && '*' !== $spacing_scale['operator'] ) ) { + if ( ! empty( $spacing_scale ) ) { trigger_error( __( 'Some of the theme.json settings.spacing.spacingScale values are invalid' ), E_USER_NOTICE ); - return null; + } + return null; } $spacing_sizes = array(); @@ -885,13 +887,13 @@ protected static function get_spacing_sizes( $spacing_scale ) { for ( $x = 1; $x <= $spacing_scale['steps'] - 1; $x++ ) { $current_step = '+' === $spacing_scale['operator'] - ? $current_step + $spacing_scale['increment'] . $spacing_scale['units'] - : $current_step * $spacing_scale['increment'] . $spacing_scale['units']; + ? $current_step + $spacing_scale['increment'] + : $current_step * $spacing_scale['increment']; $spacing_sizes[] = array( 'name' => $x + 1, 'slug' => ( $x + 1 ) * 10, - 'size' => $current_step, + 'size' => $current_step . $spacing_scale['units'], ); } From 5835f63575cd8f7a1bdb75847fe76d4dc16b2bdd Mon Sep 17 00:00:00 2001 From: Glen Davies Date: Thu, 16 Jun 2022 12:34:01 +1200 Subject: [PATCH 20/43] Fix linting errors --- lib/compat/wordpress-6.1/class-wp-theme-json-6-1.php | 2 +- .../class-wp-rest-block-editor-settings-controller.php | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) 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 f59e98deb4ebaf..ee6146636bd0ec 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 @@ -866,7 +866,7 @@ protected static function get_spacing_sizes( $spacing_scale ) { || ! is_numeric( $spacing_scale['firstStep'] ) || ( '+' !== $spacing_scale['operator'] && '*' !== $spacing_scale['operator'] ) ) { if ( ! empty( $spacing_scale ) ) { - trigger_error( __( 'Some of the theme.json settings.spacing.spacingScale values are invalid' ), E_USER_NOTICE ); + trigger_error( __( 'Some of the theme.json settings.spacing.spacingScale values are invalid', 'gutenberg' ), E_USER_NOTICE ); } return null; } diff --git a/lib/experimental/class-wp-rest-block-editor-settings-controller.php b/lib/experimental/class-wp-rest-block-editor-settings-controller.php index 34a6debf30bce4..d9b726f1158da2 100644 --- a/lib/experimental/class-wp-rest-block-editor-settings-controller.php +++ b/lib/experimental/class-wp-rest-block-editor-settings-controller.php @@ -275,12 +275,12 @@ public function get_item_schema() { 'type' => 'array', 'context' => array( 'post-editor', 'site-editor', 'widgets-editor' ), ), - 'spacingSizes' => array( + 'spacingSizes' => array( 'description' => __( 'Active theme spacing sizes.', 'gutenberg' ), 'type' => 'array', 'context' => array( 'post-editor', 'site-editor', 'widgets-editor' ), ), - 'spacingScale' => array( + 'spacingScale' => array( 'description' => __( 'Active theme spacing scale.', 'gutenberg' ), 'type' => 'array', 'context' => array( 'post-editor', 'site-editor', 'widgets-editor' ), From 6a96788835f9837edd61a92dba0b98b2a12a6886 Mon Sep 17 00:00:00 2001 From: Glen Davies Date: Thu, 16 Jun 2022 12:43:54 +1200 Subject: [PATCH 21/43] Update docs --- docs/reference-guides/theme-json-reference/theme-json-living.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/reference-guides/theme-json-reference/theme-json-living.md b/docs/reference-guides/theme-json-reference/theme-json-living.md index 4416bd276dc853..57fac0b7e95432 100644 --- a/docs/reference-guides/theme-json-reference/theme-json-living.md +++ b/docs/reference-guides/theme-json-reference/theme-json-living.md @@ -85,6 +85,7 @@ Settings related to spacing. | units | array | px,em,rem,vh,vw,% | | | customSpacingSize | boolean | true | | | spacingSizes | array | | name, size, slug | +| spacingScale | object | | | --- From 65b6fbcf1c675ad3d3e19876868ac5519017ef16 Mon Sep 17 00:00:00 2001 From: Glen Davies Date: Thu, 16 Jun 2022 12:57:15 +1200 Subject: [PATCH 22/43] Remove note about generation of classname for now --- schemas/json/theme.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/schemas/json/theme.json b/schemas/json/theme.json index 96b36728d8b182..4a0bfb678efe20 100644 --- a/schemas/json/theme.json +++ b/schemas/json/theme.json @@ -233,7 +233,7 @@ "default": true }, "spacingSizes": { - "description": "Space size presets for the space size selector.\nGenerates a single class (`.has-{slug}-space-size`) and custom property (`--wp--preset--space-size--{slug}`) per preset value.", + "description": "Space size presets for the space size selector.\nGenerates a custom property (`--wp--preset--space-size--{slug}`) per preset value.", "type": "array", "items": { "type": "object", @@ -255,7 +255,7 @@ } }, "spacingScale": { - "description": "Space size presets for the space size selector.\nGenerates a single class (`.has-{slug}-space-size`) and custom property (`--wp--preset--space-size--{slug}`) per preset value.", + "description": "Space size presets for the space size selector.\nGenerates a custom property (`--wp--preset--space-size--{slug}`) per preset value.", "type": "object", "properties": { "operator": { From 68ce764c93fad4f84c06cb47a606966b133dee7b Mon Sep 17 00:00:00 2001 From: Glen Davies Date: Mon, 20 Jun 2022 13:00:03 +1200 Subject: [PATCH 23/43] Fix theme.json schema issues --- schemas/json/theme.json | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/schemas/json/theme.json b/schemas/json/theme.json index 4a0bfb678efe20..cbd2483472989e 100644 --- a/schemas/json/theme.json +++ b/schemas/json/theme.json @@ -263,20 +263,28 @@ "type": "string" }, "increment": { - "description": "The amouunt to increment each step by", + "description": "The amount to increment each step by.", "type": "number" }, "steps": { - "description": "Number of steps to generate in scale", - "type": "number" + "description": "Number of steps to generate in scale.", + "type": "integer" }, "firstStep": { - "description": "The value to starr scale from", + "description": "The value to start scale from.", "type": "number" }, "units": { - "description": "Units that the scale uses, eg. rem, em, px", - "type": "string" + "description": "Units that the scale uses, eg. rem, em, px.", + "type": "string", + "enum": [ + "px", + "em", + "rem", + "vh", + "vw", + "%" + ] } }, "additionalProperties": false From 1295196de5244a9f598c525e5af0635b78282242 Mon Sep 17 00:00:00 2001 From: Glen Davies Date: Mon, 20 Jun 2022 13:02:37 +1200 Subject: [PATCH 24/43] One more theme.json change --- schemas/json/theme.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/schemas/json/theme.json b/schemas/json/theme.json index cbd2483472989e..706e3868273299 100644 --- a/schemas/json/theme.json +++ b/schemas/json/theme.json @@ -260,7 +260,8 @@ "properties": { "operator": { "description": "With + or * depending on whether scale is generated by increment or mulitplier.", - "type": "string" + "type": "string", + "enum": [ "+", "*" ] }, "increment": { "description": "The amount to increment each step by.", From b5eb496caedbb5f537a87bb9a0d52b88a62e84ac Mon Sep 17 00:00:00 2001 From: Glen Davies Date: Wed, 22 Jun 2022 14:39:19 +1200 Subject: [PATCH 25/43] Switch to a wider default scale using a 1.5 multiplier and t-shirt sizes --- .../wordpress-6.1/class-wp-theme-json-6-1.php | 76 ++++++++++++++----- lib/compat/wordpress-6.1/theme.json | 8 +- schemas/json/theme.json | 4 +- 3 files changed, 62 insertions(+), 26 deletions(-) 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 ee6146636bd0ec..4e61b21dc55d24 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 @@ -856,14 +856,15 @@ protected static function get_property_value( $styles, $path, $theme_json = null * @return array An array of spacing preset sizes. */ protected static function get_spacing_sizes( $spacing_scale ) { - if ( ! isset( $spacing_scale['firstStep'] ) + if ( ! is_numeric( $spacing_scale['steps'] ) + || ! $spacing_scale['steps'] > 0 + || ! isset( $spacing_scale['mediumStep'] ) || ! isset( $spacing_scale['units'] ) || ! isset( $spacing_scale['operator'] ) || ! isset( $spacing_scale['increment'] ) || ! isset( $spacing_scale['steps'] ) || ! is_numeric( $spacing_scale['increment'] ) - || ! is_numeric( $spacing_scale['steps'] ) - || ! is_numeric( $spacing_scale['firstStep'] ) + || ! is_numeric( $spacing_scale['mediumStep'] ) || ( '+' !== $spacing_scale['operator'] && '*' !== $spacing_scale['operator'] ) ) { if ( ! empty( $spacing_scale ) ) { trigger_error( __( 'Some of the theme.json settings.spacing.spacingScale values are invalid', 'gutenberg' ), E_USER_NOTICE ); @@ -871,33 +872,68 @@ protected static function get_spacing_sizes( $spacing_scale ) { return null; } - $spacing_sizes = array(); - $spacing_sizes[] = array( - 'name' => 0, - 'slug' => 0, - 'size' => 0, + $current_step = $spacing_scale['mediumStep']; + $steps_mid_point = round( ( ( $spacing_scale['steps'] ) / 2 ), 0 ); + + $x_count = null; + $below_sizes = array(); + + for ( $x = $steps_mid_point - 1; $x > 0; $x-- ) { + $current_step = '+' === $spacing_scale['operator'] + ? $current_step - $spacing_scale['increment'] + : $current_step / $spacing_scale['increment']; + + $below_sizes[] = array( + 'name' => $x === $steps_mid_point - 1 ? __( 'Small' ) : strval( $x_count ) . __( 'X-Small', 'gutenberg' ), + 'slug' => $x === $steps_mid_point - 1 ? 'small' : strval( $x_count ) . 'x-small', + 'size' => round( $current_step, 2 ) . $spacing_scale['units'], + ); + if ( $x === $steps_mid_point - 2 ) { + $x_count = 2; + } + if ( $x < $steps_mid_point - 2 ) { + $x_count++; + } + } + + $below_sizes = array_reverse( $below_sizes ); + array_unshift( + $below_sizes, + array( + 'name' => 0, + 'slug' => 0, + 'size' => 0, + ) ); - $spacing_sizes[] = array( - 'name' => 1, - 'slug' => 10, - 'size' => $spacing_scale['firstStep'] . $spacing_scale['units'], + $below_sizes[] = array( + 'name' => __( 'Medium', 'gutenberg' ), + 'slug' => 'medium', + 'size' => $spacing_scale['mediumStep'] . $spacing_scale['units'], ); - $current_step = $spacing_scale['firstStep']; - - for ( $x = 1; $x <= $spacing_scale['steps'] - 1; $x++ ) { + $current_step = $spacing_scale['mediumStep']; + $x_count = null; + $above_sizes = array(); + for ( $x = $steps_mid_point + 1; $x < $spacing_scale['steps']; $x++ ) { $current_step = '+' === $spacing_scale['operator'] ? $current_step + $spacing_scale['increment'] : $current_step * $spacing_scale['increment']; - $spacing_sizes[] = array( - 'name' => $x + 1, - 'slug' => ( $x + 1 ) * 10, - 'size' => $current_step . $spacing_scale['units'], + $above_sizes[] = array( + 'name' => $x === $steps_mid_point + 1 ? __( 'Large' ) : strval( $x_count ) . __( 'X-Large', 'gutenberg' ), + 'slug' => $x === $steps_mid_point + 1 ? 'large' : strval( $x_count ) . 'x-large', + 'size' => round( $current_step, 2 ) . $spacing_scale['units'], ); + + if ( $x === $steps_mid_point + 2 ) { + $x_count = 2; + } + if ( $x > $steps_mid_point + 2 ) { + $x_count++; + } } - return $spacing_sizes; + return array_merge( $below_sizes, $above_sizes ); } /** diff --git a/lib/compat/wordpress-6.1/theme.json b/lib/compat/wordpress-6.1/theme.json index 0e2201eff290a3..76bfe0827dc429 100644 --- a/lib/compat/wordpress-6.1/theme.json +++ b/lib/compat/wordpress-6.1/theme.json @@ -192,10 +192,10 @@ "customSpacingSizes": true, "units": [ "px", "em", "rem", "vh", "vw", "%" ], "spacingScale": { - "operator": "+", - "increment": 0.5, - "steps": 5, - "firstStep": 0.5, + "operator": "*", + "increment": 1.5, + "steps": 10, + "mediumStep": 1.5, "units": "rem" } }, diff --git a/schemas/json/theme.json b/schemas/json/theme.json index 706e3868273299..0853fd68326f49 100644 --- a/schemas/json/theme.json +++ b/schemas/json/theme.json @@ -271,8 +271,8 @@ "description": "Number of steps to generate in scale.", "type": "integer" }, - "firstStep": { - "description": "The value to start scale from.", + "mediumStep": { + "description": "The value to medium setting in the scale.", "type": "number" }, "units": { From 9c8614223e7ef79f927ef681668f795d23921212 Mon Sep 17 00:00:00 2001 From: Glen Davies Date: Wed, 22 Jun 2022 15:26:52 +1200 Subject: [PATCH 26/43] Mover generation of spacing presets until after the theme.json files are merged --- .../wordpress-6.1/class-wp-theme-json-6-1.php | 16 ++++------------ .../class-wp-theme-json-resolver-gutenberg.php | 2 ++ 2 files changed, 6 insertions(+), 12 deletions(-) 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 4e61b21dc55d24..1ff1251dc95218 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 @@ -851,11 +851,10 @@ protected static function get_property_value( $styles, $path, $theme_json = null /** * Transform the spacing scale values into an array of spacing scale presets. - * - * @param array $spacing_scale scale Array of values used to create the scale of spacing presets. - * @return array An array of spacing preset sizes. */ - protected static function get_spacing_sizes( $spacing_scale ) { + public function get_spacing_sizes() { + $spacing_scale = _wp_array_get( $this->theme_json, array( 'settings', 'spacing', 'spacingScale' ), array() ); + if ( ! is_numeric( $spacing_scale['steps'] ) || ! $spacing_scale['steps'] > 0 || ! isset( $spacing_scale['mediumStep'] ) @@ -933,7 +932,7 @@ protected static function get_spacing_sizes( $spacing_scale ) { } } - return array_merge( $below_sizes, $above_sizes ); + _wp_array_set( $this->theme_json, array( 'settings', 'spacing', 'spacingSizes', 'default' ), array_merge( $below_sizes, $above_sizes ) ); } /** @@ -1015,13 +1014,6 @@ public function merge( $incoming ) { } } } - - // Generate the default spacing sizes presets. - $spacing_size_defaults = static::get_spacing_sizes( _wp_array_get( $this->theme_json, array( 'settings', 'spacing', 'spacingScale' ), array() ) ); - if ( $spacing_size_defaults ) { - _wp_array_set( $this->theme_json, array( 'settings', 'spacing', 'spacingSizes', 'default' ), $spacing_size_defaults ); - } } - } } diff --git a/lib/experimental/class-wp-theme-json-resolver-gutenberg.php b/lib/experimental/class-wp-theme-json-resolver-gutenberg.php index 7f7d4a3ace2f19..5621d1ced56c31 100644 --- a/lib/experimental/class-wp-theme-json-resolver-gutenberg.php +++ b/lib/experimental/class-wp-theme-json-resolver-gutenberg.php @@ -173,6 +173,8 @@ public static function get_merged_data( $origin = 'custom' ) { if ( 'custom' === $origin ) { $result->merge( static::get_user_data() ); } + // Generate the default spacing sizes presets. + $result->get_spacing_sizes(); return $result; } From 4d3b97e5f054dfe2f49da7e131b48667cd92f019 Mon Sep 17 00:00:00 2001 From: Glen Davies Date: Wed, 22 Jun 2022 16:51:42 +1200 Subject: [PATCH 27/43] Switch back to numeric slugs --- lib/compat/wordpress-6.1/class-wp-theme-json-6-1.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) 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 1ff1251dc95218..511437ea038a1e 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 @@ -884,7 +884,7 @@ public function get_spacing_sizes() { $below_sizes[] = array( 'name' => $x === $steps_mid_point - 1 ? __( 'Small' ) : strval( $x_count ) . __( 'X-Small', 'gutenberg' ), - 'slug' => $x === $steps_mid_point - 1 ? 'small' : strval( $x_count ) . 'x-small', + 'slug' => $x * 10, 'size' => round( $current_step, 2 ) . $spacing_scale['units'], ); if ( $x === $steps_mid_point - 2 ) { @@ -906,7 +906,7 @@ public function get_spacing_sizes() { ); $below_sizes[] = array( 'name' => __( 'Medium', 'gutenberg' ), - 'slug' => 'medium', + 'slug' => 50, 'size' => $spacing_scale['mediumStep'] . $spacing_scale['units'], ); @@ -920,7 +920,7 @@ public function get_spacing_sizes() { $above_sizes[] = array( 'name' => $x === $steps_mid_point + 1 ? __( 'Large' ) : strval( $x_count ) . __( 'X-Large', 'gutenberg' ), - 'slug' => $x === $steps_mid_point + 1 ? 'large' : strval( $x_count ) . 'x-large', + 'slug' => $x * 10, 'size' => round( $current_step, 2 ) . $spacing_scale['units'], ); From b4c556011587535151048f9fc2b52cc7e997c6ad Mon Sep 17 00:00:00 2001 From: Glen Davies Date: Thu, 23 Jun 2022 11:41:19 +1200 Subject: [PATCH 28/43] Reduce length of preset var --- lib/compat/wordpress-6.1/class-wp-theme-json-6-1.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) 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 511437ea038a1e..aa779d16d7b724 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 @@ -780,7 +780,7 @@ protected static function get_property_value( $styles, $path, $theme_json = null 'prevent_override' => false, 'use_default_names' => true, 'value_key' => 'size', - 'css_vars' => '--wp--preset--spacing-size--$slug', + 'css_vars' => '--wp--preset--spacing--$slug', 'classes' => array(), 'properties' => array( 'padding', 'margin' ), ), @@ -789,7 +789,7 @@ protected static function get_property_value( $styles, $path, $theme_json = null 'prevent_override' => false, 'use_default_names' => true, 'value_key' => 'size', - 'css_vars' => '--wp--preset--spacing-size--$slug', + 'css_vars' => '--wp--preset--spacing--$slug', 'classes' => array(), 'properties' => array( 'padding', 'margin' ), ), From 93354cd091e60dc3a2343950457230970ceb5271 Mon Sep 17 00:00:00 2001 From: Glen Davies Date: Thu, 23 Jun 2022 17:32:29 +1200 Subject: [PATCH 29/43] Translation fix --- lib/compat/wordpress-6.1/class-wp-theme-json-6-1.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) 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 aa779d16d7b724..973f803ee791aa 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 @@ -883,7 +883,7 @@ public function get_spacing_sizes() { : $current_step / $spacing_scale['increment']; $below_sizes[] = array( - 'name' => $x === $steps_mid_point - 1 ? __( 'Small' ) : strval( $x_count ) . __( 'X-Small', 'gutenberg' ), + 'name' => $x === $steps_mid_point - 1 ? __( 'Small', 'gutenberg' ) : strval( $x_count ) . __( 'X-Small', 'gutenberg' ), 'slug' => $x * 10, 'size' => round( $current_step, 2 ) . $spacing_scale['units'], ); @@ -919,7 +919,7 @@ public function get_spacing_sizes() { : $current_step * $spacing_scale['increment']; $above_sizes[] = array( - 'name' => $x === $steps_mid_point + 1 ? __( 'Large' ) : strval( $x_count ) . __( 'X-Large', 'gutenberg' ), + 'name' => $x === $steps_mid_point + 1 ? __( 'Large', 'gutenberg' ) : strval( $x_count ) . __( 'X-Large', 'gutenberg' ), 'slug' => $x * 10, 'size' => round( $current_step, 2 ) . $spacing_scale['units'], ); From a231237054fcf7e848faa791afa0900b7cb4e49f Mon Sep 17 00:00:00 2001 From: Glen Davies Date: Mon, 27 Jun 2022 13:48:49 +1200 Subject: [PATCH 30/43] Remove 0 step and improve translation of tshirt size names --- .../wordpress-6.1/class-wp-theme-json-6-1.php | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) 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 973f803ee791aa..fd79d913bad116 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 @@ -883,7 +883,8 @@ public function get_spacing_sizes() { : $current_step / $spacing_scale['increment']; $below_sizes[] = array( - 'name' => $x === $steps_mid_point - 1 ? __( 'Small', 'gutenberg' ) : strval( $x_count ) . __( 'X-Small', 'gutenberg' ), + /* translators: %s: Muliple of t-shirt sizing, eg. 2X-Small */ + 'name' => $x === $steps_mid_point - 1 ? __( 'Small', 'gutenberg' ) : sprintf( __( '%sX-Small', 'gutenberg' ), strval( $x_count ) ), 'slug' => $x * 10, 'size' => round( $current_step, 2 ) . $spacing_scale['units'], ); @@ -896,14 +897,7 @@ public function get_spacing_sizes() { } $below_sizes = array_reverse( $below_sizes ); - array_unshift( - $below_sizes, - array( - 'name' => 0, - 'slug' => 0, - 'size' => 0, - ) - ); + $below_sizes[] = array( 'name' => __( 'Medium', 'gutenberg' ), 'slug' => 50, @@ -919,7 +913,8 @@ public function get_spacing_sizes() { : $current_step * $spacing_scale['increment']; $above_sizes[] = array( - 'name' => $x === $steps_mid_point + 1 ? __( 'Large', 'gutenberg' ) : strval( $x_count ) . __( 'X-Large', 'gutenberg' ), + /* translators: %s: Muliple of t-shirt sizing, eg. 2X-Large */ + 'name' => $x === $steps_mid_point + 1 ? __( 'Large', 'gutenberg' ) : sprintf( __( '%sX-Large', 'gutenberg' ), strval( $x_count ) ), 'slug' => $x * 10, 'size' => round( $current_step, 2 ) . $spacing_scale['units'], ); From d398be22c334875a862b5522f1ea1fdedbb6ca57 Mon Sep 17 00:00:00 2001 From: Glen Davies Date: Tue, 28 Jun 2022 16:54:16 +1200 Subject: [PATCH 31/43] Fix issue with even step numbers, and steps > 10 --- .../wordpress-6.1/class-wp-theme-json-6-1.php | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) 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 fd79d913bad116..fe91a2f180ed36 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 @@ -876,8 +876,9 @@ public function get_spacing_sizes() { $x_count = null; $below_sizes = array(); + $slug = 40; - for ( $x = $steps_mid_point - 1; $x > 0; $x-- ) { + for ( $x = $steps_mid_point - 1; $slug > 0; $x-- ) { $current_step = '+' === $spacing_scale['operator'] ? $current_step - $spacing_scale['increment'] : $current_step / $spacing_scale['increment']; @@ -885,7 +886,7 @@ public function get_spacing_sizes() { $below_sizes[] = array( /* translators: %s: Muliple of t-shirt sizing, eg. 2X-Small */ 'name' => $x === $steps_mid_point - 1 ? __( 'Small', 'gutenberg' ) : sprintf( __( '%sX-Small', 'gutenberg' ), strval( $x_count ) ), - 'slug' => $x * 10, + 'slug' => $slug, 'size' => round( $current_step, 2 ) . $spacing_scale['units'], ); if ( $x === $steps_mid_point - 2 ) { @@ -894,6 +895,7 @@ public function get_spacing_sizes() { if ( $x < $steps_mid_point - 2 ) { $x_count++; } + $slug = $slug - 10; } $below_sizes = array_reverse( $below_sizes ); @@ -907,7 +909,9 @@ public function get_spacing_sizes() { $current_step = $spacing_scale['mediumStep']; $x_count = null; $above_sizes = array(); - for ( $x = $steps_mid_point + 1; $x < $spacing_scale['steps']; $x++ ) { + $slug = 60; + $steps_above = $spacing_scale['steps'] <= 10 ? $steps_mid_point + 1 : 6; + for ( $x = $steps_above; $x <= $spacing_scale['steps']; $x++ ) { $current_step = '+' === $spacing_scale['operator'] ? $current_step + $spacing_scale['increment'] : $current_step * $spacing_scale['increment']; @@ -915,7 +919,7 @@ public function get_spacing_sizes() { $above_sizes[] = array( /* translators: %s: Muliple of t-shirt sizing, eg. 2X-Large */ 'name' => $x === $steps_mid_point + 1 ? __( 'Large', 'gutenberg' ) : sprintf( __( '%sX-Large', 'gutenberg' ), strval( $x_count ) ), - 'slug' => $x * 10, + 'slug' => $slug, 'size' => round( $current_step, 2 ) . $spacing_scale['units'], ); @@ -925,6 +929,7 @@ public function get_spacing_sizes() { if ( $x > $steps_mid_point + 2 ) { $x_count++; } + $slug = $slug + 10; } _wp_array_set( $this->theme_json, array( 'settings', 'spacing', 'spacingSizes', 'default' ), array_merge( $below_sizes, $above_sizes ) ); From 319d2a8d95fc55e5b5977edb7adf3d39dea70703 Mon Sep 17 00:00:00 2001 From: Glen Davies Date: Tue, 28 Jun 2022 17:12:33 +1200 Subject: [PATCH 32/43] fix linting error --- lib/compat/wordpress-6.1/class-wp-theme-json-6-1.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 fe91a2f180ed36..f77e880e7f244e 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 @@ -876,7 +876,7 @@ public function get_spacing_sizes() { $x_count = null; $below_sizes = array(); - $slug = 40; + $slug = 40; for ( $x = $steps_mid_point - 1; $slug > 0; $x-- ) { $current_step = '+' === $spacing_scale['operator'] From 8518b26d299c4802505daff1a2a614a138336086 Mon Sep 17 00:00:00 2001 From: Glen Davies Date: Wed, 29 Jun 2022 12:15:29 +1200 Subject: [PATCH 33/43] Account for a multiplier of < 1, in which case it needs to act like a divisor instead --- .../wordpress-6.1/class-wp-theme-json-6-1.php | 26 ++++++++++++------- 1 file changed, 16 insertions(+), 10 deletions(-) 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 f77e880e7f244e..e09eb2869e3c39 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 @@ -871,18 +871,23 @@ public function get_spacing_sizes() { return null; } + $steps = $spacing_scale['steps'] > 1 ? $spacing_scale['steps'] : 2; $current_step = $spacing_scale['mediumStep']; - $steps_mid_point = round( ( ( $spacing_scale['steps'] ) / 2 ), 0 ); + $steps_mid_point = round( ( ( $steps ) / 2 ), 0 ); + $x_count = null; + $below_sizes = array(); + $slug = 40; + $remainder = 0; - $x_count = null; - $below_sizes = array(); - $slug = 40; - - for ( $x = $steps_mid_point - 1; $slug > 0; $x-- ) { + for ( $x = $steps_mid_point - 1; $slug > 0 && $x > 0; $x-- ) { $current_step = '+' === $spacing_scale['operator'] ? $current_step - $spacing_scale['increment'] - : $current_step / $spacing_scale['increment']; + : ( $spacing_scale['increment'] > 1 ? $current_step / $spacing_scale['increment'] : $current_step * $spacing_scale['increment'] ); + if ( $current_step < 0 ) { + $remainder = $x; + break; + } $below_sizes[] = array( /* translators: %s: Muliple of t-shirt sizing, eg. 2X-Small */ 'name' => $x === $steps_mid_point - 1 ? __( 'Small', 'gutenberg' ) : sprintf( __( '%sX-Small', 'gutenberg' ), strval( $x_count ) ), @@ -910,11 +915,12 @@ public function get_spacing_sizes() { $x_count = null; $above_sizes = array(); $slug = 60; - $steps_above = $spacing_scale['steps'] <= 10 ? $steps_mid_point + 1 : 6; - for ( $x = $steps_above; $x <= $spacing_scale['steps']; $x++ ) { + $steps_above = $steps_mid_point + 1 - $remainder; + + for ( $x = $steps_above; $x <= $steps; $x++ ) { $current_step = '+' === $spacing_scale['operator'] ? $current_step + $spacing_scale['increment'] - : $current_step * $spacing_scale['increment']; + : ( $spacing_scale['increment'] >= 1 ? $current_step * $spacing_scale['increment'] : $current_step / $spacing_scale['increment'] ); $above_sizes[] = array( /* translators: %s: Muliple of t-shirt sizing, eg. 2X-Large */ From 357596c7a502228124d5736668a6a0fe64979ea5 Mon Sep 17 00:00:00 2001 From: Glen Davies Date: Wed, 29 Jun 2022 14:01:15 +1200 Subject: [PATCH 34/43] Allow single step as it might be easier than explaining that a single step scale defaults to 2 steps because what it is point in a single step scale --- lib/compat/wordpress-6.1/class-wp-theme-json-6-1.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) 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 e09eb2869e3c39..0bb530da5b9dfa 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 @@ -871,15 +871,15 @@ public function get_spacing_sizes() { return null; } - $steps = $spacing_scale['steps'] > 1 ? $spacing_scale['steps'] : 2; + //$steps = $spacing_scale['steps'] > 1 ? $spacing_scale['steps'] : 2; $current_step = $spacing_scale['mediumStep']; - $steps_mid_point = round( ( ( $steps ) / 2 ), 0 ); + $steps_mid_point = round( ( ( $spacing_scale['steps'] ) / 2 ), 0 ); $x_count = null; $below_sizes = array(); $slug = 40; $remainder = 0; - for ( $x = $steps_mid_point - 1; $slug > 0 && $x > 0; $x-- ) { + for ( $x = $steps_mid_point - 1; $spacing_scale['steps'] > 1 && $slug > 0 && $x > 0; $x-- ) { $current_step = '+' === $spacing_scale['operator'] ? $current_step - $spacing_scale['increment'] : ( $spacing_scale['increment'] > 1 ? $current_step / $spacing_scale['increment'] : $current_step * $spacing_scale['increment'] ); @@ -917,7 +917,7 @@ public function get_spacing_sizes() { $slug = 60; $steps_above = $steps_mid_point + 1 - $remainder; - for ( $x = $steps_above; $x <= $steps; $x++ ) { + for ( $x = $steps_above; $spacing_scale['steps'] > 1 && $x <= $spacing_scale['steps']; $x++ ) { $current_step = '+' === $spacing_scale['operator'] ? $current_step + $spacing_scale['increment'] : ( $spacing_scale['increment'] >= 1 ? $current_step * $spacing_scale['increment'] : $current_step / $spacing_scale['increment'] ); From 97af3a39556085274fc836dc7bf268eb647153c1 Mon Sep 17 00:00:00 2001 From: Glen Davies Date: Wed, 29 Jun 2022 14:36:50 +1200 Subject: [PATCH 35/43] Add initial tests --- phpunit/class-wp-theme-json-test.php | 127 +++++++++++++++++++++++++++ 1 file changed, 127 insertions(+) diff --git a/phpunit/class-wp-theme-json-test.php b/phpunit/class-wp-theme-json-test.php index ed5b867e775345..82af8c60a4db0a 100644 --- a/phpunit/class-wp-theme-json-test.php +++ b/phpunit/class-wp-theme-json-test.php @@ -2936,4 +2936,131 @@ 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; }'; $this->assertEquals( $expected, $theme_json->get_stylesheet() ); } + + /** + * Tests generating the spacing presets array based on the spacing scale provided. + * + * @dataProvider data_generate_spacing_scale_fixtures + */ + function test_get_spacing_sizes( $spacing_scale, $expected_output ) { + $theme_json = new WP_Theme_JSON_Gutenberg( + array( + 'version' => 2, + 'settings' => array( + 'spacing' => array( + 'spacingScale' => $spacing_scale, + ), + ), + ) + ); + + $theme_json->get_spacing_sizes(); + $this->assertSame( $expected_output, _wp_array_get( $theme_json->get_raw_data(), array( 'settings', 'spacing', 'spacingSizes', 'default' ) ) ); + } + + /** + * Data provider for spacing scale tests. + * + * @return array + */ + function data_generate_spacing_scale_fixtures() { + return array( + 'empty_spacing_scale' => array( + 'spacing_scale' => array(), + 'expected_output' => null, + ), + + 'invalid_spacing_scale_values_missing_operator' => array( + 'spacingScale' => array( + 'operator' => '', + 'increment' => 1.5, + 'steps' => 1, + 'mediumStep' => 4, + 'units' => 'rem', + ), + 'expected_output' => null, + ), + + 'invalid_spacing_scale_values_non_numeric_increment' => array( + 'spacingScale' => array( + 'operator' => '+', + 'increment' => 'add two to previous value', + 'steps' => 1, + 'mediumStep' => 4, + 'units' => 'rem', + ), + 'expected_output' => null, + ), + + 'invalid_spacing_scale_values_non_numeric_steps' => array( + 'spacingScale' => array( + 'operator' => '+', + 'increment' => 1.5, + 'steps' => 'spiral staircase preferred', + 'mediumStep' => 4, + 'units' => 'rem', + ), + 'expected_output' => null, + ), + + 'invalid_spacing_scale_values_non_numeric_medium_step' => array( + 'spacingScale' => array( + 'operator' => '+', + 'increment' => 1.5, + 'steps' => 5, + 'mediumStep' => 'That which is just right', + 'units' => 'rem', + ), + 'expected_output' => null, + ), + + 'invalid_spacing_scale_values_missing_units' => array( + 'spacingScale' => array( + 'operator' => '+', + 'increment' => 1.5, + 'steps' => 5, + 'mediumStep' => 4, + ), + 'expected_output' => null, + ), + + 'one_step_spacing_scale' => array( + 'spacingScale' => array( + 'operator' => '+', + 'increment' => 1.5, + 'steps' => 1, + 'mediumStep' => 4, + 'units' => 'rem', + ), + 'expected_output' => array( + array( + 'name' => 'Medium', + 'slug' => 50, + 'size' => '4rem', + ), + ), + ), + 'two_step_spacing_scale' => array( + 'spacingScale' => array( + 'operator' => '+', + 'increment' => 1.5, + 'steps' => 2, + 'mediumStep' => 4, + 'units' => 'rem', + ), + 'expected_output' => array( + array( + 'name' => 'Medium', + 'slug' => 50, + 'size' => '4rem', + ), + array( + 'name' => 'Large', + 'slug' => 60, + 'size' => '5.5rem', + ), + ), + ), + ); + } } From 3b173ba7fda7fe5de5a601715e782b4d5e0649ae Mon Sep 17 00:00:00 2001 From: Glen Davies Date: Wed, 29 Jun 2022 15:47:37 +1200 Subject: [PATCH 36/43] Add more tests and fix issues identified by tests --- .../wordpress-6.1/class-wp-theme-json-6-1.php | 13 +- phpunit/class-wp-theme-json-test.php | 173 +++++++++++++++++- 2 files changed, 178 insertions(+), 8 deletions(-) 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 0bb530da5b9dfa..73c6b6406cf295 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 @@ -871,7 +871,6 @@ public function get_spacing_sizes() { return null; } - //$steps = $spacing_scale['steps'] > 1 ? $spacing_scale['steps'] : 2; $current_step = $spacing_scale['mediumStep']; $steps_mid_point = round( ( ( $spacing_scale['steps'] ) / 2 ), 0 ); $x_count = null; @@ -884,7 +883,7 @@ public function get_spacing_sizes() { ? $current_step - $spacing_scale['increment'] : ( $spacing_scale['increment'] > 1 ? $current_step / $spacing_scale['increment'] : $current_step * $spacing_scale['increment'] ); - if ( $current_step < 0 ) { + if ( $current_step <= 0 ) { $remainder = $x; break; } @@ -915,24 +914,24 @@ public function get_spacing_sizes() { $x_count = null; $above_sizes = array(); $slug = 60; - $steps_above = $steps_mid_point + 1 - $remainder; + $steps_above = ( $spacing_scale['steps'] - $steps_mid_point ) + $remainder; - for ( $x = $steps_above; $spacing_scale['steps'] > 1 && $x <= $spacing_scale['steps']; $x++ ) { + for ( $x = 0; $x < $steps_above; $x++ ) { $current_step = '+' === $spacing_scale['operator'] ? $current_step + $spacing_scale['increment'] : ( $spacing_scale['increment'] >= 1 ? $current_step * $spacing_scale['increment'] : $current_step / $spacing_scale['increment'] ); $above_sizes[] = array( /* translators: %s: Muliple of t-shirt sizing, eg. 2X-Large */ - 'name' => $x === $steps_mid_point + 1 ? __( 'Large', 'gutenberg' ) : sprintf( __( '%sX-Large', 'gutenberg' ), strval( $x_count ) ), + 'name' => $x === 0 ? __( 'Large', 'gutenberg' ) : sprintf( __( '%sX-Large', 'gutenberg' ), strval( $x_count ) ), 'slug' => $slug, 'size' => round( $current_step, 2 ) . $spacing_scale['units'], ); - if ( $x === $steps_mid_point + 2 ) { + if ( 1 === $x ) { $x_count = 2; } - if ( $x > $steps_mid_point + 2 ) { + if ( $x > 1 ) { $x_count++; } $slug = $slug + 10; diff --git a/phpunit/class-wp-theme-json-test.php b/phpunit/class-wp-theme-json-test.php index 82af8c60a4db0a..ae8fc5af9f6115 100644 --- a/phpunit/class-wp-theme-json-test.php +++ b/phpunit/class-wp-theme-json-test.php @@ -3040,7 +3040,8 @@ function data_generate_spacing_scale_fixtures() { ), ), ), - 'two_step_spacing_scale' => array( + + 'two_step_spacing_scale_should_add_step_above_medium' => array( 'spacingScale' => array( 'operator' => '+', 'increment' => 1.5, @@ -3061,6 +3062,176 @@ function data_generate_spacing_scale_fixtures() { ), ), ), + + 'three_step_spacing_scale_should_add_step_above_and_below_medium' => array( + 'spacingScale' => array( + 'operator' => '+', + 'increment' => 1.5, + 'steps' => 3, + 'mediumStep' => 4, + 'units' => 'rem', + ), + 'expected_output' => array( + array( + 'name' => 'Small', + 'slug' => 40, + 'size' => '2.5rem', + ), + array( + 'name' => 'Medium', + 'slug' => 50, + 'size' => '4rem', + ), + array( + 'name' => 'Large', + 'slug' => 60, + 'size' => '5.5rem', + ), + ), + ), + + 'even_step_spacing_scale_steps_should_add_extra_step_above_medium' => array( + 'spacingScale' => array( + 'operator' => '+', + 'increment' => 1.5, + 'steps' => 4, + 'mediumStep' => 4, + 'units' => 'rem', + ), + 'expected_output' => array( + array( + 'name' => 'Small', + 'slug' => 40, + 'size' => '2.5rem', + ), + array( + 'name' => 'Medium', + 'slug' => 50, + 'size' => '4rem', + ), + array( + 'name' => 'Large', + 'slug' => 60, + 'size' => '5.5rem', + ), + array( + 'name' => 'X-Large', + 'slug' => 70, + 'size' => '7rem', + ), + ), + ), + + 'if_bottom_end_will_go_below_zero_should_add_extra_steps_above_medium_instead' => array( + 'spacingScale' => array( + 'operator' => '+', + 'increment' => 2.5, + 'steps' => 5, + 'mediumStep' => 5, + 'units' => 'rem', + ), + 'expected_output' => array( + array( + 'name' => 'Small', + 'slug' => 40, + 'size' => '2.5rem', + ), + array( + 'name' => 'Medium', + 'slug' => 50, + 'size' => '5rem', + ), + array( + 'name' => 'Large', + 'slug' => 60, + 'size' => '7.5rem', + ), + array( + 'name' => 'X-Large', + 'slug' => 70, + 'size' => '10rem', + ), + array( + 'name' => '2X-Large', + 'slug' => 80, + 'size' => '12.5rem', + ), + ), + ), + + 'multiplier_should_correctly_calculate_above_and_below_medium' => array( + 'spacingScale' => array( + 'operator' => '*', + 'increment' => 1.5, + 'steps' => 5, + 'mediumStep' => 1.5, + 'units' => 'rem', + ), + 'expected_output' => array( + array( + 'name' => 'X-Small', + 'slug' => 30, + 'size' => '0.67rem', + ), + array( + 'name' => 'Small', + 'slug' => 40, + 'size' => '1rem', + ), + array( + 'name' => 'Medium', + 'slug' => 50, + 'size' => '1.5rem', + ), + array( + 'name' => 'Large', + 'slug' => 60, + 'size' => '2.25rem', + ), + array( + 'name' => 'X-Large', + 'slug' => 70, + 'size' => '3.38rem', + ), + ), + ), + + 'increment_<_1_combined+with_*_operator_should_act_as_divisor_to_calculate_above_and_below_medium' => array( + 'spacingScale' => array( + 'operator' => '*', + 'increment' => 0.25, + 'steps' => 5, + 'mediumStep' => 1.5, + 'units' => 'rem', + ), + 'expected_output' => array( + array( + 'name' => 'X-Small', + 'slug' => 30, + 'size' => '0.09rem', + ), + array( + 'name' => 'Small', + 'slug' => 40, + 'size' => '0.38rem', + ), + array( + 'name' => 'Medium', + 'slug' => 50, + 'size' => '1.5rem', + ), + array( + 'name' => 'Large', + 'slug' => 60, + 'size' => '6rem', + ), + array( + 'name' => 'X-Large', + 'slug' => 70, + 'size' => '24rem', + ), + ), + ), ); } } From 5b227656e25b8df4d78ff2d97bdafcf6387801ba Mon Sep 17 00:00:00 2001 From: Glen Davies Date: Wed, 29 Jun 2022 15:52:25 +1200 Subject: [PATCH 37/43] Fix test fixture name --- phpunit/class-wp-theme-json-test.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/phpunit/class-wp-theme-json-test.php b/phpunit/class-wp-theme-json-test.php index ae8fc5af9f6115..0c0f73d23cf2e6 100644 --- a/phpunit/class-wp-theme-json-test.php +++ b/phpunit/class-wp-theme-json-test.php @@ -3196,7 +3196,7 @@ function data_generate_spacing_scale_fixtures() { ), ), - 'increment_<_1_combined+with_*_operator_should_act_as_divisor_to_calculate_above_and_below_medium' => array( + 'increment_<_1_combined_with_*_operator_should_act_as_divisor_to_calculate_above_and_below_medium' => array( 'spacingScale' => array( 'operator' => '*', 'increment' => 0.25, From b87084d578d6afbbb806f031f9ed0286b191dc42 Mon Sep 17 00:00:00 2001 From: Glen Davies Date: Wed, 29 Jun 2022 16:06:24 +1200 Subject: [PATCH 38/43] Tidy up some variable naming --- .../wordpress-6.1/class-wp-theme-json-6-1.php | 30 +++++++++++-------- 1 file changed, 18 insertions(+), 12 deletions(-) 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 73c6b6406cf295..c7279ea7b8bca9 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 @@ -873,7 +873,7 @@ public function get_spacing_sizes() { $current_step = $spacing_scale['mediumStep']; $steps_mid_point = round( ( ( $spacing_scale['steps'] ) / 2 ), 0 ); - $x_count = null; + $x_small_count = null; $below_sizes = array(); $slug = 40; $remainder = 0; @@ -887,18 +887,22 @@ public function get_spacing_sizes() { $remainder = $x; break; } + $below_sizes[] = array( /* translators: %s: Muliple of t-shirt sizing, eg. 2X-Small */ - 'name' => $x === $steps_mid_point - 1 ? __( 'Small', 'gutenberg' ) : sprintf( __( '%sX-Small', 'gutenberg' ), strval( $x_count ) ), + 'name' => $x === $steps_mid_point - 1 ? __( 'Small', 'gutenberg' ) : sprintf( __( '%sX-Small', 'gutenberg' ), strval( $x_small_count ) ), 'slug' => $slug, 'size' => round( $current_step, 2 ) . $spacing_scale['units'], ); + if ( $x === $steps_mid_point - 2 ) { - $x_count = 2; + $x_small_count = 2; } + if ( $x < $steps_mid_point - 2 ) { - $x_count++; + $x_small_count++; } + $slug = $slug - 10; } @@ -910,11 +914,11 @@ public function get_spacing_sizes() { 'size' => $spacing_scale['mediumStep'] . $spacing_scale['units'], ); - $current_step = $spacing_scale['mediumStep']; - $x_count = null; - $above_sizes = array(); - $slug = 60; - $steps_above = ( $spacing_scale['steps'] - $steps_mid_point ) + $remainder; + $current_step = $spacing_scale['mediumStep']; + $x_large_count = null; + $above_sizes = array(); + $slug = 60; + $steps_above = ( $spacing_scale['steps'] - $steps_mid_point ) + $remainder; for ( $x = 0; $x < $steps_above; $x++ ) { $current_step = '+' === $spacing_scale['operator'] @@ -923,17 +927,19 @@ public function get_spacing_sizes() { $above_sizes[] = array( /* translators: %s: Muliple of t-shirt sizing, eg. 2X-Large */ - 'name' => $x === 0 ? __( 'Large', 'gutenberg' ) : sprintf( __( '%sX-Large', 'gutenberg' ), strval( $x_count ) ), + 'name' => $x === 0 ? __( 'Large', 'gutenberg' ) : sprintf( __( '%sX-Large', 'gutenberg' ), strval( $x_large_count ) ), 'slug' => $slug, 'size' => round( $current_step, 2 ) . $spacing_scale['units'], ); if ( 1 === $x ) { - $x_count = 2; + $x_large_count = 2; } + if ( $x > 1 ) { - $x_count++; + $x_large_count++; } + $slug = $slug + 10; } From 66327a1b311f7467c61c1940c8a409631599a9ec Mon Sep 17 00:00:00 2001 From: Glen Davies Date: Wed, 29 Jun 2022 16:55:50 +1200 Subject: [PATCH 39/43] Fixes from PR review --- .../wordpress-6.1/class-wp-theme-json-6-1.php | 13 ++++---- ...class-wp-theme-json-resolver-gutenberg.php | 2 +- phpunit/class-wp-theme-json-test.php | 32 +++++++++---------- schemas/json/theme.json | 4 +-- 4 files changed, 26 insertions(+), 25 deletions(-) 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 c7279ea7b8bca9..0fcfc07a93fc2d 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 @@ -852,13 +852,13 @@ protected static function get_property_value( $styles, $path, $theme_json = null /** * Transform the spacing scale values into an array of spacing scale presets. */ - public function get_spacing_sizes() { + public function set_spacing_sizes() { $spacing_scale = _wp_array_get( $this->theme_json, array( 'settings', 'spacing', 'spacingScale' ), array() ); if ( ! is_numeric( $spacing_scale['steps'] ) || ! $spacing_scale['steps'] > 0 || ! isset( $spacing_scale['mediumStep'] ) - || ! isset( $spacing_scale['units'] ) + || ! isset( $spacing_scale['unit'] ) || ! isset( $spacing_scale['operator'] ) || ! isset( $spacing_scale['increment'] ) || ! isset( $spacing_scale['steps'] ) @@ -871,6 +871,7 @@ public function get_spacing_sizes() { return null; } + $unit = sanitize_title( $spacing_scale['unit'] ); $current_step = $spacing_scale['mediumStep']; $steps_mid_point = round( ( ( $spacing_scale['steps'] ) / 2 ), 0 ); $x_small_count = null; @@ -892,7 +893,7 @@ public function get_spacing_sizes() { /* translators: %s: Muliple of t-shirt sizing, eg. 2X-Small */ 'name' => $x === $steps_mid_point - 1 ? __( 'Small', 'gutenberg' ) : sprintf( __( '%sX-Small', 'gutenberg' ), strval( $x_small_count ) ), 'slug' => $slug, - 'size' => round( $current_step, 2 ) . $spacing_scale['units'], + 'size' => round( $current_step, 2 ) . $unit, ); if ( $x === $steps_mid_point - 2 ) { @@ -911,7 +912,7 @@ public function get_spacing_sizes() { $below_sizes[] = array( 'name' => __( 'Medium', 'gutenberg' ), 'slug' => 50, - 'size' => $spacing_scale['mediumStep'] . $spacing_scale['units'], + 'size' => $spacing_scale['mediumStep'] . $unit, ); $current_step = $spacing_scale['mediumStep']; @@ -927,9 +928,9 @@ public function get_spacing_sizes() { $above_sizes[] = array( /* translators: %s: Muliple of t-shirt sizing, eg. 2X-Large */ - 'name' => $x === 0 ? __( 'Large', 'gutenberg' ) : sprintf( __( '%sX-Large', 'gutenberg' ), strval( $x_large_count ) ), + 'name' => 0 === $x ? __( 'Large', 'gutenberg' ) : sprintf( __( '%sX-Large', 'gutenberg' ), strval( $x_large_count ) ), 'slug' => $slug, - 'size' => round( $current_step, 2 ) . $spacing_scale['units'], + 'size' => round( $current_step, 2 ) . $unit, ); if ( 1 === $x ) { diff --git a/lib/experimental/class-wp-theme-json-resolver-gutenberg.php b/lib/experimental/class-wp-theme-json-resolver-gutenberg.php index 5621d1ced56c31..2007893afea7fc 100644 --- a/lib/experimental/class-wp-theme-json-resolver-gutenberg.php +++ b/lib/experimental/class-wp-theme-json-resolver-gutenberg.php @@ -174,7 +174,7 @@ public static function get_merged_data( $origin = 'custom' ) { $result->merge( static::get_user_data() ); } // Generate the default spacing sizes presets. - $result->get_spacing_sizes(); + $result->set_spacing_sizes(); return $result; } diff --git a/phpunit/class-wp-theme-json-test.php b/phpunit/class-wp-theme-json-test.php index 0c0f73d23cf2e6..8c2b0172777926 100644 --- a/phpunit/class-wp-theme-json-test.php +++ b/phpunit/class-wp-theme-json-test.php @@ -2942,7 +2942,7 @@ function test_get_property_value_self() { * * @dataProvider data_generate_spacing_scale_fixtures */ - function test_get_spacing_sizes( $spacing_scale, $expected_output ) { + function test_set_spacing_sizes( $spacing_scale, $expected_output ) { $theme_json = new WP_Theme_JSON_Gutenberg( array( 'version' => 2, @@ -2954,7 +2954,7 @@ function test_get_spacing_sizes( $spacing_scale, $expected_output ) { ) ); - $theme_json->get_spacing_sizes(); + $theme_json->set_spacing_sizes(); $this->assertSame( $expected_output, _wp_array_get( $theme_json->get_raw_data(), array( 'settings', 'spacing', 'spacingSizes', 'default' ) ) ); } @@ -2965,7 +2965,7 @@ function test_get_spacing_sizes( $spacing_scale, $expected_output ) { */ function data_generate_spacing_scale_fixtures() { return array( - 'empty_spacing_scale' => array( + 'empty_spacing_scale' => array( 'spacing_scale' => array(), 'expected_output' => null, ), @@ -2976,7 +2976,7 @@ function data_generate_spacing_scale_fixtures() { 'increment' => 1.5, 'steps' => 1, 'mediumStep' => 4, - 'units' => 'rem', + 'unit' => 'rem', ), 'expected_output' => null, ), @@ -2987,7 +2987,7 @@ function data_generate_spacing_scale_fixtures() { 'increment' => 'add two to previous value', 'steps' => 1, 'mediumStep' => 4, - 'units' => 'rem', + 'unit' => 'rem', ), 'expected_output' => null, ), @@ -2998,7 +2998,7 @@ function data_generate_spacing_scale_fixtures() { 'increment' => 1.5, 'steps' => 'spiral staircase preferred', 'mediumStep' => 4, - 'units' => 'rem', + 'unit' => 'rem', ), 'expected_output' => null, ), @@ -3009,12 +3009,12 @@ function data_generate_spacing_scale_fixtures() { 'increment' => 1.5, 'steps' => 5, 'mediumStep' => 'That which is just right', - 'units' => 'rem', + 'unit' => 'rem', ), 'expected_output' => null, ), - 'invalid_spacing_scale_values_missing_units' => array( + 'invalid_spacing_scale_values_missing_unit' => array( 'spacingScale' => array( 'operator' => '+', 'increment' => 1.5, @@ -3024,13 +3024,13 @@ function data_generate_spacing_scale_fixtures() { 'expected_output' => null, ), - 'one_step_spacing_scale' => array( + 'one_step_spacing_scale' => array( 'spacingScale' => array( 'operator' => '+', 'increment' => 1.5, 'steps' => 1, 'mediumStep' => 4, - 'units' => 'rem', + 'unit' => 'rem', ), 'expected_output' => array( array( @@ -3047,7 +3047,7 @@ function data_generate_spacing_scale_fixtures() { 'increment' => 1.5, 'steps' => 2, 'mediumStep' => 4, - 'units' => 'rem', + 'unit' => 'rem', ), 'expected_output' => array( array( @@ -3069,7 +3069,7 @@ function data_generate_spacing_scale_fixtures() { 'increment' => 1.5, 'steps' => 3, 'mediumStep' => 4, - 'units' => 'rem', + 'unit' => 'rem', ), 'expected_output' => array( array( @@ -3096,7 +3096,7 @@ function data_generate_spacing_scale_fixtures() { 'increment' => 1.5, 'steps' => 4, 'mediumStep' => 4, - 'units' => 'rem', + 'unit' => 'rem', ), 'expected_output' => array( array( @@ -3128,7 +3128,7 @@ function data_generate_spacing_scale_fixtures() { 'increment' => 2.5, 'steps' => 5, 'mediumStep' => 5, - 'units' => 'rem', + 'unit' => 'rem', ), 'expected_output' => array( array( @@ -3165,7 +3165,7 @@ function data_generate_spacing_scale_fixtures() { 'increment' => 1.5, 'steps' => 5, 'mediumStep' => 1.5, - 'units' => 'rem', + 'unit' => 'rem', ), 'expected_output' => array( array( @@ -3202,7 +3202,7 @@ function data_generate_spacing_scale_fixtures() { 'increment' => 0.25, 'steps' => 5, 'mediumStep' => 1.5, - 'units' => 'rem', + 'unit' => 'rem', ), 'expected_output' => array( array( diff --git a/schemas/json/theme.json b/schemas/json/theme.json index 0853fd68326f49..36ed92025ec153 100644 --- a/schemas/json/theme.json +++ b/schemas/json/theme.json @@ -275,8 +275,8 @@ "description": "The value to medium setting in the scale.", "type": "number" }, - "units": { - "description": "Units that the scale uses, eg. rem, em, px.", + "unit": { + "description": "Unit that the scale uses, eg. rem, em, px.", "type": "string", "enum": [ "px", From df0240ac3364e6ecd15c877530fefd2f7873b0ee Mon Sep 17 00:00:00 2001 From: Glen Davies Date: Thu, 30 Jun 2022 16:22:32 +1200 Subject: [PATCH 40/43] Remove method from 6.1 that is not being modified now --- .../wordpress-6.1/class-wp-theme-json-6-1.php | 82 ------------------- 1 file changed, 82 deletions(-) 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 0fcfc07a93fc2d..5abf3b5a8dd91b 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 @@ -946,86 +946,4 @@ public function set_spacing_sizes() { _wp_array_set( $this->theme_json, array( 'settings', 'spacing', 'spacingSizes', 'default' ), array_merge( $below_sizes, $above_sizes ) ); } - - /** - * Merge new incoming data. - * - * @param WP_Theme_JSON $incoming Data to merge. - */ - public function merge( $incoming ) { - $incoming_data = $incoming->get_raw_data(); - $this->theme_json = array_replace_recursive( $this->theme_json, $incoming_data ); - - /* - * The array_replace_recursive algorithm merges at the leaf level, - * but we don't want leaf arrays to be merged, so we overwrite it. - * - * For leaf values that are sequential arrays it will use the numeric indexes for replacement. - * We rather replace the existing with the incoming value, if it exists. - * This is the case of spacing.units. - * - * For leaf values that are associative arrays it will merge them as expected. - * This is also not the behavior we want for the current associative arrays (presets). - * We rather replace the existing with the incoming value, if it exists. - * This happens, for example, when we merge data from theme.json upon existing - * theme supports or when we merge anything coming from the same source twice. - * This is the case of color.palette, color.gradients, color.duotone, - * typography.fontSizes, or typography.fontFamilies. - * - * Additionally, for some preset types, we also want to make sure the - * values they introduce don't conflict with default values. We do so - * by checking the incoming slugs for theme presets and compare them - * with the equivalent default presets: if a slug is present as a default - * we remove it from the theme presets. - */ - $nodes = static::get_setting_nodes( $incoming_data ); - $slugs_global = static::get_default_slugs( $this->theme_json, array( 'settings' ) ); - foreach ( $nodes as $node ) { - $slugs_node = static::get_default_slugs( $this->theme_json, $node['path'] ); - $slugs = array_merge_recursive( $slugs_global, $slugs_node ); - - // Replace the spacing.units. - $path = array_merge( $node['path'], array( 'spacing', 'units' ) ); - $content = _wp_array_get( $incoming_data, $path, null ); - if ( isset( $content ) ) { - _wp_array_set( $this->theme_json, $path, $content ); - } - - // Replace the presets. - foreach ( static::PRESETS_METADATA as $preset ) { - $override_preset = ! static::get_metadata_boolean( $this->theme_json['settings'], $preset['prevent_override'], true ); - - foreach ( static::VALID_ORIGINS as $origin ) { - $base_path = array_merge( $node['path'], $preset['path'] ); - $path = array_merge( $base_path, array( $origin ) ); - $content = _wp_array_get( $incoming_data, $path, null ); - if ( ! isset( $content ) ) { - continue; - } - - if ( 'theme' === $origin && $preset['use_default_names'] ) { - foreach ( $content as &$item ) { - if ( ! array_key_exists( 'name', $item ) ) { - $name = static::get_name_from_defaults( $item['slug'], $base_path ); - if ( null !== $name ) { - $item['name'] = $name; - } - } - } - } - - if ( - ( 'theme' !== $origin ) || - ( 'theme' === $origin && $override_preset ) - ) { - _wp_array_set( $this->theme_json, $path, $content ); - } else { - $slugs_for_preset = _wp_array_get( $slugs, $preset['path'], array() ); - $content = static::filter_slugs( $content, $slugs_for_preset ); - _wp_array_set( $this->theme_json, $path, $content ); - } - } - } - } - } } From 35f107bb666e7471da159dc7fc526152fc975318 Mon Sep 17 00:00:00 2001 From: Glen Davies Date: Thu, 30 Jun 2022 16:35:01 +1200 Subject: [PATCH 41/43] Fix naming of spacingScale units in theme.json --- lib/compat/wordpress-6.1/theme.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/compat/wordpress-6.1/theme.json b/lib/compat/wordpress-6.1/theme.json index 76bfe0827dc429..8aaab09312974d 100644 --- a/lib/compat/wordpress-6.1/theme.json +++ b/lib/compat/wordpress-6.1/theme.json @@ -196,7 +196,7 @@ "increment": 1.5, "steps": 10, "mediumStep": 1.5, - "units": "rem" + "unit": "rem" } }, "typography": { From 6eecad6ba7e14d3040058eabe868009f1e246a0d Mon Sep 17 00:00:00 2001 From: Glen Davies Date: Thu, 30 Jun 2022 16:54:57 +1200 Subject: [PATCH 42/43] Fix linting issues --- phpunit/class-wp-theme-json-test.php | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/phpunit/class-wp-theme-json-test.php b/phpunit/class-wp-theme-json-test.php index 8c2b0172777926..36f28873fc0ace 100644 --- a/phpunit/class-wp-theme-json-test.php +++ b/phpunit/class-wp-theme-json-test.php @@ -2965,7 +2965,7 @@ function test_set_spacing_sizes( $spacing_scale, $expected_output ) { */ function data_generate_spacing_scale_fixtures() { return array( - 'empty_spacing_scale' => array( + 'empty_spacing_scale' => array( 'spacing_scale' => array(), 'expected_output' => null, ), @@ -2976,7 +2976,7 @@ function data_generate_spacing_scale_fixtures() { 'increment' => 1.5, 'steps' => 1, 'mediumStep' => 4, - 'unit' => 'rem', + 'unit' => 'rem', ), 'expected_output' => null, ), @@ -2987,7 +2987,7 @@ function data_generate_spacing_scale_fixtures() { 'increment' => 'add two to previous value', 'steps' => 1, 'mediumStep' => 4, - 'unit' => 'rem', + 'unit' => 'rem', ), 'expected_output' => null, ), @@ -2998,7 +2998,7 @@ function data_generate_spacing_scale_fixtures() { 'increment' => 1.5, 'steps' => 'spiral staircase preferred', 'mediumStep' => 4, - 'unit' => 'rem', + 'unit' => 'rem', ), 'expected_output' => null, ), @@ -3009,7 +3009,7 @@ function data_generate_spacing_scale_fixtures() { 'increment' => 1.5, 'steps' => 5, 'mediumStep' => 'That which is just right', - 'unit' => 'rem', + 'unit' => 'rem', ), 'expected_output' => null, ), @@ -3024,13 +3024,13 @@ function data_generate_spacing_scale_fixtures() { 'expected_output' => null, ), - 'one_step_spacing_scale' => array( + 'one_step_spacing_scale' => array( 'spacingScale' => array( 'operator' => '+', 'increment' => 1.5, 'steps' => 1, 'mediumStep' => 4, - 'unit' => 'rem', + 'unit' => 'rem', ), 'expected_output' => array( array( @@ -3047,7 +3047,7 @@ function data_generate_spacing_scale_fixtures() { 'increment' => 1.5, 'steps' => 2, 'mediumStep' => 4, - 'unit' => 'rem', + 'unit' => 'rem', ), 'expected_output' => array( array( @@ -3069,7 +3069,7 @@ function data_generate_spacing_scale_fixtures() { 'increment' => 1.5, 'steps' => 3, 'mediumStep' => 4, - 'unit' => 'rem', + 'unit' => 'rem', ), 'expected_output' => array( array( @@ -3096,7 +3096,7 @@ function data_generate_spacing_scale_fixtures() { 'increment' => 1.5, 'steps' => 4, 'mediumStep' => 4, - 'unit' => 'rem', + 'unit' => 'rem', ), 'expected_output' => array( array( @@ -3128,7 +3128,7 @@ function data_generate_spacing_scale_fixtures() { 'increment' => 2.5, 'steps' => 5, 'mediumStep' => 5, - 'unit' => 'rem', + 'unit' => 'rem', ), 'expected_output' => array( array( @@ -3165,7 +3165,7 @@ function data_generate_spacing_scale_fixtures() { 'increment' => 1.5, 'steps' => 5, 'mediumStep' => 1.5, - 'unit' => 'rem', + 'unit' => 'rem', ), 'expected_output' => array( array( @@ -3202,7 +3202,7 @@ function data_generate_spacing_scale_fixtures() { 'increment' => 0.25, 'steps' => 5, 'mediumStep' => 1.5, - 'unit' => 'rem', + 'unit' => 'rem', ), 'expected_output' => array( array( From 64479cf606f3a1f751536253d10dafd31ff559d2 Mon Sep 17 00:00:00 2001 From: Glen Davies Date: Fri, 1 Jul 2022 15:26:18 +1200 Subject: [PATCH 43/43] Add style engine handling of spacing presets --- lib/block-supports/border.php | 2 +- lib/block-supports/spacing.php | 3 +- .../style-engine/class-wp-style-engine.php | 69 ++++++++++++------- .../phpunit/class-wp-style-engine-test.php | 57 ++++++++++++++- packages/style-engine/src/styles/utils.ts | 4 +- 5 files changed, 107 insertions(+), 28 deletions(-) diff --git a/lib/block-supports/border.php b/lib/block-supports/border.php index 9f9053cf970052..34c51eca868811 100644 --- a/lib/block-supports/border.php +++ b/lib/block-supports/border.php @@ -119,7 +119,7 @@ function gutenberg_apply_border_support( $block_type, $block_attributes ) { // Collect classes and styles. $attributes = array(); - $styles = gutenberg_style_engine_generate( array( 'border' => $border_block_styles ) ); + $styles = gutenberg_style_engine_generate( array( 'border' => $border_block_styles ), array( 'css_vars' => true ) ); if ( ! empty( $styles['classnames'] ) ) { $attributes['class'] = $styles['classnames']; diff --git a/lib/block-supports/spacing.php b/lib/block-supports/spacing.php index b20c7d4406f4fd..8366b9775b7488 100644 --- a/lib/block-supports/spacing.php +++ b/lib/block-supports/spacing.php @@ -58,7 +58,8 @@ function gutenberg_apply_spacing_support( $block_type, $block_attributes ) { $spacing_block_styles['padding'] = $has_padding_support && ! $skip_padding ? _wp_array_get( $block_styles, array( 'spacing', 'padding' ), null ) : null; $spacing_block_styles['margin'] = $has_margin_support && ! $skip_margin ? _wp_array_get( $block_styles, array( 'spacing', 'margin' ), null ) : null; $styles = gutenberg_style_engine_generate( - array( 'spacing' => $spacing_block_styles ) + array( 'spacing' => $spacing_block_styles ), + array( 'css_vars' => true ) ); if ( ! empty( $styles['css'] ) ) { diff --git a/packages/style-engine/class-wp-style-engine.php b/packages/style-engine/class-wp-style-engine.php index c4cdd0c19419cb..85cbdbf2e0513d 100644 --- a/packages/style-engine/class-wp-style-engine.php +++ b/packages/style-engine/class-wp-style-engine.php @@ -51,7 +51,7 @@ class WP_Style_Engine { ), 'path' => array( 'color', 'text' ), 'css_vars' => array( - '--wp--preset--color--$slug' => 'color', + 'color' => '--wp--preset--color--$slug', ), 'classnames' => array( 'has-text-color' => true, @@ -148,6 +148,9 @@ class WP_Style_Engine { 'individual' => 'padding-%s', ), 'path' => array( 'spacing', 'padding' ), + 'css_vars' => array( + 'spacing' => '--wp--preset--spacing--$slug', + ), ), 'margin' => array( 'property_keys' => array( @@ -155,6 +158,9 @@ class WP_Style_Engine { 'individual' => 'margin-%s', ), 'path' => array( 'spacing', 'margin' ), + 'css_vars' => array( + 'spacing' => '--wp--preset--spacing--$slug', + ), ), ), 'typography' => array( @@ -246,6 +252,28 @@ protected static function get_slug_from_preset_value( $style_value, $property_ke return null; } + /** + * Generates a css var string, eg var(--wp--preset--color--background) from a preset string, eg. `var:preset|space|50`. + * + * @param string $style_value A single css preset value. + * @param array $css_vars The css var patterns used to generate the var string. + * + * @return string|null The css var, or null if no match for slug found. + */ + protected static function get_css_var_value( $style_value, $css_vars ) { + foreach ( $css_vars as $property_key => $css_var_pattern ) { + $slug = static::get_slug_from_preset_value( $style_value, $property_key ); + if ( $slug ) { + $var = strtr( + $css_var_pattern, + array( '$slug' => $slug ) + ); + return "var($var)"; + } + } + return null; + } + /** * Checks whether an incoming block style value is valid. * @@ -315,7 +343,7 @@ protected static function get_css_declarations( $style_value, $style_definition, isset( $style_definition['value_func'] ) && is_callable( $style_definition['value_func'] ) ) { - return call_user_func( $style_definition['value_func'], $style_value, $style_definition ); + return call_user_func( $style_definition['value_func'], $style_value, $style_definition, $should_return_css_vars ); } $css_declarations = array(); @@ -325,15 +353,9 @@ protected static function get_css_declarations( $style_value, $style_definition, // Check if the value is a CSS preset and there's a corresponding css_var pattern in the style definition. if ( is_string( $style_value ) && strpos( $style_value, 'var:' ) !== false ) { if ( $should_return_css_vars && ! empty( $style_definition['css_vars'] ) ) { - foreach ( $style_definition['css_vars'] as $css_var_pattern => $property_key ) { - $slug = static::get_slug_from_preset_value( $style_value, $property_key ); - if ( $slug ) { - $css_var = strtr( - $css_var_pattern, - array( '$slug' => $slug ) - ); - $css_declarations[ $style_property_keys['default'] ] = "var($css_var)"; - } + $css_var = static::get_css_var_value( $style_value, $style_definition['css_vars'] ); + if ( $css_var ) { + $css_declarations[ $style_property_keys['default'] ] = $css_var; } } return $css_declarations; @@ -344,8 +366,13 @@ protected static function get_css_declarations( $style_value, $style_definition, // for styles such as margins and padding. if ( is_array( $style_value ) ) { foreach ( $style_value as $key => $value ) { - $individual_property = sprintf( $style_property_keys['individual'], _wp_to_kebab_case( $key ) ); - $css_declarations[ $individual_property ] = $value; + if ( is_string( $value ) && strpos( $value, 'var:' ) !== false && $should_return_css_vars && ! empty( $style_definition['css_vars'] ) ) { + $value = static::get_css_var_value( $value, $style_definition['css_vars'] ); + } + $individual_property = sprintf( $style_property_keys['individual'], _wp_to_kebab_case( $key ) ); + if ( $value ) { + $css_declarations[ $individual_property ] = $value; + } } } else { $css_declarations[ $style_property_keys['default'] ] = $style_value; @@ -441,12 +468,13 @@ public function generate( $block_styles, $options ) { * "border-{top|right|bottom|left}-{color|width|style}: {value};" or, * "border-image-{outset|source|width|repeat|slice}: {value};" * - * @param array $style_value A single raw Gutenberg style attributes value for a CSS property. - * @param array $individual_property_definition A single style definition from BLOCK_STYLE_DEFINITIONS_METADATA. + * @param array $style_value A single raw Gutenberg style attributes value for a CSS property. + * @param array $individual_property_definition A single style definition from BLOCK_STYLE_DEFINITIONS_METADATA. + * @param boolean $should_return_css_vars Whether to try to build and return CSS var values. * * @return array An array of CSS definitions, e.g., array( "$property" => "$value" ). */ - protected static function get_individual_property_css_declarations( $style_value, $individual_property_definition ) { + protected static function get_individual_property_css_declarations( $style_value, $individual_property_definition, $should_return_css_vars ) { $css_declarations = array(); if ( ! is_array( $style_value ) || empty( $style_value ) || empty( $individual_property_definition['path'] ) ) { @@ -470,13 +498,8 @@ protected static function get_individual_property_css_declarations( $style_value if ( $style_definition && isset( $style_definition['property_keys']['individual'] ) ) { // Set a CSS var if there is a valid preset value. - $slug = isset( $individual_property_definition['css_vars'][ $css_property ] ) ? static::get_slug_from_preset_value( $value, $css_property ) : null; - if ( $slug ) { - $css_var = strtr( - $individual_property_definition['css_vars'][ $css_property ], - array( '$slug' => $slug ) - ); - $value = "var($css_var)"; + if ( is_string( $value ) && strpos( $value, 'var:' ) !== false && $should_return_css_vars && ! empty( $individual_property_definition['css_vars'] ) ) { + $value = static::get_css_var_value( $value, $individual_property_definition['css_vars'] ); } $individual_css_property = sprintf( $style_definition['property_keys']['individual'], $individual_property_key ); $css_declarations[ $individual_css_property ] = $value; 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 e8274e85425fa3..9ff42a75f7b449 100644 --- a/packages/style-engine/phpunit/class-wp-style-engine-test.php +++ b/packages/style-engine/phpunit/class-wp-style-engine-test.php @@ -246,6 +246,59 @@ public function data_generate_styles_fixtures() { ), ), + 'valid_spacing_single_preset_values' => array( + 'block_styles' => array( + 'spacing' => array( + 'margin' => 'var:preset|spacing|10', + 'padding' => 'var:preset|spacing|20', + ), + ), + 'options' => array( 'css_vars' => true ), + 'expected_output' => array( + 'css' => 'padding: var(--wp--preset--spacing--20); margin: var(--wp--preset--spacing--10);', + ), + ), + + 'valid_spacing_multi_preset_values' => array( + 'block_styles' => array( + 'spacing' => array( + 'margin' => array( + 'left' => 'var:preset|spacing|10', + 'right' => 'var:preset|spacing|20', + 'top' => '1rem', + 'bottom' => '1rem', + ), + 'padding' => array( + 'left' => 'var:preset|spacing|30', + 'right' => 'var:preset|spacing|40', + 'top' => '14px', + 'bottom' => '14px', + ), + ), + ), + 'options' => array( 'css_vars' => true ), + '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;', + ), + ), + + 'invalid_spacing_multi_preset_values' => array( + 'block_styles' => array( + 'spacing' => array( + 'margin' => array( + 'left' => 'var:preset|spaceman|10', + 'right' => 'var:preset|spaceman|20', + 'top' => '1rem', + 'bottom' => '1rem', + ), + ), + ), + 'options' => array( 'css_vars' => true ), + 'expected_output' => array( + 'css' => 'margin-top: 1rem; margin-bottom: 1rem;', + ), + ), + 'invalid_classnames_options' => array( 'block_styles' => array( 'typography' => array( @@ -285,7 +338,7 @@ public function data_generate_styles_fixtures() { ), ), ), - 'options' => array(), + 'options' => array( 'css_vars' => true ), '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;', ), @@ -315,7 +368,7 @@ public function data_generate_styles_fixtures() { ), ), ), - 'options' => array(), + 'options' => array( 'css_vars' => true ), 'expected_output' => array( 'css' => 'border-bottom-color: var(--wp--preset--color--terrible-lizard);', ), diff --git a/packages/style-engine/src/styles/utils.ts b/packages/style-engine/src/styles/utils.ts index a905e1929fdb3f..28609794f23adf 100644 --- a/packages/style-engine/src/styles/utils.ts +++ b/packages/style-engine/src/styles/utils.ts @@ -81,7 +81,9 @@ export function generateBoxRules( } else { const sideRules = individualProperties.reduce( ( acc: GeneratedCSSRule[], side: string ) => { - const value: string | undefined = get( boxStyle, [ side ] ); + const value: string | undefined = getCSSVarFromStyleValue( + get( boxStyle, [ side ] ) + ); if ( value ) { acc.push( { selector: options?.selector,