diff --git a/components/style/values/mod.rs b/components/style/values/mod.rs index 173312cb0b5..654dbcf7e6d 100644 --- a/components/style/values/mod.rs +++ b/components/style/values/mod.rs @@ -99,6 +99,14 @@ fn nan_inf_enabled() -> bool { return false; } +/// Serialize a number with calc, and NaN/infinity handling (if enabled) +pub fn serialize_number(v: f32, was_calc: bool, dest: &mut CssWriter) -> fmt::Result +where + W: Write, +{ + serialize_specified_dimension(v, "", was_calc, dest) +} + /// Serialize a specified dimension with unit, calc, and NaN/infinity handling (if enabled) pub fn serialize_specified_dimension( v: f32, @@ -120,11 +128,15 @@ where // requires an expression like calc(infinity * 1px)." if v.is_nan() { - dest.write_str("NaN * 1")?; + dest.write_str("NaN")?; } else if v == f32::INFINITY { - dest.write_str("infinity * 1")?; + dest.write_str("infinity")?; } else if v == f32::NEG_INFINITY { - dest.write_str("-infinity * 1")?; + dest.write_str("-infinity")?; + } + + if !unit.is_empty() { + dest.write_str(" * 1")?; } } else { v.to_css(dest)?; diff --git a/components/style/values/specified/calc.rs b/components/style/values/specified/calc.rs index 8abb26716be..b91e079f405 100644 --- a/components/style/values/specified/calc.rs +++ b/components/style/values/specified/calc.rs @@ -12,7 +12,7 @@ use crate::values::generics::calc::{MinMaxOp, ModRemOp, RoundingStrategy, SortKe use crate::values::specified::length::{AbsoluteLength, FontRelativeLength, NoCalcLength}; use crate::values::specified::length::{ContainerRelativeLength, ViewportPercentageLength}; use crate::values::specified::{self, Angle, Resolution, Time}; -use crate::values::{CSSFloat, CSSInteger}; +use crate::values::{serialize_number, serialize_percentage, CSSFloat, CSSInteger}; use cssparser::{AngleOrNumber, CowRcStr, NumberOrPercentage, Parser, Token}; use smallvec::SmallVec; use std::cmp; @@ -131,9 +131,9 @@ impl ToCss for Leaf { { match *self { Self::Length(ref l) => l.to_css(dest), - Self::Number(ref n) => n.to_css(dest), + Self::Number(n) => serialize_number(n, /* was_calc = */ false, dest), Self::Resolution(ref r) => r.to_css(dest), - Self::Percentage(p) => crate::values::serialize_percentage(p, dest), + Self::Percentage(p) => serialize_percentage(p, dest), Self::Angle(ref a) => a.to_css(dest), Self::Time(ref t) => t.to_css(dest), } @@ -887,10 +887,16 @@ impl CalcNode { /// Tries to simplify this expression into a `` value. fn to_number(&self) -> Result { - self.resolve(|leaf| match *leaf { + let number = self.resolve(|leaf| match *leaf { Leaf::Number(n) => Ok(n), _ => Err(()), - }) + })?; + let result = if nan_inf_enabled() { + number + } else { + crate::values::normalize(number) + }; + Ok(result) } /// Tries to simplify this expression into a `` value. @@ -992,7 +998,6 @@ impl CalcNode { ) -> Result> { Self::parse(context, input, function, CalcUnits::empty())? .to_number() - .map(crate::values::normalize) .map_err(|()| input.new_custom_error(StyleParseErrorKind::UnspecifiedError)) } diff --git a/components/style/values/specified/mod.rs b/components/style/values/specified/mod.rs index 27aa1a85c77..30627957fa6 100644 --- a/components/style/values/specified/mod.rs +++ b/components/style/values/specified/mod.rs @@ -16,8 +16,8 @@ use super::generics::{self, GreaterThanOrEqualToOne, NonNegative}; use super::{CSSFloat, CSSInteger}; use crate::context::QuirksMode; use crate::parser::{Parse, ParserContext}; -use crate::values::serialize_atom_identifier; use crate::values::specified::calc::CalcNode; +use crate::values::{serialize_atom_identifier, serialize_number}; use crate::{Atom, Namespace, One, Prefix, Zero}; use cssparser::{Parser, Token}; use std::fmt::{self, Write}; @@ -196,15 +196,15 @@ fn parse_number_with_clamping_mode<'i, 't>( match *input.next()? { Token::Number { value, .. } if clamping_mode.is_ok(context.parsing_mode, value) => { Ok(Number { - value: value.min(f32::MAX).max(f32::MIN), + value, calc_clamping_mode: None, }) }, Token::Function(ref name) => { let function = CalcNode::math_function(context, name, location)?; - let result = CalcNode::parse_number(context, input, function)?; + let value = CalcNode::parse_number(context, input, function)?; Ok(Number { - value: result.min(f32::MAX).max(f32::MIN), + value, calc_clamping_mode: Some(clamping_mode), }) }, @@ -264,8 +264,12 @@ impl Number { /// Returns the numeric value, clamped if needed. #[inline] pub fn get(&self) -> f32 { - self.calc_clamping_mode - .map_or(self.value, |mode| mode.clamp(self.value)) + crate::values::normalize( + self.calc_clamping_mode + .map_or(self.value, |mode| mode.clamp(self.value)), + ) + .min(f32::MAX) + .max(f32::MIN) } #[allow(missing_docs)] @@ -316,14 +320,7 @@ impl ToCss for Number { where W: Write, { - if self.calc_clamping_mode.is_some() { - dest.write_str("calc(")?; - } - self.value.to_css(dest)?; - if self.calc_clamping_mode.is_some() { - dest.write_char(')')?; - } - Ok(()) + serialize_number(self.value, self.calc_clamping_mode.is_some(), dest) } }