From 8a3216333d4b1d0f96325ae02ea3a3a4de305de1 Mon Sep 17 00:00:00 2001 From: Jorge Date: Fri, 4 Dec 2020 21:53:16 +0000 Subject: [PATCH] Update packages/block-editor/src/components/text-decoration-control/index.js Co-authored-by: Aaron Robertshaw <60436221+aaronrobertshaw@users.noreply.github.com> (+4 squashed commits) Squashed commits: [84854a6ef8] Update packages/block-editor/src/components/text-transform-control/index.js Co-authored-by: Aaron Robertshaw <60436221+aaronrobertshaw@users.noreply.github.com> [c5ef934305] Add deprecation fixtures [a57bcb8c41] Backcompatibility [8c5cc3e944] Remove Font style, weight, decoration, and transform presets --- .../developers/themes/theme-json.md | 2 + lib/class-wp-theme-json.php | 62 ++------- lib/experimental-default-theme.json | 89 +------------ .../font-appearance-control/index.js | 118 +++++++++++++----- .../text-decoration-control/index.js | 73 ++++------- .../text-transform-control/index.js | 78 +++++------- .../block-editor/src/hooks/font-appearance.js | 72 ++--------- .../block-editor/src/hooks/text-decoration.js | 36 +----- .../block-editor/src/hooks/text-transform.js | 35 +----- .../src/navigation/deprecated.js | 101 ++++++++++++++- .../block-library/src/navigation/index.php | 31 +++++ .../blocks/core__navigation__deprecated.html | 3 + .../blocks/core__navigation__deprecated.json | 34 +++++ .../core__navigation__deprecated.parsed.json | 43 +++++++ ...re__navigation__deprecated.serialized.html | 3 + .../edit-site/src/components/editor/utils.js | 33 ----- .../components/sidebar/typography-panel.js | 33 +++-- phpunit/class-wp-theme-json-test.php | 44 ------- 18 files changed, 407 insertions(+), 483 deletions(-) create mode 100644 packages/e2e-tests/fixtures/blocks/core__navigation__deprecated.html create mode 100644 packages/e2e-tests/fixtures/blocks/core__navigation__deprecated.json create mode 100644 packages/e2e-tests/fixtures/blocks/core__navigation__deprecated.parsed.json create mode 100644 packages/e2e-tests/fixtures/blocks/core__navigation__deprecated.serialized.html diff --git a/docs/designers-developers/developers/themes/theme-json.md b/docs/designers-developers/developers/themes/theme-json.md index 3f89813a103207..eedc3278c3b302 100644 --- a/docs/designers-developers/developers/themes/theme-json.md +++ b/docs/designers-developers/developers/themes/theme-json.md @@ -93,6 +93,8 @@ The settings section has the following structure and default values: }, "typography": { "customFontSize": true, /* false to opt-out, as in add_theme_support( 'disable-custom-font-sizes' ) */ + "customFontWeight": true, /* false to opt-out */ + "customFontStyle": true, /* false to opt-out */ "customLineHeight": false, /* true to opt-in, as in add_theme_support( 'custom-line-height' ) */ "dropCap": true, /* false to opt-out */ "fontFamilies": [ ... ], /* font family presets */ diff --git a/lib/class-wp-theme-json.php b/lib/class-wp-theme-json.php index 548134f3cd2157..8f0071f0478abe 100644 --- a/lib/class-wp-theme-json.php +++ b/lib/class-wp-theme-json.php @@ -130,15 +130,15 @@ class WP_Theme_JSON { 'units' => null, ), 'typography' => array( - 'customFontSize' => null, - 'customLineHeight' => null, - 'dropCap' => null, - 'fontFamilies' => null, - 'fontSizes' => null, - 'fontStyles' => null, - 'fontWeights' => null, - 'textDecorations' => null, - 'textTransforms' => null, + 'customFontSize' => null, + 'customLineHeight' => null, + 'dropCap' => null, + 'fontFamilies' => null, + 'fontSizes' => null, + 'customFontStyle' => null, + 'customFontWeight' => null, + 'customTextDecorations' => null, + 'customTextTransforms' => null, ), 'custom' => null, ), @@ -221,50 +221,6 @@ class WP_Theme_JSON { 'css_var_infix' => 'font-family', 'classes' => array(), ), - array( - 'path' => array( 'settings', 'typography', 'fontStyles' ), - 'value_key' => 'value', - 'css_var_infix' => 'font-style', - 'classes' => array( - array( - 'class_suffix' => 'font-style', - 'property_name' => 'font-style', - ), - ), - ), - array( - 'path' => array( 'settings', 'typography', 'fontWeights' ), - 'value_key' => 'value', - 'css_var_infix' => 'font-weight', - 'classes' => array( - array( - 'class_suffix' => 'font-weight', - 'property_name' => 'font-weight', - ), - ), - ), - array( - 'path' => array( 'settings', 'typography', 'textDecorations' ), - 'value_key' => 'value', - 'css_var_infix' => 'text-decoration', - 'classes' => array( - array( - 'class_suffix' => 'text-decoration', - 'property_name' => 'text-decoration', - ), - ), - ), - array( - 'path' => array( 'settings', 'typography', 'textTransforms' ), - 'value_key' => 'slug', - 'css_var_infix' => 'text-transform', - 'classes' => array( - array( - 'class_suffix' => 'text-transform', - 'property_name' => 'text-transform', - ), - ), - ), ); /** diff --git a/lib/experimental-default-theme.json b/lib/experimental-default-theme.json index b2a1c31a639dbe..15904819cfd7f5 100644 --- a/lib/experimental-default-theme.json +++ b/lib/experimental-default-theme.json @@ -134,6 +134,10 @@ "dropCap": true, "customFontSize": true, "customLineHeight": false, + "customFontStyle": true, + "customFontWeight": true, + "customTextTransforms": true, + "customTextDecorations": true, "fontSizes": [ { "name": "Small", @@ -160,91 +164,6 @@ "slug": "huge", "size": "42px" } - ], - "fontStyles": [ - { - "name": "Regular", - "slug": "normal", - "value": "normal" - }, - { - "name": "Italic", - "slug": "italic", - "value": "italic" - } - ], - "fontWeights": [ - { - "name": "Ultralight", - "slug": "100", - "value": "100" - }, - { - "name": "Thin", - "slug": "200", - "value": "200" - }, - { - "name": "Light", - "slug": "300", - "value": "300" - }, - { - "name": "Regular", - "slug": "400", - "value": "400" - }, - { - "name": "Medium", - "slug": "500", - "value": "500" - }, - { - "name": "Semibold", - "slug": "600", - "value": "600" - }, - { - "name": "Bold", - "slug": "700", - "value": "700" - }, - { - "name": "Heavy", - "slug": "800", - "value": "800" - }, - { - "name": "Black", - "slug": "900", - "value": "900" - } - ], - "textTransforms": [ - { - "name": "AB", - "slug": "uppercase" - }, - { - "name": "ab", - "slug": "lowercase" - }, - { - "name": "Ab", - "slug": "capitalize" - } - ], - "textDecorations": [ - { - "name": "Underline", - "slug": "underline", - "value": "underline" - }, - { - "name": "Strikethrough", - "slug": "strikethrough", - "value": "line-through" - } ] }, "spacing": { diff --git a/packages/block-editor/src/components/font-appearance-control/index.js b/packages/block-editor/src/components/font-appearance-control/index.js index c6670368a03926..d318d3e2efcfd6 100644 --- a/packages/block-editor/src/components/font-appearance-control/index.js +++ b/packages/block-editor/src/components/font-appearance-control/index.js @@ -5,6 +5,56 @@ import { CustomSelectControl } from '@wordpress/components'; import { useMemo } from '@wordpress/element'; import { __, sprintf } from '@wordpress/i18n'; +const FONT_STYLES = [ + { + name: __( 'Regular' ), + value: 'normal', + }, + { + name: __( 'Italic' ), + value: 'italic', + }, +]; + +const FONT_WEIGHTS = [ + { + name: __( 'Ultralight' ), + value: '100', + }, + { + name: __( 'Thin' ), + value: '200', + }, + { + name: __( 'Light' ), + value: '300', + }, + { + name: __( 'Regular' ), + value: '400', + }, + { + name: __( 'Medium' ), + value: '500', + }, + { + name: __( 'Semibold' ), + value: '600', + }, + { + name: __( 'Bold' ), + value: '700', + }, + { + name: __( 'Heavy' ), + value: '800', + }, + { + name: __( 'Black' ), + value: '900', + }, +]; + /** * Control to display unified font style and weight options. * @@ -14,12 +64,11 @@ import { __, sprintf } from '@wordpress/i18n'; export default function FontAppearanceControl( props ) { const { onChange, - options: { fontStyles = [], fontWeights = [] }, + hasFontStyles = true, + hasFontWeights = true, value: { fontStyle, fontWeight }, } = props; - const hasStyles = !! fontStyles.length; - const hasWeights = !! fontWeights.length; - const hasStylesOrWeights = hasStyles || hasWeights; + const hasStylesOrWeights = hasFontStyles || hasFontWeights; const defaultOption = { key: 'default', name: __( 'Default' ), @@ -30,24 +79,29 @@ export default function FontAppearanceControl( props ) { const combineOptions = () => { const combinedOptions = [ defaultOption ]; - fontStyles.forEach( ( { name: styleName, slug: styleSlug } ) => { - fontWeights.forEach( ( { name: weightName, slug: weightSlug } ) => { - const optionName = - styleSlug === 'normal' - ? weightName - : sprintf( - /* translators: 1: Font weight name. 2: Font style name. */ - __( '%1$s %2$s' ), - weightName, - styleName - ); - - combinedOptions.push( { - key: `${ weightSlug }-${ styleSlug }`, - name: optionName, - style: { fontStyle: styleSlug, fontWeight: weightSlug }, - } ); - } ); + FONT_STYLES.forEach( ( { name: styleName, value: styleValue } ) => { + FONT_WEIGHTS.forEach( + ( { name: weightName, value: weightValue } ) => { + const optionName = + styleValue === 'normal' + ? weightName + : sprintf( + /* translators: 1: Font weight name. 2: Font style name. */ + __( '%1$s %2$s' ), + weightName, + styleName + ); + + combinedOptions.push( { + key: `${ styleValue }-${ weightValue }`, + name: optionName, + style: { + fontStyle: styleValue, + fontWeight: weightValue, + }, + } ); + } + ); } ); return combinedOptions; @@ -56,11 +110,11 @@ export default function FontAppearanceControl( props ) { // Generates select options for font styles only. const styleOptions = () => { const combinedOptions = [ defaultOption ]; - fontStyles.forEach( ( { name, slug } ) => { + FONT_STYLES.forEach( ( { name, value } ) => { combinedOptions.push( { - key: slug, + key: value, name, - style: { fontStyle: slug, fontWeight: undefined }, + style: { fontStyle: value, fontWeight: undefined }, } ); } ); return combinedOptions; @@ -69,11 +123,11 @@ export default function FontAppearanceControl( props ) { // Generates select options for font weights only. const weightOptions = () => { const combinedOptions = [ defaultOption ]; - fontWeights.forEach( ( { name, slug } ) => { + FONT_WEIGHTS.forEach( ( { name, value } ) => { combinedOptions.push( { - key: slug, + key: value, name, - style: { fontStyle: undefined, fontWeight: slug }, + style: { fontStyle: undefined, fontWeight: value }, } ); } ); return combinedOptions; @@ -81,11 +135,11 @@ export default function FontAppearanceControl( props ) { // Map font styles and weights to select options. const selectOptions = useMemo( () => { - if ( hasStyles && hasWeights ) { + if ( hasFontStyles && hasFontWeights ) { return combineOptions(); } - return hasStyles ? styleOptions() : weightOptions(); + return hasFontStyles ? styleOptions() : weightOptions(); }, [ props.options ] ); // Find current selection by comparing font style & weight against options. @@ -97,11 +151,11 @@ export default function FontAppearanceControl( props ) { // Adjusts field label in case either styles or weights are disabled. const getLabel = () => { - if ( ! hasStyles ) { + if ( ! hasFontStyles ) { return __( 'Font weight' ); } - if ( ! hasWeights ) { + if ( ! hasFontWeights ) { return __( 'Font style' ); } diff --git a/packages/block-editor/src/components/text-decoration-control/index.js b/packages/block-editor/src/components/text-decoration-control/index.js index d2be41e93622db..0385a5d6a943ec 100644 --- a/packages/block-editor/src/components/text-decoration-control/index.js +++ b/packages/block-editor/src/components/text-decoration-control/index.js @@ -5,71 +5,48 @@ import { Button } from '@wordpress/components'; import { formatStrikethrough, formatUnderline } from '@wordpress/icons'; import { __ } from '@wordpress/i18n'; +const TEXT_DECORATIONS = [ + { + name: __( 'Underline' ), + value: 'underline', + icon: formatUnderline, + }, + { + name: __( 'Strikethrough' ), + value: 'line-through', + icon: formatStrikethrough, + }, +]; + /** * Control to facilitate text decoration selections. * * @param {Object} props Component props. * @param {string} props.value Currently selected text decoration. - * @param {Array} props.textDecorations Text decorations available for selection. * @param {Function} props.onChange Handles change in text decoration selection. * @return {WPElement} Text decoration control. */ -export default function TextDecorationControl( { - value: textDecoration, - textDecorations, - onChange, -} ) { - /** - * Determines the what the new text decoration is as a result of a user - * interaction with the control. Then passes this on to the supplied - * onChange handler. - * - * @param {string} newDecoration Slug for selected decoration. - */ - const handleOnChange = ( newDecoration ) => { - // Check if we are toggling a decoration off. - const decoration = - textDecoration === newDecoration ? undefined : newDecoration; - - // Ensure only defined text decorations are allowed. - const presetDecoration = textDecorations.find( - ( { slug } ) => slug === decoration - ); - - // Create string that will be turned into CSS custom property - const newTextDecoration = presetDecoration - ? `var:preset|text-decoration|${ presetDecoration.slug }` - : undefined; - - onChange( newTextDecoration ); - }; - - // Text Decoration icons to use. - const icons = { - strikethrough: formatStrikethrough, - underline: formatUnderline, - }; - +export default function TextDecorationControl( { value, onChange } ) { return (
{ __( 'Decoration' ) }
- { textDecorations.map( ( presetDecoration ) => { + { TEXT_DECORATIONS.map( ( textDecoration ) => { return ( + aria-label={ textDecoration.name } + /> ); } ) }
diff --git a/packages/block-editor/src/components/text-transform-control/index.js b/packages/block-editor/src/components/text-transform-control/index.js index 545fed8407f398..6aeec3101256db 100644 --- a/packages/block-editor/src/components/text-transform-control/index.js +++ b/packages/block-editor/src/components/text-transform-control/index.js @@ -9,71 +9,53 @@ import { formatUppercase, } from '@wordpress/icons'; +const TEXT_TRANSFORMS = [ + { + name: __( 'Uppercase' ), + value: 'uppercase', + icon: formatUppercase, + }, + { + name: __( 'Lowercase' ), + value: 'lowercase', + icon: formatLowercase, + }, + { + name: __( 'Capitalize' ), + value: 'capitalize', + icon: formatCapitalize, + }, +]; + /** * Control to facilitate text transform selections. * * @param {Object} props Component props. * @param {string} props.value Currently selected text transform. - * @param {Array} props.textTransforms Text transforms available for selection. * @param {Function} props.onChange Handles change in text transform selection. * @return {WPElement} Text transform control. */ -export default function TextTransformControl( { - value: textTransform, - textTransforms, - onChange, -} ) { - /** - * Determines what the new text transform is as a result of a user - * interaction with the control. Then passes this on to the supplied - * onChange handler. - * - * @param {string} newTransform Slug for selected text transform. - */ - const handleOnChange = ( newTransform ) => { - // Check if we are toggling a transform off. - const transform = - textTransform === newTransform ? undefined : newTransform; - - // Ensure only defined text transforms are allowed. - const presetTransform = textTransforms.find( - ( { slug } ) => slug === transform - ); - - // Create string that will be turned into CSS custom property - const newTextTransform = presetTransform - ? `var:preset|text-transform|${ presetTransform.slug }` - : undefined; - - onChange( newTextTransform ); - }; - - // Text transform icons to use. - // Icons still to be created/designed. - const icons = { - capitalize: formatCapitalize, - lowercase: formatLowercase, - uppercase: formatUppercase, - }; - +export default function TextTransformControl( { value, onChange } ) { return (
{ __( 'Letter case' ) }
- { textTransforms.map( ( presetTransform ) => { + { TEXT_TRANSFORMS.map( ( textTransform ) => { return ( + /> ); } ) }
diff --git a/packages/block-editor/src/hooks/font-appearance.js b/packages/block-editor/src/hooks/font-appearance.js index e2055649316375..52661ce0364118 100644 --- a/packages/block-editor/src/hooks/font-appearance.js +++ b/packages/block-editor/src/hooks/font-appearance.js @@ -32,61 +32,35 @@ export function FontAppearanceEdit( props ) { setAttributes, } = props; - const fontStyles = useEditorFeature( 'typography.fontStyles' ); - const fontWeights = useEditorFeature( 'typography.fontWeights' ); - const isFontStyleDisabled = useIsFontStyleDisabled( props ); - const isFontWeightDisabled = useIsFontWeightDisabled( props ); + const hasFontStyles = ! useIsFontStyleDisabled( props ); + const hasFontWeights = ! useIsFontWeightDisabled( props ); - if ( isFontStyleDisabled && isFontWeightDisabled ) { + if ( ! hasFontStyles && ! hasFontWeights ) { return null; } const onChange = ( newStyles ) => { - // Match style selection with preset and create CSS var style if appropriate. - const presetStyle = fontStyles.find( - ( { slug } ) => slug === newStyles.fontStyle - ); - const newFontStyle = presetStyle - ? `var:preset|font-style|${ presetStyle.slug }` - : undefined; - - // Match weight selection with preset and create CSS var style if appropriate. - const presetWeight = fontWeights.find( - ( { slug } ) => slug === newStyles.fontWeight - ); - const newFontWeight = presetWeight - ? `var:preset|font-weight|${ presetWeight.slug }` - : undefined; - setAttributes( { style: cleanEmptyObject( { ...style, typography: { ...style?.typography, - fontStyle: newFontStyle, - fontWeight: newFontWeight, + fontStyle: newStyles.fontStyle, + fontWeight: newStyles.fontWeight, }, } ), } ); }; - const fontStyle = getFontAppearanceValueFromStyle( - fontStyles, - style?.typography?.fontStyle - ); + const fontStyle = style?.typography?.fontStyle; - const fontWeight = getFontAppearanceValueFromStyle( - fontWeights, - style?.typography?.fontWeight - ); + const fontWeight = style?.typography?.fontWeight; return ( ); @@ -102,9 +76,9 @@ export function FontAppearanceEdit( props ) { */ export function useIsFontStyleDisabled( { name: blockName } = {} ) { const styleSupport = hasBlockSupport( blockName, FONT_STYLE_SUPPORT_KEY ); - const fontStyles = useEditorFeature( 'typography.fontStyles' ); + const hasFontStyles = useEditorFeature( 'typography.customFontStyle' ); - return ! styleSupport || ! fontStyles?.length; + return ! styleSupport || ! hasFontStyles; } /** @@ -117,9 +91,9 @@ export function useIsFontStyleDisabled( { name: blockName } = {} ) { */ export function useIsFontWeightDisabled( { name: blockName } = {} ) { const weightSupport = hasBlockSupport( blockName, FONT_WEIGHT_SUPPORT_KEY ); - const fontWeights = useEditorFeature( 'typography.fontWeights' ); + const hasFontWeights = useEditorFeature( 'typography.customFontWeight' ); - return ! weightSupport || ! fontWeights?.length; + return ! weightSupport || ! hasFontWeights; } /** @@ -134,23 +108,3 @@ export function useIsFontAppearanceDisabled( props ) { return stylesDisabled && weightsDisabled; } - -/** - * Extracts the current selection, if available, from the CSS variable set - * within a style attribute property e.g. `style.typography.fontStyle` - * or `style.typography.fontWeight`. - * - * @param {Array} presets Available preset options. - * @param {string} style Style attribute value to parse - * @return {string} Actual CSS property value. - */ -const getFontAppearanceValueFromStyle = ( presets, style ) => { - if ( ! style ) { - return undefined; - } - - const parsedValue = style.slice( style.lastIndexOf( '|' ) + 1 ); - const preset = presets.find( ( { slug } ) => slug === parsedValue ); - - return preset?.slug || style; -}; diff --git a/packages/block-editor/src/hooks/text-decoration.js b/packages/block-editor/src/hooks/text-decoration.js index 04aaa57ae76656..d2433277e8d4b8 100644 --- a/packages/block-editor/src/hooks/text-decoration.js +++ b/packages/block-editor/src/hooks/text-decoration.js @@ -27,18 +27,12 @@ export function TextDecorationEdit( props ) { attributes: { style }, setAttributes, } = props; - const textDecorations = useEditorFeature( 'typography.textDecorations' ); const isDisabled = useIsTextDecorationDisabled( props ); if ( isDisabled ) { return null; } - const textDecoration = getTextDecorationFromAttributeValue( - textDecorations, - style?.typography?.textDecoration - ); - function onChange( newDecoration ) { setAttributes( { style: cleanEmptyObject( { @@ -53,8 +47,7 @@ export function TextDecorationEdit( props ) { return ( ); @@ -71,28 +64,9 @@ export function useIsTextDecorationDisabled( { name: blockName } = {} ) { blockName, TEXT_DECORATION_SUPPORT_KEY ); - const textDecorations = useEditorFeature( 'typography.textDecorations' ); - const hasTextDecorations = !! textDecorations?.length; + const hasTextDecoration = useEditorFeature( + 'typography.customTextDecorations' + ); - return notSupported || ! hasTextDecorations; + return notSupported || ! hasTextDecoration; } - -/** - * Extracts the current text decoration selection, if available, from the CSS - * variable set as the `styles.typography.textDecoration` attribute. - * - * @param {Array} textDecorations Available text decorations as defined in theme.json. - * @param {string} value Attribute value in `styles.typography.textDecoration` - * @return {string} Actual text decoration value - */ -const getTextDecorationFromAttributeValue = ( textDecorations, value ) => { - const attributeParsed = /var:preset\|text-decoration\|(.+)/.exec( value ); - - if ( attributeParsed && attributeParsed[ 1 ] ) { - return textDecorations.find( - ( { slug } ) => slug === attributeParsed[ 1 ] - )?.slug; - } - - return value; -}; diff --git a/packages/block-editor/src/hooks/text-transform.js b/packages/block-editor/src/hooks/text-transform.js index 8d7e807584cb09..fd317861f0e717 100644 --- a/packages/block-editor/src/hooks/text-transform.js +++ b/packages/block-editor/src/hooks/text-transform.js @@ -27,18 +27,12 @@ export function TextTransformEdit( props ) { attributes: { style }, setAttributes, } = props; - const textTransforms = useEditorFeature( 'typography.textTransforms' ); const isDisabled = useIsTextTransformDisabled( props ); if ( isDisabled ) { return null; } - const textTransform = getTextTransformFromAttributeValue( - textTransforms, - style?.typography?.textTransform - ); - function onChange( newTransform ) { setAttributes( { style: cleanEmptyObject( { @@ -53,8 +47,7 @@ export function TextTransformEdit( props ) { return ( ); @@ -71,28 +64,8 @@ export function useIsTextTransformDisabled( { name: blockName } = {} ) { blockName, TEXT_TRANSFORM_SUPPORT_KEY ); - const textTransforms = useEditorFeature( 'typography.textTransforms' ); - const hasTextTransforms = !! textTransforms?.length; - + const hasTextTransforms = useEditorFeature( + 'typography.customTextTransforms' + ); return notSupported || ! hasTextTransforms; } - -/** - * Extracts the current text transform selection, if available, from the CSS - * variable set as the `styles.typography.textTransform` attribute. - * - * @param {Array} textTransforms Available text transforms as defined in theme.json. - * @param {string} value Attribute value in `styles.typography.textTransform` - * @return {string} Actual text transform value - */ -const getTextTransformFromAttributeValue = ( textTransforms, value ) => { - const attributeParsed = /var:preset\|text-transform\|(.+)/.exec( value ); - - if ( attributeParsed && attributeParsed[ 1 ] ) { - return textTransforms.find( - ( { slug } ) => slug === attributeParsed[ 1 ] - )?.slug; - } - - return value; -}; diff --git a/packages/block-library/src/navigation/deprecated.js b/packages/block-library/src/navigation/deprecated.js index 9f8b8bce707096..0ee64c0a44da89 100644 --- a/packages/block-library/src/navigation/deprecated.js +++ b/packages/block-library/src/navigation/deprecated.js @@ -1,14 +1,113 @@ /** * External dependencies */ -import { omit } from 'lodash'; +import { mapValues, omit } from 'lodash'; /** * WordPress dependencies */ import { InnerBlocks } from '@wordpress/block-editor'; +const TYPOGRAPHY_PRESET_DEPRECATION_MAP = { + fontStyle: 'var:preset|font-style|', + fontWeight: 'var:preset|font-weight|', + textDecoration: 'var:preset|text-decoration|', + textTransform: 'var:preset|text-transform|', +}; + export default [ + { + attributes: { + orientation: { + type: 'string', + }, + textColor: { + type: 'string', + }, + customTextColor: { + type: 'string', + }, + rgbTextColor: { + type: 'string', + }, + backgroundColor: { + type: 'string', + }, + customBackgroundColor: { + type: 'string', + }, + rgbBackgroundColor: { + type: 'string', + }, + itemsJustification: { + type: 'string', + }, + showSubmenuIcon: { + type: 'boolean', + default: true, + }, + }, + supports: { + align: [ 'wide', 'full' ], + anchor: true, + html: false, + inserter: true, + fontSize: true, + __experimentalFontStyle: true, + __experimentalFontWeight: true, + __experimentalTextTransform: true, + color: true, + __experimentalFontFamily: true, + __experimentalTextDecoration: true, + }, + save() { + return ; + }, + isEligible( attributes ) { + if ( ! attributes.style || ! attributes.style.typography ) { + return false; + } + for ( const styleAttribute in TYPOGRAPHY_PRESET_DEPRECATION_MAP ) { + const attributeValue = + attributes.style.typography[ styleAttribute ]; + if ( + attributeValue && + attributeValue.startsWith( + TYPOGRAPHY_PRESET_DEPRECATION_MAP[ styleAttribute ] + ) + ) { + return true; + } + } + return false; + }, + migrate( attributes ) { + return { + ...attributes, + style: { + ...attributes.style, + typography: mapValues( + attributes.style.typography, + ( value, key ) => { + const prefix = + TYPOGRAPHY_PRESET_DEPRECATION_MAP[ key ]; + if ( prefix && value.startsWith( prefix ) ) { + const newValue = value.slice( prefix.length ); + if ( + 'textDecoration' === key && + 'strikethrough' === newValue + ) { + return 'line-through'; + } + return newValue; + } + return value; + } + ), + }, + }; + }, + }, { attributes: { className: { diff --git a/packages/block-library/src/navigation/index.php b/packages/block-library/src/navigation/index.php index b9046b529d9dcd..57e312c11f3ed5 100644 --- a/packages/block-library/src/navigation/index.php +++ b/packages/block-library/src/navigation/index.php @@ -171,3 +171,34 @@ function register_block_core_navigation() { } add_action( 'init', 'register_block_core_navigation' ); + +/** + * Filter that changes the parsed attribute values of navigation blocks contain typographic presets to contain the values directly. + * + * @param array $parsed_block The block being rendered. + * @return array The block being rendered without typographic presets. + */ +function block_core_navigation_typographic_presets_backcompatibility( $parsed_block ) { + if ( 'core/navigation' === $parsed_block['blockName'] ) { + $attribute_to_prefix_map = array( + 'fontStyle' => 'var:preset|font-style|', + 'fontWeight' => 'var:preset|font-weight|', + 'textDecoration' => 'var:preset|text-decoration|', + 'textTransform' => 'var:preset|text-transform|', + ); + foreach ( $attribute_to_prefix_map as $style_attribute => $prefix ) { + if ( ! empty( $parsed_block['attrs']['style']['typography'][ $style_attribute ] ) ) { + $prefix_len = strlen( $prefix ); + $attribute_value = &$parsed_block['attrs']['style']['typography'][ $style_attribute ]; + if ( 0 === strncmp( $attribute_value, $prefix, $prefix_len ) ) { + $attribute_value = substr( $attribute_value, $prefix_len ); + } + if ( 'textDecoration' === $style_attribute && 'strikethrough' === $attribute_value ) { + $attribute_value = 'line-through'; + } + } + } + } + return $parsed_block; +} +add_filter( 'render_block_data', 'block_core_navigation_typographic_presets_backcompatibility' ); diff --git a/packages/e2e-tests/fixtures/blocks/core__navigation__deprecated.html b/packages/e2e-tests/fixtures/blocks/core__navigation__deprecated.html new file mode 100644 index 00000000000000..f64dfae11e44a7 --- /dev/null +++ b/packages/e2e-tests/fixtures/blocks/core__navigation__deprecated.html @@ -0,0 +1,3 @@ + + + diff --git a/packages/e2e-tests/fixtures/blocks/core__navigation__deprecated.json b/packages/e2e-tests/fixtures/blocks/core__navigation__deprecated.json new file mode 100644 index 00000000000000..c1e7672aea7ca6 --- /dev/null +++ b/packages/e2e-tests/fixtures/blocks/core__navigation__deprecated.json @@ -0,0 +1,34 @@ +[ + { + "clientId": "_clientId_0", + "name": "core/navigation", + "isValid": true, + "attributes": { + "orientation": "horizontal", + "showSubmenuIcon": true, + "style": { + "typography": { + "textTransform": "lowercase", + "textDecoration": "line-through", + "fontStyle": "italic", + "fontWeight": "100" + } + } + }, + "innerBlocks": [ + { + "clientId": "_clientId_0", + "name": "core/navigation-link", + "isValid": true, + "attributes": { + "label": "WordPress", + "opensInNewTab": false, + "url": "https://www.wordpress.org/" + }, + "innerBlocks": [], + "originalContent": "" + } + ], + "originalContent": "" + } +] diff --git a/packages/e2e-tests/fixtures/blocks/core__navigation__deprecated.parsed.json b/packages/e2e-tests/fixtures/blocks/core__navigation__deprecated.parsed.json new file mode 100644 index 00000000000000..11cb1a6b198be9 --- /dev/null +++ b/packages/e2e-tests/fixtures/blocks/core__navigation__deprecated.parsed.json @@ -0,0 +1,43 @@ +[ + { + "blockName": "core/navigation", + "attrs": { + "orientation": "horizontal", + "style": { + "typography": { + "textTransform": "var:preset|text-transform|lowercase", + "textDecoration": "var:preset|text-decoration|strikethrough", + "fontStyle": "var:preset|font-style|italic", + "fontWeight": "var:preset|font-weight|100" + } + } + }, + "innerBlocks": [ + { + "blockName": "core/navigation-link", + "attrs": { + "label": "WordPress", + "url": "https://www.wordpress.org/" + }, + "innerBlocks": [], + "innerHTML": "", + "innerContent": [] + } + ], + "innerHTML": "\n\n", + "innerContent": [ + "\n", + null, + "\n" + ] + }, + { + "blockName": null, + "attrs": {}, + "innerBlocks": [], + "innerHTML": "\n", + "innerContent": [ + "\n" + ] + } +] diff --git a/packages/e2e-tests/fixtures/blocks/core__navigation__deprecated.serialized.html b/packages/e2e-tests/fixtures/blocks/core__navigation__deprecated.serialized.html new file mode 100644 index 00000000000000..22bf66bf725368 --- /dev/null +++ b/packages/e2e-tests/fixtures/blocks/core__navigation__deprecated.serialized.html @@ -0,0 +1,3 @@ + + + diff --git a/packages/edit-site/src/components/editor/utils.js b/packages/edit-site/src/components/editor/utils.js index 679badaa9fbaae..1bd54dc32d675b 100644 --- a/packages/edit-site/src/components/editor/utils.js +++ b/packages/edit-site/src/components/editor/utils.js @@ -60,39 +60,6 @@ export const PRESET_METADATA = [ cssVarInfix: 'font-family', classes: [], }, - { - path: [ 'settings', 'typography', 'fontStyles' ], - valueKey: 'value', - cssVarInfix: 'font-style', - classes: [ { classSuffix: 'font-style', propertyName: 'font-style' } ], - }, - { - path: [ 'settings', 'typography', 'fontWeights' ], - valueKey: 'value', - cssVarInfix: 'font-weight', - classes: [ - { classSuffix: 'font-weight', propertyName: 'font-weight' }, - ], - }, - { - path: [ 'settings', 'typography', 'textDecorations' ], - valueKey: 'value', - cssVarInfix: 'text-decoration', - classes: [ - { - classSuffix: 'text-decoration', - propertyName: 'text-decoration', - }, - ], - }, - { - path: [ 'settings', 'typography', 'textTransforms' ], - valueKey: 'slug', - cssVarInfix: 'text-transform', - classes: [ - { classSuffix: 'text-transform', propertyName: 'text-transform' }, - ], - }, ]; const STYLE_PROPERTIES_TO_CSS_VAR_INFIX = { diff --git a/packages/edit-site/src/components/sidebar/typography-panel.js b/packages/edit-site/src/components/sidebar/typography-panel.js index be8ffe6363b3f3..529115d8b5adf5 100644 --- a/packages/edit-site/src/components/sidebar/typography-panel.js +++ b/packages/edit-site/src/components/sidebar/typography-panel.js @@ -30,12 +30,13 @@ function useHasLineHeightControl( { supports, name } ) { } function useHasAppearenceControl( { supports, name } ) { - const fontStyles = useEditorFeature( 'typography.fontStyles', name ); - const fontWeights = useEditorFeature( 'typography.fontWeights', name ); - return ( - ( supports.includes( 'fontStyle' ) && !! fontStyles?.length ) || - ( supports.includes( 'fontWeight' ) && !! fontWeights?.length ) - ); + const hasFontStyles = + useEditorFeature( 'typography.customFontStyle', name ) && + supports.includes( 'fontStyle' ); + const hasFontWeights = + useEditorFeature( 'typography.customFontWeight', name ) && + supports.includes( 'fontWeight' ); + return hasFontStyles || hasFontWeights; } export default function TypographyPanel( { @@ -49,12 +50,14 @@ export default function TypographyPanel( { name ); const fontFamilies = useEditorFeature( 'typography.fontFamilies', name ); - const fontStyles = useEditorFeature( 'typography.fontStyles', name ); - const fontWeights = useEditorFeature( 'typography.fontWeights', name ); + const hasFontStyles = + useEditorFeature( 'typography.customFontStyle', name ) && + supports.includes( 'fontStyle' ); + const hasFontWeights = + useEditorFeature( 'typography.customFontWeight', name ) && + supports.includes( 'fontWeight' ); const hasLineHeightEnabled = useHasLineHeightControl( { supports, name } ); const hasAppearenceControl = useHasAppearenceControl( { supports, name } ); - const hasFontStyleSupport = supports.includes( 'fontStyle' ); - const hasFontWeightSupport = supports.includes( 'fontWeight' ); return ( @@ -91,18 +94,12 @@ export default function TypographyPanel( { fontStyle: getStyleProperty( name, 'fontStyle' ), fontWeight: getStyleProperty( name, 'fontWeight' ), } } - options={ { - fontStyles: hasFontStyleSupport - ? fontStyles - : undefined, - fontWeights: hasFontWeightSupport - ? fontWeights - : undefined, - } } onChange={ ( { fontStyle, fontWeight } ) => { setStyleProperty( name, 'fontStyle', fontStyle ); setStyleProperty( name, 'fontWeight', fontWeight ); } } + hasFontStyles={ hasFontStyles } + hasFontWeights={ hasFontWeights } /> ) } diff --git a/phpunit/class-wp-theme-json-test.php b/phpunit/class-wp-theme-json-test.php index 9d4070dc703695..8b5193a7f3a3ee 100644 --- a/phpunit/class-wp-theme-json-test.php +++ b/phpunit/class-wp-theme-json-test.php @@ -310,28 +310,6 @@ public function test_merge_incoming_data() { 'fontFamily' => 'fontFamily', ), ), - 'fontStyles' => array( - array( - 'slug' => 'fontStyle', - ), - ), - 'fontWeights' => array( - array( - 'slug' => 'fontWeight', - ), - ), - 'textDecorations' => array( - array( - 'slug' => 'textDecoration', - 'value' => 'textDecoration', - ), - ), - 'textTransforms' => array( - array( - 'slug' => 'textTransform', - 'value' => 'textTransform', - ), - ), ), ), ), @@ -369,28 +347,6 @@ public function test_merge_incoming_data() { 'fontFamily' => 'fontFamily', ), ), - 'fontStyles' => array( - array( - 'slug' => 'fontStyle', - ), - ), - 'fontWeights' => array( - array( - 'slug' => 'fontWeight', - ), - ), - 'textDecorations' => array( - array( - 'slug' => 'textDecoration', - 'value' => 'textDecoration', - ), - ), - 'textTransforms' => array( - array( - 'slug' => 'textTransform', - 'value' => 'textTransform', - ), - ), ), ), 'styles' => array(