diff --git a/components/style/values/computed/length.rs b/components/style/values/computed/length.rs index 10e1f211db3..42204de08f6 100644 --- a/components/style/values/computed/length.rs +++ b/components/style/values/computed/length.rs @@ -17,7 +17,7 @@ use values::generics::length::{MaxLength as GenericMaxLength, MozLength as Gener use values::generics::NonNegative; use values::specified::length::ViewportPercentageLength; use values::specified::length::{AbsoluteLength, FontBaseSize, FontRelativeLength}; -use values::{specified, Auto, CSSFloat, Either, Normal}; +use values::{specified, Auto, CSSFloat, Either, Normal, IsAuto}; pub use super::image::Image; pub use values::specified::url::UrlOrNone; @@ -528,6 +528,13 @@ impl LengthOrPercentageOrAuto { /// A wrapper of LengthOrPercentageOrAuto, whose value must be >= 0. pub type NonNegativeLengthOrPercentageOrAuto = NonNegative; +impl IsAuto for NonNegativeLengthOrPercentageOrAuto { + #[inline] + fn is_auto(&self) -> bool { + *self == Self::auto() + } +} + impl NonNegativeLengthOrPercentageOrAuto { /// `auto` #[inline] diff --git a/components/style/values/generics/background.rs b/components/style/values/generics/background.rs index a4f4c58d8cd..2f328eaa5e7 100644 --- a/components/style/values/generics/background.rs +++ b/components/style/values/generics/background.rs @@ -4,6 +4,10 @@ //! Generic types for CSS values related to backgrounds. +use std::fmt::{self, Write}; +use style_traits::{CssWriter, ToCss}; +use values::IsAuto; + /// A generic value for the `background-size` property. #[derive( Animate, @@ -17,7 +21,6 @@ ToAnimatedValue, ToAnimatedZero, ToComputedValue, - ToCss, )] pub enum BackgroundSize { /// ` ` @@ -34,3 +37,29 @@ pub enum BackgroundSize { #[animation(error)] Contain, } + +impl ToCss for BackgroundSize +where + LengthOrPercentageOrAuto: ToCss + IsAuto, +{ + fn to_css(&self, dest: &mut CssWriter) -> fmt::Result + where + W: Write, + { + match self { + BackgroundSize::Explicit { width, height } => { + width.to_css(dest)?; + // NOTE(emilio): We should probably simplify all these in case + // `width == `height`, but all other browsers agree on only + // special-casing `auto`. + if !width.is_auto() || !height.is_auto() { + dest.write_str(" ")?; + height.to_css(dest)?; + } + Ok(()) + } + BackgroundSize::Cover => dest.write_str("cover"), + BackgroundSize::Contain => dest.write_str("contain"), + } + } +} diff --git a/components/style/values/mod.rs b/components/style/values/mod.rs index f182477e374..079b579a988 100644 --- a/components/style/values/mod.rs +++ b/components/style/values/mod.rs @@ -243,6 +243,13 @@ impl KeyframesName { impl Eq for KeyframesName {} +/// A trait that returns whether a given type is the `auto` value or not. So far +/// only needed for background-size serialization, which special-cases `auto`. +pub trait IsAuto { + /// Returns whether the value is the `auto` value. + fn is_auto(&self) -> bool; +} + impl PartialEq for KeyframesName { fn eq(&self, other: &Self) -> bool { self.as_atom() == other.as_atom() diff --git a/components/style/values/specified/length.rs b/components/style/values/specified/length.rs index 05f5ccd55cd..be5bef27fb8 100644 --- a/components/style/values/specified/length.rs +++ b/components/style/values/specified/length.rs @@ -20,7 +20,7 @@ use values::computed::{self, CSSPixelLength, Context, ExtremumLength}; use values::generics::length::{MaxLength as GenericMaxLength, MozLength as GenericMozLength}; use values::generics::NonNegative; use values::specified::calc::CalcNode; -use values::{Auto, CSSFloat, Either, Normal}; +use values::{Auto, CSSFloat, Either, Normal, IsAuto}; pub use super::image::{ColorStop, EndingShape as GradientEndingShape, Gradient}; pub use super::image::{GradientKind, Image}; @@ -980,6 +980,13 @@ impl Parse for LengthOrPercentageOrAuto { /// A wrapper of LengthOrPercentageOrAuto, whose value must be >= 0. pub type NonNegativeLengthOrPercentageOrAuto = NonNegative; +impl IsAuto for NonNegativeLengthOrPercentageOrAuto { + #[inline] + fn is_auto(&self) -> bool { + *self == Self::auto() + } +} + impl NonNegativeLengthOrPercentageOrAuto { /// 0 #[inline]