interpolated ampersand in at-root
This commit is contained in:
parent
8802a92f9b
commit
26fdcfdf17
@ -15,7 +15,7 @@ pub(crate) use function::Function;
|
|||||||
pub(crate) use if_rule::If;
|
pub(crate) use if_rule::If;
|
||||||
pub(crate) use kind::AtRuleKind;
|
pub(crate) use kind::AtRuleKind;
|
||||||
pub(crate) use mixin::{eat_include, Mixin};
|
pub(crate) use mixin::{eat_include, Mixin};
|
||||||
use parse::eat_stmts;
|
use parse::{eat_stmts, eat_stmts_at_root};
|
||||||
use unknown::UnknownAtRule;
|
use unknown::UnknownAtRule;
|
||||||
|
|
||||||
mod for_rule;
|
mod for_rule;
|
||||||
@ -105,7 +105,7 @@ impl AtRule {
|
|||||||
AtRuleKind::Use => todo!("@use not yet implemented"),
|
AtRuleKind::Use => todo!("@use not yet implemented"),
|
||||||
AtRuleKind::Annotation => todo!("@annotation not yet implemented"),
|
AtRuleKind::Annotation => todo!("@annotation not yet implemented"),
|
||||||
AtRuleKind::AtRoot => {
|
AtRuleKind::AtRoot => {
|
||||||
let selector = &Selector::replace(
|
let mut selector = &Selector::replace(
|
||||||
super_selector.clone(),
|
super_selector.clone(),
|
||||||
Selector::from_tokens(
|
Selector::from_tokens(
|
||||||
&mut read_until_open_curly_brace(toks).into_iter().peekable(),
|
&mut read_until_open_curly_brace(toks).into_iter().peekable(),
|
||||||
@ -113,36 +113,33 @@ impl AtRule {
|
|||||||
super_selector,
|
super_selector,
|
||||||
)?,
|
)?,
|
||||||
);
|
);
|
||||||
|
let mut is_some = true;
|
||||||
|
if selector.is_empty() {
|
||||||
|
is_some = false;
|
||||||
|
selector = super_selector;
|
||||||
|
}
|
||||||
toks.next();
|
toks.next();
|
||||||
devour_whitespace(toks);
|
devour_whitespace(toks);
|
||||||
let mut body = read_until_closing_curly_brace(toks);
|
let mut body = read_until_closing_curly_brace(toks);
|
||||||
body.push(toks.next().unwrap());
|
body.push(toks.next().unwrap());
|
||||||
devour_whitespace(toks);
|
devour_whitespace(toks);
|
||||||
let mut styles = Vec::new();
|
let mut styles = Vec::new();
|
||||||
let raw_stmts = eat_stmts(&mut body.into_iter().peekable(), scope, &selector)?
|
let raw_stmts = eat_stmts_at_root(
|
||||||
.into_iter()
|
&mut body.into_iter().peekable(),
|
||||||
.filter_map(|s| match s {
|
scope,
|
||||||
Stmt::Style(..) => {
|
&selector,
|
||||||
styles.push(s);
|
0,
|
||||||
None
|
is_some,
|
||||||
}
|
)?
|
||||||
Stmt::RuleSet(RuleSet {
|
.into_iter()
|
||||||
selector: mut selector2,
|
.filter_map(|s| match s {
|
||||||
rules,
|
Stmt::Style(..) => {
|
||||||
super_selector: super_selector2,
|
styles.push(s);
|
||||||
}) => {
|
None
|
||||||
if selector.is_empty() {
|
}
|
||||||
selector2 = Selector::replace(super_selector.clone(), selector2);
|
_ => Some(s),
|
||||||
}
|
})
|
||||||
Some(Stmt::RuleSet(RuleSet {
|
.collect::<Vec<Stmt>>();
|
||||||
selector: selector2,
|
|
||||||
rules,
|
|
||||||
super_selector: super_selector2,
|
|
||||||
}))
|
|
||||||
}
|
|
||||||
_ => Some(s),
|
|
||||||
})
|
|
||||||
.collect::<Vec<Stmt>>();
|
|
||||||
let mut stmts = vec![Stmt::RuleSet(RuleSet {
|
let mut stmts = vec![Stmt::RuleSet(RuleSet {
|
||||||
selector: selector.clone(),
|
selector: selector.clone(),
|
||||||
rules: styles,
|
rules: styles,
|
||||||
|
@ -36,3 +36,48 @@ pub(crate) fn eat_stmts<I: Iterator<Item = Token>>(
|
|||||||
}
|
}
|
||||||
Ok(stmts)
|
Ok(stmts)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(crate) fn eat_stmts_at_root<I: Iterator<Item = Token>>(
|
||||||
|
toks: &mut Peekable<I>,
|
||||||
|
scope: &mut Scope,
|
||||||
|
super_selector: &Selector,
|
||||||
|
mut nesting: usize,
|
||||||
|
is_some: bool,
|
||||||
|
) -> SassResult<Vec<Stmt>> {
|
||||||
|
let mut stmts = Vec::new();
|
||||||
|
while let Some(expr) = eat_expr(toks, scope, super_selector)? {
|
||||||
|
match expr {
|
||||||
|
Expr::AtRule(a) => stmts.push(Stmt::AtRule(a)),
|
||||||
|
Expr::Style(s) => stmts.push(Stmt::Style(s)),
|
||||||
|
Expr::Styles(s) => stmts.extend(s.into_iter().map(Box::new).map(Stmt::Style)),
|
||||||
|
Expr::Include(s) => stmts.extend(s),
|
||||||
|
Expr::MixinDecl(..) | Expr::FunctionDecl(..) | Expr::Debug(..) | Expr::Warn(..) => {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
Expr::Selector(mut selector) => {
|
||||||
|
if nesting > 1 || is_some {
|
||||||
|
selector = super_selector.zip(&selector);
|
||||||
|
} else {
|
||||||
|
selector = Selector::replace(super_selector.clone(), selector);
|
||||||
|
}
|
||||||
|
nesting += 1;
|
||||||
|
let rules = eat_stmts_at_root(toks, scope, &selector, nesting, true)?;
|
||||||
|
nesting -= 1;
|
||||||
|
stmts.push(Stmt::RuleSet(RuleSet {
|
||||||
|
super_selector: if nesting > 1 {
|
||||||
|
super_selector.clone()
|
||||||
|
} else {
|
||||||
|
Selector::new()
|
||||||
|
},
|
||||||
|
selector,
|
||||||
|
rules,
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
Expr::VariableDecl(name, val) => {
|
||||||
|
scope.insert_var(&name, *val)?;
|
||||||
|
}
|
||||||
|
Expr::MultilineComment(s) => stmts.push(Stmt::MultilineComment(s)),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Ok(stmts)
|
||||||
|
}
|
||||||
|
@ -38,3 +38,28 @@ test!(
|
|||||||
"foo {\n @at-root {\n & {\n color: bar;\n }\n }\n}\n",
|
"foo {\n @at-root {\n & {\n color: bar;\n }\n }\n}\n",
|
||||||
"foo {\n color: bar;\n}\n"
|
"foo {\n color: bar;\n}\n"
|
||||||
);
|
);
|
||||||
|
test!(
|
||||||
|
interpolated_super_selector_with_nothing,
|
||||||
|
"test {\n @at-root {\n #{&}post {\n foo {\n bar: baz;\n }\n }\n }\n}\n",
|
||||||
|
"testpost foo {\n bar: baz;\n}\n"
|
||||||
|
);
|
||||||
|
test!(
|
||||||
|
with_ampersand_single,
|
||||||
|
"test {\n @at-root {\n #{&}post {\n foo {\n bar: baz;\n }\n }\n }\n}\n",
|
||||||
|
"testpost foo {\n bar: baz;\n}\n"
|
||||||
|
);
|
||||||
|
test!(
|
||||||
|
root_interpolated_ampersand,
|
||||||
|
"@at-root {\n #{&}post {\n foo {\n bar: baz;\n }\n }\n}\n",
|
||||||
|
"post foo {\n bar: baz;\n}\n"
|
||||||
|
);
|
||||||
|
test!(
|
||||||
|
nested_prefix_interpolated_ampersand,
|
||||||
|
"test {\n @at-root {\n pre#{&} {\n foo {\n bar: baz;\n }\n }\n }\n}\n",
|
||||||
|
"pretest foo {\n bar: baz;\n}\n"
|
||||||
|
);
|
||||||
|
test!(
|
||||||
|
nested_alone_interpolated_ampersand,
|
||||||
|
"test {\n @at-root {\n #{&} {\n foo {\n bar: baz;\n }\n }\n }\n}\n",
|
||||||
|
"test foo {\n bar: baz;\n}\n"
|
||||||
|
);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user