implement \@while
This commit is contained in:
parent
b71b11dccb
commit
e836ecb8ce
@ -40,6 +40,7 @@ pub(crate) enum AtRule {
|
||||
Unknown(UnknownAtRule),
|
||||
For(Vec<Stmt>),
|
||||
Each(Vec<Stmt>),
|
||||
While(Vec<Stmt>),
|
||||
If(If),
|
||||
}
|
||||
|
||||
@ -312,7 +313,32 @@ impl AtRule {
|
||||
|
||||
AtRule::For(stmts)
|
||||
}
|
||||
AtRuleKind::While => todo!("@while not yet implemented"),
|
||||
AtRuleKind::While => {
|
||||
let mut stmts = Vec::new();
|
||||
devour_whitespace(toks);
|
||||
let cond = read_until_open_curly_brace(toks);
|
||||
toks.next();
|
||||
let scope = &mut scope.clone();
|
||||
let body = read_until_closing_curly_brace(toks);
|
||||
toks.next();
|
||||
|
||||
devour_whitespace(toks);
|
||||
|
||||
while Value::from_tokens(
|
||||
&mut cond.clone().into_iter().peekable(),
|
||||
scope,
|
||||
super_selector,
|
||||
)?
|
||||
.is_true()?
|
||||
{
|
||||
stmts.extend(eat_stmts(
|
||||
&mut body.clone().into_iter().peekable(),
|
||||
scope,
|
||||
super_selector,
|
||||
)?);
|
||||
}
|
||||
AtRule::While(stmts)
|
||||
}
|
||||
AtRuleKind::Keyframes => todo!("@keyframes not yet implemented"),
|
||||
AtRuleKind::Unknown(name) => AtRule::Unknown(UnknownAtRule::from_tokens(
|
||||
toks,
|
||||
|
@ -382,7 +382,7 @@ impl<'a> StyleSheetParser<'a> {
|
||||
AtRule::Return(_) => {
|
||||
return Err("This at-rule is not allowed here.".into())
|
||||
}
|
||||
AtRule::Each(s) | AtRule::For(s) => rules.extend(s),
|
||||
AtRule::While(s) | AtRule::Each(s) | AtRule::For(s) => rules.extend(s),
|
||||
AtRule::Content => return Err("@content is only allowed within mixin declarations.".into()),
|
||||
AtRule::If(i) => {
|
||||
rules.extend(i.eval(&mut Scope::new(), &Selector::new())?);
|
||||
@ -412,7 +412,7 @@ impl<'a> StyleSheetParser<'a> {
|
||||
match expr {
|
||||
Expr::Style(s) => stmts.push(Stmt::Style(s)),
|
||||
Expr::AtRule(a) => match a {
|
||||
AtRule::Each(s) | AtRule::For(s) => stmts.extend(s),
|
||||
AtRule::While(s) | AtRule::Each(s) | AtRule::For(s) => stmts.extend(s),
|
||||
AtRule::If(i) => stmts.extend(i.eval(scope, super_selector)?),
|
||||
AtRule::Content => {
|
||||
return Err("@content is only allowed within mixin declarations.".into())
|
||||
@ -595,6 +595,7 @@ pub(crate) fn eat_expr<I: Iterator<Item = Token>>(
|
||||
c @ AtRule::Content => Ok(Some(Expr::AtRule(c))),
|
||||
f @ AtRule::If(..) => Ok(Some(Expr::AtRule(f))),
|
||||
f @ AtRule::For(..) => Ok(Some(Expr::AtRule(f))),
|
||||
f @ AtRule::While(..) => Ok(Some(Expr::AtRule(f))),
|
||||
f @ AtRule::Each(..) => Ok(Some(Expr::AtRule(f))),
|
||||
u @ AtRule::Unknown(..) => Ok(Some(Expr::AtRule(u))),
|
||||
};
|
||||
|
25
tests/while.rs
Normal file
25
tests/while.rs
Normal file
@ -0,0 +1,25 @@
|
||||
#![cfg(test)]
|
||||
|
||||
#[macro_use]
|
||||
mod macros;
|
||||
|
||||
test!(
|
||||
inner_increment_var,
|
||||
"$a: 4;\n$b: 1;\na {\n @while $a > $b {\n color: $b;\n $b: $b + 1;\n }\n}",
|
||||
"a {\n color: 1;\n color: 2;\n color: 3;\n}\n"
|
||||
);
|
||||
test!(
|
||||
outer_increment_var,
|
||||
"$a: 4;\n$b: 1;\n@while $a > $b {\na {\n color: $b;\n }\n $b: $b + 1;\n}",
|
||||
"a {\n color: 1;\n}\n\na {\n color: 2;\n}\n\na {\n color: 3;\n}\n"
|
||||
);
|
||||
test!(
|
||||
inner_while_false,
|
||||
"a {\n @while false {\n color: foo;\n }\n}",
|
||||
""
|
||||
);
|
||||
test!(
|
||||
outer_while_false,
|
||||
"@while false {\na {\n color: $b;\n }\n $b: $b + 1;\n}",
|
||||
""
|
||||
);
|
Loading…
x
Reference in New Issue
Block a user