@@ -1050,10 +1050,30 @@ function gutenberg_render_layout_support_flag( $block_content, $block ) {
10501050 $ first_chunk = $ block ['innerContent ' ][0 ] ?? null ;
10511051 if ( is_string ( $ first_chunk ) && count ( $ block ['innerContent ' ] ) > 1 ) {
10521052 $ first_chunk_processor = new WP_HTML_Tag_Processor ( $ first_chunk );
1053- while ( $ first_chunk_processor ->next_tag () ) {
1054- $ class_attribute = $ first_chunk_processor ->get_attribute ( 'class ' );
1053+ /*
1054+ * Use a stack to track open elements as tags are visited. Void elements
1055+ * (those without a matching closing tag) are excluded so they don't
1056+ * accumulate on the stack. At the end of the chunk, every element still
1057+ * on the stack is unclosed — meaning its closing tag lives in a later
1058+ * innerContent entry alongside the inner blocks, which makes it the
1059+ * inner-block container. Elements that open and close within this chunk
1060+ * are siblings that precede the inner blocks and should be ignored.
1061+ * The last unclosed element with a class attribute is the best candidate
1062+ * for the inner-block wrapper.
1063+ */
1064+ $ tag_stack = array ();
1065+ $ html_void_elements = array ( 'area ' , 'base ' , 'br ' , 'col ' , 'embed ' , 'hr ' , 'img ' , 'input ' , 'link ' , 'meta ' , 'param ' , 'source ' , 'track ' , 'wbr ' );
1066+ while ( $ first_chunk_processor ->next_tag ( array ( 'tag_closers ' => 'visit ' ) ) ) {
1067+ if ( $ first_chunk_processor ->is_tag_closer () ) {
1068+ array_pop ( $ tag_stack );
1069+ } elseif ( ! in_array ( strtolower ( $ first_chunk_processor ->get_tag () ), $ html_void_elements , true ) ) {
1070+ $ tag_stack [] = $ first_chunk_processor ->get_attribute ( 'class ' );
1071+ }
1072+ }
1073+ foreach ( array_reverse ( $ tag_stack ) as $ class_attribute ) {
10551074 if ( is_string ( $ class_attribute ) && ! empty ( $ class_attribute ) ) {
10561075 $ inner_block_wrapper_classes = $ class_attribute ;
1076+ break ;
10571077 }
10581078 }
10591079 }
0 commit comments