style: Serialize NaN and infinity percentages correctly

NaN and infinity percentages are now serialized as expected.

Also added some new WPT tests as percentages were previously untested
and added some spec comments to previous NaN/inf serialization code.

Differential Revision: https://phabricator.services.mozilla.com/D176726
This commit is contained in:
CanadaHonk 2023-05-01 14:50:32 +00:00 committed by Martin Robinson
parent d44f772dc3
commit 2e713d4366
3 changed files with 18 additions and 5 deletions

View file

@ -7,7 +7,7 @@
use crate::values::animated::ToAnimatedValue; use crate::values::animated::ToAnimatedValue;
use crate::values::generics::NonNegative; use crate::values::generics::NonNegative;
use crate::values::specified::percentage::ToPercentage; use crate::values::specified::percentage::ToPercentage;
use crate::values::{serialize_percentage, CSSFloat}; use crate::values::{serialize_normalized_percentage, CSSFloat};
use crate::Zero; use crate::Zero;
use std::fmt; use std::fmt;
use style_traits::{CssWriter, ToCss}; use style_traits::{CssWriter, ToCss};
@ -106,7 +106,7 @@ impl ToCss for Percentage {
where where
W: fmt::Write, W: fmt::Write,
{ {
serialize_percentage(self.0, dest) serialize_normalized_percentage(self.0, dest)
} }
} }

View file

@ -109,6 +109,11 @@ where
} }
if !v.is_finite() && nan_inf_enabled() { if !v.is_finite() && nan_inf_enabled() {
// https://drafts.csswg.org/css-values/#calc-error-constants:
// "While not technically numbers, these keywords act as numeric values,
// similar to e and pi. Thus to get an infinite length, for example,
// requires an expression like calc(infinity * 1px)."
if v.is_nan() { if v.is_nan() {
dest.write_str("NaN * 1")?; dest.write_str("NaN * 1")?;
} else if v == f32::INFINITY { } else if v == f32::INFINITY {
@ -398,8 +403,16 @@ impl std::borrow::Borrow<crate::gecko_string_cache::WeakAtom> for AtomIdent {
} }
} }
/// Serialize a normalized value into percentage. /// Serialize a value into percentage.
pub fn serialize_percentage<W>(value: CSSFloat, dest: &mut CssWriter<W>) -> fmt::Result pub fn serialize_percentage<W>(value: CSSFloat, dest: &mut CssWriter<W>) -> fmt::Result
where
W: Write,
{
serialize_specified_dimension(value * 100., "%", /* was_calc = */ false, dest)
}
/// Serialize a value into normalized (no NaN/inf serialization) percentage.
pub fn serialize_normalized_percentage<W>(value: CSSFloat, dest: &mut CssWriter<W>) -> fmt::Result
where where
W: Write, W: Write,
{ {

View file

@ -10,7 +10,7 @@ use crate::values::computed::{Context, ToComputedValue};
use crate::values::generics::NonNegative; use crate::values::generics::NonNegative;
use crate::values::specified::calc::CalcNode; use crate::values::specified::calc::CalcNode;
use crate::values::specified::Number; use crate::values::specified::Number;
use crate::values::{serialize_percentage, CSSFloat}; use crate::values::{serialize_percentage, normalize, CSSFloat};
use cssparser::{Parser, Token}; use cssparser::{Parser, Token};
use std::fmt::{self, Write}; use std::fmt::{self, Write};
use style_traits::values::specified::AllowedNumericType; use style_traits::values::specified::AllowedNumericType;
@ -172,7 +172,7 @@ impl ToComputedValue for Percentage {
#[inline] #[inline]
fn to_computed_value(&self, _: &Context) -> Self::ComputedValue { fn to_computed_value(&self, _: &Context) -> Self::ComputedValue {
ComputedPercentage(self.get()) ComputedPercentage(normalize(self.get()))
} }
#[inline] #[inline]