Skip to main content

oxc_css_parser/parser/
postcss_simple_vars.rs

1use super::Parser;
2use crate::{Parse, ast::*, config::Syntax, error::PResult, pos::Span, tokenizer::Token};
3
4// postcss-simple-vars variable reference: `$` <ident>
5// https://github.com/postcss/postcss-simple-vars
6impl<'a> Parse<'a> for PostcssSimpleVar<'a> {
7    fn parse(input: &mut Parser<'a>) -> PResult<Self> {
8        debug_assert!(input.syntax == Syntax::Css && input.options.allow_postcss_simple_vars);
9
10        let (name, span) = input.parse_dollar_var_ident()?;
11        Ok(PostcssSimpleVar { name, span })
12    }
13}
14
15// postcss-simple-vars declaration: `$` <ident> ':' <declaration-value>
16// (textual substitution; a trailing `!important` stays part of the value)
17impl<'a> Parse<'a> for PostcssSimpleVarDeclaration<'a> {
18    fn parse(input: &mut Parser<'a>) -> PResult<Self> {
19        debug_assert!(input.syntax == Syntax::Css && input.options.allow_postcss_simple_vars);
20
21        let name = input.parse::<PostcssSimpleVar>()?;
22        let (_, colon_span) = input.cursor.expect_colon()?;
23        let mut value = input.parse_declaration_value()?;
24        // postcss-simple-vars is textual substitution; `!important` is just part
25        // of the value, not a structural declaration modifier (unlike CSS's
26        // `Declaration.important`). Keep it in the value stream.
27        if let Token::Exclamation(..) = &input.cursor.peek()?.token {
28            let important = input.parse::<ImportantAnnotation>()?;
29            value.push(ComponentValue::ImportantAnnotation(important));
30        }
31
32        let end = value.last().map(|v| v.span().end).unwrap_or(colon_span.end);
33        let span = Span { start: name.span.start, end };
34
35        Ok(PostcssSimpleVarDeclaration { name, colon_span, value, span })
36    }
37}