Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 21 additions & 2 deletions src/wp-includes/block-supports/layout.php
Original file line number Diff line number Diff line change
Expand Up @@ -1008,10 +1008,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;
}
}
}
Expand Down
21 changes: 21 additions & 0 deletions tests/phpunit/tests/block-supports/layout.php
Original file line number Diff line number Diff line change
Expand Up @@ -354,6 +354,27 @@ public function data_layout_support_flag_renders_classnames_on_wrapper() {
),
'expected_output' => '<p>A paragraph</p>',
),
'outer wrapper targeted when sibling element precedes inner blocks' => array(
'args' => array(
'block_content' => '<div class="wp-block-group"><div class="wp-block-group__header">Header</div><p>Inner block</p></div>',
'block' => array(
'blockName' => 'core/group',
'attrs' => array(
'layout' => array(
'type' => 'default',
),
),
'innerBlocks' => array(),
'innerHTML' => '<div class="wp-block-group"><div class="wp-block-group__header">Header</div><p>Inner block</p></div>',
'innerContent' => array(
'<div class="wp-block-group"><div class="wp-block-group__header">Header</div>',
null,
'</div>',
),
),
),
'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>',
),
);
}

Expand Down
Loading