swc_css_parser/parser/selectors/
mod.rs

1use swc_atoms::Atom;
2use swc_common::{BytePos, Span, Spanned};
3use swc_css_ast::*;
4
5use super::{input::ParserInput, PResult, Parser};
6use crate::{
7    error::{Error, ErrorKind},
8    parser::Ctx,
9    Parse,
10};
11
12impl<I> Parse<SelectorList> for Parser<I>
13where
14    I: ParserInput,
15{
16    fn parse(&mut self) -> PResult<SelectorList> {
17        let child: ComplexSelector = self.parse()?;
18        let mut children = vec![child];
19
20        loop {
21            self.input.skip_ws();
22
23            if !eat!(self, ",") {
24                break;
25            }
26
27            self.input.skip_ws();
28
29            let child = self.parse()?;
30
31            children.push(child);
32        }
33
34        let start_pos = match children.first() {
35            Some(first) => first.span_lo(),
36            _ => {
37                unreachable!();
38            }
39        };
40        let last_pos = match children.last() {
41            Some(last) => last.span_hi(),
42            _ => {
43                unreachable!();
44            }
45        };
46
47        Ok(SelectorList {
48            span: Span::new(start_pos, last_pos),
49            children,
50        })
51    }
52}
53
54impl<I> Parse<ForgivingSelectorList> for Parser<I>
55where
56    I: ParserInput,
57{
58    fn parse(&mut self) -> PResult<ForgivingSelectorList> {
59        let parse_forgiving_complex_selector =
60            |parser: &mut Parser<I>| -> PResult<ForgivingComplexSelector> {
61                let state = parser.input.state();
62
63                parser.input.skip_ws();
64
65                match parser.parse() {
66                    Ok(child) => Ok(ForgivingComplexSelector::ComplexSelector(child)),
67                    Err(_) => {
68                        parser.input.reset(&state);
69
70                        let span = parser.input.cur_span();
71                        let mut children = Vec::new();
72
73                        while !is_one_of!(parser, EOF, ",", ")") {
74                            if let Some(token_and_span) = parser.input.bump() {
75                                children
76                                    .push(ComponentValue::PreservedToken(Box::new(token_and_span)));
77                            }
78                        }
79
80                        Ok(ForgivingComplexSelector::ListOfComponentValues(
81                            ListOfComponentValues {
82                                span: span!(parser, span.lo),
83                                children,
84                            },
85                        ))
86                    }
87                }
88            };
89
90        let child = parse_forgiving_complex_selector(self)?;
91        let mut children = vec![child];
92
93        loop {
94            self.input.skip_ws();
95
96            if !eat!(self, ",") {
97                break;
98            }
99
100            let child = parse_forgiving_complex_selector(self)?;
101
102            children.push(child);
103        }
104
105        let start_pos = match children.first() {
106            Some(first) => first.span_lo(),
107            _ => {
108                unreachable!();
109            }
110        };
111        let last_pos = match children.last() {
112            Some(last) => last.span_hi(),
113            _ => {
114                unreachable!();
115            }
116        };
117
118        Ok(ForgivingSelectorList {
119            span: Span::new(start_pos, last_pos),
120            children,
121        })
122    }
123}
124
125impl<I> Parse<CompoundSelectorList> for Parser<I>
126where
127    I: ParserInput,
128{
129    fn parse(&mut self) -> PResult<CompoundSelectorList> {
130        let child: CompoundSelector = self.parse()?;
131        let mut children = vec![child];
132
133        loop {
134            self.input.skip_ws();
135
136            if !eat!(self, ",") {
137                break;
138            }
139
140            self.input.skip_ws();
141
142            let child = self.parse()?;
143
144            children.push(child);
145        }
146
147        let start_pos = match children.first() {
148            Some(first) => first.span_lo(),
149            _ => {
150                unreachable!();
151            }
152        };
153        let last_pos = match children.last() {
154            Some(last) => last.span_hi(),
155            _ => {
156                unreachable!();
157            }
158        };
159
160        Ok(CompoundSelectorList {
161            span: Span::new(start_pos, last_pos),
162            children,
163        })
164    }
165}
166
167impl<I> Parse<RelativeSelectorList> for Parser<I>
168where
169    I: ParserInput,
170{
171    fn parse(&mut self) -> PResult<RelativeSelectorList> {
172        let child: RelativeSelector = self.parse()?;
173        let mut children = vec![child];
174
175        loop {
176            self.input.skip_ws();
177
178            if !eat!(self, ",") {
179                break;
180            }
181
182            self.input.skip_ws();
183
184            let child = self.parse()?;
185
186            children.push(child);
187        }
188
189        let start_pos = match children.first() {
190            Some(first) => first.span_lo(),
191            _ => {
192                unreachable!();
193            }
194        };
195        let last_pos = match children.last() {
196            Some(last) => last.span_hi(),
197            _ => {
198                unreachable!();
199            }
200        };
201
202        Ok(RelativeSelectorList {
203            span: Span::new(start_pos, last_pos),
204            children,
205        })
206    }
207}
208
209impl<I> Parse<ForgivingRelativeSelectorList> for Parser<I>
210where
211    I: ParserInput,
212{
213    fn parse(&mut self) -> PResult<ForgivingRelativeSelectorList> {
214        let parse_forgiving_relative_selector =
215            |parser: &mut Parser<I>| -> PResult<ForgivingRelativeSelector> {
216                let state = parser.input.state();
217
218                parser.input.skip_ws();
219
220                match parser.parse() {
221                    Ok(child) => Ok(ForgivingRelativeSelector::RelativeSelector(child)),
222                    Err(_) => {
223                        parser.input.reset(&state);
224
225                        let span = parser.input.cur_span();
226                        let mut children = Vec::new();
227
228                        while !is_one_of!(parser, EOF, ",", ")") {
229                            if let Some(token_and_span) = parser.input.bump() {
230                                children
231                                    .push(ComponentValue::PreservedToken(Box::new(token_and_span)));
232                            }
233                        }
234
235                        Ok(ForgivingRelativeSelector::ListOfComponentValues(
236                            ListOfComponentValues {
237                                span: span!(parser, span.lo),
238                                children,
239                            },
240                        ))
241                    }
242                }
243            };
244
245        let child = parse_forgiving_relative_selector(self)?;
246        let mut children = vec![child];
247
248        loop {
249            self.input.skip_ws();
250
251            if !eat!(self, ",") {
252                break;
253            }
254
255            let child = parse_forgiving_relative_selector(self)?;
256
257            children.push(child);
258        }
259
260        let start_pos = match children.first() {
261            Some(first) => first.span_lo(),
262            _ => {
263                unreachable!();
264            }
265        };
266        let last_pos = match children.last() {
267            Some(last) => last.span_hi(),
268            _ => {
269                unreachable!();
270            }
271        };
272
273        Ok(ForgivingRelativeSelectorList {
274            span: Span::new(start_pos, last_pos),
275            children,
276        })
277    }
278}
279
280impl<I> Parse<ComplexSelector> for Parser<I>
281where
282    I: ParserInput,
283{
284    fn parse(&mut self) -> PResult<ComplexSelector> {
285        let child = ComplexSelectorChildren::CompoundSelector(self.parse()?);
286        let mut children = vec![child];
287
288        loop {
289            let span = self.input.cur_span();
290
291            self.input.skip_ws();
292
293            // TODO should be refactor after grammar parsing
294            if is_one_of!(self, EOF, ",", ")") {
295                break;
296            }
297
298            let mut combinator: Combinator = self.parse()?;
299
300            if combinator.value == CombinatorValue::Descendant {
301                combinator.span = span;
302            } else {
303                self.input.skip_ws();
304            }
305
306            children.push(ComplexSelectorChildren::Combinator(combinator));
307
308            let child = self.parse()?;
309
310            children.push(ComplexSelectorChildren::CompoundSelector(child));
311        }
312
313        let start_pos = match children.first() {
314            Some(ComplexSelectorChildren::CompoundSelector(child)) => child.span.lo,
315            _ => {
316                unreachable!();
317            }
318        };
319        let last_pos = match children.last() {
320            Some(ComplexSelectorChildren::CompoundSelector(child)) => child.span.hi,
321            _ => {
322                unreachable!();
323            }
324        };
325
326        Ok(ComplexSelector {
327            span: Span::new(start_pos, last_pos),
328            children,
329        })
330    }
331}
332
333impl<I> Parse<Combinator> for Parser<I>
334where
335    I: ParserInput,
336{
337    fn parse(&mut self) -> PResult<Combinator> {
338        let span = self.input.cur_span();
339
340        if eat!(self, ">") {
341            return Ok(Combinator {
342                span,
343                value: CombinatorValue::Child,
344            });
345        } else if eat!(self, "+") {
346            return Ok(Combinator {
347                span,
348                value: CombinatorValue::NextSibling,
349            });
350        } else if eat!(self, "~") {
351            return Ok(Combinator {
352                span,
353                value: CombinatorValue::LaterSibling,
354            });
355        } else if eat!(self, "|") {
356            expect!(self, "|");
357
358            return Ok(Combinator {
359                span: span!(self, span.lo),
360                value: CombinatorValue::Column,
361            });
362        }
363
364        Ok(Combinator {
365            span,
366            value: CombinatorValue::Descendant,
367        })
368    }
369}
370
371impl<I> Parse<RelativeSelector> for Parser<I>
372where
373    I: ParserInput,
374{
375    fn parse(&mut self) -> PResult<RelativeSelector> {
376        let mut combinator = None;
377
378        if is_one_of!(self, ">", "+", "~", "|") {
379            combinator = Some(self.parse()?);
380
381            self.input.skip_ws();
382        }
383
384        let selector: ComplexSelector = self.parse()?;
385        let start_pos = match combinator {
386            Some(Combinator { span, .. }) => span.lo,
387            _ => selector.span.lo,
388        };
389        let last_pos = selector.span.hi;
390
391        Ok(RelativeSelector {
392            span: Span::new(start_pos, last_pos),
393            combinator,
394            selector,
395        })
396    }
397}
398
399impl<I> Parse<CompoundSelector> for Parser<I>
400where
401    I: ParserInput,
402{
403    fn parse(&mut self) -> PResult<CompoundSelector> {
404        let start_span = self.input.cur_span();
405        let start_pos = start_span.lo;
406
407        let mut nesting_selector = None;
408
409        // TODO: move under option, because it is draft
410        // TODO validate list of selector, each should start with `&`
411        // This is an extension: https://drafts.csswg.org/css-nesting-1/
412        if eat!(self, "&") {
413            nesting_selector = Some(NestingSelector {
414                span: span!(self, start_pos),
415            });
416        }
417
418        let type_selector = if is_one_of!(self, Ident, "*", "|") {
419            Some(self.parse()?)
420        } else {
421            None
422        };
423        let mut subclass_selectors = Vec::new();
424
425        loop {
426            if !(is!(self, "#")
427                || is!(self, ".")
428                || is!(self, "[")
429                || (is!(self, ":") && !peeked_is!(self, ":")))
430            {
431                break;
432            }
433
434            let subclass_selector = self.parse()?;
435
436            subclass_selectors.push(subclass_selector);
437        }
438
439        loop {
440            if !(is!(self, ":") && peeked_is!(self, ":")) {
441                break;
442            }
443
444            // TODO pseudo element is not subclass selector
445            let pseudo_element = SubclassSelector::PseudoElement(self.parse()?);
446
447            subclass_selectors.push(pseudo_element);
448
449            loop {
450                if !(is!(self, ":") && !peeked_is!(self, ":")) {
451                    break;
452                }
453
454                let pseudo_element = SubclassSelector::PseudoClass(self.parse()?);
455
456                subclass_selectors.push(pseudo_element);
457            }
458        }
459
460        if !self.ctx.in_global_or_local_selector
461            && nesting_selector.is_none()
462            && type_selector.is_none()
463            && subclass_selectors.is_empty()
464        {
465            return Err(Error::new(start_span, ErrorKind::InvalidSelector));
466        }
467
468        let span = span!(self, start_pos);
469
470        Ok(CompoundSelector {
471            span,
472            nesting_selector,
473            type_selector,
474            subclass_selectors,
475        })
476    }
477}
478
479impl<I> Parse<TypeSelector> for Parser<I>
480where
481    I: ParserInput,
482{
483    fn parse(&mut self) -> PResult<TypeSelector> {
484        let span = self.input.cur_span();
485        let mut prefix = None;
486
487        if is!(self, Ident) && peeked_is!(self, "|")
488            || is!(self, "*") && peeked_is!(self, "|")
489            || is!(self, "|")
490        {
491            prefix = Some(self.parse()?);
492        }
493
494        match cur!(self) {
495            tok!("ident") => {
496                let value: Ident = self.parse()?;
497
498                return Ok(TypeSelector::TagName(TagNameSelector {
499                    span: span!(self, span.lo),
500                    name: WqName {
501                        span: span!(self, span.lo),
502                        prefix,
503                        value,
504                    },
505                }));
506            }
507            tok!("*") => {
508                bump!(self);
509
510                return Ok(TypeSelector::Universal(UniversalSelector {
511                    span: span!(self, span.lo),
512                    prefix,
513                }));
514            }
515            _ => {
516                return Err(Error::new(
517                    span,
518                    ErrorKind::Expected("ident, '*' or '|' delim tokens"),
519                ));
520            }
521        }
522    }
523}
524
525impl<I> Parse<NamespacePrefix> for Parser<I>
526where
527    I: ParserInput,
528{
529    fn parse(&mut self) -> PResult<NamespacePrefix> {
530        let span = self.input.cur_span();
531
532        let mut namespace = None;
533
534        match cur!(self) {
535            Token::Ident { .. } => {
536                let name = self.parse()?;
537
538                namespace = Some(Namespace::Named(NamedNamespace {
539                    span: span!(self, span.lo),
540                    name,
541                }));
542            }
543            Token::Delim { value, .. } if *value == '*' => {
544                bump!(self);
545
546                namespace = Some(Namespace::Any(AnyNamespace {
547                    span: span!(self, span.lo),
548                }));
549            }
550            _ => {}
551        }
552
553        expect!(self, "|");
554
555        Ok(NamespacePrefix {
556            span: span!(self, span.lo),
557            namespace,
558        })
559    }
560}
561
562impl<I> Parse<WqName> for Parser<I>
563where
564    I: ParserInput,
565{
566    fn parse(&mut self) -> PResult<WqName> {
567        let span = self.input.cur_span();
568        let state = self.input.state();
569        let mut prefix = None;
570
571        if is!(self, Ident) && peeked_is!(self, "|")
572            || is!(self, "*") && peeked_is!(self, "|")
573            || is!(self, "|")
574        {
575            prefix = Some(self.parse()?);
576        }
577
578        // To avoid confusing syntax in attribute selectors:
579        //
580        // - [foo|="foo"]
581        // - [foo|*="foo"]
582        if !is!(self, Ident) {
583            prefix = None;
584
585            self.input.reset(&state);
586        }
587
588        let value = self.parse()?;
589
590        Ok(WqName {
591            span: span!(self, span.lo),
592            prefix,
593            value,
594        })
595    }
596}
597
598impl<I> Parse<SubclassSelector> for Parser<I>
599where
600    I: ParserInput,
601{
602    fn parse(&mut self) -> PResult<SubclassSelector> {
603        match cur!(self) {
604            tok!("#") => Ok(SubclassSelector::Id(self.parse()?)),
605            tok!(".") => Ok(SubclassSelector::Class(self.parse()?)),
606            tok!("[") => Ok(SubclassSelector::Attribute(self.parse()?)),
607            tok!(":") => Ok(SubclassSelector::PseudoClass(self.parse()?)),
608            _ => {
609                let span = self.input.cur_span();
610
611                return Err(Error::new(
612                    span,
613                    ErrorKind::Expected("id, class, attribute or pseudo-class selector"),
614                ));
615            }
616        }
617    }
618}
619
620impl<I> Parse<IdSelector> for Parser<I>
621where
622    I: ParserInput,
623{
624    fn parse(&mut self) -> PResult<IdSelector> {
625        let span = self.input.cur_span();
626        let text = match bump!(self) {
627            Token::Hash {
628                is_id, value, raw, ..
629            } => {
630                if !is_id {
631                    return Err(Error::new(
632                        span,
633                        ErrorKind::Unexpected("characters in ID selector"),
634                    ));
635                }
636
637                Ident {
638                    span,
639                    value,
640                    raw: Some(raw),
641                }
642            }
643            _ => {
644                unreachable!()
645            }
646        };
647
648        Ok(IdSelector {
649            span: span!(self, span.lo),
650            text,
651        })
652    }
653}
654
655impl<I> Parse<ClassSelector> for Parser<I>
656where
657    I: ParserInput,
658{
659    fn parse(&mut self) -> PResult<ClassSelector> {
660        let span = self.input.cur_span();
661
662        expect!(self, ".");
663
664        let text = self.parse()?;
665
666        Ok(ClassSelector {
667            span: span!(self, span.lo),
668            text,
669        })
670    }
671}
672
673impl<I> Parse<AttributeSelector> for Parser<I>
674where
675    I: ParserInput,
676{
677    fn parse(&mut self) -> PResult<AttributeSelector> {
678        let span = self.input.cur_span();
679
680        expect!(self, "[");
681
682        self.input.skip_ws();
683
684        let mut matcher = None;
685        let mut value = None;
686        let mut modifier = None;
687
688        let name = if let Ok(wq_name) = self.parse() {
689            wq_name
690        } else {
691            let span = self.input.cur_span();
692
693            return Err(Error::new(
694                span!(self, span.lo),
695                ErrorKind::InvalidAttrSelectorName,
696            ));
697        };
698
699        self.input.skip_ws();
700
701        if !is!(self, "]") {
702            matcher = Some(self.parse()?);
703
704            self.input.skip_ws();
705
706            value = Some(self.parse()?);
707
708            self.input.skip_ws();
709
710            if is!(self, Ident) {
711                modifier = Some(self.parse()?);
712            }
713
714            self.input.skip_ws();
715        }
716
717        expect!(self, "]");
718
719        Ok(AttributeSelector {
720            span: span!(self, span.lo),
721            name,
722            matcher,
723            value,
724            modifier,
725        })
726    }
727}
728
729impl<I> Parse<AttributeSelectorMatcher> for Parser<I>
730where
731    I: ParserInput,
732{
733    fn parse(&mut self) -> PResult<AttributeSelectorMatcher> {
734        let span = self.input.cur_span();
735
736        match cur!(self) {
737            tok!("~") => {
738                bump!(self);
739                expect!(self, "=");
740
741                Ok(AttributeSelectorMatcher {
742                    span: span!(self, span.lo),
743                    value: AttributeSelectorMatcherValue::Tilde,
744                })
745            }
746            tok!("|") => {
747                bump!(self);
748                expect!(self, "=");
749
750                Ok(AttributeSelectorMatcher {
751                    span: span!(self, span.lo),
752                    value: AttributeSelectorMatcherValue::Bar,
753                })
754            }
755            tok!("^") => {
756                bump!(self);
757                expect!(self, "=");
758
759                Ok(AttributeSelectorMatcher {
760                    span: span!(self, span.lo),
761                    value: AttributeSelectorMatcherValue::Caret,
762                })
763            }
764            tok!("$") => {
765                bump!(self);
766                expect!(self, "=");
767
768                Ok(AttributeSelectorMatcher {
769                    span: span!(self, span.lo),
770                    value: AttributeSelectorMatcherValue::Dollar,
771                })
772            }
773            tok!("*") => {
774                bump!(self);
775                expect!(self, "=");
776
777                Ok(AttributeSelectorMatcher {
778                    span: span!(self, span.lo),
779                    value: AttributeSelectorMatcherValue::Asterisk,
780                })
781            }
782            tok!("=") => {
783                bump!(self);
784
785                Ok(AttributeSelectorMatcher {
786                    span: span!(self, span.lo),
787                    value: AttributeSelectorMatcherValue::Equals,
788                })
789            }
790            _ => return Err(Error::new(span, ErrorKind::InvalidAttrSelectorMatcher)),
791        }
792    }
793}
794
795impl<I> Parse<AttributeSelectorValue> for Parser<I>
796where
797    I: ParserInput,
798{
799    fn parse(&mut self) -> PResult<AttributeSelectorValue> {
800        match cur!(self) {
801            tok!("ident") => {
802                let ident = self.parse()?;
803
804                Ok(AttributeSelectorValue::Ident(ident))
805            }
806            tok!("string") => {
807                let string = self.parse()?;
808
809                Ok(AttributeSelectorValue::Str(string))
810            }
811            _ => {
812                let span = self.input.cur_span();
813
814                return Err(Error::new(span, ErrorKind::InvalidAttrSelectorMatcherValue));
815            }
816        }
817    }
818}
819
820impl<I> Parse<AttributeSelectorModifier> for Parser<I>
821where
822    I: ParserInput,
823{
824    fn parse(&mut self) -> PResult<AttributeSelectorModifier> {
825        let span = self.input.cur_span();
826
827        match cur!(self) {
828            tok!("ident") => {
829                let value: Ident = self.parse()?;
830
831                Ok(AttributeSelectorModifier {
832                    span: span!(self, span.lo),
833                    value,
834                })
835            }
836            _ => return Err(Error::new(span, ErrorKind::InvalidAttrSelectorModifier)),
837        }
838    }
839}
840
841impl<I> Parse<PseudoClassSelector> for Parser<I>
842where
843    I: ParserInput,
844{
845    fn parse(&mut self) -> PResult<PseudoClassSelector> {
846        let span = self.input.cur_span();
847
848        expect!(self, ":");
849
850        if is!(self, Function) {
851            let fn_span = self.input.cur_span();
852            let name = bump!(self);
853            let names: (Atom, _) = match name {
854                Token::Function { value, raw } => (value.to_ascii_lowercase(), raw),
855                _ => unreachable!(),
856            };
857            let state = self.input.state();
858            let mut parse_pseudo_class_children =
859                || -> PResult<Vec<PseudoClassSelectorChildren>> {
860                    let mut children = Vec::new();
861
862                    match &*names.0 {
863                        "local" | "global" if self.config.css_modules => {
864                            self.input.skip_ws();
865
866                            let ctx = Ctx {
867                                in_global_or_local_selector: true,
868                                ..self.ctx
869                            };
870                            let selector_list = self.with_ctx(ctx).parse_as::<ComplexSelector>()?;
871
872                            self.input.skip_ws();
873
874                            children
875                                .push(PseudoClassSelectorChildren::ComplexSelector(selector_list));
876                        }
877                        "-moz-any" | "-webkit-any" => {
878                            self.input.skip_ws();
879
880                            let compound_selector_list = self.parse()?;
881
882                            self.input.skip_ws();
883
884                            children.push(PseudoClassSelectorChildren::CompoundSelectorList(
885                                compound_selector_list,
886                            ));
887                        }
888                        "dir" => {
889                            self.input.skip_ws();
890
891                            let ident: Ident = self.parse()?;
892
893                            self.input.skip_ws();
894
895                            children.push(PseudoClassSelectorChildren::Ident(ident));
896                        }
897                        "lang" => {
898                            self.input.skip_ws();
899
900                            let child = match cur!(self) {
901                                tok!("ident") => PseudoClassSelectorChildren::Ident(self.parse()?),
902                                tok!("string") => PseudoClassSelectorChildren::Str(self.parse()?),
903                                _ => {
904                                    return Err(Error::new(
905                                        span,
906                                        ErrorKind::Expected("ident or str tokens"),
907                                    ));
908                                }
909                            };
910
911                            children.push(child);
912
913                            loop {
914                                self.input.skip_ws();
915
916                                if is!(self, ",") {
917                                    children.push(PseudoClassSelectorChildren::Delimiter(
918                                        self.parse()?,
919                                    ));
920
921                                    self.input.skip_ws();
922                                } else {
923                                    break;
924                                }
925
926                                let child = match cur!(self) {
927                                    tok!("ident") => {
928                                        PseudoClassSelectorChildren::Ident(self.parse()?)
929                                    }
930                                    tok!("string") => {
931                                        PseudoClassSelectorChildren::Str(self.parse()?)
932                                    }
933                                    _ => {
934                                        return Err(Error::new(
935                                            span,
936                                            ErrorKind::Expected("ident or str tokens"),
937                                        ));
938                                    }
939                                };
940
941                                children.push(child);
942                            }
943                        }
944                        "current" | "past" | "future" => {
945                            self.input.skip_ws();
946
947                            let compound_selector_list = self.parse()?;
948
949                            self.input.skip_ws();
950
951                            children.push(PseudoClassSelectorChildren::CompoundSelectorList(
952                                compound_selector_list,
953                            ));
954                        }
955                        "not" | "matches" => {
956                            self.input.skip_ws();
957
958                            let selector_list = self.parse()?;
959
960                            self.input.skip_ws();
961
962                            children.push(PseudoClassSelectorChildren::SelectorList(selector_list));
963                        }
964                        "is" | "where" => {
965                            let forgiving_selector_list = self.parse()?;
966
967                            children.push(PseudoClassSelectorChildren::ForgivingSelectorList(
968                                forgiving_selector_list,
969                            ));
970                        }
971                        "has" => {
972                            let forgiving_relative_selector_list = self.parse()?;
973
974                            children.push(
975                                PseudoClassSelectorChildren::ForgivingRelativeSelectorList(
976                                    forgiving_relative_selector_list,
977                                ),
978                            );
979                        }
980                        "nth-child" | "nth-last-child" | "nth-of-type" | "nth-last-of-type"
981                        | "nth-col" | "nth-last-col" => {
982                            self.input.skip_ws();
983
984                            let an_plus_b = self.parse()?;
985
986                            children.push(PseudoClassSelectorChildren::AnPlusB(an_plus_b));
987
988                            self.input.skip_ws();
989
990                            if is!(self, "ident") {
991                                let of: Ident = self.parse()?;
992
993                                children.push(PseudoClassSelectorChildren::Ident(of));
994
995                                self.input.skip_ws();
996
997                                let selector_list = self.parse()?;
998
999                                self.input.skip_ws();
1000
1001                                children
1002                                    .push(PseudoClassSelectorChildren::SelectorList(selector_list));
1003                            }
1004                        }
1005                        "host" | "host-context" => {
1006                            self.input.skip_ws();
1007
1008                            let compound_selector = self.parse()?;
1009
1010                            self.input.skip_ws();
1011
1012                            children.push(PseudoClassSelectorChildren::CompoundSelector(
1013                                compound_selector,
1014                            ));
1015                        }
1016                        _ => {
1017                            return Err(Error::new(span, ErrorKind::Ignore));
1018                        }
1019                    };
1020
1021                    Ok(children)
1022                };
1023            let children = match parse_pseudo_class_children() {
1024                Ok(children) => children,
1025                Err(err) => {
1026                    if *err.kind() != ErrorKind::Ignore {
1027                        self.errors.push(err);
1028                    }
1029
1030                    self.input.reset(&state);
1031
1032                    let any_value = self.parse_any_value()?;
1033                    let any_value: Vec<PseudoClassSelectorChildren> = any_value
1034                        .into_iter()
1035                        .map(PseudoClassSelectorChildren::PreservedToken)
1036                        .collect();
1037
1038                    any_value
1039                }
1040            };
1041
1042            expect!(self, ")");
1043
1044            Ok(PseudoClassSelector {
1045                span: span!(self, span.lo),
1046                name: Ident {
1047                    span: Span::new(fn_span.lo, fn_span.hi - BytePos(1)),
1048                    value: names.0,
1049                    raw: Some(names.1),
1050                },
1051                children: Some(children),
1052            })
1053        } else if is!(self, Ident) {
1054            let name: Ident = self.parse()?;
1055
1056            Ok(PseudoClassSelector {
1057                span: span!(self, span.lo),
1058                name,
1059                children: None,
1060            })
1061        } else {
1062            let span = self.input.cur_span();
1063
1064            Err(Error::new(
1065                span,
1066                ErrorKind::Expected("function or ident tokens"),
1067            ))
1068        }
1069    }
1070}
1071
1072impl<I> Parse<PseudoElementSelector> for Parser<I>
1073where
1074    I: ParserInput,
1075{
1076    fn parse(&mut self) -> PResult<PseudoElementSelector> {
1077        let span = self.input.cur_span();
1078
1079        expect!(self, ":");
1080        expect!(self, ":");
1081
1082        if is!(self, Function) {
1083            let fn_span = self.input.cur_span();
1084            let name = bump!(self);
1085            let names: (Atom, _) = match name {
1086                Token::Function { value, raw } => (value.to_ascii_lowercase(), raw),
1087                _ => unreachable!(),
1088            };
1089
1090            let state = self.input.state();
1091            let mut parse_pseudo_element_children =
1092                || -> PResult<Vec<PseudoElementSelectorChildren>> {
1093                    let mut children = Vec::new();
1094
1095                    match &*names.0 {
1096                        "cue" | "cue-region" => {
1097                            self.input.skip_ws();
1098
1099                            let compound_selector = self.parse()?;
1100
1101                            children.push(PseudoElementSelectorChildren::CompoundSelector(
1102                                compound_selector,
1103                            ));
1104
1105                            self.input.skip_ws();
1106                        }
1107                        "part" => {
1108                            self.input.skip_ws();
1109
1110                            let ident = self.parse()?;
1111
1112                            children.push(PseudoElementSelectorChildren::Ident(ident));
1113
1114                            self.input.skip_ws();
1115                        }
1116                        "slotted" => {
1117                            self.input.skip_ws();
1118
1119                            let compound_selector = self.parse()?;
1120
1121                            children.push(PseudoElementSelectorChildren::CompoundSelector(
1122                                compound_selector,
1123                            ));
1124
1125                            self.input.skip_ws();
1126                        }
1127                        "highlight" => {
1128                            self.input.skip_ws();
1129
1130                            let custom_highlight_name = self.parse()?;
1131
1132                            children.push(PseudoElementSelectorChildren::CustomHighlightName(
1133                                custom_highlight_name,
1134                            ));
1135
1136                            self.input.skip_ws();
1137                        }
1138                        _ => {
1139                            return Err(Error::new(span, ErrorKind::Ignore));
1140                        }
1141                    };
1142
1143                    Ok(children)
1144                };
1145            let children = match parse_pseudo_element_children() {
1146                Ok(children) => children,
1147                Err(err) => {
1148                    if *err.kind() != ErrorKind::Ignore {
1149                        self.errors.push(err);
1150                    }
1151
1152                    self.input.reset(&state);
1153
1154                    let any_value = self.parse_any_value()?;
1155                    let any_value: Vec<PseudoElementSelectorChildren> = any_value
1156                        .into_iter()
1157                        .map(PseudoElementSelectorChildren::PreservedToken)
1158                        .collect();
1159
1160                    any_value
1161                }
1162            };
1163
1164            expect!(self, ")");
1165
1166            Ok(PseudoElementSelector {
1167                span: span!(self, span.lo),
1168                name: Ident {
1169                    span: Span::new(fn_span.lo, fn_span.hi - BytePos(1)),
1170                    value: names.0,
1171                    raw: Some(names.1),
1172                },
1173                children: Some(children),
1174            })
1175        } else if is!(self, Ident) {
1176            let name: Ident = self.parse()?;
1177
1178            Ok(PseudoElementSelector {
1179                span: span!(self, span.lo),
1180                name,
1181                children: None,
1182            })
1183        } else {
1184            let span = self.input.cur_span();
1185
1186            Err(Error::new(span, ErrorKind::InvalidSelector))
1187        }
1188    }
1189}
1190
1191impl<I> Parse<AnPlusB> for Parser<I>
1192where
1193    I: ParserInput,
1194{
1195    fn parse(&mut self) -> PResult<AnPlusB> {
1196        let span = self.input.cur_span();
1197
1198        match cur!(self) {
1199            //  odd | even
1200            Token::Ident { value, .. }
1201                if matches_eq_ignore_ascii_case!(value, "odd", "even") =>
1202                {
1203                    let ident: Ident = self.parse()?;
1204
1205
1206                    Ok(AnPlusB::Ident(ident))
1207                }
1208            // <integer>
1209            tok!("number") => {
1210                let number = match bump!(self) {
1211                    Token::Number { value, raw, .. } => (value, raw),
1212                    _ => {
1213                        unreachable!();
1214                    }
1215                };
1216
1217                Ok(AnPlusB::AnPlusBNotation(AnPlusBNotation {
1218                    span: span!(self, span.lo),
1219                    a: None,
1220                    a_raw: None,
1221                    b: Some(number.0 as i32),
1222                    b_raw: Some(number.1),
1223                }))
1224            }
1225            // '+'? n
1226            // '+'? <ndashdigit-ident>
1227            // '+'? n <signed-integer>
1228            // '+'? n- <signless-integer>
1229            // '+'? n ['+' | '-'] <signless-integer>
1230            // -n
1231            // <dashndashdigit-ident>
1232            // -n <signed-integer>
1233            // -n- <signless-integer>
1234            // -n ['+' | '-'] <signless-integer>
1235            tok!("ident") | tok!("+") |
1236            // <n-dimension>
1237            // <ndashdigit-dimension>
1238            // <ndash-dimension> <signless-integer>
1239            // <n-dimension> <signed-integer>
1240            // <n-dimension> ['+' | '-'] <signless-integer>
1241            tok!("dimension") => {
1242                let mut has_plus_sign = false;
1243
1244                // '+' n
1245                if let  Token::Delim { value: '+' } = cur!(self){
1246                    let peeked = self.input.peek();
1247
1248                    if let Some(Token::Ident { .. }) = peeked {
1249                        bump!(self);
1250                        has_plus_sign = true;
1251                    }
1252                }
1253                let a;
1254                let a_raw;
1255
1256                let n_value;
1257
1258                match cur!(self) {
1259                    Token::Ident {  .. } => {
1260                        let ident_value = match bump!(self) {
1261                            Token::Ident { value, .. } => value,
1262                            _ => {
1263                                unreachable!();
1264                            }
1265                        };
1266
1267                        let has_minus_sign = ident_value.starts_with('-');
1268                        let n_char = if has_minus_sign { ident_value.chars().nth(1) } else { ident_value.chars().next() };
1269
1270                        if n_char != Some('n') && n_char != Some('N') {
1271                            return Err(Error::new(
1272                                span,
1273                                ErrorKind::Expected("'n' character in Ident"),
1274                            ));
1275                        }
1276
1277                        a = Some(if has_minus_sign { -1 } else {1 });
1278                        a_raw = Some(self.input.atom(if has_plus_sign { "+" } else if has_minus_sign { "-" } else { "" }));
1279
1280                        n_value = if has_minus_sign { ident_value[1..].to_string() } else { ident_value.to_string() };
1281                    }
1282                    tok!("dimension") => {
1283                        let dimension = match bump!(self) {
1284                            Token::Dimension(dimension) => {
1285                                let DimensionToken { value, raw_value, unit, .. } = *dimension;
1286
1287                             (value, raw_value, unit)
1288                            }
1289                            _ => {
1290                                unreachable!();
1291                            }
1292                        };
1293
1294                        let n_char = dimension.2.chars().next();
1295
1296                        if n_char != Some('n') && n_char != Some('N') {
1297                            return Err(Error::new(
1298                                span,
1299                                ErrorKind::Expected("'n' character in Ident"),
1300                            ));
1301                        }
1302
1303                        a = Some(dimension.0 as i32);
1304                        a_raw = Some(dimension.1);
1305                        n_value =  (*dimension.2).to_string();
1306                    }
1307                    _ => {
1308                        return Err(Error::new(span, ErrorKind::InvalidAnPlusBMicrosyntax));
1309                    }
1310                };
1311
1312                self.input.skip_ws();
1313
1314                let mut b = None;
1315                let mut b_raw = None;
1316
1317                let dash_after_n = n_value.chars().nth(1);
1318
1319                match cur!(self) {
1320                    // '+'? n <signed-integer>
1321                    // -n <signed-integer>
1322                    // <n-dimension> <signed-integer>
1323                    tok!("number") if dash_after_n.is_none() => {
1324                        let number = match bump!(self) {
1325                            Token::Number { value, raw, .. } => (value, raw),
1326                            _ => {
1327                                unreachable!();
1328                            }
1329                        };
1330
1331                        b = Some(number.0 as i32);
1332                        b_raw = Some(number.1);
1333                    }
1334                    // -n- <signless-integer>
1335                    // '+'? n- <signless-integer>
1336                    // <ndash-dimension> <signless-integer>
1337                    tok!("number") if dash_after_n == Some('-') => {
1338                        let number = match bump!(self) {
1339                            Token::Number { value, raw, .. } => (value, raw),
1340                            _ => {
1341                                unreachable!();
1342                            }
1343                        };
1344
1345                        b = Some(-number.0 as i32);
1346
1347                        let mut b_raw_str = String::new();
1348
1349                        b_raw_str.push_str("- ");
1350                        b_raw_str.push_str(&number.1);
1351                        b_raw = Some(self.input.atom(b_raw_str));
1352                    }
1353                    // '+'? n ['+' | '-'] <signless-integer>
1354                    // -n ['+' | '-'] <signless-integer>
1355                    // <n-dimension> ['+' | '-'] <signless-integer>
1356                    tok!("-") | tok!("+") => {
1357                        let (b_sign, b_sign_raw) = match bump!(self) {
1358                            Token::Delim { value, .. } => (if value == '-' { -1 } else { 1 }, value),
1359                            _ => {
1360                                unreachable!();
1361                            }
1362                        };
1363
1364                        self.input.skip_ws();
1365
1366                        let number = match bump!(self) {
1367                            Token::Number { value, raw, .. } => (value, raw),
1368                            _ => {
1369                                return Err(Error::new(span, ErrorKind::Expected("Num")));
1370                            }
1371                        };
1372
1373                        b = Some(b_sign * number.0 as i32);
1374
1375                        let mut b_raw_str = String::new();
1376
1377                        b_raw_str.push(' ');
1378                        b_raw_str.push(b_sign_raw);
1379                        b_raw_str.push(' ');
1380                        b_raw_str.push_str(&number.1);
1381                        b_raw = Some(self.input.atom(b_raw_str));
1382                    }
1383                    // '+'? <ndashdigit-ident>
1384                    // <dashndashdigit-ident>
1385                    // <ndashdigit-dimension>
1386                    _ if dash_after_n == Some('-') => {
1387                        let b_from_ident = &n_value[2..];
1388                        let parsed: i32 = lexical::parse(b_from_ident).unwrap_or_else(|err| {
1389                            unreachable!(
1390                                "failed to parse `{}` using lexical: {:?}",
1391                                b_from_ident, err
1392                            )
1393                        });
1394
1395                        b = Some(-parsed);
1396
1397                        let mut b_raw_str = String::new();
1398
1399                        b_raw_str.push('-');
1400                        b_raw_str.push_str(b_from_ident);
1401
1402                        b_raw = Some(self.input.atom(b_raw_str));
1403                    }
1404                    // '+'? n
1405                    // -n
1406                    _ if dash_after_n.is_none() => {}
1407                    _ => {
1408                        return Err(Error::new(span, ErrorKind::InvalidAnPlusBMicrosyntax));
1409                    }
1410                }
1411
1412                Ok(AnPlusB::AnPlusBNotation(AnPlusBNotation {
1413                    span: span!(self, span.lo),
1414                    a,
1415                    a_raw,
1416                    b,
1417                    b_raw,
1418                }))
1419            }
1420            _ => {
1421                return Err(Error::new(span, ErrorKind::InvalidAnPlusBMicrosyntax));
1422            }
1423        }
1424    }
1425}
1426
1427impl<I> Parse<CustomHighlightName> for Parser<I>
1428where
1429    I: ParserInput,
1430{
1431    fn parse(&mut self) -> PResult<CustomHighlightName> {
1432        let span = self.input.cur_span();
1433
1434        if !is!(self, Ident) {
1435            return Err(Error::new(span, ErrorKind::Expected("ident token")));
1436        }
1437
1438        match bump!(self) {
1439            Token::Ident { value, raw, .. } => Ok(CustomHighlightName {
1440                span,
1441                value,
1442                raw: Some(raw),
1443            }),
1444            _ => {
1445                unreachable!()
1446            }
1447        }
1448    }
1449}