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};
7 use crate::attr::{ParsedCaseSensitivity, SELECTOR_WHITESPACE};
8 use crate::bloom::BLOOM_HASH_MASK;
9 use crate::builder::{SelectorBuilder, SelectorFlags, SpecificityAndFlags};
10 use crate::context::QuirksMode;
11 use crate::sink::Push;
12 pub use crate::visitor::SelectorVisitor;
13 use cssparser::parse_nth;
14 use cssparser::{BasicParseError, BasicParseErrorKind, ParseError, ParseErrorKind};
15 use cssparser::{CowRcStr, Delimiter, SourceLocation};
16 use cssparser::{Parser as CssParser, ToCss, Token};
17 use precomputed_hash::PrecomputedHash;
18 use servo_arc::ThinArc;
19 use smallvec::SmallVec;
20 use std::borrow::{Borrow, Cow};
21 use std::fmt::{self, Debug};
22 use std::iter::Rev;
23 use std::slice;
24 
25 /// A trait that represents a pseudo-element.
26 pub trait PseudoElement: Sized + ToCss {
27     /// The `SelectorImpl` this pseudo-element is used for.
28     type Impl: SelectorImpl;
29 
30     /// Whether the pseudo-element supports a given state selector to the right
31     /// of it.
accepts_state_pseudo_classes(&self) -> bool32     fn accepts_state_pseudo_classes(&self) -> bool {
33         false
34     }
35 
36     /// Whether this pseudo-element is valid after a ::slotted(..) pseudo.
valid_after_slotted(&self) -> bool37     fn valid_after_slotted(&self) -> bool {
38         false
39     }
40 }
41 
42 /// A trait that represents a pseudo-class.
43 pub trait NonTSPseudoClass: Sized + ToCss {
44     /// The `SelectorImpl` this pseudo-element is used for.
45     type Impl: SelectorImpl;
46 
47     /// Whether this pseudo-class is :active or :hover.
is_active_or_hover(&self) -> bool48     fn is_active_or_hover(&self) -> bool;
49 
50     /// Whether this pseudo-class belongs to:
51     ///
52     /// https://drafts.csswg.org/selectors-4/#useraction-pseudos
is_user_action_state(&self) -> bool53     fn is_user_action_state(&self) -> bool;
54 
visit<V>(&self, _visitor: &mut V) -> bool where V: SelectorVisitor<Impl = Self::Impl>,55     fn visit<V>(&self, _visitor: &mut V) -> bool
56     where
57         V: SelectorVisitor<Impl = Self::Impl>,
58     {
59         true
60     }
61 }
62 
63 /// Returns a Cow::Borrowed if `s` is already ASCII lowercase, and a
64 /// Cow::Owned if `s` had to be converted into ASCII lowercase.
to_ascii_lowercase(s: &str) -> Cow<str>65 fn to_ascii_lowercase(s: &str) -> Cow<str> {
66     if let Some(first_uppercase) = s.bytes().position(|byte| byte >= b'A' && byte <= b'Z') {
67         let mut string = s.to_owned();
68         string[first_uppercase..].make_ascii_lowercase();
69         string.into()
70     } else {
71         s.into()
72     }
73 }
74 
75 bitflags! {
76     /// Flags that indicate at which point of parsing a selector are we.
77     struct SelectorParsingState: u8 {
78         /// Whether we should avoid adding default namespaces to selectors that
79         /// aren't type or universal selectors.
80         const SKIP_DEFAULT_NAMESPACE = 1 << 0;
81 
82         /// Whether we've parsed a ::slotted() pseudo-element already.
83         ///
84         /// If so, then we can only parse a subset of pseudo-elements, and
85         /// whatever comes after them if so.
86         const AFTER_SLOTTED = 1 << 1;
87         /// Whether we've parsed a ::part() pseudo-element already.
88         ///
89         /// If so, then we can only parse a subset of pseudo-elements, and
90         /// whatever comes after them if so.
91         const AFTER_PART = 1 << 2;
92         /// Whether we've parsed a pseudo-element (as in, an
93         /// `Impl::PseudoElement` thus not accounting for `::slotted` or
94         /// `::part`) already.
95         ///
96         /// If so, then other pseudo-elements and most other selectors are
97         /// disallowed.
98         const AFTER_PSEUDO_ELEMENT = 1 << 3;
99         /// Whether we've parsed a non-stateful pseudo-element (again, as-in
100         /// `Impl::PseudoElement`) already. If so, then other pseudo-classes are
101         /// disallowed. If this flag is set, `AFTER_PSEUDO_ELEMENT` must be set
102         /// as well.
103         const AFTER_NON_STATEFUL_PSEUDO_ELEMENT = 1 << 4;
104 
105         /// Whether we are after any of the pseudo-like things.
106         const AFTER_PSEUDO = Self::AFTER_PART.bits | Self::AFTER_SLOTTED.bits | Self::AFTER_PSEUDO_ELEMENT.bits;
107 
108         /// Whether we explicitly disallow combinators.
109         const DISALLOW_COMBINATORS = 1 << 5;
110 
111         /// Whether we explicitly disallow pseudo-element-like things.
112         const DISALLOW_PSEUDOS = 1 << 6;
113     }
114 }
115 
116 impl SelectorParsingState {
117     #[inline]
allows_pseudos(self) -> bool118     fn allows_pseudos(self) -> bool {
119         // NOTE(emilio): We allow pseudos after ::part and such.
120         !self.intersects(Self::AFTER_PSEUDO_ELEMENT | Self::DISALLOW_PSEUDOS)
121     }
122 
123     #[inline]
allows_slotted(self) -> bool124     fn allows_slotted(self) -> bool {
125         !self.intersects(Self::AFTER_PSEUDO | Self::DISALLOW_PSEUDOS)
126     }
127 
128     #[inline]
allows_part(self) -> bool129     fn allows_part(self) -> bool {
130         !self.intersects(Self::AFTER_PSEUDO | Self::DISALLOW_PSEUDOS)
131     }
132 
133     // TODO(emilio): Maybe some of these should be allowed, but this gets us on
134     // the safe side for now, matching previous behavior. Gotta be careful with
135     // the ones like :-moz-any, which allow nested selectors but don't carry the
136     // state, and so on.
137     #[inline]
allows_custom_functional_pseudo_classes(self) -> bool138     fn allows_custom_functional_pseudo_classes(self) -> bool {
139         !self.intersects(Self::AFTER_PSEUDO)
140     }
141 
142     #[inline]
allows_non_functional_pseudo_classes(self) -> bool143     fn allows_non_functional_pseudo_classes(self) -> bool {
144         !self.intersects(Self::AFTER_SLOTTED | Self::AFTER_NON_STATEFUL_PSEUDO_ELEMENT)
145     }
146 
147     #[inline]
allows_tree_structural_pseudo_classes(self) -> bool148     fn allows_tree_structural_pseudo_classes(self) -> bool {
149         !self.intersects(Self::AFTER_PSEUDO)
150     }
151 
152     #[inline]
allows_combinators(self) -> bool153     fn allows_combinators(self) -> bool {
154         !self.intersects(Self::DISALLOW_COMBINATORS)
155     }
156 }
157 
158 pub type SelectorParseError<'i> = ParseError<'i, SelectorParseErrorKind<'i>>;
159 
160 #[derive(Clone, Debug, PartialEq)]
161 pub enum SelectorParseErrorKind<'i> {
162     NoQualifiedNameInAttributeSelector(Token<'i>),
163     EmptySelector,
164     DanglingCombinator,
165     NonCompoundSelector,
166     NonPseudoElementAfterSlotted,
167     InvalidPseudoElementAfterSlotted,
168     InvalidPseudoElementInsideWhere,
169     InvalidState,
170     UnexpectedTokenInAttributeSelector(Token<'i>),
171     PseudoElementExpectedColon(Token<'i>),
172     PseudoElementExpectedIdent(Token<'i>),
173     NoIdentForPseudo(Token<'i>),
174     UnsupportedPseudoClassOrElement(CowRcStr<'i>),
175     UnexpectedIdent(CowRcStr<'i>),
176     ExpectedNamespace(CowRcStr<'i>),
177     ExpectedBarInAttr(Token<'i>),
178     BadValueInAttr(Token<'i>),
179     InvalidQualNameInAttr(Token<'i>),
180     ExplicitNamespaceUnexpectedToken(Token<'i>),
181     ClassNeedsIdent(Token<'i>),
182 }
183 
184 macro_rules! with_all_bounds {
185     (
186         [ $( $InSelector: tt )* ]
187         [ $( $CommonBounds: tt )* ]
188         [ $( $FromStr: tt )* ]
189     ) => {
190         /// This trait allows to define the parser implementation in regards
191         /// of pseudo-classes/elements
192         ///
193         /// NB: We need Clone so that we can derive(Clone) on struct with that
194         /// are parameterized on SelectorImpl. See
195         /// <https://github.com/rust-lang/rust/issues/26925>
196         pub trait SelectorImpl: Clone + Debug + Sized + 'static {
197             type ExtraMatchingData: Sized + Default + 'static;
198             type AttrValue: $($InSelector)*;
199             type Identifier: $($InSelector)*;
200             type LocalName: $($InSelector)* + Borrow<Self::BorrowedLocalName>;
201             type NamespaceUrl: $($CommonBounds)* + Default + Borrow<Self::BorrowedNamespaceUrl>;
202             type NamespacePrefix: $($InSelector)* + Default;
203             type BorrowedNamespaceUrl: ?Sized + Eq;
204             type BorrowedLocalName: ?Sized + Eq;
205 
206             /// non tree-structural pseudo-classes
207             /// (see: https://drafts.csswg.org/selectors/#structural-pseudos)
208             type NonTSPseudoClass: $($CommonBounds)* + NonTSPseudoClass<Impl = Self>;
209 
210             /// pseudo-elements
211             type PseudoElement: $($CommonBounds)* + PseudoElement<Impl = Self>;
212 
213             /// Whether attribute hashes should be collected for filtering
214             /// purposes.
215             fn should_collect_attr_hash(_name: &Self::LocalName) -> bool {
216                 false
217             }
218         }
219     }
220 }
221 
222 macro_rules! with_bounds {
223     ( [ $( $CommonBounds: tt )* ] [ $( $FromStr: tt )* ]) => {
224         with_all_bounds! {
225             [$($CommonBounds)* + $($FromStr)* + ToCss]
226             [$($CommonBounds)*]
227             [$($FromStr)*]
228         }
229     }
230 }
231 
232 with_bounds! {
233     [Clone + Eq]
234     [for<'a> From<&'a str>]
235 }
236 
237 pub trait Parser<'i> {
238     type Impl: SelectorImpl;
239     type Error: 'i + From<SelectorParseErrorKind<'i>>;
240 
241     /// Whether to parse the `::slotted()` pseudo-element.
parse_slotted(&self) -> bool242     fn parse_slotted(&self) -> bool {
243         false
244     }
245 
246     /// Whether to parse the `::part()` pseudo-element.
parse_part(&self) -> bool247     fn parse_part(&self) -> bool {
248         false
249     }
250 
251     /// Whether to parse the `:where` pseudo-class.
parse_is_and_where(&self) -> bool252     fn parse_is_and_where(&self) -> bool {
253         false
254     }
255 
256     /// Whether the given function name is an alias for the `:is()` function.
is_is_alias(&self, _name: &str) -> bool257     fn is_is_alias(&self, _name: &str) -> bool {
258         false
259     }
260 
261     /// Whether to parse the `:host` pseudo-class.
parse_host(&self) -> bool262     fn parse_host(&self) -> bool {
263         false
264     }
265 
266     /// This function can return an "Err" pseudo-element in order to support CSS2.1
267     /// pseudo-elements.
parse_non_ts_pseudo_class( &self, location: SourceLocation, name: CowRcStr<'i>, ) -> Result<<Self::Impl as SelectorImpl>::NonTSPseudoClass, ParseError<'i, Self::Error>>268     fn parse_non_ts_pseudo_class(
269         &self,
270         location: SourceLocation,
271         name: CowRcStr<'i>,
272     ) -> Result<<Self::Impl as SelectorImpl>::NonTSPseudoClass, ParseError<'i, Self::Error>> {
273         Err(
274             location.new_custom_error(SelectorParseErrorKind::UnsupportedPseudoClassOrElement(
275                 name,
276             )),
277         )
278     }
279 
parse_non_ts_functional_pseudo_class<'t>( &self, name: CowRcStr<'i>, arguments: &mut CssParser<'i, 't>, ) -> Result<<Self::Impl as SelectorImpl>::NonTSPseudoClass, ParseError<'i, Self::Error>>280     fn parse_non_ts_functional_pseudo_class<'t>(
281         &self,
282         name: CowRcStr<'i>,
283         arguments: &mut CssParser<'i, 't>,
284     ) -> Result<<Self::Impl as SelectorImpl>::NonTSPseudoClass, ParseError<'i, Self::Error>> {
285         Err(
286             arguments.new_custom_error(SelectorParseErrorKind::UnsupportedPseudoClassOrElement(
287                 name,
288             )),
289         )
290     }
291 
parse_pseudo_element( &self, location: SourceLocation, name: CowRcStr<'i>, ) -> Result<<Self::Impl as SelectorImpl>::PseudoElement, ParseError<'i, Self::Error>>292     fn parse_pseudo_element(
293         &self,
294         location: SourceLocation,
295         name: CowRcStr<'i>,
296     ) -> Result<<Self::Impl as SelectorImpl>::PseudoElement, ParseError<'i, Self::Error>> {
297         Err(
298             location.new_custom_error(SelectorParseErrorKind::UnsupportedPseudoClassOrElement(
299                 name,
300             )),
301         )
302     }
303 
parse_functional_pseudo_element<'t>( &self, name: CowRcStr<'i>, arguments: &mut CssParser<'i, 't>, ) -> Result<<Self::Impl as SelectorImpl>::PseudoElement, ParseError<'i, Self::Error>>304     fn parse_functional_pseudo_element<'t>(
305         &self,
306         name: CowRcStr<'i>,
307         arguments: &mut CssParser<'i, 't>,
308     ) -> Result<<Self::Impl as SelectorImpl>::PseudoElement, ParseError<'i, Self::Error>> {
309         Err(
310             arguments.new_custom_error(SelectorParseErrorKind::UnsupportedPseudoClassOrElement(
311                 name,
312             )),
313         )
314     }
315 
default_namespace(&self) -> Option<<Self::Impl as SelectorImpl>::NamespaceUrl>316     fn default_namespace(&self) -> Option<<Self::Impl as SelectorImpl>::NamespaceUrl> {
317         None
318     }
319 
namespace_for_prefix( &self, _prefix: &<Self::Impl as SelectorImpl>::NamespacePrefix, ) -> Option<<Self::Impl as SelectorImpl>::NamespaceUrl>320     fn namespace_for_prefix(
321         &self,
322         _prefix: &<Self::Impl as SelectorImpl>::NamespacePrefix,
323     ) -> Option<<Self::Impl as SelectorImpl>::NamespaceUrl> {
324         None
325     }
326 }
327 
328 #[derive(Clone, Debug, Eq, PartialEq, ToShmem)]
329 #[shmem(no_bounds)]
330 pub struct SelectorList<Impl: SelectorImpl>(
331     #[shmem(field_bound)] pub SmallVec<[Selector<Impl>; 1]>,
332 );
333 
334 /// How to treat invalid selectors in a selector list.
335 enum ParseErrorRecovery {
336     /// Discard the entire selector list, this is the default behavior for
337     /// almost all of CSS.
338     DiscardList,
339     /// Ignore invalid selectors, potentially creating an empty selector list.
340     ///
341     /// This is the error recovery mode of :is() and :where()
342     IgnoreInvalidSelector,
343 }
344 
345 impl<Impl: SelectorImpl> SelectorList<Impl> {
346     /// Parse a comma-separated list of Selectors.
347     /// <https://drafts.csswg.org/selectors/#grouping>
348     ///
349     /// Return the Selectors or Err if there is an invalid selector.
parse<'i, 't, P>( parser: &P, input: &mut CssParser<'i, 't>, ) -> Result<Self, ParseError<'i, P::Error>> where P: Parser<'i, Impl = Impl>,350     pub fn parse<'i, 't, P>(
351         parser: &P,
352         input: &mut CssParser<'i, 't>,
353     ) -> Result<Self, ParseError<'i, P::Error>>
354     where
355         P: Parser<'i, Impl = Impl>,
356     {
357         Self::parse_with_state(
358             parser,
359             input,
360             SelectorParsingState::empty(),
361             ParseErrorRecovery::DiscardList,
362         )
363     }
364 
365     #[inline]
parse_with_state<'i, 't, P>( parser: &P, input: &mut CssParser<'i, 't>, state: SelectorParsingState, recovery: ParseErrorRecovery, ) -> Result<Self, ParseError<'i, P::Error>> where P: Parser<'i, Impl = Impl>,366     fn parse_with_state<'i, 't, P>(
367         parser: &P,
368         input: &mut CssParser<'i, 't>,
369         state: SelectorParsingState,
370         recovery: ParseErrorRecovery,
371     ) -> Result<Self, ParseError<'i, P::Error>>
372     where
373         P: Parser<'i, Impl = Impl>,
374     {
375         let mut values = SmallVec::new();
376         loop {
377             let selector = input.parse_until_before(Delimiter::Comma, |input| {
378                 parse_selector(parser, input, state)
379             });
380 
381             let was_ok = selector.is_ok();
382             match selector {
383                 Ok(selector) => values.push(selector),
384                 Err(err) => match recovery {
385                     ParseErrorRecovery::DiscardList => return Err(err),
386                     ParseErrorRecovery::IgnoreInvalidSelector => {},
387                 },
388             }
389 
390             loop {
391                 match input.next() {
392                     Err(_) => return Ok(SelectorList(values)),
393                     Ok(&Token::Comma) => break,
394                     Ok(_) => {
395                         debug_assert!(!was_ok, "Shouldn't have got a selector if getting here");
396                     },
397                 }
398             }
399         }
400     }
401 
402     /// Creates a SelectorList from a Vec of selectors. Used in tests.
from_vec(v: Vec<Selector<Impl>>) -> Self403     pub fn from_vec(v: Vec<Selector<Impl>>) -> Self {
404         SelectorList(SmallVec::from_vec(v))
405     }
406 }
407 
408 /// Parses one compound selector suitable for nested stuff like :-moz-any, etc.
parse_inner_compound_selector<'i, 't, P, Impl>( parser: &P, input: &mut CssParser<'i, 't>, state: SelectorParsingState, ) -> Result<Selector<Impl>, ParseError<'i, P::Error>> where P: Parser<'i, Impl = Impl>, Impl: SelectorImpl,409 fn parse_inner_compound_selector<'i, 't, P, Impl>(
410     parser: &P,
411     input: &mut CssParser<'i, 't>,
412     state: SelectorParsingState,
413 ) -> Result<Selector<Impl>, ParseError<'i, P::Error>>
414 where
415     P: Parser<'i, Impl = Impl>,
416     Impl: SelectorImpl,
417 {
418     parse_selector(
419         parser,
420         input,
421         state | SelectorParsingState::DISALLOW_PSEUDOS | SelectorParsingState::DISALLOW_COMBINATORS,
422     )
423 }
424 
425 /// Ancestor hashes for the bloom filter. We precompute these and store them
426 /// inline with selectors to optimize cache performance during matching.
427 /// This matters a lot.
428 ///
429 /// We use 4 hashes, which is copied from Gecko, who copied it from WebKit.
430 /// Note that increasing the number of hashes here will adversely affect the
431 /// cache hit when fast-rejecting long lists of Rules with inline hashes.
432 ///
433 /// Because the bloom filter only uses the bottom 24 bits of the hash, we pack
434 /// the fourth hash into the upper bits of the first three hashes in order to
435 /// shrink Rule (whose size matters a lot). This scheme minimizes the runtime
436 /// overhead of the packing for the first three hashes (we just need to mask
437 /// off the upper bits) at the expense of making the fourth somewhat more
438 /// complicated to assemble, because we often bail out before checking all the
439 /// hashes.
440 #[derive(Clone, Debug, Eq, PartialEq)]
441 pub struct AncestorHashes {
442     pub packed_hashes: [u32; 3],
443 }
444 
collect_ancestor_hashes<Impl: SelectorImpl>( iter: SelectorIter<Impl>, quirks_mode: QuirksMode, hashes: &mut [u32; 4], len: &mut usize, ) -> bool where Impl::Identifier: PrecomputedHash, Impl::LocalName: PrecomputedHash, Impl::NamespaceUrl: PrecomputedHash,445 fn collect_ancestor_hashes<Impl: SelectorImpl>(
446     iter: SelectorIter<Impl>,
447     quirks_mode: QuirksMode,
448     hashes: &mut [u32; 4],
449     len: &mut usize,
450 ) -> bool
451 where
452     Impl::Identifier: PrecomputedHash,
453     Impl::LocalName: PrecomputedHash,
454     Impl::NamespaceUrl: PrecomputedHash,
455 {
456     for component in AncestorIter::new(iter) {
457         let hash = match *component {
458             Component::LocalName(LocalName {
459                 ref name,
460                 ref lower_name,
461             }) => {
462                 // Only insert the local-name into the filter if it's all
463                 // lowercase.  Otherwise we would need to test both hashes, and
464                 // our data structures aren't really set up for that.
465                 if name != lower_name {
466                     continue;
467                 }
468                 name.precomputed_hash()
469             },
470             Component::DefaultNamespace(ref url) | Component::Namespace(_, ref url) => {
471                 url.precomputed_hash()
472             },
473             // In quirks mode, class and id selectors should match
474             // case-insensitively, so just avoid inserting them into the filter.
475             Component::ID(ref id) if quirks_mode != QuirksMode::Quirks => id.precomputed_hash(),
476             Component::Class(ref class) if quirks_mode != QuirksMode::Quirks => {
477                 class.precomputed_hash()
478             },
479             Component::AttributeInNoNamespace { ref local_name, .. } if Impl::should_collect_attr_hash(local_name) => {
480                 // AttributeInNoNamespace is only used when local_name ==
481                 // local_name_lower.
482                 local_name.precomputed_hash()
483             },
484             Component::AttributeInNoNamespaceExists { ref local_name, ref local_name_lower, .. } => {
485                 // Only insert the local-name into the filter if it's all
486                 // lowercase.  Otherwise we would need to test both hashes, and
487                 // our data structures aren't really set up for that.
488                 if local_name != local_name_lower || !Impl::should_collect_attr_hash(local_name) {
489                     continue;
490                 }
491                 local_name.precomputed_hash()
492             },
493             Component::AttributeOther(ref selector) => {
494                 if selector.local_name != selector.local_name_lower || !Impl::should_collect_attr_hash(&selector.local_name) {
495                     continue;
496                 }
497                 selector.local_name.precomputed_hash()
498             },
499             Component::Is(ref list) | Component::Where(ref list) => {
500                 // :where and :is OR their selectors, so we can't put any hash
501                 // in the filter if there's more than one selector, as that'd
502                 // exclude elements that may match one of the other selectors.
503                 if list.len() == 1 &&
504                     !collect_ancestor_hashes(list[0].iter(), quirks_mode, hashes, len)
505                 {
506                     return false;
507                 }
508                 continue;
509             },
510             _ => continue,
511         };
512 
513         hashes[*len] = hash & BLOOM_HASH_MASK;
514         *len += 1;
515         if *len == hashes.len() {
516             return false;
517         }
518     }
519     true
520 }
521 
522 impl AncestorHashes {
new<Impl: SelectorImpl>(selector: &Selector<Impl>, quirks_mode: QuirksMode) -> Self where Impl::Identifier: PrecomputedHash, Impl::LocalName: PrecomputedHash, Impl::NamespaceUrl: PrecomputedHash,523     pub fn new<Impl: SelectorImpl>(selector: &Selector<Impl>, quirks_mode: QuirksMode) -> Self
524     where
525         Impl::Identifier: PrecomputedHash,
526         Impl::LocalName: PrecomputedHash,
527         Impl::NamespaceUrl: PrecomputedHash,
528     {
529         // Compute ancestor hashes for the bloom filter.
530         let mut hashes = [0u32; 4];
531         let mut len = 0;
532         collect_ancestor_hashes(selector.iter(), quirks_mode, &mut hashes, &mut len);
533         debug_assert!(len <= 4);
534 
535         // Now, pack the fourth hash (if it exists) into the upper byte of each of
536         // the other three hashes.
537         if len == 4 {
538             let fourth = hashes[3];
539             hashes[0] |= (fourth & 0x000000ff) << 24;
540             hashes[1] |= (fourth & 0x0000ff00) << 16;
541             hashes[2] |= (fourth & 0x00ff0000) << 8;
542         }
543 
544         AncestorHashes {
545             packed_hashes: [hashes[0], hashes[1], hashes[2]],
546         }
547     }
548 
549     /// Returns the fourth hash, reassembled from parts.
fourth_hash(&self) -> u32550     pub fn fourth_hash(&self) -> u32 {
551         ((self.packed_hashes[0] & 0xff000000) >> 24) |
552             ((self.packed_hashes[1] & 0xff000000) >> 16) |
553             ((self.packed_hashes[2] & 0xff000000) >> 8)
554     }
555 }
556 
namespace_empty_string<Impl: SelectorImpl>() -> Impl::NamespaceUrl557 pub fn namespace_empty_string<Impl: SelectorImpl>() -> Impl::NamespaceUrl {
558     // Rust type’s default, not default namespace
559     Impl::NamespaceUrl::default()
560 }
561 
562 /// A Selector stores a sequence of simple selectors and combinators. The
563 /// iterator classes allow callers to iterate at either the raw sequence level or
564 /// at the level of sequences of simple selectors separated by combinators. Most
565 /// callers want the higher-level iterator.
566 ///
567 /// We store compound selectors internally right-to-left (in matching order).
568 /// Additionally, we invert the order of top-level compound selectors so that
569 /// each one matches left-to-right. This is because matching namespace, local name,
570 /// id, and class are all relatively cheap, whereas matching pseudo-classes might
571 /// be expensive (depending on the pseudo-class). Since authors tend to put the
572 /// pseudo-classes on the right, it's faster to start matching on the left.
573 ///
574 /// This reordering doesn't change the semantics of selector matching, and we
575 /// handle it in to_css to make it invisible to serialization.
576 #[derive(Clone, Eq, PartialEq, ToShmem)]
577 #[shmem(no_bounds)]
578 pub struct Selector<Impl: SelectorImpl>(
579     #[shmem(field_bound)] ThinArc<SpecificityAndFlags, Component<Impl>>,
580 );
581 
582 impl<Impl: SelectorImpl> Selector<Impl> {
583     #[inline]
specificity(&self) -> u32584     pub fn specificity(&self) -> u32 {
585         self.0.header.header.specificity()
586     }
587 
588     #[inline]
has_pseudo_element(&self) -> bool589     pub fn has_pseudo_element(&self) -> bool {
590         self.0.header.header.has_pseudo_element()
591     }
592 
593     #[inline]
is_slotted(&self) -> bool594     pub fn is_slotted(&self) -> bool {
595         self.0.header.header.is_slotted()
596     }
597 
598     #[inline]
is_part(&self) -> bool599     pub fn is_part(&self) -> bool {
600         self.0.header.header.is_part()
601     }
602 
603     #[inline]
parts(&self) -> Option<&[Impl::Identifier]>604     pub fn parts(&self) -> Option<&[Impl::Identifier]> {
605         if !self.is_part() {
606             return None;
607         }
608 
609         let mut iter = self.iter();
610         if self.has_pseudo_element() {
611             // Skip the pseudo-element.
612             for _ in &mut iter {}
613 
614             let combinator = iter.next_sequence()?;
615             debug_assert_eq!(combinator, Combinator::PseudoElement);
616         }
617 
618         for component in iter {
619             if let Component::Part(ref part) = *component {
620                 return Some(part);
621             }
622         }
623 
624         debug_assert!(false, "is_part() lied somehow?");
625         None
626     }
627 
628     #[inline]
pseudo_element(&self) -> Option<&Impl::PseudoElement>629     pub fn pseudo_element(&self) -> Option<&Impl::PseudoElement> {
630         if !self.has_pseudo_element() {
631             return None;
632         }
633 
634         for component in self.iter() {
635             if let Component::PseudoElement(ref pseudo) = *component {
636                 return Some(pseudo);
637             }
638         }
639 
640         debug_assert!(false, "has_pseudo_element lied!");
641         None
642     }
643 
644     /// Whether this selector (pseudo-element part excluded) matches every element.
645     ///
646     /// Used for "pre-computed" pseudo-elements in components/style/stylist.rs
647     #[inline]
is_universal(&self) -> bool648     pub fn is_universal(&self) -> bool {
649         self.iter_raw_match_order().all(|c| {
650             matches!(
651                 *c,
652                 Component::ExplicitUniversalType |
653                     Component::ExplicitAnyNamespace |
654                     Component::Combinator(Combinator::PseudoElement) |
655                     Component::PseudoElement(..)
656             )
657         })
658     }
659 
660     /// Returns an iterator over this selector in matching order (right-to-left).
661     /// When a combinator is reached, the iterator will return None, and
662     /// next_sequence() may be called to continue to the next sequence.
663     #[inline]
iter(&self) -> SelectorIter<Impl>664     pub fn iter(&self) -> SelectorIter<Impl> {
665         SelectorIter {
666             iter: self.iter_raw_match_order(),
667             next_combinator: None,
668         }
669     }
670 
671     /// Whether this selector is a featureless :host selector, with no
672     /// combinators to the left, and optionally has a pseudo-element to the
673     /// right.
674     #[inline]
is_featureless_host_selector_or_pseudo_element(&self) -> bool675     pub fn is_featureless_host_selector_or_pseudo_element(&self) -> bool {
676         let mut iter = self.iter();
677         if !self.has_pseudo_element() {
678             return iter.is_featureless_host_selector();
679         }
680 
681         // Skip the pseudo-element.
682         for _ in &mut iter {}
683 
684         match iter.next_sequence() {
685             None => return false,
686             Some(combinator) => {
687                 debug_assert_eq!(combinator, Combinator::PseudoElement);
688             },
689         }
690 
691         iter.is_featureless_host_selector()
692     }
693 
694     /// Returns an iterator over this selector in matching order (right-to-left),
695     /// skipping the rightmost |offset| Components.
696     #[inline]
iter_from(&self, offset: usize) -> SelectorIter<Impl>697     pub fn iter_from(&self, offset: usize) -> SelectorIter<Impl> {
698         let iter = self.0.slice[offset..].iter();
699         SelectorIter {
700             iter,
701             next_combinator: None,
702         }
703     }
704 
705     /// Returns the combinator at index `index` (zero-indexed from the right),
706     /// or panics if the component is not a combinator.
707     #[inline]
combinator_at_match_order(&self, index: usize) -> Combinator708     pub fn combinator_at_match_order(&self, index: usize) -> Combinator {
709         match self.0.slice[index] {
710             Component::Combinator(c) => c,
711             ref other => panic!(
712                 "Not a combinator: {:?}, {:?}, index: {}",
713                 other, self, index
714             ),
715         }
716     }
717 
718     /// Returns an iterator over the entire sequence of simple selectors and
719     /// combinators, in matching order (from right to left).
720     #[inline]
iter_raw_match_order(&self) -> slice::Iter<Component<Impl>>721     pub fn iter_raw_match_order(&self) -> slice::Iter<Component<Impl>> {
722         self.0.slice.iter()
723     }
724 
725     /// Returns the combinator at index `index` (zero-indexed from the left),
726     /// or panics if the component is not a combinator.
727     #[inline]
combinator_at_parse_order(&self, index: usize) -> Combinator728     pub fn combinator_at_parse_order(&self, index: usize) -> Combinator {
729         match self.0.slice[self.len() - index - 1] {
730             Component::Combinator(c) => c,
731             ref other => panic!(
732                 "Not a combinator: {:?}, {:?}, index: {}",
733                 other, self, index
734             ),
735         }
736     }
737 
738     /// Returns an iterator over the sequence of simple selectors and
739     /// combinators, in parse order (from left to right), starting from
740     /// `offset`.
741     #[inline]
iter_raw_parse_order_from(&self, offset: usize) -> Rev<slice::Iter<Component<Impl>>>742     pub fn iter_raw_parse_order_from(&self, offset: usize) -> Rev<slice::Iter<Component<Impl>>> {
743         self.0.slice[..self.len() - offset].iter().rev()
744     }
745 
746     /// Creates a Selector from a vec of Components, specified in parse order. Used in tests.
747     #[allow(unused)]
from_vec( vec: Vec<Component<Impl>>, specificity: u32, flags: SelectorFlags, ) -> Self748     pub(crate) fn from_vec(
749         vec: Vec<Component<Impl>>,
750         specificity: u32,
751         flags: SelectorFlags,
752     ) -> Self {
753         let mut builder = SelectorBuilder::default();
754         for component in vec.into_iter() {
755             if let Some(combinator) = component.as_combinator() {
756                 builder.push_combinator(combinator);
757             } else {
758                 builder.push_simple_selector(component);
759             }
760         }
761         let spec = SpecificityAndFlags { specificity, flags };
762         Selector(builder.build_with_specificity_and_flags(spec))
763     }
764 
765     /// Returns count of simple selectors and combinators in the Selector.
766     #[inline]
len(&self) -> usize767     pub fn len(&self) -> usize {
768         self.0.slice.len()
769     }
770 
771     /// Returns the address on the heap of the ThinArc for memory reporting.
thin_arc_heap_ptr(&self) -> *const ::std::os::raw::c_void772     pub fn thin_arc_heap_ptr(&self) -> *const ::std::os::raw::c_void {
773         self.0.heap_ptr()
774     }
775 
776     /// Traverse selector components inside `self`.
777     ///
778     /// Implementations of this method should call `SelectorVisitor` methods
779     /// or other impls of `Visit` as appropriate based on the fields of `Self`.
780     ///
781     /// A return value of `false` indicates terminating the traversal.
782     /// It should be propagated with an early return.
783     /// On the contrary, `true` indicates that all fields of `self` have been traversed:
784     ///
785     /// ```rust,ignore
786     /// if !visitor.visit_simple_selector(&self.some_simple_selector) {
787     ///     return false;
788     /// }
789     /// if !self.some_component.visit(visitor) {
790     ///     return false;
791     /// }
792     /// true
793     /// ```
visit<V>(&self, visitor: &mut V) -> bool where V: SelectorVisitor<Impl = Impl>,794     pub fn visit<V>(&self, visitor: &mut V) -> bool
795     where
796         V: SelectorVisitor<Impl = Impl>,
797     {
798         let mut current = self.iter();
799         let mut combinator = None;
800         loop {
801             if !visitor.visit_complex_selector(combinator) {
802                 return false;
803             }
804 
805             for selector in &mut current {
806                 if !selector.visit(visitor) {
807                     return false;
808                 }
809             }
810 
811             combinator = current.next_sequence();
812             if combinator.is_none() {
813                 break;
814             }
815         }
816 
817         true
818     }
819 }
820 
821 #[derive(Clone)]
822 pub struct SelectorIter<'a, Impl: 'a + SelectorImpl> {
823     iter: slice::Iter<'a, Component<Impl>>,
824     next_combinator: Option<Combinator>,
825 }
826 
827 impl<'a, Impl: 'a + SelectorImpl> SelectorIter<'a, Impl> {
828     /// Prepares this iterator to point to the next sequence to the left,
829     /// returning the combinator if the sequence was found.
830     #[inline]
next_sequence(&mut self) -> Option<Combinator>831     pub fn next_sequence(&mut self) -> Option<Combinator> {
832         self.next_combinator.take()
833     }
834 
835     /// Whether this selector is a featureless host selector, with no
836     /// combinators to the left.
837     #[inline]
is_featureless_host_selector(&mut self) -> bool838     pub(crate) fn is_featureless_host_selector(&mut self) -> bool {
839         self.selector_length() > 0 &&
840             self.all(|component| component.is_host()) &&
841             self.next_sequence().is_none()
842     }
843 
844     #[inline]
matches_for_stateless_pseudo_element(&mut self) -> bool845     pub(crate) fn matches_for_stateless_pseudo_element(&mut self) -> bool {
846         let first = match self.next() {
847             Some(c) => c,
848             // Note that this is the common path that we keep inline: the
849             // pseudo-element not having anything to its right.
850             None => return true,
851         };
852         self.matches_for_stateless_pseudo_element_internal(first)
853     }
854 
855     #[inline(never)]
matches_for_stateless_pseudo_element_internal(&mut self, first: &Component<Impl>) -> bool856     fn matches_for_stateless_pseudo_element_internal(&mut self, first: &Component<Impl>) -> bool {
857         if !first.matches_for_stateless_pseudo_element() {
858             return false;
859         }
860         for component in self {
861             // The only other parser-allowed Components in this sequence are
862             // state pseudo-classes, or one of the other things that can contain
863             // them.
864             if !component.matches_for_stateless_pseudo_element() {
865                 return false;
866             }
867         }
868         true
869     }
870 
871     /// Returns remaining count of the simple selectors and combinators in the Selector.
872     #[inline]
selector_length(&self) -> usize873     pub fn selector_length(&self) -> usize {
874         self.iter.len()
875     }
876 }
877 
878 impl<'a, Impl: SelectorImpl> Iterator for SelectorIter<'a, Impl> {
879     type Item = &'a Component<Impl>;
880 
881     #[inline]
next(&mut self) -> Option<Self::Item>882     fn next(&mut self) -> Option<Self::Item> {
883         debug_assert!(
884             self.next_combinator.is_none(),
885             "You should call next_sequence!"
886         );
887         match *self.iter.next()? {
888             Component::Combinator(c) => {
889                 self.next_combinator = Some(c);
890                 None
891             },
892             ref x => Some(x),
893         }
894     }
895 }
896 
897 impl<'a, Impl: SelectorImpl> fmt::Debug for SelectorIter<'a, Impl> {
fmt(&self, f: &mut fmt::Formatter) -> fmt::Result898     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
899         let iter = self.iter.clone().rev();
900         for component in iter {
901             component.to_css(f)?
902         }
903         Ok(())
904     }
905 }
906 
907 /// An iterator over all simple selectors belonging to ancestors.
908 struct AncestorIter<'a, Impl: 'a + SelectorImpl>(SelectorIter<'a, Impl>);
909 impl<'a, Impl: 'a + SelectorImpl> AncestorIter<'a, Impl> {
910     /// Creates an AncestorIter. The passed-in iterator is assumed to point to
911     /// the beginning of the child sequence, which will be skipped.
new(inner: SelectorIter<'a, Impl>) -> Self912     fn new(inner: SelectorIter<'a, Impl>) -> Self {
913         let mut result = AncestorIter(inner);
914         result.skip_until_ancestor();
915         result
916     }
917 
918     /// Skips a sequence of simple selectors and all subsequent sequences until
919     /// a non-pseudo-element ancestor combinator is reached.
skip_until_ancestor(&mut self)920     fn skip_until_ancestor(&mut self) {
921         loop {
922             while self.0.next().is_some() {}
923             // If this is ever changed to stop at the "pseudo-element"
924             // combinator, we will need to fix the way we compute hashes for
925             // revalidation selectors.
926             if self.0.next_sequence().map_or(true, |x| {
927                 matches!(x, Combinator::Child | Combinator::Descendant)
928             }) {
929                 break;
930             }
931         }
932     }
933 }
934 
935 impl<'a, Impl: SelectorImpl> Iterator for AncestorIter<'a, Impl> {
936     type Item = &'a Component<Impl>;
next(&mut self) -> Option<Self::Item>937     fn next(&mut self) -> Option<Self::Item> {
938         // Grab the next simple selector in the sequence if available.
939         let next = self.0.next();
940         if next.is_some() {
941             return next;
942         }
943 
944         // See if there are more sequences. If so, skip any non-ancestor sequences.
945         if let Some(combinator) = self.0.next_sequence() {
946             if !matches!(combinator, Combinator::Child | Combinator::Descendant) {
947                 self.skip_until_ancestor();
948             }
949         }
950 
951         self.0.next()
952     }
953 }
954 
955 #[derive(Clone, Copy, Debug, Eq, PartialEq, ToShmem)]
956 pub enum Combinator {
957     Child,        //  >
958     Descendant,   // space
959     NextSibling,  // +
960     LaterSibling, // ~
961     /// A dummy combinator we use to the left of pseudo-elements.
962     ///
963     /// It serializes as the empty string, and acts effectively as a child
964     /// combinator in most cases.  If we ever actually start using a child
965     /// combinator for this, we will need to fix up the way hashes are computed
966     /// for revalidation selectors.
967     PseudoElement,
968     /// Another combinator used for ::slotted(), which represent the jump from
969     /// a node to its assigned slot.
970     SlotAssignment,
971     /// Another combinator used for `::part()`, which represents the jump from
972     /// the part to the containing shadow host.
973     Part,
974 }
975 
976 impl Combinator {
977     /// Returns true if this combinator is a child or descendant combinator.
978     #[inline]
is_ancestor(&self) -> bool979     pub fn is_ancestor(&self) -> bool {
980         matches!(
981             *self,
982             Combinator::Child |
983                 Combinator::Descendant |
984                 Combinator::PseudoElement |
985                 Combinator::SlotAssignment
986         )
987     }
988 
989     /// Returns true if this combinator is a pseudo-element combinator.
990     #[inline]
is_pseudo_element(&self) -> bool991     pub fn is_pseudo_element(&self) -> bool {
992         matches!(*self, Combinator::PseudoElement)
993     }
994 
995     /// Returns true if this combinator is a next- or later-sibling combinator.
996     #[inline]
is_sibling(&self) -> bool997     pub fn is_sibling(&self) -> bool {
998         matches!(*self, Combinator::NextSibling | Combinator::LaterSibling)
999     }
1000 }
1001 
1002 /// A CSS simple selector or combinator. We store both in the same enum for
1003 /// optimal packing and cache performance, see [1].
1004 ///
1005 /// [1] https://bugzilla.mozilla.org/show_bug.cgi?id=1357973
1006 #[derive(Clone, Eq, PartialEq, ToShmem)]
1007 #[shmem(no_bounds)]
1008 pub enum Component<Impl: SelectorImpl> {
1009     Combinator(Combinator),
1010 
1011     ExplicitAnyNamespace,
1012     ExplicitNoNamespace,
1013     DefaultNamespace(#[shmem(field_bound)] Impl::NamespaceUrl),
1014     Namespace(
1015         #[shmem(field_bound)] Impl::NamespacePrefix,
1016         #[shmem(field_bound)] Impl::NamespaceUrl,
1017     ),
1018 
1019     ExplicitUniversalType,
1020     LocalName(LocalName<Impl>),
1021 
1022     ID(#[shmem(field_bound)] Impl::Identifier),
1023     Class(#[shmem(field_bound)] Impl::Identifier),
1024 
1025     AttributeInNoNamespaceExists {
1026         #[shmem(field_bound)]
1027         local_name: Impl::LocalName,
1028         local_name_lower: Impl::LocalName,
1029     },
1030     // Used only when local_name is already lowercase.
1031     AttributeInNoNamespace {
1032         local_name: Impl::LocalName,
1033         operator: AttrSelectorOperator,
1034         #[shmem(field_bound)]
1035         value: Impl::AttrValue,
1036         case_sensitivity: ParsedCaseSensitivity,
1037         never_matches: bool,
1038     },
1039     // Use a Box in the less common cases with more data to keep size_of::<Component>() small.
1040     AttributeOther(Box<AttrSelectorWithOptionalNamespace<Impl>>),
1041 
1042     /// Pseudo-classes
1043     Negation(Box<[Selector<Impl>]>),
1044     FirstChild,
1045     LastChild,
1046     OnlyChild,
1047     Root,
1048     Empty,
1049     Scope,
1050     NthChild(i32, i32),
1051     NthLastChild(i32, i32),
1052     NthOfType(i32, i32),
1053     NthLastOfType(i32, i32),
1054     FirstOfType,
1055     LastOfType,
1056     OnlyOfType,
1057     NonTSPseudoClass(#[shmem(field_bound)] Impl::NonTSPseudoClass),
1058     /// The ::slotted() pseudo-element:
1059     ///
1060     /// https://drafts.csswg.org/css-scoping/#slotted-pseudo
1061     ///
1062     /// The selector here is a compound selector, that is, no combinators.
1063     ///
1064     /// NOTE(emilio): This should support a list of selectors, but as of this
1065     /// writing no other browser does, and that allows them to put ::slotted()
1066     /// in the rule hash, so we do that too.
1067     ///
1068     /// See https://github.com/w3c/csswg-drafts/issues/2158
1069     Slotted(Selector<Impl>),
1070     /// The `::part` pseudo-element.
1071     ///   https://drafts.csswg.org/css-shadow-parts/#part
1072     Part(#[shmem(field_bound)] Box<[Impl::Identifier]>),
1073     /// The `:host` pseudo-class:
1074     ///
1075     /// https://drafts.csswg.org/css-scoping/#host-selector
1076     ///
1077     /// NOTE(emilio): This should support a list of selectors, but as of this
1078     /// writing no other browser does, and that allows them to put :host()
1079     /// in the rule hash, so we do that too.
1080     ///
1081     /// See https://github.com/w3c/csswg-drafts/issues/2158
1082     Host(Option<Selector<Impl>>),
1083     /// The `:where` pseudo-class.
1084     ///
1085     /// https://drafts.csswg.org/selectors/#zero-matches
1086     ///
1087     /// The inner argument is conceptually a SelectorList, but we move the
1088     /// selectors to the heap to keep Component small.
1089     Where(Box<[Selector<Impl>]>),
1090     /// The `:is` pseudo-class.
1091     ///
1092     /// https://drafts.csswg.org/selectors/#matches-pseudo
1093     ///
1094     /// Same comment as above re. the argument.
1095     Is(Box<[Selector<Impl>]>),
1096     /// An implementation-dependent pseudo-element selector.
1097     PseudoElement(#[shmem(field_bound)] Impl::PseudoElement),
1098 }
1099 
1100 impl<Impl: SelectorImpl> Component<Impl> {
1101     /// Returns true if this is a combinator.
1102     #[inline]
is_combinator(&self) -> bool1103     pub fn is_combinator(&self) -> bool {
1104         matches!(*self, Component::Combinator(_))
1105     }
1106 
1107     /// Returns true if this is a :host() selector.
1108     #[inline]
is_host(&self) -> bool1109     pub fn is_host(&self) -> bool {
1110         matches!(*self, Component::Host(..))
1111     }
1112 
1113     /// Returns the value as a combinator if applicable, None otherwise.
as_combinator(&self) -> Option<Combinator>1114     pub fn as_combinator(&self) -> Option<Combinator> {
1115         match *self {
1116             Component::Combinator(c) => Some(c),
1117             _ => None,
1118         }
1119     }
1120 
1121     /// Whether this component is valid after a pseudo-element. Only intended
1122     /// for sanity-checking.
maybe_allowed_after_pseudo_element(&self) -> bool1123     pub fn maybe_allowed_after_pseudo_element(&self) -> bool {
1124         match *self {
1125             Component::NonTSPseudoClass(..) => true,
1126             Component::Negation(ref selectors) |
1127             Component::Is(ref selectors) |
1128             Component::Where(ref selectors) => selectors.iter().all(|selector| {
1129                 selector
1130                     .iter_raw_match_order()
1131                     .all(|c| c.maybe_allowed_after_pseudo_element())
1132             }),
1133             _ => false,
1134         }
1135     }
1136 
1137     /// Whether a given selector should match for stateless pseudo-elements.
1138     ///
1139     /// This is a bit subtle: Only selectors that return true in
1140     /// `maybe_allowed_after_pseudo_element` should end up here, and
1141     /// `NonTSPseudoClass` never matches (as it is a stateless pseudo after
1142     /// all).
matches_for_stateless_pseudo_element(&self) -> bool1143     fn matches_for_stateless_pseudo_element(&self) -> bool {
1144         debug_assert!(
1145             self.maybe_allowed_after_pseudo_element(),
1146             "Someone messed up pseudo-element parsing: {:?}",
1147             *self
1148         );
1149         match *self {
1150             Component::Negation(ref selectors) => !selectors.iter().all(|selector| {
1151                 selector
1152                     .iter_raw_match_order()
1153                     .all(|c| c.matches_for_stateless_pseudo_element())
1154             }),
1155             Component::Is(ref selectors) | Component::Where(ref selectors) => {
1156                 selectors.iter().any(|selector| {
1157                     selector
1158                         .iter_raw_match_order()
1159                         .all(|c| c.matches_for_stateless_pseudo_element())
1160                 })
1161             },
1162             _ => false,
1163         }
1164     }
1165 
visit<V>(&self, visitor: &mut V) -> bool where V: SelectorVisitor<Impl = Impl>,1166     pub fn visit<V>(&self, visitor: &mut V) -> bool
1167     where
1168         V: SelectorVisitor<Impl = Impl>,
1169     {
1170         use self::Component::*;
1171         if !visitor.visit_simple_selector(self) {
1172             return false;
1173         }
1174 
1175         match *self {
1176             Slotted(ref selector) => {
1177                 if !selector.visit(visitor) {
1178                     return false;
1179                 }
1180             },
1181             Host(Some(ref selector)) => {
1182                 if !selector.visit(visitor) {
1183                     return false;
1184                 }
1185             },
1186             AttributeInNoNamespaceExists {
1187                 ref local_name,
1188                 ref local_name_lower,
1189             } => {
1190                 if !visitor.visit_attribute_selector(
1191                     &NamespaceConstraint::Specific(&namespace_empty_string::<Impl>()),
1192                     local_name,
1193                     local_name_lower,
1194                 ) {
1195                     return false;
1196                 }
1197             },
1198             AttributeInNoNamespace {
1199                 ref local_name,
1200                 never_matches,
1201                 ..
1202             } if !never_matches => {
1203                 if !visitor.visit_attribute_selector(
1204                     &NamespaceConstraint::Specific(&namespace_empty_string::<Impl>()),
1205                     local_name,
1206                     local_name,
1207                 ) {
1208                     return false;
1209                 }
1210             },
1211             AttributeOther(ref attr_selector) if !attr_selector.never_matches => {
1212                 let empty_string;
1213                 let namespace = match attr_selector.namespace() {
1214                     Some(ns) => ns,
1215                     None => {
1216                         empty_string = crate::parser::namespace_empty_string::<Impl>();
1217                         NamespaceConstraint::Specific(&empty_string)
1218                     },
1219                 };
1220                 if !visitor.visit_attribute_selector(
1221                     &namespace,
1222                     &attr_selector.local_name,
1223                     &attr_selector.local_name_lower,
1224                 ) {
1225                     return false;
1226                 }
1227             },
1228 
1229             NonTSPseudoClass(ref pseudo_class) => {
1230                 if !pseudo_class.visit(visitor) {
1231                     return false;
1232                 }
1233             },
1234 
1235             Negation(ref list) | Is(ref list) | Where(ref list) => {
1236                 if !visitor.visit_selector_list(&list) {
1237                     return false;
1238                 }
1239             },
1240             _ => {},
1241         }
1242 
1243         true
1244     }
1245 }
1246 
1247 #[derive(Clone, Eq, PartialEq, ToShmem)]
1248 #[shmem(no_bounds)]
1249 pub struct LocalName<Impl: SelectorImpl> {
1250     #[shmem(field_bound)]
1251     pub name: Impl::LocalName,
1252     pub lower_name: Impl::LocalName,
1253 }
1254 
1255 impl<Impl: SelectorImpl> Debug for Selector<Impl> {
fmt(&self, f: &mut fmt::Formatter) -> fmt::Result1256     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1257         f.write_str("Selector(")?;
1258         self.to_css(f)?;
1259         write!(f, ", specificity = 0x{:x})", self.specificity())
1260     }
1261 }
1262 
1263 impl<Impl: SelectorImpl> Debug for Component<Impl> {
fmt(&self, f: &mut fmt::Formatter) -> fmt::Result1264     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1265         self.to_css(f)
1266     }
1267 }
1268 impl<Impl: SelectorImpl> Debug for AttrSelectorWithOptionalNamespace<Impl> {
fmt(&self, f: &mut fmt::Formatter) -> fmt::Result1269     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1270         self.to_css(f)
1271     }
1272 }
1273 impl<Impl: SelectorImpl> Debug for LocalName<Impl> {
fmt(&self, f: &mut fmt::Formatter) -> fmt::Result1274     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1275         self.to_css(f)
1276     }
1277 }
1278 
serialize_selector_list<'a, Impl, I, W>(iter: I, dest: &mut W) -> fmt::Result where Impl: SelectorImpl, I: Iterator<Item = &'a Selector<Impl>>, W: fmt::Write,1279 fn serialize_selector_list<'a, Impl, I, W>(iter: I, dest: &mut W) -> fmt::Result
1280 where
1281     Impl: SelectorImpl,
1282     I: Iterator<Item = &'a Selector<Impl>>,
1283     W: fmt::Write,
1284 {
1285     let mut first = true;
1286     for selector in iter {
1287         if !first {
1288             dest.write_str(", ")?;
1289         }
1290         first = false;
1291         selector.to_css(dest)?;
1292     }
1293     Ok(())
1294 }
1295 
1296 impl<Impl: SelectorImpl> ToCss for SelectorList<Impl> {
to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write,1297     fn to_css<W>(&self, dest: &mut W) -> fmt::Result
1298     where
1299         W: fmt::Write,
1300     {
1301         serialize_selector_list(self.0.iter(), dest)
1302     }
1303 }
1304 
1305 impl<Impl: SelectorImpl> ToCss for Selector<Impl> {
to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write,1306     fn to_css<W>(&self, dest: &mut W) -> fmt::Result
1307     where
1308         W: fmt::Write,
1309     {
1310         // Compound selectors invert the order of their contents, so we need to
1311         // undo that during serialization.
1312         //
1313         // This two-iterator strategy involves walking over the selector twice.
1314         // We could do something more clever, but selector serialization probably
1315         // isn't hot enough to justify it, and the stringification likely
1316         // dominates anyway.
1317         //
1318         // NB: A parse-order iterator is a Rev<>, which doesn't expose as_slice(),
1319         // which we need for |split|. So we split by combinators on a match-order
1320         // sequence and then reverse.
1321 
1322         let mut combinators = self
1323             .iter_raw_match_order()
1324             .rev()
1325             .filter_map(|x| x.as_combinator());
1326         let compound_selectors = self
1327             .iter_raw_match_order()
1328             .as_slice()
1329             .split(|x| x.is_combinator())
1330             .rev();
1331 
1332         let mut combinators_exhausted = false;
1333         for compound in compound_selectors {
1334             debug_assert!(!combinators_exhausted);
1335 
1336             // https://drafts.csswg.org/cssom/#serializing-selectors
1337             if compound.is_empty() {
1338                 continue;
1339             }
1340 
1341             // 1. If there is only one simple selector in the compound selectors
1342             //    which is a universal selector, append the result of
1343             //    serializing the universal selector to s.
1344             //
1345             // Check if `!compound.empty()` first--this can happen if we have
1346             // something like `... > ::before`, because we store `>` and `::`
1347             // both as combinators internally.
1348             //
1349             // If we are in this case, after we have serialized the universal
1350             // selector, we skip Step 2 and continue with the algorithm.
1351             let (can_elide_namespace, first_non_namespace) = match compound[0] {
1352                 Component::ExplicitAnyNamespace |
1353                 Component::ExplicitNoNamespace |
1354                 Component::Namespace(..) => (false, 1),
1355                 Component::DefaultNamespace(..) => (true, 1),
1356                 _ => (true, 0),
1357             };
1358             let mut perform_step_2 = true;
1359             let next_combinator = combinators.next();
1360             if first_non_namespace == compound.len() - 1 {
1361                 match (next_combinator, &compound[first_non_namespace]) {
1362                     // We have to be careful here, because if there is a
1363                     // pseudo element "combinator" there isn't really just
1364                     // the one simple selector. Technically this compound
1365                     // selector contains the pseudo element selector as well
1366                     // -- Combinator::PseudoElement, just like
1367                     // Combinator::SlotAssignment, don't exist in the
1368                     // spec.
1369                     (Some(Combinator::PseudoElement), _) |
1370                     (Some(Combinator::SlotAssignment), _) => (),
1371                     (_, &Component::ExplicitUniversalType) => {
1372                         // Iterate over everything so we serialize the namespace
1373                         // too.
1374                         for simple in compound.iter() {
1375                             simple.to_css(dest)?;
1376                         }
1377                         // Skip step 2, which is an "otherwise".
1378                         perform_step_2 = false;
1379                     },
1380                     _ => (),
1381                 }
1382             }
1383 
1384             // 2. Otherwise, for each simple selector in the compound selectors
1385             //    that is not a universal selector of which the namespace prefix
1386             //    maps to a namespace that is not the default namespace
1387             //    serialize the simple selector and append the result to s.
1388             //
1389             // See https://github.com/w3c/csswg-drafts/issues/1606, which is
1390             // proposing to change this to match up with the behavior asserted
1391             // in cssom/serialize-namespaced-type-selectors.html, which the
1392             // following code tries to match.
1393             if perform_step_2 {
1394                 for simple in compound.iter() {
1395                     if let Component::ExplicitUniversalType = *simple {
1396                         // Can't have a namespace followed by a pseudo-element
1397                         // selector followed by a universal selector in the same
1398                         // compound selector, so we don't have to worry about the
1399                         // real namespace being in a different `compound`.
1400                         if can_elide_namespace {
1401                             continue;
1402                         }
1403                     }
1404                     simple.to_css(dest)?;
1405                 }
1406             }
1407 
1408             // 3. If this is not the last part of the chain of the selector
1409             //    append a single SPACE (U+0020), followed by the combinator
1410             //    ">", "+", "~", ">>", "||", as appropriate, followed by another
1411             //    single SPACE (U+0020) if the combinator was not whitespace, to
1412             //    s.
1413             match next_combinator {
1414                 Some(c) => c.to_css(dest)?,
1415                 None => combinators_exhausted = true,
1416             };
1417 
1418             // 4. If this is the last part of the chain of the selector and
1419             //    there is a pseudo-element, append "::" followed by the name of
1420             //    the pseudo-element, to s.
1421             //
1422             // (we handle this above)
1423         }
1424 
1425         Ok(())
1426     }
1427 }
1428 
1429 impl ToCss for Combinator {
to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write,1430     fn to_css<W>(&self, dest: &mut W) -> fmt::Result
1431     where
1432         W: fmt::Write,
1433     {
1434         match *self {
1435             Combinator::Child => dest.write_str(" > "),
1436             Combinator::Descendant => dest.write_str(" "),
1437             Combinator::NextSibling => dest.write_str(" + "),
1438             Combinator::LaterSibling => dest.write_str(" ~ "),
1439             Combinator::PseudoElement | Combinator::Part | Combinator::SlotAssignment => Ok(()),
1440         }
1441     }
1442 }
1443 
1444 impl<Impl: SelectorImpl> ToCss for Component<Impl> {
to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write,1445     fn to_css<W>(&self, dest: &mut W) -> fmt::Result
1446     where
1447         W: fmt::Write,
1448     {
1449         use self::Component::*;
1450 
1451         /// Serialize <an+b> values (part of the CSS Syntax spec, but currently only used here).
1452         /// <https://drafts.csswg.org/css-syntax-3/#serialize-an-anb-value>
1453         fn write_affine<W>(dest: &mut W, a: i32, b: i32) -> fmt::Result
1454         where
1455             W: fmt::Write,
1456         {
1457             match (a, b) {
1458                 (0, 0) => dest.write_char('0'),
1459 
1460                 (1, 0) => dest.write_char('n'),
1461                 (-1, 0) => dest.write_str("-n"),
1462                 (_, 0) => write!(dest, "{}n", a),
1463 
1464                 (0, _) => write!(dest, "{}", b),
1465                 (1, _) => write!(dest, "n{:+}", b),
1466                 (-1, _) => write!(dest, "-n{:+}", b),
1467                 (_, _) => write!(dest, "{}n{:+}", a, b),
1468             }
1469         }
1470 
1471         match *self {
1472             Combinator(ref c) => c.to_css(dest),
1473             Slotted(ref selector) => {
1474                 dest.write_str("::slotted(")?;
1475                 selector.to_css(dest)?;
1476                 dest.write_char(')')
1477             },
1478             Part(ref part_names) => {
1479                 dest.write_str("::part(")?;
1480                 for (i, name) in part_names.iter().enumerate() {
1481                     if i != 0 {
1482                         dest.write_char(' ')?;
1483                     }
1484                     name.to_css(dest)?;
1485                 }
1486                 dest.write_char(')')
1487             },
1488             PseudoElement(ref p) => p.to_css(dest),
1489             ID(ref s) => {
1490                 dest.write_char('#')?;
1491                 s.to_css(dest)
1492             },
1493             Class(ref s) => {
1494                 dest.write_char('.')?;
1495                 s.to_css(dest)
1496             },
1497             LocalName(ref s) => s.to_css(dest),
1498             ExplicitUniversalType => dest.write_char('*'),
1499 
1500             DefaultNamespace(_) => Ok(()),
1501             ExplicitNoNamespace => dest.write_char('|'),
1502             ExplicitAnyNamespace => dest.write_str("*|"),
1503             Namespace(ref prefix, _) => {
1504                 prefix.to_css(dest)?;
1505                 dest.write_char('|')
1506             },
1507 
1508             AttributeInNoNamespaceExists { ref local_name, .. } => {
1509                 dest.write_char('[')?;
1510                 local_name.to_css(dest)?;
1511                 dest.write_char(']')
1512             },
1513             AttributeInNoNamespace {
1514                 ref local_name,
1515                 operator,
1516                 ref value,
1517                 case_sensitivity,
1518                 ..
1519             } => {
1520                 dest.write_char('[')?;
1521                 local_name.to_css(dest)?;
1522                 operator.to_css(dest)?;
1523                 dest.write_char('"')?;
1524                 value.to_css(dest)?;
1525                 dest.write_char('"')?;
1526                 match case_sensitivity {
1527                     ParsedCaseSensitivity::CaseSensitive |
1528                     ParsedCaseSensitivity::AsciiCaseInsensitiveIfInHtmlElementInHtmlDocument => {},
1529                     ParsedCaseSensitivity::AsciiCaseInsensitive => dest.write_str(" i")?,
1530                     ParsedCaseSensitivity::ExplicitCaseSensitive => dest.write_str(" s")?,
1531                 }
1532                 dest.write_char(']')
1533             },
1534             AttributeOther(ref attr_selector) => attr_selector.to_css(dest),
1535 
1536             // Pseudo-classes
1537             FirstChild => dest.write_str(":first-child"),
1538             LastChild => dest.write_str(":last-child"),
1539             OnlyChild => dest.write_str(":only-child"),
1540             Root => dest.write_str(":root"),
1541             Empty => dest.write_str(":empty"),
1542             Scope => dest.write_str(":scope"),
1543             Host(ref selector) => {
1544                 dest.write_str(":host")?;
1545                 if let Some(ref selector) = *selector {
1546                     dest.write_char('(')?;
1547                     selector.to_css(dest)?;
1548                     dest.write_char(')')?;
1549                 }
1550                 Ok(())
1551             },
1552             FirstOfType => dest.write_str(":first-of-type"),
1553             LastOfType => dest.write_str(":last-of-type"),
1554             OnlyOfType => dest.write_str(":only-of-type"),
1555             NthChild(a, b) | NthLastChild(a, b) | NthOfType(a, b) | NthLastOfType(a, b) => {
1556                 match *self {
1557                     NthChild(_, _) => dest.write_str(":nth-child(")?,
1558                     NthLastChild(_, _) => dest.write_str(":nth-last-child(")?,
1559                     NthOfType(_, _) => dest.write_str(":nth-of-type(")?,
1560                     NthLastOfType(_, _) => dest.write_str(":nth-last-of-type(")?,
1561                     _ => unreachable!(),
1562                 }
1563                 write_affine(dest, a, b)?;
1564                 dest.write_char(')')
1565             },
1566             Is(ref list) | Where(ref list) | Negation(ref list) => {
1567                 match *self {
1568                     Where(..) => dest.write_str(":where(")?,
1569                     Is(..) => dest.write_str(":is(")?,
1570                     Negation(..) => dest.write_str(":not(")?,
1571                     _ => unreachable!(),
1572                 }
1573                 serialize_selector_list(list.iter(), dest)?;
1574                 dest.write_str(")")
1575             },
1576             NonTSPseudoClass(ref pseudo) => pseudo.to_css(dest),
1577         }
1578     }
1579 }
1580 
1581 impl<Impl: SelectorImpl> ToCss for AttrSelectorWithOptionalNamespace<Impl> {
to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write,1582     fn to_css<W>(&self, dest: &mut W) -> fmt::Result
1583     where
1584         W: fmt::Write,
1585     {
1586         dest.write_char('[')?;
1587         match self.namespace {
1588             Some(NamespaceConstraint::Specific((ref prefix, _))) => {
1589                 prefix.to_css(dest)?;
1590                 dest.write_char('|')?
1591             },
1592             Some(NamespaceConstraint::Any) => dest.write_str("*|")?,
1593             None => {},
1594         }
1595         self.local_name.to_css(dest)?;
1596         match self.operation {
1597             ParsedAttrSelectorOperation::Exists => {},
1598             ParsedAttrSelectorOperation::WithValue {
1599                 operator,
1600                 case_sensitivity,
1601                 ref expected_value,
1602             } => {
1603                 operator.to_css(dest)?;
1604                 dest.write_char('"')?;
1605                 expected_value.to_css(dest)?;
1606                 dest.write_char('"')?;
1607                 match case_sensitivity {
1608                     ParsedCaseSensitivity::CaseSensitive |
1609                     ParsedCaseSensitivity::AsciiCaseInsensitiveIfInHtmlElementInHtmlDocument => {},
1610                     ParsedCaseSensitivity::AsciiCaseInsensitive => dest.write_str(" i")?,
1611                     ParsedCaseSensitivity::ExplicitCaseSensitive => dest.write_str(" s")?,
1612                 }
1613             },
1614         }
1615         dest.write_char(']')
1616     }
1617 }
1618 
1619 impl<Impl: SelectorImpl> ToCss for LocalName<Impl> {
to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write,1620     fn to_css<W>(&self, dest: &mut W) -> fmt::Result
1621     where
1622         W: fmt::Write,
1623     {
1624         self.name.to_css(dest)
1625     }
1626 }
1627 
1628 /// Build up a Selector.
1629 /// selector : simple_selector_sequence [ combinator simple_selector_sequence ]* ;
1630 ///
1631 /// `Err` means invalid selector.
parse_selector<'i, 't, P, Impl>( parser: &P, input: &mut CssParser<'i, 't>, mut state: SelectorParsingState, ) -> Result<Selector<Impl>, ParseError<'i, P::Error>> where P: Parser<'i, Impl = Impl>, Impl: SelectorImpl,1632 fn parse_selector<'i, 't, P, Impl>(
1633     parser: &P,
1634     input: &mut CssParser<'i, 't>,
1635     mut state: SelectorParsingState,
1636 ) -> Result<Selector<Impl>, ParseError<'i, P::Error>>
1637 where
1638     P: Parser<'i, Impl = Impl>,
1639     Impl: SelectorImpl,
1640 {
1641     let mut builder = SelectorBuilder::default();
1642 
1643     let mut has_pseudo_element = false;
1644     let mut slotted = false;
1645     let mut part = false;
1646     'outer_loop: loop {
1647         // Parse a sequence of simple selectors.
1648         let empty = parse_compound_selector(parser, &mut state, input, &mut builder)?;
1649         if empty {
1650             return Err(input.new_custom_error(if builder.has_combinators() {
1651                 SelectorParseErrorKind::DanglingCombinator
1652             } else {
1653                 SelectorParseErrorKind::EmptySelector
1654             }));
1655         }
1656 
1657         if state.intersects(SelectorParsingState::AFTER_PSEUDO) {
1658             has_pseudo_element = state.intersects(SelectorParsingState::AFTER_PSEUDO_ELEMENT);
1659             slotted = state.intersects(SelectorParsingState::AFTER_SLOTTED);
1660             part = state.intersects(SelectorParsingState::AFTER_PART);
1661             debug_assert!(has_pseudo_element || slotted || part);
1662             break;
1663         }
1664 
1665         // Parse a combinator.
1666         let combinator;
1667         let mut any_whitespace = false;
1668         loop {
1669             let before_this_token = input.state();
1670             match input.next_including_whitespace() {
1671                 Err(_e) => break 'outer_loop,
1672                 Ok(&Token::WhiteSpace(_)) => any_whitespace = true,
1673                 Ok(&Token::Delim('>')) => {
1674                     combinator = Combinator::Child;
1675                     break;
1676                 },
1677                 Ok(&Token::Delim('+')) => {
1678                     combinator = Combinator::NextSibling;
1679                     break;
1680                 },
1681                 Ok(&Token::Delim('~')) => {
1682                     combinator = Combinator::LaterSibling;
1683                     break;
1684                 },
1685                 Ok(_) => {
1686                     input.reset(&before_this_token);
1687                     if any_whitespace {
1688                         combinator = Combinator::Descendant;
1689                         break;
1690                     } else {
1691                         break 'outer_loop;
1692                     }
1693                 },
1694             }
1695         }
1696 
1697         if !state.allows_combinators() {
1698             return Err(input.new_custom_error(SelectorParseErrorKind::InvalidState));
1699         }
1700 
1701         builder.push_combinator(combinator);
1702     }
1703 
1704     Ok(Selector(builder.build(has_pseudo_element, slotted, part)))
1705 }
1706 
1707 impl<Impl: SelectorImpl> Selector<Impl> {
1708     /// Parse a selector, without any pseudo-element.
1709     #[inline]
parse<'i, 't, P>( parser: &P, input: &mut CssParser<'i, 't>, ) -> Result<Self, ParseError<'i, P::Error>> where P: Parser<'i, Impl = Impl>,1710     pub fn parse<'i, 't, P>(
1711         parser: &P,
1712         input: &mut CssParser<'i, 't>,
1713     ) -> Result<Self, ParseError<'i, P::Error>>
1714     where
1715         P: Parser<'i, Impl = Impl>,
1716     {
1717         parse_selector(parser, input, SelectorParsingState::empty())
1718     }
1719 }
1720 
1721 /// * `Err(())`: Invalid selector, abort
1722 /// * `Ok(false)`: Not a type selector, could be something else. `input` was not consumed.
1723 /// * `Ok(true)`: Length 0 (`*|*`), 1 (`*|E` or `ns|*`) or 2 (`|E` or `ns|E`)
parse_type_selector<'i, 't, P, Impl, S>( parser: &P, input: &mut CssParser<'i, 't>, state: SelectorParsingState, sink: &mut S, ) -> Result<bool, ParseError<'i, P::Error>> where P: Parser<'i, Impl = Impl>, Impl: SelectorImpl, S: Push<Component<Impl>>,1724 fn parse_type_selector<'i, 't, P, Impl, S>(
1725     parser: &P,
1726     input: &mut CssParser<'i, 't>,
1727     state: SelectorParsingState,
1728     sink: &mut S,
1729 ) -> Result<bool, ParseError<'i, P::Error>>
1730 where
1731     P: Parser<'i, Impl = Impl>,
1732     Impl: SelectorImpl,
1733     S: Push<Component<Impl>>,
1734 {
1735     match parse_qualified_name(parser, input, /* in_attr_selector = */ false) {
1736         Err(ParseError {
1737             kind: ParseErrorKind::Basic(BasicParseErrorKind::EndOfInput),
1738             ..
1739         }) |
1740         Ok(OptionalQName::None(_)) => Ok(false),
1741         Ok(OptionalQName::Some(namespace, local_name)) => {
1742             if state.intersects(SelectorParsingState::AFTER_PSEUDO) {
1743                 return Err(input.new_custom_error(SelectorParseErrorKind::InvalidState));
1744             }
1745             match namespace {
1746                 QNamePrefix::ImplicitAnyNamespace => {},
1747                 QNamePrefix::ImplicitDefaultNamespace(url) => {
1748                     sink.push(Component::DefaultNamespace(url))
1749                 },
1750                 QNamePrefix::ExplicitNamespace(prefix, url) => {
1751                     sink.push(match parser.default_namespace() {
1752                         Some(ref default_url) if url == *default_url => {
1753                             Component::DefaultNamespace(url)
1754                         },
1755                         _ => Component::Namespace(prefix, url),
1756                     })
1757                 },
1758                 QNamePrefix::ExplicitNoNamespace => sink.push(Component::ExplicitNoNamespace),
1759                 QNamePrefix::ExplicitAnyNamespace => {
1760                     match parser.default_namespace() {
1761                         // Element type selectors that have no namespace
1762                         // component (no namespace separator) represent elements
1763                         // without regard to the element's namespace (equivalent
1764                         // to "*|") unless a default namespace has been declared
1765                         // for namespaced selectors (e.g. in CSS, in the style
1766                         // sheet). If a default namespace has been declared,
1767                         // such selectors will represent only elements in the
1768                         // default namespace.
1769                         // -- Selectors § 6.1.1
1770                         // So we'll have this act the same as the
1771                         // QNamePrefix::ImplicitAnyNamespace case.
1772                         None => {},
1773                         Some(_) => sink.push(Component::ExplicitAnyNamespace),
1774                     }
1775                 },
1776                 QNamePrefix::ImplicitNoNamespace => {
1777                     unreachable!() // Not returned with in_attr_selector = false
1778                 },
1779             }
1780             match local_name {
1781                 Some(name) => sink.push(Component::LocalName(LocalName {
1782                     lower_name: to_ascii_lowercase(&name).as_ref().into(),
1783                     name: name.as_ref().into(),
1784                 })),
1785                 None => sink.push(Component::ExplicitUniversalType),
1786             }
1787             Ok(true)
1788         },
1789         Err(e) => Err(e),
1790     }
1791 }
1792 
1793 #[derive(Debug)]
1794 enum SimpleSelectorParseResult<Impl: SelectorImpl> {
1795     SimpleSelector(Component<Impl>),
1796     PseudoElement(Impl::PseudoElement),
1797     SlottedPseudo(Selector<Impl>),
1798     PartPseudo(Box<[Impl::Identifier]>),
1799 }
1800 
1801 #[derive(Debug)]
1802 enum QNamePrefix<Impl: SelectorImpl> {
1803     ImplicitNoNamespace,                          // `foo` in attr selectors
1804     ImplicitAnyNamespace,                         // `foo` in type selectors, without a default ns
1805     ImplicitDefaultNamespace(Impl::NamespaceUrl), // `foo` in type selectors, with a default ns
1806     ExplicitNoNamespace,                          // `|foo`
1807     ExplicitAnyNamespace,                         // `*|foo`
1808     ExplicitNamespace(Impl::NamespacePrefix, Impl::NamespaceUrl), // `prefix|foo`
1809 }
1810 
1811 enum OptionalQName<'i, Impl: SelectorImpl> {
1812     Some(QNamePrefix<Impl>, Option<CowRcStr<'i>>),
1813     None(Token<'i>),
1814 }
1815 
1816 /// * `Err(())`: Invalid selector, abort
1817 /// * `Ok(None(token))`: Not a simple selector, could be something else. `input` was not consumed,
1818 ///                      but the token is still returned.
1819 /// * `Ok(Some(namespace, local_name))`: `None` for the local name means a `*` universal selector
parse_qualified_name<'i, 't, P, Impl>( parser: &P, input: &mut CssParser<'i, 't>, in_attr_selector: bool, ) -> Result<OptionalQName<'i, Impl>, ParseError<'i, P::Error>> where P: Parser<'i, Impl = Impl>, Impl: SelectorImpl,1820 fn parse_qualified_name<'i, 't, P, Impl>(
1821     parser: &P,
1822     input: &mut CssParser<'i, 't>,
1823     in_attr_selector: bool,
1824 ) -> Result<OptionalQName<'i, Impl>, ParseError<'i, P::Error>>
1825 where
1826     P: Parser<'i, Impl = Impl>,
1827     Impl: SelectorImpl,
1828 {
1829     let default_namespace = |local_name| {
1830         let namespace = match parser.default_namespace() {
1831             Some(url) => QNamePrefix::ImplicitDefaultNamespace(url),
1832             None => QNamePrefix::ImplicitAnyNamespace,
1833         };
1834         Ok(OptionalQName::Some(namespace, local_name))
1835     };
1836 
1837     let explicit_namespace = |input: &mut CssParser<'i, 't>, namespace| {
1838         let location = input.current_source_location();
1839         match input.next_including_whitespace() {
1840             Ok(&Token::Delim('*')) if !in_attr_selector => Ok(OptionalQName::Some(namespace, None)),
1841             Ok(&Token::Ident(ref local_name)) => {
1842                 Ok(OptionalQName::Some(namespace, Some(local_name.clone())))
1843             },
1844             Ok(t) if in_attr_selector => {
1845                 let e = SelectorParseErrorKind::InvalidQualNameInAttr(t.clone());
1846                 Err(location.new_custom_error(e))
1847             },
1848             Ok(t) => Err(location.new_custom_error(
1849                 SelectorParseErrorKind::ExplicitNamespaceUnexpectedToken(t.clone()),
1850             )),
1851             Err(e) => Err(e.into()),
1852         }
1853     };
1854 
1855     let start = input.state();
1856     match input.next_including_whitespace() {
1857         Ok(Token::Ident(value)) => {
1858             let value = value.clone();
1859             let after_ident = input.state();
1860             match input.next_including_whitespace() {
1861                 Ok(&Token::Delim('|')) => {
1862                     let prefix = value.as_ref().into();
1863                     let result = parser.namespace_for_prefix(&prefix);
1864                     let url = result.ok_or(
1865                         after_ident
1866                             .source_location()
1867                             .new_custom_error(SelectorParseErrorKind::ExpectedNamespace(value)),
1868                     )?;
1869                     explicit_namespace(input, QNamePrefix::ExplicitNamespace(prefix, url))
1870                 },
1871                 _ => {
1872                     input.reset(&after_ident);
1873                     if in_attr_selector {
1874                         Ok(OptionalQName::Some(
1875                             QNamePrefix::ImplicitNoNamespace,
1876                             Some(value),
1877                         ))
1878                     } else {
1879                         default_namespace(Some(value))
1880                     }
1881                 },
1882             }
1883         },
1884         Ok(Token::Delim('*')) => {
1885             let after_star = input.state();
1886             match input.next_including_whitespace() {
1887                 Ok(&Token::Delim('|')) => {
1888                     explicit_namespace(input, QNamePrefix::ExplicitAnyNamespace)
1889                 },
1890                 _ if !in_attr_selector => {
1891                     input.reset(&after_star);
1892                     default_namespace(None)
1893                 }
1894                 result => {
1895                     let t = result?;
1896                     Err(after_star
1897                         .source_location()
1898                         .new_custom_error(SelectorParseErrorKind::ExpectedBarInAttr(t.clone())))
1899                 },
1900             }
1901         },
1902         Ok(Token::Delim('|')) => explicit_namespace(input, QNamePrefix::ExplicitNoNamespace),
1903         Ok(t) => {
1904             let t = t.clone();
1905             input.reset(&start);
1906             Ok(OptionalQName::None(t))
1907         },
1908         Err(e) => {
1909             input.reset(&start);
1910             Err(e.into())
1911         },
1912     }
1913 }
1914 
parse_attribute_selector<'i, 't, P, Impl>( parser: &P, input: &mut CssParser<'i, 't>, ) -> Result<Component<Impl>, ParseError<'i, P::Error>> where P: Parser<'i, Impl = Impl>, Impl: SelectorImpl,1915 fn parse_attribute_selector<'i, 't, P, Impl>(
1916     parser: &P,
1917     input: &mut CssParser<'i, 't>,
1918 ) -> Result<Component<Impl>, ParseError<'i, P::Error>>
1919 where
1920     P: Parser<'i, Impl = Impl>,
1921     Impl: SelectorImpl,
1922 {
1923     let namespace;
1924     let local_name;
1925 
1926     input.skip_whitespace();
1927 
1928     match parse_qualified_name(parser, input, /* in_attr_selector = */ true)? {
1929         OptionalQName::None(t) => {
1930             return Err(input.new_custom_error(
1931                 SelectorParseErrorKind::NoQualifiedNameInAttributeSelector(t),
1932             ));
1933         },
1934         OptionalQName::Some(_, None) => unreachable!(),
1935         OptionalQName::Some(ns, Some(ln)) => {
1936             local_name = ln;
1937             namespace = match ns {
1938                 QNamePrefix::ImplicitNoNamespace | QNamePrefix::ExplicitNoNamespace => None,
1939                 QNamePrefix::ExplicitNamespace(prefix, url) => {
1940                     Some(NamespaceConstraint::Specific((prefix, url)))
1941                 },
1942                 QNamePrefix::ExplicitAnyNamespace => Some(NamespaceConstraint::Any),
1943                 QNamePrefix::ImplicitAnyNamespace | QNamePrefix::ImplicitDefaultNamespace(_) => {
1944                     unreachable!() // Not returned with in_attr_selector = true
1945                 },
1946             }
1947         },
1948     }
1949 
1950     let location = input.current_source_location();
1951     let operator = match input.next() {
1952         // [foo]
1953         Err(_) => {
1954             let local_name_lower = to_ascii_lowercase(&local_name).as_ref().into();
1955             let local_name = local_name.as_ref().into();
1956             if let Some(namespace) = namespace {
1957                 return Ok(Component::AttributeOther(Box::new(
1958                     AttrSelectorWithOptionalNamespace {
1959                         namespace: Some(namespace),
1960                         local_name,
1961                         local_name_lower,
1962                         operation: ParsedAttrSelectorOperation::Exists,
1963                         never_matches: false,
1964                     },
1965                 )));
1966             } else {
1967                 return Ok(Component::AttributeInNoNamespaceExists {
1968                     local_name,
1969                     local_name_lower,
1970                 });
1971             }
1972         },
1973 
1974         // [foo=bar]
1975         Ok(&Token::Delim('=')) => AttrSelectorOperator::Equal,
1976         // [foo~=bar]
1977         Ok(&Token::IncludeMatch) => AttrSelectorOperator::Includes,
1978         // [foo|=bar]
1979         Ok(&Token::DashMatch) => AttrSelectorOperator::DashMatch,
1980         // [foo^=bar]
1981         Ok(&Token::PrefixMatch) => AttrSelectorOperator::Prefix,
1982         // [foo*=bar]
1983         Ok(&Token::SubstringMatch) => AttrSelectorOperator::Substring,
1984         // [foo$=bar]
1985         Ok(&Token::SuffixMatch) => AttrSelectorOperator::Suffix,
1986         Ok(t) => {
1987             return Err(location.new_custom_error(
1988                 SelectorParseErrorKind::UnexpectedTokenInAttributeSelector(t.clone()),
1989             ));
1990         },
1991     };
1992 
1993     let value = match input.expect_ident_or_string() {
1994         Ok(t) => t.clone(),
1995         Err(BasicParseError {
1996             kind: BasicParseErrorKind::UnexpectedToken(t),
1997             location,
1998         }) => return Err(location.new_custom_error(SelectorParseErrorKind::BadValueInAttr(t))),
1999         Err(e) => return Err(e.into()),
2000     };
2001     let never_matches = match operator {
2002         AttrSelectorOperator::Equal | AttrSelectorOperator::DashMatch => false,
2003 
2004         AttrSelectorOperator::Includes => value.is_empty() || value.contains(SELECTOR_WHITESPACE),
2005 
2006         AttrSelectorOperator::Prefix |
2007         AttrSelectorOperator::Substring |
2008         AttrSelectorOperator::Suffix => value.is_empty(),
2009     };
2010 
2011     let attribute_flags = parse_attribute_flags(input)?;
2012 
2013     let value = value.as_ref().into();
2014     let local_name_lower;
2015     let local_name_is_ascii_lowercase;
2016     let case_sensitivity;
2017     {
2018         let local_name_lower_cow = to_ascii_lowercase(&local_name);
2019         case_sensitivity =
2020             attribute_flags.to_case_sensitivity(local_name_lower_cow.as_ref(), namespace.is_some());
2021         local_name_lower = local_name_lower_cow.as_ref().into();
2022         local_name_is_ascii_lowercase = matches!(local_name_lower_cow, Cow::Borrowed(..));
2023     }
2024     let local_name = local_name.as_ref().into();
2025     if namespace.is_some() || !local_name_is_ascii_lowercase {
2026         Ok(Component::AttributeOther(Box::new(
2027             AttrSelectorWithOptionalNamespace {
2028                 namespace,
2029                 local_name,
2030                 local_name_lower,
2031                 never_matches,
2032                 operation: ParsedAttrSelectorOperation::WithValue {
2033                     operator,
2034                     case_sensitivity,
2035                     expected_value: value,
2036                 },
2037             },
2038         )))
2039     } else {
2040         Ok(Component::AttributeInNoNamespace {
2041             local_name,
2042             operator,
2043             value,
2044             case_sensitivity,
2045             never_matches,
2046         })
2047     }
2048 }
2049 
2050 /// An attribute selector can have 's' or 'i' as flags, or no flags at all.
2051 enum AttributeFlags {
2052     // Matching should be case-sensitive ('s' flag).
2053     CaseSensitive,
2054     // Matching should be case-insensitive ('i' flag).
2055     AsciiCaseInsensitive,
2056     // No flags.  Matching behavior depends on the name of the attribute.
2057     CaseSensitivityDependsOnName,
2058 }
2059 
2060 impl AttributeFlags {
to_case_sensitivity(self, local_name: &str, have_namespace: bool) -> ParsedCaseSensitivity2061     fn to_case_sensitivity(self, local_name: &str, have_namespace: bool) -> ParsedCaseSensitivity {
2062         match self {
2063             AttributeFlags::CaseSensitive => ParsedCaseSensitivity::ExplicitCaseSensitive,
2064             AttributeFlags::AsciiCaseInsensitive => ParsedCaseSensitivity::AsciiCaseInsensitive,
2065             AttributeFlags::CaseSensitivityDependsOnName => {
2066                 if !have_namespace &&
2067                     include!(concat!(
2068                         env!("OUT_DIR"),
2069                         "/ascii_case_insensitive_html_attributes.rs"
2070                     ))
2071                     .contains(local_name)
2072                 {
2073                     ParsedCaseSensitivity::AsciiCaseInsensitiveIfInHtmlElementInHtmlDocument
2074                 } else {
2075                     ParsedCaseSensitivity::CaseSensitive
2076                 }
2077             },
2078         }
2079     }
2080 }
2081 
parse_attribute_flags<'i, 't>( input: &mut CssParser<'i, 't>, ) -> Result<AttributeFlags, BasicParseError<'i>>2082 fn parse_attribute_flags<'i, 't>(
2083     input: &mut CssParser<'i, 't>,
2084 ) -> Result<AttributeFlags, BasicParseError<'i>> {
2085     let location = input.current_source_location();
2086     let token = match input.next() {
2087         Ok(t) => t,
2088         Err(..) => {
2089             // Selectors spec says language-defined; HTML says it depends on the
2090             // exact attribute name.
2091             return Ok(AttributeFlags::CaseSensitivityDependsOnName);
2092         },
2093     };
2094 
2095     let ident = match *token {
2096         Token::Ident(ref i) => i,
2097         ref other => return Err(location.new_basic_unexpected_token_error(other.clone())),
2098     };
2099 
2100     Ok(match_ignore_ascii_case! {
2101         ident,
2102         "i" => AttributeFlags::AsciiCaseInsensitive,
2103         "s" => AttributeFlags::CaseSensitive,
2104         _ => return Err(location.new_basic_unexpected_token_error(token.clone())),
2105     })
2106 }
2107 
2108 /// Level 3: Parse **one** simple_selector.  (Though we might insert a second
2109 /// implied "<defaultns>|*" type selector.)
parse_negation<'i, 't, P, Impl>( parser: &P, input: &mut CssParser<'i, 't>, state: SelectorParsingState, ) -> Result<Component<Impl>, ParseError<'i, P::Error>> where P: Parser<'i, Impl = Impl>, Impl: SelectorImpl,2110 fn parse_negation<'i, 't, P, Impl>(
2111     parser: &P,
2112     input: &mut CssParser<'i, 't>,
2113     state: SelectorParsingState,
2114 ) -> Result<Component<Impl>, ParseError<'i, P::Error>>
2115 where
2116     P: Parser<'i, Impl = Impl>,
2117     Impl: SelectorImpl,
2118 {
2119     let list = SelectorList::parse_with_state(
2120         parser,
2121         input,
2122         state |
2123             SelectorParsingState::SKIP_DEFAULT_NAMESPACE |
2124             SelectorParsingState::DISALLOW_PSEUDOS,
2125         ParseErrorRecovery::DiscardList,
2126     )?;
2127 
2128     Ok(Component::Negation(list.0.into_vec().into_boxed_slice()))
2129 }
2130 
2131 /// simple_selector_sequence
2132 /// : [ type_selector | universal ] [ HASH | class | attrib | pseudo | negation ]*
2133 /// | [ HASH | class | attrib | pseudo | negation ]+
2134 ///
2135 /// `Err(())` means invalid selector.
2136 /// `Ok(true)` is an empty selector
parse_compound_selector<'i, 't, P, Impl>( parser: &P, state: &mut SelectorParsingState, input: &mut CssParser<'i, 't>, builder: &mut SelectorBuilder<Impl>, ) -> Result<bool, ParseError<'i, P::Error>> where P: Parser<'i, Impl = Impl>, Impl: SelectorImpl,2137 fn parse_compound_selector<'i, 't, P, Impl>(
2138     parser: &P,
2139     state: &mut SelectorParsingState,
2140     input: &mut CssParser<'i, 't>,
2141     builder: &mut SelectorBuilder<Impl>,
2142 ) -> Result<bool, ParseError<'i, P::Error>>
2143 where
2144     P: Parser<'i, Impl = Impl>,
2145     Impl: SelectorImpl,
2146 {
2147     input.skip_whitespace();
2148 
2149     let mut empty = true;
2150     if parse_type_selector(parser, input, *state, builder)? {
2151         empty = false;
2152     }
2153 
2154     loop {
2155         let result = match parse_one_simple_selector(parser, input, *state)? {
2156             None => break,
2157             Some(result) => result,
2158         };
2159 
2160         if empty {
2161             if let Some(url) = parser.default_namespace() {
2162                 // If there was no explicit type selector, but there is a
2163                 // default namespace, there is an implicit "<defaultns>|*" type
2164                 // selector. Except for :host() or :not() / :is() / :where(),
2165                 // where we ignore it.
2166                 //
2167                 // https://drafts.csswg.org/css-scoping/#host-element-in-tree:
2168                 //
2169                 //     When considered within its own shadow trees, the shadow
2170                 //     host is featureless. Only the :host, :host(), and
2171                 //     :host-context() pseudo-classes are allowed to match it.
2172                 //
2173                 // https://drafts.csswg.org/selectors-4/#featureless:
2174                 //
2175                 //     A featureless element does not match any selector at all,
2176                 //     except those it is explicitly defined to match. If a
2177                 //     given selector is allowed to match a featureless element,
2178                 //     it must do so while ignoring the default namespace.
2179                 //
2180                 // https://drafts.csswg.org/selectors-4/#matches
2181                 //
2182                 //     Default namespace declarations do not affect the compound
2183                 //     selector representing the subject of any selector within
2184                 //     a :is() pseudo-class, unless that compound selector
2185                 //     contains an explicit universal selector or type selector.
2186                 //
2187                 //     (Similar quotes for :where() / :not())
2188                 //
2189                 let ignore_default_ns = state
2190                     .intersects(SelectorParsingState::SKIP_DEFAULT_NAMESPACE) ||
2191                     matches!(
2192                         result,
2193                         SimpleSelectorParseResult::SimpleSelector(Component::Host(..))
2194                     );
2195                 if !ignore_default_ns {
2196                     builder.push_simple_selector(Component::DefaultNamespace(url));
2197                 }
2198             }
2199         }
2200 
2201         empty = false;
2202 
2203         match result {
2204             SimpleSelectorParseResult::SimpleSelector(s) => {
2205                 builder.push_simple_selector(s);
2206             },
2207             SimpleSelectorParseResult::PartPseudo(part_names) => {
2208                 state.insert(SelectorParsingState::AFTER_PART);
2209                 builder.push_combinator(Combinator::Part);
2210                 builder.push_simple_selector(Component::Part(part_names));
2211             },
2212             SimpleSelectorParseResult::SlottedPseudo(selector) => {
2213                 state.insert(SelectorParsingState::AFTER_SLOTTED);
2214                 builder.push_combinator(Combinator::SlotAssignment);
2215                 builder.push_simple_selector(Component::Slotted(selector));
2216             },
2217             SimpleSelectorParseResult::PseudoElement(p) => {
2218                 state.insert(SelectorParsingState::AFTER_PSEUDO_ELEMENT);
2219                 if !p.accepts_state_pseudo_classes() {
2220                     state.insert(SelectorParsingState::AFTER_NON_STATEFUL_PSEUDO_ELEMENT);
2221                 }
2222                 builder.push_combinator(Combinator::PseudoElement);
2223                 builder.push_simple_selector(Component::PseudoElement(p));
2224             },
2225         }
2226     }
2227     Ok(empty)
2228 }
2229 
parse_is_or_where<'i, 't, P, Impl>( parser: &P, input: &mut CssParser<'i, 't>, state: SelectorParsingState, component: impl FnOnce(Box<[Selector<Impl>]>) -> Component<Impl>, ) -> Result<Component<Impl>, ParseError<'i, P::Error>> where P: Parser<'i, Impl = Impl>, Impl: SelectorImpl,2230 fn parse_is_or_where<'i, 't, P, Impl>(
2231     parser: &P,
2232     input: &mut CssParser<'i, 't>,
2233     state: SelectorParsingState,
2234     component: impl FnOnce(Box<[Selector<Impl>]>) -> Component<Impl>,
2235 ) -> Result<Component<Impl>, ParseError<'i, P::Error>>
2236 where
2237     P: Parser<'i, Impl = Impl>,
2238     Impl: SelectorImpl,
2239 {
2240     debug_assert!(parser.parse_is_and_where());
2241     // https://drafts.csswg.org/selectors/#matches-pseudo:
2242     //
2243     //     Pseudo-elements cannot be represented by the matches-any
2244     //     pseudo-class; they are not valid within :is().
2245     //
2246     let inner = SelectorList::parse_with_state(
2247         parser,
2248         input,
2249         state |
2250             SelectorParsingState::SKIP_DEFAULT_NAMESPACE |
2251             SelectorParsingState::DISALLOW_PSEUDOS,
2252         ParseErrorRecovery::IgnoreInvalidSelector,
2253     )?;
2254     Ok(component(inner.0.into_vec().into_boxed_slice()))
2255 }
2256 
parse_functional_pseudo_class<'i, 't, P, Impl>( parser: &P, input: &mut CssParser<'i, 't>, name: CowRcStr<'i>, state: SelectorParsingState, ) -> Result<Component<Impl>, ParseError<'i, P::Error>> where P: Parser<'i, Impl = Impl>, Impl: SelectorImpl,2257 fn parse_functional_pseudo_class<'i, 't, P, Impl>(
2258     parser: &P,
2259     input: &mut CssParser<'i, 't>,
2260     name: CowRcStr<'i>,
2261     state: SelectorParsingState,
2262 ) -> Result<Component<Impl>, ParseError<'i, P::Error>>
2263 where
2264     P: Parser<'i, Impl = Impl>,
2265     Impl: SelectorImpl,
2266 {
2267     match_ignore_ascii_case! { &name,
2268         "nth-child" => return parse_nth_pseudo_class(parser, input, state, Component::NthChild),
2269         "nth-of-type" => return parse_nth_pseudo_class(parser, input, state, Component::NthOfType),
2270         "nth-last-child" => return parse_nth_pseudo_class(parser, input, state, Component::NthLastChild),
2271         "nth-last-of-type" => return parse_nth_pseudo_class(parser, input, state, Component::NthLastOfType),
2272         "is" if parser.parse_is_and_where() => return parse_is_or_where(parser, input, state, Component::Is),
2273         "where" if parser.parse_is_and_where() => return parse_is_or_where(parser, input, state, Component::Where),
2274         "host" => {
2275             if !state.allows_tree_structural_pseudo_classes() {
2276                 return Err(input.new_custom_error(SelectorParseErrorKind::InvalidState));
2277             }
2278             return Ok(Component::Host(Some(parse_inner_compound_selector(parser, input, state)?)));
2279         },
2280         "not" => {
2281             return parse_negation(parser, input, state)
2282         },
2283         _ => {}
2284     }
2285 
2286     if parser.parse_is_and_where() && parser.is_is_alias(&name) {
2287         return parse_is_or_where(parser, input, state, Component::Is);
2288     }
2289 
2290     if !state.allows_custom_functional_pseudo_classes() {
2291         return Err(input.new_custom_error(SelectorParseErrorKind::InvalidState));
2292     }
2293 
2294     P::parse_non_ts_functional_pseudo_class(parser, name, input).map(Component::NonTSPseudoClass)
2295 }
2296 
parse_nth_pseudo_class<'i, 't, P, Impl, F>( _: &P, input: &mut CssParser<'i, 't>, state: SelectorParsingState, selector: F, ) -> Result<Component<Impl>, ParseError<'i, P::Error>> where P: Parser<'i, Impl = Impl>, Impl: SelectorImpl, F: FnOnce(i32, i32) -> Component<Impl>,2297 fn parse_nth_pseudo_class<'i, 't, P, Impl, F>(
2298     _: &P,
2299     input: &mut CssParser<'i, 't>,
2300     state: SelectorParsingState,
2301     selector: F,
2302 ) -> Result<Component<Impl>, ParseError<'i, P::Error>>
2303 where
2304     P: Parser<'i, Impl = Impl>,
2305     Impl: SelectorImpl,
2306     F: FnOnce(i32, i32) -> Component<Impl>,
2307 {
2308     if !state.allows_tree_structural_pseudo_classes() {
2309         return Err(input.new_custom_error(SelectorParseErrorKind::InvalidState));
2310     }
2311     let (a, b) = parse_nth(input)?;
2312     Ok(selector(a, b))
2313 }
2314 
2315 /// Returns whether the name corresponds to a CSS2 pseudo-element that
2316 /// can be specified with the single colon syntax (in addition to the
2317 /// double-colon syntax, which can be used for all pseudo-elements).
is_css2_pseudo_element(name: &str) -> bool2318 fn is_css2_pseudo_element(name: &str) -> bool {
2319     // ** Do not add to this list! **
2320     match_ignore_ascii_case! { name,
2321         "before" | "after" | "first-line" | "first-letter" => true,
2322         _ => false,
2323     }
2324 }
2325 
2326 /// Parse a simple selector other than a type selector.
2327 ///
2328 /// * `Err(())`: Invalid selector, abort
2329 /// * `Ok(None)`: Not a simple selector, could be something else. `input` was not consumed.
2330 /// * `Ok(Some(_))`: Parsed a simple selector or pseudo-element
parse_one_simple_selector<'i, 't, P, Impl>( parser: &P, input: &mut CssParser<'i, 't>, state: SelectorParsingState, ) -> Result<Option<SimpleSelectorParseResult<Impl>>, ParseError<'i, P::Error>> where P: Parser<'i, Impl = Impl>, Impl: SelectorImpl,2331 fn parse_one_simple_selector<'i, 't, P, Impl>(
2332     parser: &P,
2333     input: &mut CssParser<'i, 't>,
2334     state: SelectorParsingState,
2335 ) -> Result<Option<SimpleSelectorParseResult<Impl>>, ParseError<'i, P::Error>>
2336 where
2337     P: Parser<'i, Impl = Impl>,
2338     Impl: SelectorImpl,
2339 {
2340     let start = input.state();
2341     let token = match input.next_including_whitespace().map(|t| t.clone()) {
2342         Ok(t) => t,
2343         Err(..) => {
2344             input.reset(&start);
2345             return Ok(None);
2346         },
2347     };
2348 
2349     Ok(Some(match token {
2350         Token::IDHash(id) => {
2351             if state.intersects(SelectorParsingState::AFTER_PSEUDO) {
2352                 return Err(input.new_custom_error(SelectorParseErrorKind::InvalidState));
2353             }
2354             let id = Component::ID(id.as_ref().into());
2355             SimpleSelectorParseResult::SimpleSelector(id)
2356         },
2357         Token::Delim('.') => {
2358             if state.intersects(SelectorParsingState::AFTER_PSEUDO) {
2359                 return Err(input.new_custom_error(SelectorParseErrorKind::InvalidState));
2360             }
2361             let location = input.current_source_location();
2362             let class = match *input.next_including_whitespace()? {
2363                 Token::Ident(ref class) => class,
2364                 ref t => {
2365                     let e = SelectorParseErrorKind::ClassNeedsIdent(t.clone());
2366                     return Err(location.new_custom_error(e));
2367                 },
2368             };
2369             let class = Component::Class(class.as_ref().into());
2370             SimpleSelectorParseResult::SimpleSelector(class)
2371         },
2372         Token::SquareBracketBlock => {
2373             if state.intersects(SelectorParsingState::AFTER_PSEUDO) {
2374                 return Err(input.new_custom_error(SelectorParseErrorKind::InvalidState));
2375             }
2376             let attr = input.parse_nested_block(|input| parse_attribute_selector(parser, input))?;
2377             SimpleSelectorParseResult::SimpleSelector(attr)
2378         },
2379         Token::Colon => {
2380             let location = input.current_source_location();
2381             let (is_single_colon, next_token) = match input.next_including_whitespace()?.clone() {
2382                 Token::Colon => (false, input.next_including_whitespace()?.clone()),
2383                 t => (true, t),
2384             };
2385             let (name, is_functional) = match next_token {
2386                 Token::Ident(name) => (name, false),
2387                 Token::Function(name) => (name, true),
2388                 t => {
2389                     let e = SelectorParseErrorKind::PseudoElementExpectedIdent(t);
2390                     return Err(input.new_custom_error(e));
2391                 },
2392             };
2393             let is_pseudo_element = !is_single_colon || is_css2_pseudo_element(&name);
2394             if is_pseudo_element {
2395                 if !state.allows_pseudos() {
2396                     return Err(input.new_custom_error(SelectorParseErrorKind::InvalidState));
2397                 }
2398                 let pseudo_element = if is_functional {
2399                     if P::parse_part(parser) && name.eq_ignore_ascii_case("part") {
2400                         if !state.allows_part() {
2401                             return Err(
2402                                 input.new_custom_error(SelectorParseErrorKind::InvalidState)
2403                             );
2404                         }
2405                         let names = input.parse_nested_block(|input| {
2406                             let mut result = Vec::with_capacity(1);
2407                             result.push(input.expect_ident()?.as_ref().into());
2408                             while !input.is_exhausted() {
2409                                 result.push(input.expect_ident()?.as_ref().into());
2410                             }
2411                             Ok(result.into_boxed_slice())
2412                         })?;
2413                         return Ok(Some(SimpleSelectorParseResult::PartPseudo(names)));
2414                     }
2415                     if P::parse_slotted(parser) && name.eq_ignore_ascii_case("slotted") {
2416                         if !state.allows_slotted() {
2417                             return Err(
2418                                 input.new_custom_error(SelectorParseErrorKind::InvalidState)
2419                             );
2420                         }
2421                         let selector = input.parse_nested_block(|input| {
2422                             parse_inner_compound_selector(parser, input, state)
2423                         })?;
2424                         return Ok(Some(SimpleSelectorParseResult::SlottedPseudo(selector)));
2425                     }
2426                     input.parse_nested_block(|input| {
2427                         P::parse_functional_pseudo_element(parser, name, input)
2428                     })?
2429                 } else {
2430                     P::parse_pseudo_element(parser, location, name)?
2431                 };
2432 
2433                 if state.intersects(SelectorParsingState::AFTER_SLOTTED) &&
2434                     !pseudo_element.valid_after_slotted()
2435                 {
2436                     return Err(input.new_custom_error(SelectorParseErrorKind::InvalidState));
2437                 }
2438                 SimpleSelectorParseResult::PseudoElement(pseudo_element)
2439             } else {
2440                 let pseudo_class = if is_functional {
2441                     input.parse_nested_block(|input| {
2442                         parse_functional_pseudo_class(parser, input, name, state)
2443                     })?
2444                 } else {
2445                     parse_simple_pseudo_class(parser, location, name, state)?
2446                 };
2447                 SimpleSelectorParseResult::SimpleSelector(pseudo_class)
2448             }
2449         },
2450         _ => {
2451             input.reset(&start);
2452             return Ok(None);
2453         },
2454     }))
2455 }
2456 
parse_simple_pseudo_class<'i, P, Impl>( parser: &P, location: SourceLocation, name: CowRcStr<'i>, state: SelectorParsingState, ) -> Result<Component<Impl>, ParseError<'i, P::Error>> where P: Parser<'i, Impl = Impl>, Impl: SelectorImpl,2457 fn parse_simple_pseudo_class<'i, P, Impl>(
2458     parser: &P,
2459     location: SourceLocation,
2460     name: CowRcStr<'i>,
2461     state: SelectorParsingState,
2462 ) -> Result<Component<Impl>, ParseError<'i, P::Error>>
2463 where
2464     P: Parser<'i, Impl = Impl>,
2465     Impl: SelectorImpl,
2466 {
2467     if !state.allows_non_functional_pseudo_classes() {
2468         return Err(location.new_custom_error(SelectorParseErrorKind::InvalidState));
2469     }
2470 
2471     if state.allows_tree_structural_pseudo_classes() {
2472         match_ignore_ascii_case! { &name,
2473             "first-child" => return Ok(Component::FirstChild),
2474             "last-child" => return Ok(Component::LastChild),
2475             "only-child" => return Ok(Component::OnlyChild),
2476             "root" => return Ok(Component::Root),
2477             "empty" => return Ok(Component::Empty),
2478             "scope" => return Ok(Component::Scope),
2479             "host" if P::parse_host(parser) => return Ok(Component::Host(None)),
2480             "first-of-type" => return Ok(Component::FirstOfType),
2481             "last-of-type" => return Ok(Component::LastOfType),
2482             "only-of-type" => return Ok(Component::OnlyOfType),
2483             _ => {},
2484         }
2485     }
2486 
2487     let pseudo_class = P::parse_non_ts_pseudo_class(parser, location, name)?;
2488     if state.intersects(SelectorParsingState::AFTER_PSEUDO_ELEMENT) &&
2489         !pseudo_class.is_user_action_state()
2490     {
2491         return Err(location.new_custom_error(SelectorParseErrorKind::InvalidState));
2492     }
2493     Ok(Component::NonTSPseudoClass(pseudo_class))
2494 }
2495 
2496 // NB: pub module in order to access the DummyParser
2497 #[cfg(test)]
2498 pub mod tests {
2499     use super::*;
2500     use crate::builder::SelectorFlags;
2501     use crate::parser;
2502     use cssparser::{serialize_identifier, Parser as CssParser, ParserInput, ToCss};
2503     use std::collections::HashMap;
2504     use std::fmt;
2505 
2506     #[derive(Clone, Debug, Eq, PartialEq)]
2507     pub enum PseudoClass {
2508         Hover,
2509         Active,
2510         Lang(String),
2511     }
2512 
2513     #[derive(Clone, Debug, Eq, PartialEq)]
2514     pub enum PseudoElement {
2515         Before,
2516         After,
2517     }
2518 
2519     impl parser::PseudoElement for PseudoElement {
2520         type Impl = DummySelectorImpl;
2521 
accepts_state_pseudo_classes(&self) -> bool2522         fn accepts_state_pseudo_classes(&self) -> bool {
2523             true
2524         }
2525 
valid_after_slotted(&self) -> bool2526         fn valid_after_slotted(&self) -> bool {
2527             true
2528         }
2529     }
2530 
2531     impl parser::NonTSPseudoClass for PseudoClass {
2532         type Impl = DummySelectorImpl;
2533 
2534         #[inline]
is_active_or_hover(&self) -> bool2535         fn is_active_or_hover(&self) -> bool {
2536             matches!(*self, PseudoClass::Active | PseudoClass::Hover)
2537         }
2538 
2539         #[inline]
is_user_action_state(&self) -> bool2540         fn is_user_action_state(&self) -> bool {
2541             self.is_active_or_hover()
2542         }
2543     }
2544 
2545     impl ToCss for PseudoClass {
to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write,2546         fn to_css<W>(&self, dest: &mut W) -> fmt::Result
2547         where
2548             W: fmt::Write,
2549         {
2550             match *self {
2551                 PseudoClass::Hover => dest.write_str(":hover"),
2552                 PseudoClass::Active => dest.write_str(":active"),
2553                 PseudoClass::Lang(ref lang) => {
2554                     dest.write_str(":lang(")?;
2555                     serialize_identifier(lang, dest)?;
2556                     dest.write_char(')')
2557                 },
2558             }
2559         }
2560     }
2561 
2562     impl ToCss for PseudoElement {
to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write,2563         fn to_css<W>(&self, dest: &mut W) -> fmt::Result
2564         where
2565             W: fmt::Write,
2566         {
2567             match *self {
2568                 PseudoElement::Before => dest.write_str("::before"),
2569                 PseudoElement::After => dest.write_str("::after"),
2570             }
2571         }
2572     }
2573 
2574     #[derive(Clone, Debug, PartialEq)]
2575     pub struct DummySelectorImpl;
2576 
2577     #[derive(Default)]
2578     pub struct DummyParser {
2579         default_ns: Option<DummyAtom>,
2580         ns_prefixes: HashMap<DummyAtom, DummyAtom>,
2581     }
2582 
2583     impl DummyParser {
default_with_namespace(default_ns: DummyAtom) -> DummyParser2584         fn default_with_namespace(default_ns: DummyAtom) -> DummyParser {
2585             DummyParser {
2586                 default_ns: Some(default_ns),
2587                 ns_prefixes: Default::default(),
2588             }
2589         }
2590     }
2591 
2592     impl SelectorImpl for DummySelectorImpl {
2593         type ExtraMatchingData = ();
2594         type AttrValue = DummyAttrValue;
2595         type Identifier = DummyAtom;
2596         type LocalName = DummyAtom;
2597         type NamespaceUrl = DummyAtom;
2598         type NamespacePrefix = DummyAtom;
2599         type BorrowedLocalName = DummyAtom;
2600         type BorrowedNamespaceUrl = DummyAtom;
2601         type NonTSPseudoClass = PseudoClass;
2602         type PseudoElement = PseudoElement;
2603     }
2604 
2605     #[derive(Clone, Debug, Default, Eq, Hash, PartialEq)]
2606     pub struct DummyAttrValue(String);
2607 
2608     impl ToCss for DummyAttrValue {
to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write,2609         fn to_css<W>(&self, dest: &mut W) -> fmt::Result
2610         where
2611             W: fmt::Write,
2612         {
2613             use std::fmt::Write;
2614 
2615             write!(cssparser::CssStringWriter::new(dest), "{}", &self.0)
2616         }
2617     }
2618 
2619     impl<'a> From<&'a str> for DummyAttrValue {
from(string: &'a str) -> Self2620         fn from(string: &'a str) -> Self {
2621             Self(string.into())
2622         }
2623     }
2624 
2625     #[derive(Clone, Debug, Default, Eq, Hash, PartialEq)]
2626     pub struct DummyAtom(String);
2627 
2628     impl ToCss for DummyAtom {
to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write,2629         fn to_css<W>(&self, dest: &mut W) -> fmt::Result
2630         where
2631             W: fmt::Write,
2632         {
2633             serialize_identifier(&self.0, dest)
2634         }
2635     }
2636 
2637     impl From<String> for DummyAtom {
from(string: String) -> Self2638         fn from(string: String) -> Self {
2639             DummyAtom(string)
2640         }
2641     }
2642 
2643     impl<'a> From<&'a str> for DummyAtom {
from(string: &'a str) -> Self2644         fn from(string: &'a str) -> Self {
2645             DummyAtom(string.into())
2646         }
2647     }
2648 
2649     impl<'i> Parser<'i> for DummyParser {
2650         type Impl = DummySelectorImpl;
2651         type Error = SelectorParseErrorKind<'i>;
2652 
parse_slotted(&self) -> bool2653         fn parse_slotted(&self) -> bool {
2654             true
2655         }
2656 
parse_is_and_where(&self) -> bool2657         fn parse_is_and_where(&self) -> bool {
2658             true
2659         }
2660 
parse_part(&self) -> bool2661         fn parse_part(&self) -> bool {
2662             true
2663         }
2664 
parse_non_ts_pseudo_class( &self, location: SourceLocation, name: CowRcStr<'i>, ) -> Result<PseudoClass, SelectorParseError<'i>>2665         fn parse_non_ts_pseudo_class(
2666             &self,
2667             location: SourceLocation,
2668             name: CowRcStr<'i>,
2669         ) -> Result<PseudoClass, SelectorParseError<'i>> {
2670             match_ignore_ascii_case! { &name,
2671                 "hover" => return Ok(PseudoClass::Hover),
2672                 "active" => return Ok(PseudoClass::Active),
2673                 _ => {}
2674             }
2675             Err(
2676                 location.new_custom_error(SelectorParseErrorKind::UnsupportedPseudoClassOrElement(
2677                     name,
2678                 )),
2679             )
2680         }
2681 
parse_non_ts_functional_pseudo_class<'t>( &self, name: CowRcStr<'i>, parser: &mut CssParser<'i, 't>, ) -> Result<PseudoClass, SelectorParseError<'i>>2682         fn parse_non_ts_functional_pseudo_class<'t>(
2683             &self,
2684             name: CowRcStr<'i>,
2685             parser: &mut CssParser<'i, 't>,
2686         ) -> Result<PseudoClass, SelectorParseError<'i>> {
2687             match_ignore_ascii_case! { &name,
2688                 "lang" => {
2689                     let lang = parser.expect_ident_or_string()?.as_ref().to_owned();
2690                     return Ok(PseudoClass::Lang(lang));
2691                 },
2692                 _ => {}
2693             }
2694             Err(
2695                 parser.new_custom_error(SelectorParseErrorKind::UnsupportedPseudoClassOrElement(
2696                     name,
2697                 )),
2698             )
2699         }
2700 
parse_pseudo_element( &self, location: SourceLocation, name: CowRcStr<'i>, ) -> Result<PseudoElement, SelectorParseError<'i>>2701         fn parse_pseudo_element(
2702             &self,
2703             location: SourceLocation,
2704             name: CowRcStr<'i>,
2705         ) -> Result<PseudoElement, SelectorParseError<'i>> {
2706             match_ignore_ascii_case! { &name,
2707                 "before" => return Ok(PseudoElement::Before),
2708                 "after" => return Ok(PseudoElement::After),
2709                 _ => {}
2710             }
2711             Err(
2712                 location.new_custom_error(SelectorParseErrorKind::UnsupportedPseudoClassOrElement(
2713                     name,
2714                 )),
2715             )
2716         }
2717 
default_namespace(&self) -> Option<DummyAtom>2718         fn default_namespace(&self) -> Option<DummyAtom> {
2719             self.default_ns.clone()
2720         }
2721 
namespace_for_prefix(&self, prefix: &DummyAtom) -> Option<DummyAtom>2722         fn namespace_for_prefix(&self, prefix: &DummyAtom) -> Option<DummyAtom> {
2723             self.ns_prefixes.get(prefix).cloned()
2724         }
2725     }
2726 
parse<'i>( input: &'i str, ) -> Result<SelectorList<DummySelectorImpl>, SelectorParseError<'i>>2727     fn parse<'i>(
2728         input: &'i str,
2729     ) -> Result<SelectorList<DummySelectorImpl>, SelectorParseError<'i>> {
2730         parse_ns(input, &DummyParser::default())
2731     }
2732 
parse_expected<'i, 'a>( input: &'i str, expected: Option<&'a str>, ) -> Result<SelectorList<DummySelectorImpl>, SelectorParseError<'i>>2733     fn parse_expected<'i, 'a>(
2734         input: &'i str,
2735         expected: Option<&'a str>,
2736     ) -> Result<SelectorList<DummySelectorImpl>, SelectorParseError<'i>> {
2737         parse_ns_expected(input, &DummyParser::default(), expected)
2738     }
2739 
parse_ns<'i>( input: &'i str, parser: &DummyParser, ) -> Result<SelectorList<DummySelectorImpl>, SelectorParseError<'i>>2740     fn parse_ns<'i>(
2741         input: &'i str,
2742         parser: &DummyParser,
2743     ) -> Result<SelectorList<DummySelectorImpl>, SelectorParseError<'i>> {
2744         parse_ns_expected(input, parser, None)
2745     }
2746 
parse_ns_expected<'i, 'a>( input: &'i str, parser: &DummyParser, expected: Option<&'a str>, ) -> Result<SelectorList<DummySelectorImpl>, SelectorParseError<'i>>2747     fn parse_ns_expected<'i, 'a>(
2748         input: &'i str,
2749         parser: &DummyParser,
2750         expected: Option<&'a str>,
2751     ) -> Result<SelectorList<DummySelectorImpl>, SelectorParseError<'i>> {
2752         let mut parser_input = ParserInput::new(input);
2753         let result = SelectorList::parse(parser, &mut CssParser::new(&mut parser_input));
2754         if let Ok(ref selectors) = result {
2755             assert_eq!(selectors.0.len(), 1);
2756             // We can't assume that the serialized parsed selector will equal
2757             // the input; for example, if there is no default namespace, '*|foo'
2758             // should serialize to 'foo'.
2759             assert_eq!(
2760                 selectors.0[0].to_css_string(),
2761                 match expected {
2762                     Some(x) => x,
2763                     None => input,
2764                 }
2765             );
2766         }
2767         result
2768     }
2769 
specificity(a: u32, b: u32, c: u32) -> u322770     fn specificity(a: u32, b: u32, c: u32) -> u32 {
2771         a << 20 | b << 10 | c
2772     }
2773 
2774     #[test]
test_empty()2775     fn test_empty() {
2776         let mut input = ParserInput::new(":empty");
2777         let list = SelectorList::parse(&DummyParser::default(), &mut CssParser::new(&mut input));
2778         assert!(list.is_ok());
2779     }
2780 
2781     const MATHML: &str = "http://www.w3.org/1998/Math/MathML";
2782     const SVG: &str = "http://www.w3.org/2000/svg";
2783 
2784     #[test]
test_parsing()2785     fn test_parsing() {
2786         assert!(parse("").is_err());
2787         assert!(parse(":lang(4)").is_err());
2788         assert!(parse(":lang(en US)").is_err());
2789         assert_eq!(
2790             parse("EeÉ"),
2791             Ok(SelectorList::from_vec(vec![Selector::from_vec(
2792                 vec![Component::LocalName(LocalName {
2793                     name: DummyAtom::from("EeÉ"),
2794                     lower_name: DummyAtom::from("eeÉ"),
2795                 })],
2796                 specificity(0, 0, 1),
2797                 Default::default(),
2798             )]))
2799         );
2800         assert_eq!(
2801             parse("|e"),
2802             Ok(SelectorList::from_vec(vec![Selector::from_vec(
2803                 vec![
2804                     Component::ExplicitNoNamespace,
2805                     Component::LocalName(LocalName {
2806                         name: DummyAtom::from("e"),
2807                         lower_name: DummyAtom::from("e"),
2808                     }),
2809                 ],
2810                 specificity(0, 0, 1),
2811                 Default::default(),
2812             )]))
2813         );
2814         // When the default namespace is not set, *| should be elided.
2815         // https://github.com/servo/servo/pull/17537
2816         assert_eq!(
2817             parse_expected("*|e", Some("e")),
2818             Ok(SelectorList::from_vec(vec![Selector::from_vec(
2819                 vec![Component::LocalName(LocalName {
2820                     name: DummyAtom::from("e"),
2821                     lower_name: DummyAtom::from("e"),
2822                 })],
2823                 specificity(0, 0, 1),
2824                 Default::default(),
2825             )]))
2826         );
2827         // When the default namespace is set, *| should _not_ be elided (as foo
2828         // is no longer equivalent to *|foo--the former is only for foo in the
2829         // default namespace).
2830         // https://github.com/servo/servo/issues/16020
2831         assert_eq!(
2832             parse_ns(
2833                 "*|e",
2834                 &DummyParser::default_with_namespace(DummyAtom::from("https://mozilla.org"))
2835             ),
2836             Ok(SelectorList::from_vec(vec![Selector::from_vec(
2837                 vec![
2838                     Component::ExplicitAnyNamespace,
2839                     Component::LocalName(LocalName {
2840                         name: DummyAtom::from("e"),
2841                         lower_name: DummyAtom::from("e"),
2842                     }),
2843                 ],
2844                 specificity(0, 0, 1),
2845                 Default::default(),
2846             )]))
2847         );
2848         assert_eq!(
2849             parse("*"),
2850             Ok(SelectorList::from_vec(vec![Selector::from_vec(
2851                 vec![Component::ExplicitUniversalType],
2852                 specificity(0, 0, 0),
2853                 Default::default(),
2854             )]))
2855         );
2856         assert_eq!(
2857             parse("|*"),
2858             Ok(SelectorList::from_vec(vec![Selector::from_vec(
2859                 vec![
2860                     Component::ExplicitNoNamespace,
2861                     Component::ExplicitUniversalType,
2862                 ],
2863                 specificity(0, 0, 0),
2864                 Default::default(),
2865             )]))
2866         );
2867         assert_eq!(
2868             parse_expected("*|*", Some("*")),
2869             Ok(SelectorList::from_vec(vec![Selector::from_vec(
2870                 vec![Component::ExplicitUniversalType],
2871                 specificity(0, 0, 0),
2872                 Default::default(),
2873             )]))
2874         );
2875         assert_eq!(
2876             parse_ns(
2877                 "*|*",
2878                 &DummyParser::default_with_namespace(DummyAtom::from("https://mozilla.org"))
2879             ),
2880             Ok(SelectorList::from_vec(vec![Selector::from_vec(
2881                 vec![
2882                     Component::ExplicitAnyNamespace,
2883                     Component::ExplicitUniversalType,
2884                 ],
2885                 specificity(0, 0, 0),
2886                 Default::default(),
2887             )]))
2888         );
2889         assert_eq!(
2890             parse(".foo:lang(en-US)"),
2891             Ok(SelectorList::from_vec(vec![Selector::from_vec(
2892                 vec![
2893                     Component::Class(DummyAtom::from("foo")),
2894                     Component::NonTSPseudoClass(PseudoClass::Lang("en-US".to_owned())),
2895                 ],
2896                 specificity(0, 2, 0),
2897                 Default::default(),
2898             )]))
2899         );
2900         assert_eq!(
2901             parse("#bar"),
2902             Ok(SelectorList::from_vec(vec![Selector::from_vec(
2903                 vec![Component::ID(DummyAtom::from("bar"))],
2904                 specificity(1, 0, 0),
2905                 Default::default(),
2906             )]))
2907         );
2908         assert_eq!(
2909             parse("e.foo#bar"),
2910             Ok(SelectorList::from_vec(vec![Selector::from_vec(
2911                 vec![
2912                     Component::LocalName(LocalName {
2913                         name: DummyAtom::from("e"),
2914                         lower_name: DummyAtom::from("e"),
2915                     }),
2916                     Component::Class(DummyAtom::from("foo")),
2917                     Component::ID(DummyAtom::from("bar")),
2918                 ],
2919                 specificity(1, 1, 1),
2920                 Default::default(),
2921             )]))
2922         );
2923         assert_eq!(
2924             parse("e.foo #bar"),
2925             Ok(SelectorList::from_vec(vec![Selector::from_vec(
2926                 vec![
2927                     Component::LocalName(LocalName {
2928                         name: DummyAtom::from("e"),
2929                         lower_name: DummyAtom::from("e"),
2930                     }),
2931                     Component::Class(DummyAtom::from("foo")),
2932                     Component::Combinator(Combinator::Descendant),
2933                     Component::ID(DummyAtom::from("bar")),
2934                 ],
2935                 specificity(1, 1, 1),
2936                 Default::default(),
2937             )]))
2938         );
2939         // Default namespace does not apply to attribute selectors
2940         // https://github.com/mozilla/servo/pull/1652
2941         let mut parser = DummyParser::default();
2942         assert_eq!(
2943             parse_ns("[Foo]", &parser),
2944             Ok(SelectorList::from_vec(vec![Selector::from_vec(
2945                 vec![Component::AttributeInNoNamespaceExists {
2946                     local_name: DummyAtom::from("Foo"),
2947                     local_name_lower: DummyAtom::from("foo"),
2948                 }],
2949                 specificity(0, 1, 0),
2950                 Default::default(),
2951             )]))
2952         );
2953         assert!(parse_ns("svg|circle", &parser).is_err());
2954         parser
2955             .ns_prefixes
2956             .insert(DummyAtom("svg".into()), DummyAtom(SVG.into()));
2957         assert_eq!(
2958             parse_ns("svg|circle", &parser),
2959             Ok(SelectorList::from_vec(vec![Selector::from_vec(
2960                 vec![
2961                     Component::Namespace(DummyAtom("svg".into()), SVG.into()),
2962                     Component::LocalName(LocalName {
2963                         name: DummyAtom::from("circle"),
2964                         lower_name: DummyAtom::from("circle"),
2965                     }),
2966                 ],
2967                 specificity(0, 0, 1),
2968                 Default::default(),
2969             )]))
2970         );
2971         assert_eq!(
2972             parse_ns("svg|*", &parser),
2973             Ok(SelectorList::from_vec(vec![Selector::from_vec(
2974                 vec![
2975                     Component::Namespace(DummyAtom("svg".into()), SVG.into()),
2976                     Component::ExplicitUniversalType,
2977                 ],
2978                 specificity(0, 0, 0),
2979                 Default::default(),
2980             )]))
2981         );
2982         // Default namespace does not apply to attribute selectors
2983         // https://github.com/mozilla/servo/pull/1652
2984         // but it does apply to implicit type selectors
2985         // https://github.com/servo/rust-selectors/pull/82
2986         parser.default_ns = Some(MATHML.into());
2987         assert_eq!(
2988             parse_ns("[Foo]", &parser),
2989             Ok(SelectorList::from_vec(vec![Selector::from_vec(
2990                 vec![
2991                     Component::DefaultNamespace(MATHML.into()),
2992                     Component::AttributeInNoNamespaceExists {
2993                         local_name: DummyAtom::from("Foo"),
2994                         local_name_lower: DummyAtom::from("foo"),
2995                     },
2996                 ],
2997                 specificity(0, 1, 0),
2998                 Default::default(),
2999             )]))
3000         );
3001         // Default namespace does apply to type selectors
3002         assert_eq!(
3003             parse_ns("e", &parser),
3004             Ok(SelectorList::from_vec(vec![Selector::from_vec(
3005                 vec![
3006                     Component::DefaultNamespace(MATHML.into()),
3007                     Component::LocalName(LocalName {
3008                         name: DummyAtom::from("e"),
3009                         lower_name: DummyAtom::from("e"),
3010                     }),
3011                 ],
3012                 specificity(0, 0, 1),
3013                 Default::default(),
3014             )]))
3015         );
3016         assert_eq!(
3017             parse_ns("*", &parser),
3018             Ok(SelectorList::from_vec(vec![Selector::from_vec(
3019                 vec![
3020                     Component::DefaultNamespace(MATHML.into()),
3021                     Component::ExplicitUniversalType,
3022                 ],
3023                 specificity(0, 0, 0),
3024                 Default::default(),
3025             )]))
3026         );
3027         assert_eq!(
3028             parse_ns("*|*", &parser),
3029             Ok(SelectorList::from_vec(vec![Selector::from_vec(
3030                 vec![
3031                     Component::ExplicitAnyNamespace,
3032                     Component::ExplicitUniversalType,
3033                 ],
3034                 specificity(0, 0, 0),
3035                 Default::default(),
3036             )]))
3037         );
3038         // Default namespace applies to universal and type selectors inside :not and :matches,
3039         // but not otherwise.
3040         assert_eq!(
3041             parse_ns(":not(.cl)", &parser),
3042             Ok(SelectorList::from_vec(vec![Selector::from_vec(
3043                 vec![
3044                     Component::DefaultNamespace(MATHML.into()),
3045                     Component::Negation(
3046                         vec![Selector::from_vec(
3047                             vec![Component::Class(DummyAtom::from("cl"))],
3048                             specificity(0, 1, 0),
3049                             Default::default(),
3050                         )]
3051                         .into_boxed_slice()
3052                     ),
3053                 ],
3054                 specificity(0, 1, 0),
3055                 Default::default(),
3056             )]))
3057         );
3058         assert_eq!(
3059             parse_ns(":not(*)", &parser),
3060             Ok(SelectorList::from_vec(vec![Selector::from_vec(
3061                 vec![
3062                     Component::DefaultNamespace(MATHML.into()),
3063                     Component::Negation(
3064                         vec![Selector::from_vec(
3065                             vec![
3066                                 Component::DefaultNamespace(MATHML.into()),
3067                                 Component::ExplicitUniversalType,
3068                             ],
3069                             specificity(0, 0, 0),
3070                             Default::default(),
3071                         )]
3072                         .into_boxed_slice(),
3073                     ),
3074                 ],
3075                 specificity(0, 0, 0),
3076                 Default::default(),
3077             )]))
3078         );
3079         assert_eq!(
3080             parse_ns(":not(e)", &parser),
3081             Ok(SelectorList::from_vec(vec![Selector::from_vec(
3082                 vec![
3083                     Component::DefaultNamespace(MATHML.into()),
3084                     Component::Negation(
3085                         vec![Selector::from_vec(
3086                             vec![
3087                                 Component::DefaultNamespace(MATHML.into()),
3088                                 Component::LocalName(LocalName {
3089                                     name: DummyAtom::from("e"),
3090                                     lower_name: DummyAtom::from("e"),
3091                                 }),
3092                             ],
3093                             specificity(0, 0, 1),
3094                             Default::default(),
3095                         ),]
3096                         .into_boxed_slice()
3097                     ),
3098                 ],
3099                 specificity(0, 0, 1),
3100                 Default::default(),
3101             )]))
3102         );
3103         assert_eq!(
3104             parse("[attr|=\"foo\"]"),
3105             Ok(SelectorList::from_vec(vec![Selector::from_vec(
3106                 vec![Component::AttributeInNoNamespace {
3107                     local_name: DummyAtom::from("attr"),
3108                     operator: AttrSelectorOperator::DashMatch,
3109                     value: DummyAttrValue::from("foo"),
3110                     never_matches: false,
3111                     case_sensitivity: ParsedCaseSensitivity::CaseSensitive,
3112                 }],
3113                 specificity(0, 1, 0),
3114                 Default::default(),
3115             )]))
3116         );
3117         // https://github.com/mozilla/servo/issues/1723
3118         assert_eq!(
3119             parse("::before"),
3120             Ok(SelectorList::from_vec(vec![Selector::from_vec(
3121                 vec![
3122                     Component::Combinator(Combinator::PseudoElement),
3123                     Component::PseudoElement(PseudoElement::Before),
3124                 ],
3125                 specificity(0, 0, 1),
3126                 SelectorFlags::HAS_PSEUDO,
3127             )]))
3128         );
3129         assert_eq!(
3130             parse("::before:hover"),
3131             Ok(SelectorList::from_vec(vec![Selector::from_vec(
3132                 vec![
3133                     Component::Combinator(Combinator::PseudoElement),
3134                     Component::PseudoElement(PseudoElement::Before),
3135                     Component::NonTSPseudoClass(PseudoClass::Hover),
3136                 ],
3137                 specificity(0, 1, 1),
3138                 SelectorFlags::HAS_PSEUDO,
3139             )]))
3140         );
3141         assert_eq!(
3142             parse("::before:hover:hover"),
3143             Ok(SelectorList::from_vec(vec![Selector::from_vec(
3144                 vec![
3145                     Component::Combinator(Combinator::PseudoElement),
3146                     Component::PseudoElement(PseudoElement::Before),
3147                     Component::NonTSPseudoClass(PseudoClass::Hover),
3148                     Component::NonTSPseudoClass(PseudoClass::Hover),
3149                 ],
3150                 specificity(0, 2, 1),
3151                 SelectorFlags::HAS_PSEUDO,
3152             )]))
3153         );
3154         assert!(parse("::before:hover:lang(foo)").is_err());
3155         assert!(parse("::before:hover .foo").is_err());
3156         assert!(parse("::before .foo").is_err());
3157         assert!(parse("::before ~ bar").is_err());
3158         assert!(parse("::before:active").is_ok());
3159 
3160         // https://github.com/servo/servo/issues/15335
3161         assert!(parse(":: before").is_err());
3162         assert_eq!(
3163             parse("div ::after"),
3164             Ok(SelectorList::from_vec(vec![Selector::from_vec(
3165                 vec![
3166                     Component::LocalName(LocalName {
3167                         name: DummyAtom::from("div"),
3168                         lower_name: DummyAtom::from("div"),
3169                     }),
3170                     Component::Combinator(Combinator::Descendant),
3171                     Component::Combinator(Combinator::PseudoElement),
3172                     Component::PseudoElement(PseudoElement::After),
3173                 ],
3174                 specificity(0, 0, 2),
3175                 SelectorFlags::HAS_PSEUDO,
3176             )]))
3177         );
3178         assert_eq!(
3179             parse("#d1 > .ok"),
3180             Ok(SelectorList::from_vec(vec![Selector::from_vec(
3181                 vec![
3182                     Component::ID(DummyAtom::from("d1")),
3183                     Component::Combinator(Combinator::Child),
3184                     Component::Class(DummyAtom::from("ok")),
3185                 ],
3186                 (1 << 20) + (1 << 10) + (0 << 0),
3187                 Default::default(),
3188             )]))
3189         );
3190         parser.default_ns = None;
3191         assert!(parse(":not(#provel.old)").is_ok());
3192         assert!(parse(":not(#provel > old)").is_ok());
3193         assert!(parse("table[rules]:not([rules=\"none\"]):not([rules=\"\"])").is_ok());
3194         // https://github.com/servo/servo/issues/16017
3195         assert_eq!(
3196             parse_ns(":not(*)", &parser),
3197             Ok(SelectorList::from_vec(vec![Selector::from_vec(
3198                 vec![Component::Negation(
3199                     vec![Selector::from_vec(
3200                         vec![Component::ExplicitUniversalType],
3201                         specificity(0, 0, 0),
3202                         Default::default(),
3203                     )]
3204                     .into_boxed_slice()
3205                 )],
3206                 specificity(0, 0, 0),
3207                 Default::default(),
3208             )]))
3209         );
3210         assert_eq!(
3211             parse_ns(":not(|*)", &parser),
3212             Ok(SelectorList::from_vec(vec![Selector::from_vec(
3213                 vec![Component::Negation(
3214                     vec![Selector::from_vec(
3215                         vec![
3216                             Component::ExplicitNoNamespace,
3217                             Component::ExplicitUniversalType,
3218                         ],
3219                         specificity(0, 0, 0),
3220                         Default::default(),
3221                     )]
3222                     .into_boxed_slice(),
3223                 )],
3224                 specificity(0, 0, 0),
3225                 Default::default(),
3226             )]))
3227         );
3228         // *| should be elided if there is no default namespace.
3229         // https://github.com/servo/servo/pull/17537
3230         assert_eq!(
3231             parse_ns_expected(":not(*|*)", &parser, Some(":not(*)")),
3232             Ok(SelectorList::from_vec(vec![Selector::from_vec(
3233                 vec![Component::Negation(
3234                     vec![Selector::from_vec(
3235                         vec![Component::ExplicitUniversalType],
3236                         specificity(0, 0, 0),
3237                         Default::default()
3238                     )]
3239                     .into_boxed_slice()
3240                 )],
3241                 specificity(0, 0, 0),
3242                 Default::default(),
3243             )]))
3244         );
3245 
3246         assert!(parse("::slotted()").is_err());
3247         assert!(parse("::slotted(div)").is_ok());
3248         assert!(parse("::slotted(div).foo").is_err());
3249         assert!(parse("::slotted(div + bar)").is_err());
3250         assert!(parse("::slotted(div) + foo").is_err());
3251 
3252         assert!(parse("::part()").is_err());
3253         assert!(parse("::part(42)").is_err());
3254         assert!(parse("::part(foo bar)").is_ok());
3255         assert!(parse("::part(foo):hover").is_ok());
3256         assert!(parse("::part(foo) + bar").is_err());
3257 
3258         assert!(parse("div ::slotted(div)").is_ok());
3259         assert!(parse("div + slot::slotted(div)").is_ok());
3260         assert!(parse("div + slot::slotted(div.foo)").is_ok());
3261         assert!(parse("slot::slotted(div,foo)::first-line").is_err());
3262         assert!(parse("::slotted(div)::before").is_ok());
3263         assert!(parse("slot::slotted(div,foo)").is_err());
3264 
3265         assert!(parse("foo:where()").is_ok());
3266         assert!(parse("foo:where(div, foo, .bar baz)").is_ok());
3267         assert!(parse_expected("foo:where(::before)", Some("foo:where()")).is_ok());
3268     }
3269 
3270     #[test]
test_pseudo_iter()3271     fn test_pseudo_iter() {
3272         let selector = &parse("q::before").unwrap().0[0];
3273         assert!(!selector.is_universal());
3274         let mut iter = selector.iter();
3275         assert_eq!(
3276             iter.next(),
3277             Some(&Component::PseudoElement(PseudoElement::Before))
3278         );
3279         assert_eq!(iter.next(), None);
3280         let combinator = iter.next_sequence();
3281         assert_eq!(combinator, Some(Combinator::PseudoElement));
3282         assert!(matches!(iter.next(), Some(&Component::LocalName(..))));
3283         assert_eq!(iter.next(), None);
3284         assert_eq!(iter.next_sequence(), None);
3285     }
3286 
3287     #[test]
test_universal()3288     fn test_universal() {
3289         let selector = &parse_ns(
3290             "*|*::before",
3291             &DummyParser::default_with_namespace(DummyAtom::from("https://mozilla.org")),
3292         )
3293         .unwrap()
3294         .0[0];
3295         assert!(selector.is_universal());
3296     }
3297 
3298     #[test]
test_empty_pseudo_iter()3299     fn test_empty_pseudo_iter() {
3300         let selector = &parse("::before").unwrap().0[0];
3301         assert!(selector.is_universal());
3302         let mut iter = selector.iter();
3303         assert_eq!(
3304             iter.next(),
3305             Some(&Component::PseudoElement(PseudoElement::Before))
3306         );
3307         assert_eq!(iter.next(), None);
3308         assert_eq!(iter.next_sequence(), Some(Combinator::PseudoElement));
3309         assert_eq!(iter.next(), None);
3310         assert_eq!(iter.next_sequence(), None);
3311     }
3312 
3313     struct TestVisitor {
3314         seen: Vec<String>,
3315     }
3316 
3317     impl SelectorVisitor for TestVisitor {
3318         type Impl = DummySelectorImpl;
3319 
visit_simple_selector(&mut self, s: &Component<DummySelectorImpl>) -> bool3320         fn visit_simple_selector(&mut self, s: &Component<DummySelectorImpl>) -> bool {
3321             let mut dest = String::new();
3322             s.to_css(&mut dest).unwrap();
3323             self.seen.push(dest);
3324             true
3325         }
3326     }
3327 
3328     #[test]
visitor()3329     fn visitor() {
3330         let mut test_visitor = TestVisitor { seen: vec![] };
3331         parse(":not(:hover) ~ label").unwrap().0[0].visit(&mut test_visitor);
3332         assert!(test_visitor.seen.contains(&":hover".into()));
3333 
3334         let mut test_visitor = TestVisitor { seen: vec![] };
3335         parse("::before:hover").unwrap().0[0].visit(&mut test_visitor);
3336         assert!(test_visitor.seen.contains(&":hover".into()));
3337     }
3338 }
3339