--- a/servo/components/style/values/specified/calc.rs
+++ b/servo/components/style/values/specified/calc.rs
@@ -26,16 +26,18 @@ pub enum MathFunction {
/// `calc()`: https://drafts.csswg.org/css-values-4/#funcdef-calc
Calc,
/// `min()`: https://drafts.csswg.org/css-values-4/#funcdef-min
Min,
/// `max()`: https://drafts.csswg.org/css-values-4/#funcdef-max
Max,
/// `clamp()`: https://drafts.csswg.org/css-values-4/#funcdef-clamp
Clamp,
+ /// `switch()`: no spec yet.
+ Switch,
}
/// A leaf node inside a `Calc` expression's AST.
#[derive(Clone, Debug, MallocSizeOf, PartialEq, ToShmem)]
pub enum Leaf {
/// `<length>`
Length(NoCalcLength),
/// `<angle>`
@@ -340,16 +342,35 @@ impl CalcNode {
let op = match function {
MathFunction::Min => MinMaxOp::Min,
MathFunction::Max => MinMaxOp::Max,
_ => unreachable!(),
};
Ok(Self::MinMax(arguments.into(), op))
},
+ MathFunction::Switch => {
+ let index = match Self::parse_argument(context, input, CalcUnit::Number)?.to_number() {
+ Ok(n) => n,
+ Err(()) => return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError)),
+ };
+
+ input.expect_semicolon()?;
+
+ let mut arguments = input.parse_comma_separated(|input| {
+ Self::parse_argument(context, input, expected_unit)
+ })?;
+
+ let index = std::cmp::max(index.round() as i32, 0) as usize;
+ Ok(if index < arguments.len() {
+ arguments.remove(index)
+ } else {
+ arguments.pop().unwrap()
+ })
+ },
}
})
}
fn parse_argument<'i, 't>(
context: &ParserContext,
input: &mut Parser<'i, 't>,
expected_unit: CalcUnit,
@@ -535,16 +556,17 @@ impl CalcNode {
if !comparison_functions_enabled() {
return Err(location.new_unexpected_token_error(Token::Function(name.clone())));
}
Ok(match_ignore_ascii_case! { &*name,
"min" => MathFunction::Min,
"max" => MathFunction::Max,
"clamp" => MathFunction::Clamp,
+ "switch" => MathFunction::Switch,
_ => return Err(location.new_unexpected_token_error(Token::Function(name.clone()))),
})
}
/// Convenience parsing function for integers.
pub fn parse_integer<'i, 't>(
context: &ParserContext,
input: &mut Parser<'i, 't>,