diff --git a/src/selector.rs b/src/selector.rs index 3b8d34c..11e2c19 100644 --- a/src/selector.rs +++ b/src/selector.rs @@ -72,6 +72,8 @@ pub(crate) enum SelectorKind { PseudoParen(String, Vec), /// Use the super selector: `&.red` Super, + /// Super selector in an interpolated context: `a #{&}` + InterpolatedSuper, /// Used to signify no selector (when there is no super_selector of a rule) None, Whitespace, @@ -109,7 +111,10 @@ impl Display for SelectorKind { s, toks.iter().map(ToString::to_string).collect::() ), - SelectorKind::Super | SelectorKind::None => write!(f, ""), + SelectorKind::InterpolatedSuper => write!(f, " "), + SelectorKind::Super | SelectorKind::None => { + write!(f, "") + } } } } @@ -165,6 +170,7 @@ mod test_selector_display { struct SelectorParser<'a> { scope: &'a Scope, selectors: Vec, + is_interpolated: bool, } impl<'a> SelectorParser<'a> { @@ -172,6 +178,7 @@ impl<'a> SelectorParser<'a> { SelectorParser { scope, selectors: Vec::new(), + is_interpolated: false, } } @@ -248,10 +255,19 @@ impl<'a> SelectorParser<'a> { TokenKind::Symbol(Symbol::Plus) => self.selectors.push(SelectorKind::Following), TokenKind::Symbol(Symbol::Tilde) => self.selectors.push(SelectorKind::Preceding), TokenKind::Symbol(Symbol::Mul) => self.selectors.push(SelectorKind::Universal), - TokenKind::Symbol(Symbol::BitAnd) => self.selectors.push(SelectorKind::Super), - TokenKind::Interpolation => self.tokens_to_selectors( - &mut eat_interpolation(tokens, self.scope).into_iter().peekable(), - ), + TokenKind::Symbol(Symbol::BitAnd) => self.selectors.push(if self.is_interpolated { + SelectorKind::InterpolatedSuper + } else { + SelectorKind::Super + }), + TokenKind::Interpolation => { + self.is_interpolated = true; + let v = self.tokens_to_selectors( + &mut eat_interpolation(tokens, self.scope).into_iter().peekable(), + ); + self.is_interpolated = false; + v + } TokenKind::Attribute(attr) => self.selectors.push(SelectorKind::Attribute(attr)), _ => todo!("unimplemented selector"), }; @@ -289,6 +305,8 @@ impl Selector { if sel == &SelectorKind::Super { this_selector.extend(sel1.to_vec()); found_super = true; + } else if sel == &SelectorKind::InterpolatedSuper { + this_selector.extend(sel1.to_vec()); } else { this_selector.push(sel.clone()); } diff --git a/tests/main.rs b/tests/main.rs index 2cc7cba..8af5a56 100644 --- a/tests/main.rs +++ b/tests/main.rs @@ -254,6 +254,16 @@ mod test_selectors { "$a: foo;\nab#{$a} {\n color: red;\n}\n", "abfoo {\n color: red;\n}\n" ); + test!( + selector_interpolation_super_selector, + "a {\nb #{&} { color: red; }}", + "a b a {\n color: red;\n}\n" + ); + test!( + selector_interpolation_super_selector_root, + "a#{&} {\nb { color: red; }}", + "a b {\n color: red;\n}\n" + ); test!( selector_whitespace, " a > b , c ~ d e .f #g :h i.j [ k ] { color: red }",