Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Block Supports: Allow skipping serialization of typography attributes #30880

Merged
merged 8 commits into from
May 19, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 12 additions & 9 deletions lib/block-supports/typography.php
Original file line number Diff line number Diff line change
Expand Up @@ -61,8 +61,9 @@ function gutenberg_apply_typography_support( $block_type, $block_attributes ) {
return array();
}

$classes = array();
$styles = array();
$attributes = array();
$classes = array();
$styles = array();

$has_font_family_support = _wp_array_get( $block_type->supports, array( '__experimentalFontFamily' ), false );
$has_font_style_support = _wp_array_get( $block_type->supports, array( '__experimentalFontStyle' ), false );
Expand All @@ -74,6 +75,9 @@ function gutenberg_apply_typography_support( $block_type, $block_attributes ) {

$skip_font_size_support_serialization = _wp_array_get( $block_type->supports, array( '__experimentalSkipFontSizeSerialization' ), false );

// Covers all typography features _except_ font size.
$skip_typography_serialization = _wp_array_get( $block_type->supports, array( '__experimentalSkipTypographySerialization' ), false );

// Font Size.
if ( $has_font_size_support && ! $skip_font_size_support_serialization ) {
$has_named_font_size = array_key_exists( 'fontSize', $block_attributes );
Expand All @@ -88,7 +92,7 @@ function gutenberg_apply_typography_support( $block_type, $block_attributes ) {
}

// Font Family.
if ( $has_font_family_support ) {
if ( $has_font_family_support && ! $skip_typography_serialization ) {
$has_font_family = isset( $block_attributes['style']['typography']['fontFamily'] );
// Apply required class and style.
if ( $has_font_family ) {
Expand All @@ -105,7 +109,7 @@ function gutenberg_apply_typography_support( $block_type, $block_attributes ) {
}

// Font style.
if ( $has_font_style_support ) {
if ( $has_font_style_support && ! $skip_typography_serialization ) {
// Apply font style.
$font_style = gutenberg_typography_get_css_variable_inline_style( $block_attributes, 'fontStyle', 'font-style' );
if ( $font_style ) {
Expand All @@ -114,7 +118,7 @@ function gutenberg_apply_typography_support( $block_type, $block_attributes ) {
}

// Font weight.
if ( $has_font_weight_support ) {
if ( $has_font_weight_support && ! $skip_typography_serialization ) {
// Apply font weight.
$font_weight = gutenberg_typography_get_css_variable_inline_style( $block_attributes, 'fontWeight', 'font-weight' );
if ( $font_weight ) {
Expand All @@ -123,7 +127,7 @@ function gutenberg_apply_typography_support( $block_type, $block_attributes ) {
}

// Line Height.
if ( $has_line_height_support ) {
if ( $has_line_height_support && ! $skip_typography_serialization ) {
$has_line_height = isset( $block_attributes['style']['typography']['lineHeight'] );
// Add the style (no classes for line-height).
if ( $has_line_height ) {
Expand All @@ -132,22 +136,21 @@ function gutenberg_apply_typography_support( $block_type, $block_attributes ) {
}

// Text Decoration.
if ( $has_text_decoration_support ) {
if ( $has_text_decoration_support && ! $skip_typography_serialization ) {
$text_decoration_style = gutenberg_typography_get_css_variable_inline_style( $block_attributes, 'textDecoration', 'text-decoration' );
if ( $text_decoration_style ) {
$styles[] = $text_decoration_style;
}
}

// Text Transform.
if ( $has_text_transform_support ) {
if ( $has_text_transform_support && ! $skip_typography_serialization ) {
$text_transform_style = gutenberg_typography_get_css_variable_inline_style( $block_attributes, 'textTransform', 'text-transform' );
if ( $text_transform_style ) {
$styles[] = $text_transform_style;
}
}

$attributes = array();
if ( ! empty( $classes ) ) {
$attributes['class'] = implode( ' ', $classes );
}
Expand Down
63 changes: 34 additions & 29 deletions packages/block-editor/src/hooks/style.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,17 @@
/**
* External dependencies
*/
import { capitalize, get, has, omit, omitBy, startsWith } from 'lodash';
import {
capitalize,
find,
forEach,
get,
has,
isEqual,
omit,
startsWith,
without,
} from 'lodash';

/**
* WordPress dependencies
Expand Down Expand Up @@ -98,21 +108,22 @@ function addAttribute( settings ) {
return settings;
}

/**
* Filters a style object returning only the keys
* that are serializable for a given block.
*
* @param {Object} style Input style object to filter.
* @param {Object} blockSupports Info about block supports.
* @return {Object} Filtered style.
*/
export function omitKeysNotToSerialize( style, blockSupports ) {
return omitBy(
style,
( value, key ) =>
!! blockSupports[ key ]?.__experimentalSkipSerialization
);
}
const skipSerializationPaths = {
[ `${ BORDER_SUPPORT_KEY }.__experimentalSkipSerialization` ]: [ 'border' ],
[ `${ COLOR_SUPPORT_KEY }.__experimentalSkipSerialization` ]: [
COLOR_SUPPORT_KEY,
],
[ `__experimentalSkipFontSizeSerialization` ]: [ 'typography', 'fontSize' ],
[ `__experimentalSkipTypographySerialization` ]: without(
TYPOGRAPHY_SUPPORT_KEYS,
FONT_SIZE_SUPPORT_KEY
).map(
( feature ) =>
find( STYLE_PROPERTY, ( property ) =>
isEqual( property.support, [ feature ] )
)?.value
),
};

/**
* Override props assigned to save component to inject the CSS variables definition.
Expand All @@ -127,22 +138,16 @@ export function addSaveProps( props, blockType, attributes ) {
return props;
}

const { style } = attributes;
let filteredStyle = omitKeysNotToSerialize( style, {
border: getBlockSupport( blockType, BORDER_SUPPORT_KEY ),
[ COLOR_SUPPORT_KEY ]: getBlockSupport( blockType, COLOR_SUPPORT_KEY ),
} );
let { style } = attributes;

if (
getBlockSupport( blockType, '__experimentalSkipFontSizeSerialization' )
) {
filteredStyle = omit( filteredStyle, [
[ 'typography', FONT_SIZE_SUPPORT_KEY ],
] );
}
forEach( skipSerializationPaths, ( path, indicator ) => {
if ( getBlockSupport( blockType, indicator ) ) {
style = omit( style, path );
}
} );

props.style = {
...getInlineStyles( filteredStyle ),
...getInlineStyles( style ),
...props.style,
};

Expand Down
30 changes: 1 addition & 29 deletions packages/block-editor/src/hooks/test/style.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/**
* Internal dependencies
*/
import { getInlineStyles, omitKeysNotToSerialize } from '../style';
import { getInlineStyles } from '../style';

describe( 'getInlineStyles', () => {
it( 'should return an empty object when called with undefined', () => {
Expand Down Expand Up @@ -42,31 +42,3 @@ describe( 'getInlineStyles', () => {
} );
} );
} );

describe( 'omitKeysNotToSerialize', () => {
it( 'should return the same style if no keys are skipped from serialization', () => {
const style = {
color: { text: 'red' },
lineHeight: 2,
};
expect( omitKeysNotToSerialize( style, {} ) ).toEqual( {
color: { text: 'red' },
lineHeight: 2,
} );
} );

it( 'should omit the color key if it is skipped for serialization', () => {
const style = {
color: { text: 'red' },
lineHeight: 2,
};
const blockSupports = {
color: {
__experimentalSkipSerialization: true,
},
};
expect( omitKeysNotToSerialize( style, blockSupports ) ).toEqual( {
lineHeight: 2,
} );
} );
} );