oxc_css_parser/parser/at_rule/
page.rs1use super::Parser;
2use crate::{
3 Parse,
4 ast::*,
5 error::PResult,
6 pos::Span,
7 tokenizer::{Token, TokenWithSpan},
8 util,
9};
10
11impl<'a> Parse<'a> for PageSelector<'a> {
15 fn parse(input: &mut Parser<'a>) -> PResult<Self> {
16 let mut name = None;
17 let mut pseudo = input.vec();
18 let start;
19 let mut end;
20
21 if let Token::Colon(..) | Token::ColonColon(..) = &input.cursor.peek()?.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 input.cursor.peek()? {
36 TokenWithSpan { token: Token::Colon(..) | Token::ColonColon(..), span }
37 if span.start == end =>
38 {
39 let item = input.parse::<PseudoPage>()?;
40 end = item.span.end;
41 pseudo.push(item);
42 }
43 _ => break,
44 }
45 }
46
47 Ok(PageSelector { name, pseudo, span: Span { start, end } })
48 }
49}
50
51impl<'a> Parse<'a> for PageSelectorList<'a> {
53 fn parse(input: &mut Parser<'a>) -> PResult<Self> {
54 let first = input.parse::<PageSelector>()?;
55 let mut span = first.span;
56
57 let mut selectors = input.vec1(first);
58 let mut comma_spans = input.vec();
59 while let Some((_, comma_span)) = input.cursor.eat_comma()? {
60 comma_spans.push(comma_span);
61 selectors.push(input.parse()?);
62 }
63
64 if let Some(last) = selectors.last() {
65 span.end = last.span.end;
66 }
67 Ok(PageSelectorList { selectors, comma_spans, span })
68 }
69}
70
71impl<'a> Parse<'a> for PseudoPage<'a> {
76 fn parse(input: &mut Parser<'a>) -> PResult<Self> {
77 let colon_span = match &input.cursor.peek()?.token {
78 Token::ColonColon(..) => input.cursor.expect_colon_colon()?.1,
79 _ => input.cursor.expect_colon()?.1,
80 };
81 let name = input.parse::<InterpolableIdent>()?;
82
83 let name_span = name.span();
84 util::assert_no_ws_or_comment(&colon_span, name_span)?;
85 let mut end = name_span.end;
86
87 let arg = match input.cursor.peek()? {
88 TokenWithSpan { token: Token::LParen(..), span } if span.start == end => {
89 input.cursor.bump()?;
90 let tokens = input.parse_tokens_in_parens()?;
91 end = input.cursor.expect_r_paren()?.1.end;
92 Some(tokens)
93 }
94 _ => None,
95 };
96
97 let span = Span { start: colon_span.start, end };
98 Ok(PseudoPage { name, arg, span })
99 }
100}