oxc_css_parser/parser/at_rule/
page.rs1use super::Parser;
2use crate::{
3 Parse,
4 ast::*,
5 eat,
6 error::PResult,
7 expect, peek,
8 pos::{Span, Spanned},
9 tokenizer::{Token, TokenWithSpan},
10 util,
11};
12
13impl<'cmt, 's: 'cmt> Parse<'cmt, 's> for PageSelector<'s> {
15 fn parse(input: &mut Parser<'cmt, 's>) -> PResult<Self> {
16 let mut name = None;
17 let mut pseudo = vec![];
18 let start;
19 let mut end;
20
21 if let Token::Colon(..) = &peek!(input).token {
22 let first = input.parse::<PseudoPage>()?;
23 start = first.span.start;
24 end = first.span.end;
25 pseudo.push(first);
26 } else {
27 let ident = input.parse::<InterpolableIdent>()?;
28 let ident_span = ident.span();
29 start = ident_span.start;
30 end = ident_span.end;
31 name = Some(ident)
32 }
33
34 loop {
35 match peek!(input) {
36 TokenWithSpan {
37 token: Token::Colon(..),
38 span,
39 } if span.start == end => {
40 let item = input.parse::<PseudoPage>()?;
41 end = item.span.end;
42 pseudo.push(item);
43 }
44 _ => break,
45 }
46 }
47
48 Ok(PageSelector {
49 name,
50 pseudo,
51 span: Span { start, end },
52 })
53 }
54}
55
56impl<'cmt, 's: 'cmt> Parse<'cmt, 's> for PageSelectorList<'s> {
57 fn parse(input: &mut Parser<'cmt, 's>) -> PResult<Self> {
58 let first = input.parse::<PageSelector>()?;
59 let mut span = first.span.clone();
60
61 let mut selectors = vec![first];
62 let mut comma_spans = vec![];
63 while let Some((_, comma_span)) = eat!(input, Comma) {
64 comma_spans.push(comma_span);
65 selectors.push(input.parse()?);
66 }
67
68 if let Some(last) = selectors.last() {
69 span.end = last.span.end;
70 }
71 Ok(PageSelectorList {
72 selectors,
73 comma_spans,
74 span,
75 })
76 }
77}
78
79impl<'cmt, 's: 'cmt> Parse<'cmt, 's> for PseudoPage<'s> {
80 fn parse(input: &mut Parser<'cmt, 's>) -> PResult<Self> {
81 let (_, colon_span) = expect!(input, Colon);
82 let name = input.parse::<InterpolableIdent>()?;
83
84 let name_span = name.span();
85 util::assert_no_ws_or_comment(&colon_span, name_span)?;
86
87 let span = Span {
88 start: colon_span.start,
89 end: name_span.end,
90 };
91 Ok(PseudoPage { name, span })
92 }
93}