diff --git a/components/style/values/computed/length.rs b/components/style/values/computed/length.rs index 2cca9f71b78..0908273b88c 100644 --- a/components/style/values/computed/length.rs +++ b/components/style/values/computed/length.rs @@ -224,6 +224,12 @@ impl CSSPixelLength { CSSPixelLength(px) } + /// Returns a normalized (NaN turned to zero) version of this length. + #[inline] + pub fn normalized(self) -> Self { + Self::new(crate::values::normalize(self.0)) + } + /// Scale the length by a given amount. #[inline] pub fn scale_by(self, scale: CSSFloat) -> Self { diff --git a/components/style/values/computed/length_percentage.rs b/components/style/values/computed/length_percentage.rs index 1889481ad84..22fd9b5f8c3 100644 --- a/components/style/values/computed/length_percentage.rs +++ b/components/style/values/computed/length_percentage.rs @@ -263,10 +263,10 @@ impl LengthPercentage { CalcNode::Leaf(l) => { return match l { CalcLengthPercentageLeaf::Length(l) => { - Self::new_length(Length::new(clamping_mode.clamp(l.px()))) + Self::new_length(Length::new(clamping_mode.clamp(l.px())).normalized()) }, CalcLengthPercentageLeaf::Percentage(p) => { - Self::new_percent(Percentage(clamping_mode.clamp(p.0))) + Self::new_percent(Percentage(clamping_mode.clamp(crate::values::normalize(p.0)))) }, } }, @@ -378,7 +378,7 @@ impl LengthPercentage { pub fn resolve(&self, basis: Length) -> Length { match self.unpack() { Unpacked::Length(l) => l, - Unpacked::Percentage(p) => Length::new(basis.px() * p.0), + Unpacked::Percentage(p) => (basis * p.0).normalized(), Unpacked::Calc(ref c) => c.resolve(basis), } } @@ -707,7 +707,7 @@ impl CalcLengthPercentage { }) }) .unwrap(); - Length::new(self.clamping_mode.clamp(px)) + Length::new(self.clamping_mode.clamp(px)).normalized() } } diff --git a/components/style/values/mod.rs b/components/style/values/mod.rs index 6c088535d7f..9587b52648d 100644 --- a/components/style/values/mod.rs +++ b/components/style/values/mod.rs @@ -35,6 +35,17 @@ pub mod specified; /// A CSS float value. pub type CSSFloat = f32; +/// Normalizes a float value to zero after a set of operations that might turn +/// it into NaN. +#[inline] +pub fn normalize(v: CSSFloat) -> CSSFloat { + if v.is_nan() { + 0.0 + } else { + v + } +} + /// A CSS integer value. pub type CSSInteger = i32; diff --git a/components/style/values/specified/calc.rs b/components/style/values/specified/calc.rs index fa5415ee3b8..eb8b2fe4217 100644 --- a/components/style/values/specified/calc.rs +++ b/components/style/values/specified/calc.rs @@ -482,7 +482,7 @@ impl CalcNode { Leaf::Time(ref t) => Ok(t.seconds()), _ => Err(()), })?; - Ok(Time::from_calc(seconds)) + Ok(Time::from_calc(crate::values::normalize(seconds))) } /// Tries to simplify this expression into an `Angle` value. @@ -491,7 +491,7 @@ impl CalcNode { Leaf::Angle(ref angle) => Ok(angle.degrees()), _ => Err(()), })?; - Ok(Angle::from_calc(degrees)) + Ok(Angle::from_calc(crate::values::normalize(degrees))) } /// Tries to simplify this expression into a `` value. @@ -555,6 +555,7 @@ impl CalcNode { ) -> Result> { Self::parse(context, input, function, CalcUnit::Percentage)? .to_percentage() + .map(crate::values::normalize) .map_err(|()| input.new_custom_error(StyleParseErrorKind::UnspecifiedError)) } @@ -578,6 +579,7 @@ impl CalcNode { ) -> Result> { Self::parse(context, input, function, CalcUnit::Number)? .to_number() + .map(crate::values::normalize) .map_err(|()| input.new_custom_error(StyleParseErrorKind::UnspecifiedError)) }