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 > 
							 
						 
					
						
							
								
									
										
										
										
											2025-08-12 11:17:26 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								 *  Copyright  ( c )  2021 - 2025 ,  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-12-20 11:32:17 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								# include  <LibWeb/CSS/ComputedProperties.h> 
  
						 
					
						
							
								
									
										
										
										
											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> 
  
						 
					
						
							
								
									
										
										
										
											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> 
  
						 
					
						
							
								
									
										
										
										
											2025-07-04 15:18:08 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								# include  <LibWeb/HTML/CustomElements/CustomStateSet.h> 
  
						 
					
						
							
								
									
										
										
										
											2022-09-14 13:29:07 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								# include  <LibWeb/HTML/HTMLAnchorElement.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> 
  
						 
					
						
							
								
									
										
										
										
											2025-02-02 20:41:23 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								# include  <LibWeb/HTML/HTMLFormElement.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> 
  
						 
					
						
							
								
									
										
										
										
											2025-03-18 16:56:41 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								# include  <LibWeb/HTML/HTMLMeterElement.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 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2025-01-03 20:39:25 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								static  inline  bool  matches ( CSS : : Selector  const &  selector ,  int  component_list_index ,  DOM : : Element  const &  element ,  GC : : Ptr < DOM : : Element  const >  shadow_host ,  MatchContext &  context ,  GC : : Ptr < DOM : : ParentNode  const >  scope ,  SelectorKind  selector_kind ,  GC : : Ptr < DOM : : Element  const >  anchor  =  nullptr ) ;  
						 
					
						
							
								
									
										
										
										
											2024-10-27 12:15:19 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											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.
  
						 
					
						
							
								
									
										
										
										
											2024-11-15 04:01:23 +13:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								static  inline  GC : : Ptr < DOM : : Node  const >  traverse_up ( GC : : Ptr < DOM : : Node  const >  node ,  GC : : Ptr < DOM : : Element  const >  shadow_host )  
						 
					
						
							
								
									
										
										
										
											2024-07-23 15:22:28 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    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 ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2025-05-15 14:47:05 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								// https://www.rfc-editor.org/rfc/rfc4647.html#section-3.3.2
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								// NB: Language tags only use ASCII characters, so we can get away with using StringView.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								static  bool  language_range_matches_tag ( StringView  language_range ,  StringView  language_tag )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // 1. Split both the extended language range and the language tag being compared into a list of subtags by
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    //    dividing on the hyphen (%x2D) character.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  range_subtags  =  language_range . split_view ( ' - ' ,  SplitBehavior : : KeepEmpty ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  tag_subtags  =  language_tag . split_view ( ' - ' ,  SplitBehavior : : KeepEmpty ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    //    Two subtags match if either they are the same when compared case-insensitively or the language range's subtag
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    //    is the wildcard '*'.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  subtags_match  =  [ ] ( StringView  language_range_subtag ,  StringView  language_subtag )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  language_range_subtag  = =  " * " sv 
							 
						 
					
						
							
								
									
										
										
										
											2025-05-18 15:04:56 +12:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            | |  language_range_subtag . equals_ignoring_ascii_case ( language_subtag ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2025-05-15 14:47:05 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // 2. Begin with the first subtag in each list. If the first subtag in the range does not match the first
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    //    subtag in the tag, the overall match fails. Otherwise, move to the next subtag in both the range and the
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    //    tag.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  tag_subtag  =  tag_subtags . begin ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  range_subtag  =  range_subtags . begin ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( ! subtags_match ( * range_subtag ,  * tag_subtag ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    + + tag_subtag ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    + + range_subtag ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // 3. While there are more subtags left in the language range's list:
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    while  ( ! range_subtag . is_end ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // A. If the subtag currently being examined in the range is the wildcard ('*'), move to the next subtag in
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        //    the range and continue with the loop.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( * range_subtag  = =  " * " sv )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            + + range_subtag ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // B. Else, if there are no more subtags in the language tag's list, the match fails.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( tag_subtag . is_end ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // C. Else, if the current subtag in the range's list matches the current subtag in the language tag's
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        //    list, move to the next subtag in both lists and continue with the loop.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( subtags_match ( * range_subtag ,  * tag_subtag ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            + + range_subtag ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            + + tag_subtag ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // D. Else, if the language tag's subtag is a "singleton" (a single letter or digit, which includes the
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        //    private-use subtag 'x') the match fails.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( tag_subtag - > length ( )  = =  1  & &  is_ascii_alphanumeric ( ( * tag_subtag ) [ 0 ] ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // E. Else, move to the next subtag in the language tag's list and continue with the loop.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        + + tag_subtag ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // 4. When the language range's list has no more subtags, the match succeeds.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    return  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											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 ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2025-05-15 14:47:05 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
										 
							
							
								    // The element’  
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // syntax, matches the given language range in an extended filtering operation per [RFC4647] Matching of Language
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // Tags (section 3.3.2). Both the content language and the language range must be canonicalized and converted to
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // extlang form as per section 4.5 of [RFC5646] prior to the extended filtering operation. The matching is
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // performed case-insensitively within the ASCII range.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // FIXME: Canonicalize both as extlang.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    for  ( auto  const &  language_range  :  languages )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( language_range_matches_tag ( language_range ,  element_language ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-20 12:39:11 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            return  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    return  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-07-13 09:19:30 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								// https://drafts.csswg.org/selectors-4/#relational
  
						 
					
						
							
								
									
										
										
										
											2025-01-03 20:39:25 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								static  inline  bool  matches_relative_selector ( CSS : : Selector  const &  selector ,  size_t  compound_index ,  DOM : : Element  const &  element ,  GC : : Ptr < DOM : : Element  const >  shadow_host ,  MatchContext &  context ,  GC : : Ref < 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 ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2025-01-03 20:39:25 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  matches ( selector ,  element ,  shadow_host ,  context ,  { } ,  { } ,  SelectorKind : : Relative ,  anchor ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-10-27 12:15:19 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    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 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2025-01-03 20:39:25 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( matches ( selector ,  descendant_element ,  shadow_host ,  context ,  { } ,  { } ,  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 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2025-01-03 20:39:25 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( ! matches ( selector ,  compound_index ,  child_element ,  shadow_host ,  context ,  { } ,  SelectorKind : : Relative ,  anchor ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2024-10-27 12:15:19 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                return  IterationDecision : : Continue ; 
							 
						 
					
						
							
								
									
										
										
										
											2025-01-03 20:39:25 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( matches_relative_selector ( selector ,  compound_index  +  1 ,  child_element ,  shadow_host ,  context ,  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 :  { 
							 
						 
					
						
							
								
									
										
										
										
											2025-02-08 19:09:08 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( context . collect_per_element_selector_involvement_metadata )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            const_cast < DOM : : Element & > ( * anchor ) . set_affected_by_has_pseudo_class_with_relative_selector_that_has_sibling_combinator ( true ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2024-10-27 12:15:19 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        auto *  sibling  =  element . next_element_sibling ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( ! sibling ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  false ; 
							 
						 
					
						
							
								
									
										
										
										
											2025-01-03 20:39:25 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( ! matches ( selector ,  compound_index ,  * sibling ,  shadow_host ,  context ,  { } ,  SelectorKind : : Relative ,  anchor ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2024-10-27 12:15:19 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            return  false ; 
							 
						 
					
						
							
								
									
										
										
										
											2025-01-03 20:39:25 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  matches_relative_selector ( selector ,  compound_index  +  1 ,  * sibling ,  shadow_host ,  context ,  anchor ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-10-27 12:15:19 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2024-07-13 09:19:30 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    case  CSS : : Selector : : Combinator : : SubsequentSibling :  { 
							 
						 
					
						
							
								
									
										
										
										
											2025-02-08 19:09:08 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( context . collect_per_element_selector_involvement_metadata )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            const_cast < DOM : : Element & > ( * anchor ) . set_affected_by_has_pseudo_class_with_relative_selector_that_has_sibling_combinator ( true ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2024-10-27 12:15:19 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        for  ( auto  const *  sibling  =  element . next_element_sibling ( ) ;  sibling ;  sibling  =  sibling - > next_element_sibling ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2025-01-03 20:39:25 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( ! matches ( selector ,  compound_index ,  * sibling ,  shadow_host ,  context ,  { } ,  SelectorKind : : Relative ,  anchor ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2024-10-27 12:15:19 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                continue ; 
							 
						 
					
						
							
								
									
										
										
										
											2025-01-03 20:39:25 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( matches_relative_selector ( selector ,  compound_index  +  1 ,  * sibling ,  shadow_host ,  context ,  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
  
						 
					
						
							
								
									
										
										
										
											2025-01-03 20:39:25 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								static  inline  bool  matches_has_pseudo_class ( CSS : : Selector  const &  selector ,  DOM : : Element  const &  anchor ,  GC : : Ptr < DOM : : Element  const >  shadow_host ,  MatchContext &  context )  
						 
					
						
							
								
									
										
										
										
											2024-10-27 12:15:19 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2025-01-03 20:39:25 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    return  matches_relative_selector ( selector ,  0 ,  anchor ,  shadow_host ,  context ,  anchor ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-10-27 12:15:19 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2025-02-02 20:35:29 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								static  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 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											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 : 
							 
						 
					
						
							
								
									
										
										
										
											2024-12-11 11:34:41 +09:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            // https://whatpr.org/html-attr-input-switch/9546/semantics-other.html#selector-indeterminate
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            // input elements whose type attribute is in the Checkbox state, whose switch attribute is not set
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  input_element . indeterminate ( )  & &  ! element . has_attribute ( HTML : : AttributeNames : : switch_ ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-03-20 04:35:43 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        default : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // - progress elements with no value content attribute
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( is < HTML : : HTMLProgressElement > ( element ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  ! element . has_attribute ( HTML : : AttributeNames : : value ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    return  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2025-05-15 19:18:04 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								static  inline  void  for_each_matching_attribute ( CSS : : Selector : : SimpleSelector : : Attribute  const &  attribute_selector ,  GC : : Ptr < CSS : : CSSStyleSheet  const >  style_sheet_for_rule ,  DOM : : Element  const &  element ,  Function < IterationDecision ( DOM : : Attr  const & ) >  const &  process_attribute )  
						 
					
						
							
								
									
										
										
										
											2021-07-12 14:58:03 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2025-05-15 19:18:04 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    auto  const &  qualified_name  =  attribute_selector . qualified_name ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-11-27 20:24:29 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    auto  const &  attribute_name  =  qualified_name . name . name ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2025-05-15 19:18:04 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    switch  ( qualified_name . namespace_type )  { 
							 
						 
					
						
							
								
									
										
										
										
											2024-11-27 20:24:29 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    // "In keeping with the Namespaces in the XML recommendation, default namespaces do not apply to attributes,
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    //  therefore attribute selectors without a namespace component apply only to attributes that have no namespace (equivalent to "|attr")"
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    case  CSS : : Selector : : SimpleSelector : : QualifiedName : : NamespaceType : : Default : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    case  CSS : : Selector : : SimpleSelector : : QualifiedName : : NamespaceType : : None : 
							 
						 
					
						
							
								
									
										
										
										
											2025-05-15 19:18:04 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( auto  const *  attribute  =  element . attributes ( ) - > get_attribute ( attribute_name ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            ( void ) process_attribute ( * attribute ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    case  CSS : : Selector : : SimpleSelector : : QualifiedName : : NamespaceType : : Any :  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // When comparing the name part of a CSS attribute selector to the names of attributes on HTML elements in HTML
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // documents, the name part of the CSS attribute selector must first be converted to ASCII lowercase. The same
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // selector when compared to other attributes must be compared according to its original case. In both cases, the
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // comparison is case-sensitive.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // https://html.spec.whatwg.org/multipage/semantics-other.html#case-sensitivity-of-selectors
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        bool  const  case_insensitive  =  element . document ( ) . is_html_document ( )  & &  element . namespace_uri ( )  = =  Namespace : : HTML ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        for  ( auto  i  =  0u ;  i  <  element . attributes ( ) - > length ( ) ;  + + i )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            auto  const *  attr  =  element . attributes ( ) - > item ( i ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            bool  matches  =  case_insensitive 
							 
						 
					
						
							
								
									
										
										
										
											2025-05-18 15:04:56 +12:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                ?  attr - > local_name ( ) . equals_ignoring_ascii_case ( attribute_name ) 
							 
						 
					
						
							
								
									
										
										
										
											2025-05-15 19:18:04 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                :  attr - > local_name ( )  = =  attribute_name ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( matches )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                if  ( process_attribute ( * attr )  = =  IterationDecision : : Break ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2024-11-27 20:24:29 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    case  CSS : : Selector : : SimpleSelector : : QualifiedName : : NamespaceType : : Named : 
							 
						 
					
						
							
								
									
										
										
										
											2025-01-03 20:39:25 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( ! style_sheet_for_rule ) 
							 
						 
					
						
							
								
									
										
										
										
											2025-05-15 19:18:04 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            return ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-11-27 20:24:29 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        auto  const &  selector_namespace  =  style_sheet_for_rule - > namespace_uri ( qualified_name . namespace_ ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( ! selector_namespace . has_value ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2025-05-15 19:18:04 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( auto  const *  attribute  =  element . attributes ( ) - > get_attribute_ns ( selector_namespace ,  attribute_name ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            ( void ) process_attribute ( * attribute ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-11-27 20:24:29 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    VERIFY_NOT_REACHED ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2023-08-08 16:19:20 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2025-05-15 19:18:04 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								static  bool  matches_single_attribute ( CSS : : Selector : : SimpleSelector : : Attribute  const &  attribute_selector ,  DOM : : Attr  const &  attribute ,  CaseSensitivity  case_sensitivity )  
						 
					
						
							
								
									
										
										
										
											2024-11-27 20:24:29 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2025-05-15 19:18:04 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    auto  const  case_insensitive_match  =  case_sensitivity  = =  CaseSensitivity : : CaseInsensitive ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-08-18 21:17:08 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2025-05-15 19:18:04 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    switch  ( attribute_selector . 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 
							 
						 
					
						
							
								
									
										
										
										
											2025-05-18 15:04:56 +12:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            ?  attribute . value ( ) . equals_ignoring_ascii_case ( attribute_selector . value ) 
							 
						 
					
						
							
								
									
										
										
										
											2025-05-15 19:18:04 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            :  attribute . value ( )  = =  attribute_selector . value ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-29 18:01:36 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    case  CSS : : Selector : : SimpleSelector : : Attribute : : MatchType : : ContainsWord :  { 
							 
						 
					
						
							
								
									
										
										
										
											2025-05-15 19:18:04 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( attribute_selector . value . is_empty ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-29 18:01:36 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            // This selector is always false is match value is empty.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2025-05-15 19:18:04 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        auto  const &  attribute_value  =  attribute . 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 
							 
						 
					
						
							
								
									
										
										
										
											2025-05-18 15:04:56 +12:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                    ?  value . equals_ignoring_ascii_case ( attribute_selector . value ) 
							 
						 
					
						
							
								
									
										
										
										
											2025-05-15 19:18:04 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                    :  value  = =  attribute_selector . value )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-29 18:01:36 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                return  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-12 14:58:03 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    case  CSS : : Selector : : SimpleSelector : : Attribute : : MatchType : : ContainsString : 
							 
						 
					
						
							
								
									
										
										
										
											2025-05-15 19:18:04 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  ! attribute_selector . value . is_empty ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            & &  attribute . value ( ) . contains ( attribute_selector . value ,  case_sensitivity ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-28 12:34:05 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    case  CSS : : Selector : : SimpleSelector : : Attribute : : MatchType : : StartsWithSegment :  { 
							 
						 
					
						
							
								
									
										
										
										
											2025-04-27 12:53:58 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        // https://www.w3.org/TR/CSS2/selector.html#attribute-selectors
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // [att|=val]
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // Represents an element with the att attribute, its value either being exactly "val" or beginning with "val" immediately followed by "-" (U+002D).
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2025-05-15 19:18:04 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        auto  const &  element_attr_value  =  attribute . 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.
 
							 
						 
					
						
							
								
									
										
										
										
											2025-05-15 19:18:04 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            return  attribute_selector . value . is_empty ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-29 17:46:32 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2025-05-15 19:18:04 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( attribute_selector . value . is_empty ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-29 17:46:32 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            return  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2025-04-27 12:53:58 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        auto  element_attribute_length  =  element_attr_value . bytes_as_string_view ( ) . length ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2025-05-15 19:18:04 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        auto  attribute_length  =  attribute_selector . value . bytes_as_string_view ( ) . length ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2025-04-27 12:53:58 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( element_attribute_length  <  attribute_length ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( attribute_length  = =  element_attribute_length )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  case_insensitive_match 
							 
						 
					
						
							
								
									
										
										
										
											2025-05-18 15:04:56 +12:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                ?  element_attr_value . equals_ignoring_ascii_case ( attribute_selector . value ) 
							 
						 
					
						
							
								
									
										
										
										
											2025-05-15 19:18:04 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                :  element_attr_value  = =  attribute_selector . value ; 
							 
						 
					
						
							
								
									
										
										
										
											2025-04-27 12:53:58 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2025-05-15 19:18:04 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  element_attr_value . starts_with_bytes ( attribute_selector . value ,  case_insensitive_match  ?  CaseSensitivity : : CaseInsensitive  :  CaseSensitivity : : CaseSensitive )  & &  element_attr_value . bytes_as_string_view ( ) [ attribute_length ]  = =  ' - ' ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-28 12:34:05 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-12 14:58:03 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    case  CSS : : Selector : : SimpleSelector : : Attribute : : MatchType : : StartsWithString : 
							 
						 
					
						
							
								
									
										
										
										
											2025-05-15 19:18:04 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  ! attribute_selector . value . is_empty ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            & &  attribute . value ( ) . bytes_as_string_view ( ) . starts_with ( attribute_selector . value ,  case_sensitivity ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-12 14:58:03 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    case  CSS : : Selector : : SimpleSelector : : Attribute : : MatchType : : EndsWithString : 
							 
						 
					
						
							
								
									
										
										
										
											2025-05-15 19:18:04 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  ! attribute_selector . value . is_empty ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            & &  attribute . value ( ) . bytes_as_string_view ( ) . ends_with ( attribute_selector . value ,  case_sensitivity ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    case  CSS : : Selector : : SimpleSelector : : Attribute : : MatchType : : HasAttribute : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  true ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-12 14:58:03 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    return  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2025-05-15 19:18:04 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								static  inline  bool  matches_attribute ( CSS : : Selector : : SimpleSelector : : Attribute  const &  attribute ,  [[maybe_unused]]  GC : : Ptr < CSS : : CSSStyleSheet  const >  style_sheet_for_rule ,  DOM : : Element  const &  element )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  const &  attribute_name  =  attribute . qualified_name . name . name ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    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 . qualified_name . namespace_type  = =  CSS : : Selector : : SimpleSelector : : QualifiedName : : NamespaceType : : Default 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                & &  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 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    bool  found_matching_attribute  =  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    for_each_matching_attribute ( attribute ,  style_sheet_for_rule ,  element ,  [ & attribute ,  case_sensitivity ,  & found_matching_attribute ] ( DOM : : Attr  const &  attr )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( matches_single_attribute ( attribute ,  attr ,  case_sensitivity ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            found_matching_attribute  =  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  IterationDecision : : Break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  IterationDecision : : Continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    return  found_matching_attribute ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											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 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-11-24 21:15:56 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								/// Returns true if this selector should be blocked from matching against the shadow host from within a shadow tree.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								/// Only :host pseudo-class is allowed to match the shadow host from within shadow tree, all other selectors (including other pseudo-classes) are blocked.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								/// Compound selectors (:has(), :is(), :where()), nesting, and pseudo-elements are allowed as they may contain or be contained within :host.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								static  inline  bool  should_block_shadow_host_matching ( CSS : : Selector : : SimpleSelector  const &  component ,  GC : : Ptr < DOM : : Element  const >  shadow_host ,  DOM : : Element  const &  element )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( ! shadow_host  | |  & element  ! =  shadow_host . ptr ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // From within shadow tree, only :host pseudo-class can match the host element
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( component . type  = =  CSS : : Selector : : SimpleSelector : : Type : : PseudoClass )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        auto  const &  pseudo_class  =  component . pseudo_class ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  pseudo_class . type  ! =  CSS : : PseudoClass : : Host 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            & &  pseudo_class . type  ! =  CSS : : PseudoClass : : Has 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            & &  pseudo_class . type  ! =  CSS : : PseudoClass : : Is 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            & &  pseudo_class . type  ! =  CSS : : PseudoClass : : Where ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // Allow nesting and PseudoElement as it may contain :host class
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( component . type  = =  CSS : : Selector : : SimpleSelector : : Type : : Nesting  | |  component . type  = =  CSS : : Selector : : SimpleSelector : : Type : : PseudoElement ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    return  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											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
 
							 
						 
					
						
							
								
									
										
										
										
											2024-12-06 11:41:20 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    return  element . is_editable_or_editing_host ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-08-22 16:28:06 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2025-01-31 15:34:34 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								// https://drafts.csswg.org/selectors-4/#open-state
  
						 
					
						
							
								
									
										
										
										
											2023-09-13 17:39:05 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								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.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2025-01-31 15:34:34 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    // https://html.spec.whatwg.org/multipage/semantics-other.html#selector-open
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // The :open pseudo-class must match any element falling into one of the following categories:
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // - details elements that have an open attribute
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // - dialog elements that have an open attribute
 
							 
						 
					
						
							
								
									
										
										
										
											2023-09-13 17:39:05 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( is < HTML : : HTMLDetailsElement > ( element )  | |  is < HTML : : HTMLDialogElement > ( element ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  open  = =  element . has_attribute ( HTML : : AttributeNames : : open ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2025-01-31 15:34:34 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    // - select elements that are a drop-down box and whose drop-down boxes are open
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( auto  const *  select  =  as_if < HTML : : HTMLSelectElement > ( element ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  open  = =  select - > is_open ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // - input elements that support a picker and whose pickers are open
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( auto  const *  input  =  as_if < HTML : : HTMLInputElement > ( element ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  open  = =  ( input - > supports_a_picker ( )  & &  input - > is_open ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-09-13 17:39:05 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    return  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-07-23 15:22:28 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								// https://drafts.csswg.org/css-scoping/#host-selector
  
						 
					
						
							
								
									
										
										
										
											2025-01-03 20:39:25 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								static  inline  bool  matches_host_pseudo_class ( GC : : Ref < DOM : : Element  const >  element ,  GC : : Ptr < DOM : : Element  const >  shadow_host ,  MatchContext &  context ,  CSS : : SelectorList  const &  argument_selector_list )  
						 
					
						
							
								
									
										
										
										
											2024-07-23 15:22:28 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
										 
							
							
								    // 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 ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2025-01-03 20:39:25 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  matches ( argument_selector_list . first ( ) ,  element ,  nullptr ,  context ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-07-23 15:22:28 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    return  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2025-03-18 16:56:41 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								static  bool  matches_optimal_value_pseudo_class ( DOM : : Element  const &  element ,  HTML : : HTMLMeterElement : : ValueState  desired_state )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( auto *  meter  =  as_if < HTML : : HTMLMeterElement > ( element ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  meter - > value_state ( )  = =  desired_state ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    return  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2025-01-03 20:39:25 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								static  inline  bool  matches_pseudo_class ( CSS : : Selector : : SimpleSelector : : PseudoClassSelector  const &  pseudo_class ,  DOM : : Element  const &  element ,  GC : : Ptr < DOM : : Element  const >  shadow_host ,  MatchContext &  context ,  GC : : Ptr < DOM : : ParentNode  const >  scope ,  SelectorKind  selector_kind )  
						 
					
						
							
								
									
										
										
										
											2019-10-08 15:33:58 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2025-04-17 13:39:30 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    context . attempted_pseudo_class_matches . set ( pseudo_class . type ,  true ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-12 16:18:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    switch  ( pseudo_class . type )  { 
							 
						 
					
						
							
								
									
										
										
										
											2025-04-17 13:39:30 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    case  CSS : : PseudoClass : : __Count : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        VERIFY_NOT_REACHED ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											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.
 
							 
						 
					
						
							
								
									
										
										
										
											2025-02-09 17:02:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  element . matches_link_pseudo_class ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-08-22 15:24:12 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    case  CSS : : PseudoClass : : LocalLink :  { 
							 
						 
					
						
							
								
									
										
										
										
											2025-02-09 17:02:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  element . matches_local_link_pseudo_class ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											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 : 
							 
						 
					
						
							
								
									
										
										
										
											2025-06-13 14:12:35 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  element . is_focused ( )  & &  element . should_indicate_focus ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-08-11 21:26:04 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    case  CSS : : PseudoClass : : FocusWithin :  { 
							 
						 
					
						
							
								
									
										
										
										
											2025-08-21 17:09:40 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        auto  focused_area  =  element . document ( ) . focused_area ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  focused_area  & &  element . is_inclusive_ancestor_of ( * focused_area ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-20 13:28:32 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2023-08-11 21:26:04 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    case  CSS : : PseudoClass : : FirstChild : 
							 
						 
					
						
							
								
									
										
										
										
											2025-02-05 21:29:34 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( context . collect_per_element_selector_involvement_metadata )  { 
							 
						 
					
						
							
								
									
										
										
										
											2025-05-07 12:27:42 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            const_cast < DOM : : Element & > ( element ) . set_affected_by_sibling_position_or_count_pseudo_class ( true ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2025-02-05 21:29:34 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											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 : 
							 
						 
					
						
							
								
									
										
										
										
											2025-02-05 21:29:34 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( context . collect_per_element_selector_involvement_metadata )  { 
							 
						 
					
						
							
								
									
										
										
										
											2025-05-07 12:27:42 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            const_cast < DOM : : Element & > ( element ) . set_affected_by_sibling_position_or_count_pseudo_class ( true ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2025-02-05 21:29:34 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											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 : 
							 
						 
					
						
							
								
									
										
										
										
											2025-05-07 12:27:42 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( context . collect_per_element_selector_involvement_metadata )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            const_cast < DOM : : Element & > ( element ) . set_affected_by_sibling_position_or_count_pseudo_class ( true ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											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 : 
							 
						 
					
						
							
								
									
										
										
										
											2025-01-03 20:39:25 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  matches_host_pseudo_class ( element ,  shadow_host ,  context ,  pseudo_class . argument_selector_list ) ; 
							 
						 
					
						
							
								
									
										
										
										
											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 : 
							 
						 
					
						
							
								
									
										
										
										
											2025-05-07 12:27:42 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( context . collect_per_element_selector_involvement_metadata )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            const_cast < DOM : : Element & > ( element ) . set_affected_by_sibling_position_or_count_pseudo_class ( true ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											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 : 
							 
						 
					
						
							
								
									
										
										
										
											2025-05-07 12:27:42 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( context . collect_per_element_selector_involvement_metadata )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            const_cast < DOM : : Element & > ( element ) . set_affected_by_sibling_position_or_count_pseudo_class ( true ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											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 : 
							 
						 
					
						
							
								
									
										
										
										
											2025-05-07 12:27:42 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( context . collect_per_element_selector_involvement_metadata )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            const_cast < DOM : : Element & > ( element ) . set_affected_by_sibling_position_or_count_pseudo_class ( true ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											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 : 
							 
						 
					
						
							
								
									
										
										
										
											2025-02-09 17:02:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  element . matches_disabled_pseudo_class ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-08-11 21:26:04 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    case  CSS : : PseudoClass : : Enabled : 
							 
						 
					
						
							
								
									
										
										
										
											2025-02-09 17:02:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  element . matches_enabled_pseudo_class ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-08-11 21:26:04 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    case  CSS : : PseudoClass : : Checked : 
							 
						 
					
						
							
								
									
										
										
										
											2025-02-09 17:02:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  element . matches_checked_pseudo_class ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2025-07-15 15:38:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    case  CSS : : PseudoClass : : Unchecked : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  element . matches_unchecked_pseudo_class ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											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 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2025-03-18 16:56:41 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    case  CSS : : PseudoClass : : HighValue : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( auto *  meter  =  as_if < HTML : : HTMLMeterElement > ( element ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  meter - > value ( )  >  meter - > high ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    case  CSS : : PseudoClass : : LowValue : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( auto *  meter  =  as_if < HTML : : HTMLMeterElement > ( element ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  meter - > value ( )  <  meter - > low ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    case  CSS : : PseudoClass : : OptimalValue : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  matches_optimal_value_pseudo_class ( element ,  HTML : : HTMLMeterElement : : ValueState : : Optimal ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    case  CSS : : PseudoClass : : SuboptimalValue : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  matches_optimal_value_pseudo_class ( element ,  HTML : : HTMLMeterElement : : ValueState : : Suboptimal ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    case  CSS : : PseudoClass : : EvenLessGoodValue : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  matches_optimal_value_pseudo_class ( element ,  HTML : : HTMLMeterElement : : ValueState : : EvenLessGood ) ; 
							 
						 
					
						
							
								
									
										
										
										
											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 ; 
							 
						 
					
						
							
								
									
										
										
										
											2025-02-12 16:33:24 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( context . collect_per_element_selector_involvement_metadata )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( & element  = =  context . subject )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                const_cast < DOM : : Element & > ( element ) . set_affected_by_has_pseudo_class_in_subject_position ( true ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                const_cast < DOM : : Element & > ( element ) . set_affected_by_has_pseudo_class_in_non_subject_position ( true ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            } 
							 
						 
					
						
							
								
									
										
										
										
											2025-01-29 03:31:46 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2024-07-13 09:19:30 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        // These selectors should be relative selectors (https://drafts.csswg.org/selectors-4/#relative-selector)
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        for  ( auto &  selector  :  pseudo_class . argument_selector_list )  { 
							 
						 
					
						
							
								
									
										
										
										
											2025-01-03 20:39:25 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( matches_has_pseudo_class ( selector ,  element ,  shadow_host ,  context ) ) 
							 
						 
					
						
							
								
									
										
										
										
											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 )  { 
							 
						 
					
						
							
								
									
										
										
										
											2025-01-03 20:39:25 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( matches ( selector ,  element ,  shadow_host ,  context ) ) 
							 
						 
					
						
							
								
									
										
										
										
											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 )  { 
							 
						 
					
						
							
								
									
										
										
										
											2025-01-03 20:39:25 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( matches ( selector ,  element ,  shadow_host ,  context ) ) 
							 
						 
					
						
							
								
									
										
										
										
											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 :  { 
							 
						 
					
						
							
								
									
										
										
										
											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 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2025-02-05 21:29:34 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( context . collect_per_element_selector_involvement_metadata )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            const_cast < DOM : : Element & > ( element ) . set_affected_by_nth_child_pseudo_class ( true ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2025-01-03 20:39:25 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        auto  matches_selector_list  =  [ & context ,  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 )  { 
							 
						 
					
						
							
								
									
										
										
										
											2025-01-03 20:39:25 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                if  ( matches ( child_selector ,  element ,  shadow_host ,  context ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											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 )  { 
							 
						 
					
						
							
								
									
										
										
										
											2025-04-17 13:39:30 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        case  CSS : : PseudoClass : : __Count : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            VERIFY_NOT_REACHED ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											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 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2025-08-28 10:44:17 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  pseudo_class . an_plus_b_pattern . matches ( index ) ; 
							 
						 
					
						
							
								
									
										
										
										
											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-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
 
							 
						 
					
						
							
								
									
										
										
										
											2025-05-16 14:57:18 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( ! pseudo_class . ident . has_value ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( ! first_is_one_of ( pseudo_class . ident - > 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 : 
							 
						 
					
						
							
								
									
										
										
										
											2025-05-16 14:57:18 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            return  pseudo_class . ident - > keyword  = =  CSS : : Keyword : : Ltr ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-08-16 12:11:14 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        case  DOM : : Element : : Directionality : : Rtl : 
							 
						 
					
						
							
								
									
										
										
										
											2025-05-16 14:57:18 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            return  pseudo_class . ident - > 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 : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        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 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2024-12-05 23:24:24 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    case  CSS : : PseudoClass : : PopoverOpen :  { 
							 
						 
					
						
							
								
									
										
										
										
											2025-02-02 20:41:23 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        // https://html.spec.whatwg.org/multipage/semantics-other.html#selector-popover-open
 
							 
						 
					
						
							
								
									
										
										
										
											2025-07-08 10:21:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        // The :popover-open pseudo-class is defined to match any HTML element whose popover attribute is not in the
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // No Popover state and whose popover visibility state is showing.
 
							 
						 
					
						
							
								
									
										
										
										
											2024-12-05 23:24:24 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( is < HTML : : HTMLElement > ( element )  & &  element . has_attribute ( HTML : : AttributeNames : : popover ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            auto &  html_element  =  static_cast < HTML : : HTMLElement  const & > ( element ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  html_element . popover_visibility_state ( )  = =  HTML : : HTMLElement : : PopoverVisibilityState : : Showing ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2025-02-02 20:41:23 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    case  CSS : : PseudoClass : : Valid :  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // https://html.spec.whatwg.org/multipage/semantics-other.html#selector-valid
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // The :valid pseudo-class must match any element falling into one of the following categories:
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // - elements that are candidates for constraint validation and that satisfy their constraints
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( auto  form_associated_element  =  as_if < Web : : HTML : : FormAssociatedElement > ( element ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( form_associated_element - > is_candidate_for_constraint_validation ( )  & &  form_associated_element - > satisfies_its_constraints ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                return  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // - form elements that are not the form owner of any elements that themselves are candidates for constraint validation but do not satisfy their constraints
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( auto  form_element  =  as_if < Web : : HTML : : HTMLFormElement > ( element ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            bool  has_invalid_elements  =  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            element . for_each_in_subtree ( [ & ] ( auto &  node )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                if  ( auto  form_associated_element  =  as_if < Web : : HTML : : FormAssociatedElement > ( & node ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    if  ( form_associated_element - > form ( )  = =  form_element  & &  form_associated_element - > is_candidate_for_constraint_validation ( )  & &  ! form_associated_element - > satisfies_its_constraints ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                        has_invalid_elements  =  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                        return  TraversalDecision : : Break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                return  TraversalDecision : : Continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( ! has_invalid_elements ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                return  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // - fieldset elements that have no descendant elements that themselves are candidates for constraint validation but do not satisfy their constraints
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( is < Web : : HTML : : HTMLFieldSetElement > ( element ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            bool  has_invalid_children  =  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            element . for_each_in_subtree ( [ & ] ( auto &  node )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                if  ( auto  form_associated_element  =  as_if < Web : : HTML : : FormAssociatedElement > ( & node ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    if  ( form_associated_element - > is_candidate_for_constraint_validation ( )  & &  ! form_associated_element - > satisfies_its_constraints ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                        has_invalid_children  =  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                        return  TraversalDecision : : Break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                return  TraversalDecision : : Continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( ! has_invalid_children ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                return  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    case  CSS : : PseudoClass : : Invalid :  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // https://html.spec.whatwg.org/multipage/semantics-other.html#selector-invalid
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // The :invalid pseudo-class must match any element falling into one of the following categories:
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // - elements that are candidates for constraint validation but that do not satisfy their constraints
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( auto  form_associated_element  =  as_if < Web : : HTML : : FormAssociatedElement > ( element ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( form_associated_element - > is_candidate_for_constraint_validation ( )  & &  ! form_associated_element - > satisfies_its_constraints ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                return  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // - form elements that are the form owner of one or more elements that themselves are candidates for constraint validation but do not satisfy their constraints
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( auto  form_element  =  as_if < Web : : HTML : : HTMLFormElement > ( element ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            bool  has_invalid_elements  =  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            element . for_each_in_subtree ( [ & ] ( auto &  node )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                if  ( auto  form_associated_element  =  as_if < Web : : HTML : : FormAssociatedElement > ( & node ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    if  ( form_associated_element - > form ( )  = =  form_element  & &  form_associated_element - > is_candidate_for_constraint_validation ( )  & &  ! form_associated_element - > satisfies_its_constraints ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                        has_invalid_elements  =  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                        return  TraversalDecision : : Break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                return  TraversalDecision : : Continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( has_invalid_elements ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                return  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // - fieldset elements that have of one or more descendant elements that themselves are candidates for constraint validation but do not satisfy their constraints
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( is < Web : : HTML : : HTMLFieldSetElement > ( element ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            bool  has_invalid_children  =  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            element . for_each_in_subtree ( [ & ] ( auto &  node )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                if  ( auto  form_associated_element  =  as_if < Web : : HTML : : FormAssociatedElement > ( & node ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    if  ( form_associated_element - > is_candidate_for_constraint_validation ( )  & &  ! form_associated_element - > satisfies_its_constraints ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                        has_invalid_children  =  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                        return  TraversalDecision : : Break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                return  TraversalDecision : : Continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( has_invalid_children ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                return  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    case  CSS : : PseudoClass : : UserValid :  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // https://html.spec.whatwg.org/multipage/semantics-other.html#selector-user-valid
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // The :user-valid pseudo-class must match input, textarea, and select elements whose user validity is true,
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        bool  user_validity  =  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( auto  input_element  =  as_if < Web : : HTML : : HTMLInputElement > ( element ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            user_validity  =  input_element - > user_validity ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        }  else  if  ( auto  select_element  =  as_if < Web : : HTML : : HTMLSelectElement > ( element ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            user_validity  =  select_element - > user_validity ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        }  else  if  ( auto  text_area_element  =  as_if < Web : : HTML : : HTMLTextAreaElement > ( element ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            user_validity  =  text_area_element - > user_validity ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( ! user_validity ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // are candidates for constraint validation, and that satisfy their constraints.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        auto &  form_associated_element  =  as < Web : : HTML : : FormAssociatedElement > ( element ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( form_associated_element . is_candidate_for_constraint_validation ( )  & &  form_associated_element . satisfies_its_constraints ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    case  CSS : : PseudoClass : : UserInvalid :  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // https://html.spec.whatwg.org/multipage/semantics-other.html#selector-user-invalid
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // The :user-invalid pseudo-class must match input, textarea, and select elements whose user validity is true,
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        bool  user_validity  =  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( auto  input_element  =  as_if < Web : : HTML : : HTMLInputElement > ( element ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            user_validity  =  input_element - > user_validity ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        }  else  if  ( auto  select_element  =  as_if < Web : : HTML : : HTMLSelectElement > ( element ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            user_validity  =  select_element - > user_validity ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        }  else  if  ( auto  text_area_element  =  as_if < Web : : HTML : : HTMLTextAreaElement > ( element ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            user_validity  =  text_area_element - > user_validity ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( ! user_validity ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // are candidates for constraint validation but do not satisfy their constraints.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        auto &  form_associated_element  =  as < Web : : HTML : : FormAssociatedElement > ( element ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( form_associated_element . is_candidate_for_constraint_validation ( )  & &  ! form_associated_element . satisfies_its_constraints ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2025-04-30 10:23:46 +10:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    case  CSS : : PseudoClass : : Required :  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // https://html.spec.whatwg.org/multipage/semantics-other.html#selector-required
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // The :required pseudo-class must match any element falling into one of the following categories:
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // - input elements that are required
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( auto  const *  input_element  =  as_if < Web : : HTML : : HTMLInputElement > ( element ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( input_element - > required_applies ( )  & &  input_element - > has_attribute ( HTML : : AttributeNames : : required ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                return  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // - select elements that have a required attribute
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        else  if  ( auto  const *  select_element  =  as_if < Web : : HTML : : HTMLSelectElement > ( element ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( select_element - > has_attribute ( HTML : : AttributeNames : : required ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                return  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // - textarea elements that have a required attribute
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        else  if  ( auto  const *  textarea_element  =  as_if < Web : : HTML : : HTMLTextAreaElement > ( element ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( textarea_element - > has_attribute ( HTML : : AttributeNames : : required ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                return  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    case  CSS : : PseudoClass : : Optional :  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // https://html.spec.whatwg.org/multipage/semantics-other.html#selector-optional
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // The :optional pseudo-class must match any element falling into one of the following categories:
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // - input elements to which the required attribute applies that are not required
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( auto  const *  input_element  =  as_if < Web : : HTML : : HTMLInputElement > ( element ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( input_element - > required_applies ( )  & &  ! input_element - > has_attribute ( HTML : : AttributeNames : : required ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                return  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            // AD-HOC: Chromium and Webkit also match for hidden inputs (and WPT expects this)
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            // See: https://github.com/whatwg/html/issues/11273
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( input_element - > type_state ( )  = =  HTML : : HTMLInputElement : : TypeAttributeState : : Hidden ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                return  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // - select elements that do not have a required attribute
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        else  if  ( auto  const *  select_element  =  as_if < Web : : HTML : : HTMLSelectElement > ( element ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( ! select_element - > has_attribute ( HTML : : AttributeNames : : required ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                return  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // - textarea elements that do not have a required attribute
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        else  if  ( auto  const *  textarea_element  =  as_if < Web : : HTML : : HTMLTextAreaElement > ( element ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( ! textarea_element - > has_attribute ( HTML : : AttributeNames : : required ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                return  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2025-05-24 15:24:38 +10:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    case  CSS : : PseudoClass : : Default :  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // https://html.spec.whatwg.org/multipage/semantics-other.html#selector-default
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // The :default pseudo-class must match any element falling into one of the following categories:
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( auto  const *  form_associated_element  =  as_if < Web : : HTML : : FormAssociatedElement > ( element ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            // - Submit buttons that are default buttons of their form owner.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( form_associated_element - > is_submit_button ( )  & &  form_associated_element - > form ( )  & &  form_associated_element - > form ( ) - > default_button ( )  = =  form_associated_element ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                return  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            // - input elements to which the checked attribute applies and that have a checked attribute
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( auto  const *  input_element  =  as_if < Web : : HTML : : HTMLInputElement > ( form_associated_element ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                if  ( input_element - > checked_applies ( )  & &  input_element - > has_attribute ( HTML : : AttributeNames : : checked ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    return  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // - option elements that have a selected attribute
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        else  if  ( auto  const *  option_element  =  as_if < Web : : HTML : : HTMLOptionElement > ( element ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( option_element - > has_attribute ( HTML : : AttributeNames : : selected ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                return  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2025-07-04 15:18:08 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    case  CSS : : PseudoClass : : State :  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // https://html.spec.whatwg.org/multipage/semantics-other.html#selector-custom
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // The :state(identifier) pseudo-class must match all custom elements whose states set's set entries contains identifier.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( ! element . is_custom ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( auto *  custom_state_set  =  element . custom_state_set ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  custom_state_set - > has_state ( pseudo_class . ident - > string_value ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2025-08-12 11:58:17 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    case  CSS : : PseudoClass : : Heading :  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // https://html.spec.whatwg.org/multipage/semantics-other.html#selector-heading
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // The :heading pseudo-class must match all h1, h2, h3, h4, h5, and h6 elements.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // https://html.spec.whatwg.org/multipage/semantics-other.html#selector-heading-functional
 
							 
						 
					
						
							
								
									
										
										
										
											2025-08-28 10:29:57 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        // The :heading(integer#) pseudo-class must match all h1, h2, h3, h4, h5, and h6 elements that have a heading level of integer. [CSSSYNTAX] [CSSVALUES]
 
							 
						 
					
						
							
								
									
										
										
										
											2025-08-12 11:58:17 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // NB: We combine the "is this an h* element?" and "what is it's level?" checks together here.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( ! element . is_html_element ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        auto  heading_level  =  [ ] ( auto &  local_name )  - >  Optional < int >  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( local_name  = =  HTML : : TagNames : : h1 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                return  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( local_name  = =  HTML : : TagNames : : h2 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                return  2 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( local_name  = =  HTML : : TagNames : : h3 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                return  3 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( local_name  = =  HTML : : TagNames : : h4 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                return  4 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( local_name  = =  HTML : : TagNames : : h5 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                return  5 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( local_name  = =  HTML : : TagNames : : h6 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                return  6 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } ( element . lowercased_local_name ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( ! heading_level . has_value ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2025-08-28 10:29:57 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( pseudo_class . levels . is_empty ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2025-08-12 11:58:17 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            return  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2025-08-28 10:29:57 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  pseudo_class . levels . contains_slow ( heading_level . value ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2025-08-12 11:58:17 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											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 , 
							 
						 
					
						
							
								
									
										
										
										
											2025-01-03 20:39:25 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    GC : : Ptr < CSS : : CSSStyleSheet  const >  style_sheet_for_rule ) 
							 
						 
					
						
							
								
									
										
										
										
											2024-03-19 10:34:32 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    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."
 
							 
						 
					
						
							
								
									
										
										
										
											2025-01-03 20:39:25 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( ! style_sheet_for_rule  | |  ! style_sheet_for_rule - > default_namespace_rule ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2024-03-19 10:34:32 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            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.
 
							 
						 
					
						
							
								
									
										
										
										
											2025-01-03 20:39:25 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( ! style_sheet_for_rule ) 
							 
						 
					
						
							
								
									
										
										
										
											2024-03-19 10:34:32 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            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 ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2025-01-03 20:39:25 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								static  inline  bool  matches ( CSS : : Selector : : SimpleSelector  const &  component ,  DOM : : Element  const &  element ,  GC : : Ptr < DOM : : Element  const >  shadow_host ,  MatchContext &  context ,  GC : : Ptr < DOM : : ParentNode  const >  scope ,  SelectorKind  selector_kind ,  [[maybe_unused]]  GC : : Ptr < DOM : : Element  const >  anchor )  
						 
					
						
							
								
									
										
										
										
											2021-07-12 16:18:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2024-11-24 21:15:56 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( should_block_shadow_host_matching ( component ,  shadow_host ,  element ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  false ; 
							 
						 
					
						
							
								
									
										
										
										
											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
 
							 
						 
					
						
							
								
									
										
										
										
											2024-12-25 20:54:23 +09:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( element . document ( ) . document_type ( )  = =  DOM : : Document : : Type : : HTML  & &  element . namespace_uri ( )  = =  Namespace : : 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 ; 
							 
						 
					
						
							
								
									
										
										
										
											2025-05-18 15:04:56 +12:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            }  else  if  ( ! qualified_name . name . name . equals_ignoring_ascii_case ( element . local_name ( ) ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-08-08 15:11:48 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                return  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2025-01-03 20:39:25 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  matches_namespace ( qualified_name ,  element ,  context . 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 : 
							 
						 
					
						
							
								
									
										
										
										
											2025-01-03 20:39:25 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  matches_attribute ( component . attribute ( ) ,  context . style_sheet_for_rule ,  element ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-12 16:18:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    case  CSS : : Selector : : SimpleSelector : : Type : : PseudoClass : 
							 
						 
					
						
							
								
									
										
										
										
											2025-01-03 20:39:25 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  matches_pseudo_class ( component . pseudo_class ( ) ,  element ,  shadow_host ,  context ,  scope ,  selector_kind ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-12 16:34:18 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    case  CSS : : Selector : : SimpleSelector : : Type : : PseudoElement : 
							 
						 
					
						
							
								
									
										
										
										
											2025-09-03 14:58:35 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( component . pseudo_element ( ) . type ( )  = =  CSS : : PseudoElement : : Slotted )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            VERIFY ( context . slotted_element ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  matches ( component . pseudo_element ( ) . compound_selector ( ) ,  * context . slotted_element ,  shadow_host ,  context ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											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.
 
							 
						 
					
						
							
								
									
										
										
										
											2025-01-03 20:39:25 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  matches_pseudo_class ( CSS : : Selector : : SimpleSelector : : PseudoClassSelector  {  . type  =  CSS : : PseudoClass : : Scope  } ,  element ,  shadow_host ,  context ,  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 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2025-01-03 20:39:25 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								bool  matches ( CSS : : Selector  const &  selector ,  int  component_list_index ,  DOM : : Element  const &  element ,  GC : : Ptr < DOM : : Element  const >  shadow_host ,  MatchContext &  context ,  GC : : Ptr < DOM : : ParentNode  const >  scope ,  SelectorKind  selector_kind ,  GC : : Ptr < 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 )  { 
							 
						 
					
						
							
								
									
										
										
										
											2025-01-03 20:39:25 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( ! matches ( simple_selector ,  element ,  shadow_host ,  context ,  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 ; 
							 
						 
					
						
							
								
									
										
										
										
											2025-01-03 20:39:25 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( matches ( selector ,  component_list_index  -  1 ,  static_cast < DOM : : Element  const & > ( * ancestor ) ,  shadow_host ,  context ,  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 ; 
							 
						 
					
						
							
								
									
										
										
										
											2025-01-03 20:39:25 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  matches ( selector ,  component_list_index  -  1 ,  static_cast < DOM : : Element  const & > ( * parent ) ,  shadow_host ,  context ,  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 : 
							 
						 
					
						
							
								
									
										
										
										
											2025-02-05 21:29:34 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( context . collect_per_element_selector_involvement_metadata )  { 
							 
						 
					
						
							
								
									
										
										
										
											2025-03-10 16:16:08 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            const_cast < DOM : : Element & > ( element ) . set_affected_by_direct_sibling_combinator ( true ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            auto  new_sibling_invalidation_distance  =  max ( selector . sibling_invalidation_distance ( ) ,  element . sibling_invalidation_distance ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            const_cast < DOM : : Element & > ( element ) . set_sibling_invalidation_distance ( new_sibling_invalidation_distance ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2025-02-05 21:29:34 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											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 ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2025-01-03 20:39:25 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            return  matches ( selector ,  component_list_index  -  1 ,  * sibling ,  shadow_host ,  context ,  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 : 
							 
						 
					
						
							
								
									
										
										
										
											2025-02-05 21:29:34 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( context . collect_per_element_selector_involvement_metadata )  { 
							 
						 
					
						
							
								
									
										
										
										
											2025-03-10 16:16:08 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            const_cast < DOM : : Element & > ( element ) . set_affected_by_indirect_sibling_combinator ( true ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2025-02-05 21:29:34 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											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 ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2025-01-03 20:39:25 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( matches ( selector ,  component_list_index  -  1 ,  * sibling ,  shadow_host ,  context ,  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 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2025-02-02 20:35:29 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								bool  fast_matches ( CSS : : Selector  const &  selector ,  DOM : : Element  const &  element_to_match ,  GC : : Ptr < DOM : : Element  const >  shadow_host ,  MatchContext &  context ) ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2025-03-20 16:56:46 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								bool  matches ( CSS : : Selector  const &  selector ,  DOM : : Element  const &  element ,  GC : : Ptr < DOM : : Element  const >  shadow_host ,  MatchContext &  context ,  Optional < CSS : : PseudoElement >  pseudo_element ,  GC : : Ptr < DOM : : ParentNode  const >  scope ,  SelectorKind  selector_kind ,  GC : : Ptr < DOM : : Element  const >  anchor )  
						 
					
						
							
								
									
										
										
										
											2019-10-08 15:33:58 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2025-02-02 20:35:29 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( selector_kind  = =  SelectorKind : : Normal  & &  selector . can_use_fast_matches ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  fast_matches ( selector ,  element ,  shadow_host ,  context ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											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 ; 
							 
						 
					
						
							
								
									
										
										
										
											2025-01-03 20:39:25 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    return  matches ( selector ,  selector . compound_selectors ( ) . size ( )  -  1 ,  element ,  shadow_host ,  context ,  scope ,  selector_kind ,  anchor ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-10-08 15:33:58 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2025-01-03 20:39:25 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								static  bool  fast_matches_simple_selector ( CSS : : Selector : : SimpleSelector  const &  simple_selector ,  DOM : : Element  const &  element ,  GC : : Ptr < DOM : : Element  const >  shadow_host ,  MatchContext &  context )  
						 
					
						
							
								
									
										
										
										
											2024-03-19 10:36:08 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2024-11-24 21:15:56 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( should_block_shadow_host_matching ( simple_selector ,  shadow_host ,  element ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-03-19 10:36:08 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    switch  ( simple_selector . type )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    case  CSS : : Selector : : SimpleSelector : : Type : : Universal : 
							 
						 
					
						
							
								
									
										
										
										
											2025-01-03 20:39:25 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  matches_namespace ( simple_selector . qualified_name ( ) ,  element ,  context . style_sheet_for_rule ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-03-19 10:36:08 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    case  CSS : : Selector : : SimpleSelector : : Type : : TagName : 
							 
						 
					
						
							
								
									
										
										
										
											2025-02-02 20:41:23 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        // https://html.spec.whatwg.org/multipage/semantics-other.html#case-sensitivity-of-selectors
 
							 
						 
					
						
							
								
									
										
										
										
											2025-01-08 23:07:23 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        // When comparing a CSS element type selector to the names of HTML elements in HTML documents, the CSS element type selector must first be converted to ASCII lowercase. The
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // same selector when compared to other elements must be compared according to its original case. In both cases, to match the values must be identical to each other (and therefore
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // the comparison is case sensitive).
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( element . namespace_uri ( )  = =  Namespace : : HTML  & &  element . document ( ) . document_type ( )  = =  DOM : : Document : : Type : : HTML )  { 
							 
						 
					
						
							
								
									
										
										
										
											2024-03-19 10:36:08 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( simple_selector . qualified_name ( ) . name . lowercase_name  ! =  element . local_name ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                return  false ; 
							 
						 
					
						
							
								
									
										
										
										
											2025-01-08 23:07:23 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        }  else  if  ( simple_selector . qualified_name ( ) . name . name  ! =  element . local_name ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            // NOTE: Any other elements are either SVG, XHTML or MathML, all of which are case-sensitive.
 
							 
						 
					
						
							
								
									
										
										
										
											2024-03-19 10:36:08 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            return  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2025-01-03 20:39:25 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  matches_namespace ( simple_selector . qualified_name ( ) ,  element ,  context . 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 : 
							 
						 
					
						
							
								
									
										
										
										
											2025-01-03 20:39:25 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  matches_attribute ( simple_selector . attribute ( ) ,  context . style_sheet_for_rule ,  element ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-03-19 10:58:10 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    case  CSS : : Selector : : SimpleSelector : : Type : : PseudoClass : 
							 
						 
					
						
							
								
									
										
										
										
											2025-01-03 20:39:25 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  matches_pseudo_class ( simple_selector . pseudo_class ( ) ,  element ,  shadow_host ,  context ,  nullptr ,  SelectorKind : : Normal ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-03-19 10:36:08 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    default : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        VERIFY_NOT_REACHED ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2025-01-03 20:39:25 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								static  bool  fast_matches_compound_selector ( CSS : : Selector : : CompoundSelector  const &  compound_selector ,  DOM : : Element  const &  element ,  GC : : Ptr < DOM : : Element  const >  shadow_host ,  MatchContext &  context )  
						 
					
						
							
								
									
										
										
										
											2024-03-19 10:36:08 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    for  ( auto  const &  simple_selector  :  compound_selector . simple_selectors )  { 
							 
						 
					
						
							
								
									
										
										
										
											2025-01-03 20:39:25 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( ! fast_matches_simple_selector ( simple_selector ,  element ,  shadow_host ,  context ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2024-03-19 10:36:08 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            return  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    return  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2025-01-03 20:39:25 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								bool  fast_matches ( CSS : : Selector  const &  selector ,  DOM : : Element  const &  element_to_match ,  GC : : Ptr < DOM : : Element  const >  shadow_host ,  MatchContext &  context )  
						 
					
						
							
								
									
										
										
										
											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 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2025-01-03 20:39:25 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( ! fast_matches_compound_selector ( selector . compound_selectors ( ) . last ( ) ,  * current ,  shadow_host ,  context ) ) 
							 
						 
					
						
							
								
									
										
										
										
											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-11-15 04:01:23 +13:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        GC : : Ptr < 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 ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2025-01-03 20:39:25 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                if  ( fast_matches_compound_selector ( * compound_selector ,  * current ,  shadow_host ,  context ) ) 
							 
						 
					
						
							
								
									
										
										
										
											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 ; 
							 
						 
					
						
							
								
									
										
										
										
											2025-01-03 20:39:25 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( ! fast_matches_compound_selector ( * compound_selector ,  * current ,  shadow_host ,  context ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											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 ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-10-08 15:33:58 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								}