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 > 
							 
						 
					
						
							
								
									
										
										
										
											2023-03-24 15:04:24 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								 *  Copyright  ( c )  2022 - 2023 ,  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 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-12-06 03:08:20 -03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  <AK/Error.h> 
  
						 
					
						
							
								
									
										
										
										
											2021-08-05 10:26:09 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  <AK/Optional.h> 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  <AK/TemporaryChange.h> 
  
						 
					
						
							
								
									
										
										
										
											2023-05-08 06:37:18 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  <LibWeb/CSS/StyleComputer.h> 
  
						 
					
						
							
								
									
										
										
										
											2023-04-26 21:05:38 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  <LibWeb/CSS/StyleValues/DisplayStyleValue.h> 
  
						 
					
						
							
								
									
										
										
										
											2023-03-24 15:04:24 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  <LibWeb/CSS/StyleValues/IdentifierStyleValue.h> 
  
						 
					
						
							
								
									
										
										
										
											2023-03-24 17:28:43 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  <LibWeb/CSS/StyleValues/PercentageStyleValue.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-11-30 22:15:12 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  <LibWeb/HTML/HTMLInputElement.h> 
  
						 
					
						
							
								
									
										
										
										
											2022-07-22 16:08:03 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  <LibWeb/HTML/HTMLProgressElement.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> 
  
						 
					
						
							
								
									
										
										
										
											2023-01-14 14:48:20 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  <LibWeb/Layout/TableWrapper.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> 
  
						 
					
						
							
								
									
										
										
										
											2023-02-25 11:04:29 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  <LibWeb/Layout/Viewport.h> 
  
						 
					
						
							
								
									
										
										
										
											2022-11-10 13:54:57 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  <LibWeb/SVG/SVGForeignObjectElement.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 )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2022-10-17 14:41:50 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    for  ( auto  child  =  layout_node . first_child ( ) ;  child ;  child  =  child - > next_sibling ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-22 19:13:55 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        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 ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-17 14:41:50 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    for  ( auto  child  =  layout_node . first_child ( ) ;  child ;  child  =  child - > next_sibling ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-22 19:13:55 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        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 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2022-10-07 12:47:46 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( layout_parent . display ( ) . is_inline_outside ( )  & &  layout_parent . display ( ) . is_flow_inside ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-11-26 21:18:34 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return  layout_parent ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-05-28 21:22:48 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( layout_parent . display ( ) . is_flex_inside ( )  | |  layout_parent . display ( ) . is_grid_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 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-03-25 15:33:22 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    bool  is_out_of_flow  =  layout_node . is_absolutely_positioned ( )  | |  layout_node . is_floating ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( is_out_of_flow 
							 
						 
					
						
							
								
									
										
										
										
											2023-04-06 18:01:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        & &  ! layout_parent . display ( ) . is_flex_inside ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        & &  ! layout_parent . display ( ) . is_grid_inside ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2023-03-25 15:33:22 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        & &  layout_parent . last_child ( ) - > is_anonymous ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        & &  layout_parent . last_child ( ) - > children_are_inline ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // Block is out-of-flow & previous sibling was wrapped in an anonymous block.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // Join the previous sibling inside the anonymous block.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  * layout_parent . last_child ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-11-15 22:17:27 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( ! layout_parent . children_are_inline ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // Parent block has block-level children, insert this block into parent.
 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-22 19:13:55 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return  layout_parent ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-03-25 15:33:22 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( is_out_of_flow )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-11-23 00:55:12 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        // 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.
 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-17 14:41:50 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    Vector < JS : : Handle < Layout : : Node > >  children ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    while  ( JS : : GCPtr < Layout : : Node >  child  =  layout_parent . first_child ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-02 03:30:04 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        layout_parent . remove_child ( * child ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-17 14:41:50 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        children . append ( * child ) ; 
							 
						 
					
						
							
								
									
										
										
										
											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 )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-17 14:41:50 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        layout_parent . last_child ( ) - > append_child ( * child ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-02 03:30:04 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    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 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-10-06 14:14:16 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								void  TreeBuilder : : insert_node_into_inline_or_block_ancestor ( Layout : : Node &  node ,  CSS : : Display  display ,  AppendOrPrepend  mode )  
						 
					
						
							
								
									
										
										
										
											2022-10-06 13:10:03 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2022-10-06 20:57:29 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( display . is_inline_outside ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-06 13:10:03 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        // Inlines can be inserted into the nearest ancestor.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        auto &  insertion_point  =  insertion_parent_for_inline_node ( m_ancestor_stack . last ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( mode  = =  AppendOrPrepend : : Prepend ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            insertion_point . prepend_child ( node ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            insertion_point . append_child ( node ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        insertion_point . set_children_are_inline ( true ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // Non-inlines can't be inserted into an inline parent, so find the nearest non-inline ancestor.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        auto &  nearest_non_inline_ancestor  =  [ & ] ( )  - >  Layout : : NodeWithStyle &  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            for  ( auto &  ancestor  :  m_ancestor_stack . in_reverse ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-02-26 16:09:02 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                if  ( ! ancestor - > display ( ) . is_inline_outside ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-06 21:03:30 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                    return  ancestor ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-02-26 16:09:02 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                if  ( ! ancestor - > display ( ) . is_flow_inside ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-06 13:10:03 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                    return  ancestor ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-02-26 16:09:02 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                if  ( ancestor - > dom_node ( )  & &  is < SVG : : SVGForeignObjectElement > ( * ancestor - > dom_node ( ) ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-11-10 13:54:57 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                    return  ancestor ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-06 13:10:03 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            VERIFY_NOT_REACHED ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        auto &  insertion_point  =  insertion_parent_for_block_node ( nearest_non_inline_ancestor ,  node ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( mode  = =  AppendOrPrepend : : Prepend ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            insertion_point . prepend_child ( node ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            insertion_point . append_child ( node ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // 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 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-12-06 03:08:20 -03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								ErrorOr < void >  TreeBuilder : : create_pseudo_element_if_needed ( DOM : : Element &  element ,  CSS : : Selector : : PseudoElement  pseudo_element ,  AppendOrPrepend  mode )  
						 
					
						
							
								
									
										
										
										
											2022-10-06 13:10:03 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto &  document  =  element . document ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto &  style_computer  =  document . style_computer ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-03-14 16:36:20 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    auto  pseudo_element_style  =  TRY ( style_computer . compute_pseudo_element_style_if_needed ( element ,  pseudo_element ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( ! pseudo_element_style ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-10-06 13:10:03 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    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 ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-12-06 03:08:20 -03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return  { } ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-06 13:56:54 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-03-14 16:36:20 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    auto  pseudo_element_node  =  DOM : : Element : : create_layout_node_for_display_type ( document ,  pseudo_element_display ,  * pseudo_element_style ,  nullptr ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-06 13:56:54 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( ! pseudo_element_node ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-12-06 03:08:20 -03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return  { } ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-06 13:56:54 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    pseudo_element_node - > set_generated ( true ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // FIXME: Handle images, and multiple values
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( pseudo_element_content . type  = =  CSS : : ContentData : : Type : : String )  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-02-14 16:05:40 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        auto  text  =  document . heap ( ) . allocate < DOM : : Text > ( document . realm ( ) ,  document ,  pseudo_element_content . data . to_deprecated_string ( ) ) . release_allocated_value_but_fixme_should_propagate_errors ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-17 14:41:50 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        auto  text_node  =  document . heap ( ) . allocate_without_realm < Layout : : TextNode > ( document ,  * text ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-14 12:29:57 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        text_node - > set_generated ( true ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-06 13:56:54 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        push_parent ( verify_cast < NodeWithStyle > ( * pseudo_element_node ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-17 14:41:50 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        insert_node_into_inline_or_block_ancestor ( * text_node ,  text_node - > display ( ) ,  AppendOrPrepend : : Append ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-06 13:56:54 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        pop_parent ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        TODO ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-06 13:10:03 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-10-06 20:42:22 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    element . set_pseudo_element_node ( { } ,  pseudo_element ,  pseudo_element_node ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-06 14:14:16 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    insert_node_into_inline_or_block_ancestor ( * pseudo_element_node ,  pseudo_element_display ,  mode ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-12-06 03:08:20 -03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  { } ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-06 13:56:54 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2022-10-06 13:10:03 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-12-06 03:08:20 -03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								ErrorOr < void >  TreeBuilder : : create_layout_tree ( DOM : : Node &  dom_node ,  TreeBuilder : : Context &  context )  
						 
					
						
							
								
									
										
										
										
											2020-11-26 21:18:34 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											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 )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-12-06 03:08:20 -03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return  { } ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-05 10:26:09 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-02-05 13:17:01 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    auto &  document  =  dom_node . document ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto &  style_computer  =  document . style_computer ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-17 14:41:50 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    JS : : GCPtr < Layout : : Node >  layout_node ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-12 13:24:58 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    RefPtr < CSS : : StyleProperties >  style ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-06 14:14:16 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    CSS : : Display  display ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-05 13:17:01 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( is < DOM : : Element > ( dom_node ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        auto &  element  =  static_cast < DOM : : Element & > ( dom_node ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-25 12:34:54 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // Special path for ::placeholder, which corresponds to a synthetic DOM element inside the <input> UA shadow root.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // FIXME: This is very hackish. Find a better way to architect this.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( element . pseudo_element ( )  = =  CSS : : Selector : : PseudoElement : : Placeholder )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            auto &  input_element  =  verify_cast < HTML : : HTMLInputElement > ( * element . root ( ) . parent_or_shadow_host ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            style  =  TRY ( style_computer . compute_style ( input_element ,  CSS : : Selector : : PseudoElement : : Placeholder ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( input_element . placeholder_value ( ) . has_value ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                display  =  style - > display ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                display  =  CSS : : Display : : from_short ( CSS : : Display : : Short : : None ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // Common path: this is a regular DOM element. Style should be present already, thanks to Document::update_style().
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            element . clear_pseudo_element_nodes ( { } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            VERIFY ( ! element . needs_style_update ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            style  =  element . computed_css_values ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            display  =  style - > display ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-06 14:14:16 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( display . is_none ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-12-06 03:08:20 -03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            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 ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-06 14:14:16 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        display  =  style - > display ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-02-25 11:04:29 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        layout_node  =  document . heap ( ) . allocate_without_realm < Layout : : Viewport > ( static_cast < DOM : : Document & > ( dom_node ) ,  * style ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-05 13:17:01 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    }  else  if  ( is < DOM : : Text > ( dom_node ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-17 14:41:50 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        layout_node  =  document . heap ( ) . allocate_without_realm < Layout : : TextNode > ( document ,  static_cast < DOM : : Text & > ( dom_node ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-06 14:14:16 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        display  =  CSS : : Display ( CSS : : Display : : Outside : : Inline ,  CSS : : Display : : Inside : : Flow ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-05 13:17:01 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-11-26 21:18:34 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( ! layout_node ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-12-06 03:08:20 -03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return  { } ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-10-17 23:32:08 +02: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 ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-02-26 16:09:02 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        m_ancestor_stack . last ( ) - > append_child ( * layout_node ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-25 11:59:56 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    }  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-06 14:14:16 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        insert_node_into_inline_or_block_ancestor ( * layout_node ,  display ,  AppendOrPrepend : : Append ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-11-26 21:18:34 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-01-28 20:22:52 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    auto *  shadow_root  =  is < DOM : : Element > ( dom_node )  ?  verify_cast < DOM : : Element > ( dom_node ) . shadow_root_internal ( )  :  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 ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-25 12:34:54 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( shadow_root )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            for  ( auto *  node  =  shadow_root - > first_child ( ) ;  node ;  node  =  node - > next_sibling ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                TRY ( create_layout_tree ( * node ,  context ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2022-12-06 03:08:20 -03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // This is the same as verify_cast<DOM::ParentNode>(dom_node).for_each_child
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        for  ( auto *  node  =  verify_cast < DOM : : ParentNode > ( dom_node ) . first_child ( ) ;  node ;  node  =  node - > next_sibling ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            TRY ( create_layout_tree ( * node ,  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 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        push_parent ( verify_cast < NodeWithStyle > ( * layout_node ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-12-06 03:08:20 -03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        TRY ( create_pseudo_element_if_needed ( element ,  CSS : : Selector : : PseudoElement : : Before ,  AppendOrPrepend : : Prepend ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        TRY ( create_pseudo_element_if_needed ( element ,  CSS : : Selector : : PseudoElement : : After ,  AppendOrPrepend : : Append ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											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-12-06 03:08:20 -03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        auto  marker_style  =  TRY ( style_computer . compute_style ( element ,  CSS : : Selector : : PseudoElement : : Marker ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-06-02 23:05:15 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        auto  list_item_marker  =  document . heap ( ) . allocate_without_realm < ListItemMarkerBox > ( document ,  layout_node - > computed_values ( ) . list_style_type ( ) ,  layout_node - > computed_values ( ) . list_style_position ( ) ,  child_index  +  1 ,  * marker_style ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-21 01:43:37 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        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-10-17 14:41:50 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        layout_node - > append_child ( * list_item_marker ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-21 01:43:37 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											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 ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-12-06 03:08:20 -03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            auto  bar_style  =  TRY ( style_computer . compute_style ( progress ,  CSS : : Selector : : PseudoElement : : ProgressBar ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-05 15:02:03 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            bar_style - > set_property ( CSS : : PropertyID : : Display ,  CSS : : DisplayStyleValue : : create ( CSS : : Display : : from_short ( CSS : : Display : : Short : : FlowRoot ) ) . release_value_but_fixme_should_propagate_errors ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-12-06 03:08:20 -03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            auto  value_style  =  TRY ( style_computer . compute_style ( progress ,  CSS : : Selector : : PseudoElement : : ProgressValue ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-05 15:02:03 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            value_style - > set_property ( CSS : : PropertyID : : Display ,  CSS : : DisplayStyleValue : : create ( CSS : : Display : : from_short ( CSS : : Display : : Short : : Block ) ) . release_value_but_fixme_should_propagate_errors ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-22 16:08:03 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            auto  position  =  progress . position ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-05 15:02:03 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            value_style - > set_property ( CSS : : PropertyID : : Width ,  CSS : : PercentageStyleValue : : create ( CSS : : Percentage ( position  > =  0  ?  round_to < int > ( 100  *  position )  :  0 ) ) . release_value_but_fixme_should_propagate_errors ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-08 22:15:32 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            auto  bar_display  =  bar_style - > display ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            auto  value_display  =  value_style - > display ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            auto  progress_bar  =  DOM : : Element : : create_layout_node_for_display_type ( document ,  bar_display ,  bar_style ,  nullptr ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            auto  progress_value  =  DOM : : Element : : create_layout_node_for_display_type ( document ,  value_display ,  value_style ,  nullptr ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            push_parent ( verify_cast < NodeWithStyle > ( * layout_node ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            push_parent ( verify_cast < NodeWithStyle > ( * progress_bar ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            insert_node_into_inline_or_block_ancestor ( * progress_value ,  value_display ,  AppendOrPrepend : : Append ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            pop_parent ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            insert_node_into_inline_or_block_ancestor ( * progress_bar ,  bar_display ,  AppendOrPrepend : : Append ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            pop_parent ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-22 16:08:03 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            progress . set_pseudo_element_node ( { } ,  CSS : : Selector : : PseudoElement : : ProgressBar ,  progress_bar ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            progress . set_pseudo_element_node ( { } ,  CSS : : Selector : : PseudoElement : : ProgressValue ,  progress_value ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2022-11-30 22:15:12 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-12-06 03:08:20 -03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    return  { } ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-10-15 12:22:41 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-10-17 14:41:50 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								JS : : GCPtr < Layout : : 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 ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-12-06 03:08:20 -03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    MUST ( create_layout_tree ( dom_node ,  context ) ) ;  // FIXME propagate errors
 
							 
						 
					
						
							
								
									
										
										
										
											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 )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-06 16:02:53 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        auto  const  display  =  box . display ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-06 17:57:44 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        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 )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-06 16:02:53 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        auto  const  display  =  box . 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:
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-10-17 14:41:50 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    Vector < JS : : Handle < 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 )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-06 16:02:53 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            if  ( child . 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 ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-17 14:41:50 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        box - > parent ( ) - > remove_child ( * box ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-07 18:00:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								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 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-01-04 16:38:42 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  bool  is_proper_table_child ( Node  const &  node )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  const  display  =  node . display ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  is_table_track_group ( display )  | |  is_table_track ( display )  | |  display . is_table_caption ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											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 ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-01-04 16:38:42 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    return  ! is_proper_table_child ( node ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  bool  is_table_row ( Node  const &  node )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  node . 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_row ( Node  const &  node )  
						 
					
						
							
								
									
										
										
										
											2021-01-07 18:00:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( ! node . has_style ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  true ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-01-04 16:38:42 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    return  ! is_table_row ( node ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  bool  is_table_cell ( Node  const &  node )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  node . display ( ) . is_table_cell ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											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 ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-01-04 16:38:42 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    return  ! is_table_cell ( node ) ; 
							 
						 
					
						
							
								
									
										
										
										
											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 )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2022-10-17 14:41:50 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    Vector < JS : : Handle < Node > >  sequence ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-27 18:20:41 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  sequence_is_all_ignorable_whitespace  =  [ & ] ( )  - >  bool  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        for  ( auto &  node  :  sequence )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-17 14:41:50 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            if  ( ! is_ignorable_whitespace ( * node ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-27 18:20:41 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                return  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-12-09 13:53:51 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    for  ( auto  child  =  parent . first_child ( ) ;  child ;  child  =  child - > next_sibling ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-01-04 16:38:42 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( matcher ( * child )  | |  ( ! sequence . is_empty ( )  & &  is_ignorable_whitespace ( * child ) ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-07 18:00:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            sequence . append ( * child ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( ! sequence . is_empty ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-27 18:20:41 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                if  ( ! sequence_is_all_ignorable_whitespace ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-12-09 13:53:51 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                    callback ( sequence ,  child ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-07 18:00:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                sequence . clear ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2022-12-09 13:53:51 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( ! sequence . is_empty ( )  & &  ! sequence_is_all_ignorable_whitespace ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-07 18:00:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        callback ( sequence ,  nullptr ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								template < typename  WrapperBoxType >  
						 
					
						
							
								
									
										
										
										
											2023-05-29 14:11:19 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  void  wrap_in_anonymous ( Vector < JS : : Handle < Node > > &  sequence ,  Node *  nearest_sibling ,  CSS : : Display  display )  
						 
					
						
							
								
									
										
										
										
											2021-01-07 18:00:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2021-02-23 20:42:32 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    VERIFY ( ! sequence . is_empty ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-17 14:41:50 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    auto &  parent  =  * sequence . first ( ) - > parent ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-07 18:00:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    auto  computed_values  =  parent . computed_values ( ) . clone_inherited_values ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-29 14:11:19 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    static_cast < CSS : : MutableComputedValues & > ( computed_values ) . set_display ( display ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-17 14:41:50 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    auto  wrapper  =  parent . heap ( ) . template  allocate_without_realm < WrapperBoxType > ( parent . document ( ) ,  nullptr ,  move ( computed_values ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-07 18:00:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    for  ( auto &  child  :  sequence )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-17 14:41:50 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        parent . remove_child ( * child ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        wrapper - > append_child ( * child ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-07 18:00:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-22 02:59:10 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    wrapper - > set_children_are_inline ( parent . children_are_inline ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-07 18:00:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( nearest_sibling ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-17 14:41:50 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        parent . insert_before ( * wrapper ,  * nearest_sibling ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-07 18:00:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    else 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-17 14:41:50 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        parent . append_child ( * wrapper ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-07 18:00:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								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 )  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-29 16:07:28 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            wrap_in_anonymous < Box > ( sequence ,  nearest_sibling ,  CSS : : Display  {  CSS : : Display : : Internal : : TableRow  } ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-07 18:00:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // 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 )  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-29 16:07:28 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            wrap_in_anonymous < Box > ( sequence ,  nearest_sibling ,  CSS : : Display  {  CSS : : Display : : Internal : : TableRow  } ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-07 18:00:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } ) ; 
							 
						 
					
						
							
								
									
										
										
										
											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 )  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-29 16:07:28 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            wrap_in_anonymous < Box > ( sequence ,  nearest_sibling ,  CSS : : Display  {  CSS : : Display : : Internal : : TableRow  } ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-18 18:21:26 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } ) ; 
							 
						 
					
						
							
								
									
										
										
										
											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 )  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-29 16:07:28 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            wrap_in_anonymous < Box > ( sequence ,  nearest_sibling ,  CSS : : Display  {  CSS : : Display : : Internal : : TableRow  } ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-18 18:21:26 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } ) ; 
							 
						 
					
						
							
								
									
										
										
										
											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 )  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-29 17:15:00 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            wrap_in_anonymous < BlockContainer > ( sequence ,  nearest_sibling ,  CSS : : Display  {  CSS : : Display : : Internal : : TableCell  } ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-07 18:00:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-01-04 16:38:42 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								void  TreeBuilder : : generate_missing_parents ( NodeWithStyle &  root )  
						 
					
						
							
								
									
										
										
										
											2021-01-07 18:00:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2023-05-29 14:11:19 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    Vector < JS : : Handle < Box > >  table_roots_to_wrap ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-01-04 16:38:42 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    root . for_each_in_inclusive_subtree_of_type < Box > ( [ & ] ( auto &  parent )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // An anonymous table-row box must be generated around each sequence of consecutive table-cell boxes whose parent is not a table-row.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( is_not_table_row ( parent ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            for_each_sequence_of_consecutive_children_matching ( parent ,  is_table_cell ,  [ & ] ( auto &  sequence ,  auto  nearest_sibling )  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-29 16:07:28 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                wrap_in_anonymous < Box > ( sequence ,  nearest_sibling ,  CSS : : Display  {  CSS : : Display : : Internal : : TableRow  } ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-01-04 16:38:42 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // A table-row is misparented if its parent is neither a table-row-group nor a table-root box.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( ! parent . display ( ) . is_table_inside ( )  & &  ! is_proper_table_child ( parent ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            for_each_sequence_of_consecutive_children_matching ( parent ,  is_table_row ,  [ & ] ( auto &  sequence ,  auto  nearest_sibling )  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-29 14:11:19 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                wrap_in_anonymous < Box > ( sequence ,  nearest_sibling ,  CSS : : Display : : from_short ( parent . display ( ) . is_inline_outside ( )  ?  CSS : : Display : : Short : : InlineTable  :  CSS : : Display : : Short : : Table ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-01-04 16:38:42 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // A table-row-group, table-column-group, or table-caption box is misparented if its parent is not a table-root box.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( ! parent . display ( ) . is_table_inside ( )  & &  ! is_proper_table_child ( parent ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            for_each_sequence_of_consecutive_children_matching ( parent ,  is_proper_table_child ,  [ & ] ( auto &  sequence ,  auto  nearest_sibling )  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-29 14:11:19 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                wrap_in_anonymous < Box > ( sequence ,  nearest_sibling ,  CSS : : Display : : from_short ( parent . display ( ) . is_inline_outside ( )  ?  CSS : : Display : : Short : : InlineTable  :  CSS : : Display : : Short : : Table ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-01-04 16:38:42 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-01-09 08:27:39 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        // An anonymous table-wrapper box must be generated around each table-root.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( parent . display ( ) . is_table_inside ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-29 14:11:19 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            table_roots_to_wrap . append ( parent ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-01-09 08:27:39 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-01-04 16:38:42 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return  IterationDecision : : Continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-01-09 08:27:39 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    for  ( auto &  table_box  :  table_roots_to_wrap )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        auto *  nearest_sibling  =  table_box - > next_sibling ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        auto &  parent  =  * table_box - > parent ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        CSS : : ComputedValues  wrapper_computed_values ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // The computed values of properties 'position', 'float', 'margin-*', 'top', 'right', 'bottom', and 'left' on the table element are used on the table wrapper box and not the table box;
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // all other values of non-inheritable properties are used on the table box and not the table wrapper box.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // (Where the table element's values are not used on the table and table wrapper boxes, the initial values are used instead.)
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        auto &  mutable_wrapper_computed_values  =  static_cast < CSS : : MutableComputedValues & > ( wrapper_computed_values ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-01-16 13:13:31 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( table_box - > display ( ) . is_inline_outside ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            mutable_wrapper_computed_values . set_display ( CSS : : Display : : from_short ( CSS : : Display : : Short : : InlineBlock ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            mutable_wrapper_computed_values . set_display ( CSS : : Display : : from_short ( CSS : : Display : : Short : : FlowRoot ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-01-09 08:27:39 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        mutable_wrapper_computed_values . set_position ( table_box - > computed_values ( ) . position ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        mutable_wrapper_computed_values . set_inset ( table_box - > computed_values ( ) . inset ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        mutable_wrapper_computed_values . set_float ( table_box - > computed_values ( ) . float_ ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-01-09 17:38:52 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        mutable_wrapper_computed_values . set_clear ( table_box - > computed_values ( ) . clear ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-01-09 08:27:39 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        mutable_wrapper_computed_values . set_margin ( table_box - > computed_values ( ) . margin ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        table_box - > reset_table_box_computed_values_used_by_wrapper_to_init_values ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-01-14 14:48:20 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        auto  wrapper  =  parent . heap ( ) . allocate_without_realm < TableWrapper > ( parent . document ( ) ,  nullptr ,  move ( wrapper_computed_values ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-01-09 08:27:39 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        parent . remove_child ( * table_box ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        wrapper - > append_child ( * table_box ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-02-07 01:33:10 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( nearest_sibling ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            parent . insert_before ( * wrapper ,  * nearest_sibling ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            parent . append_child ( * wrapper ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-01-09 08:27:39 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-07 18:00:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-03-07 10:27:02 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}