2020-01-18 09:38:21 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								/*
  
						 
					
						
							
								
									
										
										
										
											2024-10-04 13:19:50 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								 *  Copyright  ( c )  2018 - 2020 ,  Andreas  Kling  < andreas @ ladybird . org > 
							 
						 
					
						
							
								
									
										
										
										
											2024-10-15 12:00:29 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								 *  Copyright  ( c )  2021 - 2024 ,  Sam  Atkins  < sam @ ladybird . org > 
							 
						 
					
						
							
								
									
										
										
										
											2020-01-18 09:38:21 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								 * 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-22 01:24:48 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								 *  SPDX - License - Identifier :  BSD - 2 - Clause 
							 
						 
					
						
							
								
									
										
										
										
											2020-01-18 09:38:21 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-05-08 23:19:25 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								# include  "Selector.h" 
  
						 
					
						
							
								
									
										
										
										
											2024-10-17 12:26:37 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								# include  <AK/GenericShorthands.h> 
  
						 
					
						
							
								
									
										
										
										
											2021-10-15 12:18:09 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								# include  <LibWeb/CSS/Serialize.h> 
  
						 
					
						
							
								
									
										
										
										
											2019-06-20 23:25:25 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-07-26 20:01:35 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								namespace  Web : : CSS  {  
						 
					
						
							
								
									
										
										
										
											2020-03-07 10:27:02 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-11-13 15:49:43 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								static  bool  component_value_contains_nesting_selector ( Parser : : ComponentValue  const &  component_value )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( component_value . is_delim ( ' & ' ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( component_value . is_block ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        for  ( auto  const &  child_value  :  component_value . block ( ) . value )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( component_value_contains_nesting_selector ( child_value ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                return  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( component_value . is_function ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        for  ( auto  const &  child_value  :  component_value . function ( ) . value )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( component_value_contains_nesting_selector ( child_value ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                return  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    return  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-07-23 15:24:33 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								Selector : : Selector ( Vector < CompoundSelector > & &  compound_selectors )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    :  m_compound_selectors ( move ( compound_selectors ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2019-06-20 23:25:25 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2022-03-21 15:43:59 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    // FIXME: This assumes that only one pseudo-element is allowed in a selector, and that it appears at the end.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    //        This is not true in Selectors-4!
 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-13 16:28:20 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( ! m_compound_selectors . is_empty ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        for  ( auto  const &  simple_selector  :  m_compound_selectors . last ( ) . simple_selectors )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( simple_selector . type  = =  SimpleSelector : : Type : : PseudoElement )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-21 15:43:59 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                m_pseudo_element  =  simple_selector . pseudo_element ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-13 16:28:20 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
											 
										
											
												LibWeb: Use an ancestor filter to quickly reject many CSS selectors
Given a selector like `.foo .bar #baz`, we know that elements with
the class names `foo` and `bar` must be present in the ancestor chain of
the candidate element, or the selector cannot match.
By keeping track of the current ancestor chain during style computation,
and which strings are used in tag names and attribute names, we can do
a quick check before evaluating the selector itself, to see if all the
required ancestors are present.
The way this works:
1. CSS::Selector now has a cache of up to 8 strings that must be present
   in the ancestor chain of a matching element. Note that we actually
   store string *hashes*, not the strings themselves.
2. When Document performs a recursive style update, we now push and pop
   elements to the ancestor chain stack as they are entered and exited.
3. When entering/exiting an ancestor, StyleComputer collects all the
   relevant string hashes from that ancestor element and updates a
   counting bloom filter.
4. Before evaluating a selector, we first check if any of the hashes
   required by the selector are definitely missing from the ancestor
   filter. If so, it cannot be a match, and we reject it immediately.
5. Otherwise, we carry on and evaluate the selector as usual.
I originally tried doing this with a HashMap, but we ended up losing
a huge chunk of the time saved to HashMap instead. As it turns out,
a simple counting bloom filter is way better at handling this.
The cost is a flat 8KB per StyleComputer, and since it's a bloom filter,
false positives are a thing.
This is extremely efficient, and allows us to quickly reject the
majority of selectors on many huge websites.
Some example rejection rates:
- https://amazon.com: 77%
- https://github.com/SerenityOS/serenity: 61%
- https://nytimes.com: 57%
- https://store.steampowered.com: 55%
- https://en.wikipedia.org: 45%
- https://youtube.com: 32%
- https://shopify.com: 25%
This also yields a chunky 37% speedup on StyleBench. :^)
											 
										 
										
											2024-03-22 13:50:33 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-10-17 12:26:37 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    // https://drafts.csswg.org/css-nesting-1/#contain-the-nesting-selector
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // "A selector is said to contain the nesting selector if, when it was parsed as any type of selector,
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // a <delim-token> with the value "&" (U+0026 AMPERSAND) was encountered."
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    for  ( auto  const &  compound_selector  :  m_compound_selectors )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        for  ( auto  const &  simple_selector  :  compound_selector . simple_selectors )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( simple_selector . type  = =  SimpleSelector : : Type : : Nesting )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                m_contains_the_nesting_selector  =  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( simple_selector . type  = =  SimpleSelector : : Type : : PseudoClass )  { 
							 
						 
					
						
							
								
									
										
										
										
											2025-01-04 18:09:21 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                if  ( simple_selector . pseudo_class ( ) . type  = =  PseudoClass : : Hover )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    m_contains_hover_pseudo_class  =  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                } 
							 
						 
					
						
							
								
									
										
										
										
											2024-10-17 12:26:37 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                for  ( auto  const &  child_selector  :  simple_selector . pseudo_class ( ) . argument_selector_list )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    if  ( child_selector - > contains_the_nesting_selector ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                        m_contains_the_nesting_selector  =  true ; 
							 
						 
					
						
							
								
									
										
										
										
											2025-01-04 18:09:21 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    if  ( child_selector - > contains_hover_pseudo_class ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                        m_contains_hover_pseudo_class  =  true ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-10-17 12:26:37 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                if  ( m_contains_the_nesting_selector ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            } 
							 
						 
					
						
							
								
									
										
										
										
											2024-11-13 15:49:43 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( simple_selector . type  = =  SimpleSelector : : Type : : Invalid )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                auto &  invalid  =  simple_selector . value . get < SimpleSelector : : Invalid > ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                for  ( auto &  item  :  invalid . component_values )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    if  ( component_value_contains_nesting_selector ( item ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                        m_contains_the_nesting_selector  =  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                        break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                if  ( m_contains_the_nesting_selector ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            } 
							 
						 
					
						
							
								
									
										
										
										
											2024-10-17 12:26:37 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( m_contains_the_nesting_selector ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
											 
										
											
												LibWeb: Use an ancestor filter to quickly reject many CSS selectors
Given a selector like `.foo .bar #baz`, we know that elements with
the class names `foo` and `bar` must be present in the ancestor chain of
the candidate element, or the selector cannot match.
By keeping track of the current ancestor chain during style computation,
and which strings are used in tag names and attribute names, we can do
a quick check before evaluating the selector itself, to see if all the
required ancestors are present.
The way this works:
1. CSS::Selector now has a cache of up to 8 strings that must be present
   in the ancestor chain of a matching element. Note that we actually
   store string *hashes*, not the strings themselves.
2. When Document performs a recursive style update, we now push and pop
   elements to the ancestor chain stack as they are entered and exited.
3. When entering/exiting an ancestor, StyleComputer collects all the
   relevant string hashes from that ancestor element and updates a
   counting bloom filter.
4. Before evaluating a selector, we first check if any of the hashes
   required by the selector are definitely missing from the ancestor
   filter. If so, it cannot be a match, and we reject it immediately.
5. Otherwise, we carry on and evaluate the selector as usual.
I originally tried doing this with a HashMap, but we ended up losing
a huge chunk of the time saved to HashMap instead. As it turns out,
a simple counting bloom filter is way better at handling this.
The cost is a flat 8KB per StyleComputer, and since it's a bloom filter,
false positives are a thing.
This is extremely efficient, and allows us to quickly reject the
majority of selectors on many huge websites.
Some example rejection rates:
- https://amazon.com: 77%
- https://github.com/SerenityOS/serenity: 61%
- https://nytimes.com: 57%
- https://store.steampowered.com: 55%
- https://en.wikipedia.org: 45%
- https://youtube.com: 32%
- https://shopify.com: 25%
This also yields a chunky 37% speedup on StyleBench. :^)
											 
										 
										
											2024-03-22 13:50:33 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    collect_ancestor_hashes ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								void  Selector : : collect_ancestor_hashes ( )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    size_t  next_hash_index  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  append_unique_hash  =  [ & ] ( u32  hash )  - >  bool  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( next_hash_index  > =  m_ancestor_hashes . size ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        for  ( size_t  i  =  0 ;  i  <  next_hash_index ;  + + i )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( m_ancestor_hashes [ i ]  = =  hash ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                return  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        m_ancestor_hashes [ next_hash_index + + ]  =  hash ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  last_combinator  =  m_compound_selectors . last ( ) . combinator ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    for  ( ssize_t  compound_selector_index  =  static_cast < ssize_t > ( m_compound_selectors . size ( ) )  -  2 ;  compound_selector_index  > =  0 ;  - - compound_selector_index )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        auto  const &  compound_selector  =  m_compound_selectors [ compound_selector_index ] ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-09-09 11:18:32 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( last_combinator  = =  Combinator : : Descendant  | |  last_combinator  = =  Combinator : : ImmediateChild )  { 
							 
						 
					
						
							
								
									
										
											 
										
											
												LibWeb: Use an ancestor filter to quickly reject many CSS selectors
Given a selector like `.foo .bar #baz`, we know that elements with
the class names `foo` and `bar` must be present in the ancestor chain of
the candidate element, or the selector cannot match.
By keeping track of the current ancestor chain during style computation,
and which strings are used in tag names and attribute names, we can do
a quick check before evaluating the selector itself, to see if all the
required ancestors are present.
The way this works:
1. CSS::Selector now has a cache of up to 8 strings that must be present
   in the ancestor chain of a matching element. Note that we actually
   store string *hashes*, not the strings themselves.
2. When Document performs a recursive style update, we now push and pop
   elements to the ancestor chain stack as they are entered and exited.
3. When entering/exiting an ancestor, StyleComputer collects all the
   relevant string hashes from that ancestor element and updates a
   counting bloom filter.
4. Before evaluating a selector, we first check if any of the hashes
   required by the selector are definitely missing from the ancestor
   filter. If so, it cannot be a match, and we reject it immediately.
5. Otherwise, we carry on and evaluate the selector as usual.
I originally tried doing this with a HashMap, but we ended up losing
a huge chunk of the time saved to HashMap instead. As it turns out,
a simple counting bloom filter is way better at handling this.
The cost is a flat 8KB per StyleComputer, and since it's a bloom filter,
false positives are a thing.
This is extremely efficient, and allows us to quickly reject the
majority of selectors on many huge websites.
Some example rejection rates:
- https://amazon.com: 77%
- https://github.com/SerenityOS/serenity: 61%
- https://nytimes.com: 57%
- https://store.steampowered.com: 55%
- https://en.wikipedia.org: 45%
- https://youtube.com: 32%
- https://shopify.com: 25%
This also yields a chunky 37% speedup on StyleBench. :^)
											 
										 
										
											2024-03-22 13:50:33 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            for  ( auto  const &  simple_selector  :  compound_selector . simple_selectors )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                switch  ( simple_selector . type )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                case  SimpleSelector : : Type : : Id : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                case  SimpleSelector : : Type : : Class : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    if  ( append_unique_hash ( simple_selector . name ( ) . hash ( ) ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                        return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                case  SimpleSelector : : Type : : TagName : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    if  ( append_unique_hash ( simple_selector . qualified_name ( ) . name . name . hash ( ) ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                        return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                case  SimpleSelector : : Type : : Attribute : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    if  ( append_unique_hash ( simple_selector . attribute ( ) . qualified_name . name . name . hash ( ) ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                        return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                default : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        last_combinator  =  compound_selector . combinator ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    for  ( size_t  i  =  next_hash_index ;  i  <  m_ancestor_hashes . size ( ) ;  + + i ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        m_ancestor_hashes [ i ]  =  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-06-20 23:25:25 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-02-25 12:56:55 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								// https://www.w3.org/TR/selectors-4/#specificity-rules
  
						 
					
						
							
								
									
										
										
										
											2020-06-25 16:43:49 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								u32  Selector : : specificity ( )  const  
						 
					
						
							
								
									
										
										
										
											2019-06-29 17:32:32 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2022-02-05 17:40:18 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( m_specificity . has_value ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  * m_specificity ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-03-17 16:40:52 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    constexpr  u32  ids_shift  =  16 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    constexpr  u32  classes_shift  =  8 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    constexpr  u32  tag_names_shift  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    constexpr  u32  ids_mask  =  0xff  < <  ids_shift ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    constexpr  u32  classes_mask  =  0xff  < <  classes_shift ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    constexpr  u32  tag_names_mask  =  0xff  < <  tag_names_shift ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    u32  ids  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    u32  classes  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    u32  tag_names  =  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-06-29 17:32:32 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-03-17 19:13:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    auto  count_specificity_of_most_complex_selector  =  [ & ] ( auto &  selector_list )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        u32  max_selector_list_argument_specificity  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        for  ( auto  const &  complex_selector  :  selector_list )  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-03-06 14:17:01 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            max_selector_list_argument_specificity  =  max ( max_selector_list_argument_specificity ,  complex_selector - > specificity ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-17 19:13:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        u32  child_ids  =  ( max_selector_list_argument_specificity  &  ids_mask )  > >  ids_shift ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        u32  child_classes  =  ( max_selector_list_argument_specificity  &  classes_mask )  > >  classes_shift ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        u32  child_tag_names  =  ( max_selector_list_argument_specificity  &  tag_names_mask )  > >  tag_names_shift ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        ids  + =  child_ids ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        classes  + =  child_classes ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        tag_names  + =  child_tag_names ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-07-23 15:24:33 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    for  ( auto &  list  :  m_compound_selectors )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        for  ( auto &  simple_selector  :  list . simple_selectors )  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-11-27 20:37:36 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            switch  ( simple_selector . type )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            case  SimpleSelector : : Type : : Id : 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-17 16:40:52 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                // count the number of ID selectors in the selector (= A)
 
							 
						 
					
						
							
								
									
										
										
										
											2019-11-27 20:37:36 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                + + ids ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            case  SimpleSelector : : Type : : Class : 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-25 12:56:55 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            case  SimpleSelector : : Type : : Attribute : 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-17 16:40:52 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                // count the number of class selectors, attributes selectors, and pseudo-classes in the selector (= B)
 
							 
						 
					
						
							
								
									
										
										
										
											2019-11-27 20:37:36 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                + + classes ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                break ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-21 15:43:59 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            case  SimpleSelector : : Type : : PseudoClass :  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                auto &  pseudo_class  =  simple_selector . pseudo_class ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                switch  ( pseudo_class . type )  { 
							 
						 
					
						
							
								
									
										
										
										
											2024-07-13 09:19:30 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                case  PseudoClass : : Has : 
							 
						 
					
						
							
								
									
										
										
										
											2023-08-11 21:26:04 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                case  PseudoClass : : Is : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                case  PseudoClass : : Not :  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-17 16:40:52 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                    // The specificity of an :is(), :not(), or :has() pseudo-class is replaced by the
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    // specificity of the most specific complex selector in its selector list argument.
 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-21 15:43:59 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                    count_specificity_of_most_complex_selector ( pseudo_class . argument_selector_list ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-17 19:13:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                    break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                } 
							 
						 
					
						
							
								
									
										
										
										
											2023-08-11 21:26:04 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                case  PseudoClass : : NthChild : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                case  PseudoClass : : NthLastChild :  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-17 19:13:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                    // Analogously, the specificity of an :nth-child() or :nth-last-child() selector
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    // is the specificity of the pseudo class itself (counting as one pseudo-class selector)
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    // plus the specificity of the most specific complex selector in its selector list argument (if any).
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    + + classes ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-21 15:43:59 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                    count_specificity_of_most_complex_selector ( pseudo_class . argument_selector_list ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-17 16:40:52 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                    break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                } 
							 
						 
					
						
							
								
									
										
										
										
											2023-08-11 21:26:04 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                case  PseudoClass : : Where : 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-17 16:40:52 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                    // The specificity of a :where() pseudo-class is replaced by zero.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                default : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    + + classes ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                break ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-21 15:43:59 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            } 
							 
						 
					
						
							
								
									
										
										
										
											2019-11-27 20:37:36 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            case  SimpleSelector : : Type : : TagName : 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-25 12:56:55 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            case  SimpleSelector : : Type : : PseudoElement : 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-17 16:40:52 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                // count the number of type selectors and pseudo-elements in the selector (= C)
 
							 
						 
					
						
							
								
									
										
										
										
											2019-11-27 20:37:36 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                + + tag_names ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                break ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-17 16:40:52 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            case  SimpleSelector : : Type : : Universal : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                // ignore the universal selector
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                break ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-10-15 12:00:29 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            case  SimpleSelector : : Type : : Nesting : 
							 
						 
					
						
							
								
									
										
										
										
											2024-11-08 20:34:48 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
										 
							
							
								                // "The specificity of the nesting selector is equal to the largest specificity among the complex selectors in the parent style rule’  
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                // - https://drafts.csswg.org/css-nesting/#ref-for-specificity
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                // The parented case is handled by replacing & with :is().
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                // So if we got here, the specificity is 0.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                break ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-11-13 15:49:43 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            case  SimpleSelector : : Type : : Invalid : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                // Ignore invalid selectors
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                break ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-11-27 20:37:36 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            } 
							 
						 
					
						
							
								
									
										
										
										
											2019-06-29 17:32:32 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-03-17 16:40:52 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    // Due to storage limitations, implementations may have limitations on the size of A, B, or C.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // If so, values higher than the limit must be clamped to that limit, and not overflow.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    m_specificity  =  ( min ( ids ,  0xff )  < <  ids_shift ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        +  ( min ( classes ,  0xff )  < <  classes_shift ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        +  ( min ( tag_names ,  0xff )  < <  tag_names_shift ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-05 17:40:18 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    return  * m_specificity ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-06-29 17:32:32 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2020-03-07 10:27:02 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-10-15 11:30:01 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								// https://www.w3.org/TR/cssom/#serialize-a-simple-selector
  
						 
					
						
							
								
									
										
										
										
											2023-08-22 12:45:29 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								String  Selector : : SimpleSelector : : serialize ( )  const  
						 
					
						
							
								
									
										
										
										
											2021-10-15 11:30:01 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    StringBuilder  s ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    switch  ( type )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    case  Selector : : SimpleSelector : : Type : : TagName : 
							 
						 
					
						
							
								
									
										
										
										
											2023-08-08 15:11:48 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    case  Selector : : SimpleSelector : : Type : : Universal :  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        auto  qualified_name  =  this - > qualified_name ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // 1. If the namespace prefix maps to a namespace that is not the default namespace and is not the null
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        //    namespace (not in a namespace) append the serialization of the namespace prefix as an identifier,
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        //    followed by a "|" (U+007C) to s.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( qualified_name . namespace_type  = =  QualifiedName : : NamespaceType : : Named )  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-08-22 12:05:44 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            serialize_an_identifier ( s ,  qualified_name . namespace_ ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-08-22 12:45:29 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            s . append ( ' | ' ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-15 11:30:01 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2023-08-08 15:11:48 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // 2. If the namespace prefix maps to a namespace that is the null namespace (not in a namespace)
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        //    append "|" (U+007C) to s.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( qualified_name . namespace_type  = =  QualifiedName : : NamespaceType : : None ) 
							 
						 
					
						
							
								
									
										
										
										
											2023-08-22 12:45:29 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            s . append ( ' | ' ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-08-08 15:11:48 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // 3. If this is a type selector append the serialization of the element name as an identifier to s.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( type  = =  Selector : : SimpleSelector : : Type : : TagName ) 
							 
						 
					
						
							
								
									
										
										
										
											2023-08-22 12:05:44 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            serialize_an_identifier ( s ,  qualified_name . name . name ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-08-08 15:11:48 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-10-15 11:30:01 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        // 4. If this is a universal selector append "*" (U+002A) to s.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( type  = =  Selector : : SimpleSelector : : Type : : Universal ) 
							 
						 
					
						
							
								
									
										
										
										
											2023-08-22 12:45:29 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            s . append ( ' * ' ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-08-08 15:11:48 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-10-15 11:30:01 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        break ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-08-08 15:11:48 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-21 15:43:59 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    case  Selector : : SimpleSelector : : Type : : Attribute :  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        auto &  attribute  =  this - > attribute ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-10-15 11:30:01 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        // 1. Append "[" (U+005B) to s.
 
							 
						 
					
						
							
								
									
										
										
										
											2023-08-22 12:45:29 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        s . append ( ' [ ' ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-15 11:30:01 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-08-08 16:19:20 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        // 2. If the namespace prefix maps to a namespace that is not the null namespace (not in a namespace)
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        //    append the serialization of the namespace prefix as an identifier, followed by a "|" (U+007C) to s.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( attribute . qualified_name . namespace_type  = =  QualifiedName : : NamespaceType : : Named )  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-08-22 12:05:44 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            serialize_an_identifier ( s ,  attribute . qualified_name . namespace_ ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-08-22 12:45:29 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            s . append ( ' | ' ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-08-08 16:19:20 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-15 11:30:01 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // 3. Append the serialization of the attribute name as an identifier to s.
 
							 
						 
					
						
							
								
									
										
										
										
											2023-08-22 12:05:44 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        serialize_an_identifier ( s ,  attribute . qualified_name . name . name ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-15 11:30:01 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // 4. If there is an attribute value specified, append "=", "~=", "|=", "^=", "$=", or "*=" as appropriate (depending on the type of attribute selector),
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        //    followed by the serialization of the attribute value as a string, to s.
 
							 
						 
					
						
							
								
									
										
										
										
											2023-02-18 15:42:55 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( ! attribute . value . is_empty ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-15 11:30:01 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            switch  ( attribute . match_type )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            case  Selector : : SimpleSelector : : Attribute : : MatchType : : ExactValueMatch : 
							 
						 
					
						
							
								
									
										
										
										
											2023-08-22 12:45:29 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                s . append ( " = " sv ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-15 11:30:01 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            case  Selector : : SimpleSelector : : Attribute : : MatchType : : ContainsWord : 
							 
						 
					
						
							
								
									
										
										
										
											2023-08-22 12:45:29 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                s . append ( " ~= " sv ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-15 11:30:01 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            case  Selector : : SimpleSelector : : Attribute : : MatchType : : ContainsString : 
							 
						 
					
						
							
								
									
										
										
										
											2023-08-22 12:45:29 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                s . append ( " *= " sv ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-15 11:30:01 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            case  Selector : : SimpleSelector : : Attribute : : MatchType : : StartsWithSegment : 
							 
						 
					
						
							
								
									
										
										
										
											2023-08-22 12:45:29 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                s . append ( " |= " sv ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-15 11:30:01 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            case  Selector : : SimpleSelector : : Attribute : : MatchType : : StartsWithString : 
							 
						 
					
						
							
								
									
										
										
										
											2023-08-22 12:45:29 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                s . append ( " ^= " sv ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-15 11:30:01 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            case  Selector : : SimpleSelector : : Attribute : : MatchType : : EndsWithString : 
							 
						 
					
						
							
								
									
										
										
										
											2023-08-22 12:45:29 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                s . append ( " $= " sv ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-15 11:30:01 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            default : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            } 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-15 12:18:09 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-08-22 12:05:44 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            serialize_a_string ( s ,  attribute . value ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-15 11:30:01 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-29 18:01:36 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // 5. If the attribute selector has the case-insensitivity flag present, append " i" (U+0020 U+0069) to s.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        //    If the attribute selector has the case-insensitivity flag present, append " s" (U+0020 U+0073) to s.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        //    (the line just above is an addition to CSS OM to match Selectors Level 4 last draft)
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        switch  ( attribute . case_type )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        case  Selector : : SimpleSelector : : Attribute : : CaseType : : CaseInsensitiveMatch : 
							 
						 
					
						
							
								
									
										
										
										
											2023-08-22 12:45:29 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            s . append ( "  i " sv ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-29 18:01:36 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        case  Selector : : SimpleSelector : : Attribute : : CaseType : : CaseSensitiveMatch : 
							 
						 
					
						
							
								
									
										
										
										
											2023-08-22 12:45:29 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            s . append ( "  s " sv ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-29 18:01:36 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        default : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-15 11:30:01 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // 6. Append "]" (U+005D) to s.
 
							 
						 
					
						
							
								
									
										
										
										
											2023-08-22 12:45:29 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        s . append ( ' ] ' ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-15 11:30:01 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        break ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-21 15:43:59 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-15 11:30:01 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    case  Selector : : SimpleSelector : : Type : : Class : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // Append a "." (U+002E), followed by the serialization of the class name as an identifier to s.
 
							 
						 
					
						
							
								
									
										
										
										
											2023-08-22 12:45:29 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        s . append ( ' . ' ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-08-22 12:05:44 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        serialize_an_identifier ( s ,  name ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-15 11:30:01 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    case  Selector : : SimpleSelector : : Type : : Id : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // Append a "#" (U+0023), followed by the serialization of the ID as an identifier to s.
 
							 
						 
					
						
							
								
									
										
										
										
											2023-08-22 12:45:29 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        s . append ( ' # ' ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-08-22 12:05:44 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        serialize_an_identifier ( s ,  name ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-15 11:30:01 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-03-21 15:43:59 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    case  Selector : : SimpleSelector : : Type : : PseudoClass :  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        auto &  pseudo_class  =  this - > pseudo_class ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-08-12 13:57:18 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        auto  metadata  =  pseudo_class_metadata ( pseudo_class . type ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-08-12 13:58:19 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        // HACK: `:host()` has both a function and a non-function form, so handle that first.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        //       It's also not in the spec.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( pseudo_class . type  = =  PseudoClass : : Host )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( pseudo_class . argument_selector_list . is_empty ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-08-22 12:45:29 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                s . append ( ' : ' ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                s . append ( pseudo_class_name ( pseudo_class . type ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-08-12 13:58:19 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            }  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-08-22 12:45:29 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                s . append ( ' : ' ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                s . append ( pseudo_class_name ( pseudo_class . type ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                s . append ( ' ( ' ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                s . append ( serialize_a_group_of_selectors ( pseudo_class . argument_selector_list ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                s . append ( ' ) ' ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-08-12 13:58:19 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2023-08-12 13:57:18 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        // If the pseudo-class does not accept arguments append ":" (U+003A), followed by the name of the pseudo-class, to s.
 
							 
						 
					
						
							
								
									
										
										
										
											2023-08-12 13:58:19 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        else  if  ( metadata . is_valid_as_identifier )  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-08-22 12:45:29 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            s . append ( ' : ' ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            s . append ( pseudo_class_name ( pseudo_class . type ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-08-12 13:57:18 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // Otherwise, append ":" (U+003A), followed by the name of the pseudo-class, followed by "(" (U+0028),
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // followed by the value of the pseudo-class argument(s) determined as per below, followed by ")" (U+0029), to s.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        else  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-08-22 12:45:29 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            s . append ( ' : ' ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            s . append ( pseudo_class_name ( pseudo_class . type ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            s . append ( ' ( ' ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-08-11 21:26:04 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( pseudo_class . type  = =  PseudoClass : : NthChild 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                | |  pseudo_class . type  = =  PseudoClass : : NthLastChild 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                | |  pseudo_class . type  = =  PseudoClass : : NthOfType 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                | |  pseudo_class . type  = =  PseudoClass : : NthLastOfType )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-15 12:18:09 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                // The result of serializing the value using the rules to serialize an <an+b> value.
 
							 
						 
					
						
							
								
									
										
										
										
											2023-08-22 12:45:29 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                s . append ( pseudo_class . nth_child_pattern . serialize ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-08-11 21:26:04 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            }  else  if  ( pseudo_class . type  = =  PseudoClass : : Not 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                | |  pseudo_class . type  = =  PseudoClass : : Is 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                | |  pseudo_class . type  = =  PseudoClass : : Where )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-15 11:30:01 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                // The result of serializing the value using the rules for serializing a group of selectors.
 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-17 16:13:13 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                // NOTE: `:is()` and `:where()` aren't in the spec for this yet, but it should be!
 
							 
						 
					
						
							
								
									
										
										
										
											2023-08-22 12:45:29 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                s . append ( serialize_a_group_of_selectors ( pseudo_class . argument_selector_list ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-08-11 21:26:04 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            }  else  if  ( pseudo_class . type  = =  PseudoClass : : Lang )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-11-05 15:18:14 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
										 
							
							
								                // The serialization of a comma-separated list of each argument’  
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                s . join ( " ,  " sv ,  pseudo_class . languages ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-15 11:30:01 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            } 
							 
						 
					
						
							
								
									
										
										
										
											2023-08-22 12:45:29 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            s . append ( ' ) ' ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-15 11:30:01 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        break ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-21 15:43:59 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-25 12:56:55 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    case  Selector : : SimpleSelector : : Type : : PseudoElement : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // Note: Pseudo-elements are dealt with in Selector::serialize()
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        break ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-10-15 12:00:29 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    case  Type : : Nesting : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // AD-HOC: Not in spec yet.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        s . append ( ' & ' ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-15 11:30:01 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        break ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-11-13 15:49:43 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    case  Type : : Invalid : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // AD-HOC: We're not told how to do these. Just serialize their component values.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        auto  invalid  =  value . get < Invalid > ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        for  ( auto  const &  component_value  :  invalid . component_values ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            s . append ( component_value . to_string ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        break ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-15 11:30:01 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2023-08-22 12:45:29 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    return  MUST ( s . to_string ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-15 11:30:01 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								// https://www.w3.org/TR/cssom/#serialize-a-selector
  
						 
					
						
							
								
									
										
										
										
											2023-08-22 12:45:29 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								String  Selector : : serialize ( )  const  
						 
					
						
							
								
									
										
										
										
											2021-10-15 11:30:01 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    StringBuilder  s ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // To serialize a selector let s be the empty string, run the steps below for each part of the chain of the selector, and finally return s:
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    for  ( size_t  i  =  0 ;  i  <  compound_selectors ( ) . size ( ) ;  + + i )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        auto  const &  compound_selector  =  compound_selectors ( ) [ i ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // 1. If there is only one simple selector in the compound selectors which is a universal selector, append the result of serializing the universal selector to s.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( compound_selector . simple_selectors . size ( )  = =  1 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            & &  compound_selector . simple_selectors . first ( ) . type  = =  Selector : : SimpleSelector : : Type : : Universal )  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-08-22 12:45:29 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            s . append ( compound_selector . simple_selectors . first ( ) . serialize ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-15 11:30:01 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2023-08-08 15:11:48 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        // 2. Otherwise, for each simple selector in the compound selectors that is not a universal selector
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        //    of which the namespace prefix maps to a namespace that is not the default namespace
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        //    serialize the simple selector and append the result to s.
 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-15 11:30:01 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            for  ( auto &  simple_selector  :  compound_selector . simple_selectors )  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-08-08 15:11:48 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                if  ( simple_selector . type  = =  SimpleSelector : : Type : : Universal )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    auto  qualified_name  =  simple_selector . qualified_name ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    if  ( qualified_name . namespace_type  = =  SimpleSelector : : QualifiedName : : NamespaceType : : Default ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                        continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    // FIXME: I *think* if we have a namespace prefix that happens to equal the same as the default namespace,
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    //        we also should skip it. But we don't have access to that here. eg:
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    // <style>
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    //   @namespace "http://example";
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    //   @namespace foo "http://example";
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    //   foo|*.bar { } /* This would skip the `foo|*` when serializing. */
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    // </style>
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                } 
							 
						 
					
						
							
								
									
										
										
										
											2023-08-22 12:45:29 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                s . append ( simple_selector . serialize ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-15 11:30:01 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // 3. If this is not the last part of the chain of the selector append a single SPACE (U+0020),
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        //    followed by the combinator ">", "+", "~", ">>", "||", as appropriate, followed by another
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        //    single SPACE (U+0020) if the combinator was not whitespace, to s.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( i  ! =  compound_selectors ( ) . size ( )  -  1 )  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-08-22 12:45:29 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            s . append ( '   ' ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-15 11:51:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            // Note: The combinator that appears between parts `i` and `i+1` appears with the `i+1` selector,
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            //       so we have to check that one.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            switch  ( compound_selectors ( ) [ i  +  1 ] . combinator )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-15 11:30:01 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            case  Selector : : Combinator : : ImmediateChild : 
							 
						 
					
						
							
								
									
										
										
										
											2023-08-22 12:45:29 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                s . append ( " >  " sv ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-15 11:30:01 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            case  Selector : : Combinator : : NextSibling : 
							 
						 
					
						
							
								
									
										
										
										
											2023-08-22 12:45:29 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                s . append ( " +  " sv ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-15 11:30:01 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            case  Selector : : Combinator : : SubsequentSibling : 
							 
						 
					
						
							
								
									
										
										
										
											2023-08-22 12:45:29 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                s . append ( " ~  " sv ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-15 11:30:01 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            case  Selector : : Combinator : : Column : 
							 
						 
					
						
							
								
									
										
										
										
											2023-08-22 12:45:29 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                s . append ( " ||  " sv ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-15 11:30:01 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            default : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        }  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-15 11:53:23 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            // 4. If this is the last part of the chain of the selector and there is a pseudo-element,
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            // append "::" followed by the name of the pseudo-element, to s.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( compound_selector . simple_selectors . last ( ) . type  = =  Selector : : SimpleSelector : : Type : : PseudoElement )  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-08-22 12:45:29 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                s . append ( " :: " sv ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-12-10 21:00:03 +13:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                s . append ( compound_selector . simple_selectors . last ( ) . pseudo_element ( ) . name ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-15 11:30:01 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-08-22 12:45:29 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    return  MUST ( s . to_string ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-15 11:30:01 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								// https://www.w3.org/TR/cssom/#serialize-a-group-of-selectors
  
						 
					
						
							
								
									
										
										
										
											2024-10-17 12:01:13 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								String  serialize_a_group_of_selectors ( SelectorList  const &  selectors )  
						 
					
						
							
								
									
										
										
										
											2021-10-15 11:30:01 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // To serialize a group of selectors serialize each selector in the group of selectors and then serialize a comma-separated list of these serializations.
 
							 
						 
					
						
							
								
									
										
										
										
											2023-08-22 12:45:29 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    return  MUST ( String : : join ( " ,  " sv ,  selectors ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-15 11:30:01 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-12-10 21:00:03 +13:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								StringView  Selector : : PseudoElement : : name ( Selector : : PseudoElement : : Type  pseudo_element )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    switch  ( pseudo_element )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    case  Selector : : PseudoElement : : Type : : Before : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  " before " sv ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    case  Selector : : PseudoElement : : Type : : After : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  " after " sv ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    case  Selector : : PseudoElement : : Type : : FirstLine : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  " first-line " sv ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    case  Selector : : PseudoElement : : Type : : FirstLetter : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  " first-letter " sv ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    case  Selector : : PseudoElement : : Type : : Marker : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  " marker " sv ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    case  Selector : : PseudoElement : : Type : : MeterBar : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  " -webkit-meter-bar " sv ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    case  Selector : : PseudoElement : : Type : : MeterEvenLessGoodValue : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  " -webkit-meter-even-less-good-value " sv ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    case  Selector : : PseudoElement : : Type : : MeterOptimumValue : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  " -webkit-meter-optimum-value " sv ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    case  Selector : : PseudoElement : : Type : : MeterSuboptimumValue : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  " -webkit-meter-suboptimum-value " sv ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    case  Selector : : PseudoElement : : Type : : ProgressBar : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  " -webkit-progress-bar " sv ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    case  Selector : : PseudoElement : : Type : : ProgressValue : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  " -webkit-progress-value " sv ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    case  Selector : : PseudoElement : : Type : : Placeholder : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  " placeholder " sv ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    case  Selector : : PseudoElement : : Type : : Selection : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  " selection " sv ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-12-11 18:00:06 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    case  Selector : : PseudoElement : : Type : : SliderRunnableTrack : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  " -webkit-slider-runnable-track " sv ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    case  Selector : : PseudoElement : : Type : : SliderThumb : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  " -webkit-slider-thumb " sv ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-03-19 20:58:19 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    case  Selector : : PseudoElement : : Type : : Backdrop : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  " backdrop " sv ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-11-30 22:41:00 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    case  Selector : : PseudoElement : : Type : : FileSelectorButton : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  " file-selector-button " sv ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-11-30 23:46:26 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    case  Selector : : PseudoElement : : Type : : DetailsContent : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  " details-content " sv ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-12-10 22:06:55 +13:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    case  Selector : : PseudoElement : : Type : : KnownPseudoElementCount : 
							 
						 
					
						
							
								
									
										
										
										
											2023-12-10 21:00:03 +13:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        break ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-12-10 22:06:55 +13:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    case  Selector : : PseudoElement : : Type : : UnknownWebKit : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        VERIFY_NOT_REACHED ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-12-10 21:00:03 +13:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    VERIFY_NOT_REACHED ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								Optional < Selector : : PseudoElement >  Selector : : PseudoElement : : from_string ( FlyString  const &  name )  
						 
					
						
							
								
									
										
										
										
											2022-03-03 14:22:50 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2023-03-10 08:48:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( name . equals_ignoring_ascii_case ( " after " sv ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-12-10 21:00:03 +13:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  Selector : : PseudoElement  {  Selector : : PseudoElement : : Type : : After  } ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-03-10 08:48:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    }  else  if  ( name . equals_ignoring_ascii_case ( " before " sv ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-12-10 21:00:03 +13:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  Selector : : PseudoElement  {  Selector : : PseudoElement : : Type : : Before  } ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-03-10 08:48:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    }  else  if  ( name . equals_ignoring_ascii_case ( " first-letter " sv ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-12-10 21:00:03 +13:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  Selector : : PseudoElement  {  Selector : : PseudoElement : : Type : : FirstLetter  } ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-03-10 08:48:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    }  else  if  ( name . equals_ignoring_ascii_case ( " first-line " sv ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-12-10 21:00:03 +13:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  Selector : : PseudoElement  {  Selector : : PseudoElement : : Type : : FirstLine  } ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-03-10 08:48:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    }  else  if  ( name . equals_ignoring_ascii_case ( " marker " sv ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-12-10 21:00:03 +13:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  Selector : : PseudoElement  {  Selector : : PseudoElement : : Type : : Marker  } ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-11-25 14:32:40 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    }  else  if  ( name . equals_ignoring_ascii_case ( " -webkit-meter-bar " sv ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-12-10 21:00:03 +13:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  Selector : : PseudoElement  {  Selector : : PseudoElement : : Type : : MeterBar  } ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-11-25 14:32:40 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    }  else  if  ( name . equals_ignoring_ascii_case ( " -webkit-meter-even-less-good-value " sv ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-12-10 21:00:03 +13:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  Selector : : PseudoElement  {  Selector : : PseudoElement : : Type : : MeterEvenLessGoodValue  } ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-11-25 14:32:40 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    }  else  if  ( name . equals_ignoring_ascii_case ( " -webkit-meter-optimum-value " sv ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-12-10 21:00:03 +13:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  Selector : : PseudoElement  {  Selector : : PseudoElement : : Type : : MeterOptimumValue  } ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-11-25 14:32:40 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    }  else  if  ( name . equals_ignoring_ascii_case ( " -webkit-meter-suboptimum-value " sv ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-12-10 21:00:03 +13:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  Selector : : PseudoElement  {  Selector : : PseudoElement : : Type : : MeterSuboptimumValue  } ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-03-10 08:48:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    }  else  if  ( name . equals_ignoring_ascii_case ( " -webkit-progress-bar " sv ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-12-10 21:00:03 +13:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  Selector : : PseudoElement  {  Selector : : PseudoElement : : Type : : ProgressBar  } ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-03-10 08:48:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    }  else  if  ( name . equals_ignoring_ascii_case ( " -webkit-progress-value " sv ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-12-10 21:00:03 +13:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  Selector : : PseudoElement  {  Selector : : PseudoElement : : Type : : ProgressValue  } ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-03-10 08:48:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    }  else  if  ( name . equals_ignoring_ascii_case ( " placeholder " sv ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-12-10 21:00:03 +13:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  Selector : : PseudoElement  {  Selector : : PseudoElement : : Type : : Placeholder  } ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-07-02 22:19:19 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    }  else  if  ( name . equals_ignoring_ascii_case ( " selection " sv ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-12-10 21:00:03 +13:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  Selector : : PseudoElement  {  Selector : : PseudoElement : : Type : : Selection  } ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-03-19 20:58:19 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    }  else  if  ( name . equals_ignoring_ascii_case ( " backdrop " sv ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  Selector : : PseudoElement  {  Selector : : PseudoElement : : Type : : Backdrop  } ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-11-30 22:41:00 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    }  else  if  ( name . equals_ignoring_ascii_case ( " file-selector-button " sv ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  Selector : : PseudoElement  {  Selector : : PseudoElement : : Type : : FileSelectorButton  } ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-11-30 23:46:26 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    }  else  if  ( name . equals_ignoring_ascii_case ( " details-content " sv ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  Selector : : PseudoElement  {  Selector : : PseudoElement : : Type : : DetailsContent  } ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-12-11 18:00:06 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    }  else  if  ( name . equals_ignoring_ascii_case ( " -webkit-slider-runnable-track " sv ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  Selector : : PseudoElement  {  Selector : : PseudoElement : : Type : : SliderRunnableTrack  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    }  else  if  ( name . equals_ignoring_ascii_case ( " -webkit-slider-thumb " sv ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  Selector : : PseudoElement  {  Selector : : PseudoElement : : Type : : SliderThumb  } ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-03 14:22:50 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-10-17 12:26:37 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								NonnullRefPtr < Selector >  Selector : : relative_to ( SimpleSelector  const &  parent )  const  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // To make us relative to the parent, prepend it to the list of compound selectors,
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // and ensure the next compound selector starts with a combinator.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    Vector < CompoundSelector >  copied_compound_selectors ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    copied_compound_selectors . ensure_capacity ( compound_selectors ( ) . size ( )  +  1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    copied_compound_selectors . empend ( CompoundSelector  {  . simple_selectors  =  {  parent  }  } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    bool  first  =  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    for  ( auto  compound_selector  :  compound_selectors ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( first )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( compound_selector . combinator  = =  Combinator : : None ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                compound_selector . combinator  =  Combinator : : Descendant ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            first  =  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        copied_compound_selectors . append ( move ( compound_selector ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    return  Selector : : create ( move ( copied_compound_selectors ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-11-14 12:48:50 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								RefPtr < Selector >  Selector : : absolutized ( Selector : : SimpleSelector  const &  selector_for_nesting )  const  
						 
					
						
							
								
									
										
										
										
											2024-10-17 12:26:37 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( ! contains_the_nesting_selector ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  * this ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    Vector < CompoundSelector >  absolutized_compound_selectors ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    absolutized_compound_selectors . ensure_capacity ( m_compound_selectors . size ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-11-14 12:48:50 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    for  ( auto  const &  compound_selector  :  m_compound_selectors )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( auto  absolutized  =  compound_selector . absolutized ( selector_for_nesting ) ;  absolutized . has_value ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            absolutized_compound_selectors . append ( absolutized . release_value ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  nullptr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2024-10-17 12:26:37 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    return  Selector : : create ( move ( absolutized_compound_selectors ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-11-14 12:48:50 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								Optional < Selector : : CompoundSelector >  Selector : : CompoundSelector : : absolutized ( Selector : : SimpleSelector  const &  selector_for_nesting )  const  
						 
					
						
							
								
									
										
										
										
											2024-10-17 12:26:37 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // TODO: Cache if it contains the nesting selector?
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    Vector < SimpleSelector >  absolutized_simple_selectors ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    absolutized_simple_selectors . ensure_capacity ( simple_selectors . size ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-11-14 12:48:50 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    for  ( auto  const &  simple_selector  :  simple_selectors )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( auto  absolutized  =  simple_selector . absolutized ( selector_for_nesting ) ;  absolutized . has_value ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            absolutized_simple_selectors . append ( absolutized . release_value ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2024-10-17 12:26:37 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    return  CompoundSelector  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        . combinator  =  this - > combinator , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        . simple_selectors  =  absolutized_simple_selectors , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-11-14 14:07:38 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								static  bool  contains_invalid_contents_for_has ( Selector  const &  selector )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // :has() has special validity rules:
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // - It can't appear inside itself
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // - It bans most pseudo-elements
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // https://drafts.csswg.org/selectors/#relational
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    for  ( auto  const &  compound_selector  :  selector . compound_selectors ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        for  ( auto  const &  simple_selector  :  compound_selector . simple_selectors )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( simple_selector . type  = =  Selector : : SimpleSelector : : Type : : PseudoElement )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                if  ( ! is_has_allowed_pseudo_element ( simple_selector . pseudo_element ( ) . type ( ) ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    return  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( simple_selector . type  = =  Selector : : SimpleSelector : : Type : : PseudoClass )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                if  ( simple_selector . pseudo_class ( ) . type  = =  PseudoClass : : Has ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    return  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                for  ( auto &  child_selector  :  simple_selector . pseudo_class ( ) . argument_selector_list )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    if  ( contains_invalid_contents_for_has ( * child_selector ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                        return  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    return  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-11-14 12:48:50 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								Optional < Selector : : SimpleSelector >  Selector : : SimpleSelector : : absolutized ( Selector : : SimpleSelector  const &  selector_for_nesting )  const  
						 
					
						
							
								
									
										
										
										
											2024-10-17 12:26:37 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    switch  ( type )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    case  Type : : Nesting : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // Nesting selectors get replaced directly.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  selector_for_nesting ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    case  Type : : PseudoClass :  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // Pseudo-classes may contain other selectors, so we need to absolutize them.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // Copy the PseudoClassSelector, and then replace its argument selector list.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        auto  pseudo_class  =  this - > pseudo_class ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( ! pseudo_class . argument_selector_list . is_empty ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            SelectorList  new_selector_list ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            new_selector_list . ensure_capacity ( pseudo_class . argument_selector_list . size ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-11-14 12:48:50 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            for  ( auto  const &  argument_selector  :  pseudo_class . argument_selector_list )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                if  ( auto  absolutized  =  argument_selector - > absolutized ( selector_for_nesting ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    new_selector_list . append ( absolutized . release_nonnull ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                }  else  if  ( ! pseudo_class . is_forgiving )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            } 
							 
						 
					
						
							
								
									
										
										
										
											2024-10-17 12:26:37 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            pseudo_class . argument_selector_list  =  move ( new_selector_list ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2024-11-14 14:07:38 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // :has() has special validity rules
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( pseudo_class . type  = =  PseudoClass : : Has )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            for  ( auto  const &  selector  :  pseudo_class . argument_selector_list )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                if  ( contains_invalid_contents_for_has ( selector ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    dbgln_if ( CSS_PARSER_DEBUG ,  " After absolutizing, :has() would contain invalid contents; rejecting " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-10-17 12:26:37 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  SimpleSelector  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            . type  =  Type : : PseudoClass , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            . value  =  move ( pseudo_class ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    case  Type : : Universal : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    case  Type : : TagName : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    case  Type : : Id : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    case  Type : : Class : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    case  Type : : Attribute : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    case  Type : : PseudoElement : 
							 
						 
					
						
							
								
									
										
										
										
											2024-11-13 15:49:43 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    case  Type : : Invalid : 
							 
						 
					
						
							
								
									
										
										
										
											2024-10-17 12:26:37 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        // Everything else isn't affected
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  * this ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    VERIFY_NOT_REACHED ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-11-08 17:50:38 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								SelectorList  adapt_nested_relative_selector_list ( SelectorList  const &  selectors )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // "Nested style rules differ from non-nested rules in the following ways:
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // - A nested style rule accepts a <relative-selector-list> as its prelude (rather than just a <selector-list>).
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    //   Any relative selectors are relative to the elements represented by the nesting selector.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // - If a selector in the <relative-selector-list> does not start with a combinator but does contain the nesting
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    //   selector, it is interpreted as a non-relative selector."
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // https://drafts.csswg.org/css-nesting-1/#syntax
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // NOTE: We already parsed the selectors as a <relative-selector-list>
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // Nested relative selectors get a `&` inserted at the beginning.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // This is, handily, how the spec wants them serialized:
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // "When serializing a relative selector in a nested style rule, the selector must be absolutized,
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // with the implied nesting selector inserted."
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // - https://drafts.csswg.org/css-nesting-1/#cssom
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    CSS : : SelectorList  new_list ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    new_list . ensure_capacity ( selectors . size ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    for  ( auto  const &  selector  :  selectors )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        auto  first_combinator  =  selector - > compound_selectors ( ) . first ( ) . combinator ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( ! first_is_one_of ( first_combinator ,  CSS : : Selector : : Combinator : : None ,  CSS : : Selector : : Combinator : : Descendant ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            | |  ! selector - > contains_the_nesting_selector ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            new_list . append ( selector - > relative_to ( CSS : : Selector : : SimpleSelector  {  . type  =  CSS : : Selector : : SimpleSelector : : Type : : Nesting  } ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        }  else  if  ( first_combinator  = =  CSS : : Selector : : Combinator : : Descendant )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            // Replace leading descendant combinator (whitespace) with none, because we're not actually relative.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            auto  copied_compound_selectors  =  selector - > compound_selectors ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            copied_compound_selectors . first ( ) . combinator  =  CSS : : Selector : : Combinator : : None ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            new_list . append ( CSS : : Selector : : create ( move ( copied_compound_selectors ) ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            new_list . append ( selector ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    return  new_list ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-11-14 12:18:10 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								// https://drafts.csswg.org/selectors/#has-allowed-pseudo-element
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								bool  is_has_allowed_pseudo_element ( Selector : : PseudoElement : : Type )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // No spec currently defines any pseudo-elements that are allowed in :has()
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    return  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-03-07 10:27:02 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								}