style: Percentage values of translate are serialized as percent for computed values.

Basically, we rewrite the type of generics::transform::Translate and its
ToCss to match the spec. Besides, we always serialize Translate by servo,
so we could drop a lot of duplicated code.

Differential Revision: https://phabricator.services.mozilla.com/D11206
This commit is contained in:
Boris Chiou 2018-11-08 22:41:00 +00:00 committed by Emilio Cobos Álvarez
parent d9453bc0ea
commit c6ead1dc0e
No known key found for this signature in database
GPG key ID: 056B727BB9C1027C
7 changed files with 127 additions and 34 deletions

View file

@ -11,6 +11,7 @@ use crate::values::distance::{ComputeSquaredDistance, SquaredDistance};
use crate::values::generics::length::{
MaxLength as GenericMaxLength, MozLength as GenericMozLength,
};
use crate::values::generics::transform::IsZeroLength;
use crate::values::generics::NonNegative;
use crate::values::specified::length::ViewportPercentageLength;
use crate::values::specified::length::{AbsoluteLength, FontBaseSize, FontRelativeLength};
@ -496,6 +497,17 @@ impl ToComputedValue for specified::LengthOrPercentage {
}
}
impl IsZeroLength for LengthOrPercentage {
#[inline]
fn is_zero_length(&self) -> bool {
match *self {
LengthOrPercentage::Length(l) => l.0 == 0.0,
LengthOrPercentage::Percentage(p) => p.0 == 0.0,
LengthOrPercentage::Calc(c) => c.unclamped_length().0 == 0.0 && c.percentage() == 0.0,
}
}
}
#[allow(missing_docs)]
#[animate(fallback = "Self::animate_fallback")]
#[css(derive_debug)]

View file

