Skip to content

Commit c8f7e7d

Browse files
Editor: ensure layout classnames are applied to the inner blocks wrapper.
Checks that the element classnames get added to doesn’t have a closing tag before the inner blocks start. Props isabel_brison, andrewserong, @darshitrajyaguru97, @tusharaddweb, @gaurangsondagar. Fixes #65101. git-svn-id: https://develop.svn.wordpress.org/trunk@62504 602fd350-edb4-49c9-b593-d223f7449a82
1 parent 2f682ae commit c8f7e7d

2 files changed

Lines changed: 43 additions & 2 deletions

File tree

src/wp-includes/block-supports/layout.php

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1271,10 +1271,29 @@ function wp_render_layout_support_flag( $block_content, $block ) {
12711271
$first_chunk = $block['innerContent'][0] ?? null;
12721272
if ( is_string( $first_chunk ) && count( $block['innerContent'] ) > 1 ) {
12731273
$first_chunk_processor = new WP_HTML_Tag_Processor( $first_chunk );
1274-
while ( $first_chunk_processor->next_tag() ) {
1275-
$class_attribute = $first_chunk_processor->get_attribute( 'class' );
1274+
/*
1275+
* Use a stack to track open elements as tags are visited. Void elements
1276+
* (those without a matching closing tag) are excluded so they don't
1277+
* accumulate on the stack. At the end of the chunk, every element still
1278+
* on the stack is unclosed — meaning its closing tag lives in a later
1279+
* innerContent entry alongside the inner blocks, which makes it the
1280+
* inner-block container. Elements that open and close within this chunk
1281+
* are siblings that precede the inner blocks and should be ignored.
1282+
* The last unclosed element with a class attribute is the best candidate
1283+
* for the inner-block wrapper.
1284+
*/
1285+
$tag_stack = array();
1286+
while ( $first_chunk_processor->next_tag( array( 'tag_closers' => 'visit' ) ) ) {
1287+
if ( $first_chunk_processor->is_tag_closer() ) {
1288+
array_pop( $tag_stack );
1289+
} elseif ( ! WP_HTML_Processor::is_void( $first_chunk_processor->get_tag() ) ) {
1290+
$tag_stack[] = $first_chunk_processor->get_attribute( 'class' );
1291+
}
1292+
}
1293+
foreach ( array_reverse( $tag_stack ) as $class_attribute ) {
12761294
if ( is_string( $class_attribute ) && ! empty( $class_attribute ) ) {
12771295
$inner_block_wrapper_classes = $class_attribute;
1296+
break;
12781297
}
12791298
}
12801299
}

tests/phpunit/tests/block-supports/layout.php

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -194,6 +194,7 @@ public function test_outer_container_not_restored_for_aligned_image_block_with_t
194194
* @ticket 58548
195195
* @ticket 60292
196196
* @ticket 61111
197+
* @ticket 65101
197198
*
198199
* @dataProvider data_layout_support_flag_renders_classnames_on_wrapper
199200
*
@@ -354,6 +355,27 @@ public function data_layout_support_flag_renders_classnames_on_wrapper() {
354355
),
355356
'expected_output' => '<p>A paragraph</p>',
356357
),
358+
'outer wrapper targeted when sibling element precedes inner blocks' => array(
359+
'args' => array(
360+
'block_content' => '<div class="wp-block-group"><div class="wp-block-group__header">Header</div><p>Inner block</p></div>',
361+
'block' => array(
362+
'blockName' => 'core/group',
363+
'attrs' => array(
364+
'layout' => array(
365+
'type' => 'default',
366+
),
367+
),
368+
'innerBlocks' => array(),
369+
'innerHTML' => '<div class="wp-block-group"><div class="wp-block-group__header">Header</div><p>Inner block</p></div>',
370+
'innerContent' => array(
371+
'<div class="wp-block-group"><div class="wp-block-group__header">Header</div>',
372+
null,
373+
'</div>',
374+
),
375+
),
376+
),
377+
'expected_output' => '<div class="wp-block-group is-layout-flow wp-block-group-is-layout-flow"><div class="wp-block-group__header">Header</div><p>Inner block</p></div>',
378+
),
357379
);
358380
}
359381

0 commit comments

Comments
 (0)