style: Normalize NaN to zero as a result of calc().

Differential Revision: https://phabricator.services.mozilla.com/D104563
This commit is contained in:
Emilio Cobos Álvarez 2021-02-10 15:30:40 +00:00
parent 20f5e14bf8
commit db03b2cf8e
4 changed files with 25 additions and 6 deletions

View file

@ -224,6 +224,12 @@ impl CSSPixelLength {
CSSPixelLength(px) 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. /// Scale the length by a given amount.
#[inline] #[inline]
pub fn scale_by(self, scale: CSSFloat) -> Self { pub fn scale_by(self, scale: CSSFloat) -> Self {

View file

@ -263,10 +263,10 @@ impl LengthPercentage {
CalcNode::Leaf(l) => { CalcNode::Leaf(l) => {
return match l { return match l {
CalcLengthPercentageLeaf::Length(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) => { 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 { pub fn resolve(&self, basis: Length) -> Length {
match self.unpack() { match self.unpack() {
Unpacked::Length(l) => l, 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), Unpacked::Calc(ref c) => c.resolve(basis),
} }
} }
@ -707,7 +707,7 @@ impl CalcLengthPercentage {
}) })
}) })
.unwrap(); .unwrap();
Length::new(self.clamping_mode.clamp(px)) Length::new(self.clamping_mode.clamp(px)).normalized()
} }
} }

View file

@ -35,6 +35,17 @@ pub mod specified;
/// A CSS float value. /// A CSS float value.
pub type CSSFloat = f32; 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. /// A CSS integer value.
pub type CSSInteger = i32; pub type CSSInteger = i32;

View file

@ -482,7 +482,7 @@ impl CalcNode {
Leaf::Time(ref t) => Ok(t.seconds()), Leaf::Time(ref t) => Ok(t.seconds()),
_ => Err(()), _ => Err(()),
})?; })?;
Ok(Time::from_calc(seconds)) Ok(Time::from_calc(crate::values::normalize(seconds)))
} }
/// Tries to simplify this expression into an `Angle` value. /// Tries to simplify this expression into an `Angle` value.
@ -491,7 +491,7 @@ impl CalcNode {
Leaf::Angle(ref angle) => Ok(angle.degrees()), Leaf::Angle(ref angle) => Ok(angle.degrees()),
_ => Err(()), _ => Err(()),
})?; })?;
Ok(Angle::from_calc(degrees)) Ok(Angle::from_calc(crate::values::normalize(degrees)))
} }
/// Tries to simplify this expression into a `<number>` value. /// Tries to simplify this expression into a `<number>` value.
@ -555,6 +555,7 @@ impl CalcNode {
) -> Result<CSSFloat, ParseError<'i>> { ) -> Result<CSSFloat, ParseError<'i>> {
Self::parse(context, input, function, CalcUnit::Percentage)? Self::parse(context, input, function, CalcUnit::Percentage)?
.to_percentage() .to_percentage()
.map(crate::values::normalize)
.map_err(|()| input.new_custom_error(StyleParseErrorKind::UnspecifiedError)) .map_err(|()| input.new_custom_error(StyleParseErrorKind::UnspecifiedError))
} }
@ -578,6 +579,7 @@ impl CalcNode {
) -> Result<CSSFloat, ParseError<'i>> { ) -> Result<CSSFloat, ParseError<'i>> {
Self::parse(context, input, function, CalcUnit::Number)? Self::parse(context, input, function, CalcUnit::Number)?
.to_number() .to_number()
.map(crate::values::normalize)
.map_err(|()| input.new_custom_error(StyleParseErrorKind::UnspecifiedError)) .map_err(|()| input.new_custom_error(StyleParseErrorKind::UnspecifiedError))
} }