@ -334,7 +334,6 @@ impl Translate {
pub fn to_transform_operation(&self) -> Option<TransformOperation> {
match *self {
generic::Translate::None => None,
generic::Translate::TranslateX(tx) => Some(generic::TransformOperation::TranslateX(tx)),
generic::Translate::Translate(tx, ty) => {
Some(generic::TransformOperation::Translate(tx, Some(ty)))
},
@ -347,7 +346,6 @@ impl Translate {
/// Convert Translate to TransformOperation.
pub fn from_transform_operation(operation: &TransformOperation) -> Translate {
match *operation {
generic::TransformOperation::TranslateX(tx) => generic::Translate::TranslateX(tx),
generic::TransformOperation::Translate(tx, Some(ty)) => {
generic::Translate::Translate(tx, ty)
},

View file

@ -610,7 +610,6 @@ impl<Number: ToCss + PartialEq> ToCss for Scale<Number> {
SpecifiedValueInfo,
ToAnimatedZero,
ToComputedValue,
ToCss,
)]
/// A value of the `Translate` property
///
@ -618,14 +617,56 @@ impl<Number: ToCss + PartialEq> ToCss for Scale<Number> {
pub enum Translate<LengthOrPercentage, Length> {
/// 'none'
None,
/// '<length-percentage>'
TranslateX(LengthOrPercentage),
/// '<length-percentage> <length-percentage>'
/// '<length-percentage>' or '<length-percentage> <length-percentage>'
Translate(LengthOrPercentage, LengthOrPercentage),
/// '<length-percentage> <length-percentage> <length>'
Translate3D(LengthOrPercentage, LengthOrPercentage, Length),
}
/// A trait to check if this is a zero length.
/// An alternative way is use num_traits::Zero. However, in order to implement num_traits::Zero,
/// we also have to implement Add, which may be complicated for LengthOrPercentage::Calc.
/// We could do this if other types also need it. If so, we could drop this trait.
pub trait IsZeroLength {
/// Returns true if this is a zero length.
fn is_zero_length(&self) -> bool;
}
impl<LoP: ToCss + IsZeroLength, L: ToCss> ToCss for Translate<LoP, L> {
fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result
where
W: fmt::Write,
{
// The spec says:
// 1. If a 2d translation is specified, the property must serialize with only one or two
// values (per usual, if the second value is 0px, the default, it must be omitted when
// serializing).
// 2. If a 3d translation is specified, all three values must be serialized.
// https://drafts.csswg.org/css-transforms-2/#individual-transform-serialization
//
// We don't omit the 3rd component even if it is 0px for now, and the related
// spec issue is https://github.com/w3c/csswg-drafts/issues/3305
match *self {
Translate::None => dest.write_str("none"),
Translate::Translate(ref x, ref y) => {
x.to_css(dest)?;
if !y.is_zero_length() {
dest.write_char(' ')?;
y.to_css(dest)?;
}
Ok(())
},
Translate::Translate3D(ref x, ref y, ref z) => {
x.to_css(dest)?;
dest.write_char(' ')?;
y.to_css(dest)?;
dest.write_char(' ')?;
z.to_css(dest)
},
}
}
}
#[allow(missing_docs)]
#[derive(
Clone, Copy, Debug, MallocSizeOf, Parse, PartialEq, SpecifiedValueInfo, ToComputedValue, ToCss,

View file

@ -14,6 +14,7 @@ use crate::values::computed::{self, CSSPixelLength, Context, ExtremumLength};
use crate::values::generics::length::{
MaxLength as GenericMaxLength, MozLength as GenericMozLength,
};
use values::generics::transform::IsZeroLength;
use crate::values::generics::NonNegative;
use crate::values::specified::calc::CalcNode;
use crate::values::{Auto, CSSFloat, Either, IsAuto, Normal};
@ -99,6 +100,16 @@ impl FontBaseSize {
}
impl FontRelativeLength {
/// Return true if this is a zero value.
fn is_zero(&self) -> bool {
match *self {
FontRelativeLength::Em(v) |
FontRelativeLength::Ex(v) |
FontRelativeLength::Ch(v) |
FontRelativeLength::Rem(v) => v == 0.0,
}
}
/// Computes the font-relative length.
pub fn to_computed_value(&self, context: &Context, base_size: FontBaseSize) -> CSSPixelLength {
use std::f32;
@ -232,6 +243,16 @@ pub enum ViewportPercentageLength {
}
impl ViewportPercentageLength {
/// Return true if this is a zero value.
fn is_zero(&self) -> bool {
match *self {
ViewportPercentageLength::Vw(v) |
ViewportPercentageLength::Vh(v) |
ViewportPercentageLength::Vmin(v) |
ViewportPercentageLength::Vmax(v) => v == 0.0,
}
}
/// Computes the given viewport-relative length for the given viewport size.
pub fn to_computed_value(&self, viewport_size: Size2D<Au>) -> CSSPixelLength {
let (factor, length) = match *self {
@ -487,6 +508,18 @@ impl NoCalcLength {
impl SpecifiedValueInfo for NoCalcLength {}
impl IsZeroLength for NoCalcLength {
#[inline]
fn is_zero_length(&self) -> bool {
match *self {
NoCalcLength::Absolute(v) => v.is_zero(),
NoCalcLength::FontRelative(v) => v.is_zero(),
NoCalcLength::ViewportPercentage(v) => v.is_zero(),
NoCalcLength::ServoCharacterWidth(v) => v.0 == 0,
}
}
}
/// An extension to `NoCalcLength` to parse `calc` expressions.
/// This is commonly used for the `<length>` values.
///
@ -841,6 +874,17 @@ impl LengthOrPercentage {
}
}
impl IsZeroLength for LengthOrPercentage {
#[inline]
fn is_zero_length(&self) -> bool {
match *self {
LengthOrPercentage::Length(l) => l.is_zero_length(),
LengthOrPercentage::Percentage(p) => p.0 == 0.0,
LengthOrPercentage::Calc(_) => false,
}
}
}
/// Either a `<length>`, a `<percentage>`, or the `auto` keyword.
#[allow(missing_docs)]
#[derive(Clone, Debug, MallocSizeOf, PartialEq, SpecifiedValueInfo, ToCss)]

View file

@ -395,7 +395,7 @@ impl Parse for Translate {
}
// 'translate: <length-percentage> '
Ok(generic::Translate::TranslateX(tx))
Ok(generic::Translate::Translate(tx, specified::LengthOrPercentage::zero()))
}
}