implement \@while
This commit is contained in:
parent
b71b11dccb
commit
e836ecb8ce
@ -40,6 +40,7 @@ pub(crate) enum AtRule {
|
|||||||
Unknown(UnknownAtRule),
|
Unknown(UnknownAtRule),
|
||||||
For(Vec<Stmt>),
|
For(Vec<Stmt>),
|
||||||
Each(Vec<Stmt>),
|
Each(Vec<Stmt>),
|
||||||
|
While(Vec<Stmt>),
|
||||||
If(If),
|
If(If),
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -312,7 +313,32 @@ impl AtRule {
|
|||||||
|
|
||||||
AtRule::For(stmts)
|
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::Keyframes => todo!("@keyframes not yet implemented"),
|
||||||
AtRuleKind::Unknown(name) => AtRule::Unknown(UnknownAtRule::from_tokens(
|
AtRuleKind::Unknown(name) => AtRule::Unknown(UnknownAtRule::from_tokens(
|
||||||
toks,
|
toks,
|
||||||
|
@ -382,7 +382,7 @@ impl<'a> StyleSheetParser<'a> {
|
|||||||
AtRule::Return(_) => {
|
AtRule::Return(_) => {
|
||||||
return Err("This at-rule is not allowed here.".into())
|
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::Content => return Err("@content is only allowed within mixin declarations.".into()),
|
||||||
AtRule::If(i) => {
|
AtRule::If(i) => {
|
||||||
rules.extend(i.eval(&mut Scope::new(), &Selector::new())?);
|
rules.extend(i.eval(&mut Scope::new(), &Selector::new())?);
|
||||||
@ -412,7 +412,7 @@ impl<'a> StyleSheetParser<'a> {
|
|||||||
match expr {
|
match expr {
|
||||||
Expr::Style(s) => stmts.push(Stmt::Style(s)),
|
Expr::Style(s) => stmts.push(Stmt::Style(s)),
|
||||||
Expr::AtRule(a) => match a {
|
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::If(i) => stmts.extend(i.eval(scope, super_selector)?),
|
||||||
AtRule::Content => {
|
AtRule::Content => {
|
||||||
return Err("@content is only allowed within mixin declarations.".into())
|
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))),
|
c @ AtRule::Content => Ok(Some(Expr::AtRule(c))),
|
||||||
f @ AtRule::If(..) => Ok(Some(Expr::AtRule(f))),
|
f @ AtRule::If(..) => Ok(Some(Expr::AtRule(f))),
|
||||||
f @ AtRule::For(..) => 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))),
|
f @ AtRule::Each(..) => Ok(Some(Expr::AtRule(f))),
|
||||||
u @ AtRule::Unknown(..) => Ok(Some(Expr::AtRule(u))),
|
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