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