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

Fix: Stabilize border block support keys #64330

Closed
wants to merge 1 commit into from
Closed
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
20 changes: 10 additions & 10 deletions lib/block-supports/border.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ function gutenberg_register_border_support( $block_type ) {
$block_type->attributes = array();
}

if ( block_has_support( $block_type, array( '__experimentalBorder' ) ) && ! array_key_exists( 'style', $block_type->attributes ) ) {
if ( block_has_support( $block_type, array( 'border' ) ) && ! array_key_exists( 'style', $block_type->attributes ) ) {
$block_type->attributes['style'] = array(
'type' => 'object',
);
Expand Down Expand Up @@ -52,7 +52,7 @@ function gutenberg_apply_border_support( $block_type, $block_attributes ) {
if (
gutenberg_has_border_feature_support( $block_type, 'radius' ) &&
isset( $block_attributes['style']['border']['radius'] ) &&
! wp_should_skip_block_supports_serialization( $block_type, '__experimentalBorder', 'radius' )
! wp_should_skip_block_supports_serialization( $block_type, 'border', 'radius' )
) {
$border_radius = $block_attributes['style']['border']['radius'];

Expand All @@ -67,7 +67,7 @@ function gutenberg_apply_border_support( $block_type, $block_attributes ) {
if (
gutenberg_has_border_feature_support( $block_type, 'style' ) &&
isset( $block_attributes['style']['border']['style'] ) &&
! wp_should_skip_block_supports_serialization( $block_type, '__experimentalBorder', 'style' )
! wp_should_skip_block_supports_serialization( $block_type, 'border', 'style' )
) {
$border_block_styles['style'] = $block_attributes['style']['border']['style'];
}
Expand All @@ -76,7 +76,7 @@ function gutenberg_apply_border_support( $block_type, $block_attributes ) {
if (
$has_border_width_support &&
isset( $block_attributes['style']['border']['width'] ) &&
! wp_should_skip_block_supports_serialization( $block_type, '__experimentalBorder', 'width' )
! wp_should_skip_block_supports_serialization( $block_type, 'border', 'width' )
) {
$border_width = $block_attributes['style']['border']['width'];

Expand All @@ -91,7 +91,7 @@ function gutenberg_apply_border_support( $block_type, $block_attributes ) {
// Border color.
if (
$has_border_color_support &&
! wp_should_skip_block_supports_serialization( $block_type, '__experimentalBorder', 'color' )
! wp_should_skip_block_supports_serialization( $block_type, 'border', 'color' )
) {
$preset_border_color = array_key_exists( 'borderColor', $block_attributes ) ? "var:preset|color|{$block_attributes['borderColor']}" : null;
$custom_border_color = $block_attributes['style']['border']['color'] ?? null;
Expand All @@ -103,9 +103,9 @@ function gutenberg_apply_border_support( $block_type, $block_attributes ) {
foreach ( array( 'top', 'right', 'bottom', 'left' ) as $side ) {
$border = $block_attributes['style']['border'][ $side ] ?? null;
$border_side_values = array(
'width' => isset( $border['width'] ) && ! wp_should_skip_block_supports_serialization( $block_type, '__experimentalBorder', 'width' ) ? $border['width'] : null,
'color' => isset( $border['color'] ) && ! wp_should_skip_block_supports_serialization( $block_type, '__experimentalBorder', 'color' ) ? $border['color'] : null,
'style' => isset( $border['style'] ) && ! wp_should_skip_block_supports_serialization( $block_type, '__experimentalBorder', 'style' ) ? $border['style'] : null,
'width' => isset( $border['width'] ) && ! wp_should_skip_block_supports_serialization( $block_type, 'border', 'width' ) ? $border['width'] : null,
'color' => isset( $border['color'] ) && ! wp_should_skip_block_supports_serialization( $block_type, 'border', 'color' ) ? $border['color'] : null,
'style' => isset( $border['style'] ) && ! wp_should_skip_block_supports_serialization( $block_type, 'border', 'style' ) ? $border['style'] : null,
);
$border_block_styles[ $side ] = $border_side_values;
}
Expand Down Expand Up @@ -143,15 +143,15 @@ function gutenberg_apply_border_support( $block_type, $block_attributes ) {
function gutenberg_has_border_feature_support( $block_type, $feature, $default_value = false ) {
// Check if all border support features have been opted into via `"__experimentalBorder": true`.
if ( $block_type instanceof WP_Block_Type ) {
$block_type_supports_border = $block_type->supports['__experimentalBorder'] ?? $default_value;
$block_type_supports_border = $block_type->supports['border'] ?? $default_value;
if ( true === $block_type_supports_border ) {
return true;
}
}

// Check if the specific feature has been opted into individually
// via nested flag under `__experimentalBorder`.
return block_has_support( $block_type, array( '__experimentalBorder', $feature ), $default_value );
return block_has_support( $block_type, array( 'border', $feature ), $default_value );
}

// Register the block support.
Expand Down
22 changes: 22 additions & 0 deletions lib/compat/wordpress-6.7/blocks.php
Original file line number Diff line number Diff line change
Expand Up @@ -43,3 +43,25 @@ function gutenberg_filter_block_type_metadata_settings_allow_variations_php_file
return $settings;
}
add_filter( 'block_type_metadata_settings', 'gutenberg_filter_block_type_metadata_settings_allow_variations_php_file', 10, 2 );

/**
* Filters the block type arguments during registration to stabilize experimental block supports.
*
* This is a temporary compatibility shim as the approach in core is for this to be handled
* within the WP_Block_Type class rather than requiring a filter.
*
* @param array $args Array of arguments for registering a block type.
* @return array Array of arguments for registering a block type.
*/
function gutenberg_stabilize_experimental_block_supports( $args ) {

if ( empty( $args['supports']['__experimentalBorder'] ) ) {
return $args;
}

$args['supports']['border'] = $args['supports']['__experimentalBorder'];
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This would completely overwrite any prior config that already uses the stabilized key.


return $args;
}

add_filter( 'register_block_type_args', 'gutenberg_stabilize_experimental_block_supports', PHP_INT_MAX, 1 );
Copy link
Contributor

@aaronrobertshaw aaronrobertshaw Nov 7, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As this won't land until 6.8, we'll need to move this to the 6.8 compat folder. Given there's already the same filter equivalent for typography supports, we probably only need to move the border stabilization into that same filter function and rename.

I believe there is a small cost with filters, so while I like the separation of concerns to have each support in its own filter, there could be a benefit to have a single function to stabilize block supports.

2 changes: 1 addition & 1 deletion packages/block-editor/src/hooks/border.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ import {
import { store as blockEditorStore } from '../store';
import { __ } from '@wordpress/i18n';

export const BORDER_SUPPORT_KEY = '__experimentalBorder';
export const BORDER_SUPPORT_KEY = 'border';
export const SHADOW_SUPPORT_KEY = 'shadow';

const getColorByProperty = ( colors, property, value ) => {
Expand Down
2 changes: 1 addition & 1 deletion packages/block-editor/src/hooks/supports.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { Platform } from '@wordpress/element';

const ALIGN_SUPPORT_KEY = 'align';
const ALIGN_WIDE_SUPPORT_KEY = 'alignWide';
const BORDER_SUPPORT_KEY = '__experimentalBorder';
const BORDER_SUPPORT_KEY = 'border';
const COLOR_SUPPORT_KEY = 'color';
const CUSTOM_CLASS_NAME_SUPPORT_KEY = 'customClassName';
const FONT_FAMILY_SUPPORT_KEY = 'typography.__experimentalFontFamily';
Expand Down
32 changes: 16 additions & 16 deletions packages/blocks/src/api/constants.js
Original file line number Diff line number Diff line change
Expand Up @@ -58,12 +58,12 @@ export const __EXPERIMENTAL_STYLE_PROPERTY = {
},
borderColor: {
value: [ 'border', 'color' ],
support: [ '__experimentalBorder', 'color' ],
support: [ 'border', 'color' ],
useEngine: true,
},
borderRadius: {
value: [ 'border', 'radius' ],
support: [ '__experimentalBorder', 'radius' ],
support: [ 'border', 'radius' ],
properties: {
borderTopLeftRadius: 'topLeft',
borderTopRightRadius: 'topRight',
Expand All @@ -74,72 +74,72 @@ export const __EXPERIMENTAL_STYLE_PROPERTY = {
},
borderStyle: {
value: [ 'border', 'style' ],
support: [ '__experimentalBorder', 'style' ],
support: [ 'border', 'style' ],
useEngine: true,
},
borderWidth: {
value: [ 'border', 'width' ],
support: [ '__experimentalBorder', 'width' ],
support: [ 'border', 'width' ],
useEngine: true,
},
borderTopColor: {
value: [ 'border', 'top', 'color' ],
support: [ '__experimentalBorder', 'color' ],
support: [ 'border', 'color' ],
useEngine: true,
},
borderTopStyle: {
value: [ 'border', 'top', 'style' ],
support: [ '__experimentalBorder', 'style' ],
support: [ 'border', 'style' ],
useEngine: true,
},
borderTopWidth: {
value: [ 'border', 'top', 'width' ],
support: [ '__experimentalBorder', 'width' ],
support: [ 'border', 'width' ],
useEngine: true,
},
borderRightColor: {
value: [ 'border', 'right', 'color' ],
support: [ '__experimentalBorder', 'color' ],
support: [ 'border', 'color' ],
useEngine: true,
},
borderRightStyle: {
value: [ 'border', 'right', 'style' ],
support: [ '__experimentalBorder', 'style' ],
support: [ 'border', 'style' ],
useEngine: true,
},
borderRightWidth: {
value: [ 'border', 'right', 'width' ],
support: [ '__experimentalBorder', 'width' ],
support: [ 'border', 'width' ],
useEngine: true,
},
borderBottomColor: {
value: [ 'border', 'bottom', 'color' ],
support: [ '__experimentalBorder', 'color' ],
support: [ 'border', 'color' ],
useEngine: true,
},
borderBottomStyle: {
value: [ 'border', 'bottom', 'style' ],
support: [ '__experimentalBorder', 'style' ],
support: [ 'border', 'style' ],
useEngine: true,
},
borderBottomWidth: {
value: [ 'border', 'bottom', 'width' ],
support: [ '__experimentalBorder', 'width' ],
support: [ 'border', 'width' ],
useEngine: true,
},
borderLeftColor: {
value: [ 'border', 'left', 'color' ],
support: [ '__experimentalBorder', 'color' ],
support: [ 'border', 'color' ],
useEngine: true,
},
borderLeftStyle: {
value: [ 'border', 'left', 'style' ],
support: [ '__experimentalBorder', 'style' ],
support: [ 'border', 'style' ],
useEngine: true,
},
borderLeftWidth: {
value: [ 'border', 'left', 'width' ],
support: [ '__experimentalBorder', 'width' ],
support: [ 'border', 'width' ],
useEngine: true,
},
color: {
Expand Down
89 changes: 68 additions & 21 deletions packages/blocks/src/store/process-block-type.js
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,34 @@ function mergeBlockVariations(
return result;
}

/**
* Function to stabilize border supports.
* This function needs to be merged once we have below PR merged.
*
* Reference from - https://github.com/WordPress/gutenberg/pull/63401/
*
*
* @param {Object} rawSupports Support for the block.
*
* @return {Object} Stabilized supports.
*/
function stabilizeBorderSupports( rawSupports ) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The typography stabilization PR introduced a stabilizeSupports function. This border stabilization should probably be rolled into that too.

if ( ! rawSupports ) {
return rawSupports;
}

const supports = { ...rawSupports };

if (
supports?.__experimentalBorder &&
typeof supports.__experimentalBorder === 'object'
) {
supports.border = supports.__experimentalBorder;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This needs to merge with values already using the stabilized border property rather than flat out replacing it.

}

return supports;
}

/**
* Takes the unprocessed block type settings, merges them with block type metadata
* and applies all the existing filters for the registered block type.
Expand Down Expand Up @@ -102,13 +130,21 @@ export const processBlockType =
),
};

blockType.supports = stabilizeBorderSupports( blockType.supports );
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We'll need some unit tests to cover all the stabilization, similar to those in #63401.


const settings = applyFilters(
'blocks.registerBlockType',
blockType,
name,
null
);

// Re-stabilize any experimental supports after applying filters.
// This ensures that any supports updated by filters are also stabilized.
// Reference from - https://github.com/WordPress/gutenberg/pull/63401/

blockType.supports = stabilizeBorderSupports( blockType.supports );

if (
settings.description &&
typeof settings.description !== 'string'
Expand All @@ -119,29 +155,40 @@ export const processBlockType =
}

if ( settings.deprecated ) {
settings.deprecated = settings.deprecated.map( ( deprecation ) =>
Object.fromEntries(
Object.entries(
// Only keep valid deprecation keys.
applyFilters(
'blocks.registerBlockType',
// Merge deprecation keys with pre-filter settings
// so that filters that depend on specific keys being
// present don't fail.
{
// Omit deprecation keys here so that deprecations
// can opt out of specific keys like "supports".
...omit( blockType, DEPRECATED_ENTRY_KEYS ),
...deprecation,
},
blockType.name,
deprecation
)
).filter( ( [ key ] ) =>
settings.deprecated = settings.deprecated.map( ( deprecation ) => {
// Stabilize any experimental supports before applying filters.
deprecation.supports = stabilizeBorderSupports(
deprecation.supports
);

const filteredDeprecation = // Only keep valid deprecation keys.
applyFilters(
'blocks.registerBlockType',
// Merge deprecation keys with pre-filter settings
// so that filters that depend on specific keys being
// present don't fail.
{
// Omit deprecation keys here so that deprecations
// can opt out of specific keys like "supports".
...omit( blockType, DEPRECATED_ENTRY_KEYS ),
...deprecation,
},
blockType.name,
deprecation
);

// Re-stabilize any experimental supports after applying filters.
// This ensures that any supports updated by filters are also stabilized.
filteredDeprecation.supports = stabilizeBorderSupports(
filteredDeprecation.supports
);

return Object.fromEntries(
Object.entries( filteredDeprecation ).filter( ( [ key ] ) =>
DEPRECATED_ENTRY_KEYS.includes( key )
)
)
);
);
} );
}

if ( ! isPlainObject( settings ) ) {
Expand Down
Loading