mirror of
https://github.com/servo/servo.git
synced 2025-08-05 05:30:08 +01:00
style: Serialize NaN and infinity angles as per spec
`NaN`, `infinity`, and `-infinity` angles should be specially serialized. Also fixed a few relevant WPT tests which did not follow spec. (see https://github.com/web-platform-tests/wpt/pull/38825) Adjusted WPT test expectations, 40 newly pass 🎉 Differential Revision: https://phabricator.services.mozilla.com/D171658
This commit is contained in:
parent
7b28572309
commit
a8fef9d4f2
3 changed files with 66 additions and 16 deletions
|
@ -92,6 +92,39 @@ where
|
|||
serialize_name(&ident, dest)
|
||||
}
|
||||
|
||||
fn nan_inf_enabled() -> bool {
|
||||
static_prefs::pref!("layout.css.nan-inf.enabled")
|
||||
}
|
||||
|
||||
/// Serialize a specified dimension with unit, calc, and NaN/infinity handling (if enabled)
|
||||
pub fn serialize_specified_dimension<W>(v: f32, unit: &str, was_calc: bool, dest: &mut CssWriter<W>) -> fmt::Result
|
||||
where
|
||||
W: Write,
|
||||
{
|
||||
if was_calc {
|
||||
dest.write_str("calc(")?;
|
||||
}
|
||||
|
||||
if !v.is_finite() && nan_inf_enabled() {
|
||||
if v.is_nan() {
|
||||
dest.write_str("NaN * 1")?;
|
||||
} else if v == f32::INFINITY {
|
||||
dest.write_str("infinity * 1")?;
|
||||
} else if v == f32::NEG_INFINITY {
|
||||
dest.write_str("-infinity * 1")?;
|
||||
}
|
||||
} else {
|
||||
v.to_css(dest)?;
|
||||
}
|
||||
|
||||
dest.write_str(unit)?;
|
||||
|
||||
if was_calc {
|
||||
dest.write_char(')')?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// A CSS string stored as an `Atom`.
|
||||
#[repr(transparent)]
|
||||
#[derive(
|
||||
|
|
|
@ -39,12 +39,7 @@ impl Zero for AngleDimension {
|
|||
}
|
||||
|
||||
fn is_zero(&self) -> bool {
|
||||
match *self {
|
||||
AngleDimension::Deg(ref f) |
|
||||
AngleDimension::Grad(ref f) |
|
||||
AngleDimension::Rad(ref f) |
|
||||
AngleDimension::Turn(ref f) => *f == 0.,
|
||||
}
|
||||
self.unitless_value() == 0.0
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -63,6 +58,24 @@ impl AngleDimension {
|
|||
AngleDimension::Grad(gradians) => gradians * DEG_PER_GRAD,
|
||||
}
|
||||
}
|
||||
|
||||
fn unitless_value(&self) -> CSSFloat {
|
||||
match *self {
|
||||
AngleDimension::Deg(v) |
|
||||
AngleDimension::Rad(v) |
|
||||
AngleDimension::Turn(v) |
|
||||
AngleDimension::Grad(v) => v,
|
||||
}
|
||||
}
|
||||
|
||||
fn unit(&self) -> &'static str {
|
||||
match *self {
|
||||
AngleDimension::Deg(_) => "deg",
|
||||
AngleDimension::Rad(_) => "rad",
|
||||
AngleDimension::Turn(_) => "turn",
|
||||
AngleDimension::Grad(_) => "grad"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// A specified Angle value, which is just the angle dimension, plus whether it
|
||||
|
@ -92,14 +105,7 @@ impl ToCss for Angle {
|
|||
where
|
||||
W: Write,
|
||||
{
|
||||
if self.was_calc {
|
||||
dest.write_str("calc(")?;
|
||||
}
|
||||
self.value.to_css(dest)?;
|
||||
if self.was_calc {
|
||||
dest.write_char(')')?;
|
||||
}
|
||||
Ok(())
|
||||
crate::values::serialize_specified_dimension(self.value.unitless_value(), self.value.unit(), self.was_calc, dest)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -108,7 +114,7 @@ impl ToComputedValue for Angle {
|
|||
|
||||
#[inline]
|
||||
fn to_computed_value(&self, _context: &Context) -> Self::ComputedValue {
|
||||
ComputedAngle::from_degrees(self.degrees())
|
||||
ComputedAngle::from_degrees(crate::values::normalize(self.degrees()))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
|
@ -170,6 +176,12 @@ impl Angle {
|
|||
was_calc: true,
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the unit of the angle.
|
||||
#[inline]
|
||||
pub fn unit(&self) -> &'static str {
|
||||
self.value.unit()
|
||||
}
|
||||
}
|
||||
|
||||
/// Whether to allow parsing an unitless zero as a valid angle.
|
||||
|
|
|
@ -836,7 +836,12 @@ impl CalcNode {
|
|||
Leaf::Angle(ref angle) => Ok(angle.degrees()),
|
||||
_ => Err(()),
|
||||
})?;
|
||||
Ok(Angle::from_calc(crate::values::normalize(degrees)))
|
||||
let result = Angle::from_calc(if nan_inf_enabled() {
|
||||
degrees
|
||||
} else {
|
||||
crate::values::normalize(degrees)
|
||||
});
|
||||
Ok(result)
|
||||
}
|
||||
|
||||
/// Tries to simplify this expression into a `<number>` value.
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue