@@ -47,24 +47,12 @@ pub trait PseudoElement: Sized + ToCss {
4747 false
4848 }
4949
50- /// Whether this pseudo-element is valid when directly after a ::before/::after pseudo.
51- fn valid_after_before_or_after ( & self ) -> bool {
52- false
53- }
54-
5550 /// Whether this pseudo-element is element-backed.
5651 /// https://drafts.csswg.org/css-pseudo-4/#element-like
5752 fn is_element_backed ( & self ) -> bool {
5853 false
5954 }
6055
61- /// Whether this pseudo-element is ::before or ::after pseudo element,
62- /// which are treated specially when deciding what can come after them.
63- /// https://drafts.csswg.org/css-pseudo-4/#generated-content
64- fn is_before_or_after ( & self ) -> bool {
65- false
66- }
67-
6856 /// The count we contribute to the specificity from this pseudo-element.
6957 fn specificity_count ( & self ) -> u32 {
7058 1
@@ -141,30 +129,32 @@ bitflags! {
141129 /// disallowed. If this flag is set, `AFTER_NON_ELEMENT_BACKED_PSEUDO` must be set
142130 /// as well.
143131 const AFTER_NON_STATEFUL_PSEUDO_ELEMENT = 1 << 4 ;
144- // Whether we've parsed a generated pseudo-element (as in ::before, ::after).
145- // If so then some other pseudo elements are disallowed (e.g. another generated pseudo)
146- // while others allowed (e.g. ::marker).
147- const AFTER_BEFORE_OR_AFTER_PSEUDO = 1 << 5 ;
148132
149133 /// Whether we are after any of the pseudo-like things.
150- const AFTER_PSEUDO = Self :: AFTER_PART_LIKE . bits( ) | Self :: AFTER_SLOTTED . bits( ) | Self :: AFTER_NON_ELEMENT_BACKED_PSEUDO . bits( ) | Self :: AFTER_BEFORE_OR_AFTER_PSEUDO . bits ( ) ;
134+ const AFTER_PSEUDO = Self :: AFTER_PART_LIKE . bits( ) | Self :: AFTER_SLOTTED . bits( ) | Self :: AFTER_NON_ELEMENT_BACKED_PSEUDO . bits( ) ;
151135
152136 /// Whether we explicitly disallow combinators.
153- const DISALLOW_COMBINATORS = 1 << 6 ;
137+ const DISALLOW_COMBINATORS = 1 << 5 ;
154138
155139 /// Whether we explicitly disallow pseudo-element-like things.
156- const DISALLOW_PSEUDOS = 1 << 7 ;
140+ const DISALLOW_PSEUDOS = 1 << 6 ;
157141
158142 /// Whether we explicitly disallow relative selectors (i.e. `:has()`).
159- const DISALLOW_RELATIVE_SELECTOR = 1 << 8 ;
143+ const DISALLOW_RELATIVE_SELECTOR = 1 << 7 ;
160144
161145 /// Whether we've parsed a pseudo-element which is in a pseudo-element tree (i.e. it is a
162146 /// descendant pseudo of a pseudo-element root).
163- const IN_PSEUDO_ELEMENT_TREE = 1 << 9 ;
147+ const IN_PSEUDO_ELEMENT_TREE = 1 << 8 ;
164148 }
165149}
166150
167151impl SelectorParsingState {
152+ #[ inline]
153+ fn allows_pseudos ( self ) -> bool {
154+ // NOTE(emilio): We allow pseudos after ::part and such.
155+ !self . intersects ( Self :: AFTER_NON_ELEMENT_BACKED_PSEUDO | Self :: DISALLOW_PSEUDOS )
156+ }
157+
168158 #[ inline]
169159 fn allows_slotted ( self ) -> bool {
170160 !self . intersects ( Self :: AFTER_PSEUDO | Self :: DISALLOW_PSEUDOS )
@@ -938,32 +928,6 @@ impl<Impl: SelectorImpl> Selector<Impl> {
938928 None
939929 }
940930
941- #[ inline]
942- pub fn pseudo_elements ( & self ) -> SmallVec < [ & Impl :: PseudoElement ; 3 ] > {
943- let mut pseudos = SmallVec :: new ( ) ;
944-
945- if !self . has_pseudo_element ( ) {
946- return pseudos;
947- }
948-
949- let mut iter = self . iter ( ) ;
950- loop {
951- for component in & mut iter {
952- if let Component :: PseudoElement ( ref pseudo) = * component {
953- pseudos. push ( pseudo) ;
954- }
955- }
956- match iter. next_sequence ( ) {
957- Some ( Combinator :: PseudoElement ) => { } ,
958- _ => break ,
959- }
960- }
961-
962- debug_assert ! ( !pseudos. is_empty( ) , "has_pseudo_element lied!" ) ;
963-
964- pseudos
965- }
966-
967931 /// Whether this selector (pseudo-element part excluded) matches every element.
968932 ///
969933 /// Used for "pre-computed" pseudo-elements in components/style/stylist.rs
@@ -2808,7 +2772,6 @@ where
28082772 if state. intersects ( SelectorParsingState :: AFTER_PSEUDO ) {
28092773 debug_assert ! ( state. intersects(
28102774 SelectorParsingState :: AFTER_NON_ELEMENT_BACKED_PSEUDO |
2811- SelectorParsingState :: AFTER_BEFORE_OR_AFTER_PSEUDO |
28122775 SelectorParsingState :: AFTER_SLOTTED |
28132776 SelectorParsingState :: AFTER_PART_LIKE
28142777 ) ) ;
@@ -3347,9 +3310,6 @@ where
33473310 state. insert ( SelectorParsingState :: AFTER_PART_LIKE ) ;
33483311 } else {
33493312 state. insert ( SelectorParsingState :: AFTER_NON_ELEMENT_BACKED_PSEUDO ) ;
3350- if p. is_before_or_after ( ) {
3351- state. insert ( SelectorParsingState :: AFTER_BEFORE_OR_AFTER_PSEUDO ) ;
3352- }
33533313 }
33543314 if !p. accepts_state_pseudo_classes ( ) {
33553315 state. insert ( SelectorParsingState :: AFTER_NON_STATEFUL_PSEUDO_ELEMENT ) ;
@@ -3592,15 +3552,7 @@ where
35923552 } ;
35933553 let is_pseudo_element = !is_single_colon || is_css2_pseudo_element ( & name) ;
35943554 if is_pseudo_element {
3595- // Pseudos after pseudo elements are not allowed in some cases:
3596- // - Some states will disallow pseudos, such as the interiors of
3597- // :has/:is/:where/:not (DISALLOW_PSEUDOS).
3598- // - Non-element backed pseudos do not allow other pseudos to follow (AFTER_NON_ELEMENT_BACKED_PSEUDO)...
3599- // - ... except ::before and ::after, which allow _some_ pseudos.
3600- if state. intersects ( SelectorParsingState :: DISALLOW_PSEUDOS )
3601- || ( state. intersects ( SelectorParsingState :: AFTER_NON_ELEMENT_BACKED_PSEUDO )
3602- && !state. intersects ( SelectorParsingState :: AFTER_BEFORE_OR_AFTER_PSEUDO ) )
3603- {
3555+ if !state. allows_pseudos ( ) {
36043556 return Err ( input. new_custom_error ( SelectorParseErrorKind :: InvalidState ) ) ;
36053557 }
36063558 let pseudo_element = if is_functional {
@@ -3638,12 +3590,6 @@ where
36383590 P :: parse_pseudo_element ( parser, location, name) ?
36393591 } ;
36403592
3641- if state. intersects ( SelectorParsingState :: AFTER_BEFORE_OR_AFTER_PSEUDO ) &&
3642- !pseudo_element. valid_after_before_or_after ( )
3643- {
3644- return Err ( input. new_custom_error ( SelectorParseErrorKind :: InvalidState ) ) ;
3645- }
3646-
36473593 if state. intersects ( SelectorParsingState :: AFTER_SLOTTED ) &&
36483594 !pseudo_element. valid_after_slotted ( )
36493595 {
@@ -3742,8 +3688,6 @@ pub mod tests {
37423688 pub enum PseudoElement {
37433689 Before ,
37443690 After ,
3745- Marker ,
3746- DetailsContent ,
37473691 Highlight ( String ) ,
37483692 }
37493693
@@ -3758,16 +3702,8 @@ pub mod tests {
37583702 true
37593703 }
37603704
3761- fn valid_after_before_or_after ( & self ) -> bool {
3762- matches ! ( self , Self :: Marker )
3763- }
3764-
3765- fn is_before_or_after ( & self ) -> bool {
3766- matches ! ( self , Self :: Before | Self :: After )
3767- }
3768-
37693705 fn is_element_backed ( & self ) -> bool {
3770- matches ! ( self , Self :: DetailsContent )
3706+ true
37713707 }
37723708 }
37733709
@@ -3810,8 +3746,6 @@ pub mod tests {
38103746 match * self {
38113747 PseudoElement :: Before => dest. write_str ( "::before" ) ,
38123748 PseudoElement :: After => dest. write_str ( "::after" ) ,
3813- PseudoElement :: Marker => dest. write_str ( "::marker" ) ,
3814- PseudoElement :: DetailsContent => dest. write_str ( "::details-content" ) ,
38153749 PseudoElement :: Highlight ( ref name) => {
38163750 dest. write_str ( "::highlight(" ) ?;
38173751 serialize_identifier ( & name, dest) ?;
@@ -3981,8 +3915,6 @@ pub mod tests {
39813915 match_ignore_ascii_case ! { & name,
39823916 "before" => return Ok ( PseudoElement :: Before ) ,
39833917 "after" => return Ok ( PseudoElement :: After ) ,
3984- "marker" => return Ok ( PseudoElement :: Marker ) ,
3985- "details-content" => return Ok ( PseudoElement :: DetailsContent ) ,
39863918 _ => { }
39873919 }
39883920 Err (
@@ -4647,53 +4579,6 @@ pub mod tests {
46474579 assert_eq ! ( iter. next_sequence( ) , None ) ;
46484580 }
46494581
4650- #[ test]
4651- fn test_pseudo_before_marker ( ) {
4652- let list = parse ( "::before::marker" ) . unwrap ( ) ;
4653- let selector = & list. slice ( ) [ 0 ] ;
4654- let mut iter = selector. iter ( ) ;
4655- assert_eq ! (
4656- iter. next( ) ,
4657- Some ( & Component :: PseudoElement ( PseudoElement :: Marker ) )
4658- ) ;
4659- assert_eq ! ( iter. next( ) , None ) ;
4660- let combinator = iter. next_sequence ( ) ;
4661- assert_eq ! ( combinator, Some ( Combinator :: PseudoElement ) ) ;
4662- assert ! ( matches!( iter. next( ) , Some ( & Component :: PseudoElement ( PseudoElement :: Before ) ) ) ) ;
4663- assert_eq ! ( iter. next( ) , None ) ;
4664- let combinator = iter. next_sequence ( ) ;
4665- assert_eq ! ( combinator, Some ( Combinator :: PseudoElement ) ) ;
4666- assert_eq ! ( iter. next( ) , None ) ;
4667- assert_eq ! ( iter. next_sequence( ) , None ) ;
4668- }
4669-
4670- #[ test]
4671- fn test_pseudo_duplicate_before_after_or_marker ( ) {
4672- assert ! ( parse( "::before::before" ) . is_err( ) ) ;
4673- assert ! ( parse( "::after::after" ) . is_err( ) ) ;
4674- assert ! ( parse( "::marker::marker" ) . is_err( ) ) ;
4675- }
4676-
4677- #[ test]
4678- fn test_pseudo_on_element_backed_pseudo ( ) {
4679- let list = parse ( "::details-content::before" ) . unwrap ( ) ;
4680- let selector = & list. slice ( ) [ 0 ] ;
4681- let mut iter = selector. iter ( ) ;
4682- assert_eq ! (
4683- iter. next( ) ,
4684- Some ( & Component :: PseudoElement ( PseudoElement :: Before ) )
4685- ) ;
4686- assert_eq ! ( iter. next( ) , None ) ;
4687- let combinator = iter. next_sequence ( ) ;
4688- assert_eq ! ( combinator, Some ( Combinator :: PseudoElement ) ) ;
4689- assert ! ( matches!( iter. next( ) , Some ( & Component :: PseudoElement ( PseudoElement :: DetailsContent ) ) ) ) ;
4690- assert_eq ! ( iter. next( ) , None ) ;
4691- let combinator = iter. next_sequence ( ) ;
4692- assert_eq ! ( combinator, Some ( Combinator :: PseudoElement ) ) ;
4693- assert_eq ! ( iter. next( ) , None ) ;
4694- assert_eq ! ( iter. next_sequence( ) , None ) ;
4695- }
4696-
46974582 #[ test]
46984583 fn test_universal ( ) {
46994584 let list = parse_ns (
0 commit comments