Make WordPress Core


Ignore:
Timestamp:
03/19/2026 02:39:42 PM (7 months ago)
Author:
wildworks
Message:

Blocks: Fix wrapper attribute merging in get_block_wrapper_attributes().

Replace the previous generic concatenation logic in get_block_wrapper_attributes() with attribute-specific merge behavior:

  • Add explicit merge callbacks for each attribute.
  • Merge style values safely, normalize trailing semicolons, and sanitize the result.
  • Merge class values with deduplication .
  • Treat id and aria-label as override attributes, giving precedence to explicitly passed extra attributes.

Props adrock42, mamaduka, r1k0, westonruter, wildworks.

Fixes #64603.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/wp-includes/class-wp-block-supports.php

    r59925 r62068  
    180180        }
    181181
    182         // This is hardcoded on purpose.
    183         // We only support a fixed list of attributes.
    184         $attributes_to_merge = array( 'style', 'class', 'id', 'aria-label' );
    185         $attributes          = array();
    186         foreach ( $attributes_to_merge as $attribute_name ) {
    187                 if ( empty( $new_attributes[ $attribute_name ] ) && empty( $extra_attributes[ $attribute_name ] ) ) {
     182        // Attribute values are concatenated or overridden depending on the attribute type.
     183        // This is hardcoded on purpose, as we only support a fixed list of attributes.
     184        $attribute_merge_callbacks = array(
     185                'style'      => static function ( $new_attribute, $extra_attribute ) {
     186                        $styles = array_filter(
     187                                array(
     188                                        rtrim( trim( $new_attribute ), ';' ),
     189                                        rtrim( trim( $extra_attribute ), ';' ),
     190                                )
     191                        );
     192                        return safecss_filter_attr( implode( ';', array_filter( $styles ) ) );
     193                },
     194                'class'      => static function ( $new_attribute, $extra_attribute ) {
     195                        $classes = array_merge(
     196                                (array) preg_split( '/\s+/', $extra_attribute, -1, PREG_SPLIT_NO_EMPTY ),
     197                                (array) preg_split( '/\s+/', $new_attribute, -1, PREG_SPLIT_NO_EMPTY )
     198                        );
     199                        $classes = array_unique( array_filter( $classes ) );
     200                        return implode( ' ', $classes );
     201                },
     202                'id'         => static function ( $new_attribute, $extra_attribute ) {
     203                        return '' !== $extra_attribute ? $extra_attribute : $new_attribute;
     204                },
     205                'aria-label' => static function ( $new_attribute, $extra_attribute ) {
     206                        return '' !== $extra_attribute ? $extra_attribute : $new_attribute;
     207                },
     208        );
     209
     210        $attributes = array();
     211        foreach ( $attribute_merge_callbacks as $attribute_name => $merge_callback ) {
     212                $new_attribute   = $new_attributes[ $attribute_name ] ?? '';
     213                $extra_attribute = $extra_attributes[ $attribute_name ] ?? '';
     214                $new_attribute   = is_string( $new_attribute ) ? $new_attribute : '';
     215                $extra_attribute = is_string( $extra_attribute ) ? $extra_attribute : '';
     216
     217                if ( '' === $new_attribute && '' === $extra_attribute ) {
    188218                        continue;
    189219                }
    190220
    191                 if ( empty( $new_attributes[ $attribute_name ] ) ) {
    192                         $attributes[ $attribute_name ] = $extra_attributes[ $attribute_name ];
    193                         continue;
    194                 }
    195 
    196                 if ( empty( $extra_attributes[ $attribute_name ] ) ) {
    197                         $attributes[ $attribute_name ] = $new_attributes[ $attribute_name ];
    198                         continue;
    199                 }
    200 
    201                 $attributes[ $attribute_name ] = $extra_attributes[ $attribute_name ] . ' ' . $new_attributes[ $attribute_name ];
     221                $attributes[ $attribute_name ] = $merge_callback( $new_attribute, $extra_attribute );
    202222        }
    203223
    204224        foreach ( $extra_attributes as $attribute_name => $value ) {
    205                 if ( ! in_array( $attribute_name, $attributes_to_merge, true ) ) {
     225                if ( ! isset( $attribute_merge_callbacks[ $attribute_name ] ) ) {
    206226                        $attributes[ $attribute_name ] = $value;
    207227                }
Note: See TracChangeset for help on using the changeset viewer.