2020-01-18 09:38:21 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								/*
  
						 
					
						
							
								
									
										
										
										
											2022-02-10 20:52:58 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								 *  Copyright  ( c )  2018 - 2022 ,  Andreas  Kling  < kling @ serenityos . org > 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-03 11:14:37 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								 *  Copyright  ( c )  2021 ,  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> 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  <LibWeb/DOM/Document.h> 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  <LibWeb/DOM/Element.h> 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# 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> 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# 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> 
  
						 
					
						
							
								
									
										
										
										
											2022-09-30 19:40:19 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  <LibWeb/HTML/HTMLOptGroupElement.h> 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  <LibWeb/HTML/HTMLOptionElement.h> 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  <LibWeb/HTML/HTMLSelectElement.h> 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  <LibWeb/HTML/HTMLTextAreaElement.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
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  inline  bool  matches_lang_pseudo_class ( DOM : : Element  const &  element ,  Vector < FlyString >  const &  languages )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    FlyString  element_language ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    for  ( auto  const *  e  =  & element ;  e ;  e  =  e - > parent_element ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        auto  lang  =  e - > attribute ( HTML : : AttributeNames : : lang ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( ! lang . is_null ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            element_language  =  lang ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( element_language . is_null ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        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 ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            return  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( language  = =  " * " sv ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            return  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( ! element_language . view ( ) . contains ( ' - ' ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            return  element_language . equals_ignoring_case ( language ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        auto  parts  =  element_language . view ( ) . split_view ( ' - ' ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  parts [ 0 ] . equals_ignoring_case ( language ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    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 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // FIXME: - option elements whose selectedness is true
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-02-05 17:41:43 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  inline  bool  matches_attribute ( CSS : : Selector : : SimpleSelector : : Attribute  const &  attribute ,  DOM : : Element  const &  element )  
						 
					
						
							
								
									
										
										
										
											2021-07-12 14:58:03 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											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.
 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-12 14:58:03 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return  element . has_attribute ( attribute . name ) ; 
							 
						 
					
						
							
								
									
										
										
										
											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 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            ?  element . attribute ( attribute . name ) . equals_ignoring_case ( attribute . value ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            :  element . attribute ( attribute . name )  = =  attribute . value ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    case  CSS : : Selector : : SimpleSelector : : Attribute : : MatchType : : ContainsWord :  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( attribute . value . is_empty ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            // This selector is always false is match value is empty.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            return  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        auto  const  view  =  element . attribute ( attribute . name ) . split_view ( '   ' ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        auto  const  size  =  view . size ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        for  ( size_t  i  =  0 ;  i  <  size ;  + + i )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            auto  const  value  =  view . at ( i ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( case_insensitive_match 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    ?  value . equals_ignoring_case ( attribute . value ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    :  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 ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-29 18:01:36 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            & &  element . attribute ( attribute . name ) . contains ( attribute . value ,  case_sensitivity ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-28 12:34:05 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    case  CSS : : Selector : : SimpleSelector : : Attribute : : MatchType : : StartsWithSegment :  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-01 20:58:27 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        auto  const  element_attr_value  =  element . attribute ( attribute . name ) ; 
							 
						 
					
						
							
								
									
										
										
										
											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 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        auto  segments  =  element_attr_value . split_view ( ' - ' ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-29 18:01:36 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return  case_insensitive_match 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            ?  segments . first ( ) . equals_ignoring_case ( attribute . value ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            :  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 ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-29 18:01:36 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            & &  element . attribute ( attribute . name ) . 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 ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-29 18:01:36 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            & &  element . attribute ( attribute . name ) . ends_with ( attribute . value ,  case_sensitivity ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    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 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-02-05 17:41:43 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  inline  bool  matches_pseudo_class ( CSS : : Selector : : SimpleSelector : : PseudoClass  const &  pseudo_class ,  DOM : : Element  const &  element )  
						 
					
						
							
								
									
										
										
										
											2019-10-08 15:33:58 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2021-07-12 16:18:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    switch  ( pseudo_class . type )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    case  CSS : : Selector : : SimpleSelector : : PseudoClass : : Type : : Link : 
							 
						 
					
						
							
								
									
										
										
										
											2022-09-14 13:29:07 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return  matches_link_pseudo_class ( element ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-12 16:18:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    case  CSS : : Selector : : SimpleSelector : : PseudoClass : : Type : : Visited : 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-13 00:21:42 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        // FIXME: Maybe match this selector sometimes?
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  false ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-12 16:18:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    case  CSS : : Selector : : SimpleSelector : : PseudoClass : : Type : : Active : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  element . is_active ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    case  CSS : : Selector : : SimpleSelector : : PseudoClass : : Type : : Hover : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  matches_hover_pseudo_class ( element ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    case  CSS : : Selector : : SimpleSelector : : PseudoClass : : Type : : Focus : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  element . is_focused ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-20 13:28:32 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    case  CSS : : Selector : : SimpleSelector : : PseudoClass : : Type : : FocusWithin :  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        auto *  focused_element  =  element . document ( ) . focused_element ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  focused_element  & &  element . is_inclusive_ancestor_of ( * focused_element ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-12 16:18:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    case  CSS : : Selector : : SimpleSelector : : PseudoClass : : Type : : FirstChild : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  ! element . previous_element_sibling ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    case  CSS : : Selector : : SimpleSelector : : PseudoClass : : Type : : LastChild : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  ! element . next_element_sibling ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    case  CSS : : Selector : : SimpleSelector : : PseudoClass : : Type : : OnlyChild : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  ! ( element . previous_element_sibling ( )  | |  element . next_element_sibling ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-25 17:14:14 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    case  CSS : : Selector : : SimpleSelector : : PseudoClass : : Type : : Empty :  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        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 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-12 16:18:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    case  CSS : : Selector : : SimpleSelector : : PseudoClass : : Type : : Root : 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-10 20:52:58 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return  is < HTML : : HTMLHtmlElement > ( element ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-12 16:18:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    case  CSS : : Selector : : SimpleSelector : : PseudoClass : : Type : : FirstOfType : 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-17 22:43:22 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return  ! previous_sibling_with_same_tag_name ( element ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-12 16:18:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    case  CSS : : Selector : : SimpleSelector : : PseudoClass : : Type : : LastOfType : 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-17 22:43:22 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return  ! next_sibling_with_same_tag_name ( element ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    case  CSS : : Selector : : SimpleSelector : : PseudoClass : : Type : : OnlyOfType : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  ! previous_sibling_with_same_tag_name ( element )  & &  ! next_sibling_with_same_tag_name ( element ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-20 12:39:11 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    case  CSS : : Selector : : SimpleSelector : : PseudoClass : : Type : : Lang : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  matches_lang_pseudo_class ( element ,  pseudo_class . languages ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-12 16:18:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    case  CSS : : Selector : : SimpleSelector : : PseudoClass : : Type : : 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 ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-12 16:18:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    case  CSS : : Selector : : SimpleSelector : : PseudoClass : : Type : : 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 ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-12 16:18:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    case  CSS : : Selector : : SimpleSelector : : PseudoClass : : Type : : Checked : 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-16 23:29:17 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return  matches_checked_pseudo_class ( element ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-17 15:28:42 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    case  CSS : : Selector : : SimpleSelector : : PseudoClass : : Type : : Is : 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-17 16:13:13 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    case  CSS : : Selector : : SimpleSelector : : PseudoClass : : Type : : Where : 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-17 15:28:42 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        for  ( auto &  selector  :  pseudo_class . argument_selector_list )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( matches ( selector ,  element ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                return  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  false ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-12 17:58:47 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    case  CSS : : Selector : : SimpleSelector : : PseudoClass : : Type : : Not : 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-17 15:28:42 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        for  ( auto &  selector  :  pseudo_class . argument_selector_list )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-12 17:58:47 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            if  ( matches ( selector ,  element ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                return  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  true ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-12 16:18:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    case  CSS : : Selector : : SimpleSelector : : PseudoClass : : Type : : NthChild : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    case  CSS : : Selector : : SimpleSelector : : PseudoClass : : Type : : NthLastChild : 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-26 13:53:13 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    case  CSS : : Selector : : SimpleSelector : : PseudoClass : : Type : : NthOfType : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    case  CSS : : Selector : : SimpleSelector : : PseudoClass : : Type : : 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 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-03-17 19:13:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        auto  matches_selector_list  =  [ ] ( CSS : : SelectorList  const &  list ,  DOM : : Element  const &  element )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( list . is_empty ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                return  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            for  ( auto  const &  child_selector  :  list )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                if  ( matches ( child_selector ,  element ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    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 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        case  CSS : : Selector : : SimpleSelector : : PseudoClass : : Type : : 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 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        case  CSS : : Selector : : SimpleSelector : : PseudoClass : : Type : : 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 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        case  CSS : : Selector : : SimpleSelector : : PseudoClass : : Type : : NthOfType :  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            for  ( auto *  child  =  previous_sibling_with_same_tag_name ( element ) ;  child ;  child  =  previous_sibling_with_same_tag_name ( * child ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                + + index ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        case  CSS : : Selector : : SimpleSelector : : PseudoClass : : Type : : NthLastOfType :  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            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 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-02-05 17:41:43 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  inline  bool  matches ( CSS : : Selector : : SimpleSelector  const &  component ,  DOM : : Element  const &  element )  
						 
					
						
							
								
									
										
										
										
											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 : 
							 
						 
					
						
							
								
									
										
										
										
											2019-11-19 18:22:12 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return  true ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-07-26 20:01:35 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    case  CSS : : Selector : : SimpleSelector : : Type : : Id : 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-21 15:43:59 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return  component . name ( )  = =  element . attribute ( HTML : : AttributeNames : : id ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-07-26 20:01:35 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    case  CSS : : Selector : : SimpleSelector : : Type : : Class : 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-21 15:43:59 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return  element . has_class ( component . name ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-07-26 20:01:35 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    case  CSS : : Selector : : SimpleSelector : : Type : : TagName : 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-03 20:54:13 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        // See https://html.spec.whatwg.org/multipage/semantics-other.html#case-sensitivity-of-selectors
 
							 
						 
					
						
							
								
									
										
										
										
											2022-09-15 13:51:30 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( element . document ( ) . document_type ( )  = =  DOM : : Document : : Type : : HTML ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            return  component . lowercase_name ( )  = =  element . local_name ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  component . name ( ) . equals_ignoring_case ( element . local_name ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-12 14:58:03 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    case  CSS : : Selector : : SimpleSelector : : Type : : Attribute : 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-21 15:43:59 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return  matches_attribute ( component . attribute ( ) ,  element ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-12 16:18:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    case  CSS : : Selector : : SimpleSelector : : Type : : PseudoClass : 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-21 15:43:59 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return  matches_pseudo_class ( component . pseudo_class ( ) ,  element ) ; 
							 
						 
					
						
							
								
									
										
										
										
											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 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-02-05 17:41:43 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  inline  bool  matches ( CSS : : Selector  const &  selector ,  int  component_list_index ,  DOM : : Element  const &  element )  
						 
					
						
							
								
									
										
										
										
											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 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( ! matches ( simple_selector ,  element ) ) 
							 
						 
					
						
							
								
									
										
										
										
											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 ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-19 09:47:04 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            if  ( matches ( selector ,  component_list_index  -  1 ,  static_cast < DOM : : Element  const & > ( * ancestor ) ) ) 
							 
						 
					
						
							
								
									
										
										
										
											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 ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-19 09:47:04 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return  matches ( selector ,  component_list_index  -  1 ,  static_cast < DOM : : Element  const & > ( * element . parent ( ) ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											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 ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2019-11-27 20:37:36 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            return  matches ( selector ,  component_list_index  -  1 ,  * sibling ) ; 
							 
						 
					
						
							
								
									
										
										
										
											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 ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-11-27 20:37:36 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            if  ( matches ( selector ,  component_list_index  -  1 ,  * sibling ) ) 
							 
						 
					
						
							
								
									
										
										
										
											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 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-02-24 15:54:12 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								bool  matches ( CSS : : Selector  const &  selector ,  DOM : : Element  const &  element ,  Optional < CSS : : Selector : : PseudoElement >  pseudo_element )  
						 
					
						
							
								
									
										
										
										
											2019-10-08 15:33:58 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2021-07-23 15:24:33 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    VERIFY ( ! selector . compound_selectors ( ) . is_empty ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-24 15:54:12 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( pseudo_element . has_value ( )  & &  selector . pseudo_element ( )  ! =  pseudo_element ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( ! pseudo_element . has_value ( )  & &  selector . pseudo_element ( ) . has_value ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  false ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-23 15:24:33 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    return  matches ( selector ,  selector . compound_selectors ( ) . size ( )  -  1 ,  element ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-10-08 15:33:58 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}