2020-01-18 09:38:21 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								/*
  
						 
					
						
							
								
									
										
										
										
											2022-02-21 01:43:37 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								 *  Copyright  ( c )  2018 - 2022 ,  Andreas  Kling  < kling @ serenityos . org > 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-25 11:59:56 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								 *  Copyright  ( c )  2022 ,  Sam  Atkins  < atkinssj @ serenityos . org > 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-22 16:08:03 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								 *  Copyright  ( c )  2022 ,  MacDue  < macdue @ dueutil . tech > 
							 
						 
					
						
							
								
									
										
										
										
											2020-01-18 09:38:21 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								 * 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-22 01:24:48 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								 *  SPDX - License - Identifier :  BSD - 2 - Clause 
							 
						 
					
						
							
								
									
										
										
										
											2020-01-18 09:38:21 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-08-05 10:26:09 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  <AK/Optional.h> 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  <AK/TemporaryChange.h> 
  
						 
					
						
							
								
									
										
										
										
											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> 
  
						 
					
						
							
								
									
										
										
										
											2022-07-22 16:08:03 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  <LibWeb/HTML/HTMLProgressElement.h> 
  
						 
					
						
							
								
									
										
										
										
											2021-09-08 11:27:46 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  <LibWeb/Layout/InitialContainingBlock.h> 
  
						 
					
						
							
								
									
										
										
										
											2022-02-21 01:43:37 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  <LibWeb/Layout/ListItemBox.h> 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  <LibWeb/Layout/ListItemMarkerBox.h> 
  
						 
					
						
							
								
									
										
										
										
											2020-11-22 15:53:01 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  <LibWeb/Layout/Node.h> 
  
						 
					
						
							
								
									
										
										
										
											2022-07-22 16:08:03 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  <LibWeb/Layout/Progress.h> 
  
						 
					
						
							
								
									
										
										
										
											2020-11-22 15:53:01 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# 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 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-03-14 13:21:51 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								TreeBuilder : : TreeBuilder ( )  =  default ;  
						 
					
						
							
								
									
										
										
										
											2019-10-15 12:22:41 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-03-22 19:13:55 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  bool  has_inline_or_in_flow_block_children ( Layout : : Node  const &  layout_node )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    for  ( auto  const *  child  =  layout_node . first_child ( ) ;  child ;  child  =  child - > next_sibling ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( child - > is_inline ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            return  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( ! child - > is_floating ( )  & &  ! child - > is_absolutely_positioned ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            return  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  bool  has_in_flow_block_children ( Layout : : Node  const &  layout_node )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( layout_node . children_are_inline ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    for  ( auto  const *  child  =  layout_node . first_child ( ) ;  child ;  child  =  child - > next_sibling ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( child - > is_inline ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( ! child - > is_floating ( )  & &  ! child - > is_absolutely_positioned ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            return  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// The insertion_parent_for_*() functions maintain the invariant that the in-flow children of
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// block-level boxes must be either all block-level or all inline-level.
  
						 
					
						
							
								
									
										
										
										
											2021-01-02 03:30:04 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											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 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-10-06 17:57:44 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( layout_parent . computed_values ( ) . display ( ) . is_flex_inside ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-29 17:18:49 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        layout_parent . append_child ( layout_parent . create_anonymous_wrapper ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-13 01:18:59 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return  * layout_parent . last_child ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-29 17:18:49 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-03-22 19:13:55 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( ! has_in_flow_block_children ( layout_parent )  | |  layout_parent . children_are_inline ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-11-26 21:18:34 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        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 ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-03-24 18:03:58 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  Layout : : Node &  insertion_parent_for_block_node ( Layout : : NodeWithStyle &  layout_parent ,  Layout : : Node &  layout_node )  
						 
					
						
							
								
									
										
										
										
											2020-11-26 21:18:34 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2022-03-22 19:13:55 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( ! has_inline_or_in_flow_block_children ( layout_parent ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-02 03:30:04 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        // 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 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-03-22 19:13:55 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( layout_node . is_floating ( )  | |  layout_node . is_absolutely_positioned ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // Block is out-of-flow, it can have inline siblings if necessary.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  layout_parent ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											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 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-24 18:03:58 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    layout_parent . append_child ( layout_parent . create_anonymous_wrapper ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											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 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-08-05 10:26:09 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								void  TreeBuilder : : create_layout_tree ( DOM : : Node &  dom_node ,  TreeBuilder : : Context &  context )  
						 
					
						
							
								
									
										
										
										
											2020-11-26 21:18:34 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // 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-08-05 10:26:09 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    Optional < TemporaryChange < bool > >  has_svg_root_change ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( dom_node . is_svg_container ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        has_svg_root_change . emplace ( context . has_svg_root ,  true ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    }  else  if  ( dom_node . requires_svg_container ( )  & &  ! context . has_svg_root )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-02-05 13:17:01 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    auto &  document  =  dom_node . document ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto &  style_computer  =  document . style_computer ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    RefPtr < Layout : : Node >  layout_node ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-12 13:24:58 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    RefPtr < CSS : : StyleProperties >  style ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-05 13:17:01 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( is < DOM : : Element > ( dom_node ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        auto &  element  =  static_cast < DOM : : Element & > ( dom_node ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-03 17:50:12 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        element . clear_pseudo_element_nodes ( { } ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-14 21:47:37 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        VERIFY ( ! element . needs_style_update ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        style  =  element . computed_css_values ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-05 13:17:01 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( style - > display ( ) . is_none ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            return ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-12 13:24:58 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        layout_node  =  element . create_layout_node ( * style ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-05 13:17:01 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    }  else  if  ( is < DOM : : Document > ( dom_node ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-12 13:24:58 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        style  =  style_computer . create_document_style ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        layout_node  =  adopt_ref ( * new  Layout : : InitialContainingBlock ( static_cast < DOM : : Document & > ( dom_node ) ,  * style ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-05 13:17:01 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    }  else  if  ( is < DOM : : Text > ( dom_node ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        layout_node  =  adopt_ref ( * new  Layout : : TextNode ( document ,  static_cast < DOM : : Text & > ( dom_node ) ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    }  else  if  ( is < DOM : : ShadowRoot > ( dom_node ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        layout_node  =  adopt_ref ( * new  Layout : : BlockContainer ( document ,  & static_cast < DOM : : ShadowRoot & > ( dom_node ) ,  CSS : : ComputedValues  { } ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-11-26 21:18:34 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( ! layout_node ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-10-17 23:32:08 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-02-25 11:59:56 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    auto  insert_node_into_inline_or_block_ancestor  =  [ this ] ( auto &  node ,  bool  prepend  =  false )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-13 18:44:14 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( node - > is_inline ( )  & &  ! ( node - > is_inline_block ( )  & &  m_ancestor_stack . last ( ) . computed_values ( ) . display ( ) . is_flex_inside ( ) ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-11-26 21:18:34 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            // Inlines can be inserted into the nearest ancestor.
 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-13 18:44:14 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            auto &  insertion_point  =  insertion_parent_for_inline_node ( m_ancestor_stack . last ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-25 11:59:56 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            if  ( prepend ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                insertion_point . prepend_child ( * node ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                insertion_point . append_child ( * node ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-11-26 21:18:34 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            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.
 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-24 18:03:58 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            auto &  nearest_non_inline_ancestor  =  [ & ] ( )  - >  Layout : : NodeWithStyle &  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-13 18:44:14 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                for  ( auto &  ancestor  :  m_ancestor_stack . in_reverse ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    if  ( ! ancestor . is_inline ( )  | |  ancestor . is_inline_block ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        return  ancestor ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-11-26 21:18:34 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                } 
							 
						 
					
						
							
								
									
										
										
										
											2021-02-23 20:42:32 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                VERIFY_NOT_REACHED ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-11-26 21:18:34 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            } ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-25 11:59:56 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            auto &  insertion_point  =  insertion_parent_for_block_node ( nearest_non_inline_ancestor ,  * node ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( prepend ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                insertion_point . prepend_child ( * node ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                insertion_point . append_child ( * node ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-29 19:51:21 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            // After inserting an in-flow block-level box into a parent, mark the parent as having non-inline children.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( ! node - > is_floating ( )  & &  ! node - > is_absolutely_positioned ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                insertion_point . set_children_are_inline ( false ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-11-26 21:18:34 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-25 11:59:56 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( ! dom_node . parent_or_shadow_host ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        m_layout_root  =  layout_node ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-18 22:13:26 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    }  else  if  ( layout_node - > is_svg_box ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-13 18:44:14 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        m_ancestor_stack . last ( ) . append_child ( * layout_node ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-25 11:59:56 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        insert_node_into_inline_or_block_ancestor ( layout_node ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-11-26 21:18:34 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-03-12 13:24:58 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( layout_node - > has_style ( )  & &  style ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        static_cast < Layout : : NodeWithStyle & > ( * layout_node ) . did_insert_into_layout_tree ( * style ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-06-24 19:53:42 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    auto *  shadow_root  =  is < DOM : : Element > ( dom_node )  ?  verify_cast < DOM : : Element > ( dom_node ) . shadow_root ( )  :  nullptr ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-02-10 18:23:52 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( ( dom_node . has_children ( )  | |  shadow_root )  & &  layout_node - > can_have_children ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-24 19:53:42 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        push_parent ( verify_cast < NodeWithStyle > ( * layout_node ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-02-10 18:23:52 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( shadow_root ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-05 10:26:09 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            create_layout_tree ( * shadow_root ,  context ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-24 19:53:42 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        verify_cast < DOM : : ParentNode > ( dom_node ) . for_each_child ( [ & ] ( auto &  dom_child )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-05 10:26:09 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            create_layout_tree ( dom_child ,  context ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-11-26 21:18:34 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        pop_parent ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-21 01:43:37 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-02-25 11:59:56 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    // Add nodes for the ::before and ::after pseudo-elements.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( is < DOM : : Element > ( dom_node ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        auto &  element  =  static_cast < DOM : : Element & > ( dom_node ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        auto  create_pseudo_element_if_needed  =  [ & ] ( CSS : : Selector : : PseudoElement  pseudo_element )  - >  RefPtr < Node >  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            auto  pseudo_element_style  =  style_computer . compute_style ( element ,  pseudo_element ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            auto  pseudo_element_content  =  pseudo_element_style - > content ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            auto  pseudo_element_display  =  pseudo_element_style - > display ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            // ::before and ::after only exist if they have content. `content: normal` computes to `none` for them.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            // We also don't create them if they are `display: none`.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( pseudo_element_display . is_none ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                | |  pseudo_element_content . type  = =  CSS : : ContentData : : Type : : Normal 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                | |  pseudo_element_content . type  = =  CSS : : ContentData : : Type : : None ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                return  nullptr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( auto  pseudo_element_node  =  DOM : : Element : : create_layout_node_for_display_type ( document ,  pseudo_element_display ,  move ( pseudo_element_style ) ,  nullptr ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                // FIXME: Handle images, and multiple values
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                if  ( pseudo_element_content . type  = =  CSS : : ContentData : : Type : : String )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-08-28 13:42:07 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                    auto *  text  =  document . heap ( ) . allocate < DOM : : Text > ( document . realm ( ) ,  document ,  pseudo_element_content . data ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    auto  text_node  =  adopt_ref ( * new  TextNode ( document ,  * text ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-25 11:59:56 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                    push_parent ( verify_cast < NodeWithStyle > ( * pseudo_element_node ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    insert_node_into_inline_or_block_ancestor ( text_node ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    pop_parent ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    TODO ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                } 
							 
						 
					
						
							
								
									
										
										
										
											2022-08-28 13:42:07 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                return  pseudo_element_node . ptr ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-25 11:59:56 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            return  nullptr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        push_parent ( verify_cast < NodeWithStyle > ( * layout_node ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-03 17:50:12 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( auto  before_node  =  create_pseudo_element_if_needed ( CSS : : Selector : : PseudoElement : : Before ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-08-28 13:42:07 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            element . set_pseudo_element_node ( { } ,  CSS : : Selector : : PseudoElement : : Before ,  before_node . ptr ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-25 11:59:56 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            insert_node_into_inline_or_block_ancestor ( before_node ,  true ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-03 17:50:12 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( auto  after_node  =  create_pseudo_element_if_needed ( CSS : : Selector : : PseudoElement : : After ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-08-28 13:42:07 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            element . set_pseudo_element_node ( { } ,  CSS : : Selector : : PseudoElement : : After ,  after_node . ptr ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-25 11:59:56 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            insert_node_into_inline_or_block_ancestor ( after_node ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-03 17:50:12 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-25 11:59:56 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        pop_parent ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-02-21 01:43:37 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( is < ListItemBox > ( * layout_node ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-03 17:50:12 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        auto &  element  =  static_cast < DOM : : Element & > ( dom_node ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-21 01:43:37 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        int  child_index  =  layout_node - > parent ( ) - > index_of_child < ListItemBox > ( * layout_node ) . value ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-03 17:50:12 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        auto  marker_style  =  style_computer . compute_style ( element ,  CSS : : Selector : : PseudoElement : : Marker ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-21 01:43:37 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        auto  list_item_marker  =  adopt_ref ( * new  ListItemMarkerBox ( document ,  layout_node - > computed_values ( ) . list_style_type ( ) ,  child_index  +  1 ,  * marker_style ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( layout_node - > first_child ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            list_item_marker - > set_inline ( layout_node - > first_child ( ) - > is_inline ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        static_cast < ListItemBox & > ( * layout_node ) . set_marker ( list_item_marker ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-03 17:50:12 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        element . set_pseudo_element_node ( { } ,  CSS : : Selector : : PseudoElement : : Marker ,  list_item_marker ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-21 01:43:37 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        layout_node - > append_child ( move ( list_item_marker ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-22 16:08:03 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( is < HTML : : HTMLProgressElement > ( dom_node ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        auto &  progress  =  static_cast < HTML : : HTMLProgressElement & > ( dom_node ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( ! progress . using_system_appearance ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            auto  bar_style  =  style_computer . compute_style ( progress ,  CSS : : Selector : : PseudoElement : : ProgressBar ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            auto  value_style  =  style_computer . compute_style ( progress ,  CSS : : Selector : : PseudoElement : : ProgressValue ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            auto  position  =  progress . position ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            value_style - > set_property ( CSS : : PropertyID : : Width ,  CSS : : PercentageStyleValue : : create ( CSS : : Percentage ( position  > =  0  ?  round_to < int > ( 100  *  position )  :  0 ) ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            auto  progress_bar  =  adopt_ref ( * new  Layout : : BlockContainer ( document ,  nullptr ,  bar_style ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            auto  progress_value  =  adopt_ref ( * new  Layout : : BlockContainer ( document ,  nullptr ,  value_style ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            progress_bar - > append_child ( * progress_value ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            layout_node - > append_child ( * progress_bar ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            progress . set_pseudo_element_node ( { } ,  CSS : : Selector : : PseudoElement : : ProgressBar ,  progress_bar ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            progress . set_pseudo_element_node ( { } ,  CSS : : Selector : : PseudoElement : : ProgressValue ,  progress_value ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											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 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2022-03-14 20:25:58 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    VERIFY ( dom_node . is_document ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-11-26 21:18:34 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-08-05 10:26:09 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    Context  context ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    create_layout_tree ( dom_node ,  context ) ; 
							 
						 
					
						
							
								
									
										
										
										
											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-10-06 17:57:44 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								template < CSS : : Display : : Internal  internal ,  typename  Callback >  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  TreeBuilder : : for_each_in_tree_with_internal_display ( NodeWithStyle &  root ,  Callback  callback )  
						 
					
						
							
								
									
										
										
										
											2021-01-07 18:00:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2021-04-06 18:38:10 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    root . for_each_in_inclusive_subtree_of_type < Box > ( [ & ] ( auto &  box )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-06 17:57:44 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        auto  const &  display  =  box . computed_values ( ) . display ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( display . is_internal ( )  & &  display . internal ( )  = =  internal ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            callback ( box ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  IterationDecision : : Continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								template < CSS : : Display : : Inside  inside ,  typename  Callback >  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  TreeBuilder : : for_each_in_tree_with_inside_display ( NodeWithStyle &  root ,  Callback  callback )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    root . for_each_in_inclusive_subtree_of_type < Box > ( [ & ] ( auto &  box )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        auto  const &  display  =  box . computed_values ( ) . display ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-13 01:03:40 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( display . is_outside_and_inside ( )  & &  display . inside ( )  = =  inside ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-07 18:00:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            callback ( box ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  IterationDecision : : Continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  TreeBuilder : : fixup_tables ( NodeWithStyle &  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:
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-09-03 19:11:51 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    NonnullRefPtrVector < Node >  to_remove ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-07 18:00:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // Children of a table-column.
 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-06 17:57:44 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    for_each_in_tree_with_internal_display < CSS : : Display : : Internal : : TableColumn > ( root ,  [ & ] ( Box &  table_column )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-07 18:00:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        table_column . for_each_child ( [ & ] ( auto &  child )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            to_remove . append ( child ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // Children of a table-column-group which are not a table-column.
 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-06 17:57:44 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    for_each_in_tree_with_internal_display < CSS : : Display : : Internal : : TableColumnGroup > ( root ,  [ & ] ( Box &  table_column_group )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-07 18:00:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        table_column_group . for_each_child ( [ & ] ( auto &  child )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-06 17:57:44 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            if  ( child . computed_values ( ) . display ( ) . is_table_column ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-07 18:00:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                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 )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2021-10-06 17:57:44 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    return  display . is_table_row ( )  | |  display . is_table_column ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-07 18:00:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								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.
 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-06 17:57:44 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    return  display . is_table_row_group ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        | |  display . is_table_header_group ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        | |  display . is_table_footer_group ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        | |  display . is_table_column_group ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-07 18:00:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-04-01 20:58:27 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  bool  is_not_proper_table_child ( Node  const &  node )  
						 
					
						
							
								
									
										
										
										
											2021-01-07 18:00:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( ! node . has_style ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  display  =  node . computed_values ( ) . display ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-06 17:57:44 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    return  ! is_table_track_group ( display )  & &  ! is_table_track ( display )  & &  ! display . is_table_caption ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-07 18:00:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-04-01 20:58:27 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  bool  is_not_table_row ( Node  const &  node )  
						 
					
						
							
								
									
										
										
										
											2021-01-07 18:00:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( ! node . has_style ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  display  =  node . computed_values ( ) . display ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-06 17:57:44 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    return  ! display . is_table_row ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-07 18:00:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-04-01 20:58:27 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  bool  is_not_table_cell ( Node  const &  node )  
						 
					
						
							
								
									
										
										
										
											2021-01-07 18:00:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( ! node . has_style ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  display  =  node . computed_values ( ) . display ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-06 17:57:44 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    return  ! display . is_table_cell ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-07 18:00:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-10-27 18:20:41 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  bool  is_ignorable_whitespace ( Layout : : Node  const &  node )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( node . is_text_node ( )  & &  static_cast < TextNode  const & > ( node ) . text_for_rendering ( ) . is_whitespace ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( node . is_anonymous ( )  & &  node . is_block_container ( )  & &  static_cast < BlockContainer  const & > ( node ) . children_are_inline ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        bool  contains_only_white_space  =  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        node . for_each_in_inclusive_subtree_of_type < TextNode > ( [ & contains_only_white_space ] ( auto &  text_node )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( ! text_node . text_for_rendering ( ) . is_whitespace ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                contains_only_white_space  =  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                return  IterationDecision : : Break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            return  IterationDecision : : Continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( contains_only_white_space ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            return  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-01-07 18:00:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								template < typename  Matcher ,  typename  Callback >  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  void  for_each_sequence_of_consecutive_children_matching ( NodeWithStyle &  parent ,  Matcher  matcher ,  Callback  callback )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    NonnullRefPtrVector < Node >  sequence ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-27 18:20:41 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  sequence_is_all_ignorable_whitespace  =  [ & ] ( )  - >  bool  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        for  ( auto &  node  :  sequence )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( ! is_ignorable_whitespace ( node ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                return  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-01-07 18:00:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    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 ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-27 18:20:41 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                if  ( ! sequence_is_all_ignorable_whitespace ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    callback ( sequence ,  next_sibling ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-07 18:00:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                sequence . clear ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-27 18:20:41 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( sequence . is_empty ( )  & &  ! sequence_is_all_ignorable_whitespace ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-07 18:00:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        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 ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-23 16:46:57 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    auto  wrapper  =  adopt_ref ( * new  WrapperBoxType ( parent . document ( ) ,  nullptr ,  move ( computed_values ) ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-07 18:00:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    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.
 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-06 17:57:44 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    for_each_in_tree_with_inside_display < CSS : : Display : : Inside : : Table > ( root ,  [ & ] ( auto &  parent )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-07 18:00:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        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.
 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-06 17:57:44 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    for_each_in_tree_with_internal_display < CSS : : Display : : Internal : : TableRowGroup > ( root ,  [ & ] ( auto &  parent )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-07 18:00:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        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.
 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-06 17:57:44 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    for_each_in_tree_with_internal_display < CSS : : Display : : Internal : : TableHeaderGroup > ( root ,  [ & ] ( auto &  parent )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-18 18:21:26 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        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-10-06 17:57:44 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    for_each_in_tree_with_internal_display < CSS : : Display : : Internal : : TableFooterGroup > ( root ,  [ & ] ( auto &  parent )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-18 18:21:26 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        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
 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-06 17:57:44 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    for_each_in_tree_with_internal_display < CSS : : Display : : Internal : : TableRow > ( root ,  [ & ] ( auto &  parent )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-07 18:00:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        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 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}