oxc_css_parser/parser/at_rule/
page.rs1use super::Parser;
2use crate::{
3 Parse, arena_vec,
4 ast::*,
5 eat,
6 error::PResult,
7 expect, peek,
8 pos::{Span, Spanned},
9 tokenizer::{Token, TokenWithSpan},
10 util,
11};
12
13impl<'a> Parse<'a> for PageSelector<'a> {
15 fn parse(input: &mut Parser<'a>) -> PResult<Self> {
16 let mut name = None;
17 let mut pseudo = arena_vec!(input);
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 { token: Token::Colon(..), span } if span.start == end => {
37 let item = input.parse::<PseudoPage>()?;
38 end = item.span.end;
39 pseudo.push(item);
40 }
41 _ => break,
42 }
43 }
44
45 Ok(PageSelector { name, pseudo, span: Span { start, end } })
46 }
47}
48
49impl<'a> Parse<'a> for PageSelectorList<'a> {
50 fn parse(input: &mut Parser<'a>) -> PResult<Self> {
51 let first = input.parse::<PageSelector>()?;
52 let mut span = first.span.clone();
53
54 let mut selectors = arena_vec!(input; first);
55 let mut comma_spans = arena_vec!(input);
56 while let Some((_, comma_span)) = eat!(input, Comma) {
57 comma_spans.push(comma_span);
58 selectors.push(input.parse()?);
59 }
60
61 if let Some(last) = selectors.last() {
62 span.end = last.span.end;
63 }
64 Ok(PageSelectorList { selectors, comma_spans, span })
65 }
66}
67
68impl<'a> Parse<'a> for PseudoPage<'a> {
69 fn parse(input: &mut Parser<'a>) -> PResult<Self> {
70 let (_, colon_span) = expect!(input, Colon);
71 let name = input.parse::<InterpolableIdent>()?;
72
73 let name_span = name.span();
74 util::assert_no_ws_or_comment(&colon_span, name_span)?;
75
76 let span = Span { start: colon_span.start, end: name_span.end };
77 Ok(PseudoPage { name, span })
78 }
79}