From 6ed4bd3bbefc381d863969ab6138720b3b31e1f9 Mon Sep 17 00:00:00 2001 From: isabel_brison Date: Thu, 2 May 2024 07:01:15 +0000 Subject: [PATCH] Editor: Merge element style and classname generation to single filter. Fixes element classnames not being output when block attributes are filtered with `render_block_data`. Props aaronrobertshaw, isabel_brison, jorbin. Fixes #60681. Built from https://develop.svn.wordpress.org/trunk@58074 git-svn-id: http://core.svn.wordpress.org/trunk@57539 1a063a9b-81f0-0310-95a4-ce76da25c4cd --- wp-includes/block-supports/elements.php | 145 ++++++++++++++++-------- wp-includes/version.php | 2 +- 2 files changed, 99 insertions(+), 48 deletions(-) diff --git a/wp-includes/block-supports/elements.php b/wp-includes/block-supports/elements.php index e7fa76a9ae..afa31eb618 100644 --- a/wp-includes/block-supports/elements.php +++ b/wp-includes/block-supports/elements.php @@ -22,6 +22,8 @@ function wp_get_elements_class_name( $block ) { /** * Updates the block content with elements class names. * + * @deprecated 6.6.0 Generation of element class name is handled via `render_block_data` filter. + * * @since 5.8.0 * @since 6.4.0 Added support for button and heading element styling. * @access private @@ -31,18 +33,28 @@ function wp_get_elements_class_name( $block ) { * @return string Filtered block content. */ function wp_render_elements_support( $block_content, $block ) { - if ( ! $block_content || ! isset( $block['attrs']['style']['elements'] ) ) { - return $block_content; - } + _deprecated_function( __FUNCTION__, '6.6.0', 'wp_render_elements_class_name' ); + return $block_content; +} - $block_type = WP_Block_Type_Registry::get_instance()->get_registered( $block['blockName'] ); - if ( ! $block_type ) { - return $block_content; +/** + * Determines whether an elements class name should be added to the block. + * + * @since 6.6.0 + * @access private + * + * @param array $block Block object. + * @param array $options Per element type options e.g. whether to skip serialization. + * @return boolean Whether the block needs an elements class name. + */ +function wp_should_add_elements_class_name( $block, $options ) { + if ( ! isset( $block['attrs']['style']['elements'] ) ) { + return false; } $element_color_properties = array( 'button' => array( - 'skip' => wp_should_skip_block_supports_serialization( $block_type, 'color', 'button' ), + 'skip' => isset( $options['button']['skip'] ) ? $options['button']['skip'] : false, 'paths' => array( array( 'button', 'color', 'text' ), array( 'button', 'color', 'background' ), @@ -50,14 +62,14 @@ function wp_render_elements_support( $block_content, $block ) { ), ), 'link' => array( - 'skip' => wp_should_skip_block_supports_serialization( $block_type, 'color', 'link' ), + 'skip' => isset( $options['link']['skip'] ) ? $options['link']['skip'] : false, 'paths' => array( array( 'link', 'color', 'text' ), array( 'link', ':hover', 'color', 'text' ), ), ), 'heading' => array( - 'skip' => wp_should_skip_block_supports_serialization( $block_type, 'color', 'heading' ), + 'skip' => isset( $options['heading']['skip'] ) ? $options['heading']['skip'] : false, 'paths' => array( array( 'heading', 'color', 'text' ), array( 'heading', 'color', 'background' ), @@ -84,14 +96,6 @@ function wp_render_elements_support( $block_content, $block ) { ), ); - $skip_all_element_color_serialization = $element_color_properties['button']['skip'] && - $element_color_properties['link']['skip'] && - $element_color_properties['heading']['skip']; - - if ( $skip_all_element_color_serialization ) { - return $block_content; - } - $elements_style_attributes = $block['attrs']['style']['elements']; foreach ( $element_color_properties as $element_config ) { @@ -101,31 +105,16 @@ function wp_render_elements_support( $block_content, $block ) { foreach ( $element_config['paths'] as $path ) { if ( null !== _wp_array_get( $elements_style_attributes, $path, null ) ) { - /* - * It only takes a single custom attribute to require that the custom - * class name be added to the block, so once one is found there's no - * need to continue looking for others. - * - * As is done with the layout hook, this code assumes that the block - * contains a single wrapper and that it's the first element in the - * rendered output. That first element, if it exists, gets the class. - */ - $tags = new WP_HTML_Tag_Processor( $block_content ); - if ( $tags->next_tag() ) { - $tags->add_class( wp_get_elements_class_name( $block ) ); - } - - return $tags->get_updated_html(); + return true; } } } - // If no custom attributes were found then there's nothing to modify. - return $block_content; + return false; } /** - * Renders the elements stylesheet. + * Render the elements stylesheet and adds elements class name to block as required. * * In the case of nested blocks we want the parent element styles to be rendered before their descendants. * This solves the issue of an element (e.g.: link color) being styled in both the parent and a descendant: @@ -133,18 +122,36 @@ function wp_render_elements_support( $block_content, $block ) { * * @since 6.0.0 * @since 6.1.0 Implemented the style engine to generate CSS and classnames. + * @since 6.6.0 Element block support class and styles are generated via the `render_block_data` filter instead of `pre_render_block`. * @access private * - * @param string|null $pre_render The pre-rendered content. Default null. - * @param array $block The block being rendered. - * @return null + * @param array $parsed_block The parsed block. + * @return array The same parsed block with elements classname added if appropriate. */ -function wp_render_elements_support_styles( $pre_render, $block ) { - $block_type = WP_Block_Type_Registry::get_instance()->get_registered( $block['blockName'] ); - $element_block_styles = isset( $block['attrs']['style']['elements'] ) ? $block['attrs']['style']['elements'] : null; +function wp_render_elements_support_styles( $parsed_block ) { + /* + * The generation of element styles and classname were moved to the + * `render_block_data` filter in 6.6.0 to avoid filtered attributes + * breaking the application of the elements CSS class. + * + * @see https://github.com/WordPress/gutenberg/pull/59535. + * + * The change in filter means, the argument types for this function + * have changed and require deprecating. + */ + if ( is_string( $parsed_block ) ) { + _deprecated_argument( + __FUNCTION__, + '6.6.0', + __( 'Use as a `pre_render_block` filter is deprecated. Use with `render_block_data` instead.' ) + ); + } + + $block_type = WP_Block_Type_Registry::get_instance()->get_registered( $parsed_block['blockName'] ); + $element_block_styles = isset( $parsed_block['attrs']['style']['elements'] ) ? $parsed_block['attrs']['style']['elements'] : null; if ( ! $element_block_styles ) { - return null; + return $parsed_block; } $skip_link_color_serialization = wp_should_skip_block_supports_serialization( $block_type, 'color', 'link' ); @@ -155,11 +162,25 @@ function wp_render_elements_support_styles( $pre_render, $block ) { $skip_button_color_serialization; if ( $skips_all_element_color_serialization ) { - return null; + return $parsed_block; } - $class_name = wp_get_elements_class_name( $block ); + $options = array( + 'button' => array( 'skip' => $skip_button_color_serialization ), + 'link' => array( 'skip' => $skip_link_color_serialization ), + 'heading' => array( 'skip' => $skip_heading_color_serialization ), + ); + if ( ! wp_should_add_elements_class_name( $parsed_block, $options ) ) { + return $parsed_block; + } + + $class_name = wp_get_elements_class_name( $parsed_block ); + $updated_class_name = isset( $parsed_block['attrs']['className'] ) ? $parsed_block['attrs']['className'] . " $class_name" : $class_name; + + _wp_array_set( $parsed_block, array( 'attrs', 'className' ), $updated_class_name ); + + // Generate element styles based on selector and store in style engine for enqueuing. $element_types = array( 'button' => array( 'selector' => ".$class_name .wp-element-button, .$class_name .wp-block-button__link", @@ -225,8 +246,38 @@ function wp_render_elements_support_styles( $pre_render, $block ) { } } - return null; + return $parsed_block; } -add_filter( 'render_block', 'wp_render_elements_support', 10, 2 ); -add_filter( 'pre_render_block', 'wp_render_elements_support_styles', 10, 2 ); +/** + * Ensure the elements block support class name generated, and added to + * block attributes, in the `render_block_data` filter gets applied to the + * block's markup. + * + * @see wp_render_elements_support_styles + * @since 6.6.0 + * + * @param string $block_content Rendered block content. + * @param array $block Block object. + * + * @return string Filtered block content. + */ +function wp_render_elements_class_name( $block_content, $block ) { + $class_string = $block['attrs']['className'] ?? ''; + preg_match( '/\bwp-elements-\S+\b/', $class_string, $matches ); + + if ( empty( $matches ) ) { + return $block_content; + } + + $tags = new WP_HTML_Tag_Processor( $block_content ); + + if ( $tags->next_tag() ) { + $tags->add_class( $matches[0] ); + } + + return $tags->get_updated_html(); +} + +add_filter( 'render_block', 'wp_render_elements_class_name', 10, 2 ); +add_filter( 'render_block_data', 'wp_render_elements_support_styles', 10, 1 ); diff --git a/wp-includes/version.php b/wp-includes/version.php index 74cc3ba10b..c20f659de3 100644 --- a/wp-includes/version.php +++ b/wp-includes/version.php @@ -16,7 +16,7 @@ * * @global string $wp_version */ -$wp_version = '6.6-alpha-58073'; +$wp_version = '6.6-alpha-58074'; /** * Holds the WordPress DB revision, increments when changes are made to the WordPress DB schema.