2020-01-18 09:38:21 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								/*
  
						 
					
						
							
								
									
										
										
										
											2021-01-07 18:00:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								 *  Copyright  ( c )  2018 - 2021 ,  Andreas  Kling  < kling @ serenityos . org > 
							 
						 
					
						
							
								
									
										
										
										
											2020-01-18 09:38:21 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								 *  All  rights  reserved . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  Redistribution  and  use  in  source  and  binary  forms ,  with  or  without 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  modification ,  are  permitted  provided  that  the  following  conditions  are  met : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  1.  Redistributions  of  source  code  must  retain  the  above  copyright  notice ,  this 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *     list  of  conditions  and  the  following  disclaimer . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  2.  Redistributions  in  binary  form  must  reproduce  the  above  copyright  notice , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *     this  list  of  conditions  and  the  following  disclaimer  in  the  documentation 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *     and / or  other  materials  provided  with  the  distribution . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  THIS  SOFTWARE  IS  PROVIDED  BY  THE  COPYRIGHT  HOLDERS  AND  CONTRIBUTORS  " AS IS " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  AND  ANY  EXPRESS  OR  IMPLIED  WARRANTIES ,  INCLUDING ,  BUT  NOT  LIMITED  TO ,  THE 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  IMPLIED  WARRANTIES  OF  MERCHANTABILITY  AND  FITNESS  FOR  A  PARTICULAR  PURPOSE  ARE 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  DISCLAIMED .  IN  NO  EVENT  SHALL  THE  COPYRIGHT  HOLDER  OR  CONTRIBUTORS  BE  LIABLE 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  FOR  ANY  DIRECT ,  INDIRECT ,  INCIDENTAL ,  SPECIAL ,  EXEMPLARY ,  OR  CONSEQUENTIAL 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  DAMAGES  ( INCLUDING ,  BUT  NOT  LIMITED  TO ,  PROCUREMENT  OF  SUBSTITUTE  GOODS  OR 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  SERVICES ;  LOSS  OF  USE ,  DATA ,  OR  PROFITS ;  OR  BUSINESS  INTERRUPTION )  HOWEVER 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  CAUSED  AND  ON  ANY  THEORY  OF  LIABILITY ,  WHETHER  IN  CONTRACT ,  STRICT  LIABILITY , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  OR  TORT  ( INCLUDING  NEGLIGENCE  OR  OTHERWISE )  ARISING  IN  ANY  WAY  OUT  OF  THE  USE 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  OF  THIS  SOFTWARE ,  EVEN  IF  ADVISED  OF  THE  POSSIBILITY  OF  SUCH  DAMAGE . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-03-07 10:32:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  <LibWeb/DOM/Document.h> 
  
						 
					
						
							
								
									
										
										
										
											2021-01-06 14:10:53 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  <LibWeb/DOM/Element.h> 
  
						 
					
						
							
								
									
										
										
										
											2020-03-07 10:32:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  <LibWeb/DOM/ParentNode.h> 
  
						 
					
						
							
								
									
										
										
										
											2021-02-10 18:23:52 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  <LibWeb/DOM/ShadowRoot.h> 
  
						 
					
						
							
								
									
										
										
										
											2021-01-07 18:00:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  <LibWeb/Dump.h> 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  <LibWeb/Layout/InitialContainingBlockBox.h> 
  
						 
					
						
							
								
									
										
										
										
											2020-11-22 15:53:01 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  <LibWeb/Layout/Node.h> 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  <LibWeb/Layout/TableBox.h> 
  
						 
					
						
							
								
									
										
										
										
											2021-01-07 18:00:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  <LibWeb/Layout/TableCellBox.h> 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  <LibWeb/Layout/TableRowBox.h> 
  
						 
					
						
							
								
									
										
										
										
											2020-11-22 15:53:01 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  <LibWeb/Layout/TextNode.h> 
  
						 
					
						
							
								
									
										
										
										
											2020-11-25 20:29:03 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  <LibWeb/Layout/TreeBuilder.h> 
  
						 
					
						
							
								
									
										
										
										
											2019-10-15 12:22:41 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-11-22 15:53:01 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								namespace  Web : : Layout  {  
						 
					
						
							
								
									
										
										
										
											2020-03-07 10:27:02 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-11-25 20:29:03 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								TreeBuilder : : TreeBuilder ( )  
						 
					
						
							
								
									
										
										
										
											2019-10-15 12:22:41 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-01-02 03:30:04 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// The insertion_parent_for_*() functions maintain the invariant that block-level boxes must have either
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// only block-level children or only inline-level children.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-01-06 14:10:53 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  Layout : : Node &  insertion_parent_for_inline_node ( Layout : : NodeWithStyle &  layout_parent )  
						 
					
						
							
								
									
										
										
										
											2020-11-26 21:18:34 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2021-01-04 22:32:34 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( layout_parent . is_inline ( )  & &  ! layout_parent . is_inline_block ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-11-26 21:18:34 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return  layout_parent ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( ! layout_parent . has_children ( )  | |  layout_parent . children_are_inline ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  layout_parent ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-01-02 03:30:04 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    // Parent has block-level children, insert into an anonymous wrapper block (and create it first if needed)
 
							 
						 
					
						
							
								
									
										
										
										
											2020-11-26 21:18:34 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( ! layout_parent . last_child ( ) - > is_anonymous ( )  | |  ! layout_parent . last_child ( ) - > children_are_inline ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-06 14:10:53 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        layout_parent . append_child ( layout_parent . create_anonymous_wrapper ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-11-26 21:18:34 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  * layout_parent . last_child ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  Layout : : Node &  insertion_parent_for_block_node ( Layout : : Node &  layout_parent ,  Layout : : Node &  layout_node )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2021-01-02 03:30:04 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( ! layout_parent . has_children ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // Parent block has no children, insert this block into parent.
 
							 
						 
					
						
							
								
									
										
										
										
											2020-11-26 21:18:34 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return  layout_parent ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-02 03:30:04 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2020-11-26 21:18:34 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-01-02 03:30:04 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( ! layout_parent . children_are_inline ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // Parent block has block-level children, insert this block into parent.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  layout_parent ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-10-17 22:42:51 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-01-02 03:30:04 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    // Parent block has inline-level children (our siblings).
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // First move these siblings into an anonymous wrapper block.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    NonnullRefPtrVector < Layout : : Node >  children ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    while  ( RefPtr < Layout : : Node >  child  =  layout_parent . first_child ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        layout_parent . remove_child ( * child ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        children . append ( child . release_nonnull ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-11-26 21:18:34 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-06 14:10:53 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    layout_parent . append_child ( adopt ( * new  BlockBox ( layout_node . document ( ) ,  nullptr ,  layout_parent . computed_values ( ) . clone_inherited_values ( ) ) ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-02 03:30:04 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    layout_parent . set_children_are_inline ( false ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    for  ( auto &  child  :  children )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        layout_parent . last_child ( ) - > append_child ( child ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    layout_parent . last_child ( ) - > set_children_are_inline ( true ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // Then it's safe to insert this block into parent.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  layout_parent ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-11-26 21:18:34 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  TreeBuilder : : create_layout_tree ( DOM : : Node &  dom_node )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // If the parent doesn't have a layout node, we don't need one either.
 
							 
						 
					
						
							
								
									
										
										
										
											2021-02-10 18:23:52 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( dom_node . parent_or_shadow_host ( )  & &  ! dom_node . parent_or_shadow_host ( ) - > layout_node ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-11-26 21:18:34 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-01-06 14:27:40 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    auto  layout_node  =  dom_node . create_layout_node ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-11-26 21:18:34 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( ! layout_node ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-10-17 23:32:08 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-02-10 18:23:52 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( ! dom_node . parent_or_shadow_host ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-11-26 21:18:34 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        m_layout_root  =  layout_node ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( layout_node - > is_inline ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            // Inlines can be inserted into the nearest ancestor.
 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-06 14:10:53 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            auto &  insertion_point  =  insertion_parent_for_inline_node ( * m_parent_stack . last ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-11-26 21:18:34 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            insertion_point . append_child ( * layout_node ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            insertion_point . set_children_are_inline ( true ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        }  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-11-29 16:11:27 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            // Non-inlines can't be inserted into an inline parent, so find the nearest non-inline ancestor.
 
							 
						 
					
						
							
								
									
										
										
										
											2020-11-29 12:39:10 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            auto &  nearest_non_inline_ancestor  =  [ & ] ( )  - >  Layout : : Node &  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-11-26 21:18:34 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                for  ( ssize_t  i  =  m_parent_stack . size ( )  -  1 ;  i  > =  0 ;  - - i )  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-11-29 22:24:53 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                    if  ( ! m_parent_stack [ i ] - > is_inline ( )  | |  m_parent_stack [ i ] - > is_inline_block ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-11-26 21:18:34 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                        return  * m_parent_stack [ i ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                } 
							 
						 
					
						
							
								
									
										
										
										
											2021-02-23 20:42:32 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                VERIFY_NOT_REACHED ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-11-26 21:18:34 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            } ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-11-29 12:39:10 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            auto &  insertion_point  =  insertion_parent_for_block_node ( nearest_non_inline_ancestor ,  * layout_node ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-11-26 21:18:34 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            insertion_point . append_child ( * layout_node ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            insertion_point . set_children_are_inline ( false ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-02-10 18:23:52 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    auto *  shadow_root  =  is < DOM : : Element > ( dom_node )  ?  downcast < DOM : : Element > ( dom_node ) . shadow_root ( )  :  nullptr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( ( dom_node . has_children ( )  | |  shadow_root )  & &  layout_node - > can_have_children ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-06 14:10:53 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        push_parent ( downcast < NodeWithStyle > ( * layout_node ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-02-10 18:23:52 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( shadow_root ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            create_layout_tree ( * shadow_root ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-11-26 21:18:34 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        downcast < DOM : : ParentNode > ( dom_node ) . for_each_child ( [ & ] ( auto &  dom_child )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            create_layout_tree ( dom_child ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        pop_parent ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2019-10-15 12:22:41 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-11-26 21:18:34 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								RefPtr < Node >  TreeBuilder : : build ( DOM : : Node &  dom_node )  
						 
					
						
							
								
									
										
										
										
											2019-10-15 12:22:41 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2020-11-29 16:11:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( dom_node . parent ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // We're building a partial layout tree, so start by building up the stack of parent layout nodes.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        for  ( auto *  ancestor  =  dom_node . parent ( ) - > layout_node ( ) ;  ancestor ;  ancestor  =  ancestor - > parent ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-06 14:10:53 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            m_parent_stack . prepend ( downcast < NodeWithStyle > ( ancestor ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-06 22:13:24 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2020-11-26 21:18:34 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    create_layout_tree ( dom_node ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-07 18:00:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( auto *  root  =  dom_node . document ( ) . layout_node ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        fixup_tables ( * root ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-11-26 21:18:34 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    return  move ( m_layout_root ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-10-15 12:22:41 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2020-03-07 10:27:02 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-01-07 18:00:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								template < CSS : : Display  display ,  typename  Callback >  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  TreeBuilder : : for_each_in_tree_with_display ( NodeWithStyle &  root ,  Callback  callback )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2021-04-06 18:38:10 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    root . for_each_in_inclusive_subtree_of_type < Box > ( [ & ] ( auto &  box )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-07 18:00:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( box . computed_values ( ) . display ( )  = =  display ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            callback ( box ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  IterationDecision : : Continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  TreeBuilder : : fixup_tables ( NodeWithStyle &  root )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // NOTE: Even if we only do a partial build, we always do fixup from the root.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    remove_irrelevant_boxes ( root ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    generate_missing_child_wrappers ( root ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    generate_missing_parents ( root ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  TreeBuilder : : remove_irrelevant_boxes ( NodeWithStyle &  root )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // The following boxes are discarded as if they were display:none:
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    NonnullRefPtrVector < Box >  to_remove ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // Children of a table-column.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    for_each_in_tree_with_display < CSS : : Display : : TableColumn > ( root ,  [ & ] ( Box &  table_column )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        table_column . for_each_child ( [ & ] ( auto &  child )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            to_remove . append ( child ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // Children of a table-column-group which are not a table-column.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    for_each_in_tree_with_display < CSS : : Display : : TableColumnGroup > ( root ,  [ & ] ( Box &  table_column_group )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        table_column_group . for_each_child ( [ & ] ( auto &  child )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( child . computed_values ( ) . display ( )  ! =  CSS : : Display : : TableColumn ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                to_remove . append ( child ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // FIXME:
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // Anonymous inline boxes which contain only white space and are between two immediate siblings each of which is a table-non-root box.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // Anonymous inline boxes which meet all of the following criteria:
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // - they contain only white space
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // - they are the first and/or last child of a tabular container
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // - whose immediate sibling, if any, is a table-non-root box
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    for  ( auto &  box  :  to_remove ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        box . parent ( ) - > remove_child ( box ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  bool  is_table_track ( CSS : : Display  display )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  display  = =  CSS : : Display : : TableRow  | |  display  = =  CSS : : Display : : TableColumn ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  bool  is_table_track_group ( CSS : : Display  display )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2021-04-18 18:21:26 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    // Unless explicitly mentioned otherwise, mentions of table-row-groups in this spec also encompass the specialized
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // table-header-groups and table-footer-groups.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  display  = =  CSS : : Display : : TableRowGroup  | |  display  = =  CSS : : Display : : TableHeaderGroup  | |  display  = =  CSS : : Display : : TableFooterGroup 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        | |  display  = =  CSS : : Display : : TableColumnGroup ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-07 18:00:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  bool  is_not_proper_table_child ( const  Node &  node )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( ! node . has_style ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  display  =  node . computed_values ( ) . display ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  ! is_table_track_group ( display )  & &  ! is_table_track ( display )  & &  display  ! =  CSS : : Display : : TableCaption ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  bool  is_not_table_row ( const  Node &  node )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( ! node . has_style ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  display  =  node . computed_values ( ) . display ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  display  ! =  CSS : : Display : : TableRow ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  bool  is_not_table_cell ( const  Node &  node )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( ! node . has_style ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  display  =  node . computed_values ( ) . display ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  display  ! =  CSS : : Display : : TableCell ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								template < typename  Matcher ,  typename  Callback >  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  void  for_each_sequence_of_consecutive_children_matching ( NodeWithStyle &  parent ,  Matcher  matcher ,  Callback  callback )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    NonnullRefPtrVector < Node >  sequence ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    Node *  next_sibling  =  nullptr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    for  ( auto *  child  =  parent . first_child ( ) ;  child ;  child  =  next_sibling )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        next_sibling  =  child - > next_sibling ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( matcher ( * child ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            sequence . append ( * child ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( ! sequence . is_empty ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                callback ( sequence ,  next_sibling ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                sequence . clear ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( ! sequence . is_empty ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        callback ( sequence ,  nullptr ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								template < typename  WrapperBoxType >  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  void  wrap_in_anonymous ( NonnullRefPtrVector < Node > &  sequence ,  Node *  nearest_sibling )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2021-02-23 20:42:32 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    VERIFY ( ! sequence . is_empty ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-07 18:00:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    auto &  parent  =  * sequence . first ( ) . parent ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  computed_values  =  parent . computed_values ( ) . clone_inherited_values ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    static_cast < CSS : : MutableComputedValues & > ( computed_values ) . set_display ( WrapperBoxType : : static_display ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  wrapper  =  adopt ( * new  WrapperBoxType ( parent . document ( ) ,  nullptr ,  move ( computed_values ) ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    for  ( auto &  child  :  sequence )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        parent . remove_child ( child ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        wrapper - > append_child ( child ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( nearest_sibling ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        parent . insert_before ( move ( wrapper ) ,  * nearest_sibling ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        parent . append_child ( move ( wrapper ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  TreeBuilder : : generate_missing_child_wrappers ( NodeWithStyle &  root )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // An anonymous table-row box must be generated around each sequence of consecutive children of a table-root box which are not proper table child boxes.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    for_each_in_tree_with_display < CSS : : Display : : Table > ( root ,  [ & ] ( auto &  parent )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        for_each_sequence_of_consecutive_children_matching ( parent ,  is_not_proper_table_child ,  [ & ] ( auto  sequence ,  auto  nearest_sibling )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            wrap_in_anonymous < TableRowBox > ( sequence ,  nearest_sibling ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // An anonymous table-row box must be generated around each sequence of consecutive children of a table-row-group box which are not table-row boxes.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    for_each_in_tree_with_display < CSS : : Display : : TableRowGroup > ( root ,  [ & ] ( auto &  parent )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        for_each_sequence_of_consecutive_children_matching ( parent ,  is_not_table_row ,  [ & ] ( auto &  sequence ,  auto  nearest_sibling )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            wrap_in_anonymous < TableRowBox > ( sequence ,  nearest_sibling ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-18 18:21:26 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    // Unless explicitly mentioned otherwise, mentions of table-row-groups in this spec also encompass the specialized
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // table-header-groups and table-footer-groups.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    for_each_in_tree_with_display < CSS : : Display : : TableHeaderGroup > ( root ,  [ & ] ( auto &  parent )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        for_each_sequence_of_consecutive_children_matching ( parent ,  is_not_table_row ,  [ & ] ( auto &  sequence ,  auto  nearest_sibling )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            wrap_in_anonymous < TableRowBox > ( sequence ,  nearest_sibling ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    for_each_in_tree_with_display < CSS : : Display : : TableFooterGroup > ( root ,  [ & ] ( auto &  parent )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        for_each_sequence_of_consecutive_children_matching ( parent ,  is_not_table_row ,  [ & ] ( auto &  sequence ,  auto  nearest_sibling )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            wrap_in_anonymous < TableRowBox > ( sequence ,  nearest_sibling ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-07 18:00:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // An anonymous table-cell box must be generated around each sequence of consecutive children of a table-row box which are not table-cell boxes. !Testcase
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    for_each_in_tree_with_display < CSS : : Display : : TableRow > ( root ,  [ & ] ( auto &  parent )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        for_each_sequence_of_consecutive_children_matching ( parent ,  is_not_table_cell ,  [ & ] ( auto &  sequence ,  auto  nearest_sibling )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            wrap_in_anonymous < TableCellBox > ( sequence ,  nearest_sibling ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  TreeBuilder : : generate_missing_parents ( NodeWithStyle & )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // FIXME: Implement.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-03-07 10:27:02 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}