Make WordPress Core

Changeset 60968


Ignore:
Timestamp:
10/17/2025 11:52:41 PM (5 months ago)
Author:
dmsnell
Message:

HTML API: Backport from Gutenberg of layout image container refactor.

For classic themes, image blocks need to create a DIV wrapper which contains alignment classes from the inner FIGURE. This has been processed using PCRE matching.

With this change the HTML API is used instead of PCRE functions to provide more semantic transformation, clearer intent, and to eliminate possible parsing issues.

Developed in https://github.com/WordPress/wordpress-develop/pull/10218
Discussed in https://core.trac.wordpress.org/ticket/63694

Gutenberg patch in https://github.com/WordPress/gutenberg/pull/72264

Props dmsnell, isabel_brison.
See #63694.

Location:
trunk
Files:
2 edited

Legend:

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

    r60651 r60968  
    10751075 */
    10761076function wp_restore_image_outer_container( $block_content, $block ) {
    1077     $image_with_align = "
    1078 /# 1) everything up to the class attribute contents
    1079 (
    1080     ^\s*
    1081     <figure\b
    1082     [^>]*
    1083     \bclass=
    1084     [\"']
    1085 )
    1086 # 2) the class attribute contents
    1087 (
    1088     [^\"']*
    1089     \bwp-block-image\b
    1090     [^\"']*
    1091     \b(?:alignleft|alignright|aligncenter)\b
    1092     [^\"']*
    1093 )
    1094 # 3) everything after the class attribute contents
    1095 (
    1096     [\"']
    1097     [^>]*
    1098     >
    1099     .*
    1100     <\/figure>
    1101 )/iUx";
    1102 
     1077    if ( wp_theme_has_theme_json() ) {
     1078        return $block_content;
     1079    }
     1080
     1081    $figure_processor = new WP_HTML_Tag_Processor( $block_content );
    11031082    if (
    1104         wp_theme_has_theme_json() ||
    1105         0 === preg_match( $image_with_align, $block_content, $matches )
     1083        ! $figure_processor->next_tag( 'FIGURE' ) ||
     1084        ! $figure_processor->has_class( 'wp-block-image' ) ||
     1085        ! (
     1086            $figure_processor->has_class( 'alignleft' ) ||
     1087            $figure_processor->has_class( 'aligncenter' ) ||
     1088            $figure_processor->has_class( 'alignright' )
     1089        )
    11061090    ) {
    11071091        return $block_content;
    11081092    }
    11091093
    1110     $wrapper_classnames = array( 'wp-block-image' );
    1111 
    1112     // If the block has a classNames attribute these classnames need to be removed from the content and added back
    1113     // to the new wrapper div also.
    1114     if ( ! empty( $block['attrs']['className'] ) ) {
    1115         $wrapper_classnames = array_merge( $wrapper_classnames, explode( ' ', $block['attrs']['className'] ) );
    1116     }
    1117     $content_classnames          = explode( ' ', $matches[2] );
    1118     $filtered_content_classnames = array_diff( $content_classnames, $wrapper_classnames );
    1119 
    1120     return '<div class="' . implode( ' ', $wrapper_classnames ) . '">' . $matches[1] . implode( ' ', $filtered_content_classnames ) . $matches[3] . '</div>';
     1094    /*
     1095     * The next section of code wraps the existing figure in a new DIV element.
     1096     * While doing it, it needs to transfer the layout and the additional CSS
     1097     * class names from the original figure upward to the wrapper.
     1098     *
     1099     * Example:
     1100     *
     1101     *     // From this…
     1102     *     <!-- wp:image {"className":"hires"} -->
     1103     *     <figure class="wp-block-image wide hires">…
     1104     *
     1105     *     // To this…
     1106     *     <div class="wp-block-image hires"><figure class="wide">…
     1107     */
     1108    $wrapper_processor = new WP_HTML_Tag_Processor( '<div>' );
     1109    $wrapper_processor->next_token();
     1110    $wrapper_processor->set_attribute(
     1111        'class',
     1112        is_string( $block['attrs']['className'] ?? null )
     1113            ? "wp-block-image {$block['attrs']['className']}"
     1114            : 'wp-block-image'
     1115    );
     1116
     1117    // And remove them from the existing content; it has been transferred upward.
     1118    $figure_processor->remove_class( 'wp-block-image' );
     1119    foreach ( $wrapper_processor->class_list() as $class_name ) {
     1120        $figure_processor->remove_class( $class_name );
     1121    }
     1122
     1123    return "{$wrapper_processor->get_updated_html()}{$figure_processor->get_updated_html()}</div>";
    11211124}
    11221125
  • trunk/tests/phpunit/tests/block-supports/layout.php

    r60727 r60968  
    7575        $expected      = '<figure class="wp-block-image size-full"><img src="/my-image.jpg"/></figure>';
    7676
    77         $this->assertSame( $expected, wp_restore_image_outer_container( $block_content, $block ) );
     77        $this->assertEqualHTML( $expected, wp_restore_image_outer_container( $block_content, $block ) );
    7878    }
    7979
     
    9191        $expected      = '<div class="wp-block-image"><figure class="alignright size-full"><img src="/my-image.jpg"/></figure></div>';
    9292
    93         $this->assertSame( $expected, wp_restore_image_outer_container( $block_content, $block ) );
     93        $this->assertEqualHTML( $expected, wp_restore_image_outer_container( $block_content, $block ) );
    9494    }
    9595
     
    112112        );
    113113
    114         $this->assertSame( $expected, wp_restore_image_outer_container( $block_image_html, $block ) );
     114        $this->assertEqualHTML( $expected, wp_restore_image_outer_container( $block_image_html, $block ) );
    115115    }
    116116
     
    166166        $expected      = '<figure class="wp-block-image alignright size-full is-style-round my-custom-classname"><img src="/my-image.jpg"/></figure>';
    167167
    168         $this->assertSame( $expected, wp_restore_image_outer_container( $block_content, $block ) );
     168        $this->assertEqualHTML( $expected, wp_restore_image_outer_container( $block_content, $block ) );
    169169    }
    170170
Note: See TracChangeset for help on using the changeset viewer.