properly parse plain css functions
This commit is contained in:
parent
9faaabebfa
commit
ce346077f9
20
src/args.rs
20
src/args.rs
@ -40,7 +40,7 @@ enum CallArg {
|
||||
impl CallArg {
|
||||
pub fn position(&self) -> SassResult<usize> {
|
||||
match self {
|
||||
Self::Named(..) => todo!(),
|
||||
Self::Named(..) => Err("found named".into()),
|
||||
Self::Positional(p) => Ok(*p),
|
||||
}
|
||||
}
|
||||
@ -58,6 +58,24 @@ impl CallArgs {
|
||||
CallArgs(HashMap::new())
|
||||
}
|
||||
|
||||
pub fn to_css_string(self, scope: &Scope, super_selector: &Selector) -> SassResult<String> {
|
||||
let mut string = String::with_capacity(2 + self.len() * 10);
|
||||
string.push('(');
|
||||
let args = match self.get_variadic(scope, super_selector) {
|
||||
Ok(v) => v,
|
||||
Err(..) => return Err("Plain CSS functions don't support keyword arguments.".into()),
|
||||
};
|
||||
string.push_str(
|
||||
&args
|
||||
.iter()
|
||||
.map(std::string::ToString::to_string)
|
||||
.collect::<Vec<String>>()
|
||||
.join(", "),
|
||||
);
|
||||
string.push(')');
|
||||
Ok(string)
|
||||
}
|
||||
|
||||
/// Get argument by name
|
||||
///
|
||||
/// Removes the argument
|
||||
|
@ -16,7 +16,7 @@ use crate::selector::Selector;
|
||||
use crate::unit::Unit;
|
||||
use crate::utils::{
|
||||
devour_whitespace, eat_comment, eat_ident, eat_ident_no_interpolation, eat_number,
|
||||
parse_interpolation, parse_quoted_string, read_until_char, read_until_closing_paren,
|
||||
parse_quoted_string, read_until_char, read_until_closing_paren,
|
||||
read_until_closing_square_brace, read_until_newline, IsWhitespace,
|
||||
};
|
||||
use crate::value::Value;
|
||||
@ -374,34 +374,10 @@ impl Value {
|
||||
)?))
|
||||
}
|
||||
None => {
|
||||
s.push('(');
|
||||
let mut unclosed_parens = 0;
|
||||
while let Some(t) = toks.next() {
|
||||
match &t.kind {
|
||||
'(' => {
|
||||
unclosed_parens += 1;
|
||||
}
|
||||
'#' if toks.next().unwrap().kind == '{' => s.push_str(
|
||||
&parse_interpolation(toks, scope, super_selector)?
|
||||
.to_string(),
|
||||
),
|
||||
'$' => s.push_str(
|
||||
&scope
|
||||
.get_var(&eat_ident(toks, scope, super_selector)?)?
|
||||
.to_string(),
|
||||
),
|
||||
')' => {
|
||||
if unclosed_parens <= 1 {
|
||||
s.push(')');
|
||||
break;
|
||||
} else {
|
||||
unclosed_parens -= 1;
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
s.push_str(&t.kind.to_string());
|
||||
}
|
||||
s.push_str(
|
||||
&eat_call_args(toks, scope, super_selector)?
|
||||
.to_css_string(scope, super_selector)?,
|
||||
);
|
||||
return Ok(IntermediateValue::Value(Value::Ident(s, QuoteKind::None)));
|
||||
}
|
||||
},
|
||||
|
45
tests/plain-css-fn.rs
Normal file
45
tests/plain-css-fn.rs
Normal file
@ -0,0 +1,45 @@
|
||||
#![cfg(test)]
|
||||
|
||||
#[macro_use]
|
||||
mod macros;
|
||||
|
||||
test!(
|
||||
type_is_string,
|
||||
"a {\n color: type-of(foo(1+1));\n}\n",
|
||||
"a {\n color: string;\n}\n"
|
||||
);
|
||||
test!(
|
||||
evaluates_arguments,
|
||||
"a {\n color: foo(1+1);\n}\n",
|
||||
"a {\n color: foo(2);\n}\n"
|
||||
);
|
||||
test!(
|
||||
arguments_are_comma_separated,
|
||||
"a {\n color: foo(1+1, 2+3, 4+5);\n}\n",
|
||||
"a {\n color: foo(2, 5, 9);\n}\n"
|
||||
);
|
||||
test!(
|
||||
converts_sql_quotes,
|
||||
"a {\n color: foo('hi');\n}\n",
|
||||
"a {\n color: foo(\"hi\");\n}\n"
|
||||
);
|
||||
test!(
|
||||
super_selector,
|
||||
"a {\n color: foo(&);\n}\n",
|
||||
"a {\n color: foo(a);\n}\n"
|
||||
);
|
||||
test!(
|
||||
nested_plain_css_fn,
|
||||
"a {\n color: foo(foo(foo(foo(1+1))));\n}\n",
|
||||
"a {\n color: foo(foo(foo(foo(2))));\n}\n"
|
||||
);
|
||||
error!(
|
||||
disallows_named_arguments,
|
||||
"a {\n color: foo($a: 1+1);\n}\n",
|
||||
"Error: Plain CSS functions don't support keyword arguments."
|
||||
);
|
||||
test!(
|
||||
evalutes_variables,
|
||||
"a {\n $primary: #f2ece4;\n $accent: #e1d7d2;\n color: radial-gradient($primary, $accent);\n}\n",
|
||||
"a {\n color: radial-gradient(#f2ece4, #e1d7d2);\n}\n"
|
||||
);
|
Loading…
x
Reference in New Issue
Block a user