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> {
13 fn parse(input: &mut Parser<'a>) -> PResult<Self> {
14 let mut name = None;
15 let mut pseudo = input.vec();
16 let start;
17 let mut end;
18
19 if let Token::Colon(..) = &input.cursor.peek()?.token {
20 let first = input.parse::<PseudoPage>()?;
21 start = first.span.start;
22 end = first.span.end;
23 pseudo.push(first);
24 } else {
25 let ident = input.parse::<InterpolableIdent>()?;
26 let ident_span = ident.span();
27 start = ident_span.start;
28 end = ident_span.end;
29 name = Some(ident)
30 }
31
32 loop {
33 match input.cursor.peek()? {
34 TokenWithSpan { token: Token::Colon(..), span } if span.start == end => {
35 let item = input.parse::<PseudoPage>()?;
36 end = item.span.end;
37 pseudo.push(item);
38 }
39 _ => break,
40 }
41 }
42
43 Ok(PageSelector { name, pseudo, span: Span { start, end } })
44 }
45}
46
47impl<'a> Parse<'a> for PageSelectorList<'a> {
48 fn parse(input: &mut Parser<'a>) -> PResult<Self> {
49 let first = input.parse::<PageSelector>()?;
50 let mut span = first.span.clone();
51
52 let mut selectors = input.vec1(first);
53 let mut comma_spans = input.vec();
54 while let Some((_, comma_span)) = input.cursor.eat_comma()? {
55 comma_spans.push(comma_span);
56 selectors.push(input.parse()?);
57 }
58
59 if let Some(last) = selectors.last() {
60 span.end = last.span.end;
61 }
62 Ok(PageSelectorList { selectors, comma_spans, span })
63 }
64}
65
66impl<'a> Parse<'a> for PseudoPage<'a> {
67 fn parse(input: &mut Parser<'a>) -> PResult<Self> {
68 let (_, colon_span) = input.cursor.expect_colon()?;
69 let name = input.parse::<InterpolableIdent>()?;
70
71 let name_span = name.span();
72 util::assert_no_ws_or_comment(&colon_span, name_span)?;
73
74 let span = Span { start: colon_span.start, end: name_span.end };
75 Ok(PseudoPage { name, span })
76 }
77}