aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAnthony Ramine <n.oxyde@gmail.com>2017-06-07 14:53:31 +0200
committerAnthony Ramine <n.oxyde@gmail.com>2017-06-07 16:47:59 +0200
commit45e8b0e8c7a7958c688fbbfcdd056592a9958ca5 (patch)
tree61d0a4e0001dd24300a974e8a7d13f160b69d1eb
parent7d09ce0495caba59848140b4c3e771c88a2f20bc (diff)
downloadservo-45e8b0e8c7a7958c688fbbfcdd056592a9958ca5.tar.gz
servo-45e8b0e8c7a7958c688fbbfcdd056592a9958ca5.zip
Support unit variants when deriving ToCss
-rw-r--r--components/style/properties/longhand/box.mako.rs13
-rw-r--r--components/style/properties/longhand/font.mako.rs29
-rw-r--r--components/style/properties/properties.mako.rs18
-rw-r--r--components/style/values/generics/background.rs23
-rw-r--r--components/style/values/generics/basic_shape.rs13
-rw-r--r--components/style/values/generics/border.rs16
-rw-r--r--components/style/values/generics/grid.rs12
-rw-r--r--components/style/values/generics/mod.rs25
-rw-r--r--components/style/values/generics/text.rs33
-rw-r--r--components/style/values/specified/border.rs15
-rw-r--r--components/style/values/specified/length.rs41
-rw-r--r--components/style/values/specified/transform.rs18
-rw-r--r--components/style_derive/to_css.rs46
-rw-r--r--components/style_traits/values.rs11
14 files changed, 71 insertions, 242 deletions
diff --git a/components/style/properties/longhand/box.mako.rs b/components/style/properties/longhand/box.mako.rs
index 623810c8724..59c1e669aea 100644
--- a/components/style/properties/longhand/box.mako.rs
+++ b/components/style/properties/longhand/box.mako.rs
@@ -545,8 +545,6 @@ ${helpers.predefined_type("animation-timing-function",
extra_prefixes="moz webkit"
spec="https://drafts.csswg.org/css-animations/#propdef-animation-iteration-count",
allowed_in_keyframe_block="False">
- use std::fmt;
- use style_traits::ToCss;
use values::computed::ComputedValueAsSpecified;
pub mod computed_value {
@@ -554,8 +552,8 @@ ${helpers.predefined_type("animation-timing-function",
}
// https://drafts.csswg.org/css-animations/#animation-iteration-count
- #[derive(Debug, Clone, PartialEq)]
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
+ #[derive(Debug, Clone, PartialEq, ToCss)]
pub enum SpecifiedValue {
Number(f32),
Infinite,
@@ -576,15 +574,6 @@ ${helpers.predefined_type("animation-timing-function",
}
}
- impl ToCss for SpecifiedValue {
- fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
- match *self {
- SpecifiedValue::Number(n) => write!(dest, "{}", n),
- SpecifiedValue::Infinite => dest.write_str("infinite"),
- }
- }
- }
-
no_viewport_percentage!(SpecifiedValue);
#[inline]
diff --git a/components/style/properties/longhand/font.mako.rs b/components/style/properties/longhand/font.mako.rs
index 2c491a1630a..51963a7dbb0 100644
--- a/components/style/properties/longhand/font.mako.rs
+++ b/components/style/properties/longhand/font.mako.rs
@@ -1039,28 +1039,15 @@ ${helpers.single_keyword_system("font-variant-caps",
pub mod computed_value {
use properties::animated_properties::Animatable;
- use std::fmt;
- use style_traits::ToCss;
use values::CSSFloat;
- #[derive(Copy, Clone, Debug, PartialEq)]
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
+ #[derive(Copy, Clone, Debug, PartialEq, ToCss)]
pub enum T {
None,
Number(CSSFloat),
}
- impl ToCss for T {
- fn to_css<W>(&self, dest: &mut W) -> fmt::Result
- where W: fmt::Write,
- {
- match *self {
- T::None => dest.write_str("none"),
- T::Number(number) => number.to_css(dest),
- }
- }
- }
-
impl T {
pub fn from_gecko_adjust(gecko: f32) -> Self {
if gecko == -1.0 {
@@ -2214,9 +2201,7 @@ ${helpers.single_keyword("-moz-math-variant",
use app_units::Au;
use cssparser::Parser;
use properties::longhands;
- use std::fmt;
use std::hash::{Hash, Hasher};
- use style_traits::ToCss;
use values::computed::{ToComputedValue, Context};
<%
system_fonts = """caption icon menu message-box small-caption status-bar
@@ -2230,23 +2215,13 @@ ${helpers.single_keyword("-moz-math-variant",
kw_cast = """font_style font_variant_caps font_stretch
font_kerning font_variant_position""".split()
%>
- #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
+ #[derive(Clone, Copy, Debug, Eq, Hash, PartialEq, ToCss)]
pub enum SystemFont {
% for font in system_fonts:
${to_camel_case(font)},
% endfor
}
- impl ToCss for SystemFont {
- fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
- dest.write_str(match *self {
- % for font in system_fonts:
- SystemFont::${to_camel_case(font)} => "${font}",
- % endfor
- })
- }
- }
-
// ComputedValues are compared at times
// so we need these impls. We don't want to
// add Eq to Number (which contains a float)
diff --git a/components/style/properties/properties.mako.rs b/components/style/properties/properties.mako.rs
index 4114b2f2b22..7c0ea1e9abb 100644
--- a/components/style/properties/properties.mako.rs
+++ b/components/style/properties/properties.mako.rs
@@ -450,8 +450,8 @@ impl PropertyDeclarationIdSet {
% endfor
/// An enum to represent a CSS Wide keyword.
-#[derive(Copy, Clone, PartialEq, Eq, Debug)]
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
+#[derive(Copy, Clone, Debug, Eq, PartialEq, ToCss)]
pub enum CSSWideKeyword {
/// The `initial` keyword.
Initial,
@@ -483,12 +483,6 @@ impl CSSWideKeyword {
}
}
-impl ToCss for CSSWideKeyword {
- fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
- dest.write_str(self.to_str())
- }
-}
-
impl Parse for CSSWideKeyword {
fn parse(_context: &ParserContext, input: &mut Parser) -> Result<Self, ()> {
let ident = input.expect_ident()?;
@@ -628,8 +622,8 @@ impl LonghandId {
}
/// An identifier for a given shorthand property.
-#[derive(Clone, Copy, Eq, PartialEq, Debug)]
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
+#[derive(Clone, Copy, Debug, Eq, PartialEq, ToCss)]
pub enum ShorthandId {
% for property in data.shorthands:
/// ${property.name}
@@ -637,14 +631,6 @@ pub enum ShorthandId {
% endfor
}
-impl ToCss for ShorthandId {
- fn to_css<W>(&self, dest: &mut W) -> fmt::Result
- where W: fmt::Write,
- {
- dest.write_str(self.name())
- }
-}
-
impl ShorthandId {
/// Get the name for this shorthand property.
pub fn name(&self) -> &'static str {
diff --git a/components/style/values/generics/background.rs b/components/style/values/generics/background.rs
index af8cef23a38..aa24454ef6d 100644
--- a/components/style/values/generics/background.rs
+++ b/components/style/values/generics/background.rs
@@ -4,11 +4,8 @@
//! Generic types for CSS values related to backgrounds.
-use std::fmt;
-use style_traits::ToCss;
-
/// A generic value for the `background-size` property.
-#[derive(Clone, Copy, Debug, HasViewportPercentage, PartialEq, ToComputedValue)]
+#[derive(Clone, Copy, Debug, HasViewportPercentage, PartialEq, ToComputedValue, ToCss)]
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
pub enum BackgroundSize<LengthOrPercentageOrAuto> {
/// `<width> <height>`
@@ -32,21 +29,3 @@ impl<L> From<L> for BackgroundSize<L>
BackgroundSize::Explicit { width: value.clone(), height: value }
}
}
-
-impl<L> ToCss for BackgroundSize<L>
- where L: ToCss
-{
- fn to_css<W>(&self, dest: &mut W) -> fmt::Result
- where W: fmt::Write
- {
- match *self {
- BackgroundSize::Explicit { ref width, ref height } => {
- width.to_css(dest)?;
- dest.write_str(" ")?;
- height.to_css(dest)
- },
- BackgroundSize::Cover => dest.write_str("cover"),
- BackgroundSize::Contain => dest.write_str("contain"),
- }
- }
-}
diff --git a/components/style/values/generics/basic_shape.rs b/components/style/values/generics/basic_shape.rs
index b2d402dd38f..cd8e315f3b3 100644
--- a/components/style/values/generics/basic_shape.rs
+++ b/components/style/values/generics/basic_shape.rs
@@ -19,7 +19,7 @@ pub type ClippingShape<BasicShape> = ShapeSource<BasicShape, GeometryBox>;
/// https://drafts.fxtf.org/css-masking-1/#typedef-geometry-box
#[allow(missing_docs)]
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
-#[derive(Clone, Copy, Debug, PartialEq)]
+#[derive(Clone, Copy, Debug, PartialEq, ToCss)]
pub enum GeometryBox {
FillBox,
StrokeBox,
@@ -142,17 +142,6 @@ impl<B: ToCss, T: ToCss> ToCss for ShapeSource<B, T> {
}
}
-impl ToCss for GeometryBox {
- fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
- match *self {
- GeometryBox::FillBox => dest.write_str("fill-box"),
- GeometryBox::StrokeBox => dest.write_str("stroke-box"),
- GeometryBox::ViewBox => dest.write_str("view-box"),
- GeometryBox::ShapeBox(s) => s.to_css(dest),
- }
- }
-}
-
impl<L> ToCss for InsetRect<L>
where L: ToCss + PartialEq
{
diff --git a/components/style/values/generics/border.rs b/components/style/values/generics/border.rs
index f1384e580e3..5d8c9032e6a 100644
--- a/components/style/values/generics/border.rs
+++ b/components/style/values/generics/border.rs
@@ -11,7 +11,7 @@ use values::generics::rect::Rect;
/// A generic value for a single side of a `border-image-width` property.
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
-#[derive(Clone, Copy, Debug, HasViewportPercentage, PartialEq, ToComputedValue)]
+#[derive(Clone, Copy, Debug, HasViewportPercentage, PartialEq, ToComputedValue, ToCss)]
pub enum BorderImageSideWidth<LengthOrPercentage, Number> {
/// `<length-or-percentage>`
Length(LengthOrPercentage),
@@ -52,20 +52,6 @@ pub struct BorderRadius<LengthOrPercentage> {
/// A generic value for `border-*-radius` longhand properties.
pub struct BorderCornerRadius<L>(pub Size2D<L>);
-impl<L, N> ToCss for BorderImageSideWidth<L, N>
- where L: ToCss, N: ToCss,
-{
- fn to_css<W>(&self, dest: &mut W) -> fmt::Result
- where W: fmt::Write
- {
- match *self {
- BorderImageSideWidth::Length(ref length) => length.to_css(dest),
- BorderImageSideWidth::Number(ref number) => number.to_css(dest),
- BorderImageSideWidth::Auto => dest.write_str("auto"),
- }
- }
-}
-
impl<N> From<N> for BorderImageSlice<N>
where N: Clone,
{
diff --git a/components/style/values/generics/grid.rs b/components/style/values/generics/grid.rs
index 73640a91e49..3775bb30597 100644
--- a/components/style/values/generics/grid.rs
+++ b/components/style/values/generics/grid.rs
@@ -329,8 +329,8 @@ pub fn concat_serialize_idents<W>(prefix: &str, suffix: &str,
/// The initial argument of the `repeat` function.
///
/// https://drafts.csswg.org/css-grid/#typedef-track-repeat
-#[derive(Clone, Copy, PartialEq, Debug)]
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
+#[derive(Clone, Copy, Debug, PartialEq, ToCss)]
pub enum RepeatCount {
/// A positive integer. This is allowed only for `<track-repeat>` and `<fixed-repeat>`
Number(Integer),
@@ -340,16 +340,6 @@ pub enum RepeatCount {
AutoFit,
}
-impl ToCss for RepeatCount {
- fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
- match *self {
- RepeatCount::Number(ref c) => c.to_css(dest),
- RepeatCount::AutoFill => dest.write_str("auto-fill"),
- RepeatCount::AutoFit => dest.write_str("auto-fit"),
- }
- }
-}
-
impl Parse for RepeatCount {
fn parse(context: &ParserContext, input: &mut Parser) -> Result<Self, ()> {
if let Ok(i) = input.try(|i| Integer::parse(context, i)) {
diff --git a/components/style/values/generics/mod.rs b/components/style/values/generics/mod.rs
index ef88d7c342c..40d3f4e46df 100644
--- a/components/style/values/generics/mod.rs
+++ b/components/style/values/generics/mod.rs
@@ -182,8 +182,8 @@ impl<T: Parse> Parse for FontSettingTag<T> {
/// A font settings value for font-variation-settings or font-feature-settings
-#[derive(Clone, Debug, Eq, PartialEq)]
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
+#[derive(Clone, Debug, Eq, PartialEq, ToCss)]
pub enum FontSettings<T> {
/// No settings (default)
Normal,
@@ -191,15 +191,6 @@ pub enum FontSettings<T> {
Tag(Vec<FontSettingTag<T>>)
}
-impl<T: ToCss> ToCss for FontSettings<T> {
- fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
- match *self {
- FontSettings::Normal => dest.write_str("normal"),
- FontSettings::Tag(ref ftvs) => ftvs.to_css(dest)
- }
- }
-}
-
impl<T: Parse> Parse for FontSettings<T> {
/// https://www.w3.org/TR/css-fonts-3/#propdef-font-feature-settings
fn parse(context: &ParserContext, input: &mut Parser) -> Result<Self, ()> {
@@ -290,8 +281,8 @@ pub struct SVGPaint<ColorType> {
/// Whereas the spec only allows PaintServer
/// to have a fallback, Gecko lets the context
/// properties have a fallback as well.
-#[derive(Debug, Clone, PartialEq)]
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
+#[derive(Clone, Debug, PartialEq, ToCss)]
pub enum SVGPaintKind<ColorType> {
/// `none`
None,
@@ -378,18 +369,6 @@ impl<ColorType: Parse> Parse for SVGPaint<ColorType> {
}
}
-impl<ColorType: ToCss> ToCss for SVGPaintKind<ColorType> {
- fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
- match *self {
- SVGPaintKind::None => dest.write_str("none"),
- SVGPaintKind::ContextStroke => dest.write_str("context-stroke"),
- SVGPaintKind::ContextFill => dest.write_str("context-fill"),
- SVGPaintKind::Color(ref color) => color.to_css(dest),
- SVGPaintKind::PaintServer(ref server) => server.to_css(dest),
- }
- }
-}
-
impl<ColorType: ToCss> ToCss for SVGPaint<ColorType> {
fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
self.kind.to_css(dest)?;
diff --git a/components/style/values/generics/text.rs b/components/style/values/generics/text.rs
index 0652fa91224..5a5a10bb9d9 100644
--- a/components/style/values/generics/text.rs
+++ b/components/style/values/generics/text.rs
@@ -54,7 +54,7 @@ where
/// A generic spacing value for the `letter-spacing` and `word-spacing` properties.
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
-#[derive(Clone, Copy, Debug, HasViewportPercentage, PartialEq, ToComputedValue)]
+#[derive(Clone, Copy, Debug, HasViewportPercentage, PartialEq, ToComputedValue, ToCss)]
pub enum Spacing<Value> {
/// `normal`
Normal,
@@ -117,22 +117,9 @@ impl<Value> Animatable for Spacing<Value>
}
}
-impl<Value> ToCss for Spacing<Value>
- where Value: ToCss,
-{
- fn to_css<W>(&self, dest: &mut W) -> fmt::Result
- where W: fmt::Write
- {
- match *self {
- Spacing::Normal => dest.write_str("normal"),
- Spacing::Value(ref value) => value.to_css(dest),
- }
- }
-}
-
/// A generic value for the `line-height` property.
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
-#[derive(Clone, Copy, Debug, HasViewportPercentage, PartialEq)]
+#[derive(Clone, Copy, Debug, HasViewportPercentage, PartialEq, ToCss)]
pub enum LineHeight<Number, LengthOrPercentage> {
/// `normal`
Normal,
@@ -152,19 +139,3 @@ impl<N, L> LineHeight<N, L> {
LineHeight::Normal
}
}
-
-impl<N, L> ToCss for LineHeight<N, L>
- where N: ToCss, L: ToCss,
-{
- fn to_css<W>(&self, dest: &mut W) -> fmt::Result
- where W: fmt::Write,
- {
- match *self {
- LineHeight::Normal => dest.write_str("normal"),
- #[cfg(feature = "gecko")]
- LineHeight::MozBlockHeight => dest.write_str("-moz-block-height"),
- LineHeight::Number(ref number) => number.to_css(dest),
- LineHeight::Length(ref value) => value.to_css(dest),
- }
- }
-}
diff --git a/components/style/values/specified/border.rs b/components/style/values/specified/border.rs
index b931ef36245..53260bc8e33 100644
--- a/components/style/values/specified/border.rs
+++ b/components/style/values/specified/border.rs
@@ -7,8 +7,6 @@
use app_units::Au;
use cssparser::Parser;
use parser::{Parse, ParserContext};
-use std::fmt;
-use style_traits::ToCss;
use values::computed::{Context, ToComputedValue};
use values::generics::border::BorderCornerRadius as GenericBorderCornerRadius;
use values::generics::border::BorderImageSideWidth as GenericBorderImageSideWidth;
@@ -20,7 +18,7 @@ use values::specified::length::{Length, LengthOrPercentage};
/// A specified value for a single side of the `border-width` property.
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
-#[derive(Clone, Debug, HasViewportPercentage, PartialEq)]
+#[derive(Clone, Debug, HasViewportPercentage, PartialEq, ToCss)]
pub enum BorderSideWidth {
/// `thin`
Thin,
@@ -73,17 +71,6 @@ impl Parse for BorderSideWidth {
}
}
-impl ToCss for BorderSideWidth {
- fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
- match *self {
- BorderSideWidth::Thin => dest.write_str("thin"),
- BorderSideWidth::Medium => dest.write_str("medium"),
- BorderSideWidth::Thick => dest.write_str("thick"),
- BorderSideWidth::Length(ref length) => length.to_css(dest)
- }
- }
-}
-
impl ToComputedValue for BorderSideWidth {
type ComputedValue = Au;
diff --git a/components/style/values/specified/length.rs b/components/style/values/specified/length.rs
index 61335ee0e55..e7b49ee9392 100644
--- a/components/style/values/specified/length.rs
+++ b/components/style/values/specified/length.rs
@@ -894,9 +894,9 @@ impl LengthOrPercentage {
}
/// Either a `<length>`, a `<percentage>`, or the `auto` keyword.
-#[derive(Clone, Debug, HasViewportPercentage, PartialEq)]
-#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
#[allow(missing_docs)]
+#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
+#[derive(Clone, Debug, HasViewportPercentage, PartialEq, ToCss)]
pub enum LengthOrPercentageOrAuto {
Length(NoCalcLength),
Percentage(Percentage),
@@ -918,17 +918,6 @@ impl From<Percentage> for LengthOrPercentageOrAuto {
}
}
-impl ToCss for LengthOrPercentageOrAuto {
- fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
- match *self {
- LengthOrPercentageOrAuto::Length(ref length) => length.to_css(dest),
- LengthOrPercentageOrAuto::Percentage(percentage) => percentage.to_css(dest),
- LengthOrPercentageOrAuto::Auto => dest.write_str("auto"),
- LengthOrPercentageOrAuto::Calc(ref calc) => calc.to_css(dest),
- }
- }
-}
-
impl LengthOrPercentageOrAuto {
fn parse_internal(context: &ParserContext,
input: &mut Parser,
@@ -1012,8 +1001,8 @@ impl LengthOrPercentageOrAuto {
}
/// Either a `<length>`, a `<percentage>`, or the `none` keyword.
-#[derive(Clone, Debug, HasViewportPercentage, PartialEq)]
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
+#[derive(Clone, Debug, HasViewportPercentage, PartialEq, ToCss)]
#[allow(missing_docs)]
pub enum LengthOrPercentageOrNone {
Length(NoCalcLength),
@@ -1022,16 +1011,6 @@ pub enum LengthOrPercentageOrNone {
None,
}
-impl ToCss for LengthOrPercentageOrNone {
- fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
- match *self {
- LengthOrPercentageOrNone::Length(ref length) => length.to_css(dest),
- LengthOrPercentageOrNone::Percentage(ref percentage) => percentage.to_css(dest),
- LengthOrPercentageOrNone::Calc(ref calc) => calc.to_css(dest),
- LengthOrPercentageOrNone::None => dest.write_str("none"),
- }
- }
-}
impl LengthOrPercentageOrNone {
fn parse_internal(context: &ParserContext,
input: &mut Parser,
@@ -1099,8 +1078,8 @@ pub type LengthOrAuto = Either<Length, Auto>;
/// Either a `<length>` or a `<percentage>` or the `auto` keyword or the
/// `content` keyword.
-#[derive(Clone, Debug, HasViewportPercentage, PartialEq)]
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
+#[derive(Clone, Debug, HasViewportPercentage, PartialEq, ToCss)]
pub enum LengthOrPercentageOrAutoOrContent {
/// A `<length>`.
Length(NoCalcLength),
@@ -1156,18 +1135,6 @@ impl LengthOrPercentageOrAutoOrContent {
}
}
-impl ToCss for LengthOrPercentageOrAutoOrContent {
- fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
- match *self {
- LengthOrPercentageOrAutoOrContent::Length(ref len) => len.to_css(dest),
- LengthOrPercentageOrAutoOrContent::Percentage(perc) => perc.to_css(dest),
- LengthOrPercentageOrAutoOrContent::Auto => dest.write_str("auto"),
- LengthOrPercentageOrAutoOrContent::Content => dest.write_str("content"),
- LengthOrPercentageOrAutoOrContent::Calc(ref calc) => calc.to_css(dest),
- }
- }
-}
-
/// Either a `<length>` or a `<number>`.
pub type LengthOrNumber = Either<Length, Number>;
diff --git a/components/style/values/specified/transform.rs b/components/style/values/specified/transform.rs
index f41539fc5b2..e0e5b1c2d6f 100644
--- a/components/style/values/specified/transform.rs
+++ b/components/style/values/specified/transform.rs
@@ -7,8 +7,6 @@
use cssparser::Parser;
use euclid::Point2D;
use parser::{Parse, ParserContext};
-use std::fmt;
-use style_traits::ToCss;
use values::computed::{LengthOrPercentage as ComputedLengthOrPercentage, Context, ToComputedValue};
use values::computed::transform::TimingFunction as ComputedTimingFunction;
use values::generics::transform::{StepPosition, TimingFunction as GenericTimingFunction};
@@ -22,7 +20,7 @@ pub type TransformOrigin = GenericTransformOrigin<OriginComponent<X>, OriginComp
/// The specified value of a component of a CSS `<transform-origin>`.
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
-#[derive(Clone, Debug, HasViewportPercentage, PartialEq)]
+#[derive(Clone, Debug, HasViewportPercentage, PartialEq, ToCss)]
pub enum OriginComponent<S> {
/// `center`
Center,
@@ -99,20 +97,6 @@ impl<S> Parse for OriginComponent<S>
}
}
-impl<S: ToCss> ToCss for OriginComponent<S>
- where S: ToCss,
-{
- fn to_css<W>(&self, dest: &mut W) -> fmt::Result
- where W: fmt::Write,
- {
- match *self {
- OriginComponent::Center => dest.write_str("center"),
- OriginComponent::Length(ref lop) => lop.to_css(dest),
- OriginComponent::Side(ref keyword) => keyword.to_css(dest),
- }
- }
-}
-
impl<S> ToComputedValue for OriginComponent<S>
where S: Side,
{
diff --git a/components/style_derive/to_css.rs b/components/style_derive/to_css.rs
index 774add083fa..f85fe1ce418 100644
--- a/components/style_derive/to_css.rs
+++ b/components/style_derive/to_css.rs
@@ -15,9 +15,12 @@ pub fn derive(input: syn::DeriveInput) -> quote::Tokens {
}
let style = synstructure::BindStyle::Ref.into();
- let match_body = synstructure::each_variant(&input, &style, |bindings, _| {
+ let match_body = synstructure::each_variant(&input, &style, |bindings, variant| {
if bindings.is_empty() {
- panic!("unit variants are not yet supported");
+ let identifier = to_css_identifier(variant.ident.as_ref());
+ return Some(quote! {
+ ::std::fmt::Write::write_str(dest, #identifier)
+ });
}
let (first, rest) = bindings.split_first().expect("unit variants are not yet supported");
where_clause.predicates.push(where_predicate(first.field.ty.clone()));
@@ -28,7 +31,7 @@ pub fn derive(input: syn::DeriveInput) -> quote::Tokens {
where_clause.predicates.push(where_predicate(binding.field.ty.clone()));
expr = quote! {
#expr?;
- dest.write_str(" ")?;
+ ::std::fmt::Write::write_str(dest, " ")?;
::style_traits::ToCss::to_css(#binding, dest)
};
}
@@ -68,3 +71,40 @@ fn where_predicate(ty: syn::Ty) -> syn::WherePredicate {
)],
})
}
+
+/// Transforms "FooBar" to "foo-bar".
+///
+/// If the first Camel segment is "Moz"" or "Webkit", the result string
+/// is prepended with "-".
+fn to_css_identifier(mut camel_case: &str) -> String {
+ let mut first = true;
+ let mut result = String::with_capacity(camel_case.len());
+ while let Some(segment) = split_camel_segment(&mut camel_case) {
+ if first {
+ match segment {
+ "Moz" | "Webkit" => first = false,
+ _ => {},
+ }
+ }
+ if !first {
+ result.push_str("-");
+ }
+ first = false;
+ result.push_str(&segment.to_lowercase());
+ }
+ result
+}
+
+/// Given "FooBar", returns "Foo" and sets `camel_case` to "Bar".
+fn split_camel_segment<'input>(camel_case: &mut &'input str) -> Option<&'input str> {
+ let index = match camel_case.chars().next() {
+ None => return None,
+ Some(ch) => ch.len_utf8(),
+ };
+ let end_position = camel_case[index..]
+ .find(char::is_uppercase)
+ .map_or(camel_case.len(), |pos| index + pos);
+ let result = &camel_case[..end_position];
+ *camel_case = &camel_case[end_position..];
+ Some(result)
+}
diff --git a/components/style_traits/values.rs b/components/style_traits/values.rs
index aaff1a998ea..7c73f7bd4cf 100644
--- a/components/style_traits/values.rs
+++ b/components/style_traits/values.rs
@@ -8,8 +8,15 @@ use app_units::Au;
use cssparser::UnicodeRange;
use std::fmt;
-/// The real `ToCss` trait can't be implemented for types in crates that don't
-/// depend on each other.
+/// Serialises a value according to its CSS representation.
+///
+/// This trait is derivable with `#[derive(ToCss)]`, with the following behaviour:
+/// * unit variants get serialised as the `snake-case` representation
+/// of their name;
+/// * unit variants whose name starts with "Moz" or "Webkit" are prepended
+/// with a "-";
+/// * variants with fields get serialised as the space-separated serialisations
+/// of their fields.
pub trait ToCss {
/// Serialize `self` in CSS syntax, writing to `dest`.
fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write;