Handle interpolated super selectors
This commit is contained in:
parent
4fdd1ce69a
commit
4e6ae91825
@ -72,6 +72,8 @@ pub(crate) enum SelectorKind {
|
|||||||
PseudoParen(String, Vec<TokenKind>),
|
PseudoParen(String, Vec<TokenKind>),
|
||||||
/// Use the super selector: `&.red`
|
/// Use the super selector: `&.red`
|
||||||
Super,
|
Super,
|
||||||
|
/// Super selector in an interpolated context: `a #{&}`
|
||||||
|
InterpolatedSuper,
|
||||||
/// Used to signify no selector (when there is no super_selector of a rule)
|
/// Used to signify no selector (when there is no super_selector of a rule)
|
||||||
None,
|
None,
|
||||||
Whitespace,
|
Whitespace,
|
||||||
@ -109,7 +111,10 @@ impl Display for SelectorKind {
|
|||||||
s,
|
s,
|
||||||
toks.iter().map(ToString::to_string).collect::<String>()
|
toks.iter().map(ToString::to_string).collect::<String>()
|
||||||
),
|
),
|
||||||
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> {
|
struct SelectorParser<'a> {
|
||||||
scope: &'a Scope,
|
scope: &'a Scope,
|
||||||
selectors: Vec<SelectorKind>,
|
selectors: Vec<SelectorKind>,
|
||||||
|
is_interpolated: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> SelectorParser<'a> {
|
impl<'a> SelectorParser<'a> {
|
||||||
@ -172,6 +178,7 @@ impl<'a> SelectorParser<'a> {
|
|||||||
SelectorParser {
|
SelectorParser {
|
||||||
scope,
|
scope,
|
||||||
selectors: Vec::new(),
|
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::Plus) => self.selectors.push(SelectorKind::Following),
|
||||||
TokenKind::Symbol(Symbol::Tilde) => self.selectors.push(SelectorKind::Preceding),
|
TokenKind::Symbol(Symbol::Tilde) => self.selectors.push(SelectorKind::Preceding),
|
||||||
TokenKind::Symbol(Symbol::Mul) => self.selectors.push(SelectorKind::Universal),
|
TokenKind::Symbol(Symbol::Mul) => self.selectors.push(SelectorKind::Universal),
|
||||||
TokenKind::Symbol(Symbol::BitAnd) => self.selectors.push(SelectorKind::Super),
|
TokenKind::Symbol(Symbol::BitAnd) => self.selectors.push(if self.is_interpolated {
|
||||||
TokenKind::Interpolation => self.tokens_to_selectors(
|
SelectorKind::InterpolatedSuper
|
||||||
&mut eat_interpolation(tokens, self.scope).into_iter().peekable(),
|
} 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)),
|
TokenKind::Attribute(attr) => self.selectors.push(SelectorKind::Attribute(attr)),
|
||||||
_ => todo!("unimplemented selector"),
|
_ => todo!("unimplemented selector"),
|
||||||
};
|
};
|
||||||
@ -289,6 +305,8 @@ impl Selector {
|
|||||||
if sel == &SelectorKind::Super {
|
if sel == &SelectorKind::Super {
|
||||||
this_selector.extend(sel1.to_vec());
|
this_selector.extend(sel1.to_vec());
|
||||||
found_super = true;
|
found_super = true;
|
||||||
|
} else if sel == &SelectorKind::InterpolatedSuper {
|
||||||
|
this_selector.extend(sel1.to_vec());
|
||||||
} else {
|
} else {
|
||||||
this_selector.push(sel.clone());
|
this_selector.push(sel.clone());
|
||||||
}
|
}
|
||||||
|
@ -254,6 +254,16 @@ mod test_selectors {
|
|||||||
"$a: foo;\nab#{$a} {\n color: red;\n}\n",
|
"$a: foo;\nab#{$a} {\n color: red;\n}\n",
|
||||||
"abfoo {\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!(
|
test!(
|
||||||
selector_whitespace,
|
selector_whitespace,
|
||||||
" a > b , c ~ d e .f #g :h i.j [ k ] { color: red }",
|
" a > b , c ~ d e .f #g :h i.j [ k ] { color: red }",
|
||||||
|
Loading…
x
Reference in New Issue
Block a user