Skip to main content

oxc_css_parser/parser/at_rule/
document.rs

1use super::Parser;
2use crate::{Parse, ast::*, error::PResult};
3
4// https://developer.mozilla.org/en-US/docs/Web/CSS/@document
5//
6// Non-standard (dropped from css-conditional); a comma-separated matcher list:
7// @document <matcher> [ , <matcher> ]* { <rule-list> }
8impl<'a> Parse<'a> for DocumentPrelude<'a> {
9    fn parse(input: &mut Parser<'a>) -> PResult<Self> {
10        let first = input.parse::<DocumentPreludeMatcher>()?;
11        let mut span = first.span().clone();
12
13        let mut matchers = input.vec1(first);
14        let mut comma_spans = input.vec();
15        while let Some((_, comma_span)) = input.cursor.eat_comma()? {
16            comma_spans.push(comma_span);
17            matchers.push(input.parse()?);
18        }
19        debug_assert_eq!(comma_spans.len() + 1, matchers.len());
20
21        if let Some(last) = matchers.last() {
22            span.end = last.span().end;
23        }
24        Ok(DocumentPrelude { matchers, comma_spans, span })
25    }
26}
27
28// <matcher> = <url>
29//           | url-prefix( <string> ) | domain( <string> )
30//           | media-document( <string> ) | regexp( <string> )
31impl<'a> Parse<'a> for DocumentPreludeMatcher<'a> {
32    fn parse(input: &mut Parser<'a>) -> PResult<Self> {
33        if let Ok(url) = input.try_parse(Url::parse) {
34            Ok(DocumentPreludeMatcher::Url(url))
35        } else {
36            input.parse().map(DocumentPreludeMatcher::Function)
37        }
38    }
39}