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 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 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 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 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 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 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 tok!("ident") | tok!("+") |
1236 tok!("dimension") => {
1242 let mut has_plus_sign = false;
1243
1244 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 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 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 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 _ 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 _ 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}