2020-01-18 09:38:21 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								/*
  
						 
					
						
							
								
									
										
										
										
											2024-10-04 13:19:50 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								 *  Copyright  ( c )  2018 - 2024 ,  Andreas  Kling  < andreas @ ladybird . org > 
							 
						 
					
						
							
								
									
										
										
										
											2024-10-15 12:00:29 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								 *  Copyright  ( c )  2021 - 2024 ,  Sam  Atkins  < sam @ ladybird . org > 
							 
						 
					
						
							
								
									
										
										
										
											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 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-08-14 14:06:03 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								# include  <LibWeb/CSS/Keyword.h> 
  
						 
					
						
							
								
									
										
										
										
											2021-07-30 19:31:46 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								# include  <LibWeb/CSS/Parser/Parser.h> 
  
						 
					
						
							
								
									
										
										
										
											2020-03-07 10:32:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								# include  <LibWeb/CSS/SelectorEngine.h> 
  
						 
					
						
							
								
									
										
										
										
											2023-08-22 16:51:42 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								# include  <LibWeb/CSS/StyleProperties.h> 
  
						 
					
						
							
								
									
										
										
										
											2024-03-15 18:19:59 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								# include  <LibWeb/DOM/Attr.h> 
  
						 
					
						
							
								
									
										
										
										
											2020-03-07 10:32:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								# include  <LibWeb/DOM/Document.h> 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								# include  <LibWeb/DOM/Element.h> 
  
						 
					
						
							
								
									
										
										
										
											2024-03-15 18:19:59 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								# include  <LibWeb/DOM/NamedNodeMap.h> 
  
						 
					
						
							
								
									
										
										
										
											2020-03-07 10:32:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								# include  <LibWeb/DOM/Text.h> 
  
						 
					
						
							
								
									
										
										
										
											2020-08-12 14:46:53 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								# include  <LibWeb/HTML/AttributeNames.h> 
  
						 
					
						
							
								
									
										
										
										
											2022-09-14 13:29:07 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								# include  <LibWeb/HTML/HTMLAnchorElement.h> 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								# include  <LibWeb/HTML/HTMLAreaElement.h> 
  
						 
					
						
							
								
									
										
										
										
											2022-09-30 19:40:19 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								# include  <LibWeb/HTML/HTMLButtonElement.h> 
  
						 
					
						
							
								
									
										
										
										
											2023-09-13 17:39:05 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								# include  <LibWeb/HTML/HTMLDetailsElement.h> 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								# include  <LibWeb/HTML/HTMLDialogElement.h> 
  
						 
					
						
							
								
									
										
										
										
											2022-09-30 19:40:19 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								# include  <LibWeb/HTML/HTMLFieldSetElement.h> 
  
						 
					
						
							
								
									
										
										
										
											2022-02-10 20:52:58 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								# include  <LibWeb/HTML/HTMLHtmlElement.h> 
  
						 
					
						
							
								
									
										
										
										
											2022-02-15 23:50:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								# include  <LibWeb/HTML/HTMLInputElement.h> 
  
						 
					
						
							
								
									
										
										
										
											2023-08-01 12:31:41 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								# include  <LibWeb/HTML/HTMLMediaElement.h> 
  
						 
					
						
							
								
									
										
										
										
											2022-09-30 19:40:19 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								# include  <LibWeb/HTML/HTMLOptGroupElement.h> 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								# include  <LibWeb/HTML/HTMLOptionElement.h> 
  
						 
					
						
							
								
									
										
										
										
											2023-03-20 04:35:43 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								# include  <LibWeb/HTML/HTMLProgressElement.h> 
  
						 
					
						
							
								
									
										
										
										
											2022-09-30 19:40:19 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								# include  <LibWeb/HTML/HTMLSelectElement.h> 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								# include  <LibWeb/HTML/HTMLTextAreaElement.h> 
  
						 
					
						
							
								
									
										
										
										
											2023-02-18 15:42:55 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								# include  <LibWeb/Infra/Strings.h> 
  
						 
					
						
							
								
									
										
										
										
											2024-03-15 18:19:59 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								# include  <LibWeb/Namespace.h> 
  
						 
					
						
							
								
									
										
										
										
											2024-11-06 18:07:28 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								# include  <LibWeb/SVG/SVGAElement.h> 
  
						 
					
						
							
								
									
										
										
										
											2019-10-08 15:33:58 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-07-26 20:01:35 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								namespace  Web : : SelectorEngine  {  
						 
					
						
							
								
									
										
										
										
											2019-10-08 15:33:58 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-10-27 12:15:19 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								static  inline  bool  matches ( CSS : : Selector  const &  selector ,  Optional < CSS : : CSSStyleSheet  const & >  style_sheet_for_rule ,  int  component_list_index ,  DOM : : Element  const &  element ,  JS : : GCPtr < DOM : : Element  const >  shadow_host ,  JS : : GCPtr < DOM : : ParentNode  const >  scope ,  SelectorKind  selector_kind ,  JS : : GCPtr < DOM : : Element  const >  anchor  =  nullptr ) ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-07-23 15:22:28 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								// Upward traversal for descendant (' ') and immediate child combinator ('>')
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								// If we're starting inside a shadow tree, traversal stops at the nearest shadow host.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								// This is an implementation detail of the :host selector. Otherwise we would just traverse up to the document root.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								static  inline  JS : : GCPtr < DOM : : Node  const >  traverse_up ( JS : : GCPtr < DOM : : Node  const >  node ,  JS : : GCPtr < DOM : : Element  const >  shadow_host )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( ! node ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  nullptr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( shadow_host )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // NOTE: We only traverse up to the shadow host, not beyond.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( node  = =  shadow_host ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  nullptr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  node - > parent_or_shadow_host_element ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    return  node - > parent ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-03-20 12:39:11 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								// https://drafts.csswg.org/selectors-4/#the-lang-pseudo
  
						 
					
						
							
								
									
										
										
										
											2023-02-18 15:42:55 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								static  inline  bool  matches_lang_pseudo_class ( DOM : : Element  const &  element ,  Vector < FlyString >  const &  languages )  
						 
					
						
							
								
									
										
										
										
											2022-03-20 12:39:11 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2024-10-27 14:58:36 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    auto  maybe_element_language  =  element . lang ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( ! maybe_element_language . has_value ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-20 12:39:11 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-10-27 14:58:36 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    auto  element_language  =  maybe_element_language . release_value ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-03-20 12:39:11 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    // FIXME: This is ad-hoc. Implement a proper language range matching algorithm as recommended by BCP47.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    for  ( auto  const &  language  :  languages )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( language . is_empty ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2023-08-16 14:37:47 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            continue ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-20 12:39:11 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( language  = =  " * " sv ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  true ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-10-27 14:58:36 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( ! element_language . contains ( ' - ' )  & &  Infra : : is_ascii_case_insensitive_match ( element_language ,  language ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2023-08-16 14:37:47 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            return  true ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-10-27 14:58:36 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        auto  parts  =  element_language . split_limit ( ' - ' ,  2 ) . release_value_but_fixme_should_propagate_errors ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-11-02 03:48:19 +13:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( ! parts . is_empty ( )  & &  Infra : : is_ascii_case_insensitive_match ( parts [ 0 ] ,  language ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2023-08-16 14:37:47 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            return  true ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-20 12:39:11 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    return  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-07-13 09:19:30 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								// https://drafts.csswg.org/selectors-4/#relational
  
						 
					
						
							
								
									
										
										
										
											2024-10-27 12:15:19 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								static  inline  bool  matches_relative_selector ( CSS : : Selector  const &  selector ,  size_t  compound_index ,  Optional < CSS : : CSSStyleSheet  const & >  style_sheet_for_rule ,  DOM : : Element  const &  element ,  JS : : GCPtr < DOM : : Element  const >  shadow_host ,  JS : : NonnullGCPtr < DOM : : Element  const >  anchor )  
						 
					
						
							
								
									
										
										
										
											2024-07-13 09:19:30 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2024-10-27 12:15:19 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( compound_index  > =  selector . compound_selectors ( ) . size ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  matches ( selector ,  style_sheet_for_rule ,  element ,  shadow_host ,  { } ,  { } ,  SelectorKind : : Relative ,  anchor ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    switch  ( selector . compound_selectors ( ) [ compound_index ] . combinator )  { 
							 
						 
					
						
							
								
									
										
										
										
											2024-07-13 09:19:30 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    // Shouldn't be possible because we've parsed relative selectors, which always have a combinator, implicitly or explicitly.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    case  CSS : : Selector : : Combinator : : None : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        VERIFY_NOT_REACHED ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    case  CSS : : Selector : : Combinator : : Descendant :  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        bool  has  =  false ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-10-27 12:15:19 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        element . for_each_in_subtree ( [ & ] ( auto  const &  descendant )  { 
							 
						 
					
						
							
								
									
										
										
										
											2024-07-13 09:19:30 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( ! descendant . is_element ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                return  TraversalDecision : : Continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            auto  const &  descendant_element  =  static_cast < DOM : : Element  const & > ( descendant ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-10-27 12:15:19 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( matches ( selector ,  style_sheet_for_rule ,  descendant_element ,  shadow_host ,  { } ,  { } ,  SelectorKind : : Relative ,  anchor ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2024-07-13 09:19:30 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                has  =  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                return  TraversalDecision : : Break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  TraversalDecision : : Continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  has ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    case  CSS : : Selector : : Combinator : : ImmediateChild :  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        bool  has  =  false ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-10-27 12:15:19 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        element . for_each_child ( [ & ] ( DOM : : Node  const &  child )  { 
							 
						 
					
						
							
								
									
										
										
										
											2024-07-13 09:19:30 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( ! child . is_element ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                return  IterationDecision : : Continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            auto  const &  child_element  =  static_cast < DOM : : Element  const & > ( child ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-10-27 12:15:19 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( ! matches ( selector ,  style_sheet_for_rule ,  compound_index ,  child_element ,  shadow_host ,  { } ,  SelectorKind : : Relative ,  anchor ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                return  IterationDecision : : Continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( matches_relative_selector ( selector ,  compound_index  +  1 ,  style_sheet_for_rule ,  child_element ,  shadow_host ,  anchor ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2024-07-13 09:19:30 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                has  =  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                return  IterationDecision : : Break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  IterationDecision : : Continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  has ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2024-10-27 12:15:19 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    case  CSS : : Selector : : Combinator : : NextSibling :  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        auto *  sibling  =  element . next_element_sibling ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( ! sibling ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( ! matches ( selector ,  style_sheet_for_rule ,  compound_index ,  * sibling ,  shadow_host ,  { } ,  SelectorKind : : Relative ,  anchor ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  matches_relative_selector ( selector ,  compound_index  +  1 ,  style_sheet_for_rule ,  * sibling ,  shadow_host ,  anchor ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2024-07-13 09:19:30 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    case  CSS : : Selector : : Combinator : : SubsequentSibling :  { 
							 
						 
					
						
							
								
									
										
										
										
											2024-10-27 12:15:19 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        for  ( auto  const *  sibling  =  element . next_element_sibling ( ) ;  sibling ;  sibling  =  sibling - > next_element_sibling ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( ! matches ( selector ,  style_sheet_for_rule ,  compound_index ,  * sibling ,  shadow_host ,  { } ,  SelectorKind : : Relative ,  anchor ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( matches_relative_selector ( selector ,  compound_index  +  1 ,  style_sheet_for_rule ,  * sibling ,  shadow_host ,  anchor ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2024-07-13 09:19:30 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                return  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    case  CSS : : Selector : : Combinator : : Column : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        TODO ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    return  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-10-27 12:15:19 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								// https://drafts.csswg.org/selectors-4/#relational
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								static  inline  bool  matches_has_pseudo_class ( CSS : : Selector  const &  selector ,  Optional < CSS : : CSSStyleSheet  const & >  style_sheet_for_rule ,  DOM : : Element  const &  anchor ,  JS : : GCPtr < DOM : : Element  const >  shadow_host )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    return  matches_relative_selector ( selector ,  0 ,  style_sheet_for_rule ,  anchor ,  shadow_host ,  anchor ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-09-14 13:29:07 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								// https://html.spec.whatwg.org/multipage/semantics-other.html#selector-link
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								static  inline  bool  matches_link_pseudo_class ( DOM : : Element  const &  element )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // All a elements that have an href attribute, and all area elements that have an href attribute, must match one of :link and :visited.
 
							 
						 
					
						
							
								
									
										
										
										
											2024-11-06 18:07:28 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( ! is < HTML : : HTMLAnchorElement > ( element )  & &  ! is < HTML : : HTMLAreaElement > ( element )  & &  ! is < SVG : : SVGAElement > ( element ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-09-14 13:29:07 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    return  element . has_attribute ( HTML : : AttributeNames : : href ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-09-09 15:37:17 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								bool  matches_hover_pseudo_class ( DOM : : Element  const &  element )  
						 
					
						
							
								
									
										
										
										
											2019-10-14 17:54:17 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto *  hovered_node  =  element . document ( ) . hovered_node ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( ! hovered_node ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( & element  = =  hovered_node ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  true ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-08-25 10:14:24 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    return  element . is_shadow_including_ancestor_of ( * hovered_node ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-10-14 17:54:17 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-03-16 23:29:17 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								// https://html.spec.whatwg.org/multipage/semantics-other.html#selector-checked
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								static  inline  bool  matches_checked_pseudo_class ( DOM : : Element  const &  element )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // The :checked pseudo-class must match any element falling into one of the following categories:
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // - input elements whose type attribute is in the Checkbox state and whose checkedness state is true
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // - input elements whose type attribute is in the Radio Button state and whose checkedness state is true
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( is < HTML : : HTMLInputElement > ( element ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        auto  const &  input_element  =  static_cast < HTML : : HTMLInputElement  const & > ( element ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        switch  ( input_element . type_state ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        case  HTML : : HTMLInputElement : : TypeAttributeState : : Checkbox : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        case  HTML : : HTMLInputElement : : TypeAttributeState : : RadioButton : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  static_cast < HTML : : HTMLInputElement  const & > ( element ) . checked ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        default : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-03-20 04:33:22 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    // - option elements whose selectedness is true
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( is < HTML : : HTMLOptionElement > ( element ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  static_cast < HTML : : HTMLOptionElement  const & > ( element ) . selected ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-16 23:29:17 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    return  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-03-20 04:35:43 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								// https://html.spec.whatwg.org/multipage/semantics-other.html#selector-indeterminate
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								static  inline  bool  matches_indeterminate_pseudo_class ( DOM : : Element  const &  element )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // The :indeterminate pseudo-class must match any element falling into one of the following categories:
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // - input elements whose type attribute is in the Checkbox state and whose indeterminate IDL attribute is set to true
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // FIXME: - input elements whose type attribute is in the Radio Button state and whose radio button group contains no input elements whose checkedness state is true.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( is < HTML : : HTMLInputElement > ( element ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        auto  const &  input_element  =  static_cast < HTML : : HTMLInputElement  const & > ( element ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        switch  ( input_element . type_state ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        case  HTML : : HTMLInputElement : : TypeAttributeState : : Checkbox : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  input_element . indeterminate ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        default : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // - progress elements with no value content attribute
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( is < HTML : : HTMLProgressElement > ( element ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  ! element . has_attribute ( HTML : : AttributeNames : : value ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    return  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-08-08 16:19:20 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								static  inline  bool  matches_attribute ( CSS : : Selector : : SimpleSelector : : Attribute  const &  attribute ,  [[maybe_unused]]  Optional < CSS : : CSSStyleSheet  const & >  style_sheet_for_rule ,  DOM : : Element  const &  element )  
						 
					
						
							
								
									
										
										
										
											2021-07-12 14:58:03 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2023-08-08 16:19:20 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    // FIXME: Check the attribute's namespace, once we support that in DOM::Element!
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-11-04 22:45:04 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    auto  const &  attribute_name  =  attribute . qualified_name . name . name ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-08-08 16:19:20 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-03-15 18:19:59 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    auto  const *  attr  =  element . namespace_uri ( )  = =  Namespace : : HTML  ?  element . attributes ( ) - > get_attribute_with_lowercase_qualified_name ( attribute_name ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                                                                  :  element . attributes ( ) - > get_attribute ( attribute_name ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-03-29 18:01:36 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( attribute . match_type  = =  CSS : : Selector : : SimpleSelector : : Attribute : : MatchType : : HasAttribute )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // Early way out in case of an attribute existence selector.
 
							 
						 
					
						
							
								
									
										
										
										
											2024-03-15 18:19:59 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  attr  ! =  nullptr ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-29 18:01:36 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-03-15 18:19:59 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( ! attr ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-08-18 21:17:08 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    auto  case_sensitivity  =  [ & ] ( CSS : : Selector : : SimpleSelector : : Attribute : : CaseType  case_type )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        switch  ( case_type )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        case  CSS : : Selector : : SimpleSelector : : Attribute : : CaseType : : CaseInsensitiveMatch : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  CaseSensitivity : : CaseInsensitive ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        case  CSS : : Selector : : SimpleSelector : : Attribute : : CaseType : : CaseSensitiveMatch : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  CaseSensitivity : : CaseSensitive ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        case  CSS : : Selector : : SimpleSelector : : Attribute : : CaseType : : DefaultMatch : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            // See: https://html.spec.whatwg.org/multipage/semantics-other.html#case-sensitivity-of-selectors
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( element . document ( ) . is_html_document ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                & &  element . namespace_uri ( )  = =  Namespace : : HTML 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                & &  attribute_name . is_one_of ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    HTML : : AttributeNames : : accept ,  HTML : : AttributeNames : : accept_charset ,  HTML : : AttributeNames : : align , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    HTML : : AttributeNames : : alink ,  HTML : : AttributeNames : : axis ,  HTML : : AttributeNames : : bgcolor ,  HTML : : AttributeNames : : charset , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    HTML : : AttributeNames : : checked ,  HTML : : AttributeNames : : clear ,  HTML : : AttributeNames : : codetype ,  HTML : : AttributeNames : : color , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    HTML : : AttributeNames : : compact ,  HTML : : AttributeNames : : declare ,  HTML : : AttributeNames : : defer ,  HTML : : AttributeNames : : dir , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    HTML : : AttributeNames : : direction ,  HTML : : AttributeNames : : disabled ,  HTML : : AttributeNames : : enctype ,  HTML : : AttributeNames : : face , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    HTML : : AttributeNames : : frame ,  HTML : : AttributeNames : : hreflang ,  HTML : : AttributeNames : : http_equiv ,  HTML : : AttributeNames : : lang , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    HTML : : AttributeNames : : language ,  HTML : : AttributeNames : : link ,  HTML : : AttributeNames : : media ,  HTML : : AttributeNames : : method , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    HTML : : AttributeNames : : multiple ,  HTML : : AttributeNames : : nohref ,  HTML : : AttributeNames : : noresize ,  HTML : : AttributeNames : : noshade , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    HTML : : AttributeNames : : nowrap ,  HTML : : AttributeNames : : readonly ,  HTML : : AttributeNames : : rel ,  HTML : : AttributeNames : : rev , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    HTML : : AttributeNames : : rules ,  HTML : : AttributeNames : : scope ,  HTML : : AttributeNames : : scrolling ,  HTML : : AttributeNames : : selected , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    HTML : : AttributeNames : : shape ,  HTML : : AttributeNames : : target ,  HTML : : AttributeNames : : text ,  HTML : : AttributeNames : : type , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    HTML : : AttributeNames : : valign ,  HTML : : AttributeNames : : valuetype ,  HTML : : AttributeNames : : vlink ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                return  CaseSensitivity : : CaseInsensitive ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  CaseSensitivity : : CaseSensitive ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        VERIFY_NOT_REACHED ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } ( attribute . case_type ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  case_insensitive_match  =  case_sensitivity  = =  CaseSensitivity : : CaseInsensitive ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-29 18:01:36 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    switch  ( attribute . match_type )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-12 14:58:03 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    case  CSS : : Selector : : SimpleSelector : : Attribute : : MatchType : : ExactValueMatch : 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-29 18:01:36 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  case_insensitive_match 
							 
						 
					
						
							
								
									
										
										
										
											2024-03-15 18:19:59 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            ?  Infra : : is_ascii_case_insensitive_match ( attr - > value ( ) ,  attribute . value ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            :  attr - > value ( )  = =  attribute . value ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-29 18:01:36 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    case  CSS : : Selector : : SimpleSelector : : Attribute : : MatchType : : ContainsWord :  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( attribute . value . is_empty ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            // This selector is always false is match value is empty.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2024-03-15 18:19:59 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        auto  const &  attribute_value  =  attr - > value ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-12-24 02:51:02 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        auto  const  view  =  attribute_value . bytes_as_string_view ( ) . split_view ( '   ' ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-29 18:01:36 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        auto  const  size  =  view . size ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        for  ( size_t  i  =  0 ;  i  <  size ;  + + i )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            auto  const  value  =  view . at ( i ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( case_insensitive_match 
							 
						 
					
						
							
								
									
										
										
										
											2023-02-18 15:42:55 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                    ?  Infra : : is_ascii_case_insensitive_match ( value ,  attribute . value ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-29 18:01:36 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                    :  value  = =  attribute . value )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                return  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-12 14:58:03 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    case  CSS : : Selector : : SimpleSelector : : Attribute : : MatchType : : ContainsString : 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-29 17:46:32 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  ! attribute . value . is_empty ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2024-03-15 18:19:59 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            & &  attr - > value ( ) . contains ( attribute . value ,  case_sensitivity ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-28 12:34:05 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    case  CSS : : Selector : : SimpleSelector : : Attribute : : MatchType : : StartsWithSegment :  { 
							 
						 
					
						
							
								
									
										
										
										
											2024-03-15 18:19:59 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        auto  const &  element_attr_value  =  attr - > value ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-29 17:46:32 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( element_attr_value . is_empty ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            // If the attribute value on element is empty, the selector is true
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            // if the match value is also empty and false otherwise.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  attribute . value . is_empty ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( attribute . value . is_empty ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2023-11-04 22:45:04 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        auto  segments  =  element_attr_value . bytes_as_string_view ( ) . split_view ( ' - ' ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-29 18:01:36 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  case_insensitive_match 
							 
						 
					
						
							
								
									
										
										
										
											2023-02-18 15:42:55 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            ?  Infra : : is_ascii_case_insensitive_match ( segments . first ( ) ,  attribute . value ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-29 18:01:36 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            :  segments . first ( )  = =  attribute . value ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-28 12:34:05 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-12 14:58:03 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    case  CSS : : Selector : : SimpleSelector : : Attribute : : MatchType : : StartsWithString : 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-29 17:46:32 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  ! attribute . value . is_empty ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2024-03-15 18:19:59 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            & &  attr - > value ( ) . bytes_as_string_view ( ) . starts_with ( attribute . value ,  case_sensitivity ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-12 14:58:03 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    case  CSS : : Selector : : SimpleSelector : : Attribute : : MatchType : : EndsWithString : 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-29 17:46:32 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  ! attribute . value . is_empty ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2024-03-15 18:19:59 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            & &  attr - > value ( ) . bytes_as_string_view ( ) . ends_with ( attribute . value ,  case_sensitivity ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-29 18:01:36 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    default : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        break ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-12 14:58:03 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    return  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-02-17 22:43:22 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								static  inline  DOM : : Element  const *  previous_sibling_with_same_tag_name ( DOM : : Element  const &  element )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    for  ( auto  const *  sibling  =  element . previous_element_sibling ( ) ;  sibling ;  sibling  =  sibling - > previous_element_sibling ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( sibling - > tag_name ( )  = =  element . tag_name ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  sibling ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    return  nullptr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								static  inline  DOM : : Element  const *  next_sibling_with_same_tag_name ( DOM : : Element  const &  element )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    for  ( auto  const *  sibling  =  element . next_element_sibling ( ) ;  sibling ;  sibling  =  sibling - > next_element_sibling ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( sibling - > tag_name ( )  = =  element . tag_name ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  sibling ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    return  nullptr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-08-22 16:28:06 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								// https://html.spec.whatwg.org/multipage/semantics-other.html#selector-read-write
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								static  bool  matches_read_write_pseudo_class ( DOM : : Element  const &  element )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // The :read-write pseudo-class must match any element falling into one of the following categories,
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // which for the purposes of Selectors are thus considered user-alterable: [SELECTORS]
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // - input elements to which the readonly attribute applies, and that are mutable
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    //   (i.e. that do not have the readonly attribute specified and that are not disabled)
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( is < HTML : : HTMLInputElement > ( element ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        auto &  input_element  =  static_cast < HTML : : HTMLInputElement  const & > ( element ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( input_element . has_attribute ( HTML : : AttributeNames : : readonly ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( ! input_element . enabled ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // - textarea elements that do not have a readonly attribute, and that are not disabled
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( is < HTML : : HTMLTextAreaElement > ( element ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        auto &  input_element  =  static_cast < HTML : : HTMLTextAreaElement  const & > ( element ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( input_element . has_attribute ( HTML : : AttributeNames : : readonly ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( ! input_element . enabled ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // - elements that are editing hosts or editable and are neither input elements nor textarea elements
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    return  element . is_editable ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-09-13 17:39:05 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								// https://www.w3.org/TR/selectors-4/#open-state
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								static  bool  matches_open_state_pseudo_class ( DOM : : Element  const &  element ,  bool  open )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // The :open pseudo-class represents an element that has both “open” and “closed” states,
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // and which is currently in the “open” state.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // The :closed pseudo-class represents an element that has both “open” and “closed” states,
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // and which is currently in the closed state.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // NOTE: Spec specifically suggests supporting <details>, <dialog>, and <select>.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    //       There may be others we want to treat as open or closed.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( is < HTML : : HTMLDetailsElement > ( element )  | |  is < HTML : : HTMLDialogElement > ( element ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  open  = =  element . has_attribute ( HTML : : AttributeNames : : open ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( is < HTML : : HTMLSelectElement > ( element ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  open  = =  static_cast < HTML : : HTMLSelectElement  const & > ( element ) . is_open ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    return  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-07-23 15:22:28 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								// https://drafts.csswg.org/css-scoping/#host-selector
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								static  inline  bool  matches_host_pseudo_class ( JS : : NonnullGCPtr < DOM : : Element  const >  element ,  JS : : GCPtr < DOM : : Element  const >  shadow_host ,  CSS : : SelectorList  const &  argument_selector_list ,  Optional < CSS : : CSSStyleSheet  const & >  style_sheet_for_rule )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
										 
							
							
								    // When evaluated in the context of a shadow tree, it matches the shadow tree’  
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // in its normal context, matches the selector argument. In any other context, it matches nothing.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( ! shadow_host  | |  element  ! =  shadow_host ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // NOTE: There's either 0 or 1 argument selector, since the syntax is :host or :host(<compound-selector>)
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( ! argument_selector_list . is_empty ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  matches ( argument_selector_list . first ( ) ,  style_sheet_for_rule ,  element ,  nullptr ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    return  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								static  inline  bool  matches_pseudo_class ( CSS : : Selector : : SimpleSelector : : PseudoClassSelector  const &  pseudo_class ,  Optional < CSS : : CSSStyleSheet  const & >  style_sheet_for_rule ,  DOM : : Element  const &  element ,  JS : : GCPtr < DOM : : Element  const >  shadow_host ,  JS : : GCPtr < DOM : : ParentNode  const >  scope ,  SelectorKind  selector_kind )  
						 
					
						
							
								
									
										
										
										
											2019-10-08 15:33:58 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2021-07-12 16:18:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    switch  ( pseudo_class . type )  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-08-11 21:26:04 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    case  CSS : : PseudoClass : : Link : 
							 
						 
					
						
							
								
									
										
										
										
											2023-08-22 15:24:12 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    case  CSS : : PseudoClass : : AnyLink : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // NOTE: AnyLink should match whether the link is visited or not, so if we ever start matching
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        //       :visited, we'll need to handle these differently.
 
							 
						 
					
						
							
								
									
										
										
										
											2022-09-14 13:29:07 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  matches_link_pseudo_class ( element ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-08-22 15:24:12 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    case  CSS : : PseudoClass : : LocalLink :  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // The :local-link pseudo-class allows authors to style hyperlinks based on the users current location
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
										 
							
							
								        // within a site. It represents an element that is the source anchor of a hyperlink whose target’  
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
										 
							
							
								        // absolute URL matches the element’ ’  
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // URL, then the fragment URL of the current URL must also match; if it does not, then the fragment
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // URL portion of the current URL is not taken into account in the comparison.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( ! matches_link_pseudo_class ( element ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        auto  document_url  =  element . document ( ) . url ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-03-18 16:22:27 +13:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        URL : : URL  target_url  =  element . document ( ) . parse_url ( element . attribute ( HTML : : AttributeNames : : href ) . value_or ( { } ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-08-22 15:24:12 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( target_url . fragment ( ) . has_value ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2024-02-11 20:15:39 +13:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            return  document_url . equals ( target_url ,  URL : : ExcludeFragment : : No ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  document_url . equals ( target_url ,  URL : : ExcludeFragment : : Yes ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-08-22 15:24:12 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2023-08-11 21:26:04 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    case  CSS : : PseudoClass : : Visited : 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-13 00:21:42 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        // FIXME: Maybe match this selector sometimes?
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  false ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-08-11 21:26:04 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    case  CSS : : PseudoClass : : Active : 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-12 16:18:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  element . is_active ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-08-11 21:26:04 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    case  CSS : : PseudoClass : : Hover : 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-12 16:18:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  matches_hover_pseudo_class ( element ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-08-11 21:26:04 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    case  CSS : : PseudoClass : : Focus : 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-12 16:18:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  element . is_focused ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-08-11 21:26:04 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    case  CSS : : PseudoClass : : FocusVisible : 
							 
						 
					
						
							
								
									
										
										
										
											2023-08-02 14:17:04 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        // FIXME: We should only apply this when a visible focus is useful. Decide when that is!
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  element . is_focused ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-08-11 21:26:04 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    case  CSS : : PseudoClass : : FocusWithin :  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-20 13:28:32 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        auto *  focused_element  =  element . document ( ) . focused_element ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  focused_element  & &  element . is_inclusive_ancestor_of ( * focused_element ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2023-08-11 21:26:04 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    case  CSS : : PseudoClass : : FirstChild : 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-12 16:18:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  ! element . previous_element_sibling ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-08-11 21:26:04 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    case  CSS : : PseudoClass : : LastChild : 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-12 16:18:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  ! element . next_element_sibling ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-08-11 21:26:04 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    case  CSS : : PseudoClass : : OnlyChild : 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-12 16:18:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  ! ( element . previous_element_sibling ( )  | |  element . next_element_sibling ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-08-11 21:26:04 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    case  CSS : : PseudoClass : : Empty :  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-25 17:14:14 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( ! element . has_children ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( element . first_child_of_type < DOM : : Element > ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // NOTE: CSS Selectors level 4 changed ":empty" to also match whitespace-only text nodes.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        //       However, none of the major browser supports this yet, so let's just hang back until they do.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        bool  has_nonempty_text_child  =  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        element . for_each_child_of_type < DOM : : Text > ( [ & ] ( auto  const &  text_child )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( ! text_child . data ( ) . is_empty ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                has_nonempty_text_child  =  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                return  IterationDecision : : Break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  IterationDecision : : Continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  ! has_nonempty_text_child ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2023-08-11 21:26:04 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    case  CSS : : PseudoClass : : Root : 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-10 20:52:58 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  is < HTML : : HTMLHtmlElement > ( element ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-08-11 21:26:04 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    case  CSS : : PseudoClass : : Host : 
							 
						 
					
						
							
								
									
										
										
										
											2024-07-23 15:22:28 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  matches_host_pseudo_class ( element ,  shadow_host ,  pseudo_class . argument_selector_list ,  style_sheet_for_rule ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-08-11 21:26:04 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    case  CSS : : PseudoClass : : Scope : 
							 
						 
					
						
							
								
									
										
										
										
											2023-03-20 23:42:17 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  scope  ?  & element  = =  scope  :  is < HTML : : HTMLHtmlElement > ( element ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-08-11 21:26:04 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    case  CSS : : PseudoClass : : FirstOfType : 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-17 22:43:22 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  ! previous_sibling_with_same_tag_name ( element ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-08-11 21:26:04 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    case  CSS : : PseudoClass : : LastOfType : 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-17 22:43:22 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  ! next_sibling_with_same_tag_name ( element ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-08-11 21:26:04 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    case  CSS : : PseudoClass : : OnlyOfType : 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-17 22:43:22 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  ! previous_sibling_with_same_tag_name ( element )  & &  ! next_sibling_with_same_tag_name ( element ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-08-11 21:26:04 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    case  CSS : : PseudoClass : : Lang : 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-20 12:39:11 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  matches_lang_pseudo_class ( element ,  pseudo_class . languages ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-08-11 21:26:04 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    case  CSS : : PseudoClass : : Disabled : 
							 
						 
					
						
							
								
									
										
										
										
											2022-09-30 16:21:34 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        // https://html.spec.whatwg.org/multipage/semantics-other.html#selector-disabled
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // The :disabled pseudo-class must match any element that is actually disabled.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  element . is_actually_disabled ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-08-11 21:26:04 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    case  CSS : : PseudoClass : : Enabled : 
							 
						 
					
						
							
								
									
										
										
										
											2022-09-30 16:21:34 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        // https://html.spec.whatwg.org/multipage/semantics-other.html#selector-enabled
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // The :enabled pseudo-class must match any button, input, select, textarea, optgroup, option, fieldset element, or form-associated custom element that is not actually disabled.
 
							 
						 
					
						
							
								
									
										
										
										
											2022-09-30 19:40:19 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  ( is < HTML : : HTMLButtonElement > ( element )  | |  is < HTML : : HTMLInputElement > ( element )  | |  is < HTML : : HTMLSelectElement > ( element )  | |  is < HTML : : HTMLTextAreaElement > ( element )  | |  is < HTML : : HTMLOptGroupElement > ( element )  | |  is < HTML : : HTMLOptionElement > ( element )  | |  is < HTML : : HTMLFieldSetElement > ( element ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            & &  ! element . is_actually_disabled ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-08-11 21:26:04 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    case  CSS : : PseudoClass : : Checked : 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-16 23:29:17 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  matches_checked_pseudo_class ( element ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-08-11 21:26:04 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    case  CSS : : PseudoClass : : Indeterminate : 
							 
						 
					
						
							
								
									
										
										
										
											2023-03-20 04:35:43 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  matches_indeterminate_pseudo_class ( element ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-08-11 21:26:04 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    case  CSS : : PseudoClass : : Defined : 
							 
						 
					
						
							
								
									
										
										
										
											2023-03-29 23:48:40 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  element . is_defined ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-07-13 09:19:30 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    case  CSS : : PseudoClass : : Has : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // :has() cannot be nested in a :has()
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( selector_kind  = =  SelectorKind : : Relative ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // These selectors should be relative selectors (https://drafts.csswg.org/selectors-4/#relative-selector)
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        for  ( auto &  selector  :  pseudo_class . argument_selector_list )  { 
							 
						 
					
						
							
								
									
										
										
										
											2024-07-23 15:22:28 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( matches_has_pseudo_class ( selector ,  style_sheet_for_rule ,  element ,  shadow_host ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2024-07-13 09:19:30 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                return  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  false ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-08-11 21:26:04 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    case  CSS : : PseudoClass : : Is : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    case  CSS : : PseudoClass : : Where : 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-17 15:28:42 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        for  ( auto &  selector  :  pseudo_class . argument_selector_list )  { 
							 
						 
					
						
							
								
									
										
										
										
											2024-07-23 15:22:28 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( matches ( selector ,  style_sheet_for_rule ,  element ,  shadow_host ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-17 15:28:42 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                return  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  false ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-08-11 21:26:04 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    case  CSS : : PseudoClass : : Not : 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-17 15:28:42 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        for  ( auto &  selector  :  pseudo_class . argument_selector_list )  { 
							 
						 
					
						
							
								
									
										
										
										
											2024-07-23 15:22:28 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( matches ( selector ,  style_sheet_for_rule ,  element ,  shadow_host ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-12 17:58:47 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                return  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  true ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-08-11 21:26:04 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    case  CSS : : PseudoClass : : NthChild : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    case  CSS : : PseudoClass : : NthLastChild : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    case  CSS : : PseudoClass : : NthOfType : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    case  CSS : : PseudoClass : : NthLastOfType :  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-12 16:18:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        auto  const  step_size  =  pseudo_class . nth_child_pattern . step_size ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        auto  const  offset  =  pseudo_class . nth_child_pattern . offset ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-05-08 23:19:25 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( step_size  = =  0  & &  offset  = =  0 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  false ;  // "If both a and b are equal to zero, the pseudo-class represents no element in the document tree."
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-11-06 19:52:49 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        auto  const *  parent  =  element . parent ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-05-08 23:19:25 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( ! parent ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-07-23 15:22:28 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        auto  matches_selector_list  =  [ & style_sheet_for_rule ,  shadow_host ] ( CSS : : SelectorList  const &  list ,  DOM : : Element  const &  element )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-17 19:13:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( list . is_empty ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                return  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            for  ( auto  const &  child_selector  :  list )  { 
							 
						 
					
						
							
								
									
										
										
										
											2024-07-23 15:22:28 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                if  ( matches ( child_selector ,  style_sheet_for_rule ,  element ,  shadow_host ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-17 19:13:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                    return  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-05-08 23:19:25 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        int  index  =  1 ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-26 13:53:13 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        switch  ( pseudo_class . type )  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-08-11 21:26:04 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        case  CSS : : PseudoClass : : NthChild :  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-17 19:13:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( ! matches_selector_list ( pseudo_class . argument_selector_list ,  element ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                return  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            for  ( auto *  child  =  parent - > first_child_of_type < DOM : : Element > ( ) ;  child  & &  child  ! =  & element ;  child  =  child - > next_element_sibling ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                if  ( matches_selector_list ( pseudo_class . argument_selector_list ,  * child ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    + + index ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            } 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-26 13:53:13 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2023-08-11 21:26:04 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        case  CSS : : PseudoClass : : NthLastChild :  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-17 19:13:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( ! matches_selector_list ( pseudo_class . argument_selector_list ,  element ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                return  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            for  ( auto *  child  =  parent - > last_child_of_type < DOM : : Element > ( ) ;  child  & &  child  ! =  & element ;  child  =  child - > previous_element_sibling ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                if  ( matches_selector_list ( pseudo_class . argument_selector_list ,  * child ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    + + index ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            } 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-26 13:53:13 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2023-08-11 21:26:04 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        case  CSS : : PseudoClass : : NthOfType :  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-26 13:53:13 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            for  ( auto *  child  =  previous_sibling_with_same_tag_name ( element ) ;  child ;  child  =  previous_sibling_with_same_tag_name ( * child ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                + + index ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2023-08-11 21:26:04 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        case  CSS : : PseudoClass : : NthLastOfType :  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-26 13:53:13 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            for  ( auto *  child  =  next_sibling_with_same_tag_name ( element ) ;  child ;  child  =  next_sibling_with_same_tag_name ( * child ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                + + index ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        default : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            VERIFY_NOT_REACHED ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-05-08 23:19:25 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-03-02 15:58:16 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        // When "step_size == -1", selector represents first "offset" elements in document tree.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( step_size  = =  - 1 ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-12 16:18:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            return  ! ( offset  < =  0  | |  index  >  offset ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-02 15:58:16 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // When "step_size == 1", selector represents last "offset" elements in document tree.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( step_size  = =  1 ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-12 16:18:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            return  ! ( offset  <  0  | |  index  <  offset ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-02 15:58:16 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // When "step_size == 0", selector picks only the "offset" element.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( step_size  = =  0 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  index  = =  offset ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // If both are negative, nothing can match.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( step_size  <  0  & &  offset  <  0 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  false ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-05-08 23:19:25 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // Like "a % b", but handles negative integers correctly.
 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-12 14:13:29 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        auto  const  canonical_modulo  =  [ ] ( int  a ,  int  b )  - >  int  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-05-08 23:19:25 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            int  c  =  a  %  b ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( ( c  <  0  & &  b  >  0 )  | |  ( c  >  0  & &  b  <  0 ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                c  + =  b ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  c ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-03-02 15:58:16 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        // When "step_size < 0", we start at "offset" and count backwards.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( step_size  <  0 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  index  < =  offset  & &  canonical_modulo ( index  -  offset ,  - step_size )  = =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // Otherwise, we start at "offset" and count forwards.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  index  > =  offset  & &  canonical_modulo ( index  -  offset ,  step_size )  = =  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-12 16:18:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2023-08-11 21:26:04 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    case  CSS : : PseudoClass : : Playing :  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-08-01 12:31:41 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( ! is < HTML : : HTMLMediaElement > ( element ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        auto  const &  media_element  =  static_cast < HTML : : HTMLMediaElement  const & > ( element ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  ! media_element . paused ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2023-08-11 21:26:04 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    case  CSS : : PseudoClass : : Paused :  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-08-01 12:31:41 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( ! is < HTML : : HTMLMediaElement > ( element ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        auto  const &  media_element  =  static_cast < HTML : : HTMLMediaElement  const & > ( element ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  media_element . paused ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2023-08-11 21:26:04 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    case  CSS : : PseudoClass : : Seeking :  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-08-01 13:04:47 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( ! is < HTML : : HTMLMediaElement > ( element ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        auto  const &  media_element  =  static_cast < HTML : : HTMLMediaElement  const & > ( element ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  media_element . seeking ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2023-08-11 21:26:04 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    case  CSS : : PseudoClass : : Muted :  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-08-01 14:49:28 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( ! is < HTML : : HTMLMediaElement > ( element ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        auto  const &  media_element  =  static_cast < HTML : : HTMLMediaElement  const & > ( element ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  media_element . muted ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2023-08-11 21:26:04 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    case  CSS : : PseudoClass : : VolumeLocked :  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-08-01 15:00:03 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        // FIXME: Currently we don't allow the user to specify an override volume, so this is always false.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        //        Once we do, implement this!
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2023-08-11 21:26:04 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    case  CSS : : PseudoClass : : Buffering :  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-08-01 15:26:56 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( ! is < HTML : : HTMLMediaElement > ( element ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        auto  const &  media_element  =  static_cast < HTML : : HTMLMediaElement  const & > ( element ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  media_element . blocked ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2023-08-11 21:26:04 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    case  CSS : : PseudoClass : : Stalled :  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-08-01 15:26:56 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( ! is < HTML : : HTMLMediaElement > ( element ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        auto  const &  media_element  =  static_cast < HTML : : HTMLMediaElement  const & > ( element ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  media_element . stalled ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2023-08-11 21:26:04 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    case  CSS : : PseudoClass : : Target : 
							 
						 
					
						
							
								
									
										
										
										
											2023-08-11 20:07:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  element . is_target ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-08-22 15:55:46 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    case  CSS : : PseudoClass : : TargetWithin :  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        auto *  target_element  =  element . document ( ) . target_element ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( ! target_element ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  element . is_inclusive_ancestor_of ( * target_element ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2023-08-16 12:11:14 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    case  CSS : : PseudoClass : : Dir :  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // "Values other than ltr and rtl are not invalid, but do not match anything."
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // - https://www.w3.org/TR/selectors-4/#the-dir-pseudo
 
							 
						 
					
						
							
								
									
										
										
										
											2024-08-14 14:06:03 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( ! first_is_one_of ( pseudo_class . keyword ,  CSS : : Keyword : : Ltr ,  CSS : : Keyword : : Rtl ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2023-08-16 12:11:14 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            return  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        switch  ( element . directionality ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        case  DOM : : Element : : Directionality : : Ltr : 
							 
						 
					
						
							
								
									
										
										
										
											2024-08-14 14:06:03 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            return  pseudo_class . keyword  = =  CSS : : Keyword : : Ltr ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-08-16 12:11:14 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        case  DOM : : Element : : Directionality : : Rtl : 
							 
						 
					
						
							
								
									
										
										
										
											2024-08-14 14:06:03 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            return  pseudo_class . keyword  = =  CSS : : Keyword : : Rtl ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-08-16 12:11:14 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        VERIFY_NOT_REACHED ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2023-08-22 16:28:06 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    case  CSS : : PseudoClass : : ReadOnly : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  ! matches_read_write_pseudo_class ( element ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    case  CSS : : PseudoClass : : ReadWrite : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  matches_read_write_pseudo_class ( element ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-08-22 16:51:42 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    case  CSS : : PseudoClass : : PlaceholderShown :  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // https://html.spec.whatwg.org/multipage/semantics-other.html#selector-placeholder-shown
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        //  The :placeholder-shown pseudo-class must match any element falling into one of the following categories:
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // - input elements that have a placeholder attribute whose value is currently being presented to the user.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( is < HTML : : HTMLInputElement > ( element )  & &  element . has_attribute ( HTML : : AttributeNames : : placeholder ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            auto  const &  input_element  =  static_cast < HTML : : HTMLInputElement  const & > ( element ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  input_element . placeholder_element ( )  & &  input_element . placeholder_value ( ) . has_value ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // - FIXME: textarea elements that have a placeholder attribute whose value is currently being presented to the user.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2023-09-13 17:39:05 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    case  CSS : : PseudoClass : : Open : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    case  CSS : : PseudoClass : : Closed : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  matches_open_state_pseudo_class ( element ,  pseudo_class . type  = =  CSS : : PseudoClass : : Open ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-07-02 00:36:36 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    case  CSS : : PseudoClass : : Modal :  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // https://drafts.csswg.org/selectors/#modal-state
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( is < HTML : : HTMLDialogElement > ( element ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            auto  const &  dialog_element  =  static_cast < HTML : : HTMLDialogElement  const & > ( element ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  dialog_element . is_modal ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // FIXME: fullscreen elements are also modal.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2023-08-01 12:31:41 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-12 16:18:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    return  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-03-19 10:34:32 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								static  ALWAYS_INLINE  bool  matches_namespace (  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    CSS : : Selector : : SimpleSelector : : QualifiedName  const &  qualified_name , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    DOM : : Element  const &  element , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    Optional < CSS : : CSSStyleSheet  const & >  style_sheet_for_rule ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    switch  ( qualified_name . namespace_type )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    case  CSS : : Selector : : SimpleSelector : : QualifiedName : : NamespaceType : : Default : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // "if no default namespace has been declared for selectors, this is equivalent to *|E."
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( ! style_sheet_for_rule . has_value ( )  | |  ! style_sheet_for_rule - > default_namespace_rule ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // "Otherwise it is equivalent to ns|E where ns is the default namespace."
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  element . namespace_uri ( )  = =  style_sheet_for_rule - > default_namespace_rule ( ) - > namespace_uri ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    case  CSS : : Selector : : SimpleSelector : : QualifiedName : : NamespaceType : : None : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // "elements with name E without a namespace"
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  ! element . namespace_uri ( ) . has_value ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    case  CSS : : Selector : : SimpleSelector : : QualifiedName : : NamespaceType : : Any : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // "elements with name E in any namespace, including those without a namespace"
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    case  CSS : : Selector : : SimpleSelector : : QualifiedName : : NamespaceType : : Named : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // "elements with name E in namespace ns"
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // Unrecognized namespace prefixes are invalid, so don't match.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // (We can't detect this at parse time, since a namespace rule may be inserted later.)
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // So, if we don't have a context to look up namespaces from, we fail to match.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( ! style_sheet_for_rule . has_value ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        auto  selector_namespace  =  style_sheet_for_rule - > namespace_uri ( qualified_name . namespace_ ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  selector_namespace . has_value ( )  & &  selector_namespace . value ( )  = =  element . namespace_uri ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    VERIFY_NOT_REACHED ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-10-27 12:15:19 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								static  inline  bool  matches ( CSS : : Selector : : SimpleSelector  const &  component ,  Optional < CSS : : CSSStyleSheet  const & >  style_sheet_for_rule ,  DOM : : Element  const &  element ,  JS : : GCPtr < DOM : : Element  const >  shadow_host ,  JS : : GCPtr < DOM : : ParentNode  const >  scope ,  SelectorKind  selector_kind ,  [[maybe_unused]]  JS : : GCPtr < DOM : : Element  const >  anchor )  
						 
					
						
							
								
									
										
										
										
											2021-07-12 16:18:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2019-10-08 15:33:58 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    switch  ( component . type )  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-07-26 20:01:35 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    case  CSS : : Selector : : SimpleSelector : : Type : : Universal : 
							 
						 
					
						
							
								
									
										
										
										
											2023-08-08 15:11:48 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    case  CSS : : Selector : : SimpleSelector : : Type : : TagName :  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-11-02 08:09:01 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        auto  const &  qualified_name  =  component . qualified_name ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-08-08 15:11:48 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // Reject if the tag name doesn't match
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( component . type  = =  CSS : : Selector : : SimpleSelector : : Type : : TagName )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            // See https://html.spec.whatwg.org/multipage/semantics-other.html#case-sensitivity-of-selectors
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( element . document ( ) . document_type ( )  = =  DOM : : Document : : Type : : HTML )  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-10-01 20:07:44 +13:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                if  ( qualified_name . name . lowercase_name  ! =  element . local_name ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2023-08-08 15:11:48 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                    return  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            }  else  if  ( ! Infra : : is_ascii_case_insensitive_match ( qualified_name . name . name ,  element . local_name ( ) ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                return  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-03-19 10:34:32 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  matches_namespace ( qualified_name ,  element ,  style_sheet_for_rule ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-08-08 15:11:48 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2020-07-26 20:01:35 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    case  CSS : : Selector : : SimpleSelector : : Type : : Id : 
							 
						 
					
						
							
								
									
										
										
										
											2023-11-02 14:57:40 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  component . name ( )  = =  element . id ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-08-02 22:21:12 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    case  CSS : : Selector : : SimpleSelector : : Type : : Class :  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // Class selectors are matched case insensitively in quirks mode.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // See: https://drafts.csswg.org/selectors-4/#class-html
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        auto  case_sensitivity  =  element . document ( ) . in_quirks_mode ( )  ?  CaseSensitivity : : CaseInsensitive  :  CaseSensitivity : : CaseSensitive ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  element . has_class ( component . name ( ) ,  case_sensitivity ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-12 14:58:03 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    case  CSS : : Selector : : SimpleSelector : : Type : : Attribute : 
							 
						 
					
						
							
								
									
										
										
										
											2023-08-08 16:19:20 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  matches_attribute ( component . attribute ( ) ,  style_sheet_for_rule ,  element ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-12 16:18:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    case  CSS : : Selector : : SimpleSelector : : Type : : PseudoClass : 
							 
						 
					
						
							
								
									
										
										
										
											2024-07-23 15:22:28 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  matches_pseudo_class ( component . pseudo_class ( ) ,  style_sheet_for_rule ,  element ,  shadow_host ,  scope ,  selector_kind ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-12 16:34:18 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    case  CSS : : Selector : : SimpleSelector : : Type : : PseudoElement : 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-24 15:54:12 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        // Pseudo-element matching/not-matching is handled in the top level matches().
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  true ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-10-15 12:00:29 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    case  CSS : : Selector : : SimpleSelector : : Type : : Nesting : 
							 
						 
					
						
							
								
									
										
										
										
											2024-11-08 20:34:48 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        // Nesting either behaves like :is(), or like :scope.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // :is() is handled already, by us replacing it with :is() directly, so if we
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // got here, it's :scope.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  matches_pseudo_class ( CSS : : Selector : : SimpleSelector : : PseudoClassSelector  {  . type  =  CSS : : PseudoClass : : Scope  } ,  style_sheet_for_rule ,  element ,  shadow_host ,  scope ,  selector_kind ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-11-13 15:49:43 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    case  CSS : : Selector : : SimpleSelector : : Type : : Invalid : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // Invalid selectors never match
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  false ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-10-08 15:33:58 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2024-10-15 12:00:29 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    VERIFY_NOT_REACHED ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-10-08 15:33:58 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-10-27 12:15:19 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								bool  matches ( CSS : : Selector  const &  selector ,  Optional < CSS : : CSSStyleSheet  const & >  style_sheet_for_rule ,  int  component_list_index ,  DOM : : Element  const &  element ,  JS : : GCPtr < DOM : : Element  const >  shadow_host ,  JS : : GCPtr < DOM : : ParentNode  const >  scope ,  SelectorKind  selector_kind ,  JS : : GCPtr < DOM : : Element  const >  anchor )  
						 
					
						
							
								
									
										
										
										
											2019-10-08 15:33:58 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2024-07-13 09:19:30 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    auto &  compound_selector  =  selector . compound_selectors ( ) [ component_list_index ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    for  ( auto &  simple_selector  :  compound_selector . simple_selectors )  { 
							 
						 
					
						
							
								
									
										
										
										
											2024-10-27 12:15:19 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( ! matches ( simple_selector ,  style_sheet_for_rule ,  element ,  shadow_host ,  scope ,  selector_kind ,  anchor ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-11-27 20:37:36 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            return  false ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-07-23 15:22:28 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2019-11-27 20:37:36 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2024-10-27 12:15:19 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( selector_kind  = =  SelectorKind : : Relative  & &  component_list_index  = =  0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        VERIFY ( anchor ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  & element  ! =  anchor ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-07-13 09:19:30 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    switch  ( compound_selector . combinator )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-23 15:24:33 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    case  CSS : : Selector : : Combinator : : None : 
							 
						 
					
						
							
								
									
										
										
										
											2024-07-13 09:19:30 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        VERIFY ( selector_kind  ! =  SelectorKind : : Relative ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-10-08 15:33:58 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  true ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-23 15:24:33 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    case  CSS : : Selector : : Combinator : : Descendant : 
							 
						 
					
						
							
								
									
										
										
										
											2021-02-23 20:42:32 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        VERIFY ( component_list_index  ! =  0 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-07-23 15:22:28 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        for  ( auto  ancestor  =  traverse_up ( element ,  shadow_host ) ;  ancestor ;  ancestor  =  traverse_up ( ancestor ,  shadow_host ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-07-26 19:37:56 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( ! is < DOM : : Element > ( * ancestor ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2019-10-08 15:33:58 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                continue ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-10-27 12:15:19 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( ancestor  = =  anchor ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                return  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( matches ( selector ,  style_sheet_for_rule ,  component_list_index  -  1 ,  static_cast < DOM : : Element  const & > ( * ancestor ) ,  shadow_host ,  scope ,  selector_kind ,  anchor ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2019-10-08 15:33:58 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                return  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  false ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-07-23 15:22:28 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    case  CSS : : Selector : : Combinator : : ImmediateChild :  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-02-23 20:42:32 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        VERIFY ( component_list_index  ! =  0 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-07-23 15:22:28 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        auto  parent  =  traverse_up ( element ,  shadow_host ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( ! parent  | |  ! parent - > is_element ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2019-10-08 15:33:58 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  false ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-10-27 12:15:19 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  matches ( selector ,  style_sheet_for_rule ,  component_list_index  -  1 ,  static_cast < DOM : : Element  const & > ( * parent ) ,  shadow_host ,  scope ,  selector_kind ,  anchor ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-07-23 15:22:28 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-23 15:24:33 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    case  CSS : : Selector : : Combinator : : NextSibling : 
							 
						 
					
						
							
								
									
										
										
										
											2021-02-23 20:42:32 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        VERIFY ( component_list_index  ! =  0 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-10-08 15:33:58 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( auto *  sibling  =  element . previous_element_sibling ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2024-10-27 12:15:19 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            return  matches ( selector ,  style_sheet_for_rule ,  component_list_index  -  1 ,  * sibling ,  shadow_host ,  scope ,  selector_kind ,  anchor ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-10-08 15:33:58 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  false ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-23 15:24:33 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    case  CSS : : Selector : : Combinator : : SubsequentSibling : 
							 
						 
					
						
							
								
									
										
										
										
											2021-02-23 20:42:32 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        VERIFY ( component_list_index  ! =  0 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-10-08 15:33:58 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        for  ( auto *  sibling  =  element . previous_element_sibling ( ) ;  sibling ;  sibling  =  sibling - > previous_element_sibling ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2024-10-27 12:15:19 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( matches ( selector ,  style_sheet_for_rule ,  component_list_index  -  1 ,  * sibling ,  shadow_host ,  scope ,  selector_kind ,  anchor ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2019-10-08 15:33:58 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                return  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  false ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-23 15:24:33 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    case  CSS : : Selector : : Combinator : : Column : 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-29 21:16:28 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        TODO ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-10-08 15:33:58 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2021-02-23 20:42:32 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    VERIFY_NOT_REACHED ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-10-08 15:33:58 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-10-27 12:15:19 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								bool  matches ( CSS : : Selector  const &  selector ,  Optional < CSS : : CSSStyleSheet  const & >  style_sheet_for_rule ,  DOM : : Element  const &  element ,  JS : : GCPtr < DOM : : Element  const >  shadow_host ,  Optional < CSS : : Selector : : PseudoElement : : Type >  pseudo_element ,  JS : : GCPtr < DOM : : ParentNode  const >  scope ,  SelectorKind  selector_kind ,  JS : : GCPtr < DOM : : Element  const >  anchor )  
						 
					
						
							
								
									
										
										
										
											2019-10-08 15:33:58 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2021-07-23 15:24:33 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    VERIFY ( ! selector . compound_selectors ( ) . is_empty ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-12-10 21:00:03 +13:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( pseudo_element . has_value ( )  & &  selector . pseudo_element ( ) . has_value ( )  & &  selector . pseudo_element ( ) . value ( ) . type ( )  ! =  pseudo_element ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-24 15:54:12 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( ! pseudo_element . has_value ( )  & &  selector . pseudo_element ( ) . has_value ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  false ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-10-27 12:15:19 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    return  matches ( selector ,  style_sheet_for_rule ,  selector . compound_selectors ( ) . size ( )  -  1 ,  element ,  shadow_host ,  scope ,  selector_kind ,  anchor ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-10-08 15:33:58 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-07-23 15:22:28 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								static  bool  fast_matches_simple_selector ( CSS : : Selector : : SimpleSelector  const &  simple_selector ,  Optional < CSS : : CSSStyleSheet  const & >  style_sheet_for_rule ,  DOM : : Element  const &  element ,  JS : : GCPtr < DOM : : Element  const >  shadow_host )  
						 
					
						
							
								
									
										
										
										
											2024-03-19 10:36:08 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    switch  ( simple_selector . type )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    case  CSS : : Selector : : SimpleSelector : : Type : : Universal : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  matches_namespace ( simple_selector . qualified_name ( ) ,  element ,  style_sheet_for_rule ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    case  CSS : : Selector : : SimpleSelector : : Type : : TagName : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( element . document ( ) . document_type ( )  = =  DOM : : Document : : Type : : HTML )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( simple_selector . qualified_name ( ) . name . lowercase_name  ! =  element . local_name ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                return  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        }  else  if  ( ! Infra : : is_ascii_case_insensitive_match ( simple_selector . qualified_name ( ) . name . name ,  element . local_name ( ) ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  matches_namespace ( simple_selector . qualified_name ( ) ,  element ,  style_sheet_for_rule ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-08-02 22:21:12 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    case  CSS : : Selector : : SimpleSelector : : Type : : Class :  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // Class selectors are matched case insensitively in quirks mode.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // See: https://drafts.csswg.org/selectors-4/#class-html
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        auto  case_sensitivity  =  element . document ( ) . in_quirks_mode ( )  ?  CaseSensitivity : : CaseInsensitive  :  CaseSensitivity : : CaseSensitive ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  element . has_class ( simple_selector . name ( ) ,  case_sensitivity ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2024-03-19 10:36:08 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    case  CSS : : Selector : : SimpleSelector : : Type : : Id : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  simple_selector . name ( )  = =  element . id ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    case  CSS : : Selector : : SimpleSelector : : Type : : Attribute : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  matches_attribute ( simple_selector . attribute ( ) ,  style_sheet_for_rule ,  element ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-03-19 10:58:10 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    case  CSS : : Selector : : SimpleSelector : : Type : : PseudoClass : 
							 
						 
					
						
							
								
									
										
										
										
											2024-07-23 15:22:28 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  matches_pseudo_class ( simple_selector . pseudo_class ( ) ,  style_sheet_for_rule ,  element ,  shadow_host ,  nullptr ,  SelectorKind : : Normal ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-03-19 10:36:08 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    default : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        VERIFY_NOT_REACHED ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-07-23 15:22:28 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								static  bool  fast_matches_compound_selector ( CSS : : Selector : : CompoundSelector  const &  compound_selector ,  Optional < CSS : : CSSStyleSheet  const & >  style_sheet_for_rule ,  DOM : : Element  const &  element ,  JS : : GCPtr < DOM : : Element  const >  shadow_host )  
						 
					
						
							
								
									
										
										
										
											2024-03-19 10:36:08 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    for  ( auto  const &  simple_selector  :  compound_selector . simple_selectors )  { 
							 
						 
					
						
							
								
									
										
										
										
											2024-07-23 15:22:28 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( ! fast_matches_simple_selector ( simple_selector ,  style_sheet_for_rule ,  element ,  shadow_host ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2024-03-19 10:36:08 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            return  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    return  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-07-23 15:22:28 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								bool  fast_matches ( CSS : : Selector  const &  selector ,  Optional < CSS : : CSSStyleSheet  const & >  style_sheet_for_rule ,  DOM : : Element  const &  element_to_match ,  JS : : GCPtr < DOM : : Element  const >  shadow_host )  
						 
					
						
							
								
									
										
										
										
											2024-03-19 10:36:08 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    DOM : : Element  const *  current  =  & element_to_match ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    ssize_t  compound_selector_index  =  selector . compound_selectors ( ) . size ( )  -  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-07-23 15:22:28 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( ! fast_matches_compound_selector ( selector . compound_selectors ( ) . last ( ) ,  style_sheet_for_rule ,  * current ,  shadow_host ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2024-03-19 10:36:08 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // NOTE: If we fail after following a child combinator, we may need to backtrack
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    //       to the last matched descendant. We store the state here.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    struct  { 
							 
						 
					
						
							
								
									
										
										
										
											2024-04-05 13:47:48 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        JS : : GCPtr < DOM : : Element  const >  element ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-03-19 10:36:08 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        ssize_t  compound_selector_index  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    }  backtrack_state ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    for  ( ; ; )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // NOTE: There should always be a leftmost compound selector without combinator that kicks us out of this loop.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        VERIFY ( compound_selector_index  > =  0 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        auto  const *  compound_selector  =  & selector . compound_selectors ( ) [ compound_selector_index ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        switch  ( compound_selector - > combinator )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        case  CSS : : Selector : : Combinator : : None : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        case  CSS : : Selector : : Combinator : : Descendant : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            backtrack_state  =  {  current - > parent_element ( ) ,  compound_selector_index  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            compound_selector  =  & selector . compound_selectors ( ) [ - - compound_selector_index ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            for  ( current  =  current - > parent_element ( ) ;  current ;  current  =  current - > parent_element ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2024-07-23 15:22:28 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                if  ( fast_matches_compound_selector ( * compound_selector ,  style_sheet_for_rule ,  * current ,  shadow_host ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2024-03-19 10:36:08 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                    break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( ! current ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                return  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        case  CSS : : Selector : : Combinator : : ImmediateChild : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            compound_selector  =  & selector . compound_selectors ( ) [ - - compound_selector_index ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            current  =  current - > parent_element ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( ! current ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                return  false ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-07-23 15:22:28 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( ! fast_matches_compound_selector ( * compound_selector ,  style_sheet_for_rule ,  * current ,  shadow_host ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2024-03-19 10:36:08 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                if  ( backtrack_state . element )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    current  =  backtrack_state . element ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    compound_selector_index  =  backtrack_state . compound_selector_index ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                return  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        default : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            VERIFY_NOT_REACHED ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								bool  can_use_fast_matches ( CSS : : Selector  const &  selector )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    for  ( auto  const &  compound_selector  :  selector . compound_selectors ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( compound_selector . combinator  ! =  CSS : : Selector : : Combinator : : None 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            & &  compound_selector . combinator  ! =  CSS : : Selector : : Combinator : : Descendant 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            & &  compound_selector . combinator  ! =  CSS : : Selector : : Combinator : : ImmediateChild )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        for  ( auto  const &  simple_selector  :  compound_selector . simple_selectors )  { 
							 
						 
					
						
							
								
									
										
										
										
											2024-03-19 10:58:10 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( simple_selector . type  = =  CSS : : Selector : : SimpleSelector : : Type : : PseudoClass )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                auto  const  pseudo_class  =  simple_selector . pseudo_class ( ) . type ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                if  ( pseudo_class  ! =  CSS : : PseudoClass : : FirstChild 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    & &  pseudo_class  ! =  CSS : : PseudoClass : : LastChild 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    & &  pseudo_class  ! =  CSS : : PseudoClass : : OnlyChild 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    & &  pseudo_class  ! =  CSS : : PseudoClass : : Hover 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    & &  pseudo_class  ! =  CSS : : PseudoClass : : Active 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    & &  pseudo_class  ! =  CSS : : PseudoClass : : Focus 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    & &  pseudo_class  ! =  CSS : : PseudoClass : : FocusVisible 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    & &  pseudo_class  ! =  CSS : : PseudoClass : : FocusWithin 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    & &  pseudo_class  ! =  CSS : : PseudoClass : : Link 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    & &  pseudo_class  ! =  CSS : : PseudoClass : : AnyLink 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    & &  pseudo_class  ! =  CSS : : PseudoClass : : Visited 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    & &  pseudo_class  ! =  CSS : : PseudoClass : : LocalLink 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    & &  pseudo_class  ! =  CSS : : PseudoClass : : Empty 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    & &  pseudo_class  ! =  CSS : : PseudoClass : : Root 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    & &  pseudo_class  ! =  CSS : : PseudoClass : : Enabled 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    & &  pseudo_class  ! =  CSS : : PseudoClass : : Disabled 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    & &  pseudo_class  ! =  CSS : : PseudoClass : : Checked )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    return  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            }  else  if  ( simple_selector . type  ! =  CSS : : Selector : : SimpleSelector : : Type : : TagName 
							 
						 
					
						
							
								
									
										
										
										
											2024-03-19 10:36:08 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                & &  simple_selector . type  ! =  CSS : : Selector : : SimpleSelector : : Type : : Universal 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                & &  simple_selector . type  ! =  CSS : : Selector : : SimpleSelector : : Type : : Class 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                & &  simple_selector . type  ! =  CSS : : Selector : : SimpleSelector : : Type : : Id 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                & &  simple_selector . type  ! =  CSS : : Selector : : SimpleSelector : : Type : : Attribute )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                return  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    return  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-10-08 15:33:58 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								}