tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

parser.rs (176481B)


      1 /* This Source Code Form is subject to the terms of the Mozilla Public
      2 * License, v. 2.0. If a copy of the MPL was not distributed with this
      3 * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
      4 
      5 use crate::attr::{AttrSelectorOperator, AttrSelectorWithOptionalNamespace};
      6 use crate::attr::{NamespaceConstraint, ParsedAttrSelectorOperation, ParsedCaseSensitivity};
      7 use crate::bloom::BLOOM_HASH_MASK;
      8 use crate::builder::{
      9    relative_selector_list_specificity_and_flags, selector_list_specificity_and_flags,
     10    SelectorBuilder, SelectorFlags, Specificity, SpecificityAndFlags,
     11 };
     12 use crate::context::QuirksMode;
     13 use crate::sink::Push;
     14 use crate::visitor::SelectorListKind;
     15 pub use crate::visitor::SelectorVisitor;
     16 use bitflags::bitflags;
     17 use cssparser::match_ignore_ascii_case;
     18 use cssparser::parse_nth;
     19 use cssparser::{BasicParseError, BasicParseErrorKind, ParseError, ParseErrorKind};
     20 use cssparser::{CowRcStr, Delimiter, SourceLocation};
     21 use cssparser::{Parser as CssParser, ToCss, Token};
     22 use debug_unreachable::debug_unreachable;
     23 use precomputed_hash::PrecomputedHash;
     24 use servo_arc::{Arc, ArcUnionBorrow, ThinArc, ThinArcUnion, UniqueArc};
     25 use smallvec::SmallVec;
     26 use std::borrow::{Borrow, Cow};
     27 use std::fmt::{self, Debug};
     28 use std::iter::Rev;
     29 use std::slice;
     30 
     31 #[cfg(feature = "to_shmem")]
     32 use to_shmem_derive::ToShmem;
     33 
     34 /// A trait that represents a pseudo-element.
     35 pub trait PseudoElement: Sized + ToCss {
     36    /// The `SelectorImpl` this pseudo-element is used for.
     37    type Impl: SelectorImpl;
     38 
     39    /// Whether the pseudo-element supports a given state selector to the right
     40    /// of it.
     41    fn accepts_state_pseudo_classes(&self) -> bool {
     42        false
     43    }
     44 
     45    /// Whether this pseudo-element is valid after a ::slotted(..) pseudo.
     46    fn valid_after_slotted(&self) -> bool {
     47        false
     48    }
     49 
     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 
     55    /// Whether this pseudo-element is element-backed.
     56    /// https://drafts.csswg.org/css-pseudo-4/#element-like
     57    fn is_element_backed(&self) -> bool {
     58        false
     59    }
     60 
     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 
     68    /// The count we contribute to the specificity from this pseudo-element.
     69    fn specificity_count(&self) -> u32 {
     70        1
     71    }
     72 
     73    /// Whether this pseudo-element is in a pseudo-element tree (excluding the pseudo-element
     74    /// root).
     75    /// https://drafts.csswg.org/css-view-transitions-1/#pseudo-root
     76    fn is_in_pseudo_element_tree(&self) -> bool {
     77        false
     78    }
     79 }
     80 
     81 /// A trait that represents a pseudo-class.
     82 pub trait NonTSPseudoClass: Sized + ToCss {
     83    /// The `SelectorImpl` this pseudo-element is used for.
     84    type Impl: SelectorImpl;
     85 
     86    /// Whether this pseudo-class is :active or :hover.
     87    fn is_active_or_hover(&self) -> bool;
     88 
     89    /// Whether this pseudo-class belongs to:
     90    ///
     91    /// https://drafts.csswg.org/selectors-4/#useraction-pseudos
     92    fn is_user_action_state(&self) -> bool;
     93 
     94    fn visit<V>(&self, _visitor: &mut V) -> bool
     95    where
     96        V: SelectorVisitor<Impl = Self::Impl>,
     97    {
     98        true
     99    }
    100 }
    101 
    102 /// Returns a Cow::Borrowed if `s` is already ASCII lowercase, and a
    103 /// Cow::Owned if `s` had to be converted into ASCII lowercase.
    104 fn to_ascii_lowercase(s: &str) -> Cow<'_, str> {
    105    if let Some(first_uppercase) = s.bytes().position(|byte| byte >= b'A' && byte <= b'Z') {
    106        let mut string = s.to_owned();
    107        string[first_uppercase..].make_ascii_lowercase();
    108        string.into()
    109    } else {
    110        s.into()
    111    }
    112 }
    113 
    114 bitflags! {
    115    /// Flags that indicate at which point of parsing a selector are we.
    116    #[derive(Copy, Clone)]
    117    struct SelectorParsingState: u16 {
    118        /// Whether we should avoid adding default namespaces to selectors that
    119        /// aren't type or universal selectors.
    120        const SKIP_DEFAULT_NAMESPACE = 1 << 0;
    121 
    122        /// Whether we've parsed a ::slotted() pseudo-element already.
    123        ///
    124        /// If so, then we can only parse a subset of pseudo-elements, and
    125        /// whatever comes after them if so.
    126        const AFTER_SLOTTED = 1 << 1;
    127        /// Whether we've parsed a ::part() or element-backed pseudo-element already.
    128        ///
    129        /// If so, then we can only parse a subset of pseudo-elements, and
    130        /// whatever comes after them if so.
    131        const AFTER_PART_LIKE = 1 << 2;
    132        /// Whether we've parsed a non-element-backed pseudo-element (as in, an
    133        /// `Impl::PseudoElement` thus not accounting for `::slotted` or
    134        /// `::part`) already.
    135        ///
    136        /// If so, then other pseudo-elements and most other selectors are
    137        /// disallowed.
    138        const AFTER_NON_ELEMENT_BACKED_PSEUDO = 1 << 3;
    139        /// Whether we've parsed a non-stateful pseudo-element (again, as-in
    140        /// `Impl::PseudoElement`) already. If so, then other pseudo-classes are
    141        /// disallowed. If this flag is set, `AFTER_NON_ELEMENT_BACKED_PSEUDO` must be set
    142        /// as well.
    143        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;
    148 
    149        /// 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();
    151 
    152        /// Whether we explicitly disallow combinators.
    153        const DISALLOW_COMBINATORS = 1 << 6;
    154 
    155        /// Whether we explicitly disallow pseudo-element-like things.
    156        const DISALLOW_PSEUDOS = 1 << 7;
    157 
    158        /// Whether we explicitly disallow relative selectors (i.e. `:has()`).
    159        const DISALLOW_RELATIVE_SELECTOR = 1 << 8;
    160 
    161        /// Whether we've parsed a pseudo-element which is in a pseudo-element tree (i.e. it is a
    162        /// descendant pseudo of a pseudo-element root).
    163        const IN_PSEUDO_ELEMENT_TREE = 1 << 9;
    164    }
    165 }
    166 
    167 impl SelectorParsingState {
    168    #[inline]
    169    fn allows_slotted(self) -> bool {
    170        !self.intersects(Self::AFTER_PSEUDO | Self::DISALLOW_PSEUDOS)
    171    }
    172 
    173    #[inline]
    174    fn allows_part(self) -> bool {
    175        !self.intersects(Self::AFTER_PSEUDO | Self::DISALLOW_PSEUDOS)
    176    }
    177 
    178    #[inline]
    179    fn allows_non_functional_pseudo_classes(self) -> bool {
    180        !self.intersects(Self::AFTER_SLOTTED | Self::AFTER_NON_STATEFUL_PSEUDO_ELEMENT)
    181    }
    182 
    183    #[inline]
    184    fn allows_tree_structural_pseudo_classes(self) -> bool {
    185        !self.intersects(Self::AFTER_PSEUDO) || self.intersects(Self::IN_PSEUDO_ELEMENT_TREE)
    186    }
    187 
    188    #[inline]
    189    fn allows_combinators(self) -> bool {
    190        !self.intersects(Self::DISALLOW_COMBINATORS)
    191    }
    192 
    193    #[inline]
    194    fn allows_only_child_pseudo_class_only(self) -> bool {
    195        self.intersects(Self::IN_PSEUDO_ELEMENT_TREE)
    196    }
    197 }
    198 
    199 pub type SelectorParseError<'i> = ParseError<'i, SelectorParseErrorKind<'i>>;
    200 
    201 #[derive(Clone, Debug, PartialEq)]
    202 pub enum SelectorParseErrorKind<'i> {
    203    NoQualifiedNameInAttributeSelector(Token<'i>),
    204    EmptySelector,
    205    DanglingCombinator,
    206    NonCompoundSelector,
    207    NonPseudoElementAfterSlotted,
    208    InvalidPseudoElementAfterSlotted,
    209    InvalidPseudoElementInsideWhere,
    210    InvalidState,
    211    UnexpectedTokenInAttributeSelector(Token<'i>),
    212    PseudoElementExpectedColon(Token<'i>),
    213    PseudoElementExpectedIdent(Token<'i>),
    214    NoIdentForPseudo(Token<'i>),
    215    UnsupportedPseudoClassOrElement(CowRcStr<'i>),
    216    UnexpectedIdent(CowRcStr<'i>),
    217    ExpectedNamespace(CowRcStr<'i>),
    218    ExpectedBarInAttr(Token<'i>),
    219    BadValueInAttr(Token<'i>),
    220    InvalidQualNameInAttr(Token<'i>),
    221    ExplicitNamespaceUnexpectedToken(Token<'i>),
    222    ClassNeedsIdent(Token<'i>),
    223 }
    224 
    225 macro_rules! with_all_bounds {
    226    (
    227        [ $( $InSelector: tt )* ]
    228        [ $( $CommonBounds: tt )* ]
    229        [ $( $FromStr: tt )* ]
    230    ) => {
    231        /// This trait allows to define the parser implementation in regards
    232        /// of pseudo-classes/elements
    233        ///
    234        /// NB: We need Clone so that we can derive(Clone) on struct with that
    235        /// are parameterized on SelectorImpl. See
    236        /// <https://github.com/rust-lang/rust/issues/26925>
    237        pub trait SelectorImpl: Clone + Debug + Sized + 'static {
    238            type ExtraMatchingData<'a>: Sized + Default;
    239            type AttrValue: $($InSelector)*;
    240            type Identifier: $($InSelector)* + PrecomputedHash;
    241            type LocalName: $($InSelector)* + Borrow<Self::BorrowedLocalName> + PrecomputedHash;
    242            type NamespaceUrl: $($CommonBounds)* + Default + Borrow<Self::BorrowedNamespaceUrl> + PrecomputedHash;
    243            type NamespacePrefix: $($InSelector)* + Default;
    244            type BorrowedNamespaceUrl: ?Sized + Eq;
    245            type BorrowedLocalName: ?Sized + Eq;
    246 
    247            /// non tree-structural pseudo-classes
    248            /// (see: https://drafts.csswg.org/selectors/#structural-pseudos)
    249            type NonTSPseudoClass: $($CommonBounds)* + NonTSPseudoClass<Impl = Self>;
    250 
    251            /// pseudo-elements
    252            type PseudoElement: $($CommonBounds)* + PseudoElement<Impl = Self>;
    253 
    254            /// Whether attribute hashes should be collected for filtering
    255            /// purposes.
    256            fn should_collect_attr_hash(_name: &Self::LocalName) -> bool {
    257                false
    258            }
    259        }
    260    }
    261 }
    262 
    263 macro_rules! with_bounds {
    264    ( [ $( $CommonBounds: tt )* ] [ $( $FromStr: tt )* ]) => {
    265        with_all_bounds! {
    266            [$($CommonBounds)* + $($FromStr)* + ToCss]
    267            [$($CommonBounds)*]
    268            [$($FromStr)*]
    269        }
    270    }
    271 }
    272 
    273 with_bounds! {
    274    [Clone + Eq]
    275    [for<'a> From<&'a str>]
    276 }
    277 
    278 pub trait Parser<'i> {
    279    type Impl: SelectorImpl;
    280    type Error: 'i + From<SelectorParseErrorKind<'i>>;
    281 
    282    /// Whether to parse the `::slotted()` pseudo-element.
    283    fn parse_slotted(&self) -> bool {
    284        false
    285    }
    286 
    287    /// Whether to parse the `::part()` pseudo-element.
    288    fn parse_part(&self) -> bool {
    289        false
    290    }
    291 
    292    /// Whether to parse the selector list of nth-child() or nth-last-child().
    293    fn parse_nth_child_of(&self) -> bool {
    294        false
    295    }
    296 
    297    /// Whether to parse `:is` and `:where` pseudo-classes.
    298    fn parse_is_and_where(&self) -> bool {
    299        false
    300    }
    301 
    302    /// Whether to parse the :has pseudo-class.
    303    fn parse_has(&self) -> bool {
    304        false
    305    }
    306 
    307    /// Whether to parse the '&' delimiter as a parent selector.
    308    fn parse_parent_selector(&self) -> bool {
    309        false
    310    }
    311 
    312    /// Whether the given function name is an alias for the `:is()` function.
    313    fn is_is_alias(&self, _name: &str) -> bool {
    314        false
    315    }
    316 
    317    /// Whether to parse the `:host` pseudo-class.
    318    fn parse_host(&self) -> bool {
    319        false
    320    }
    321 
    322    /// Whether to allow forgiving selector-list parsing.
    323    fn allow_forgiving_selectors(&self) -> bool {
    324        true
    325    }
    326 
    327    /// This function can return an "Err" pseudo-element in order to support CSS2.1
    328    /// pseudo-elements.
    329    fn parse_non_ts_pseudo_class(
    330        &self,
    331        location: SourceLocation,
    332        name: CowRcStr<'i>,
    333    ) -> Result<<Self::Impl as SelectorImpl>::NonTSPseudoClass, ParseError<'i, Self::Error>> {
    334        Err(
    335            location.new_custom_error(SelectorParseErrorKind::UnsupportedPseudoClassOrElement(
    336                name,
    337            )),
    338        )
    339    }
    340 
    341    fn parse_non_ts_functional_pseudo_class<'t>(
    342        &self,
    343        name: CowRcStr<'i>,
    344        parser: &mut CssParser<'i, 't>,
    345        _after_part: bool,
    346    ) -> Result<<Self::Impl as SelectorImpl>::NonTSPseudoClass, ParseError<'i, Self::Error>> {
    347        Err(
    348            parser.new_custom_error(SelectorParseErrorKind::UnsupportedPseudoClassOrElement(
    349                name,
    350            )),
    351        )
    352    }
    353 
    354    fn parse_pseudo_element(
    355        &self,
    356        location: SourceLocation,
    357        name: CowRcStr<'i>,
    358    ) -> Result<<Self::Impl as SelectorImpl>::PseudoElement, ParseError<'i, Self::Error>> {
    359        Err(
    360            location.new_custom_error(SelectorParseErrorKind::UnsupportedPseudoClassOrElement(
    361                name,
    362            )),
    363        )
    364    }
    365 
    366    fn parse_functional_pseudo_element<'t>(
    367        &self,
    368        name: CowRcStr<'i>,
    369        arguments: &mut CssParser<'i, 't>,
    370    ) -> Result<<Self::Impl as SelectorImpl>::PseudoElement, ParseError<'i, Self::Error>> {
    371        Err(
    372            arguments.new_custom_error(SelectorParseErrorKind::UnsupportedPseudoClassOrElement(
    373                name,
    374            )),
    375        )
    376    }
    377 
    378    fn default_namespace(&self) -> Option<<Self::Impl as SelectorImpl>::NamespaceUrl> {
    379        None
    380    }
    381 
    382    fn namespace_for_prefix(
    383        &self,
    384        _prefix: &<Self::Impl as SelectorImpl>::NamespacePrefix,
    385    ) -> Option<<Self::Impl as SelectorImpl>::NamespaceUrl> {
    386        None
    387    }
    388 }
    389 
    390 /// A selector list is a tagged pointer with either a single selector, or a ThinArc<()> of multiple
    391 /// selectors.
    392 #[derive(Clone, Eq, Debug, PartialEq)]
    393 #[cfg_attr(feature = "to_shmem", derive(ToShmem))]
    394 #[cfg_attr(feature = "to_shmem", shmem(no_bounds))]
    395 pub struct SelectorList<Impl: SelectorImpl>(
    396    #[cfg_attr(feature = "to_shmem", shmem(field_bound))]
    397    ThinArcUnion<SpecificityAndFlags, Component<Impl>, (), Selector<Impl>>,
    398 );
    399 
    400 impl<Impl: SelectorImpl> SelectorList<Impl> {
    401    /// See Arc::mark_as_intentionally_leaked
    402    pub fn mark_as_intentionally_leaked(&self) {
    403        if let ArcUnionBorrow::Second(ref list) = self.0.borrow() {
    404            list.with_arc(|list| list.mark_as_intentionally_leaked())
    405        }
    406        self.slice()
    407            .iter()
    408            .for_each(|s| s.mark_as_intentionally_leaked())
    409    }
    410 
    411    pub fn from_one(selector: Selector<Impl>) -> Self {
    412        #[cfg(debug_assertions)]
    413        let selector_repr = unsafe { *(&selector as *const _ as *const usize) };
    414        let list = Self(ThinArcUnion::from_first(selector.into_data()));
    415        #[cfg(debug_assertions)]
    416        debug_assert_eq!(
    417            selector_repr,
    418            unsafe { *(&list as *const _ as *const usize) },
    419            "We rely on the same bit representation for the single selector variant"
    420        );
    421        list
    422    }
    423 
    424    pub fn from_iter(mut iter: impl ExactSizeIterator<Item = Selector<Impl>>) -> Self {
    425        if iter.len() == 1 {
    426            Self::from_one(iter.next().unwrap())
    427        } else {
    428            Self(ThinArcUnion::from_second(ThinArc::from_header_and_iter(
    429                (),
    430                iter,
    431            )))
    432        }
    433    }
    434 
    435    #[inline]
    436    pub fn slice(&self) -> &[Selector<Impl>] {
    437        match self.0.borrow() {
    438            ArcUnionBorrow::First(..) => {
    439                // SAFETY: see from_one.
    440                let selector: &Selector<Impl> = unsafe { std::mem::transmute(self) };
    441                std::slice::from_ref(selector)
    442            },
    443            ArcUnionBorrow::Second(list) => list.get().slice(),
    444        }
    445    }
    446 
    447    #[inline]
    448    pub fn len(&self) -> usize {
    449        match self.0.borrow() {
    450            ArcUnionBorrow::First(..) => 1,
    451            ArcUnionBorrow::Second(list) => list.len(),
    452        }
    453    }
    454 
    455    /// Returns the address on the heap of the ThinArc for memory reporting.
    456    pub fn thin_arc_heap_ptr(&self) -> *const ::std::os::raw::c_void {
    457        match self.0.borrow() {
    458            ArcUnionBorrow::First(s) => s.with_arc(|a| a.heap_ptr()),
    459            ArcUnionBorrow::Second(s) => s.with_arc(|a| a.heap_ptr()),
    460        }
    461    }
    462 }
    463 
    464 /// Uniquely identify a selector based on its components, which is behind ThinArc and
    465 /// is therefore stable.
    466 #[derive(Clone, Copy, Hash, Eq, PartialEq)]
    467 pub struct SelectorKey(usize);
    468 
    469 impl SelectorKey {
    470    /// Create a new key based on the given selector.
    471    pub fn new<Impl: SelectorImpl>(selector: &Selector<Impl>) -> Self {
    472        Self(selector.0.slice().as_ptr() as usize)
    473    }
    474 }
    475 
    476 /// Whether or not we're using forgiving parsing mode
    477 #[derive(PartialEq)]
    478 enum ForgivingParsing {
    479    /// Discard the entire selector list upon encountering any invalid selector.
    480    /// This is the default behavior for almost all of CSS.
    481    No,
    482    /// Ignore invalid selectors, potentially creating an empty selector list.
    483    ///
    484    /// This is the error recovery mode of :is() and :where()
    485    Yes,
    486 }
    487 
    488 /// Flag indicating if we're parsing relative selectors.
    489 #[derive(Copy, Clone, PartialEq)]
    490 pub enum ParseRelative {
    491    /// Expect selectors to start with a combinator, assuming descendant combinator if not present.
    492    ForHas,
    493    /// Allow selectors to start with a combinator, prepending a parent selector if so. Do nothing
    494    /// otherwise
    495    ForNesting,
    496    /// Allow selectors to start with a combinator, prepending a scope selector if so. Do nothing
    497    /// otherwise
    498    ForScope,
    499    /// Treat as parse error if any selector begins with a combinator.
    500    No,
    501 }
    502 
    503 impl<Impl: SelectorImpl> SelectorList<Impl> {
    504    /// Returns a selector list with a single `:scope` selector (with specificity)
    505    pub fn scope() -> Self {
    506        Self::from_one(Selector::scope())
    507    }
    508    /// Returns a selector list with a single implicit `:scope` selector (no specificity)
    509    pub fn implicit_scope() -> Self {
    510        Self::from_one(Selector::implicit_scope())
    511    }
    512 
    513    /// Parse a comma-separated list of Selectors.
    514    /// <https://drafts.csswg.org/selectors/#grouping>
    515    ///
    516    /// Return the Selectors or Err if there is an invalid selector.
    517    pub fn parse<'i, 't, P>(
    518        parser: &P,
    519        input: &mut CssParser<'i, 't>,
    520        parse_relative: ParseRelative,
    521    ) -> Result<Self, ParseError<'i, P::Error>>
    522    where
    523        P: Parser<'i, Impl = Impl>,
    524    {
    525        Self::parse_with_state(
    526            parser,
    527            input,
    528            SelectorParsingState::empty(),
    529            ForgivingParsing::No,
    530            parse_relative,
    531        )
    532    }
    533 
    534    /// Same as `parse`, but disallow parsing of pseudo-elements.
    535    pub fn parse_disallow_pseudo<'i, 't, P>(
    536        parser: &P,
    537        input: &mut CssParser<'i, 't>,
    538        parse_relative: ParseRelative,
    539    ) -> Result<Self, ParseError<'i, P::Error>>
    540    where
    541        P: Parser<'i, Impl = Impl>,
    542    {
    543        Self::parse_with_state(
    544            parser,
    545            input,
    546            SelectorParsingState::DISALLOW_PSEUDOS,
    547            ForgivingParsing::No,
    548            parse_relative,
    549        )
    550    }
    551 
    552    pub fn parse_forgiving<'i, 't, P>(
    553        parser: &P,
    554        input: &mut CssParser<'i, 't>,
    555        parse_relative: ParseRelative,
    556    ) -> Result<Self, ParseError<'i, P::Error>>
    557    where
    558        P: Parser<'i, Impl = Impl>,
    559    {
    560        Self::parse_with_state(
    561            parser,
    562            input,
    563            SelectorParsingState::empty(),
    564            ForgivingParsing::Yes,
    565            parse_relative,
    566        )
    567    }
    568 
    569    #[inline]
    570    fn parse_with_state<'i, 't, P>(
    571        parser: &P,
    572        input: &mut CssParser<'i, 't>,
    573        state: SelectorParsingState,
    574        recovery: ForgivingParsing,
    575        parse_relative: ParseRelative,
    576    ) -> Result<Self, ParseError<'i, P::Error>>
    577    where
    578        P: Parser<'i, Impl = Impl>,
    579    {
    580        let mut values = SmallVec::<[_; 4]>::new();
    581        let forgiving = recovery == ForgivingParsing::Yes && parser.allow_forgiving_selectors();
    582        loop {
    583            let selector = input.parse_until_before(Delimiter::Comma, |input| {
    584                let start = input.position();
    585                let mut selector = parse_selector(parser, input, state, parse_relative);
    586                if forgiving && (selector.is_err() || input.expect_exhausted().is_err()) {
    587                    input.expect_no_error_token()?;
    588                    selector = Ok(Selector::new_invalid(input.slice_from(start)));
    589                }
    590                selector
    591            })?;
    592 
    593            values.push(selector);
    594 
    595            match input.next() {
    596                Ok(&Token::Comma) => {},
    597                Ok(_) => unreachable!(),
    598                Err(_) => break,
    599            }
    600        }
    601        Ok(Self::from_iter(values.into_iter()))
    602    }
    603 
    604    /// Replaces the parent selector in all the items of the selector list.
    605    pub fn replace_parent_selector(&self, parent: &SelectorList<Impl>) -> Self {
    606        Self::from_iter(
    607            self.slice()
    608                .iter()
    609                .map(|selector| selector.replace_parent_selector(parent)),
    610        )
    611    }
    612 
    613    /// Creates a SelectorList from a Vec of selectors. Used in tests.
    614    #[allow(dead_code)]
    615    pub(crate) fn from_vec(v: Vec<Selector<Impl>>) -> Self {
    616        SelectorList::from_iter(v.into_iter())
    617    }
    618 }
    619 
    620 /// Parses one compound selector suitable for nested stuff like :-moz-any, etc.
    621 fn parse_inner_compound_selector<'i, 't, P, Impl>(
    622    parser: &P,
    623    input: &mut CssParser<'i, 't>,
    624    state: SelectorParsingState,
    625 ) -> Result<Selector<Impl>, ParseError<'i, P::Error>>
    626 where
    627    P: Parser<'i, Impl = Impl>,
    628    Impl: SelectorImpl,
    629 {
    630    parse_selector(
    631        parser,
    632        input,
    633        state | SelectorParsingState::DISALLOW_PSEUDOS | SelectorParsingState::DISALLOW_COMBINATORS,
    634        ParseRelative::No,
    635    )
    636 }
    637 
    638 /// Ancestor hashes for the bloom filter. We precompute these and store them
    639 /// inline with selectors to optimize cache performance during matching.
    640 /// This matters a lot.
    641 ///
    642 /// We use 4 hashes, which is copied from Gecko, who copied it from WebKit.
    643 /// Note that increasing the number of hashes here will adversely affect the
    644 /// cache hit when fast-rejecting long lists of Rules with inline hashes.
    645 ///
    646 /// Because the bloom filter only uses the bottom 24 bits of the hash, we pack
    647 /// the fourth hash into the upper bits of the first three hashes in order to
    648 /// shrink Rule (whose size matters a lot). This scheme minimizes the runtime
    649 /// overhead of the packing for the first three hashes (we just need to mask
    650 /// off the upper bits) at the expense of making the fourth somewhat more
    651 /// complicated to assemble, because we often bail out before checking all the
    652 /// hashes.
    653 #[derive(Clone, Debug, Eq, PartialEq)]
    654 pub struct AncestorHashes {
    655    pub packed_hashes: [u32; 3],
    656 }
    657 
    658 pub(crate) fn collect_selector_hashes<'a, Impl: SelectorImpl, Iter>(
    659    iter: Iter,
    660    quirks_mode: QuirksMode,
    661    hashes: &mut [u32; 4],
    662    len: &mut usize,
    663    create_inner_iterator: fn(&'a Selector<Impl>) -> Iter,
    664 ) -> bool
    665 where
    666    Iter: Iterator<Item = &'a Component<Impl>>,
    667 {
    668    for component in iter {
    669        let hash = match *component {
    670            Component::LocalName(LocalName {
    671                ref name,
    672                ref lower_name,
    673            }) => {
    674                // Only insert the local-name into the filter if it's all
    675                // lowercase.  Otherwise we would need to test both hashes, and
    676                // our data structures aren't really set up for that.
    677                if name != lower_name {
    678                    continue;
    679                }
    680                name.precomputed_hash()
    681            },
    682            Component::DefaultNamespace(ref url) | Component::Namespace(_, ref url) => {
    683                url.precomputed_hash()
    684            },
    685            // In quirks mode, class and id selectors should match
    686            // case-insensitively, so just avoid inserting them into the filter.
    687            Component::ID(ref id) if quirks_mode != QuirksMode::Quirks => id.precomputed_hash(),
    688            Component::Class(ref class) if quirks_mode != QuirksMode::Quirks => {
    689                class.precomputed_hash()
    690            },
    691            Component::AttributeInNoNamespace { ref local_name, .. }
    692                if Impl::should_collect_attr_hash(local_name) =>
    693            {
    694                // AttributeInNoNamespace is only used when local_name ==
    695                // local_name_lower.
    696                local_name.precomputed_hash()
    697            },
    698            Component::AttributeInNoNamespaceExists {
    699                ref local_name,
    700                ref local_name_lower,
    701                ..
    702            } => {
    703                // Only insert the local-name into the filter if it's all
    704                // lowercase.  Otherwise we would need to test both hashes, and
    705                // our data structures aren't really set up for that.
    706                if local_name != local_name_lower || !Impl::should_collect_attr_hash(local_name) {
    707                    continue;
    708                }
    709                local_name.precomputed_hash()
    710            },
    711            Component::AttributeOther(ref selector) => {
    712                if selector.local_name != selector.local_name_lower
    713                    || !Impl::should_collect_attr_hash(&selector.local_name)
    714                {
    715                    continue;
    716                }
    717                selector.local_name.precomputed_hash()
    718            },
    719            Component::Is(ref list) | Component::Where(ref list) => {
    720                // :where and :is OR their selectors, so we can't put any hash
    721                // in the filter if there's more than one selector, as that'd
    722                // exclude elements that may match one of the other selectors.
    723                let slice = list.slice();
    724                if slice.len() == 1
    725                    && !collect_selector_hashes(
    726                        create_inner_iterator(&slice[0]),
    727                        quirks_mode,
    728                        hashes,
    729                        len,
    730                        create_inner_iterator,
    731                    )
    732                {
    733                    return false;
    734                }
    735                continue;
    736            },
    737            _ => continue,
    738        };
    739 
    740        hashes[*len] = hash & BLOOM_HASH_MASK;
    741        *len += 1;
    742        if *len == hashes.len() {
    743            return false;
    744        }
    745    }
    746    true
    747 }
    748 
    749 fn collect_ancestor_hashes<Impl: SelectorImpl>(
    750    iter: SelectorIter<Impl>,
    751    quirks_mode: QuirksMode,
    752    hashes: &mut [u32; 4],
    753    len: &mut usize,
    754 ) {
    755    collect_selector_hashes(AncestorIter::new(iter), quirks_mode, hashes, len, |s| {
    756        AncestorIter(s.iter())
    757    });
    758 }
    759 
    760 impl AncestorHashes {
    761    pub fn new<Impl: SelectorImpl>(selector: &Selector<Impl>, quirks_mode: QuirksMode) -> Self {
    762        // Compute ancestor hashes for the bloom filter.
    763        let mut hashes = [0u32; 4];
    764        let mut len = 0;
    765        collect_ancestor_hashes(selector.iter(), quirks_mode, &mut hashes, &mut len);
    766        debug_assert!(len <= 4);
    767 
    768        // Now, pack the fourth hash (if it exists) into the upper byte of each of
    769        // the other three hashes.
    770        if len == 4 {
    771            let fourth = hashes[3];
    772            hashes[0] |= (fourth & 0x000000ff) << 24;
    773            hashes[1] |= (fourth & 0x0000ff00) << 16;
    774            hashes[2] |= (fourth & 0x00ff0000) << 8;
    775        }
    776 
    777        AncestorHashes {
    778            packed_hashes: [hashes[0], hashes[1], hashes[2]],
    779        }
    780    }
    781 
    782    /// Returns the fourth hash, reassembled from parts.
    783    pub fn fourth_hash(&self) -> u32 {
    784        ((self.packed_hashes[0] & 0xff000000) >> 24)
    785            | ((self.packed_hashes[1] & 0xff000000) >> 16)
    786            | ((self.packed_hashes[2] & 0xff000000) >> 8)
    787    }
    788 }
    789 
    790 #[inline]
    791 pub fn namespace_empty_string<Impl: SelectorImpl>() -> Impl::NamespaceUrl {
    792    // Rust type’s default, not default namespace
    793    Impl::NamespaceUrl::default()
    794 }
    795 
    796 pub(super) type SelectorData<Impl> = ThinArc<SpecificityAndFlags, Component<Impl>>;
    797 
    798 /// Whether a selector may match a featureless host element, and whether it may match other
    799 /// elements.
    800 #[derive(Clone, Copy, Debug, Eq, PartialEq)]
    801 pub enum MatchesFeaturelessHost {
    802    /// The selector may match a featureless host, but also a non-featureless element.
    803    Yes,
    804    /// The selector is guaranteed to never match a non-featureless host element.
    805    Only,
    806    /// The selector never matches a featureless host.
    807    Never,
    808 }
    809 
    810 impl MatchesFeaturelessHost {
    811    /// Whether we may match.
    812    #[inline]
    813    pub fn may_match(self) -> bool {
    814        return !matches!(self, Self::Never);
    815    }
    816 }
    817 
    818 /// A Selector stores a sequence of simple selectors and combinators. The
    819 /// iterator classes allow callers to iterate at either the raw sequence level or
    820 /// at the level of sequences of simple selectors separated by combinators. Most
    821 /// callers want the higher-level iterator.
    822 ///
    823 /// We store compound selectors internally right-to-left (in matching order).
    824 /// Additionally, we invert the order of top-level compound selectors so that
    825 /// each one matches left-to-right. This is because matching namespace, local name,
    826 /// id, and class are all relatively cheap, whereas matching pseudo-classes might
    827 /// be expensive (depending on the pseudo-class). Since authors tend to put the
    828 /// pseudo-classes on the right, it's faster to start matching on the left.
    829 ///
    830 /// This reordering doesn't change the semantics of selector matching, and we
    831 /// handle it in to_css to make it invisible to serialization.
    832 #[derive(Clone, Eq, PartialEq)]
    833 #[cfg_attr(feature = "to_shmem", derive(ToShmem))]
    834 #[cfg_attr(feature = "to_shmem", shmem(no_bounds))]
    835 #[repr(transparent)]
    836 pub struct Selector<Impl: SelectorImpl>(
    837    #[cfg_attr(feature = "to_shmem", shmem(field_bound))] SelectorData<Impl>,
    838 );
    839 
    840 impl<Impl: SelectorImpl> Selector<Impl> {
    841    /// See Arc::mark_as_intentionally_leaked
    842    pub fn mark_as_intentionally_leaked(&self) {
    843        self.0.mark_as_intentionally_leaked()
    844    }
    845 
    846    fn scope() -> Self {
    847        Self(ThinArc::from_header_and_iter(
    848            SpecificityAndFlags {
    849                specificity: Specificity::single_class_like().into(),
    850                flags: SelectorFlags::HAS_SCOPE,
    851            },
    852            std::iter::once(Component::Scope),
    853        ))
    854    }
    855 
    856    /// An implicit scope selector, much like :where(:scope).
    857    fn implicit_scope() -> Self {
    858        Self(ThinArc::from_header_and_iter(
    859            SpecificityAndFlags {
    860                specificity: 0,
    861                flags: SelectorFlags::HAS_SCOPE,
    862            },
    863            std::iter::once(Component::ImplicitScope),
    864        ))
    865    }
    866 
    867    #[inline]
    868    pub fn specificity(&self) -> u32 {
    869        self.0.header.specificity
    870    }
    871 
    872    #[inline]
    873    pub(crate) fn flags(&self) -> SelectorFlags {
    874        self.0.header.flags
    875    }
    876 
    877    #[inline]
    878    pub fn has_pseudo_element(&self) -> bool {
    879        self.flags().intersects(SelectorFlags::HAS_PSEUDO)
    880    }
    881 
    882    #[inline]
    883    pub fn has_parent_selector(&self) -> bool {
    884        self.flags().intersects(SelectorFlags::HAS_PARENT)
    885    }
    886 
    887    #[inline]
    888    pub fn has_scope_selector(&self) -> bool {
    889        self.flags().intersects(SelectorFlags::HAS_SCOPE)
    890    }
    891 
    892    #[inline]
    893    pub fn is_slotted(&self) -> bool {
    894        self.flags().intersects(SelectorFlags::HAS_SLOTTED)
    895    }
    896 
    897    #[inline]
    898    pub fn is_part(&self) -> bool {
    899        self.flags().intersects(SelectorFlags::HAS_PART)
    900    }
    901 
    902    #[inline]
    903    pub fn parts(&self) -> Option<&[Impl::Identifier]> {
    904        if !self.is_part() {
    905            return None;
    906        }
    907 
    908        let mut iter = self.iter();
    909        if self.has_pseudo_element() {
    910            // Skip the pseudo-element.
    911            for _ in &mut iter {}
    912 
    913            let combinator = iter.next_sequence()?;
    914            debug_assert_eq!(combinator, Combinator::PseudoElement);
    915        }
    916 
    917        for component in iter {
    918            if let Component::Part(ref part) = *component {
    919                return Some(part);
    920            }
    921        }
    922 
    923        debug_assert!(false, "is_part() lied somehow?");
    924        None
    925    }
    926 
    927    #[inline]
    928    pub fn pseudo_element(&self) -> Option<&Impl::PseudoElement> {
    929        if !self.has_pseudo_element() {
    930            return None;
    931        }
    932 
    933        for component in self.iter() {
    934            if let Component::PseudoElement(ref pseudo) = *component {
    935                return Some(pseudo);
    936            }
    937        }
    938 
    939        debug_assert!(false, "has_pseudo_element lied!");
    940        None
    941    }
    942 
    943    #[inline]
    944    pub fn pseudo_elements(&self) -> SmallVec<[&Impl::PseudoElement; 3]> {
    945        let mut pseudos = SmallVec::new();
    946 
    947        if !self.has_pseudo_element() {
    948            return pseudos;
    949        }
    950 
    951        let mut iter = self.iter();
    952        loop {
    953            for component in &mut iter {
    954                if let Component::PseudoElement(ref pseudo) = *component {
    955                    pseudos.push(pseudo);
    956                }
    957            }
    958            match iter.next_sequence() {
    959                Some(Combinator::PseudoElement) => {},
    960                _ => break,
    961            }
    962        }
    963 
    964        debug_assert!(!pseudos.is_empty(), "has_pseudo_element lied!");
    965 
    966        pseudos
    967    }
    968 
    969    /// Whether this selector (pseudo-element part excluded) matches every element.
    970    ///
    971    /// Used for "pre-computed" pseudo-elements in components/style/stylist.rs
    972    #[inline]
    973    pub fn is_universal(&self) -> bool {
    974        self.iter_raw_match_order().all(|c| {
    975            matches!(
    976                *c,
    977                Component::ExplicitUniversalType
    978                    | Component::ExplicitAnyNamespace
    979                    | Component::Combinator(Combinator::PseudoElement)
    980                    | Component::PseudoElement(..)
    981            )
    982        })
    983    }
    984 
    985    /// Whether this selector may match a featureless shadow host, with no combinators to the
    986    /// left, and optionally has a pseudo-element to the right.
    987    #[inline]
    988    pub fn matches_featureless_host(
    989        &self,
    990        scope_matches_featureless_host: bool,
    991    ) -> MatchesFeaturelessHost {
    992        let flags = self.flags();
    993        if !flags.intersects(SelectorFlags::HAS_HOST | SelectorFlags::HAS_SCOPE) {
    994            return MatchesFeaturelessHost::Never;
    995        }
    996 
    997        let mut iter = self.iter();
    998        if flags.intersects(SelectorFlags::HAS_PSEUDO) {
    999            for _ in &mut iter {
   1000                // Skip over pseudo-elements
   1001            }
   1002            match iter.next_sequence() {
   1003                Some(c) if c.is_pseudo_element() => {},
   1004                _ => {
   1005                    debug_assert!(false, "Pseudo selector without pseudo combinator?");
   1006                    return MatchesFeaturelessHost::Never;
   1007                },
   1008            }
   1009        }
   1010 
   1011        let compound_matches = crate::matching::compound_matches_featureless_host(
   1012            &mut iter,
   1013            scope_matches_featureless_host,
   1014        );
   1015        if iter.next_sequence().is_some() {
   1016            return MatchesFeaturelessHost::Never;
   1017        }
   1018        return compound_matches;
   1019    }
   1020 
   1021    /// Returns an iterator over this selector in matching order (right-to-left).
   1022    /// When a combinator is reached, the iterator will return None, and
   1023    /// next_sequence() may be called to continue to the next sequence.
   1024    #[inline]
   1025    pub fn iter(&self) -> SelectorIter<'_, Impl> {
   1026        SelectorIter {
   1027            iter: self.iter_raw_match_order(),
   1028            next_combinator: None,
   1029        }
   1030    }
   1031 
   1032    /// Same as `iter()`, but skips `RelativeSelectorAnchor` and its associated combinator.
   1033    #[inline]
   1034    pub fn iter_skip_relative_selector_anchor(&self) -> SelectorIter<'_, Impl> {
   1035        if cfg!(debug_assertions) {
   1036            let mut selector_iter = self.iter_raw_parse_order_from(0);
   1037            assert!(
   1038                matches!(
   1039                    selector_iter.next().unwrap(),
   1040                    Component::RelativeSelectorAnchor
   1041                ),
   1042                "Relative selector does not start with RelativeSelectorAnchor"
   1043            );
   1044            assert!(
   1045                selector_iter.next().unwrap().is_combinator(),
   1046                "Relative combinator does not exist"
   1047            );
   1048        }
   1049 
   1050        SelectorIter {
   1051            iter: self.0.slice()[..self.len() - 2].iter(),
   1052            next_combinator: None,
   1053        }
   1054    }
   1055 
   1056    /// Returns an iterator over this selector in matching order (right-to-left),
   1057    /// skipping the rightmost |offset| Components.
   1058    #[inline]
   1059    pub fn iter_from(&self, offset: usize) -> SelectorIter<'_, Impl> {
   1060        let iter = self.0.slice()[offset..].iter();
   1061        SelectorIter {
   1062            iter,
   1063            next_combinator: None,
   1064        }
   1065    }
   1066 
   1067    /// Returns the combinator at index `index` (zero-indexed from the right),
   1068    /// or panics if the component is not a combinator.
   1069    #[inline]
   1070    pub fn combinator_at_match_order(&self, index: usize) -> Combinator {
   1071        match self.0.slice()[index] {
   1072            Component::Combinator(c) => c,
   1073            ref other => panic!(
   1074                "Not a combinator: {:?}, {:?}, index: {}",
   1075                other, self, index
   1076            ),
   1077        }
   1078    }
   1079 
   1080    /// Returns an iterator over the entire sequence of simple selectors and
   1081    /// combinators, in matching order (from right to left).
   1082    #[inline]
   1083    pub fn iter_raw_match_order(&self) -> slice::Iter<'_, Component<Impl>> {
   1084        self.0.slice().iter()
   1085    }
   1086 
   1087    /// Returns the combinator at index `index` (zero-indexed from the left),
   1088    /// or panics if the component is not a combinator.
   1089    #[inline]
   1090    pub fn combinator_at_parse_order(&self, index: usize) -> Combinator {
   1091        match self.0.slice()[self.len() - index - 1] {
   1092            Component::Combinator(c) => c,
   1093            ref other => panic!(
   1094                "Not a combinator: {:?}, {:?}, index: {}",
   1095                other, self, index
   1096            ),
   1097        }
   1098    }
   1099 
   1100    /// Returns an iterator over the sequence of simple selectors and
   1101    /// combinators, in parse order (from left to right), starting from
   1102    /// `offset`.
   1103    #[inline]
   1104    pub fn iter_raw_parse_order_from(
   1105        &self,
   1106        offset: usize,
   1107    ) -> Rev<slice::Iter<'_, Component<Impl>>> {
   1108        self.0.slice()[..self.len() - offset].iter().rev()
   1109    }
   1110 
   1111    /// Creates a Selector from a vec of Components, specified in parse order. Used in tests.
   1112    #[allow(dead_code)]
   1113    pub(crate) fn from_vec(
   1114        vec: Vec<Component<Impl>>,
   1115        specificity: u32,
   1116        flags: SelectorFlags,
   1117    ) -> Self {
   1118        let mut builder = SelectorBuilder::default();
   1119        for component in vec.into_iter() {
   1120            if let Some(combinator) = component.as_combinator() {
   1121                builder.push_combinator(combinator);
   1122            } else {
   1123                builder.push_simple_selector(component);
   1124            }
   1125        }
   1126        let spec = SpecificityAndFlags { specificity, flags };
   1127        Selector(builder.build_with_specificity_and_flags(spec, ParseRelative::No))
   1128    }
   1129 
   1130    #[inline]
   1131    fn into_data(self) -> SelectorData<Impl> {
   1132        self.0
   1133    }
   1134 
   1135    pub fn replace_parent_selector(&self, parent: &SelectorList<Impl>) -> Self {
   1136        let parent_specificity_and_flags = selector_list_specificity_and_flags(
   1137            parent.slice().iter(),
   1138            /* for_nesting_parent = */ true,
   1139        );
   1140 
   1141        let mut specificity = Specificity::from(self.specificity());
   1142        let mut flags = self.flags() - SelectorFlags::HAS_PARENT;
   1143        let forbidden_flags = SelectorFlags::forbidden_for_nesting();
   1144 
   1145        fn replace_parent_on_selector_list<Impl: SelectorImpl>(
   1146            orig: &[Selector<Impl>],
   1147            parent: &SelectorList<Impl>,
   1148            specificity: &mut Specificity,
   1149            flags: &mut SelectorFlags,
   1150            propagate_specificity: bool,
   1151            forbidden_flags: SelectorFlags,
   1152        ) -> Option<SelectorList<Impl>> {
   1153            if !orig.iter().any(|s| s.has_parent_selector()) {
   1154                return None;
   1155            }
   1156 
   1157            let result =
   1158                SelectorList::from_iter(orig.iter().map(|s| s.replace_parent_selector(parent)));
   1159 
   1160            let result_specificity_and_flags = selector_list_specificity_and_flags(
   1161                result.slice().iter(),
   1162                /* for_nesting_parent = */ false,
   1163            );
   1164            if propagate_specificity {
   1165                *specificity += Specificity::from(
   1166                    result_specificity_and_flags.specificity
   1167                        - selector_list_specificity_and_flags(
   1168                            orig.iter(),
   1169                            /* for_nesting_parent = */ false,
   1170                        )
   1171                        .specificity,
   1172                );
   1173            }
   1174            flags.insert(result_specificity_and_flags.flags - forbidden_flags);
   1175            Some(result)
   1176        }
   1177 
   1178        fn replace_parent_on_relative_selector_list<Impl: SelectorImpl>(
   1179            orig: &[RelativeSelector<Impl>],
   1180            parent: &SelectorList<Impl>,
   1181            specificity: &mut Specificity,
   1182            flags: &mut SelectorFlags,
   1183            forbidden_flags: SelectorFlags,
   1184        ) -> Vec<RelativeSelector<Impl>> {
   1185            let mut any = false;
   1186 
   1187            let result = orig
   1188                .iter()
   1189                .map(|s| {
   1190                    if !s.selector.has_parent_selector() {
   1191                        return s.clone();
   1192                    }
   1193                    any = true;
   1194                    RelativeSelector {
   1195                        match_hint: s.match_hint,
   1196                        selector: s.selector.replace_parent_selector(parent),
   1197                    }
   1198                })
   1199                .collect();
   1200 
   1201            if !any {
   1202                return result;
   1203            }
   1204 
   1205            let result_specificity_and_flags = relative_selector_list_specificity_and_flags(
   1206                &result, /* for_nesting_parent = */ false,
   1207            );
   1208            flags.insert(result_specificity_and_flags.flags - forbidden_flags);
   1209            *specificity += Specificity::from(
   1210                result_specificity_and_flags.specificity
   1211                    - relative_selector_list_specificity_and_flags(
   1212                        orig, /* for_nesting_parent = */ false,
   1213                    )
   1214                    .specificity,
   1215            );
   1216            result
   1217        }
   1218 
   1219        fn replace_parent_on_selector<Impl: SelectorImpl>(
   1220            orig: &Selector<Impl>,
   1221            parent: &SelectorList<Impl>,
   1222            specificity: &mut Specificity,
   1223            flags: &mut SelectorFlags,
   1224            forbidden_flags: SelectorFlags,
   1225        ) -> Selector<Impl> {
   1226            let new_selector = orig.replace_parent_selector(parent);
   1227            *specificity += Specificity::from(new_selector.specificity() - orig.specificity());
   1228            flags.insert(new_selector.flags() - forbidden_flags);
   1229            new_selector
   1230        }
   1231 
   1232        if !self.has_parent_selector() {
   1233            return self.clone();
   1234        }
   1235 
   1236        let iter = self.iter_raw_match_order().map(|component| {
   1237            use self::Component::*;
   1238            match *component {
   1239                LocalName(..)
   1240                | ID(..)
   1241                | Class(..)
   1242                | AttributeInNoNamespaceExists { .. }
   1243                | AttributeInNoNamespace { .. }
   1244                | AttributeOther(..)
   1245                | ExplicitUniversalType
   1246                | ExplicitAnyNamespace
   1247                | ExplicitNoNamespace
   1248                | DefaultNamespace(..)
   1249                | Namespace(..)
   1250                | Root
   1251                | Empty
   1252                | Scope
   1253                | ImplicitScope
   1254                | Nth(..)
   1255                | NonTSPseudoClass(..)
   1256                | PseudoElement(..)
   1257                | Combinator(..)
   1258                | Host(None)
   1259                | Part(..)
   1260                | Invalid(..)
   1261                | RelativeSelectorAnchor => component.clone(),
   1262                ParentSelector => {
   1263                    specificity += Specificity::from(parent_specificity_and_flags.specificity);
   1264                    flags.insert(parent_specificity_and_flags.flags - forbidden_flags);
   1265                    Is(parent.clone())
   1266                },
   1267                Negation(ref selectors) => {
   1268                    Negation(
   1269                        replace_parent_on_selector_list(
   1270                            selectors.slice(),
   1271                            parent,
   1272                            &mut specificity,
   1273                            &mut flags,
   1274                            /* propagate_specificity = */ true,
   1275                            forbidden_flags,
   1276                        )
   1277                        .unwrap_or_else(|| selectors.clone()),
   1278                    )
   1279                },
   1280                Is(ref selectors) => {
   1281                    Is(replace_parent_on_selector_list(
   1282                        selectors.slice(),
   1283                        parent,
   1284                        &mut specificity,
   1285                        &mut flags,
   1286                        /* propagate_specificity = */ true,
   1287                        forbidden_flags,
   1288                    )
   1289                    .unwrap_or_else(|| selectors.clone()))
   1290                },
   1291                Where(ref selectors) => {
   1292                    Where(
   1293                        replace_parent_on_selector_list(
   1294                            selectors.slice(),
   1295                            parent,
   1296                            &mut specificity,
   1297                            &mut flags,
   1298                            /* propagate_specificity = */ false,
   1299                            forbidden_flags,
   1300                        )
   1301                        .unwrap_or_else(|| selectors.clone()),
   1302                    )
   1303                },
   1304                Has(ref selectors) => Has(replace_parent_on_relative_selector_list(
   1305                    selectors,
   1306                    parent,
   1307                    &mut specificity,
   1308                    &mut flags,
   1309                    forbidden_flags,
   1310                )
   1311                .into_boxed_slice()),
   1312 
   1313                Host(Some(ref selector)) => Host(Some(replace_parent_on_selector(
   1314                    selector,
   1315                    parent,
   1316                    &mut specificity,
   1317                    &mut flags,
   1318                    forbidden_flags,
   1319                ))),
   1320                NthOf(ref data) => {
   1321                    let selectors = replace_parent_on_selector_list(
   1322                        data.selectors(),
   1323                        parent,
   1324                        &mut specificity,
   1325                        &mut flags,
   1326                        /* propagate_specificity = */ true,
   1327                        forbidden_flags,
   1328                    );
   1329                    NthOf(match selectors {
   1330                        Some(s) => {
   1331                            NthOfSelectorData::new(data.nth_data(), s.slice().iter().cloned())
   1332                        },
   1333                        None => data.clone(),
   1334                    })
   1335                },
   1336                Slotted(ref selector) => Slotted(replace_parent_on_selector(
   1337                    selector,
   1338                    parent,
   1339                    &mut specificity,
   1340                    &mut flags,
   1341                    forbidden_flags,
   1342                )),
   1343            }
   1344        });
   1345        let mut items = UniqueArc::from_header_and_iter(Default::default(), iter);
   1346        *items.header_mut() = SpecificityAndFlags {
   1347            specificity: specificity.into(),
   1348            flags,
   1349        };
   1350        Selector(items.shareable())
   1351    }
   1352 
   1353    /// Returns count of simple selectors and combinators in the Selector.
   1354    #[inline]
   1355    pub fn len(&self) -> usize {
   1356        self.0.len()
   1357    }
   1358 
   1359    /// Returns the address on the heap of the ThinArc for memory reporting.
   1360    pub fn thin_arc_heap_ptr(&self) -> *const ::std::os::raw::c_void {
   1361        self.0.heap_ptr()
   1362    }
   1363 
   1364    /// Traverse selector components inside `self`.
   1365    ///
   1366    /// Implementations of this method should call `SelectorVisitor` methods
   1367    /// or other impls of `Visit` as appropriate based on the fields of `Self`.
   1368    ///
   1369    /// A return value of `false` indicates terminating the traversal.
   1370    /// It should be propagated with an early return.
   1371    /// On the contrary, `true` indicates that all fields of `self` have been traversed:
   1372    ///
   1373    /// ```rust,ignore
   1374    /// if !visitor.visit_simple_selector(&self.some_simple_selector) {
   1375    ///     return false;
   1376    /// }
   1377    /// if !self.some_component.visit(visitor) {
   1378    ///     return false;
   1379    /// }
   1380    /// true
   1381    /// ```
   1382    pub fn visit<V>(&self, visitor: &mut V) -> bool
   1383    where
   1384        V: SelectorVisitor<Impl = Impl>,
   1385    {
   1386        let mut current = self.iter();
   1387        let mut combinator = None;
   1388        loop {
   1389            if !visitor.visit_complex_selector(combinator) {
   1390                return false;
   1391            }
   1392 
   1393            for selector in &mut current {
   1394                if !selector.visit(visitor) {
   1395                    return false;
   1396                }
   1397            }
   1398 
   1399            combinator = current.next_sequence();
   1400            if combinator.is_none() {
   1401                break;
   1402            }
   1403        }
   1404 
   1405        true
   1406    }
   1407 
   1408    /// Parse a selector, without any pseudo-element.
   1409    #[inline]
   1410    pub fn parse<'i, 't, P>(
   1411        parser: &P,
   1412        input: &mut CssParser<'i, 't>,
   1413    ) -> Result<Self, ParseError<'i, P::Error>>
   1414    where
   1415        P: Parser<'i, Impl = Impl>,
   1416    {
   1417        parse_selector(
   1418            parser,
   1419            input,
   1420            SelectorParsingState::empty(),
   1421            ParseRelative::No,
   1422        )
   1423    }
   1424 
   1425    pub fn new_invalid(s: &str) -> Self {
   1426        fn check_for_parent(input: &mut CssParser, has_parent: &mut bool) {
   1427            while let Ok(t) = input.next() {
   1428                match *t {
   1429                    Token::Function(_)
   1430                    | Token::ParenthesisBlock
   1431                    | Token::CurlyBracketBlock
   1432                    | Token::SquareBracketBlock => {
   1433                        let _ = input.parse_nested_block(
   1434                            |i| -> Result<(), ParseError<'_, BasicParseError>> {
   1435                                check_for_parent(i, has_parent);
   1436                                Ok(())
   1437                            },
   1438                        );
   1439                    },
   1440                    Token::Delim('&') => {
   1441                        *has_parent = true;
   1442                    },
   1443                    _ => {},
   1444                }
   1445                if *has_parent {
   1446                    break;
   1447                }
   1448            }
   1449        }
   1450        let mut has_parent = false;
   1451        {
   1452            let mut parser = cssparser::ParserInput::new(s);
   1453            let mut parser = CssParser::new(&mut parser);
   1454            check_for_parent(&mut parser, &mut has_parent);
   1455        }
   1456        Self(ThinArc::from_header_and_iter(
   1457            SpecificityAndFlags {
   1458                specificity: 0,
   1459                flags: if has_parent {
   1460                    SelectorFlags::HAS_PARENT
   1461                } else {
   1462                    SelectorFlags::empty()
   1463                },
   1464            },
   1465            std::iter::once(Component::Invalid(Arc::new(String::from(s.trim())))),
   1466        ))
   1467    }
   1468 
   1469    /// Is the compound starting at the offset the subject compound, or referring to its pseudo-element?
   1470    pub fn is_rightmost(&self, offset: usize) -> bool {
   1471        // There can really be only one pseudo-element, and it's not really valid for anything else to
   1472        // follow it.
   1473        offset == 0
   1474            || matches!(
   1475                self.combinator_at_match_order(offset - 1),
   1476                Combinator::PseudoElement
   1477            )
   1478    }
   1479 }
   1480 
   1481 #[derive(Clone)]
   1482 pub struct SelectorIter<'a, Impl: 'a + SelectorImpl> {
   1483    iter: slice::Iter<'a, Component<Impl>>,
   1484    next_combinator: Option<Combinator>,
   1485 }
   1486 
   1487 impl<'a, Impl: 'a + SelectorImpl> SelectorIter<'a, Impl> {
   1488    /// Prepares this iterator to point to the next sequence to the left,
   1489    /// returning the combinator if the sequence was found.
   1490    #[inline]
   1491    pub fn next_sequence(&mut self) -> Option<Combinator> {
   1492        self.next_combinator.take()
   1493    }
   1494 
   1495    #[inline]
   1496    pub(crate) fn matches_for_stateless_pseudo_element(&mut self) -> bool {
   1497        let first = match self.next() {
   1498            Some(c) => c,
   1499            // Note that this is the common path that we keep inline: the
   1500            // pseudo-element not having anything to its right.
   1501            None => return true,
   1502        };
   1503        self.matches_for_stateless_pseudo_element_internal(first)
   1504    }
   1505 
   1506    #[inline(never)]
   1507    fn matches_for_stateless_pseudo_element_internal(&mut self, first: &Component<Impl>) -> bool {
   1508        if !first.matches_for_stateless_pseudo_element() {
   1509            return false;
   1510        }
   1511        for component in self {
   1512            // The only other parser-allowed Components in this sequence are
   1513            // state pseudo-classes, or one of the other things that can contain
   1514            // them.
   1515            if !component.matches_for_stateless_pseudo_element() {
   1516                return false;
   1517            }
   1518        }
   1519        true
   1520    }
   1521 
   1522    /// Returns remaining count of the simple selectors and combinators in the Selector.
   1523    #[inline]
   1524    pub fn selector_length(&self) -> usize {
   1525        self.iter.len()
   1526    }
   1527 }
   1528 
   1529 impl<'a, Impl: SelectorImpl> Iterator for SelectorIter<'a, Impl> {
   1530    type Item = &'a Component<Impl>;
   1531 
   1532    #[inline]
   1533    fn next(&mut self) -> Option<Self::Item> {
   1534        debug_assert!(
   1535            self.next_combinator.is_none(),
   1536            "You should call next_sequence!"
   1537        );
   1538        match *self.iter.next()? {
   1539            Component::Combinator(c) => {
   1540                self.next_combinator = Some(c);
   1541                None
   1542            },
   1543            ref x => Some(x),
   1544        }
   1545    }
   1546 }
   1547 
   1548 impl<'a, Impl: SelectorImpl> fmt::Debug for SelectorIter<'a, Impl> {
   1549    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
   1550        let iter = self.iter.clone().rev();
   1551        for component in iter {
   1552            component.to_css(f)?
   1553        }
   1554        Ok(())
   1555    }
   1556 }
   1557 
   1558 /// An iterator over all combinators in a selector. Does not traverse selectors within psuedoclasses.
   1559 struct CombinatorIter<'a, Impl: 'a + SelectorImpl>(SelectorIter<'a, Impl>);
   1560 impl<'a, Impl: 'a + SelectorImpl> CombinatorIter<'a, Impl> {
   1561    fn new(inner: SelectorIter<'a, Impl>) -> Self {
   1562        let mut result = CombinatorIter(inner);
   1563        result.consume_non_combinators();
   1564        result
   1565    }
   1566 
   1567    fn consume_non_combinators(&mut self) {
   1568        while self.0.next().is_some() {}
   1569    }
   1570 }
   1571 
   1572 impl<'a, Impl: SelectorImpl> Iterator for CombinatorIter<'a, Impl> {
   1573    type Item = Combinator;
   1574    fn next(&mut self) -> Option<Self::Item> {
   1575        let result = self.0.next_sequence();
   1576        self.consume_non_combinators();
   1577        result
   1578    }
   1579 }
   1580 
   1581 /// An iterator over all simple selectors belonging to ancestors.
   1582 struct AncestorIter<'a, Impl: 'a + SelectorImpl>(SelectorIter<'a, Impl>);
   1583 impl<'a, Impl: 'a + SelectorImpl> AncestorIter<'a, Impl> {
   1584    /// Creates an AncestorIter. The passed-in iterator is assumed to point to
   1585    /// the beginning of the child sequence, which will be skipped.
   1586    fn new(inner: SelectorIter<'a, Impl>) -> Self {
   1587        let mut result = AncestorIter(inner);
   1588        result.skip_until_ancestor();
   1589        result
   1590    }
   1591 
   1592    /// Skips a sequence of simple selectors and all subsequent sequences until
   1593    /// a non-pseudo-element ancestor combinator is reached.
   1594    fn skip_until_ancestor(&mut self) {
   1595        loop {
   1596            while self.0.next().is_some() {}
   1597            // If this is ever changed to stop at the "pseudo-element"
   1598            // combinator, we will need to fix the way we compute hashes for
   1599            // revalidation selectors.
   1600            if self.0.next_sequence().map_or(true, |x| {
   1601                matches!(x, Combinator::Child | Combinator::Descendant)
   1602            }) {
   1603                break;
   1604            }
   1605        }
   1606    }
   1607 }
   1608 
   1609 impl<'a, Impl: SelectorImpl> Iterator for AncestorIter<'a, Impl> {
   1610    type Item = &'a Component<Impl>;
   1611    fn next(&mut self) -> Option<Self::Item> {
   1612        // Grab the next simple selector in the sequence if available.
   1613        let next = self.0.next();
   1614        if next.is_some() {
   1615            return next;
   1616        }
   1617 
   1618        // See if there are more sequences. If so, skip any non-ancestor sequences.
   1619        if let Some(combinator) = self.0.next_sequence() {
   1620            if !matches!(combinator, Combinator::Child | Combinator::Descendant) {
   1621                self.skip_until_ancestor();
   1622            }
   1623        }
   1624 
   1625        self.0.next()
   1626    }
   1627 }
   1628 
   1629 #[derive(Clone, Copy, Debug, Eq, PartialEq)]
   1630 #[cfg_attr(feature = "to_shmem", derive(ToShmem))]
   1631 pub enum Combinator {
   1632    Child,        //  >
   1633    Descendant,   // space
   1634    NextSibling,  // +
   1635    LaterSibling, // ~
   1636    /// A dummy combinator we use to the left of pseudo-elements.
   1637    ///
   1638    /// It serializes as the empty string, and acts effectively as a child
   1639    /// combinator in most cases.  If we ever actually start using a child
   1640    /// combinator for this, we will need to fix up the way hashes are computed
   1641    /// for revalidation selectors.
   1642    PseudoElement,
   1643    /// Another combinator used for ::slotted(), which represent the jump from
   1644    /// a node to its assigned slot.
   1645    SlotAssignment,
   1646    /// Another combinator used for `::part()`, which represents the jump from
   1647    /// the part to the containing shadow host.
   1648    Part,
   1649 }
   1650 
   1651 impl Combinator {
   1652    /// Returns true if this combinator is a child or descendant combinator.
   1653    #[inline]
   1654    pub fn is_ancestor(&self) -> bool {
   1655        matches!(
   1656            *self,
   1657            Combinator::Child
   1658                | Combinator::Descendant
   1659                | Combinator::PseudoElement
   1660                | Combinator::SlotAssignment
   1661        )
   1662    }
   1663 
   1664    /// Returns true if this combinator is a pseudo-element combinator.
   1665    #[inline]
   1666    pub fn is_pseudo_element(&self) -> bool {
   1667        matches!(*self, Combinator::PseudoElement)
   1668    }
   1669 
   1670    /// Returns true if this combinator is a next- or later-sibling combinator.
   1671    #[inline]
   1672    pub fn is_sibling(&self) -> bool {
   1673        matches!(*self, Combinator::NextSibling | Combinator::LaterSibling)
   1674    }
   1675 }
   1676 
   1677 /// An enum for the different types of :nth- pseudoclasses
   1678 #[derive(Copy, Clone, Eq, PartialEq)]
   1679 #[cfg_attr(feature = "to_shmem", derive(ToShmem))]
   1680 #[cfg_attr(feature = "to_shmem", shmem(no_bounds))]
   1681 pub enum NthType {
   1682    Child,
   1683    LastChild,
   1684    OnlyChild,
   1685    OfType,
   1686    LastOfType,
   1687    OnlyOfType,
   1688 }
   1689 
   1690 impl NthType {
   1691    pub fn is_only(self) -> bool {
   1692        self == Self::OnlyChild || self == Self::OnlyOfType
   1693    }
   1694 
   1695    pub fn is_of_type(self) -> bool {
   1696        self == Self::OfType || self == Self::LastOfType || self == Self::OnlyOfType
   1697    }
   1698 
   1699    pub fn is_from_end(self) -> bool {
   1700        self == Self::LastChild || self == Self::LastOfType
   1701    }
   1702 }
   1703 
   1704 /// The properties that comprise an An+B syntax
   1705 #[derive(Copy, Clone, Eq, PartialEq, Debug)]
   1706 #[cfg_attr(feature = "to_shmem", derive(ToShmem))]
   1707 #[cfg_attr(feature = "to_shmem", shmem(no_bounds))]
   1708 pub struct AnPlusB(pub i32, pub i32);
   1709 
   1710 impl AnPlusB {
   1711    #[inline]
   1712    pub fn matches_index(&self, i: i32) -> bool {
   1713        // Is there a non-negative integer n such that An+B=i?
   1714        match i.checked_sub(self.1) {
   1715            None => false,
   1716            Some(an) => match an.checked_div(self.0) {
   1717                Some(n) => n >= 0 && self.0 * n == an,
   1718                None /* a == 0 */ => an == 0,
   1719            },
   1720        }
   1721    }
   1722 }
   1723 
   1724 impl ToCss for AnPlusB {
   1725    /// Serialize <an+b> (part of the CSS Syntax spec).
   1726    /// <https://drafts.csswg.org/css-syntax-3/#serialize-an-anb-value>
   1727    #[inline]
   1728    fn to_css<W>(&self, dest: &mut W) -> fmt::Result
   1729    where
   1730        W: fmt::Write,
   1731    {
   1732        match (self.0, self.1) {
   1733            (0, 0) => dest.write_char('0'),
   1734 
   1735            (1, 0) => dest.write_char('n'),
   1736            (-1, 0) => dest.write_str("-n"),
   1737            (_, 0) => write!(dest, "{}n", self.0),
   1738 
   1739            (0, _) => write!(dest, "{}", self.1),
   1740            (1, _) => write!(dest, "n{:+}", self.1),
   1741            (-1, _) => write!(dest, "-n{:+}", self.1),
   1742            (_, _) => write!(dest, "{}n{:+}", self.0, self.1),
   1743        }
   1744    }
   1745 }
   1746 
   1747 /// The properties that comprise an :nth- pseudoclass as of Selectors 3 (e.g.,
   1748 /// nth-child(An+B)).
   1749 /// https://www.w3.org/TR/selectors-3/#nth-child-pseudo
   1750 #[derive(Copy, Clone, Eq, PartialEq)]
   1751 #[cfg_attr(feature = "to_shmem", derive(ToShmem))]
   1752 #[cfg_attr(feature = "to_shmem", shmem(no_bounds))]
   1753 pub struct NthSelectorData {
   1754    pub ty: NthType,
   1755    pub is_function: bool,
   1756    pub an_plus_b: AnPlusB,
   1757 }
   1758 
   1759 impl NthSelectorData {
   1760    /// Returns selector data for :only-{child,of-type}
   1761    #[inline]
   1762    pub const fn only(of_type: bool) -> Self {
   1763        Self {
   1764            ty: if of_type {
   1765                NthType::OnlyOfType
   1766            } else {
   1767                NthType::OnlyChild
   1768            },
   1769            is_function: false,
   1770            an_plus_b: AnPlusB(0, 1),
   1771        }
   1772    }
   1773 
   1774    /// Returns selector data for :first-{child,of-type}
   1775    #[inline]
   1776    pub const fn first(of_type: bool) -> Self {
   1777        Self {
   1778            ty: if of_type {
   1779                NthType::OfType
   1780            } else {
   1781                NthType::Child
   1782            },
   1783            is_function: false,
   1784            an_plus_b: AnPlusB(0, 1),
   1785        }
   1786    }
   1787 
   1788    /// Returns selector data for :last-{child,of-type}
   1789    #[inline]
   1790    pub const fn last(of_type: bool) -> Self {
   1791        Self {
   1792            ty: if of_type {
   1793                NthType::LastOfType
   1794            } else {
   1795                NthType::LastChild
   1796            },
   1797            is_function: false,
   1798            an_plus_b: AnPlusB(0, 1),
   1799        }
   1800    }
   1801 
   1802    /// Returns true if this is an edge selector that is not `:*-of-type``
   1803    #[inline]
   1804    pub fn is_simple_edge(&self) -> bool {
   1805        self.an_plus_b.0 == 0
   1806            && self.an_plus_b.1 == 1
   1807            && !self.ty.is_of_type()
   1808            && !self.ty.is_only()
   1809    }
   1810 
   1811    /// Writes the beginning of the selector.
   1812    #[inline]
   1813    fn write_start<W: fmt::Write>(&self, dest: &mut W) -> fmt::Result {
   1814        dest.write_str(match self.ty {
   1815            NthType::Child if self.is_function => ":nth-child(",
   1816            NthType::Child => ":first-child",
   1817            NthType::LastChild if self.is_function => ":nth-last-child(",
   1818            NthType::LastChild => ":last-child",
   1819            NthType::OfType if self.is_function => ":nth-of-type(",
   1820            NthType::OfType => ":first-of-type",
   1821            NthType::LastOfType if self.is_function => ":nth-last-of-type(",
   1822            NthType::LastOfType => ":last-of-type",
   1823            NthType::OnlyChild => ":only-child",
   1824            NthType::OnlyOfType => ":only-of-type",
   1825        })
   1826    }
   1827 
   1828    #[inline]
   1829    fn write_affine<W: fmt::Write>(&self, dest: &mut W) -> fmt::Result {
   1830        self.an_plus_b.to_css(dest)
   1831    }
   1832 }
   1833 
   1834 /// The properties that comprise an :nth- pseudoclass as of Selectors 4 (e.g.,
   1835 /// nth-child(An+B [of S]?)).
   1836 /// https://www.w3.org/TR/selectors-4/#nth-child-pseudo
   1837 #[derive(Clone, Eq, PartialEq)]
   1838 #[cfg_attr(feature = "to_shmem", derive(ToShmem))]
   1839 #[cfg_attr(feature = "to_shmem", shmem(no_bounds))]
   1840 pub struct NthOfSelectorData<Impl: SelectorImpl>(
   1841    #[cfg_attr(feature = "to_shmem", shmem(field_bound))] ThinArc<NthSelectorData, Selector<Impl>>,
   1842 );
   1843 
   1844 impl<Impl: SelectorImpl> NthOfSelectorData<Impl> {
   1845    /// Returns selector data for :nth-{,last-}{child,of-type}(An+B [of S])
   1846    #[inline]
   1847    pub fn new<I>(nth_data: &NthSelectorData, selectors: I) -> Self
   1848    where
   1849        I: Iterator<Item = Selector<Impl>> + ExactSizeIterator,
   1850    {
   1851        Self(ThinArc::from_header_and_iter(*nth_data, selectors))
   1852    }
   1853 
   1854    /// Returns the An+B part of the selector
   1855    #[inline]
   1856    pub fn nth_data(&self) -> &NthSelectorData {
   1857        &self.0.header
   1858    }
   1859 
   1860    /// Returns the selector list part of the selector
   1861    #[inline]
   1862    pub fn selectors(&self) -> &[Selector<Impl>] {
   1863        self.0.slice()
   1864    }
   1865 }
   1866 
   1867 /// Flag indicating where a given relative selector's match would be contained.
   1868 #[derive(Clone, Copy, Eq, PartialEq)]
   1869 #[cfg_attr(feature = "to_shmem", derive(ToShmem))]
   1870 pub enum RelativeSelectorMatchHint {
   1871    /// Within this element's subtree.
   1872    InSubtree,
   1873    /// Within this element's direct children.
   1874    InChild,
   1875    /// This element's next sibling.
   1876    InNextSibling,
   1877    /// Within this element's next sibling's subtree.
   1878    InNextSiblingSubtree,
   1879    /// Within this element's subsequent siblings.
   1880    InSibling,
   1881    /// Across this element's subsequent siblings and their subtrees.
   1882    InSiblingSubtree,
   1883 }
   1884 
   1885 impl RelativeSelectorMatchHint {
   1886    /// Create a new relative selector match hint based on its composition.
   1887    pub fn new(
   1888        relative_combinator: Combinator,
   1889        has_child_or_descendants: bool,
   1890        has_adjacent_or_next_siblings: bool,
   1891    ) -> Self {
   1892        match relative_combinator {
   1893            Combinator::Descendant => RelativeSelectorMatchHint::InSubtree,
   1894            Combinator::Child => {
   1895                if !has_child_or_descendants {
   1896                    RelativeSelectorMatchHint::InChild
   1897                } else {
   1898                    // Technically, for any composition that consists of child combinators only,
   1899                    // the search space is depth-constrained, but it's probably not worth optimizing for.
   1900                    RelativeSelectorMatchHint::InSubtree
   1901                }
   1902            },
   1903            Combinator::NextSibling => {
   1904                if !has_child_or_descendants && !has_adjacent_or_next_siblings {
   1905                    RelativeSelectorMatchHint::InNextSibling
   1906                } else if !has_child_or_descendants && has_adjacent_or_next_siblings {
   1907                    RelativeSelectorMatchHint::InSibling
   1908                } else if has_child_or_descendants && !has_adjacent_or_next_siblings {
   1909                    // Match won't cross multiple siblings.
   1910                    RelativeSelectorMatchHint::InNextSiblingSubtree
   1911                } else {
   1912                    RelativeSelectorMatchHint::InSiblingSubtree
   1913                }
   1914            },
   1915            Combinator::LaterSibling => {
   1916                if !has_child_or_descendants {
   1917                    RelativeSelectorMatchHint::InSibling
   1918                } else {
   1919                    // Even if the match may not cross multiple siblings, we have to look until
   1920                    // we find a match anyway.
   1921                    RelativeSelectorMatchHint::InSiblingSubtree
   1922                }
   1923            },
   1924            Combinator::Part | Combinator::PseudoElement | Combinator::SlotAssignment => {
   1925                debug_assert!(false, "Unexpected relative combinator");
   1926                RelativeSelectorMatchHint::InSubtree
   1927            },
   1928        }
   1929    }
   1930 
   1931    /// Is the match traversal direction towards the descendant of this element (As opposed to siblings)?
   1932    pub fn is_descendant_direction(&self) -> bool {
   1933        matches!(*self, Self::InChild | Self::InSubtree)
   1934    }
   1935 
   1936    /// Is the match traversal terminated at the next sibling?
   1937    pub fn is_next_sibling(&self) -> bool {
   1938        matches!(*self, Self::InNextSibling | Self::InNextSiblingSubtree)
   1939    }
   1940 
   1941    /// Does the match involve matching the subtree?
   1942    pub fn is_subtree(&self) -> bool {
   1943        matches!(
   1944            *self,
   1945            Self::InSubtree | Self::InSiblingSubtree | Self::InNextSiblingSubtree
   1946        )
   1947    }
   1948 }
   1949 
   1950 /// Count of combinators in a given relative selector, not traversing selectors of pseudoclasses.
   1951 #[derive(Clone, Copy)]
   1952 pub struct RelativeSelectorCombinatorCount {
   1953    relative_combinator: Combinator,
   1954    pub child_or_descendants: usize,
   1955    pub adjacent_or_next_siblings: usize,
   1956 }
   1957 
   1958 impl RelativeSelectorCombinatorCount {
   1959    /// Create a new relative selector combinator count from a given relative selector.
   1960    pub fn new<Impl: SelectorImpl>(relative_selector: &RelativeSelector<Impl>) -> Self {
   1961        let mut result = RelativeSelectorCombinatorCount {
   1962            relative_combinator: relative_selector.selector.combinator_at_parse_order(1),
   1963            child_or_descendants: 0,
   1964            adjacent_or_next_siblings: 0,
   1965        };
   1966 
   1967        for combinator in CombinatorIter::new(
   1968            relative_selector
   1969                .selector
   1970                .iter_skip_relative_selector_anchor(),
   1971        ) {
   1972            match combinator {
   1973                Combinator::Descendant | Combinator::Child => {
   1974                    result.child_or_descendants += 1;
   1975                },
   1976                Combinator::NextSibling | Combinator::LaterSibling => {
   1977                    result.adjacent_or_next_siblings += 1;
   1978                },
   1979                Combinator::Part | Combinator::PseudoElement | Combinator::SlotAssignment => {
   1980                    continue
   1981                },
   1982            };
   1983        }
   1984        result
   1985    }
   1986 
   1987    /// Get the match hint based on the current combinator count.
   1988    pub fn get_match_hint(&self) -> RelativeSelectorMatchHint {
   1989        RelativeSelectorMatchHint::new(
   1990            self.relative_combinator,
   1991            self.child_or_descendants != 0,
   1992            self.adjacent_or_next_siblings != 0,
   1993        )
   1994    }
   1995 }
   1996 
   1997 /// Storage for a relative selector.
   1998 #[derive(Clone, Eq, PartialEq)]
   1999 #[cfg_attr(feature = "to_shmem", derive(ToShmem))]
   2000 #[cfg_attr(feature = "to_shmem", shmem(no_bounds))]
   2001 pub struct RelativeSelector<Impl: SelectorImpl> {
   2002    /// Match space constraining hint.
   2003    pub match_hint: RelativeSelectorMatchHint,
   2004    /// The selector. Guaranteed to contain `RelativeSelectorAnchor` and the relative combinator in parse order.
   2005    #[cfg_attr(feature = "to_shmem", shmem(field_bound))]
   2006    pub selector: Selector<Impl>,
   2007 }
   2008 
   2009 bitflags! {
   2010    /// Composition of combinators in a given selector, not traversing selectors of pseudoclasses.
   2011    #[derive(Clone, Debug, Eq, PartialEq)]
   2012    struct CombinatorComposition: u8 {
   2013        const DESCENDANTS = 1 << 0;
   2014        const SIBLINGS = 1 << 1;
   2015    }
   2016 }
   2017 
   2018 impl CombinatorComposition {
   2019    fn for_relative_selector<Impl: SelectorImpl>(inner_selector: &Selector<Impl>) -> Self {
   2020        let mut result = CombinatorComposition::empty();
   2021        for combinator in CombinatorIter::new(inner_selector.iter_skip_relative_selector_anchor()) {
   2022            match combinator {
   2023                Combinator::Descendant | Combinator::Child => {
   2024                    result.insert(Self::DESCENDANTS);
   2025                },
   2026                Combinator::NextSibling | Combinator::LaterSibling => {
   2027                    result.insert(Self::SIBLINGS);
   2028                },
   2029                Combinator::Part | Combinator::PseudoElement | Combinator::SlotAssignment => {
   2030                    continue
   2031                },
   2032            };
   2033            if result.is_all() {
   2034                break;
   2035            }
   2036        }
   2037        return result;
   2038    }
   2039 }
   2040 
   2041 impl<Impl: SelectorImpl> RelativeSelector<Impl> {
   2042    fn from_selector_list(selector_list: SelectorList<Impl>) -> Box<[Self]> {
   2043        selector_list
   2044            .slice()
   2045            .iter()
   2046            .map(|selector| {
   2047                // It's more efficient to keep track of all this during the parse time, but that seems like a lot of special
   2048                // case handling for what it's worth.
   2049                if cfg!(debug_assertions) {
   2050                    let relative_selector_anchor = selector.iter_raw_parse_order_from(0).next();
   2051                    debug_assert!(
   2052                        relative_selector_anchor.is_some(),
   2053                        "Relative selector is empty"
   2054                    );
   2055                    debug_assert!(
   2056                        matches!(
   2057                            relative_selector_anchor.unwrap(),
   2058                            Component::RelativeSelectorAnchor
   2059                        ),
   2060                        "Relative selector anchor is missing"
   2061                    );
   2062                }
   2063                // Leave a hint for narrowing down the search space when we're matching.
   2064                let composition = CombinatorComposition::for_relative_selector(&selector);
   2065                let match_hint = RelativeSelectorMatchHint::new(
   2066                    selector.combinator_at_parse_order(1),
   2067                    composition.intersects(CombinatorComposition::DESCENDANTS),
   2068                    composition.intersects(CombinatorComposition::SIBLINGS),
   2069                );
   2070                RelativeSelector {
   2071                    match_hint,
   2072                    selector: selector.clone(),
   2073                }
   2074            })
   2075            .collect()
   2076    }
   2077 }
   2078 
   2079 /// A CSS simple selector or combinator. We store both in the same enum for
   2080 /// optimal packing and cache performance, see [1].
   2081 ///
   2082 /// [1] https://bugzilla.mozilla.org/show_bug.cgi?id=1357973
   2083 #[derive(Clone, Eq, PartialEq)]
   2084 #[cfg_attr(feature = "to_shmem", derive(ToShmem))]
   2085 #[cfg_attr(feature = "to_shmem", shmem(no_bounds))]
   2086 pub enum Component<Impl: SelectorImpl> {
   2087    LocalName(LocalName<Impl>),
   2088 
   2089    ID(#[cfg_attr(feature = "to_shmem", shmem(field_bound))] Impl::Identifier),
   2090    Class(#[cfg_attr(feature = "to_shmem", shmem(field_bound))] Impl::Identifier),
   2091 
   2092    AttributeInNoNamespaceExists {
   2093        #[cfg_attr(feature = "to_shmem", shmem(field_bound))]
   2094        local_name: Impl::LocalName,
   2095        local_name_lower: Impl::LocalName,
   2096    },
   2097    // Used only when local_name is already lowercase.
   2098    AttributeInNoNamespace {
   2099        local_name: Impl::LocalName,
   2100        operator: AttrSelectorOperator,
   2101        #[cfg_attr(feature = "to_shmem", shmem(field_bound))]
   2102        value: Impl::AttrValue,
   2103        case_sensitivity: ParsedCaseSensitivity,
   2104    },
   2105    // Use a Box in the less common cases with more data to keep size_of::<Component>() small.
   2106    AttributeOther(Box<AttrSelectorWithOptionalNamespace<Impl>>),
   2107 
   2108    ExplicitUniversalType,
   2109    ExplicitAnyNamespace,
   2110 
   2111    ExplicitNoNamespace,
   2112    DefaultNamespace(#[cfg_attr(feature = "to_shmem", shmem(field_bound))] Impl::NamespaceUrl),
   2113    Namespace(
   2114        #[cfg_attr(feature = "to_shmem", shmem(field_bound))] Impl::NamespacePrefix,
   2115        #[cfg_attr(feature = "to_shmem", shmem(field_bound))] Impl::NamespaceUrl,
   2116    ),
   2117 
   2118    /// Pseudo-classes
   2119    Negation(SelectorList<Impl>),
   2120    Root,
   2121    Empty,
   2122    Scope,
   2123    /// :scope added implicitly into scoped rules (i.e. In `@scope`) not
   2124    /// explicitly using `:scope` or `&` selectors.
   2125    ///
   2126    /// https://drafts.csswg.org/css-cascade-6/#scoped-rules
   2127    ///
   2128    /// Unlike the normal `:scope` selector, this does not add any specificity.
   2129    /// See https://github.com/w3c/csswg-drafts/issues/10196
   2130    ImplicitScope,
   2131    ParentSelector,
   2132    Nth(NthSelectorData),
   2133    NthOf(NthOfSelectorData<Impl>),
   2134    NonTSPseudoClass(#[cfg_attr(feature = "to_shmem", shmem(field_bound))] Impl::NonTSPseudoClass),
   2135    /// The ::slotted() pseudo-element:
   2136    ///
   2137    /// https://drafts.csswg.org/css-scoping/#slotted-pseudo
   2138    ///
   2139    /// The selector here is a compound selector, that is, no combinators.
   2140    ///
   2141    /// NOTE(emilio): This should support a list of selectors, but as of this
   2142    /// writing no other browser does, and that allows them to put ::slotted()
   2143    /// in the rule hash, so we do that too.
   2144    ///
   2145    /// See https://github.com/w3c/csswg-drafts/issues/2158
   2146    Slotted(Selector<Impl>),
   2147    /// The `::part` pseudo-element.
   2148    ///   https://drafts.csswg.org/css-shadow-parts/#part
   2149    Part(#[cfg_attr(feature = "to_shmem", shmem(field_bound))] Box<[Impl::Identifier]>),
   2150    /// The `:host` pseudo-class:
   2151    ///
   2152    /// https://drafts.csswg.org/css-scoping/#host-selector
   2153    ///
   2154    /// NOTE(emilio): This should support a list of selectors, but as of this
   2155    /// writing no other browser does, and that allows them to put :host()
   2156    /// in the rule hash, so we do that too.
   2157    ///
   2158    /// See https://github.com/w3c/csswg-drafts/issues/2158
   2159    Host(Option<Selector<Impl>>),
   2160    /// The `:where` pseudo-class.
   2161    ///
   2162    /// https://drafts.csswg.org/selectors/#zero-matches
   2163    ///
   2164    /// The inner argument is conceptually a SelectorList, but we move the
   2165    /// selectors to the heap to keep Component small.
   2166    Where(SelectorList<Impl>),
   2167    /// The `:is` pseudo-class.
   2168    ///
   2169    /// https://drafts.csswg.org/selectors/#matches-pseudo
   2170    ///
   2171    /// Same comment as above re. the argument.
   2172    Is(SelectorList<Impl>),
   2173    /// The `:has` pseudo-class.
   2174    ///
   2175    /// https://drafts.csswg.org/selectors/#has-pseudo
   2176    ///
   2177    /// Same comment as above re. the argument.
   2178    Has(Box<[RelativeSelector<Impl>]>),
   2179    /// An invalid selector inside :is() / :where().
   2180    Invalid(Arc<String>),
   2181    /// An implementation-dependent pseudo-element selector.
   2182    PseudoElement(#[cfg_attr(feature = "to_shmem", shmem(field_bound))] Impl::PseudoElement),
   2183 
   2184    Combinator(Combinator),
   2185 
   2186    /// Used only for relative selectors, which starts with a combinator
   2187    /// (With an implied descendant combinator if not specified).
   2188    ///
   2189    /// https://drafts.csswg.org/selectors-4/#typedef-relative-selector
   2190    RelativeSelectorAnchor,
   2191 }
   2192 
   2193 impl<Impl: SelectorImpl> Component<Impl> {
   2194    /// Returns true if this is a combinator.
   2195    #[inline]
   2196    pub fn is_combinator(&self) -> bool {
   2197        matches!(*self, Component::Combinator(_))
   2198    }
   2199 
   2200    /// Returns true if this is a :host() selector.
   2201    #[inline]
   2202    pub fn is_host(&self) -> bool {
   2203        matches!(*self, Component::Host(..))
   2204    }
   2205 
   2206    /// Returns the value as a combinator if applicable, None otherwise.
   2207    pub fn as_combinator(&self) -> Option<Combinator> {
   2208        match *self {
   2209            Component::Combinator(c) => Some(c),
   2210            _ => None,
   2211        }
   2212    }
   2213 
   2214    /// Whether a given selector (to the right of a pseudo-element) should match for stateless
   2215    /// pseudo-elements. Note that generally nothing matches for those, but since we have :not(),
   2216    /// we still need to traverse nested selector lists.
   2217    fn matches_for_stateless_pseudo_element(&self) -> bool {
   2218        match *self {
   2219            Component::Negation(ref selectors) => !selectors.slice().iter().all(|selector| {
   2220                selector
   2221                    .iter_raw_match_order()
   2222                    .all(|c| c.matches_for_stateless_pseudo_element())
   2223            }),
   2224            Component::Is(ref selectors) | Component::Where(ref selectors) => {
   2225                selectors.slice().iter().any(|selector| {
   2226                    selector
   2227                        .iter_raw_match_order()
   2228                        .all(|c| c.matches_for_stateless_pseudo_element())
   2229                })
   2230            },
   2231            _ => false,
   2232        }
   2233    }
   2234 
   2235    pub fn visit<V>(&self, visitor: &mut V) -> bool
   2236    where
   2237        V: SelectorVisitor<Impl = Impl>,
   2238    {
   2239        use self::Component::*;
   2240        if !visitor.visit_simple_selector(self) {
   2241            return false;
   2242        }
   2243 
   2244        match *self {
   2245            Slotted(ref selector) => {
   2246                if !selector.visit(visitor) {
   2247                    return false;
   2248                }
   2249            },
   2250            Host(Some(ref selector)) => {
   2251                if !selector.visit(visitor) {
   2252                    return false;
   2253                }
   2254            },
   2255            AttributeInNoNamespaceExists {
   2256                ref local_name,
   2257                ref local_name_lower,
   2258            } => {
   2259                if !visitor.visit_attribute_selector(
   2260                    &NamespaceConstraint::Specific(&namespace_empty_string::<Impl>()),
   2261                    local_name,
   2262                    local_name_lower,
   2263                ) {
   2264                    return false;
   2265                }
   2266            },
   2267            AttributeInNoNamespace { ref local_name, .. } => {
   2268                if !visitor.visit_attribute_selector(
   2269                    &NamespaceConstraint::Specific(&namespace_empty_string::<Impl>()),
   2270                    local_name,
   2271                    local_name,
   2272                ) {
   2273                    return false;
   2274                }
   2275            },
   2276            AttributeOther(ref attr_selector) => {
   2277                let empty_string;
   2278                let namespace = match attr_selector.namespace() {
   2279                    Some(ns) => ns,
   2280                    None => {
   2281                        empty_string = crate::parser::namespace_empty_string::<Impl>();
   2282                        NamespaceConstraint::Specific(&empty_string)
   2283                    },
   2284                };
   2285                if !visitor.visit_attribute_selector(
   2286                    &namespace,
   2287                    &attr_selector.local_name,
   2288                    &attr_selector.local_name_lower,
   2289                ) {
   2290                    return false;
   2291                }
   2292            },
   2293 
   2294            NonTSPseudoClass(ref pseudo_class) => {
   2295                if !pseudo_class.visit(visitor) {
   2296                    return false;
   2297                }
   2298            },
   2299            Negation(ref list) | Is(ref list) | Where(ref list) => {
   2300                let list_kind = SelectorListKind::from_component(self);
   2301                debug_assert!(!list_kind.is_empty());
   2302                if !visitor.visit_selector_list(list_kind, list.slice()) {
   2303                    return false;
   2304                }
   2305            },
   2306            NthOf(ref nth_of_data) => {
   2307                if !visitor.visit_selector_list(SelectorListKind::NTH_OF, nth_of_data.selectors()) {
   2308                    return false;
   2309                }
   2310            },
   2311            Has(ref list) => {
   2312                if !visitor.visit_relative_selector_list(list) {
   2313                    return false;
   2314                }
   2315            },
   2316            _ => {},
   2317        }
   2318 
   2319        true
   2320    }
   2321 
   2322    // Returns true if this has any selector that requires an index calculation. e.g.
   2323    // :nth-child, :first-child, etc. For nested selectors, return true only if the
   2324    // indexed selector is in its subject compound.
   2325    pub fn has_indexed_selector_in_subject(&self) -> bool {
   2326        match *self {
   2327            Component::NthOf(..) | Component::Nth(..) => return true,
   2328            Component::Is(ref selectors)
   2329            | Component::Where(ref selectors)
   2330            | Component::Negation(ref selectors) => {
   2331                // Check the subject compound.
   2332                for selector in selectors.slice() {
   2333                    let mut iter = selector.iter();
   2334                    while let Some(c) = iter.next() {
   2335                        if c.has_indexed_selector_in_subject() {
   2336                            return true;
   2337                        }
   2338                    }
   2339                }
   2340            },
   2341            _ => (),
   2342        };
   2343        false
   2344    }
   2345 }
   2346 
   2347 #[derive(Clone, Eq, PartialEq)]
   2348 #[cfg_attr(feature = "to_shmem", derive(ToShmem))]
   2349 #[cfg_attr(feature = "to_shmem", shmem(no_bounds))]
   2350 pub struct LocalName<Impl: SelectorImpl> {
   2351    #[cfg_attr(feature = "to_shmem", shmem(field_bound))]
   2352    pub name: Impl::LocalName,
   2353    pub lower_name: Impl::LocalName,
   2354 }
   2355 
   2356 impl<Impl: SelectorImpl> Debug for Selector<Impl> {
   2357    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
   2358        f.write_str("Selector(")?;
   2359        self.to_css(f)?;
   2360        write!(
   2361            f,
   2362            ", specificity = {:#x}, flags = {:?})",
   2363            self.specificity(),
   2364            self.flags()
   2365        )
   2366    }
   2367 }
   2368 
   2369 impl<Impl: SelectorImpl> Debug for Component<Impl> {
   2370    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
   2371        self.to_css(f)
   2372    }
   2373 }
   2374 impl<Impl: SelectorImpl> Debug for AttrSelectorWithOptionalNamespace<Impl> {
   2375    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
   2376        self.to_css(f)
   2377    }
   2378 }
   2379 impl<Impl: SelectorImpl> Debug for LocalName<Impl> {
   2380    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
   2381        self.to_css(f)
   2382    }
   2383 }
   2384 
   2385 fn serialize_selector_list<'a, Impl, I, W>(iter: I, dest: &mut W) -> fmt::Result
   2386 where
   2387    Impl: SelectorImpl,
   2388    I: Iterator<Item = &'a Selector<Impl>>,
   2389    W: fmt::Write,
   2390 {
   2391    let mut first = true;
   2392    for selector in iter {
   2393        if !first {
   2394            dest.write_str(", ")?;
   2395        }
   2396        first = false;
   2397        selector.to_css(dest)?;
   2398    }
   2399    Ok(())
   2400 }
   2401 
   2402 impl<Impl: SelectorImpl> ToCss for SelectorList<Impl> {
   2403    fn to_css<W>(&self, dest: &mut W) -> fmt::Result
   2404    where
   2405        W: fmt::Write,
   2406    {
   2407        serialize_selector_list(self.slice().iter(), dest)
   2408    }
   2409 }
   2410 
   2411 impl<Impl: SelectorImpl> ToCss for Selector<Impl> {
   2412    fn to_css<W>(&self, dest: &mut W) -> fmt::Result
   2413    where
   2414        W: fmt::Write,
   2415    {
   2416        // Compound selectors invert the order of their contents, so we need to
   2417        // undo that during serialization.
   2418        //
   2419        // This two-iterator strategy involves walking over the selector twice.
   2420        // We could do something more clever, but selector serialization probably
   2421        // isn't hot enough to justify it, and the stringification likely
   2422        // dominates anyway.
   2423        //
   2424        // NB: A parse-order iterator is a Rev<>, which doesn't expose as_slice(),
   2425        // which we need for |split|. So we split by combinators on a match-order
   2426        // sequence and then reverse.
   2427 
   2428        let mut combinators = self
   2429            .iter_raw_match_order()
   2430            .rev()
   2431            .filter_map(|x| x.as_combinator());
   2432        let compound_selectors = self
   2433            .iter_raw_match_order()
   2434            .as_slice()
   2435            .split(|x| x.is_combinator())
   2436            .rev();
   2437 
   2438        let mut combinators_exhausted = false;
   2439        for compound in compound_selectors {
   2440            debug_assert!(!combinators_exhausted);
   2441 
   2442            // https://drafts.csswg.org/cssom/#serializing-selectors
   2443            let first_compound = match compound.first() {
   2444                None => continue,
   2445                Some(c) => c,
   2446            };
   2447            if matches!(
   2448                first_compound,
   2449                Component::RelativeSelectorAnchor | Component::ImplicitScope
   2450            ) {
   2451                debug_assert!(
   2452                    compound.len() == 1,
   2453                    "RelativeSelectorAnchor/ImplicitScope should only be a simple selector"
   2454                );
   2455                if let Some(c) = combinators.next() {
   2456                    c.to_css_relative(dest)?;
   2457                } else {
   2458                    // Direct property declarations in `@scope` does not have
   2459                    // combinators, since its selector is `:implicit-scope`.
   2460                    debug_assert!(
   2461                        matches!(first_compound, Component::ImplicitScope),
   2462                        "Only implicit :scope may not have any combinator"
   2463                    );
   2464                }
   2465                continue;
   2466            }
   2467 
   2468            // 1. If there is only one simple selector in the compound selectors
   2469            //    which is a universal selector, append the result of
   2470            //    serializing the universal selector to s.
   2471            //
   2472            // Check if `!compound.empty()` first--this can happen if we have
   2473            // something like `... > ::before`, because we store `>` and `::`
   2474            // both as combinators internally.
   2475            //
   2476            // If we are in this case, after we have serialized the universal
   2477            // selector, we skip Step 2 and continue with the algorithm.
   2478            let (can_elide_namespace, first_non_namespace) = match compound[0] {
   2479                Component::ExplicitAnyNamespace
   2480                | Component::ExplicitNoNamespace
   2481                | Component::Namespace(..) => (false, 1),
   2482                Component::DefaultNamespace(..) => (true, 1),
   2483                _ => (true, 0),
   2484            };
   2485            let mut perform_step_2 = true;
   2486            let next_combinator = combinators.next();
   2487            if first_non_namespace == compound.len() - 1 {
   2488                match (next_combinator, &compound[first_non_namespace]) {
   2489                    // We have to be careful here, because if there is a
   2490                    // pseudo element "combinator" there isn't really just
   2491                    // the one simple selector. Technically this compound
   2492                    // selector contains the pseudo element selector as well
   2493                    // -- Combinator::PseudoElement, just like
   2494                    // Combinator::SlotAssignment, don't exist in the
   2495                    // spec.
   2496                    (Some(Combinator::PseudoElement), _)
   2497                    | (Some(Combinator::SlotAssignment), _) => (),
   2498                    (_, &Component::ExplicitUniversalType) => {
   2499                        // Iterate over everything so we serialize the namespace
   2500                        // too.
   2501                        for simple in compound.iter() {
   2502                            simple.to_css(dest)?;
   2503                        }
   2504                        // Skip step 2, which is an "otherwise".
   2505                        perform_step_2 = false;
   2506                    },
   2507                    _ => (),
   2508                }
   2509            }
   2510 
   2511            // 2. Otherwise, for each simple selector in the compound selectors
   2512            //    that is not a universal selector of which the namespace prefix
   2513            //    maps to a namespace that is not the default namespace
   2514            //    serialize the simple selector and append the result to s.
   2515            //
   2516            // See https://github.com/w3c/csswg-drafts/issues/1606, which is
   2517            // proposing to change this to match up with the behavior asserted
   2518            // in cssom/serialize-namespaced-type-selectors.html, which the
   2519            // following code tries to match.
   2520            if perform_step_2 {
   2521                for simple in compound.iter() {
   2522                    if let Component::ExplicitUniversalType = *simple {
   2523                        // Can't have a namespace followed by a pseudo-element
   2524                        // selector followed by a universal selector in the same
   2525                        // compound selector, so we don't have to worry about the
   2526                        // real namespace being in a different `compound`.
   2527                        if can_elide_namespace {
   2528                            continue;
   2529                        }
   2530                    }
   2531                    simple.to_css(dest)?;
   2532                }
   2533            }
   2534 
   2535            // 3. If this is not the last part of the chain of the selector
   2536            //    append a single SPACE (U+0020), followed by the combinator
   2537            //    ">", "+", "~", ">>", "||", as appropriate, followed by another
   2538            //    single SPACE (U+0020) if the combinator was not whitespace, to
   2539            //    s.
   2540            match next_combinator {
   2541                Some(c) => c.to_css(dest)?,
   2542                None => combinators_exhausted = true,
   2543            };
   2544 
   2545            // 4. If this is the last part of the chain of the selector and
   2546            //    there is a pseudo-element, append "::" followed by the name of
   2547            //    the pseudo-element, to s.
   2548            //
   2549            // (we handle this above)
   2550        }
   2551 
   2552        Ok(())
   2553    }
   2554 }
   2555 
   2556 impl Combinator {
   2557    fn to_css_internal<W>(&self, dest: &mut W, prefix_space: bool) -> fmt::Result
   2558    where
   2559        W: fmt::Write,
   2560    {
   2561        if matches!(
   2562            *self,
   2563            Combinator::PseudoElement | Combinator::Part | Combinator::SlotAssignment
   2564        ) {
   2565            return Ok(());
   2566        }
   2567        if prefix_space {
   2568            dest.write_char(' ')?;
   2569        }
   2570        match *self {
   2571            Combinator::Child => dest.write_str("> "),
   2572            Combinator::Descendant => Ok(()),
   2573            Combinator::NextSibling => dest.write_str("+ "),
   2574            Combinator::LaterSibling => dest.write_str("~ "),
   2575            Combinator::PseudoElement | Combinator::Part | Combinator::SlotAssignment => unsafe {
   2576                debug_unreachable!("Already handled")
   2577            },
   2578        }
   2579    }
   2580 
   2581    fn to_css_relative<W>(&self, dest: &mut W) -> fmt::Result
   2582    where
   2583        W: fmt::Write,
   2584    {
   2585        self.to_css_internal(dest, false)
   2586    }
   2587 }
   2588 
   2589 impl ToCss for Combinator {
   2590    fn to_css<W>(&self, dest: &mut W) -> fmt::Result
   2591    where
   2592        W: fmt::Write,
   2593    {
   2594        self.to_css_internal(dest, true)
   2595    }
   2596 }
   2597 
   2598 impl<Impl: SelectorImpl> ToCss for Component<Impl> {
   2599    fn to_css<W>(&self, dest: &mut W) -> fmt::Result
   2600    where
   2601        W: fmt::Write,
   2602    {
   2603        use self::Component::*;
   2604 
   2605        match *self {
   2606            Combinator(ref c) => c.to_css(dest),
   2607            Slotted(ref selector) => {
   2608                dest.write_str("::slotted(")?;
   2609                selector.to_css(dest)?;
   2610                dest.write_char(')')
   2611            },
   2612            Part(ref part_names) => {
   2613                dest.write_str("::part(")?;
   2614                for (i, name) in part_names.iter().enumerate() {
   2615                    if i != 0 {
   2616                        dest.write_char(' ')?;
   2617                    }
   2618                    name.to_css(dest)?;
   2619                }
   2620                dest.write_char(')')
   2621            },
   2622            PseudoElement(ref p) => p.to_css(dest),
   2623            ID(ref s) => {
   2624                dest.write_char('#')?;
   2625                s.to_css(dest)
   2626            },
   2627            Class(ref s) => {
   2628                dest.write_char('.')?;
   2629                s.to_css(dest)
   2630            },
   2631            LocalName(ref s) => s.to_css(dest),
   2632            ExplicitUniversalType => dest.write_char('*'),
   2633 
   2634            DefaultNamespace(_) => Ok(()),
   2635            ExplicitNoNamespace => dest.write_char('|'),
   2636            ExplicitAnyNamespace => dest.write_str("*|"),
   2637            Namespace(ref prefix, _) => {
   2638                prefix.to_css(dest)?;
   2639                dest.write_char('|')
   2640            },
   2641 
   2642            AttributeInNoNamespaceExists { ref local_name, .. } => {
   2643                dest.write_char('[')?;
   2644                local_name.to_css(dest)?;
   2645                dest.write_char(']')
   2646            },
   2647            AttributeInNoNamespace {
   2648                ref local_name,
   2649                operator,
   2650                ref value,
   2651                case_sensitivity,
   2652                ..
   2653            } => {
   2654                dest.write_char('[')?;
   2655                local_name.to_css(dest)?;
   2656                operator.to_css(dest)?;
   2657                value.to_css(dest)?;
   2658                match case_sensitivity {
   2659                    ParsedCaseSensitivity::CaseSensitive
   2660                    | ParsedCaseSensitivity::AsciiCaseInsensitiveIfInHtmlElementInHtmlDocument => {
   2661                    },
   2662                    ParsedCaseSensitivity::AsciiCaseInsensitive => dest.write_str(" i")?,
   2663                    ParsedCaseSensitivity::ExplicitCaseSensitive => dest.write_str(" s")?,
   2664                }
   2665                dest.write_char(']')
   2666            },
   2667            AttributeOther(ref attr_selector) => attr_selector.to_css(dest),
   2668 
   2669            // Pseudo-classes
   2670            Root => dest.write_str(":root"),
   2671            Empty => dest.write_str(":empty"),
   2672            Scope => dest.write_str(":scope"),
   2673            ParentSelector => dest.write_char('&'),
   2674            Host(ref selector) => {
   2675                dest.write_str(":host")?;
   2676                if let Some(ref selector) = *selector {
   2677                    dest.write_char('(')?;
   2678                    selector.to_css(dest)?;
   2679                    dest.write_char(')')?;
   2680                }
   2681                Ok(())
   2682            },
   2683            Nth(ref nth_data) => {
   2684                nth_data.write_start(dest)?;
   2685                if nth_data.is_function {
   2686                    nth_data.write_affine(dest)?;
   2687                    dest.write_char(')')?;
   2688                }
   2689                Ok(())
   2690            },
   2691            NthOf(ref nth_of_data) => {
   2692                let nth_data = nth_of_data.nth_data();
   2693                nth_data.write_start(dest)?;
   2694                debug_assert!(
   2695                    nth_data.is_function,
   2696                    "A selector must be a function to hold An+B notation"
   2697                );
   2698                nth_data.write_affine(dest)?;
   2699                debug_assert!(
   2700                    matches!(nth_data.ty, NthType::Child | NthType::LastChild),
   2701                    "Only :nth-child or :nth-last-child can be of a selector list"
   2702                );
   2703                debug_assert!(
   2704                    !nth_of_data.selectors().is_empty(),
   2705                    "The selector list should not be empty"
   2706                );
   2707                dest.write_str(" of ")?;
   2708                serialize_selector_list(nth_of_data.selectors().iter(), dest)?;
   2709                dest.write_char(')')
   2710            },
   2711            Is(ref list) | Where(ref list) | Negation(ref list) => {
   2712                match *self {
   2713                    Where(..) => dest.write_str(":where(")?,
   2714                    Is(..) => dest.write_str(":is(")?,
   2715                    Negation(..) => dest.write_str(":not(")?,
   2716                    _ => unreachable!(),
   2717                }
   2718                serialize_selector_list(list.slice().iter(), dest)?;
   2719                dest.write_str(")")
   2720            },
   2721            Has(ref list) => {
   2722                dest.write_str(":has(")?;
   2723                serialize_selector_list(list.iter().map(|rel| &rel.selector), dest)?;
   2724                dest.write_str(")")
   2725            },
   2726            NonTSPseudoClass(ref pseudo) => pseudo.to_css(dest),
   2727            Invalid(ref css) => dest.write_str(css),
   2728            RelativeSelectorAnchor | ImplicitScope => Ok(()),
   2729        }
   2730    }
   2731 }
   2732 
   2733 impl<Impl: SelectorImpl> ToCss for AttrSelectorWithOptionalNamespace<Impl> {
   2734    fn to_css<W>(&self, dest: &mut W) -> fmt::Result
   2735    where
   2736        W: fmt::Write,
   2737    {
   2738        dest.write_char('[')?;
   2739        match self.namespace {
   2740            Some(NamespaceConstraint::Specific((ref prefix, _))) => {
   2741                prefix.to_css(dest)?;
   2742                dest.write_char('|')?
   2743            },
   2744            Some(NamespaceConstraint::Any) => dest.write_str("*|")?,
   2745            None => {},
   2746        }
   2747        self.local_name.to_css(dest)?;
   2748        match self.operation {
   2749            ParsedAttrSelectorOperation::Exists => {},
   2750            ParsedAttrSelectorOperation::WithValue {
   2751                operator,
   2752                case_sensitivity,
   2753                ref value,
   2754            } => {
   2755                operator.to_css(dest)?;
   2756                value.to_css(dest)?;
   2757                match case_sensitivity {
   2758                    ParsedCaseSensitivity::CaseSensitive
   2759                    | ParsedCaseSensitivity::AsciiCaseInsensitiveIfInHtmlElementInHtmlDocument => {
   2760                    },
   2761                    ParsedCaseSensitivity::AsciiCaseInsensitive => dest.write_str(" i")?,
   2762                    ParsedCaseSensitivity::ExplicitCaseSensitive => dest.write_str(" s")?,
   2763                }
   2764            },
   2765        }
   2766        dest.write_char(']')
   2767    }
   2768 }
   2769 
   2770 impl<Impl: SelectorImpl> ToCss for LocalName<Impl> {
   2771    fn to_css<W>(&self, dest: &mut W) -> fmt::Result
   2772    where
   2773        W: fmt::Write,
   2774    {
   2775        self.name.to_css(dest)
   2776    }
   2777 }
   2778 
   2779 /// Build up a Selector.
   2780 /// selector : simple_selector_sequence [ combinator simple_selector_sequence ]* ;
   2781 ///
   2782 /// `Err` means invalid selector.
   2783 fn parse_selector<'i, 't, P, Impl>(
   2784    parser: &P,
   2785    input: &mut CssParser<'i, 't>,
   2786    mut state: SelectorParsingState,
   2787    parse_relative: ParseRelative,
   2788 ) -> Result<Selector<Impl>, ParseError<'i, P::Error>>
   2789 where
   2790    P: Parser<'i, Impl = Impl>,
   2791    Impl: SelectorImpl,
   2792 {
   2793    let mut builder = SelectorBuilder::default();
   2794 
   2795    // Helps rewind less, but also simplifies dealing with relative combinators below.
   2796    input.skip_whitespace();
   2797 
   2798    if parse_relative != ParseRelative::No {
   2799        let combinator = try_parse_combinator(input);
   2800        match parse_relative {
   2801            ParseRelative::ForHas => {
   2802                builder.push_simple_selector(Component::RelativeSelectorAnchor);
   2803                // Do we see a combinator? If so, push that. Otherwise, push a descendant
   2804                // combinator.
   2805                builder.push_combinator(combinator.unwrap_or(Combinator::Descendant));
   2806            },
   2807            ParseRelative::ForNesting | ParseRelative::ForScope => {
   2808                if let Ok(combinator) = combinator {
   2809                    let selector = match parse_relative {
   2810                        ParseRelative::ForHas | ParseRelative::No => unreachable!(),
   2811                        ParseRelative::ForNesting => Component::ParentSelector,
   2812                        // See https://github.com/w3c/csswg-drafts/issues/10196
   2813                        // Implicitly added `:scope` does not add specificity
   2814                        // for non-relative selectors, so do the same.
   2815                        ParseRelative::ForScope => Component::ImplicitScope,
   2816                    };
   2817                    builder.push_simple_selector(selector);
   2818                    builder.push_combinator(combinator);
   2819                }
   2820            },
   2821            ParseRelative::No => unreachable!(),
   2822        }
   2823    }
   2824    loop {
   2825        // Parse a sequence of simple selectors.
   2826        let empty = parse_compound_selector(parser, &mut state, input, &mut builder)?;
   2827        if empty {
   2828            return Err(input.new_custom_error(if builder.has_combinators() {
   2829                SelectorParseErrorKind::DanglingCombinator
   2830            } else {
   2831                SelectorParseErrorKind::EmptySelector
   2832            }));
   2833        }
   2834 
   2835        if state.intersects(SelectorParsingState::AFTER_PSEUDO) {
   2836            debug_assert!(state.intersects(
   2837                SelectorParsingState::AFTER_NON_ELEMENT_BACKED_PSEUDO
   2838                    | SelectorParsingState::AFTER_BEFORE_OR_AFTER_PSEUDO
   2839                    | SelectorParsingState::AFTER_SLOTTED
   2840                    | SelectorParsingState::AFTER_PART_LIKE
   2841            ));
   2842            break;
   2843        }
   2844 
   2845        let combinator = if let Ok(c) = try_parse_combinator(input) {
   2846            c
   2847        } else {
   2848            break;
   2849        };
   2850 
   2851        if !state.allows_combinators() {
   2852            return Err(input.new_custom_error(SelectorParseErrorKind::InvalidState));
   2853        }
   2854 
   2855        builder.push_combinator(combinator);
   2856    }
   2857    return Ok(Selector(builder.build(parse_relative)));
   2858 }
   2859 
   2860 fn try_parse_combinator<'i, 't>(input: &mut CssParser<'i, 't>) -> Result<Combinator, ()> {
   2861    let mut any_whitespace = false;
   2862    loop {
   2863        let before_this_token = input.state();
   2864        match input.next_including_whitespace() {
   2865            Err(_e) => return Err(()),
   2866            Ok(&Token::WhiteSpace(_)) => any_whitespace = true,
   2867            Ok(&Token::Delim('>')) => {
   2868                return Ok(Combinator::Child);
   2869            },
   2870            Ok(&Token::Delim('+')) => {
   2871                return Ok(Combinator::NextSibling);
   2872            },
   2873            Ok(&Token::Delim('~')) => {
   2874                return Ok(Combinator::LaterSibling);
   2875            },
   2876            Ok(_) => {
   2877                input.reset(&before_this_token);
   2878                if any_whitespace {
   2879                    return Ok(Combinator::Descendant);
   2880                } else {
   2881                    return Err(());
   2882                }
   2883            },
   2884        }
   2885    }
   2886 }
   2887 
   2888 /// * `Err(())`: Invalid selector, abort
   2889 /// * `Ok(false)`: Not a type selector, could be something else. `input` was not consumed.
   2890 /// * `Ok(true)`: Length 0 (`*|*`), 1 (`*|E` or `ns|*`) or 2 (`|E` or `ns|E`)
   2891 fn parse_type_selector<'i, 't, P, Impl, S>(
   2892    parser: &P,
   2893    input: &mut CssParser<'i, 't>,
   2894    state: SelectorParsingState,
   2895    sink: &mut S,
   2896 ) -> Result<bool, ParseError<'i, P::Error>>
   2897 where
   2898    P: Parser<'i, Impl = Impl>,
   2899    Impl: SelectorImpl,
   2900    S: Push<Component<Impl>>,
   2901 {
   2902    match parse_qualified_name(parser, input, /* in_attr_selector = */ false) {
   2903        Err(ParseError {
   2904            kind: ParseErrorKind::Basic(BasicParseErrorKind::EndOfInput),
   2905            ..
   2906        })
   2907        | Ok(OptionalQName::None(_)) => Ok(false),
   2908        Ok(OptionalQName::Some(namespace, local_name)) => {
   2909            if state.intersects(SelectorParsingState::AFTER_PSEUDO) {
   2910                return Err(input.new_custom_error(SelectorParseErrorKind::InvalidState));
   2911            }
   2912            match namespace {
   2913                QNamePrefix::ImplicitAnyNamespace => {},
   2914                QNamePrefix::ImplicitDefaultNamespace(url) => {
   2915                    sink.push(Component::DefaultNamespace(url))
   2916                },
   2917                QNamePrefix::ExplicitNamespace(prefix, url) => {
   2918                    sink.push(match parser.default_namespace() {
   2919                        Some(ref default_url) if url == *default_url => {
   2920                            Component::DefaultNamespace(url)
   2921                        },
   2922                        _ => Component::Namespace(prefix, url),
   2923                    })
   2924                },
   2925                QNamePrefix::ExplicitNoNamespace => sink.push(Component::ExplicitNoNamespace),
   2926                QNamePrefix::ExplicitAnyNamespace => {
   2927                    match parser.default_namespace() {
   2928                        // Element type selectors that have no namespace
   2929                        // component (no namespace separator) represent elements
   2930                        // without regard to the element's namespace (equivalent
   2931                        // to "*|") unless a default namespace has been declared
   2932                        // for namespaced selectors (e.g. in CSS, in the style
   2933                        // sheet). If a default namespace has been declared,
   2934                        // such selectors will represent only elements in the
   2935                        // default namespace.
   2936                        // -- Selectors § 6.1.1
   2937                        // So we'll have this act the same as the
   2938                        // QNamePrefix::ImplicitAnyNamespace case.
   2939                        None => {},
   2940                        Some(_) => sink.push(Component::ExplicitAnyNamespace),
   2941                    }
   2942                },
   2943                QNamePrefix::ImplicitNoNamespace => {
   2944                    unreachable!() // Not returned with in_attr_selector = false
   2945                },
   2946            }
   2947            match local_name {
   2948                Some(name) => sink.push(Component::LocalName(LocalName {
   2949                    lower_name: to_ascii_lowercase(&name).as_ref().into(),
   2950                    name: name.as_ref().into(),
   2951                })),
   2952                None => sink.push(Component::ExplicitUniversalType),
   2953            }
   2954            Ok(true)
   2955        },
   2956        Err(e) => Err(e),
   2957    }
   2958 }
   2959 
   2960 #[derive(Debug)]
   2961 enum SimpleSelectorParseResult<Impl: SelectorImpl> {
   2962    SimpleSelector(Component<Impl>),
   2963    PseudoElement(Impl::PseudoElement),
   2964    SlottedPseudo(Selector<Impl>),
   2965    PartPseudo(Box<[Impl::Identifier]>),
   2966 }
   2967 
   2968 #[derive(Debug)]
   2969 enum QNamePrefix<Impl: SelectorImpl> {
   2970    ImplicitNoNamespace,                          // `foo` in attr selectors
   2971    ImplicitAnyNamespace,                         // `foo` in type selectors, without a default ns
   2972    ImplicitDefaultNamespace(Impl::NamespaceUrl), // `foo` in type selectors, with a default ns
   2973    ExplicitNoNamespace,                          // `|foo`
   2974    ExplicitAnyNamespace,                         // `*|foo`
   2975    ExplicitNamespace(Impl::NamespacePrefix, Impl::NamespaceUrl), // `prefix|foo`
   2976 }
   2977 
   2978 enum OptionalQName<'i, Impl: SelectorImpl> {
   2979    Some(QNamePrefix<Impl>, Option<CowRcStr<'i>>),
   2980    None(Token<'i>),
   2981 }
   2982 
   2983 /// * `Err(())`: Invalid selector, abort
   2984 /// * `Ok(None(token))`: Not a simple selector, could be something else. `input` was not consumed,
   2985 ///                      but the token is still returned.
   2986 /// * `Ok(Some(namespace, local_name))`: `None` for the local name means a `*` universal selector
   2987 fn parse_qualified_name<'i, 't, P, Impl>(
   2988    parser: &P,
   2989    input: &mut CssParser<'i, 't>,
   2990    in_attr_selector: bool,
   2991 ) -> Result<OptionalQName<'i, Impl>, ParseError<'i, P::Error>>
   2992 where
   2993    P: Parser<'i, Impl = Impl>,
   2994    Impl: SelectorImpl,
   2995 {
   2996    let default_namespace = |local_name| {
   2997        let namespace = match parser.default_namespace() {
   2998            Some(url) => QNamePrefix::ImplicitDefaultNamespace(url),
   2999            None => QNamePrefix::ImplicitAnyNamespace,
   3000        };
   3001        Ok(OptionalQName::Some(namespace, local_name))
   3002    };
   3003 
   3004    let explicit_namespace = |input: &mut CssParser<'i, 't>, namespace| {
   3005        let location = input.current_source_location();
   3006        match input.next_including_whitespace() {
   3007            Ok(&Token::Delim('*')) if !in_attr_selector => Ok(OptionalQName::Some(namespace, None)),
   3008            Ok(&Token::Ident(ref local_name)) => {
   3009                Ok(OptionalQName::Some(namespace, Some(local_name.clone())))
   3010            },
   3011            Ok(t) if in_attr_selector => {
   3012                let e = SelectorParseErrorKind::InvalidQualNameInAttr(t.clone());
   3013                Err(location.new_custom_error(e))
   3014            },
   3015            Ok(t) => Err(location.new_custom_error(
   3016                SelectorParseErrorKind::ExplicitNamespaceUnexpectedToken(t.clone()),
   3017            )),
   3018            Err(e) => Err(e.into()),
   3019        }
   3020    };
   3021 
   3022    let start = input.state();
   3023    match input.next_including_whitespace() {
   3024        Ok(Token::Ident(value)) => {
   3025            let value = value.clone();
   3026            let after_ident = input.state();
   3027            match input.next_including_whitespace() {
   3028                Ok(&Token::Delim('|')) => {
   3029                    let prefix = value.as_ref().into();
   3030                    let result = parser.namespace_for_prefix(&prefix);
   3031                    let url = result.ok_or(
   3032                        after_ident
   3033                            .source_location()
   3034                            .new_custom_error(SelectorParseErrorKind::ExpectedNamespace(value)),
   3035                    )?;
   3036                    explicit_namespace(input, QNamePrefix::ExplicitNamespace(prefix, url))
   3037                },
   3038                _ => {
   3039                    input.reset(&after_ident);
   3040                    if in_attr_selector {
   3041                        Ok(OptionalQName::Some(
   3042                            QNamePrefix::ImplicitNoNamespace,
   3043                            Some(value),
   3044                        ))
   3045                    } else {
   3046                        default_namespace(Some(value))
   3047                    }
   3048                },
   3049            }
   3050        },
   3051        Ok(Token::Delim('*')) => {
   3052            let after_star = input.state();
   3053            match input.next_including_whitespace() {
   3054                Ok(&Token::Delim('|')) => {
   3055                    explicit_namespace(input, QNamePrefix::ExplicitAnyNamespace)
   3056                },
   3057                _ if !in_attr_selector => {
   3058                    input.reset(&after_star);
   3059                    default_namespace(None)
   3060                },
   3061                result => {
   3062                    let t = result?;
   3063                    Err(after_star
   3064                        .source_location()
   3065                        .new_custom_error(SelectorParseErrorKind::ExpectedBarInAttr(t.clone())))
   3066                },
   3067            }
   3068        },
   3069        Ok(Token::Delim('|')) => explicit_namespace(input, QNamePrefix::ExplicitNoNamespace),
   3070        Ok(t) => {
   3071            let t = t.clone();
   3072            input.reset(&start);
   3073            Ok(OptionalQName::None(t))
   3074        },
   3075        Err(e) => {
   3076            input.reset(&start);
   3077            Err(e.into())
   3078        },
   3079    }
   3080 }
   3081 
   3082 fn parse_attribute_selector<'i, 't, P, Impl>(
   3083    parser: &P,
   3084    input: &mut CssParser<'i, 't>,
   3085 ) -> Result<Component<Impl>, ParseError<'i, P::Error>>
   3086 where
   3087    P: Parser<'i, Impl = Impl>,
   3088    Impl: SelectorImpl,
   3089 {
   3090    let namespace;
   3091    let local_name;
   3092 
   3093    input.skip_whitespace();
   3094 
   3095    match parse_qualified_name(parser, input, /* in_attr_selector = */ true)? {
   3096        OptionalQName::None(t) => {
   3097            return Err(input.new_custom_error(
   3098                SelectorParseErrorKind::NoQualifiedNameInAttributeSelector(t),
   3099            ));
   3100        },
   3101        OptionalQName::Some(_, None) => unreachable!(),
   3102        OptionalQName::Some(ns, Some(ln)) => {
   3103            local_name = ln;
   3104            namespace = match ns {
   3105                QNamePrefix::ImplicitNoNamespace | QNamePrefix::ExplicitNoNamespace => None,
   3106                QNamePrefix::ExplicitNamespace(prefix, url) => {
   3107                    Some(NamespaceConstraint::Specific((prefix, url)))
   3108                },
   3109                QNamePrefix::ExplicitAnyNamespace => Some(NamespaceConstraint::Any),
   3110                QNamePrefix::ImplicitAnyNamespace | QNamePrefix::ImplicitDefaultNamespace(_) => {
   3111                    unreachable!() // Not returned with in_attr_selector = true
   3112                },
   3113            }
   3114        },
   3115    }
   3116 
   3117    let location = input.current_source_location();
   3118    let operator = match input.next() {
   3119        // [foo]
   3120        Err(_) => {
   3121            let local_name_lower = to_ascii_lowercase(&local_name).as_ref().into();
   3122            let local_name = local_name.as_ref().into();
   3123            if let Some(namespace) = namespace {
   3124                return Ok(Component::AttributeOther(Box::new(
   3125                    AttrSelectorWithOptionalNamespace {
   3126                        namespace: Some(namespace),
   3127                        local_name,
   3128                        local_name_lower,
   3129                        operation: ParsedAttrSelectorOperation::Exists,
   3130                    },
   3131                )));
   3132            } else {
   3133                return Ok(Component::AttributeInNoNamespaceExists {
   3134                    local_name,
   3135                    local_name_lower,
   3136                });
   3137            }
   3138        },
   3139 
   3140        // [foo=bar]
   3141        Ok(&Token::Delim('=')) => AttrSelectorOperator::Equal,
   3142        // [foo~=bar]
   3143        Ok(&Token::IncludeMatch) => AttrSelectorOperator::Includes,
   3144        // [foo|=bar]
   3145        Ok(&Token::DashMatch) => AttrSelectorOperator::DashMatch,
   3146        // [foo^=bar]
   3147        Ok(&Token::PrefixMatch) => AttrSelectorOperator::Prefix,
   3148        // [foo*=bar]
   3149        Ok(&Token::SubstringMatch) => AttrSelectorOperator::Substring,
   3150        // [foo$=bar]
   3151        Ok(&Token::SuffixMatch) => AttrSelectorOperator::Suffix,
   3152        Ok(t) => {
   3153            return Err(location.new_custom_error(
   3154                SelectorParseErrorKind::UnexpectedTokenInAttributeSelector(t.clone()),
   3155            ));
   3156        },
   3157    };
   3158 
   3159    let value = match input.expect_ident_or_string() {
   3160        Ok(t) => t.clone(),
   3161        Err(BasicParseError {
   3162            kind: BasicParseErrorKind::UnexpectedToken(t),
   3163            location,
   3164        }) => return Err(location.new_custom_error(SelectorParseErrorKind::BadValueInAttr(t))),
   3165        Err(e) => return Err(e.into()),
   3166    };
   3167 
   3168    let attribute_flags = parse_attribute_flags(input)?;
   3169    let value = value.as_ref().into();
   3170    let local_name_lower;
   3171    let local_name_is_ascii_lowercase;
   3172    let case_sensitivity;
   3173    {
   3174        let local_name_lower_cow = to_ascii_lowercase(&local_name);
   3175        case_sensitivity =
   3176            attribute_flags.to_case_sensitivity(local_name_lower_cow.as_ref(), namespace.is_some());
   3177        local_name_lower = local_name_lower_cow.as_ref().into();
   3178        local_name_is_ascii_lowercase = matches!(local_name_lower_cow, Cow::Borrowed(..));
   3179    }
   3180    let local_name = local_name.as_ref().into();
   3181    if namespace.is_some() || !local_name_is_ascii_lowercase {
   3182        Ok(Component::AttributeOther(Box::new(
   3183            AttrSelectorWithOptionalNamespace {
   3184                namespace,
   3185                local_name,
   3186                local_name_lower,
   3187                operation: ParsedAttrSelectorOperation::WithValue {
   3188                    operator,
   3189                    case_sensitivity,
   3190                    value,
   3191                },
   3192            },
   3193        )))
   3194    } else {
   3195        Ok(Component::AttributeInNoNamespace {
   3196            local_name,
   3197            operator,
   3198            value,
   3199            case_sensitivity,
   3200        })
   3201    }
   3202 }
   3203 
   3204 /// An attribute selector can have 's' or 'i' as flags, or no flags at all.
   3205 enum AttributeFlags {
   3206    // Matching should be case-sensitive ('s' flag).
   3207    CaseSensitive,
   3208    // Matching should be case-insensitive ('i' flag).
   3209    AsciiCaseInsensitive,
   3210    // No flags.  Matching behavior depends on the name of the attribute.
   3211    CaseSensitivityDependsOnName,
   3212 }
   3213 
   3214 impl AttributeFlags {
   3215    fn to_case_sensitivity(
   3216        self,
   3217        local_name_lower: &str,
   3218        have_namespace: bool,
   3219    ) -> ParsedCaseSensitivity {
   3220        match self {
   3221            AttributeFlags::CaseSensitive => ParsedCaseSensitivity::ExplicitCaseSensitive,
   3222            AttributeFlags::AsciiCaseInsensitive => ParsedCaseSensitivity::AsciiCaseInsensitive,
   3223            AttributeFlags::CaseSensitivityDependsOnName => {
   3224                if !have_namespace
   3225                    && include!(concat!(
   3226                        env!("OUT_DIR"),
   3227                        "/ascii_case_insensitive_html_attributes.rs"
   3228                    ))
   3229                    .contains(local_name_lower)
   3230                {
   3231                    ParsedCaseSensitivity::AsciiCaseInsensitiveIfInHtmlElementInHtmlDocument
   3232                } else {
   3233                    ParsedCaseSensitivity::CaseSensitive
   3234                }
   3235            },
   3236        }
   3237    }
   3238 }
   3239 
   3240 fn parse_attribute_flags<'i, 't>(
   3241    input: &mut CssParser<'i, 't>,
   3242 ) -> Result<AttributeFlags, BasicParseError<'i>> {
   3243    let location = input.current_source_location();
   3244    let token = match input.next() {
   3245        Ok(t) => t,
   3246        Err(..) => {
   3247            // Selectors spec says language-defined; HTML says it depends on the
   3248            // exact attribute name.
   3249            return Ok(AttributeFlags::CaseSensitivityDependsOnName);
   3250        },
   3251    };
   3252 
   3253    let ident = match *token {
   3254        Token::Ident(ref i) => i,
   3255        ref other => return Err(location.new_basic_unexpected_token_error(other.clone())),
   3256    };
   3257 
   3258    Ok(match_ignore_ascii_case! {
   3259        ident,
   3260        "i" => AttributeFlags::AsciiCaseInsensitive,
   3261        "s" => AttributeFlags::CaseSensitive,
   3262        _ => return Err(location.new_basic_unexpected_token_error(token.clone())),
   3263    })
   3264 }
   3265 
   3266 /// Level 3: Parse **one** simple_selector.  (Though we might insert a second
   3267 /// implied "<defaultns>|*" type selector.)
   3268 fn parse_negation<'i, 't, P, Impl>(
   3269    parser: &P,
   3270    input: &mut CssParser<'i, 't>,
   3271    state: SelectorParsingState,
   3272 ) -> Result<Component<Impl>, ParseError<'i, P::Error>>
   3273 where
   3274    P: Parser<'i, Impl = Impl>,
   3275    Impl: SelectorImpl,
   3276 {
   3277    let list = SelectorList::parse_with_state(
   3278        parser,
   3279        input,
   3280        state
   3281            | SelectorParsingState::SKIP_DEFAULT_NAMESPACE
   3282            | SelectorParsingState::DISALLOW_PSEUDOS,
   3283        ForgivingParsing::No,
   3284        ParseRelative::No,
   3285    )?;
   3286 
   3287    Ok(Component::Negation(list))
   3288 }
   3289 
   3290 /// simple_selector_sequence
   3291 /// : [ type_selector | universal ] [ HASH | class | attrib | pseudo | negation ]*
   3292 /// | [ HASH | class | attrib | pseudo | negation ]+
   3293 ///
   3294 /// `Err(())` means invalid selector.
   3295 /// `Ok(true)` is an empty selector
   3296 fn parse_compound_selector<'i, 't, P, Impl>(
   3297    parser: &P,
   3298    state: &mut SelectorParsingState,
   3299    input: &mut CssParser<'i, 't>,
   3300    builder: &mut SelectorBuilder<Impl>,
   3301 ) -> Result<bool, ParseError<'i, P::Error>>
   3302 where
   3303    P: Parser<'i, Impl = Impl>,
   3304    Impl: SelectorImpl,
   3305 {
   3306    input.skip_whitespace();
   3307 
   3308    let mut empty = true;
   3309    if parse_type_selector(parser, input, *state, builder)? {
   3310        empty = false;
   3311    }
   3312 
   3313    loop {
   3314        let result = match parse_one_simple_selector(parser, input, *state)? {
   3315            None => break,
   3316            Some(result) => result,
   3317        };
   3318 
   3319        if empty {
   3320            if let Some(url) = parser.default_namespace() {
   3321                // If there was no explicit type selector, but there is a
   3322                // default namespace, there is an implicit "<defaultns>|*" type
   3323                // selector. Except for :host() or :not() / :is() / :where(),
   3324                // where we ignore it.
   3325                //
   3326                // https://drafts.csswg.org/css-scoping/#host-element-in-tree:
   3327                //
   3328                //     When considered within its own shadow trees, the shadow
   3329                //     host is featureless. Only the :host, :host(), and
   3330                //     :host-context() pseudo-classes are allowed to match it.
   3331                //
   3332                // https://drafts.csswg.org/selectors-4/#featureless:
   3333                //
   3334                //     A featureless element does not match any selector at all,
   3335                //     except those it is explicitly defined to match. If a
   3336                //     given selector is allowed to match a featureless element,
   3337                //     it must do so while ignoring the default namespace.
   3338                //
   3339                // https://drafts.csswg.org/selectors-4/#matches
   3340                //
   3341                //     Default namespace declarations do not affect the compound
   3342                //     selector representing the subject of any selector within
   3343                //     a :is() pseudo-class, unless that compound selector
   3344                //     contains an explicit universal selector or type selector.
   3345                //
   3346                //     (Similar quotes for :where() / :not())
   3347                //
   3348                let ignore_default_ns = state
   3349                    .intersects(SelectorParsingState::SKIP_DEFAULT_NAMESPACE)
   3350                    || matches!(
   3351                        result,
   3352                        SimpleSelectorParseResult::SimpleSelector(Component::Host(..))
   3353                    );
   3354                if !ignore_default_ns {
   3355                    builder.push_simple_selector(Component::DefaultNamespace(url));
   3356                }
   3357            }
   3358        }
   3359 
   3360        empty = false;
   3361 
   3362        match result {
   3363            SimpleSelectorParseResult::SimpleSelector(s) => {
   3364                builder.push_simple_selector(s);
   3365            },
   3366            SimpleSelectorParseResult::PartPseudo(part_names) => {
   3367                state.insert(SelectorParsingState::AFTER_PART_LIKE);
   3368                builder.push_combinator(Combinator::Part);
   3369                builder.push_simple_selector(Component::Part(part_names));
   3370            },
   3371            SimpleSelectorParseResult::SlottedPseudo(selector) => {
   3372                state.insert(SelectorParsingState::AFTER_SLOTTED);
   3373                builder.push_combinator(Combinator::SlotAssignment);
   3374                builder.push_simple_selector(Component::Slotted(selector));
   3375            },
   3376            SimpleSelectorParseResult::PseudoElement(p) => {
   3377                if p.is_element_backed() {
   3378                    state.insert(SelectorParsingState::AFTER_PART_LIKE);
   3379                } else {
   3380                    state.insert(SelectorParsingState::AFTER_NON_ELEMENT_BACKED_PSEUDO);
   3381                    if p.is_before_or_after() {
   3382                        state.insert(SelectorParsingState::AFTER_BEFORE_OR_AFTER_PSEUDO);
   3383                    }
   3384                }
   3385                if !p.accepts_state_pseudo_classes() {
   3386                    state.insert(SelectorParsingState::AFTER_NON_STATEFUL_PSEUDO_ELEMENT);
   3387                }
   3388                if p.is_in_pseudo_element_tree() {
   3389                    state.insert(SelectorParsingState::IN_PSEUDO_ELEMENT_TREE);
   3390                }
   3391                builder.push_combinator(Combinator::PseudoElement);
   3392                builder.push_simple_selector(Component::PseudoElement(p));
   3393            },
   3394        }
   3395    }
   3396    Ok(empty)
   3397 }
   3398 
   3399 fn parse_is_where<'i, 't, P, Impl>(
   3400    parser: &P,
   3401    input: &mut CssParser<'i, 't>,
   3402    state: SelectorParsingState,
   3403    component: impl FnOnce(SelectorList<Impl>) -> Component<Impl>,
   3404 ) -> Result<Component<Impl>, ParseError<'i, P::Error>>
   3405 where
   3406    P: Parser<'i, Impl = Impl>,
   3407    Impl: SelectorImpl,
   3408 {
   3409    debug_assert!(parser.parse_is_and_where());
   3410    // https://drafts.csswg.org/selectors/#matches-pseudo:
   3411    //
   3412    //     Pseudo-elements cannot be represented by the matches-any
   3413    //     pseudo-class; they are not valid within :is().
   3414    //
   3415    let inner = SelectorList::parse_with_state(
   3416        parser,
   3417        input,
   3418        state
   3419            | SelectorParsingState::SKIP_DEFAULT_NAMESPACE
   3420            | SelectorParsingState::DISALLOW_PSEUDOS,
   3421        ForgivingParsing::Yes,
   3422        ParseRelative::No,
   3423    )?;
   3424    Ok(component(inner))
   3425 }
   3426 
   3427 fn parse_has<'i, 't, P, Impl>(
   3428    parser: &P,
   3429    input: &mut CssParser<'i, 't>,
   3430    state: SelectorParsingState,
   3431 ) -> Result<Component<Impl>, ParseError<'i, P::Error>>
   3432 where
   3433    P: Parser<'i, Impl = Impl>,
   3434    Impl: SelectorImpl,
   3435 {
   3436    debug_assert!(parser.parse_has());
   3437    if state.intersects(
   3438        SelectorParsingState::DISALLOW_RELATIVE_SELECTOR | SelectorParsingState::AFTER_PSEUDO,
   3439    ) {
   3440        return Err(input.new_custom_error(SelectorParseErrorKind::InvalidState));
   3441    }
   3442    // Nested `:has()` is disallowed, mark it as such.
   3443    // Note: The spec defines ":has-allowed pseudo-element," but there's no
   3444    // pseudo-element defined as such at the moment.
   3445    // https://w3c.github.io/csswg-drafts/selectors-4/#has-allowed-pseudo-element
   3446    let inner = SelectorList::parse_with_state(
   3447        parser,
   3448        input,
   3449        state
   3450            | SelectorParsingState::SKIP_DEFAULT_NAMESPACE
   3451            | SelectorParsingState::DISALLOW_PSEUDOS
   3452            | SelectorParsingState::DISALLOW_RELATIVE_SELECTOR,
   3453        ForgivingParsing::No,
   3454        ParseRelative::ForHas,
   3455    )?;
   3456    Ok(Component::Has(RelativeSelector::from_selector_list(inner)))
   3457 }
   3458 
   3459 fn parse_functional_pseudo_class<'i, 't, P, Impl>(
   3460    parser: &P,
   3461    input: &mut CssParser<'i, 't>,
   3462    name: CowRcStr<'i>,
   3463    state: SelectorParsingState,
   3464 ) -> Result<Component<Impl>, ParseError<'i, P::Error>>
   3465 where
   3466    P: Parser<'i, Impl = Impl>,
   3467    Impl: SelectorImpl,
   3468 {
   3469    match_ignore_ascii_case! { &name,
   3470        "nth-child" => return parse_nth_pseudo_class(parser, input, state, NthType::Child),
   3471        "nth-of-type" => return parse_nth_pseudo_class(parser, input, state, NthType::OfType),
   3472        "nth-last-child" => return parse_nth_pseudo_class(parser, input, state, NthType::LastChild),
   3473        "nth-last-of-type" => return parse_nth_pseudo_class(parser, input, state, NthType::LastOfType),
   3474        "is" if parser.parse_is_and_where() => return parse_is_where(parser, input, state, Component::Is),
   3475        "where" if parser.parse_is_and_where() => return parse_is_where(parser, input, state, Component::Where),
   3476        "has" if parser.parse_has() => return parse_has(parser, input, state),
   3477        "host" => {
   3478            if !state.allows_tree_structural_pseudo_classes() {
   3479                return Err(input.new_custom_error(SelectorParseErrorKind::InvalidState));
   3480            }
   3481            return Ok(Component::Host(Some(parse_inner_compound_selector(parser, input, state)?)));
   3482        },
   3483        "not" => {
   3484            return parse_negation(parser, input, state)
   3485        },
   3486        _ => {}
   3487    }
   3488 
   3489    if parser.parse_is_and_where() && parser.is_is_alias(&name) {
   3490        return parse_is_where(parser, input, state, Component::Is);
   3491    }
   3492 
   3493    if state.intersects(
   3494        SelectorParsingState::AFTER_NON_ELEMENT_BACKED_PSEUDO | SelectorParsingState::AFTER_SLOTTED,
   3495    ) {
   3496        return Err(input.new_custom_error(SelectorParseErrorKind::InvalidState));
   3497    }
   3498 
   3499    let after_part = state.intersects(SelectorParsingState::AFTER_PART_LIKE);
   3500    P::parse_non_ts_functional_pseudo_class(parser, name, input, after_part)
   3501        .map(Component::NonTSPseudoClass)
   3502 }
   3503 
   3504 fn parse_nth_pseudo_class<'i, 't, P, Impl>(
   3505    parser: &P,
   3506    input: &mut CssParser<'i, 't>,
   3507    state: SelectorParsingState,
   3508    ty: NthType,
   3509 ) -> Result<Component<Impl>, ParseError<'i, P::Error>>
   3510 where
   3511    P: Parser<'i, Impl = Impl>,
   3512    Impl: SelectorImpl,
   3513 {
   3514    if !state.allows_tree_structural_pseudo_classes() {
   3515        return Err(input.new_custom_error(SelectorParseErrorKind::InvalidState));
   3516    }
   3517    let (a, b) = parse_nth(input)?;
   3518    let nth_data = NthSelectorData {
   3519        ty,
   3520        is_function: true,
   3521        an_plus_b: AnPlusB(a, b),
   3522    };
   3523    if !parser.parse_nth_child_of() || ty.is_of_type() {
   3524        return Ok(Component::Nth(nth_data));
   3525    }
   3526 
   3527    // Try to parse "of <selector-list>".
   3528    if input.try_parse(|i| i.expect_ident_matching("of")).is_err() {
   3529        return Ok(Component::Nth(nth_data));
   3530    }
   3531    // Whitespace between "of" and the selector list is optional
   3532    // https://github.com/w3c/csswg-drafts/issues/8285
   3533    let selectors = SelectorList::parse_with_state(
   3534        parser,
   3535        input,
   3536        state
   3537            | SelectorParsingState::SKIP_DEFAULT_NAMESPACE
   3538            | SelectorParsingState::DISALLOW_PSEUDOS,
   3539        ForgivingParsing::No,
   3540        ParseRelative::No,
   3541    )?;
   3542    Ok(Component::NthOf(NthOfSelectorData::new(
   3543        &nth_data,
   3544        selectors.slice().iter().cloned(),
   3545    )))
   3546 }
   3547 
   3548 /// Returns whether the name corresponds to a CSS2 pseudo-element that
   3549 /// can be specified with the single colon syntax (in addition to the
   3550 /// double-colon syntax, which can be used for all pseudo-elements).
   3551 pub fn is_css2_pseudo_element(name: &str) -> bool {
   3552    // ** Do not add to this list! **
   3553    match_ignore_ascii_case! { name,
   3554        "before" | "after" | "first-line" | "first-letter" => true,
   3555        _ => false,
   3556    }
   3557 }
   3558 
   3559 /// Parse a simple selector other than a type selector.
   3560 ///
   3561 /// * `Err(())`: Invalid selector, abort
   3562 /// * `Ok(None)`: Not a simple selector, could be something else. `input` was not consumed.
   3563 /// * `Ok(Some(_))`: Parsed a simple selector or pseudo-element
   3564 fn parse_one_simple_selector<'i, 't, P, Impl>(
   3565    parser: &P,
   3566    input: &mut CssParser<'i, 't>,
   3567    state: SelectorParsingState,
   3568 ) -> Result<Option<SimpleSelectorParseResult<Impl>>, ParseError<'i, P::Error>>
   3569 where
   3570    P: Parser<'i, Impl = Impl>,
   3571    Impl: SelectorImpl,
   3572 {
   3573    let start = input.state();
   3574    let token = match input.next_including_whitespace().map(|t| t.clone()) {
   3575        Ok(t) => t,
   3576        Err(..) => {
   3577            input.reset(&start);
   3578            return Ok(None);
   3579        },
   3580    };
   3581 
   3582    Ok(Some(match token {
   3583        Token::IDHash(id) => {
   3584            if state.intersects(SelectorParsingState::AFTER_PSEUDO) {
   3585                return Err(input.new_custom_error(SelectorParseErrorKind::InvalidState));
   3586            }
   3587            let id = Component::ID(id.as_ref().into());
   3588            SimpleSelectorParseResult::SimpleSelector(id)
   3589        },
   3590        Token::Delim(delim) if delim == '.' || (delim == '&' && parser.parse_parent_selector()) => {
   3591            if state.intersects(SelectorParsingState::AFTER_PSEUDO) {
   3592                return Err(input.new_custom_error(SelectorParseErrorKind::InvalidState));
   3593            }
   3594            let location = input.current_source_location();
   3595            SimpleSelectorParseResult::SimpleSelector(if delim == '&' {
   3596                Component::ParentSelector
   3597            } else {
   3598                let class = match *input.next_including_whitespace()? {
   3599                    Token::Ident(ref class) => class,
   3600                    ref t => {
   3601                        let e = SelectorParseErrorKind::ClassNeedsIdent(t.clone());
   3602                        return Err(location.new_custom_error(e));
   3603                    },
   3604                };
   3605                Component::Class(class.as_ref().into())
   3606            })
   3607        },
   3608        Token::SquareBracketBlock => {
   3609            if state.intersects(SelectorParsingState::AFTER_PSEUDO) {
   3610                return Err(input.new_custom_error(SelectorParseErrorKind::InvalidState));
   3611            }
   3612            let attr = input.parse_nested_block(|input| parse_attribute_selector(parser, input))?;
   3613            SimpleSelectorParseResult::SimpleSelector(attr)
   3614        },
   3615        Token::Colon => {
   3616            let location = input.current_source_location();
   3617            let (is_single_colon, next_token) = match input.next_including_whitespace()?.clone() {
   3618                Token::Colon => (false, input.next_including_whitespace()?.clone()),
   3619                t => (true, t),
   3620            };
   3621            let (name, is_functional) = match next_token {
   3622                Token::Ident(name) => (name, false),
   3623                Token::Function(name) => (name, true),
   3624                t => {
   3625                    let e = SelectorParseErrorKind::PseudoElementExpectedIdent(t);
   3626                    return Err(input.new_custom_error(e));
   3627                },
   3628            };
   3629            let is_pseudo_element = !is_single_colon || is_css2_pseudo_element(&name);
   3630            if is_pseudo_element {
   3631                // Pseudos after pseudo elements are not allowed in some cases:
   3632                // - Some states will disallow pseudos, such as the interiors of
   3633                // :has/:is/:where/:not (DISALLOW_PSEUDOS).
   3634                // - Non-element backed pseudos do not allow other pseudos to follow (AFTER_NON_ELEMENT_BACKED_PSEUDO)...
   3635                // - ... except ::before and ::after, which allow _some_ pseudos.
   3636                if state.intersects(SelectorParsingState::DISALLOW_PSEUDOS)
   3637                    || (state.intersects(SelectorParsingState::AFTER_NON_ELEMENT_BACKED_PSEUDO)
   3638                        && !state.intersects(SelectorParsingState::AFTER_BEFORE_OR_AFTER_PSEUDO))
   3639                {
   3640                    return Err(input.new_custom_error(SelectorParseErrorKind::InvalidState));
   3641                }
   3642                let pseudo_element = if is_functional {
   3643                    if P::parse_part(parser) && name.eq_ignore_ascii_case("part") {
   3644                        if !state.allows_part() {
   3645                            return Err(
   3646                                input.new_custom_error(SelectorParseErrorKind::InvalidState)
   3647                            );
   3648                        }
   3649                        let names = input.parse_nested_block(|input| {
   3650                            let mut result = Vec::with_capacity(1);
   3651                            result.push(input.expect_ident()?.as_ref().into());
   3652                            while !input.is_exhausted() {
   3653                                result.push(input.expect_ident()?.as_ref().into());
   3654                            }
   3655                            Ok(result.into_boxed_slice())
   3656                        })?;
   3657                        return Ok(Some(SimpleSelectorParseResult::PartPseudo(names)));
   3658                    }
   3659                    if P::parse_slotted(parser) && name.eq_ignore_ascii_case("slotted") {
   3660                        if !state.allows_slotted() {
   3661                            return Err(
   3662                                input.new_custom_error(SelectorParseErrorKind::InvalidState)
   3663                            );
   3664                        }
   3665                        let selector = input.parse_nested_block(|input| {
   3666                            parse_inner_compound_selector(parser, input, state)
   3667                        })?;
   3668                        return Ok(Some(SimpleSelectorParseResult::SlottedPseudo(selector)));
   3669                    }
   3670                    input.parse_nested_block(|input| {
   3671                        P::parse_functional_pseudo_element(parser, name, input)
   3672                    })?
   3673                } else {
   3674                    P::parse_pseudo_element(parser, location, name)?
   3675                };
   3676 
   3677                if state.intersects(SelectorParsingState::AFTER_BEFORE_OR_AFTER_PSEUDO)
   3678                    && !pseudo_element.valid_after_before_or_after()
   3679                {
   3680                    return Err(input.new_custom_error(SelectorParseErrorKind::InvalidState));
   3681                }
   3682 
   3683                if state.intersects(SelectorParsingState::AFTER_SLOTTED)
   3684                    && !pseudo_element.valid_after_slotted()
   3685                {
   3686                    return Err(input.new_custom_error(SelectorParseErrorKind::InvalidState));
   3687                }
   3688                SimpleSelectorParseResult::PseudoElement(pseudo_element)
   3689            } else {
   3690                let pseudo_class = if is_functional {
   3691                    input.parse_nested_block(|input| {
   3692                        parse_functional_pseudo_class(parser, input, name, state)
   3693                    })?
   3694                } else {
   3695                    parse_simple_pseudo_class(parser, location, name, state)?
   3696                };
   3697                SimpleSelectorParseResult::SimpleSelector(pseudo_class)
   3698            }
   3699        },
   3700        _ => {
   3701            input.reset(&start);
   3702            return Ok(None);
   3703        },
   3704    }))
   3705 }
   3706 
   3707 fn parse_simple_pseudo_class<'i, P, Impl>(
   3708    parser: &P,
   3709    location: SourceLocation,
   3710    name: CowRcStr<'i>,
   3711    state: SelectorParsingState,
   3712 ) -> Result<Component<Impl>, ParseError<'i, P::Error>>
   3713 where
   3714    P: Parser<'i, Impl = Impl>,
   3715    Impl: SelectorImpl,
   3716 {
   3717    if !state.allows_non_functional_pseudo_classes() {
   3718        return Err(location.new_custom_error(SelectorParseErrorKind::InvalidState));
   3719    }
   3720 
   3721    if state.allows_tree_structural_pseudo_classes() {
   3722        // If a descendant pseudo of a pseudo-element root has no other siblings, then :only-child
   3723        // matches that pseudo. Note that we don't accept other tree structural pseudo classes in
   3724        // this case (to match other browsers). And the spec mentions only `:only-child` as well.
   3725        // https://drafts.csswg.org/css-view-transitions-1/#pseudo-root
   3726        if state.allows_only_child_pseudo_class_only() {
   3727            if name.eq_ignore_ascii_case("only-child") {
   3728                return Ok(Component::Nth(NthSelectorData::only(
   3729                    /* of_type = */ false,
   3730                )));
   3731            }
   3732            // Other non-functional pseudo classes are not allowed.
   3733            // FIXME: Perhaps we can refactor this, e.g. distinguish tree-structural pseudo classes
   3734            // from other non-ts pseudo classes. Otherwise, this special case looks weird.
   3735            return Err(location.new_custom_error(SelectorParseErrorKind::InvalidState));
   3736        }
   3737 
   3738        match_ignore_ascii_case! { &name,
   3739            "first-child" => return Ok(Component::Nth(NthSelectorData::first(/* of_type = */ false))),
   3740            "last-child" => return Ok(Component::Nth(NthSelectorData::last(/* of_type = */ false))),
   3741            "only-child" => return Ok(Component::Nth(NthSelectorData::only(/* of_type = */ false))),
   3742            "root" => return Ok(Component::Root),
   3743            "empty" => return Ok(Component::Empty),
   3744            "scope" => return Ok(Component::Scope),
   3745            "host" if P::parse_host(parser) => return Ok(Component::Host(None)),
   3746            "first-of-type" => return Ok(Component::Nth(NthSelectorData::first(/* of_type = */ true))),
   3747            "last-of-type" => return Ok(Component::Nth(NthSelectorData::last(/* of_type = */ true))),
   3748            "only-of-type" => return Ok(Component::Nth(NthSelectorData::only(/* of_type = */ true))),
   3749            _ => {},
   3750        }
   3751    }
   3752 
   3753    let pseudo_class = P::parse_non_ts_pseudo_class(parser, location, name)?;
   3754    if state.intersects(SelectorParsingState::AFTER_NON_ELEMENT_BACKED_PSEUDO)
   3755        && !pseudo_class.is_user_action_state()
   3756    {
   3757        return Err(location.new_custom_error(SelectorParseErrorKind::InvalidState));
   3758    }
   3759    Ok(Component::NonTSPseudoClass(pseudo_class))
   3760 }
   3761 
   3762 // NB: pub module in order to access the DummyParser
   3763 #[cfg(test)]
   3764 pub mod tests {
   3765    use super::*;
   3766    use crate::builder::SelectorFlags;
   3767    use crate::parser;
   3768    use cssparser::{serialize_identifier, Parser as CssParser, ParserInput, ToCss};
   3769    use std::collections::HashMap;
   3770    use std::fmt;
   3771 
   3772    #[derive(Clone, Debug, Eq, PartialEq)]
   3773    pub enum PseudoClass {
   3774        Hover,
   3775        Active,
   3776        Lang(String),
   3777    }
   3778 
   3779    #[derive(Clone, Debug, Eq, PartialEq)]
   3780    pub enum PseudoElement {
   3781        Before,
   3782        After,
   3783        Marker,
   3784        DetailsContent,
   3785        Highlight(String),
   3786    }
   3787 
   3788    impl parser::PseudoElement for PseudoElement {
   3789        type Impl = DummySelectorImpl;
   3790 
   3791        fn accepts_state_pseudo_classes(&self) -> bool {
   3792            true
   3793        }
   3794 
   3795        fn valid_after_slotted(&self) -> bool {
   3796            true
   3797        }
   3798 
   3799        fn valid_after_before_or_after(&self) -> bool {
   3800            matches!(self, Self::Marker)
   3801        }
   3802 
   3803        fn is_before_or_after(&self) -> bool {
   3804            matches!(self, Self::Before | Self::After)
   3805        }
   3806 
   3807        fn is_element_backed(&self) -> bool {
   3808            matches!(self, Self::DetailsContent)
   3809        }
   3810    }
   3811 
   3812    impl parser::NonTSPseudoClass for PseudoClass {
   3813        type Impl = DummySelectorImpl;
   3814 
   3815        #[inline]
   3816        fn is_active_or_hover(&self) -> bool {
   3817            matches!(*self, PseudoClass::Active | PseudoClass::Hover)
   3818        }
   3819 
   3820        #[inline]
   3821        fn is_user_action_state(&self) -> bool {
   3822            self.is_active_or_hover()
   3823        }
   3824    }
   3825 
   3826    impl ToCss for PseudoClass {
   3827        fn to_css<W>(&self, dest: &mut W) -> fmt::Result
   3828        where
   3829            W: fmt::Write,
   3830        {
   3831            match *self {
   3832                PseudoClass::Hover => dest.write_str(":hover"),
   3833                PseudoClass::Active => dest.write_str(":active"),
   3834                PseudoClass::Lang(ref lang) => {
   3835                    dest.write_str(":lang(")?;
   3836                    serialize_identifier(lang, dest)?;
   3837                    dest.write_char(')')
   3838                },
   3839            }
   3840        }
   3841    }
   3842 
   3843    impl ToCss for PseudoElement {
   3844        fn to_css<W>(&self, dest: &mut W) -> fmt::Result
   3845        where
   3846            W: fmt::Write,
   3847        {
   3848            match *self {
   3849                PseudoElement::Before => dest.write_str("::before"),
   3850                PseudoElement::After => dest.write_str("::after"),
   3851                PseudoElement::Marker => dest.write_str("::marker"),
   3852                PseudoElement::DetailsContent => dest.write_str("::details-content"),
   3853                PseudoElement::Highlight(ref name) => {
   3854                    dest.write_str("::highlight(")?;
   3855                    serialize_identifier(&name, dest)?;
   3856                    dest.write_char(')')
   3857                },
   3858            }
   3859        }
   3860    }
   3861 
   3862    #[derive(Clone, Debug, PartialEq)]
   3863    pub struct DummySelectorImpl;
   3864 
   3865    #[derive(Default)]
   3866    pub struct DummyParser {
   3867        default_ns: Option<DummyAtom>,
   3868        ns_prefixes: HashMap<DummyAtom, DummyAtom>,
   3869    }
   3870 
   3871    impl DummyParser {
   3872        fn default_with_namespace(default_ns: DummyAtom) -> DummyParser {
   3873            DummyParser {
   3874                default_ns: Some(default_ns),
   3875                ns_prefixes: Default::default(),
   3876            }
   3877        }
   3878    }
   3879 
   3880    impl SelectorImpl for DummySelectorImpl {
   3881        type ExtraMatchingData<'a> = std::marker::PhantomData<&'a ()>;
   3882        type AttrValue = DummyAttrValue;
   3883        type Identifier = DummyAtom;
   3884        type LocalName = DummyAtom;
   3885        type NamespaceUrl = DummyAtom;
   3886        type NamespacePrefix = DummyAtom;
   3887        type BorrowedLocalName = DummyAtom;
   3888        type BorrowedNamespaceUrl = DummyAtom;
   3889        type NonTSPseudoClass = PseudoClass;
   3890        type PseudoElement = PseudoElement;
   3891    }
   3892 
   3893    #[derive(Clone, Debug, Default, Eq, Hash, PartialEq)]
   3894    pub struct DummyAttrValue(String);
   3895 
   3896    impl ToCss for DummyAttrValue {
   3897        fn to_css<W>(&self, dest: &mut W) -> fmt::Result
   3898        where
   3899            W: fmt::Write,
   3900        {
   3901            use std::fmt::Write;
   3902 
   3903            dest.write_char('"')?;
   3904            write!(cssparser::CssStringWriter::new(dest), "{}", &self.0)?;
   3905            dest.write_char('"')
   3906        }
   3907    }
   3908 
   3909    impl<'a> From<&'a str> for DummyAttrValue {
   3910        fn from(string: &'a str) -> Self {
   3911            Self(string.into())
   3912        }
   3913    }
   3914 
   3915    #[derive(Clone, Debug, Default, Eq, Hash, PartialEq)]
   3916    pub struct DummyAtom(String);
   3917 
   3918    impl ToCss for DummyAtom {
   3919        fn to_css<W>(&self, dest: &mut W) -> fmt::Result
   3920        where
   3921            W: fmt::Write,
   3922        {
   3923            serialize_identifier(&self.0, dest)
   3924        }
   3925    }
   3926 
   3927    impl From<String> for DummyAtom {
   3928        fn from(string: String) -> Self {
   3929            DummyAtom(string)
   3930        }
   3931    }
   3932 
   3933    impl<'a> From<&'a str> for DummyAtom {
   3934        fn from(string: &'a str) -> Self {
   3935            DummyAtom(string.into())
   3936        }
   3937    }
   3938 
   3939    impl PrecomputedHash for DummyAtom {
   3940        fn precomputed_hash(&self) -> u32 {
   3941            self.0.as_ptr() as u32
   3942        }
   3943    }
   3944 
   3945    impl<'i> Parser<'i> for DummyParser {
   3946        type Impl = DummySelectorImpl;
   3947        type Error = SelectorParseErrorKind<'i>;
   3948 
   3949        fn parse_slotted(&self) -> bool {
   3950            true
   3951        }
   3952 
   3953        fn parse_nth_child_of(&self) -> bool {
   3954            true
   3955        }
   3956 
   3957        fn parse_is_and_where(&self) -> bool {
   3958            true
   3959        }
   3960 
   3961        fn parse_has(&self) -> bool {
   3962            true
   3963        }
   3964 
   3965        fn parse_parent_selector(&self) -> bool {
   3966            true
   3967        }
   3968 
   3969        fn parse_part(&self) -> bool {
   3970            true
   3971        }
   3972 
   3973        fn parse_host(&self) -> bool {
   3974            true
   3975        }
   3976 
   3977        fn parse_non_ts_pseudo_class(
   3978            &self,
   3979            location: SourceLocation,
   3980            name: CowRcStr<'i>,
   3981        ) -> Result<PseudoClass, SelectorParseError<'i>> {
   3982            match_ignore_ascii_case! { &name,
   3983                "hover" => return Ok(PseudoClass::Hover),
   3984                "active" => return Ok(PseudoClass::Active),
   3985                _ => {}
   3986            }
   3987            Err(
   3988                location.new_custom_error(SelectorParseErrorKind::UnsupportedPseudoClassOrElement(
   3989                    name,
   3990                )),
   3991            )
   3992        }
   3993 
   3994        fn parse_non_ts_functional_pseudo_class<'t>(
   3995            &self,
   3996            name: CowRcStr<'i>,
   3997            parser: &mut CssParser<'i, 't>,
   3998            after_part: bool,
   3999        ) -> Result<PseudoClass, SelectorParseError<'i>> {
   4000            match_ignore_ascii_case! { &name,
   4001                "lang" if !after_part => {
   4002                    let lang = parser.expect_ident_or_string()?.as_ref().to_owned();
   4003                    return Ok(PseudoClass::Lang(lang));
   4004                },
   4005                _ => {}
   4006            }
   4007            Err(
   4008                parser.new_custom_error(SelectorParseErrorKind::UnsupportedPseudoClassOrElement(
   4009                    name,
   4010                )),
   4011            )
   4012        }
   4013 
   4014        fn parse_pseudo_element(
   4015            &self,
   4016            location: SourceLocation,
   4017            name: CowRcStr<'i>,
   4018        ) -> Result<PseudoElement, SelectorParseError<'i>> {
   4019            match_ignore_ascii_case! { &name,
   4020                "before" => return Ok(PseudoElement::Before),
   4021                "after" => return Ok(PseudoElement::After),
   4022                "marker" => return Ok(PseudoElement::Marker),
   4023                "details-content" => return Ok(PseudoElement::DetailsContent),
   4024                _ => {}
   4025            }
   4026            Err(
   4027                location.new_custom_error(SelectorParseErrorKind::UnsupportedPseudoClassOrElement(
   4028                    name,
   4029                )),
   4030            )
   4031        }
   4032 
   4033        fn parse_functional_pseudo_element<'t>(
   4034            &self,
   4035            name: CowRcStr<'i>,
   4036            parser: &mut CssParser<'i, 't>,
   4037        ) -> Result<PseudoElement, SelectorParseError<'i>> {
   4038            match_ignore_ascii_case! {&name,
   4039                "highlight" => return Ok(PseudoElement::Highlight(parser.expect_ident()?.as_ref().to_owned())),
   4040                _ => {}
   4041            }
   4042            Err(
   4043                parser.new_custom_error(SelectorParseErrorKind::UnsupportedPseudoClassOrElement(
   4044                    name,
   4045                )),
   4046            )
   4047        }
   4048 
   4049        fn default_namespace(&self) -> Option<DummyAtom> {
   4050            self.default_ns.clone()
   4051        }
   4052 
   4053        fn namespace_for_prefix(&self, prefix: &DummyAtom) -> Option<DummyAtom> {
   4054            self.ns_prefixes.get(prefix).cloned()
   4055        }
   4056    }
   4057 
   4058    fn parse<'i>(
   4059        input: &'i str,
   4060    ) -> Result<SelectorList<DummySelectorImpl>, SelectorParseError<'i>> {
   4061        parse_relative(input, ParseRelative::No)
   4062    }
   4063 
   4064    fn parse_relative<'i>(
   4065        input: &'i str,
   4066        parse_relative: ParseRelative,
   4067    ) -> Result<SelectorList<DummySelectorImpl>, SelectorParseError<'i>> {
   4068        parse_ns_relative(input, &DummyParser::default(), parse_relative)
   4069    }
   4070 
   4071    fn parse_expected<'i, 'a>(
   4072        input: &'i str,
   4073        expected: Option<&'a str>,
   4074    ) -> Result<SelectorList<DummySelectorImpl>, SelectorParseError<'i>> {
   4075        parse_ns_expected(input, &DummyParser::default(), expected)
   4076    }
   4077 
   4078    fn parse_relative_expected<'i, 'a>(
   4079        input: &'i str,
   4080        parse_relative: ParseRelative,
   4081        expected: Option<&'a str>,
   4082    ) -> Result<SelectorList<DummySelectorImpl>, SelectorParseError<'i>> {
   4083        parse_ns_relative_expected(input, &DummyParser::default(), parse_relative, expected)
   4084    }
   4085 
   4086    fn parse_ns<'i>(
   4087        input: &'i str,
   4088        parser: &DummyParser,
   4089    ) -> Result<SelectorList<DummySelectorImpl>, SelectorParseError<'i>> {
   4090        parse_ns_relative(input, parser, ParseRelative::No)
   4091    }
   4092 
   4093    fn parse_ns_relative<'i>(
   4094        input: &'i str,
   4095        parser: &DummyParser,
   4096        parse_relative: ParseRelative,
   4097    ) -> Result<SelectorList<DummySelectorImpl>, SelectorParseError<'i>> {
   4098        parse_ns_relative_expected(input, parser, parse_relative, None)
   4099    }
   4100 
   4101    fn parse_ns_expected<'i, 'a>(
   4102        input: &'i str,
   4103        parser: &DummyParser,
   4104        expected: Option<&'a str>,
   4105    ) -> Result<SelectorList<DummySelectorImpl>, SelectorParseError<'i>> {
   4106        parse_ns_relative_expected(input, parser, ParseRelative::No, expected)
   4107    }
   4108 
   4109    fn parse_ns_relative_expected<'i, 'a>(
   4110        input: &'i str,
   4111        parser: &DummyParser,
   4112        parse_relative: ParseRelative,
   4113        expected: Option<&'a str>,
   4114    ) -> Result<SelectorList<DummySelectorImpl>, SelectorParseError<'i>> {
   4115        let mut parser_input = ParserInput::new(input);
   4116        let result = SelectorList::parse(
   4117            parser,
   4118            &mut CssParser::new(&mut parser_input),
   4119            parse_relative,
   4120        );
   4121        if let Ok(ref selectors) = result {
   4122            // We can't assume that the serialized parsed selector will equal
   4123            // the input; for example, if there is no default namespace, '*|foo'
   4124            // should serialize to 'foo'.
   4125            assert_eq!(
   4126                selectors.to_css_string(),
   4127                match expected {
   4128                    Some(x) => x,
   4129                    None => input,
   4130                }
   4131            );
   4132        }
   4133        result
   4134    }
   4135 
   4136    fn specificity(a: u32, b: u32, c: u32) -> u32 {
   4137        a << 20 | b << 10 | c
   4138    }
   4139 
   4140    #[test]
   4141    fn test_empty() {
   4142        let mut input = ParserInput::new(":empty");
   4143        let list = SelectorList::parse(
   4144            &DummyParser::default(),
   4145            &mut CssParser::new(&mut input),
   4146            ParseRelative::No,
   4147        );
   4148        assert!(list.is_ok());
   4149    }
   4150 
   4151    const MATHML: &str = "http://www.w3.org/1998/Math/MathML";
   4152    const SVG: &str = "http://www.w3.org/2000/svg";
   4153 
   4154    #[test]
   4155    fn test_parsing() {
   4156        assert!(parse("").is_err());
   4157        assert!(parse(":lang(4)").is_err());
   4158        assert!(parse(":lang(en US)").is_err());
   4159        assert_eq!(
   4160            parse("EeÉ"),
   4161            Ok(SelectorList::from_vec(vec![Selector::from_vec(
   4162                vec![Component::LocalName(LocalName {
   4163                    name: DummyAtom::from("EeÉ"),
   4164                    lower_name: DummyAtom::from("eeÉ"),
   4165                })],
   4166                specificity(0, 0, 1),
   4167                SelectorFlags::empty(),
   4168            )]))
   4169        );
   4170        assert_eq!(
   4171            parse("|e"),
   4172            Ok(SelectorList::from_vec(vec![Selector::from_vec(
   4173                vec![
   4174                    Component::ExplicitNoNamespace,
   4175                    Component::LocalName(LocalName {
   4176                        name: DummyAtom::from("e"),
   4177                        lower_name: DummyAtom::from("e"),
   4178                    }),
   4179                ],
   4180                specificity(0, 0, 1),
   4181                SelectorFlags::empty(),
   4182            )]))
   4183        );
   4184        // When the default namespace is not set, *| should be elided.
   4185        // https://github.com/servo/servo/pull/17537
   4186        assert_eq!(
   4187            parse_expected("*|e", Some("e")),
   4188            Ok(SelectorList::from_vec(vec![Selector::from_vec(
   4189                vec![Component::LocalName(LocalName {
   4190                    name: DummyAtom::from("e"),
   4191                    lower_name: DummyAtom::from("e"),
   4192                })],
   4193                specificity(0, 0, 1),
   4194                SelectorFlags::empty(),
   4195            )]))
   4196        );
   4197        // When the default namespace is set, *| should _not_ be elided (as foo
   4198        // is no longer equivalent to *|foo--the former is only for foo in the
   4199        // default namespace).
   4200        // https://github.com/servo/servo/issues/16020
   4201        assert_eq!(
   4202            parse_ns(
   4203                "*|e",
   4204                &DummyParser::default_with_namespace(DummyAtom::from("https://mozilla.org"))
   4205            ),
   4206            Ok(SelectorList::from_vec(vec![Selector::from_vec(
   4207                vec![
   4208                    Component::ExplicitAnyNamespace,
   4209                    Component::LocalName(LocalName {
   4210                        name: DummyAtom::from("e"),
   4211                        lower_name: DummyAtom::from("e"),
   4212                    }),
   4213                ],
   4214                specificity(0, 0, 1),
   4215                SelectorFlags::empty(),
   4216            )]))
   4217        );
   4218        assert_eq!(
   4219            parse("*"),
   4220            Ok(SelectorList::from_vec(vec![Selector::from_vec(
   4221                vec![Component::ExplicitUniversalType],
   4222                specificity(0, 0, 0),
   4223                SelectorFlags::empty(),
   4224            )]))
   4225        );
   4226        assert_eq!(
   4227            parse("|*"),
   4228            Ok(SelectorList::from_vec(vec![Selector::from_vec(
   4229                vec![
   4230                    Component::ExplicitNoNamespace,
   4231                    Component::ExplicitUniversalType,
   4232                ],
   4233                specificity(0, 0, 0),
   4234                SelectorFlags::empty(),
   4235            )]))
   4236        );
   4237        assert_eq!(
   4238            parse_expected("*|*", Some("*")),
   4239            Ok(SelectorList::from_vec(vec![Selector::from_vec(
   4240                vec![Component::ExplicitUniversalType],
   4241                specificity(0, 0, 0),
   4242                SelectorFlags::empty(),
   4243            )]))
   4244        );
   4245        assert_eq!(
   4246            parse_ns(
   4247                "*|*",
   4248                &DummyParser::default_with_namespace(DummyAtom::from("https://mozilla.org"))
   4249            ),
   4250            Ok(SelectorList::from_vec(vec![Selector::from_vec(
   4251                vec![
   4252                    Component::ExplicitAnyNamespace,
   4253                    Component::ExplicitUniversalType,
   4254                ],
   4255                specificity(0, 0, 0),
   4256                SelectorFlags::empty(),
   4257            )]))
   4258        );
   4259        assert_eq!(
   4260            parse(".foo:lang(en-US)"),
   4261            Ok(SelectorList::from_vec(vec![Selector::from_vec(
   4262                vec![
   4263                    Component::Class(DummyAtom::from("foo")),
   4264                    Component::NonTSPseudoClass(PseudoClass::Lang("en-US".to_owned())),
   4265                ],
   4266                specificity(0, 2, 0),
   4267                SelectorFlags::empty(),
   4268            )]))
   4269        );
   4270        assert_eq!(
   4271            parse("#bar"),
   4272            Ok(SelectorList::from_vec(vec![Selector::from_vec(
   4273                vec![Component::ID(DummyAtom::from("bar"))],
   4274                specificity(1, 0, 0),
   4275                SelectorFlags::empty(),
   4276            )]))
   4277        );
   4278        assert_eq!(
   4279            parse("e.foo#bar"),
   4280            Ok(SelectorList::from_vec(vec![Selector::from_vec(
   4281                vec![
   4282                    Component::LocalName(LocalName {
   4283                        name: DummyAtom::from("e"),
   4284                        lower_name: DummyAtom::from("e"),
   4285                    }),
   4286                    Component::Class(DummyAtom::from("foo")),
   4287                    Component::ID(DummyAtom::from("bar")),
   4288                ],
   4289                specificity(1, 1, 1),
   4290                SelectorFlags::empty(),
   4291            )]))
   4292        );
   4293        assert_eq!(
   4294            parse("e.foo #bar"),
   4295            Ok(SelectorList::from_vec(vec![Selector::from_vec(
   4296                vec![
   4297                    Component::LocalName(LocalName {
   4298                        name: DummyAtom::from("e"),
   4299                        lower_name: DummyAtom::from("e"),
   4300                    }),
   4301                    Component::Class(DummyAtom::from("foo")),
   4302                    Component::Combinator(Combinator::Descendant),
   4303                    Component::ID(DummyAtom::from("bar")),
   4304                ],
   4305                specificity(1, 1, 1),
   4306                SelectorFlags::empty(),
   4307            )]))
   4308        );
   4309        // Default namespace does not apply to attribute selectors
   4310        // https://github.com/mozilla/servo/pull/1652
   4311        let mut parser = DummyParser::default();
   4312        assert_eq!(
   4313            parse_ns("[Foo]", &parser),
   4314            Ok(SelectorList::from_vec(vec![Selector::from_vec(
   4315                vec![Component::AttributeInNoNamespaceExists {
   4316                    local_name: DummyAtom::from("Foo"),
   4317                    local_name_lower: DummyAtom::from("foo"),
   4318                }],
   4319                specificity(0, 1, 0),
   4320                SelectorFlags::empty(),
   4321            )]))
   4322        );
   4323        assert!(parse_ns("svg|circle", &parser).is_err());
   4324        parser
   4325            .ns_prefixes
   4326            .insert(DummyAtom("svg".into()), DummyAtom(SVG.into()));
   4327        assert_eq!(
   4328            parse_ns("svg|circle", &parser),
   4329            Ok(SelectorList::from_vec(vec![Selector::from_vec(
   4330                vec![
   4331                    Component::Namespace(DummyAtom("svg".into()), SVG.into()),
   4332                    Component::LocalName(LocalName {
   4333                        name: DummyAtom::from("circle"),
   4334                        lower_name: DummyAtom::from("circle"),
   4335                    }),
   4336                ],
   4337                specificity(0, 0, 1),
   4338                SelectorFlags::empty(),
   4339            )]))
   4340        );
   4341        assert_eq!(
   4342            parse_ns("svg|*", &parser),
   4343            Ok(SelectorList::from_vec(vec![Selector::from_vec(
   4344                vec![
   4345                    Component::Namespace(DummyAtom("svg".into()), SVG.into()),
   4346                    Component::ExplicitUniversalType,
   4347                ],
   4348                specificity(0, 0, 0),
   4349                SelectorFlags::empty(),
   4350            )]))
   4351        );
   4352        // Default namespace does not apply to attribute selectors
   4353        // https://github.com/mozilla/servo/pull/1652
   4354        // but it does apply to implicit type selectors
   4355        // https://github.com/servo/rust-selectors/pull/82
   4356        parser.default_ns = Some(MATHML.into());
   4357        assert_eq!(
   4358            parse_ns("[Foo]", &parser),
   4359            Ok(SelectorList::from_vec(vec![Selector::from_vec(
   4360                vec![
   4361                    Component::DefaultNamespace(MATHML.into()),
   4362                    Component::AttributeInNoNamespaceExists {
   4363                        local_name: DummyAtom::from("Foo"),
   4364                        local_name_lower: DummyAtom::from("foo"),
   4365                    },
   4366                ],
   4367                specificity(0, 1, 0),
   4368                SelectorFlags::empty(),
   4369            )]))
   4370        );
   4371        // Default namespace does apply to type selectors
   4372        assert_eq!(
   4373            parse_ns("e", &parser),
   4374            Ok(SelectorList::from_vec(vec![Selector::from_vec(
   4375                vec![
   4376                    Component::DefaultNamespace(MATHML.into()),
   4377                    Component::LocalName(LocalName {
   4378                        name: DummyAtom::from("e"),
   4379                        lower_name: DummyAtom::from("e"),
   4380                    }),
   4381                ],
   4382                specificity(0, 0, 1),
   4383                SelectorFlags::empty(),
   4384            )]))
   4385        );
   4386        assert_eq!(
   4387            parse_ns("*", &parser),
   4388            Ok(SelectorList::from_vec(vec![Selector::from_vec(
   4389                vec![
   4390                    Component::DefaultNamespace(MATHML.into()),
   4391                    Component::ExplicitUniversalType,
   4392                ],
   4393                specificity(0, 0, 0),
   4394                SelectorFlags::empty(),
   4395            )]))
   4396        );
   4397        assert_eq!(
   4398            parse_ns("*|*", &parser),
   4399            Ok(SelectorList::from_vec(vec![Selector::from_vec(
   4400                vec![
   4401                    Component::ExplicitAnyNamespace,
   4402                    Component::ExplicitUniversalType,
   4403                ],
   4404                specificity(0, 0, 0),
   4405                SelectorFlags::empty(),
   4406            )]))
   4407        );
   4408        // Default namespace applies to universal and type selectors inside :not and :matches,
   4409        // but not otherwise.
   4410        assert_eq!(
   4411            parse_ns(":not(.cl)", &parser),
   4412            Ok(SelectorList::from_vec(vec![Selector::from_vec(
   4413                vec![
   4414                    Component::DefaultNamespace(MATHML.into()),
   4415                    Component::Negation(SelectorList::from_vec(vec![Selector::from_vec(
   4416                        vec![Component::Class(DummyAtom::from("cl"))],
   4417                        specificity(0, 1, 0),
   4418                        SelectorFlags::empty(),
   4419                    )])),
   4420                ],
   4421                specificity(0, 1, 0),
   4422                SelectorFlags::empty(),
   4423            )]))
   4424        );
   4425        assert_eq!(
   4426            parse_ns(":not(*)", &parser),
   4427            Ok(SelectorList::from_vec(vec![Selector::from_vec(
   4428                vec![
   4429                    Component::DefaultNamespace(MATHML.into()),
   4430                    Component::Negation(SelectorList::from_vec(vec![Selector::from_vec(
   4431                        vec![
   4432                            Component::DefaultNamespace(MATHML.into()),
   4433                            Component::ExplicitUniversalType,
   4434                        ],
   4435                        specificity(0, 0, 0),
   4436                        SelectorFlags::empty(),
   4437                    )]),),
   4438                ],
   4439                specificity(0, 0, 0),
   4440                SelectorFlags::empty(),
   4441            )]))
   4442        );
   4443        assert_eq!(
   4444            parse_ns(":not(e)", &parser),
   4445            Ok(SelectorList::from_vec(vec![Selector::from_vec(
   4446                vec![
   4447                    Component::DefaultNamespace(MATHML.into()),
   4448                    Component::Negation(SelectorList::from_vec(vec![Selector::from_vec(
   4449                        vec![
   4450                            Component::DefaultNamespace(MATHML.into()),
   4451                            Component::LocalName(LocalName {
   4452                                name: DummyAtom::from("e"),
   4453                                lower_name: DummyAtom::from("e"),
   4454                            }),
   4455                        ],
   4456                        specificity(0, 0, 1),
   4457                        SelectorFlags::empty(),
   4458                    )])),
   4459                ],
   4460                specificity(0, 0, 1),
   4461                SelectorFlags::empty(),
   4462            )]))
   4463        );
   4464        assert_eq!(
   4465            parse("[attr|=\"foo\"]"),
   4466            Ok(SelectorList::from_vec(vec![Selector::from_vec(
   4467                vec![Component::AttributeInNoNamespace {
   4468                    local_name: DummyAtom::from("attr"),
   4469                    operator: AttrSelectorOperator::DashMatch,
   4470                    value: DummyAttrValue::from("foo"),
   4471                    case_sensitivity: ParsedCaseSensitivity::CaseSensitive,
   4472                }],
   4473                specificity(0, 1, 0),
   4474                SelectorFlags::empty(),
   4475            )]))
   4476        );
   4477        // https://github.com/mozilla/servo/issues/1723
   4478        assert_eq!(
   4479            parse("::before"),
   4480            Ok(SelectorList::from_vec(vec![Selector::from_vec(
   4481                vec![
   4482                    Component::Combinator(Combinator::PseudoElement),
   4483                    Component::PseudoElement(PseudoElement::Before),
   4484                ],
   4485                specificity(0, 0, 1),
   4486                SelectorFlags::HAS_PSEUDO,
   4487            )]))
   4488        );
   4489        assert_eq!(
   4490            parse("::before:hover"),
   4491            Ok(SelectorList::from_vec(vec![Selector::from_vec(
   4492                vec![
   4493                    Component::Combinator(Combinator::PseudoElement),
   4494                    Component::PseudoElement(PseudoElement::Before),
   4495                    Component::NonTSPseudoClass(PseudoClass::Hover),
   4496                ],
   4497                specificity(0, 1, 1),
   4498                SelectorFlags::HAS_PSEUDO,
   4499            )]))
   4500        );
   4501        assert_eq!(
   4502            parse("::before:hover:hover"),
   4503            Ok(SelectorList::from_vec(vec![Selector::from_vec(
   4504                vec![
   4505                    Component::Combinator(Combinator::PseudoElement),
   4506                    Component::PseudoElement(PseudoElement::Before),
   4507                    Component::NonTSPseudoClass(PseudoClass::Hover),
   4508                    Component::NonTSPseudoClass(PseudoClass::Hover),
   4509                ],
   4510                specificity(0, 2, 1),
   4511                SelectorFlags::HAS_PSEUDO,
   4512            )]))
   4513        );
   4514        assert!(parse("::before:hover:lang(foo)").is_err());
   4515        assert!(parse("::before:hover .foo").is_err());
   4516        assert!(parse("::before .foo").is_err());
   4517        assert!(parse("::before ~ bar").is_err());
   4518        assert!(parse("::before:active").is_ok());
   4519 
   4520        // https://github.com/servo/servo/issues/15335
   4521        assert!(parse(":: before").is_err());
   4522        assert_eq!(
   4523            parse("div ::after"),
   4524            Ok(SelectorList::from_vec(vec![Selector::from_vec(
   4525                vec![
   4526                    Component::LocalName(LocalName {
   4527                        name: DummyAtom::from("div"),
   4528                        lower_name: DummyAtom::from("div"),
   4529                    }),
   4530                    Component::Combinator(Combinator::Descendant),
   4531                    Component::Combinator(Combinator::PseudoElement),
   4532                    Component::PseudoElement(PseudoElement::After),
   4533                ],
   4534                specificity(0, 0, 2),
   4535                SelectorFlags::HAS_PSEUDO,
   4536            )]))
   4537        );
   4538        assert_eq!(
   4539            parse("#d1 > .ok"),
   4540            Ok(SelectorList::from_vec(vec![Selector::from_vec(
   4541                vec![
   4542                    Component::ID(DummyAtom::from("d1")),
   4543                    Component::Combinator(Combinator::Child),
   4544                    Component::Class(DummyAtom::from("ok")),
   4545                ],
   4546                specificity(1, 1, 0),
   4547                SelectorFlags::empty(),
   4548            )]))
   4549        );
   4550        parser.default_ns = None;
   4551        assert!(parse(":not(#provel.old)").is_ok());
   4552        assert!(parse(":not(#provel > old)").is_ok());
   4553        assert!(parse("table[rules]:not([rules=\"none\"]):not([rules=\"\"])").is_ok());
   4554        // https://github.com/servo/servo/issues/16017
   4555        assert_eq!(
   4556            parse_ns(":not(*)", &parser),
   4557            Ok(SelectorList::from_vec(vec![Selector::from_vec(
   4558                vec![Component::Negation(SelectorList::from_vec(vec![
   4559                    Selector::from_vec(
   4560                        vec![Component::ExplicitUniversalType],
   4561                        specificity(0, 0, 0),
   4562                        SelectorFlags::empty(),
   4563                    )
   4564                ]))],
   4565                specificity(0, 0, 0),
   4566                SelectorFlags::empty(),
   4567            )]))
   4568        );
   4569        assert_eq!(
   4570            parse_ns(":not(|*)", &parser),
   4571            Ok(SelectorList::from_vec(vec![Selector::from_vec(
   4572                vec![Component::Negation(SelectorList::from_vec(vec![
   4573                    Selector::from_vec(
   4574                        vec![
   4575                            Component::ExplicitNoNamespace,
   4576                            Component::ExplicitUniversalType,
   4577                        ],
   4578                        specificity(0, 0, 0),
   4579                        SelectorFlags::empty(),
   4580                    )
   4581                ]))],
   4582                specificity(0, 0, 0),
   4583                SelectorFlags::empty(),
   4584            )]))
   4585        );
   4586        // *| should be elided if there is no default namespace.
   4587        // https://github.com/servo/servo/pull/17537
   4588        assert_eq!(
   4589            parse_ns_expected(":not(*|*)", &parser, Some(":not(*)")),
   4590            Ok(SelectorList::from_vec(vec![Selector::from_vec(
   4591                vec![Component::Negation(SelectorList::from_vec(vec![
   4592                    Selector::from_vec(
   4593                        vec![Component::ExplicitUniversalType],
   4594                        specificity(0, 0, 0),
   4595                        SelectorFlags::empty(),
   4596                    )
   4597                ]))],
   4598                specificity(0, 0, 0),
   4599                SelectorFlags::empty(),
   4600            )]))
   4601        );
   4602 
   4603        assert!(parse("::highlight(foo)").is_ok());
   4604 
   4605        assert!(parse("::slotted()").is_err());
   4606        assert!(parse("::slotted(div)").is_ok());
   4607        assert!(parse("::slotted(div).foo").is_err());
   4608        assert!(parse("::slotted(div + bar)").is_err());
   4609        assert!(parse("::slotted(div) + foo").is_err());
   4610 
   4611        assert!(parse("::part()").is_err());
   4612        assert!(parse("::part(42)").is_err());
   4613        assert!(parse("::part(foo bar)").is_ok());
   4614        assert!(parse("::part(foo):hover").is_ok());
   4615        assert!(parse("::part(foo) + bar").is_err());
   4616 
   4617        assert!(parse("div ::slotted(div)").is_ok());
   4618        assert!(parse("div + slot::slotted(div)").is_ok());
   4619        assert!(parse("div + slot::slotted(div.foo)").is_ok());
   4620        assert!(parse("slot::slotted(div,foo)::first-line").is_err());
   4621        assert!(parse("::slotted(div)::before").is_ok());
   4622        assert!(parse("slot::slotted(div,foo)").is_err());
   4623 
   4624        assert!(parse("foo:where()").is_ok());
   4625        assert!(parse("foo:where(div, foo, .bar baz)").is_ok());
   4626        assert!(parse("foo:where(::before)").is_ok());
   4627    }
   4628 
   4629    #[test]
   4630    fn parent_selector() {
   4631        assert!(parse("foo &").is_ok());
   4632        assert_eq!(
   4633            parse("#foo &.bar"),
   4634            Ok(SelectorList::from_vec(vec![Selector::from_vec(
   4635                vec![
   4636                    Component::ID(DummyAtom::from("foo")),
   4637                    Component::Combinator(Combinator::Descendant),
   4638                    Component::ParentSelector,
   4639                    Component::Class(DummyAtom::from("bar")),
   4640                ],
   4641                specificity(1, 1, 0),
   4642                SelectorFlags::HAS_PARENT
   4643            )]))
   4644        );
   4645 
   4646        let parent = parse(".bar, div .baz").unwrap();
   4647        let child = parse("#foo &.bar").unwrap();
   4648        assert_eq!(
   4649            child.replace_parent_selector(&parent),
   4650            parse("#foo :is(.bar, div .baz).bar").unwrap()
   4651        );
   4652 
   4653        let has_child = parse("#foo:has(&.bar)").unwrap();
   4654        assert_eq!(
   4655            has_child.replace_parent_selector(&parent),
   4656            parse("#foo:has(:is(.bar, div .baz).bar)").unwrap()
   4657        );
   4658 
   4659        let child =
   4660            parse_relative_expected("#foo", ParseRelative::ForNesting, Some("& #foo")).unwrap();
   4661        assert_eq!(
   4662            child.replace_parent_selector(&parent),
   4663            parse(":is(.bar, div .baz) #foo").unwrap()
   4664        );
   4665 
   4666        let child =
   4667            parse_relative_expected("+ #foo", ParseRelative::ForNesting, Some("& + #foo")).unwrap();
   4668        assert_eq!(child, parse("& + #foo").unwrap());
   4669    }
   4670 
   4671    #[test]
   4672    fn test_pseudo_iter() {
   4673        let list = parse("q::before").unwrap();
   4674        let selector = &list.slice()[0];
   4675        assert!(!selector.is_universal());
   4676        let mut iter = selector.iter();
   4677        assert_eq!(
   4678            iter.next(),
   4679            Some(&Component::PseudoElement(PseudoElement::Before))
   4680        );
   4681        assert_eq!(iter.next(), None);
   4682        let combinator = iter.next_sequence();
   4683        assert_eq!(combinator, Some(Combinator::PseudoElement));
   4684        assert_eq!(
   4685            iter.next(),
   4686            Some(&Component::LocalName(LocalName {
   4687                name: DummyAtom::from("q"),
   4688                lower_name: DummyAtom::from("q"),
   4689            }))
   4690        );
   4691        assert_eq!(iter.next(), None);
   4692        assert_eq!(iter.next_sequence(), None);
   4693    }
   4694 
   4695    #[test]
   4696    fn test_pseudo_before_marker() {
   4697        let list = parse("::before::marker").unwrap();
   4698        let selector = &list.slice()[0];
   4699        let mut iter = selector.iter();
   4700        assert_eq!(
   4701            iter.next(),
   4702            Some(&Component::PseudoElement(PseudoElement::Marker))
   4703        );
   4704        assert_eq!(iter.next(), None);
   4705        let combinator = iter.next_sequence();
   4706        assert_eq!(combinator, Some(Combinator::PseudoElement));
   4707        assert_eq!(
   4708            iter.next(),
   4709            Some(&Component::PseudoElement(PseudoElement::Before))
   4710        );
   4711        assert_eq!(iter.next(), None);
   4712        let combinator = iter.next_sequence();
   4713        assert_eq!(combinator, Some(Combinator::PseudoElement));
   4714        assert_eq!(iter.next(), None);
   4715        assert_eq!(iter.next_sequence(), None);
   4716    }
   4717 
   4718    #[test]
   4719    fn test_pseudo_duplicate_before_after_or_marker() {
   4720        assert!(parse("::before::before").is_err());
   4721        assert!(parse("::after::after").is_err());
   4722        assert!(parse("::marker::marker").is_err());
   4723    }
   4724 
   4725    #[test]
   4726    fn test_pseudo_on_element_backed_pseudo() {
   4727        let list = parse("::details-content::before").unwrap();
   4728        let selector = &list.slice()[0];
   4729        let mut iter = selector.iter();
   4730        assert_eq!(
   4731            iter.next(),
   4732            Some(&Component::PseudoElement(PseudoElement::Before))
   4733        );
   4734        assert_eq!(iter.next(), None);
   4735        let combinator = iter.next_sequence();
   4736        assert_eq!(combinator, Some(Combinator::PseudoElement));
   4737        assert_eq!(
   4738            iter.next(),
   4739            Some(&Component::PseudoElement(PseudoElement::DetailsContent))
   4740        );
   4741        assert_eq!(iter.next(), None);
   4742        let combinator = iter.next_sequence();
   4743        assert_eq!(combinator, Some(Combinator::PseudoElement));
   4744        assert_eq!(iter.next(), None);
   4745        assert_eq!(iter.next_sequence(), None);
   4746    }
   4747 
   4748    #[test]
   4749    fn test_universal() {
   4750        let list = parse_ns(
   4751            "*|*::before",
   4752            &DummyParser::default_with_namespace(DummyAtom::from("https://mozilla.org")),
   4753        )
   4754        .unwrap();
   4755        let selector = &list.slice()[0];
   4756        assert!(selector.is_universal());
   4757    }
   4758 
   4759    #[test]
   4760    fn test_empty_pseudo_iter() {
   4761        let list = parse("::before").unwrap();
   4762        let selector = &list.slice()[0];
   4763        assert!(selector.is_universal());
   4764        let mut iter = selector.iter();
   4765        assert_eq!(
   4766            iter.next(),
   4767            Some(&Component::PseudoElement(PseudoElement::Before))
   4768        );
   4769        assert_eq!(iter.next(), None);
   4770        assert_eq!(iter.next_sequence(), Some(Combinator::PseudoElement));
   4771        assert_eq!(iter.next(), None);
   4772        assert_eq!(iter.next_sequence(), None);
   4773    }
   4774 
   4775    #[test]
   4776    fn test_parse_implicit_scope() {
   4777        assert_eq!(
   4778            parse_relative_expected(".foo", ParseRelative::ForScope, None).unwrap(),
   4779            SelectorList::from_vec(vec![Selector::from_vec(
   4780                vec![
   4781                    Component::ImplicitScope,
   4782                    Component::Combinator(Combinator::Descendant),
   4783                    Component::Class(DummyAtom::from("foo")),
   4784                ],
   4785                specificity(0, 1, 0),
   4786                SelectorFlags::HAS_SCOPE,
   4787            )])
   4788        );
   4789 
   4790        assert_eq!(
   4791            parse_relative_expected(":scope .foo", ParseRelative::ForScope, None).unwrap(),
   4792            SelectorList::from_vec(vec![Selector::from_vec(
   4793                vec![
   4794                    Component::Scope,
   4795                    Component::Combinator(Combinator::Descendant),
   4796                    Component::Class(DummyAtom::from("foo")),
   4797                ],
   4798                specificity(0, 2, 0),
   4799                SelectorFlags::HAS_SCOPE
   4800            )])
   4801        );
   4802 
   4803        assert_eq!(
   4804            parse_relative_expected("> .foo", ParseRelative::ForScope, Some("> .foo")).unwrap(),
   4805            SelectorList::from_vec(vec![Selector::from_vec(
   4806                vec![
   4807                    Component::ImplicitScope,
   4808                    Component::Combinator(Combinator::Child),
   4809                    Component::Class(DummyAtom::from("foo")),
   4810                ],
   4811                specificity(0, 1, 0),
   4812                SelectorFlags::HAS_SCOPE
   4813            )])
   4814        );
   4815 
   4816        assert_eq!(
   4817            parse_relative_expected(".foo :scope > .bar", ParseRelative::ForScope, None).unwrap(),
   4818            SelectorList::from_vec(vec![Selector::from_vec(
   4819                vec![
   4820                    Component::Class(DummyAtom::from("foo")),
   4821                    Component::Combinator(Combinator::Descendant),
   4822                    Component::Scope,
   4823                    Component::Combinator(Combinator::Child),
   4824                    Component::Class(DummyAtom::from("bar")),
   4825                ],
   4826                specificity(0, 3, 0),
   4827                SelectorFlags::HAS_SCOPE
   4828            )])
   4829        );
   4830    }
   4831 
   4832    struct TestVisitor {
   4833        seen: Vec<String>,
   4834    }
   4835 
   4836    impl SelectorVisitor for TestVisitor {
   4837        type Impl = DummySelectorImpl;
   4838 
   4839        fn visit_simple_selector(&mut self, s: &Component<DummySelectorImpl>) -> bool {
   4840            let mut dest = String::new();
   4841            s.to_css(&mut dest).unwrap();
   4842            self.seen.push(dest);
   4843            true
   4844        }
   4845    }
   4846 
   4847    #[test]
   4848    fn visitor() {
   4849        let mut test_visitor = TestVisitor { seen: vec![] };
   4850        parse(":not(:hover) ~ label").unwrap().slice()[0].visit(&mut test_visitor);
   4851        assert!(test_visitor.seen.contains(&":hover".into()));
   4852 
   4853        let mut test_visitor = TestVisitor { seen: vec![] };
   4854        parse("::before:hover").unwrap().slice()[0].visit(&mut test_visitor);
   4855        assert!(test_visitor.seen.contains(&":hover".into()));
   4856    }
   4857 }