From 225d3914380a56a5dd7d16a0e241998dae78117d Mon Sep 17 00:00:00 2001 From: tellthemachines Date: Mon, 20 Apr 2026 10:11:52 +1000 Subject: [PATCH 1/2] Ensure layout classnames are applied to the inner blocks wrapper --- src/wp-includes/block-supports/layout.php | 23 +++++++++++++++++-- tests/phpunit/tests/block-supports/layout.php | 21 +++++++++++++++++ 2 files changed, 42 insertions(+), 2 deletions(-) diff --git a/src/wp-includes/block-supports/layout.php b/src/wp-includes/block-supports/layout.php index 2f7eebd4e2cda..71acf0519c4f2 100644 --- a/src/wp-includes/block-supports/layout.php +++ b/src/wp-includes/block-supports/layout.php @@ -1271,10 +1271,29 @@ function wp_render_layout_support_flag( $block_content, $block ) { $first_chunk = $block['innerContent'][0] ?? null; if ( is_string( $first_chunk ) && count( $block['innerContent'] ) > 1 ) { $first_chunk_processor = new WP_HTML_Tag_Processor( $first_chunk ); - while ( $first_chunk_processor->next_tag() ) { - $class_attribute = $first_chunk_processor->get_attribute( 'class' ); + /* + * Use a stack to track open elements as tags are visited. Void elements + * (those without a matching closing tag) are excluded so they don't + * accumulate on the stack. At the end of the chunk, every element still + * on the stack is unclosed — meaning its closing tag lives in a later + * innerContent entry alongside the inner blocks, which makes it the + * inner-block container. Elements that open and close within this chunk + * are siblings that precede the inner blocks and should be ignored. + * The last unclosed element with a class attribute is the best candidate + * for the inner-block wrapper. + */ + $tag_stack = array(); + while ( $first_chunk_processor->next_tag( array( 'tag_closers' => 'visit' ) ) ) { + if ( $first_chunk_processor->is_tag_closer() ) { + array_pop( $tag_stack ); + } elseif ( ! WP_HTML_Processor::is_void( $first_chunk_processor->get_tag() ) ) { + $tag_stack[] = $first_chunk_processor->get_attribute( 'class' ); + } + } + foreach ( array_reverse( $tag_stack ) as $class_attribute ) { if ( is_string( $class_attribute ) && ! empty( $class_attribute ) ) { $inner_block_wrapper_classes = $class_attribute; + break; } } } diff --git a/tests/phpunit/tests/block-supports/layout.php b/tests/phpunit/tests/block-supports/layout.php index f47a7a3e35d2b..08520085e39b3 100644 --- a/tests/phpunit/tests/block-supports/layout.php +++ b/tests/phpunit/tests/block-supports/layout.php @@ -354,6 +354,27 @@ public function data_layout_support_flag_renders_classnames_on_wrapper() { ), 'expected_output' => '

A paragraph

', ), + 'outer wrapper targeted when sibling element precedes inner blocks' => array( + 'args' => array( + 'block_content' => '
Header

Inner block

', + 'block' => array( + 'blockName' => 'core/group', + 'attrs' => array( + 'layout' => array( + 'type' => 'default', + ), + ), + 'innerBlocks' => array(), + 'innerHTML' => '
Header

Inner block

', + 'innerContent' => array( + '
Header
', + null, + '
', + ), + ), + ), + 'expected_output' => '
Header

Inner block

', + ), ); } From d62365248d091cf4cd5a656e0c10bbc381f23f3f Mon Sep 17 00:00:00 2001 From: tellthemachines Date: Tue, 16 Jun 2026 14:08:41 +1000 Subject: [PATCH 2/2] add ticket tag to test --- tests/phpunit/tests/block-supports/layout.php | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/phpunit/tests/block-supports/layout.php b/tests/phpunit/tests/block-supports/layout.php index 08520085e39b3..fd6404505396f 100644 --- a/tests/phpunit/tests/block-supports/layout.php +++ b/tests/phpunit/tests/block-supports/layout.php @@ -194,6 +194,7 @@ public function test_outer_container_not_restored_for_aligned_image_block_with_t * @ticket 58548 * @ticket 60292 * @ticket 61111 + * @ticket 65101 * * @dataProvider data_layout_support_flag_renders_classnames_on_wrapper *