Skip to content

Commit a0e678d

Browse files
dmsnellglendaviesnztellthemachines
committed
HTML API: Refactor layout image container. (#72264)
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 eliminate possible parsing issues. Co-authored-by: Glen Davies <glendaviesnz@users.noreply.github.com> Co-authored-by: tellthemachines <isabel@tellthemachines.com> Github-PR: 72264 Github-PR-URL: #72264 Core-Backport-PR: WordPress/wordpress-develop#10218 Core-Backport-PR-URL: WordPress/wordpress-develop#10218
1 parent f05fe79 commit a0e678d

File tree

3 files changed

+42
-37
lines changed

3 files changed

+42
-37
lines changed

backport-changelog/6.9/10218.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
https://github.com/WordPress/wordpress-develop/pull/10218
2+
3+
* https://github.com/WordPress/gutenberg/pull/72264

lib/block-supports/layout.php

Lines changed: 38 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1113,7 +1113,6 @@ static function ( $matches ) {
11131113
}
11141114
add_filter( 'render_block_core/group', 'gutenberg_restore_group_inner_container', 10, 2 );
11151115

1116-
11171116
/**
11181117
* For themes without theme.json file, make sure
11191118
* to restore the outer div for the aligned image block
@@ -1124,50 +1123,53 @@ static function ( $matches ) {
11241123
* @return string Filtered block content.
11251124
*/
11261125
function gutenberg_restore_image_outer_container( $block_content, $block ) {
1127-
$image_with_align = "
1128-
/# 1) everything up to the class attribute contents
1129-
(
1130-
^\s*
1131-
<figure\b
1132-
[^>]*
1133-
\bclass=
1134-
[\"']
1135-
)
1136-
# 2) the class attribute contents
1137-
(
1138-
[^\"']*
1139-
\bwp-block-image\b
1140-
[^\"']*
1141-
\b(?:alignleft|alignright|aligncenter)\b
1142-
[^\"']*
1143-
)
1144-
# 3) everything after the class attribute contents
1145-
(
1146-
[\"']
1147-
[^>]*
1148-
>
1149-
.*
1150-
<\/figure>
1151-
)/iUx";
1126+
if ( wp_theme_has_theme_json() ) {
1127+
return $block_content;
1128+
}
11521129

1130+
$figure_processor = new WP_HTML_Tag_Processor( $block_content );
11531131
if (
1154-
wp_theme_has_theme_json() ||
1155-
0 === preg_match( $image_with_align, $block_content, $matches )
1132+
! $figure_processor->next_tag( 'FIGURE' ) ||
1133+
! $figure_processor->has_class( 'wp-block-image' ) ||
1134+
! (
1135+
$figure_processor->has_class( 'alignleft' ) ||
1136+
$figure_processor->has_class( 'aligncenter' ) ||
1137+
$figure_processor->has_class( 'alignright' )
1138+
)
11561139
) {
11571140
return $block_content;
11581141
}
11591142

1160-
$wrapper_classnames = array( 'wp-block-image' );
1143+
/*
1144+
* The next section of code wraps the existing figure in a new DIV element.
1145+
* While doing it, it needs to transfer the layout and the additional CSS
1146+
* class names from the original figure upward to the wrapper.
1147+
*
1148+
* Example:
1149+
*
1150+
* // From this…
1151+
* <!-- wp:image {"className":"hires"} -->
1152+
* <figure class="wp-block-image wide hires">…
1153+
*
1154+
* // To this…
1155+
* <div class="wp-block-image hires"><figure class="wide">…
1156+
*/
1157+
$wrapper_processor = new WP_HTML_Tag_Processor( '<div>' );
1158+
$wrapper_processor->next_token();
1159+
$wrapper_processor->set_attribute(
1160+
'class',
1161+
is_string( $block['attrs']['className'] ?? null )
1162+
? "wp-block-image {$block['attrs']['className']}"
1163+
: 'wp-block-image'
1164+
);
11611165

1162-
// If the block has a classNames attribute these classnames need to be removed from the content and added back
1163-
// to the new wrapper div also.
1164-
if ( ! empty( $block['attrs']['className'] ) ) {
1165-
$wrapper_classnames = array_merge( $wrapper_classnames, explode( ' ', $block['attrs']['className'] ) );
1166+
// And remove them from the existing content; it has been transferred upward.
1167+
$figure_processor->remove_class( 'wp-block-image' );
1168+
foreach ( $wrapper_processor->class_list() as $class_name ) {
1169+
$figure_processor->remove_class( $class_name );
11661170
}
1167-
$content_classnames = explode( ' ', $matches[2] );
1168-
$filtered_content_classnames = array_diff( $content_classnames, $wrapper_classnames );
11691171

1170-
return '<div class="' . implode( ' ', $wrapper_classnames ) . '">' . $matches[1] . implode( ' ', $filtered_content_classnames ) . $matches[3] . '</div>';
1172+
return "{$wrapper_processor->get_updated_html()}{$figure_processor->get_updated_html()}</div>";
11711173
}
11721174

11731175
if ( function_exists( 'wp_restore_image_outer_container' ) ) {

phpunit/block-supports/layout-test.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ public function test_additional_styles_moved_to_restored_outer_container_for_ali
9999
$this->assertSame( $expected, gutenberg_restore_image_outer_container( $block_classes_random_placement, $block ) );
100100

101101
$block_classes_other_attributes = '<figure style="color: red" class=\'is-style-round wp-block-image alignright my-custom-classname size-full\' data-random-tag=">"><img src="/my-image.jpg"/></figure>';
102-
$expected_other_attributes = '<div class="wp-block-image is-style-round my-custom-classname"><figure style="color: red" class=\'alignright size-full\' data-random-tag=">"><img src="/my-image.jpg"/></figure></div>';
102+
$expected_other_attributes = '<div class="wp-block-image is-style-round my-custom-classname"><figure style="color: red" class="alignright size-full" data-random-tag=">"><img src="/my-image.jpg"/></figure></div>';
103103

104104
$this->assertSame( $expected_other_attributes, gutenberg_restore_image_outer_container( $block_classes_other_attributes, $block ) );
105105
}

0 commit comments

Comments
 (0)