Auto merge of #17662 - servo:derive-all-the-things, r=emilio,SimonSapin

Improve derivation of ToCss again

<!-- Reviewable:start -->
This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/servo/17662)
<!-- Reviewable:end -->
This commit is contained in:
bors-servo 2017-07-12 04:56:31 -07:00 committed by GitHub
commit f9fad3d959
18 changed files with 332 additions and 553 deletions

View file

@ -380,7 +380,7 @@ impl Symbol {
}
/// https://drafts.csswg.org/css-counter-styles/#counter-style-negative
#[derive(Debug, Clone)]
#[derive(Debug, Clone, ToCss)]
pub struct Negative(pub Symbol, pub Option<Symbol>);
impl Parse for Negative {
@ -392,17 +392,6 @@ impl Parse for Negative {
}
}
impl ToCss for Negative {
fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
self.0.to_css(dest)?;
if let Some(ref symbol) = self.1 {
dest.write_char(' ')?;
symbol.to_css(dest)?
}
Ok(())
}
}
/// https://drafts.csswg.org/css-counter-styles/#counter-style-range
///
/// Empty Vec represents 'auto'

View file

@ -75,7 +75,7 @@ add_impls_for_keyword_enum!(FontDisplay);
/// A font-weight value for a @font-face rule.
/// The font-weight CSS property specifies the weight or boldness of the font.
#[cfg(feature = "gecko")]
#[derive(Clone, Debug, PartialEq, Eq)]
#[derive(Clone, Debug, Eq, PartialEq, ToCss)]
pub enum FontWeight {
/// Numeric font weights for fonts that provide more than just normal and bold.
Weight(font_weight::T),
@ -85,17 +85,6 @@ pub enum FontWeight {
Bold,
}
#[cfg(feature = "gecko")]
impl ToCss for FontWeight {
fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
match *self {
FontWeight::Normal => dest.write_str("normal"),
FontWeight::Bold => dest.write_str("bold"),
FontWeight::Weight(ref weight) => weight.to_css(dest),
}
}
}
#[cfg(feature = "gecko")]
impl Parse for FontWeight {
fn parse<'i, 't>(_: &ParserContext, input: &mut Parser<'i, 't>)

View file

@ -370,7 +370,7 @@ impl nsStyleImage {
pub unsafe fn into_image(self: &nsStyleImage) -> Option<Image> {
use gecko_bindings::bindings::Gecko_GetImageElement;
use gecko_bindings::structs::nsStyleImageType;
use values::computed::{NumberOrPercentage, ImageRect};
use values::computed::{NumberOrPercentage, MozImageRect};
match self.mType {
nsStyleImageType::eStyleImageType_Null => {
@ -387,7 +387,7 @@ impl nsStyleImage {
NumberOrPercentage::from_gecko_style_coord(&rect.data_at(2)),
NumberOrPercentage::from_gecko_style_coord(&rect.data_at(3))) {
(Some(top), Some(right), Some(bottom), Some(left)) =>
Some(GenericImage::Rect(ImageRect { url, top, right, bottom, left } )),
Some(GenericImage::Rect(MozImageRect { url, top, right, bottom, left } )),
_ => {
debug_assert!(false, "mCropRect could not convert to NumberOrPercentage");
None
@ -815,7 +815,7 @@ impl TrackSize<LengthOrPercentage> {
if min == max {
TrackSize::Breadth(max)
} else {
TrackSize::MinMax(min, max)
TrackSize::Minmax(min, max)
}
}
@ -836,7 +836,7 @@ impl TrackSize<LengthOrPercentage> {
breadth.to_gecko_style_coord(gecko_min);
breadth.to_gecko_style_coord(gecko_max);
},
TrackSize::MinMax(ref min, ref max) => {
TrackSize::Minmax(ref min, ref max) => {
min.to_gecko_style_coord(gecko_min);
max.to_gecko_style_coord(gecko_max);
},

View file

@ -46,8 +46,8 @@ ${helpers.predefined_type("background-image", "ImageLayer",
"round" => Round,
"no-repeat" => NoRepeat);
#[derive(Debug, Clone, PartialEq)]
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
#[derive(Clone, Debug, PartialEq, ToCss)]
pub enum SpecifiedValue {
RepeatX,
RepeatY,
@ -80,22 +80,6 @@ ${helpers.predefined_type("background-image", "ImageLayer",
}
}
}
impl ToCss for SpecifiedValue {
fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
match *self {
SpecifiedValue::RepeatX => dest.write_str("repeat-x"),
SpecifiedValue::RepeatY => dest.write_str("repeat-y"),
SpecifiedValue::Other(horizontal, vertical) => {
horizontal.to_css(dest)?;
if let Some(vertical) = vertical {
dest.write_str(" ")?;
vertical.to_css(dest)?;
}
Ok(())
}
}
}
}
#[inline]
pub fn get_initial_value() -> computed_value::T {

View file

@ -688,6 +688,7 @@ ${helpers.predefined_type(
use app_units::Au;
use values::computed::{LengthOrPercentageOrNumber as ComputedLoPoNumber, LengthOrNumber as ComputedLoN};
use values::computed::{LengthOrPercentage as ComputedLoP, Length as ComputedLength};
use values::generics::transform::Matrix;
use values::specified::{Angle, Integer, Length, LengthOrPercentage, Percentage};
use values::specified::{LengthOrNumber, LengthOrPercentageOrNumber as LoPoNumber, Number};
use style_traits::ToCss;
@ -791,10 +792,10 @@ ${helpers.predefined_type(
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
pub enum SpecifiedOperation {
/// Represents a 2D 2x3 matrix.
Matrix { a: Number, b: Number, c: Number, d: Number, e: Number, f: Number },
Matrix(Matrix<Number>),
/// Represents a 3D 4x4 matrix with percentage and length values.
/// For `moz-transform`.
PrefixedMatrix { a: Number, b: Number, c: Number, d: Number, e: LoPoNumber, f: LoPoNumber },
PrefixedMatrix(Matrix<Number, LoPoNumber>),
/// Represents a 3D 4x4 matrix.
Matrix3D {
m11: Number, m12: Number, m13: Number, m14: Number,
@ -872,15 +873,10 @@ ${helpers.predefined_type(
impl ToCss for SpecifiedOperation {
fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
use self::SpecifiedOperation::*;
match *self {
Matrix { a, b, c, d, e, f} => write!(
dest, "matrix({}, {}, {}, {}, {}, {})",
Css(a), Css(b), Css(c), Css(d), Css(e), Css(f)),
PrefixedMatrix { a, b, c, d, ref e, ref f} => write!(
dest, "matrix({}, {}, {}, {}, {}, {})",
Css(a), Css(b), Css(c), Css(d), Css(e), Css(f)),
Matrix3D {
SpecifiedOperation::Matrix(ref m) => m.to_css(dest),
SpecifiedOperation::PrefixedMatrix(ref m) => m.to_css(dest),
SpecifiedOperation::Matrix3D {
m11, m12, m13, m14,
m21, m22, m23, m24,
m31, m32, m33, m34,
@ -890,7 +886,7 @@ ${helpers.predefined_type(
Css(m21), Css(m22), Css(m23), Css(m24),
Css(m31), Css(m32), Css(m33), Css(m34),
Css(m41), Css(m42), Css(m43), Css(m44)),
PrefixedMatrix3D {
SpecifiedOperation::PrefixedMatrix3D {
m11, m12, m13, m14,
m21, m22, m23, m24,
m31, m32, m33, m34,
@ -900,31 +896,35 @@ ${helpers.predefined_type(
Css(m21), Css(m22), Css(m23), Css(m24),
Css(m31), Css(m32), Css(m33), Css(m34),
Css(m41), Css(m42), Css(m43), Css(m44)),
Skew(ax, None) => write!(dest, "skew({})", Css(ax)),
Skew(ax, Some(ay)) => write!(dest, "skew({}, {})", Css(ax), Css(ay)),
SkewX(angle) => write!(dest, "skewX({})", Css(angle)),
SkewY(angle) => write!(dest, "skewY({})", Css(angle)),
Translate(ref tx, None) => write!(dest, "translate({})", Css(tx)),
Translate(ref tx, Some(ref ty)) => write!(dest, "translate({}, {})", Css(tx), Css(ty)),
TranslateX(ref tx) => write!(dest, "translateX({})", Css(tx)),
TranslateY(ref ty) => write!(dest, "translateY({})", Css(ty)),
TranslateZ(ref tz) => write!(dest, "translateZ({})", Css(tz)),
Translate3D(ref tx, ref ty, ref tz) => write!(
SpecifiedOperation::Skew(ax, None) => write!(dest, "skew({})", Css(ax)),
SpecifiedOperation::Skew(ax, Some(ay)) => write!(dest, "skew({}, {})", Css(ax), Css(ay)),
SpecifiedOperation::SkewX(angle) => write!(dest, "skewX({})", Css(angle)),
SpecifiedOperation::SkewY(angle) => write!(dest, "skewY({})", Css(angle)),
SpecifiedOperation::Translate(ref tx, None) => write!(dest, "translate({})", Css(tx)),
SpecifiedOperation::Translate(ref tx, Some(ref ty)) => {
write!(dest, "translate({}, {})", Css(tx), Css(ty))
},
SpecifiedOperation::TranslateX(ref tx) => write!(dest, "translateX({})", Css(tx)),
SpecifiedOperation::TranslateY(ref ty) => write!(dest, "translateY({})", Css(ty)),
SpecifiedOperation::TranslateZ(ref tz) => write!(dest, "translateZ({})", Css(tz)),
SpecifiedOperation::Translate3D(ref tx, ref ty, ref tz) => write!(
dest, "translate3d({}, {}, {})", Css(tx), Css(ty), Css(tz)),
Scale(factor, None) => write!(dest, "scale({})", Css(factor)),
Scale(sx, Some(sy)) => write!(dest, "scale({}, {})", Css(sx), Css(sy)),
ScaleX(sx) => write!(dest, "scaleX({})", Css(sx)),
ScaleY(sy) => write!(dest, "scaleY({})", Css(sy)),
ScaleZ(sz) => write!(dest, "scaleZ({})", Css(sz)),
Scale3D(sx, sy, sz) => write!(dest, "scale3d({}, {}, {})", Css(sx), Css(sy), Css(sz)),
Rotate(theta) => write!(dest, "rotate({})", Css(theta)),
RotateX(theta) => write!(dest, "rotateX({})", Css(theta)),
RotateY(theta) => write!(dest, "rotateY({})", Css(theta)),
RotateZ(theta) => write!(dest, "rotateZ({})", Css(theta)),
Rotate3D(x, y, z, theta) => write!(
SpecifiedOperation::Scale(factor, None) => write!(dest, "scale({})", Css(factor)),
SpecifiedOperation::Scale(sx, Some(sy)) => write!(dest, "scale({}, {})", Css(sx), Css(sy)),
SpecifiedOperation::ScaleX(sx) => write!(dest, "scaleX({})", Css(sx)),
SpecifiedOperation::ScaleY(sy) => write!(dest, "scaleY({})", Css(sy)),
SpecifiedOperation::ScaleZ(sz) => write!(dest, "scaleZ({})", Css(sz)),
SpecifiedOperation::Scale3D(sx, sy, sz) => {
write!(dest, "scale3d({}, {}, {})", Css(sx), Css(sy), Css(sz))
},
SpecifiedOperation::Rotate(theta) => write!(dest, "rotate({})", Css(theta)),
SpecifiedOperation::RotateX(theta) => write!(dest, "rotateX({})", Css(theta)),
SpecifiedOperation::RotateY(theta) => write!(dest, "rotateY({})", Css(theta)),
SpecifiedOperation::RotateZ(theta) => write!(dest, "rotateZ({})", Css(theta)),
SpecifiedOperation::Rotate3D(x, y, z, theta) => write!(
dest, "rotate3d({}, {}, {}, {})",
Css(x), Css(y), Css(z), Css(theta)),
Perspective(ref length) => write!(dest, "perspective({})", Css(length)),
SpecifiedOperation::Perspective(ref length) => write!(dest, "perspective({})", Css(length)),
_ => unreachable!(),
}
}
@ -959,248 +959,176 @@ ${helpers.predefined_type(
}
// Allow unitless zero angle for rotate() and skew() to align with gecko
fn parse_internal<'i, 't>(context: &ParserContext, input: &mut Parser<'i, 't>, prefixed: bool)
-> Result<SpecifiedValue,ParseError<'i>> {
fn parse_internal<'i, 't>(
context: &ParserContext,
input: &mut Parser<'i, 't>,
prefixed: bool,
) -> Result<SpecifiedValue,ParseError<'i>> {
use style_traits::{Separator, Space};
if input.try(|input| input.expect_ident_matching("none")).is_ok() {
return Ok(SpecifiedValue(Vec::new()))
}
let mut result = Vec::new();
loop {
let name = match input.try(|i| i.expect_function()) {
Ok(name) => name,
Err(_) => break,
};
let valid_fn = match_ignore_ascii_case! {
&name,
"matrix" => {
input.parse_nested_block(|input| {
// Standard matrix parsing.
Ok(SpecifiedValue(Space::parse(input, |input| {
let function = input.expect_function()?;
input.parse_nested_block(|input| {
let result = match_ignore_ascii_case! { &function,
"matrix" => {
let a = specified::parse_number(context, input)?;
input.expect_comma()?;
let b = specified::parse_number(context, input)?;
input.expect_comma()?;
let c = specified::parse_number(context, input)?;
input.expect_comma()?;
let d = specified::parse_number(context, input)?;
input.expect_comma()?;
if !prefixed {
let values = input.parse_comma_separated(|input| {
specified::parse_number(context, input)
})?;
if values.len() != 6 {
return Err(StyleParseError::UnspecifiedError.into())
}
result.push(SpecifiedOperation::Matrix {
a: values[0],
b: values[1],
c: values[2],
d: values[3],
e: values[4],
f: values[5],
});
return Ok(true);
}
// Non-standard prefixed matrix parsing.
//
// -moz-transform accepts LengthOrPercentageOrNumber in the
// nondiagonal homogeneous components. transform accepts only number.
let mut values = Vec::with_capacity(4);
let mut lengths = Vec::with_capacity(2);
// Consume first number
values.push(specified::parse_number(context, input)?);
// Parse other 5 number/LengthOrPercentageOrNumber
for i in 0..5 {
// Standard matrix parsing.
let e = specified::parse_number(context, input)?;
input.expect_comma()?;
if i < 3 {
values.push(specified::parse_number(context, input)?);
} else {
// -moz-transform accepts LengthOrPercentageOrNumber in the nondiagonal
// homogeneous components. transform accepts only number.
lengths.push(LoPoNumber::parse(context, input)?)
}
let f = specified::parse_number(context, input)?;
Ok(SpecifiedOperation::Matrix(Matrix { a, b, c, d, e, f }))
} else {
// Non-standard prefixed matrix parsing for -moz-transform.
let e = LoPoNumber::parse(context, input)?;
input.expect_comma()?;
let f = LoPoNumber::parse(context, input)?;
Ok(SpecifiedOperation::PrefixedMatrix(Matrix { a, b, c, d, e, f }))
}
result.push(SpecifiedOperation::PrefixedMatrix {
a: values[0],
b: values[1],
c: values[2],
d: values[3],
e: lengths[0].clone(),
f: lengths[1].clone(),
});
Ok(true)
})?
},
"matrix3d" => {
input.parse_nested_block(|input| {
// Standard matrix3d parsing.
},
"matrix3d" => {
let m11 = specified::parse_number(context, input)?;
input.expect_comma()?;
let m12 = specified::parse_number(context, input)?;
input.expect_comma()?;
let m13 = specified::parse_number(context, input)?;
input.expect_comma()?;
let m14 = specified::parse_number(context, input)?;
input.expect_comma()?;
let m21 = specified::parse_number(context, input)?;
input.expect_comma()?;
let m22 = specified::parse_number(context, input)?;
input.expect_comma()?;
let m23 = specified::parse_number(context, input)?;
input.expect_comma()?;
let m24 = specified::parse_number(context, input)?;
input.expect_comma()?;
let m31 = specified::parse_number(context, input)?;
input.expect_comma()?;
let m32 = specified::parse_number(context, input)?;
input.expect_comma()?;
let m33 = specified::parse_number(context, input)?;
input.expect_comma()?;
let m34 = specified::parse_number(context, input)?;
input.expect_comma()?;
if !prefixed {
let values = input.parse_comma_separated(|i| specified::parse_number(context, i))?;
if values.len() != 16 {
return Err(StyleParseError::UnspecifiedError.into())
}
result.push(SpecifiedOperation::Matrix3D {
m11: values[ 0], m12: values[ 1], m13: values[ 2], m14: values[ 3],
m21: values[ 4], m22: values[ 5], m23: values[ 6], m24: values[ 7],
m31: values[ 8], m32: values[ 9], m33: values[10], m34: values[11],
m41: values[12], m42: values[13], m43: values[14], m44: values[15]
});
return Ok(true);
}
// Non-standard prefixed matrix3d parsing.
//
// -moz-transform accepts LengthOrPercentageOrNumber in the
// nondiagonal homogeneous components. transform accepts only number.
let mut values = Vec::with_capacity(13);
let mut lops = Vec::with_capacity(2);
let mut length_or_number = None;
// Parse first number
values.push(specified::parse_number(context, input)?);
// Parse other 15 number/LengthOrPercentageOrNumber
for i in 0..15 {
// Standard matrix3d parsing.
let m41 = specified::parse_number(context, input)?;
input.expect_comma()?;
// -moz-transform accepts LengthOrPercentageOrNumber in the nondiagonal
// homogeneous components. transform accepts only number.
if i < 11 || i > 13 {
values.push(specified::parse_number(context, input)?);
} else if i == 13 {
// m43
length_or_number = Some(LengthOrNumber::parse(context, input)?);
} else {
// m41 and m42
lops.push(LoPoNumber::parse(context, input)?);
}
let m42 = specified::parse_number(context, input)?;
input.expect_comma()?;
let m43 = specified::parse_number(context, input)?;
input.expect_comma()?;
let m44 = specified::parse_number(context, input)?;
Ok(SpecifiedOperation::Matrix3D {
m11, m12, m13, m14,
m21, m22, m23, m24,
m31, m32, m33, m34,
m41, m42, m43, m44,
})
} else {
// Non-standard prefixed matrix parsing for -moz-transform.
let m41 = LoPoNumber::parse(context, input)?;
input.expect_comma()?;
let m42 = LoPoNumber::parse(context, input)?;
input.expect_comma()?;
let m43 = LengthOrNumber::parse(context, input)?;
input.expect_comma()?;
let m44 = specified::parse_number(context, input)?;
Ok(SpecifiedOperation::PrefixedMatrix3D {
m11, m12, m13, m14,
m21, m22, m23, m24,
m31, m32, m33, m34,
m41, m42, m43, m44,
})
}
result.push(SpecifiedOperation::PrefixedMatrix3D {
m11: values[ 0], m12: values[ 1], m13: values[ 2], m14: values[ 3],
m21: values[ 4], m22: values[ 5], m23: values[ 6], m24: values[ 7],
m31: values[ 8], m32: values[ 9], m33: values[10], m34: values[11],
m41: lops[0].clone(), m42: lops[1].clone(), m43: length_or_number.unwrap(),
m44: values[12]
});
Ok(true)
})?
},
"translate" => {
input.parse_nested_block(|input| {
},
"translate" => {
let sx = specified::LengthOrPercentage::parse(context, input)?;
if input.try(|input| input.expect_comma()).is_ok() {
let sy = specified::LengthOrPercentage::parse(context, input)?;
result.push(SpecifiedOperation::Translate(sx, Some(sy)));
Ok(SpecifiedOperation::Translate(sx, Some(sy)))
} else {
result.push(SpecifiedOperation::Translate(sx, None));
Ok(SpecifiedOperation::Translate(sx, None))
}
Ok(true)
})?
},
"translatex" => {
input.parse_nested_block(|input| {
},
"translatex" => {
let tx = specified::LengthOrPercentage::parse(context, input)?;
result.push(SpecifiedOperation::TranslateX(tx));
Ok(true)
})?
},
"translatey" => {
input.parse_nested_block(|input| {
Ok(SpecifiedOperation::TranslateX(tx))
},
"translatey" => {
let ty = specified::LengthOrPercentage::parse(context, input)?;
result.push(SpecifiedOperation::TranslateY(ty));
Ok(true)
})?
},
"translatez" => {
input.parse_nested_block(|input| {
Ok(SpecifiedOperation::TranslateY(ty))
},
"translatez" => {
let tz = specified::Length::parse(context, input)?;
result.push(SpecifiedOperation::TranslateZ(tz));
Ok(true)
})?
},
"translate3d" => {
input.parse_nested_block(|input| {
Ok(SpecifiedOperation::TranslateZ(tz))
},
"translate3d" => {
let tx = specified::LengthOrPercentage::parse(context, input)?;
input.expect_comma()?;
let ty = specified::LengthOrPercentage::parse(context, input)?;
input.expect_comma()?;
let tz = specified::Length::parse(context, input)?;
result.push(SpecifiedOperation::Translate3D(tx, ty, tz));
Ok(true)
})?
},
"scale" => {
input.parse_nested_block(|input| {
Ok(SpecifiedOperation::Translate3D(tx, ty, tz))
},
"scale" => {
let sx = specified::parse_number(context, input)?;
if input.try(|input| input.expect_comma()).is_ok() {
let sy = specified::parse_number(context, input)?;
result.push(SpecifiedOperation::Scale(sx, Some(sy)));
Ok(SpecifiedOperation::Scale(sx, Some(sy)))
} else {
result.push(SpecifiedOperation::Scale(sx, None));
Ok(SpecifiedOperation::Scale(sx, None))
}
Ok(true)
})?
},
"scalex" => {
input.parse_nested_block(|input| {
},
"scalex" => {
let sx = specified::parse_number(context, input)?;
result.push(SpecifiedOperation::ScaleX(sx));
Ok(true)
})?
},
"scaley" => {
input.parse_nested_block(|input| {
Ok(SpecifiedOperation::ScaleX(sx))
},
"scaley" => {
let sy = specified::parse_number(context, input)?;
result.push(SpecifiedOperation::ScaleY(sy));
Ok(true)
})?
},
"scalez" => {
input.parse_nested_block(|input| {
Ok(SpecifiedOperation::ScaleY(sy))
},
"scalez" => {
let sz = specified::parse_number(context, input)?;
result.push(SpecifiedOperation::ScaleZ(sz));
Ok(true)
})?
},
"scale3d" => {
input.parse_nested_block(|input| {
Ok(SpecifiedOperation::ScaleZ(sz))
},
"scale3d" => {
let sx = specified::parse_number(context, input)?;
input.expect_comma()?;
let sy = specified::parse_number(context, input)?;
input.expect_comma()?;
let sz = specified::parse_number(context, input)?;
result.push(SpecifiedOperation::Scale3D(sx, sy, sz));
Ok(true)
})?
},
"rotate" => {
input.parse_nested_block(|input| {
Ok(SpecifiedOperation::Scale3D(sx, sy, sz))
},
"rotate" => {
let theta = specified::Angle::parse_with_unitless(context, input)?;
result.push(SpecifiedOperation::Rotate(theta));
Ok(true)
})?
},
"rotatex" => {
input.parse_nested_block(|input| {
Ok(SpecifiedOperation::Rotate(theta))
},
"rotatex" => {
let theta = specified::Angle::parse_with_unitless(context, input)?;
result.push(SpecifiedOperation::RotateX(theta));
Ok(true)
})?
},
"rotatey" => {
input.parse_nested_block(|input| {
Ok(SpecifiedOperation::RotateX(theta))
},
"rotatey" => {
let theta = specified::Angle::parse_with_unitless(context, input)?;
result.push(SpecifiedOperation::RotateY(theta));
Ok(true)
})?
},
"rotatez" => {
input.parse_nested_block(|input| {
Ok(SpecifiedOperation::RotateY(theta))
},
"rotatez" => {
let theta = specified::Angle::parse_with_unitless(context, input)?;
result.push(SpecifiedOperation::RotateZ(theta));
Ok(true)
})?
},
"rotate3d" => {
input.parse_nested_block(|input| {
Ok(SpecifiedOperation::RotateZ(theta))
},
"rotate3d" => {
let ax = specified::parse_number(context, input)?;
input.expect_comma()?;
let ay = specified::parse_number(context, input)?;
@ -1208,56 +1136,36 @@ ${helpers.predefined_type(
let az = specified::parse_number(context, input)?;
input.expect_comma()?;
let theta = specified::Angle::parse_with_unitless(context, input)?;
// TODO(gw): Check the axis can be normalized!!
result.push(SpecifiedOperation::Rotate3D(ax, ay, az, theta));
Ok(true)
})?
},
"skew" => {
input.parse_nested_block(|input| {
let theta_x = specified::Angle::parse_with_unitless(context, input)?;
// TODO(gw): Check that the axis can be normalized.
Ok(SpecifiedOperation::Rotate3D(ax, ay, az, theta))
},
"skew" => {
let ax = specified::Angle::parse_with_unitless(context, input)?;
if input.try(|input| input.expect_comma()).is_ok() {
let theta_y = specified::Angle::parse_with_unitless(context, input)?;
result.push(SpecifiedOperation::Skew(theta_x, Some(theta_y)));
let ay = specified::Angle::parse_with_unitless(context, input)?;
Ok(SpecifiedOperation::Skew(ax, Some(ay)))
} else {
result.push(SpecifiedOperation::Skew(theta_x, None));
Ok(SpecifiedOperation::Skew(ax, None))
}
Ok(true)
})?
},
"skewx" => {
input.parse_nested_block(|input| {
let theta_x = specified::Angle::parse_with_unitless(context, input)?;
result.push(SpecifiedOperation::SkewX(theta_x));
Ok(true)
})?
},
"skewy" => {
input.parse_nested_block(|input| {
let theta_y = specified::Angle::parse_with_unitless(context, input)?;
result.push(SpecifiedOperation::SkewY(theta_y));
Ok(true)
})?
},
"perspective" => {
input.parse_nested_block(|input| {
},
"skewx" => {
let theta = specified::Angle::parse_with_unitless(context, input)?;
Ok(SpecifiedOperation::SkewX(theta))
},
"skewy" => {
let theta = specified::Angle::parse_with_unitless(context, input)?;
Ok(SpecifiedOperation::SkewY(theta))
},
"perspective" => {
let d = specified::Length::parse_non_negative(context, input)?;
result.push(SpecifiedOperation::Perspective(d));
Ok(true)
})?
},
_ => false
};
if !valid_fn {
return Err(StyleParseError::UnexpectedFunction(name).into());
}
}
if !result.is_empty() {
Ok(SpecifiedValue(result))
} else {
Err(StyleParseError::UnspecifiedError.into())
}
Ok(SpecifiedOperation::Perspective(d))
},
_ => Err(()),
};
result
.map_err(|()| StyleParseError::UnexpectedFunction(function).into())
})
})?))
}
/// Parses `transform` property.
@ -1280,8 +1188,6 @@ ${helpers.predefined_type(
#[inline]
fn to_computed_value(&self, context: &Context) -> computed_value::T {
use self::SpecifiedOperation::*;
if self.0.is_empty() {
return computed_value::T(None)
}
@ -1289,7 +1195,7 @@ ${helpers.predefined_type(
let mut result = vec!();
for operation in &self.0 {
match *operation {
Matrix { a, b, c, d, e, f } => {
SpecifiedOperation::Matrix(Matrix { a, b, c, d, e, f }) => {
let mut comp = computed_value::ComputedMatrix::identity();
comp.m11 = a.to_computed_value(context);
comp.m12 = b.to_computed_value(context);
@ -1299,7 +1205,7 @@ ${helpers.predefined_type(
comp.m42 = f.to_computed_value(context);
result.push(computed_value::ComputedOperation::Matrix(comp));
}
PrefixedMatrix { a, b, c, d, ref e, ref f } => {
SpecifiedOperation::PrefixedMatrix(Matrix { a, b, c, d, ref e, ref f }) => {
let mut comp = computed_value::ComputedMatrixWithPercents::identity();
comp.m11 = a.to_computed_value(context);
comp.m12 = b.to_computed_value(context);
@ -1309,7 +1215,7 @@ ${helpers.predefined_type(
comp.m42 = lopon_to_lop(&f.to_computed_value(context));
result.push(computed_value::ComputedOperation::MatrixWithPercents(comp));
}
Matrix3D {
SpecifiedOperation::Matrix3D {
m11, m12, m13, m14,
m21, m22, m23, m24,
m31, m32, m33, m34,
@ -1334,7 +1240,7 @@ ${helpers.predefined_type(
};
result.push(computed_value::ComputedOperation::Matrix(comp));
}
PrefixedMatrix3D {
SpecifiedOperation::PrefixedMatrix3D {
m11, m12, m13, m14,
m21, m22, m23, m24,
m31, m32, m33, m34,
@ -1359,14 +1265,14 @@ ${helpers.predefined_type(
};
result.push(computed_value::ComputedOperation::MatrixWithPercents(comp));
}
Translate(ref tx, None) => {
SpecifiedOperation::Translate(ref tx, None) => {
let tx = tx.to_computed_value(context);
result.push(computed_value::ComputedOperation::Translate(
tx,
computed::length::LengthOrPercentage::zero(),
computed::length::Length::new(0)));
}
Translate(ref tx, Some(ref ty)) => {
SpecifiedOperation::Translate(ref tx, Some(ref ty)) => {
let tx = tx.to_computed_value(context);
let ty = ty.to_computed_value(context);
result.push(computed_value::ComputedOperation::Translate(
@ -1374,77 +1280,77 @@ ${helpers.predefined_type(
ty,
computed::length::Length::new(0)));
}
TranslateX(ref tx) => {
SpecifiedOperation::TranslateX(ref tx) => {
let tx = tx.to_computed_value(context);
result.push(computed_value::ComputedOperation::Translate(
tx,
computed::length::LengthOrPercentage::zero(),
computed::length::Length::new(0)));
}
TranslateY(ref ty) => {
SpecifiedOperation::TranslateY(ref ty) => {
let ty = ty.to_computed_value(context);
result.push(computed_value::ComputedOperation::Translate(
computed::length::LengthOrPercentage::zero(),
ty,
computed::length::Length::new(0)));
}
TranslateZ(ref tz) => {
SpecifiedOperation::TranslateZ(ref tz) => {
let tz = tz.to_computed_value(context);
result.push(computed_value::ComputedOperation::Translate(
computed::length::LengthOrPercentage::zero(),
computed::length::LengthOrPercentage::zero(),
tz));
}
Translate3D(ref tx, ref ty, ref tz) => {
SpecifiedOperation::Translate3D(ref tx, ref ty, ref tz) => {
let tx = tx.to_computed_value(context);
let ty = ty.to_computed_value(context);
let tz = tz.to_computed_value(context);
result.push(computed_value::ComputedOperation::Translate(tx, ty, tz));
}
Scale(factor, None) => {
SpecifiedOperation::Scale(factor, None) => {
let factor = factor.to_computed_value(context);
result.push(computed_value::ComputedOperation::Scale(factor, factor, 1.0));
}
Scale(sx, Some(sy)) => {
SpecifiedOperation::Scale(sx, Some(sy)) => {
let sx = sx.to_computed_value(context);
let sy = sy.to_computed_value(context);
result.push(computed_value::ComputedOperation::Scale(sx, sy, 1.0));
}
ScaleX(sx) => {
SpecifiedOperation::ScaleX(sx) => {
let sx = sx.to_computed_value(context);
result.push(computed_value::ComputedOperation::Scale(sx, 1.0, 1.0));
}
ScaleY(sy) => {
SpecifiedOperation::ScaleY(sy) => {
let sy = sy.to_computed_value(context);
result.push(computed_value::ComputedOperation::Scale(1.0, sy, 1.0));
}
ScaleZ(sz) => {
SpecifiedOperation::ScaleZ(sz) => {
let sz = sz.to_computed_value(context);
result.push(computed_value::ComputedOperation::Scale(1.0, 1.0, sz));
}
Scale3D(sx, sy, sz) => {
SpecifiedOperation::Scale3D(sx, sy, sz) => {
let sx = sx.to_computed_value(context);
let sy = sy.to_computed_value(context);
let sz = sz.to_computed_value(context);
result.push(computed_value::ComputedOperation::Scale(sx, sy, sz));
}
Rotate(theta) => {
SpecifiedOperation::Rotate(theta) => {
let theta = theta.to_computed_value(context);
result.push(computed_value::ComputedOperation::Rotate(0.0, 0.0, 1.0, theta));
}
RotateX(theta) => {
SpecifiedOperation::RotateX(theta) => {
let theta = theta.to_computed_value(context);
result.push(computed_value::ComputedOperation::Rotate(1.0, 0.0, 0.0, theta));
}
RotateY(theta) => {
SpecifiedOperation::RotateY(theta) => {
let theta = theta.to_computed_value(context);
result.push(computed_value::ComputedOperation::Rotate(0.0, 1.0, 0.0, theta));
}
RotateZ(theta) => {
SpecifiedOperation::RotateZ(theta) => {
let theta = theta.to_computed_value(context);
result.push(computed_value::ComputedOperation::Rotate(0.0, 0.0, 1.0, theta));
}
Rotate3D(ax, ay, az, theta) => {
SpecifiedOperation::Rotate3D(ax, ay, az, theta) => {
let ax = ax.to_computed_value(context);
let ay = ay.to_computed_value(context);
let az = az.to_computed_value(context);
@ -1452,34 +1358,34 @@ ${helpers.predefined_type(
let len = (ax * ax + ay * ay + az * az).sqrt();
result.push(computed_value::ComputedOperation::Rotate(ax / len, ay / len, az / len, theta));
}
Skew(theta_x, None) => {
SpecifiedOperation::Skew(theta_x, None) => {
let theta_x = theta_x.to_computed_value(context);
result.push(computed_value::ComputedOperation::Skew(theta_x, computed::Angle::zero()));
}
Skew(theta_x, Some(theta_y)) => {
SpecifiedOperation::Skew(theta_x, Some(theta_y)) => {
let theta_x = theta_x.to_computed_value(context);
let theta_y = theta_y.to_computed_value(context);
result.push(computed_value::ComputedOperation::Skew(theta_x, theta_y));
}
SkewX(theta_x) => {
SpecifiedOperation::SkewX(theta_x) => {
let theta_x = theta_x.to_computed_value(context);
result.push(computed_value::ComputedOperation::Skew(theta_x, computed::Angle::zero()));
}
SkewY(theta_y) => {
SpecifiedOperation::SkewY(theta_y) => {
let theta_y = theta_y.to_computed_value(context);
result.push(computed_value::ComputedOperation::Skew(computed::Angle::zero(), theta_y));
}
Perspective(ref d) => {
SpecifiedOperation::Perspective(ref d) => {
result.push(computed_value::ComputedOperation::Perspective(d.to_computed_value(context)));
}
InterpolateMatrix { ref from_list, ref to_list, progress } => {
SpecifiedOperation::InterpolateMatrix { ref from_list, ref to_list, progress } => {
result.push(computed_value::ComputedOperation::InterpolateMatrix {
from_list: from_list.to_computed_value(context),
to_list: to_list.to_computed_value(context),
progress: progress
});
}
AccumulateMatrix { ref from_list, ref to_list, count } => {
SpecifiedOperation::AccumulateMatrix { ref from_list, ref to_list, count } => {
result.push(computed_value::ComputedOperation::AccumulateMatrix {
from_list: from_list.to_computed_value(context),
to_list: to_list.to_computed_value(context),

View file

@ -399,14 +399,12 @@ ${helpers.single_keyword_system("font-variant-caps",
<%helpers:longhand name="font-weight" need_clone="True" animation_value_type="ComputedValue"
spec="https://drafts.csswg.org/css-fonts/#propdef-font-weight">
use std::fmt;
use style_traits::ToCss;
use properties::longhands::system_font::SystemFont;
no_viewport_percentage!(SpecifiedValue);
#[derive(Debug, Clone, PartialEq, Eq, Copy)]
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
#[derive(Clone, Copy, Debug, Eq, PartialEq, ToCss)]
pub enum SpecifiedValue {
Normal,
Bold,
@ -416,19 +414,6 @@ ${helpers.single_keyword_system("font-variant-caps",
System(SystemFont),
}
impl ToCss for SpecifiedValue {
fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
match *self {
SpecifiedValue::Normal => dest.write_str("normal"),
SpecifiedValue::Bold => dest.write_str("bold"),
SpecifiedValue::Bolder => dest.write_str("bolder"),
SpecifiedValue::Lighter => dest.write_str("lighter"),
SpecifiedValue::Weight(weight) => weight.to_css(dest),
SpecifiedValue::System(sys) => sys.to_css(dest),
}
}
}
/// normal | bold | bolder | lighter | 100 | 200 | 300 | 400 | 500 | 600 | 700 | 800 | 900
pub fn parse<'i, 't>(context: &ParserContext, input: &mut Parser<'i, 't>)
-> Result<SpecifiedValue, ParseError<'i>> {
@ -1003,12 +988,10 @@ ${helpers.single_keyword_system("font-variant-caps",
<%helpers:longhand products="gecko" name="font-size-adjust" animation_value_type="ComputedValue"
spec="https://drafts.csswg.org/css-fonts/#propdef-font-size-adjust">
use properties::longhands::system_font::SystemFont;
use std::fmt;
use style_traits::ToCss;
no_viewport_percentage!(SpecifiedValue);
#[derive(Copy, Clone, Debug, PartialEq)]
#[derive(Clone, Copy, Debug, PartialEq, ToCss)]
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
pub enum SpecifiedValue {
None,
@ -1016,18 +999,6 @@ ${helpers.single_keyword_system("font-variant-caps",
System(SystemFont),
}
impl ToCss for SpecifiedValue {
fn to_css<W>(&self, dest: &mut W) -> fmt::Result
where W: fmt::Write,
{
match *self {
SpecifiedValue::None => dest.write_str("none"),
SpecifiedValue::Number(number) => number.to_css(dest),
SpecifiedValue::System(sys) => sys.to_css(dest),
}
}
}
impl ToComputedValue for SpecifiedValue {
type ComputedValue = computed_value::T;

View file

@ -27,8 +27,8 @@
String(Box<str>),
}
#[derive(PartialEq, Eq, Clone, Debug)]
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
#[derive(Clone, Debug, Eq, PartialEq, ToCss)]
pub struct SpecifiedValue {
pub first: Side,
pub second: Option<Side>
@ -130,17 +130,6 @@
}
}
}
impl ToCss for SpecifiedValue {
fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
self.first.to_css(dest)?;
if let Some(ref second) = self.second {
dest.write_str(" ")?;
second.to_css(dest)?;
}
Ok(())
}
}
</%helpers:longhand>
${helpers.single_keyword("unicode-bidi",

View file

@ -17,7 +17,7 @@ use values::computed::position::Position;
use values::generics::image::{CompatMode, ColorStop as GenericColorStop, EndingShape as GenericEndingShape};
use values::generics::image::{Gradient as GenericGradient, GradientItem as GenericGradientItem};
use values::generics::image::{Image as GenericImage, GradientKind as GenericGradientKind};
use values::generics::image::{ImageRect as GenericImageRect, LineDirection as GenericLineDirection};
use values::generics::image::{LineDirection as GenericLineDirection, MozImageRect as GenericMozImageRect};
use values::specified::image::{Gradient as SpecifiedGradient, LineDirection as SpecifiedLineDirection};
use values::specified::image::{GradientKind as SpecifiedGradientKind};
use values::specified::position::{X, Y};
@ -27,7 +27,7 @@ pub type ImageLayer = Either<None_, Image>;
/// Computed values for an image according to CSS-IMAGES.
/// https://drafts.csswg.org/css-images/#image-values
pub type Image = GenericImage<Gradient, ImageRect>;
pub type Image = GenericImage<Gradient, MozImageRect>;
/// Computed values for a CSS gradient.
/// https://drafts.csswg.org/css-images/#gradients
@ -71,8 +71,8 @@ pub type GradientItem = GenericGradientItem<RGBA, LengthOrPercentage>;
/// A computed color stop.
pub type ColorStop = GenericColorStop<RGBA, LengthOrPercentage>;
/// Computed values for ImageRect.
pub type ImageRect = GenericImageRect<NumberOrPercentage>;
/// Computed values for `-moz-image-rect(...)`.
pub type MozImageRect = GenericMozImageRect<NumberOrPercentage>;
impl GenericLineDirection for LineDirection {
fn points_downwards(&self) -> bool {

View file

@ -30,7 +30,7 @@ pub use self::border::{BorderRadius, BorderCornerRadius};
pub use self::color::{Color, RGBAColor};
pub use self::effects::{BoxShadow, Filter, SimpleShadow};
pub use self::flex::FlexBasis;
pub use self::image::{Gradient, GradientItem, ImageLayer, LineDirection, Image, ImageRect};
pub use self::image::{Gradient, GradientItem, Image, ImageLayer, LineDirection, MozImageRect};
#[cfg(feature = "gecko")]
pub use self::gecko::ScrollSnapPoint;
pub use self::rect::LengthOrNumberRect;

View file

@ -200,12 +200,12 @@ impl<L: ToComputedValue> ToComputedValue for TrackBreadth<L> {
}
}
#[derive(Clone, Debug, HasViewportPercentage, PartialEq)]
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
/// A `<track-size>` type for explicit grid track sizing. Like `<track-breadth>`, this is
/// generic only to avoid code bloat. It only takes `<length-percentage>`
///
/// https://drafts.csswg.org/css-grid/#typedef-track-size
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
#[derive(Clone, Debug, HasViewportPercentage, PartialEq, ToCss)]
pub enum TrackSize<L> {
/// A flexible `<track-breadth>`
Breadth(TrackBreadth<L>),
@ -213,10 +213,12 @@ pub enum TrackSize<L> {
/// and a flexible `<track-breadth>`
///
/// https://drafts.csswg.org/css-grid/#valdef-grid-template-columns-minmax
MinMax(TrackBreadth<L>, TrackBreadth<L>),
#[css(comma, function)]
Minmax(TrackBreadth<L>, TrackBreadth<L>),
/// A `fit-content` function.
///
/// https://drafts.csswg.org/css-grid/#valdef-grid-template-columns-fit-content
#[css(function)]
FitContent(L),
}
@ -231,7 +233,7 @@ impl<L> TrackSize<L> {
// minmax(<fixed-breadth>, <track-breadth>) or minmax(<inflexible-breadth>, <fixed-breadth>),
// and since both variants are a subset of minmax(<inflexible-breadth>, <track-breadth>), we only
// need to make sure that they're fixed. So, we don't have to modify the parsing function.
TrackSize::MinMax(ref breadth_1, ref breadth_2) => {
TrackSize::Minmax(ref breadth_1, ref breadth_2) => {
if breadth_1.is_fixed() {
return true // the second value is always a <track-breadth>
}
@ -259,26 +261,6 @@ impl<L: PartialEq> TrackSize<L> {
}
}
impl<L: ToCss> ToCss for TrackSize<L> {
fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
match *self {
TrackSize::Breadth(ref b) => b.to_css(dest),
TrackSize::MinMax(ref infexible, ref flexible) => {
dest.write_str("minmax(")?;
infexible.to_css(dest)?;
dest.write_str(", ")?;
flexible.to_css(dest)?;
dest.write_str(")")
},
TrackSize::FitContent(ref lop) => {
dest.write_str("fit-content(")?;
lop.to_css(dest)?;
dest.write_str(")")
},
}
}
}
impl<L: ToComputedValue> ToComputedValue for TrackSize<L> {
type ComputedValue = TrackSize<L::ComputedValue>;
@ -289,11 +271,11 @@ impl<L: ToComputedValue> ToComputedValue for TrackSize<L> {
// <flex> outside `minmax()` expands to `mimmax(auto, <flex>)`
// https://drafts.csswg.org/css-grid/#valdef-grid-template-columns-flex
TrackBreadth::Flex(f) =>
TrackSize::MinMax(TrackBreadth::Keyword(TrackKeyword::Auto), TrackBreadth::Flex(f)),
TrackSize::Minmax(TrackBreadth::Keyword(TrackKeyword::Auto), TrackBreadth::Flex(f)),
_ => TrackSize::Breadth(b.to_computed_value(context)),
},
TrackSize::MinMax(ref b_1, ref b_2) =>
TrackSize::MinMax(b_1.to_computed_value(context), b_2.to_computed_value(context)),
TrackSize::Minmax(ref b_1, ref b_2) =>
TrackSize::Minmax(b_1.to_computed_value(context), b_2.to_computed_value(context)),
TrackSize::FitContent(ref lop) => TrackSize::FitContent(lop.to_computed_value(context)),
}
}
@ -303,8 +285,8 @@ impl<L: ToComputedValue> ToComputedValue for TrackSize<L> {
match *computed {
TrackSize::Breadth(ref b) =>
TrackSize::Breadth(ToComputedValue::from_computed_value(b)),
TrackSize::MinMax(ref b_1, ref b_2) =>
TrackSize::MinMax(ToComputedValue::from_computed_value(b_1),
TrackSize::Minmax(ref b_1, ref b_2) =>
TrackSize::Minmax(ToComputedValue::from_computed_value(b_1),
ToComputedValue::from_computed_value(b_2)),
TrackSize::FitContent(ref lop) =>
TrackSize::FitContent(ToComputedValue::from_computed_value(lop)),

View file

@ -18,13 +18,13 @@ use values::specified::url::SpecifiedUrl;
/// [image]: https://drafts.csswg.org/css-images/#image-values
#[derive(Clone, PartialEq, ToComputedValue)]
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
pub enum Image<Gradient, ImageRect> {
pub enum Image<Gradient, MozImageRect> {
/// A `<url()>` image.
Url(SpecifiedUrl),
/// A `<gradient>` image.
Gradient(Gradient),
/// A `-moz-image-rect` image
Rect(ImageRect),
Rect(MozImageRect),
/// A `-moz-element(# <element-id>)`
Element(Atom),
/// A paint worklet image.
@ -154,14 +154,15 @@ impl ToCss for PaintWorklet {
/// Values for `moz-image-rect`.
///
/// `-moz-image-rect(<uri>, top, right, bottom, left);`
#[derive(Clone, Debug, PartialEq, ToComputedValue)]
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
#[allow(missing_docs)]
pub struct ImageRect<NumberOrPercentage> {
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
#[css(comma, function)]
#[derive(Clone, Debug, PartialEq, ToComputedValue, ToCss)]
pub struct MozImageRect<NumberOrPercentage> {
pub url: SpecifiedUrl,
pub top: NumberOrPercentage,
pub bottom: NumberOrPercentage,
pub right: NumberOrPercentage,
pub bottom: NumberOrPercentage,
pub left: NumberOrPercentage,
}
@ -329,21 +330,3 @@ impl<C, L> fmt::Debug for ColorStop<C, L>
Ok(())
}
}
impl<C> ToCss for ImageRect<C>
where C: ToCss,
{
fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
dest.write_str("-moz-image-rect(")?;
self.url.to_css(dest)?;
dest.write_str(", ")?;
self.top.to_css(dest)?;
dest.write_str(", ")?;
self.right.to_css(dest)?;
dest.write_str(", ")?;
self.bottom.to_css(dest)?;
dest.write_str(", ")?;
self.left.to_css(dest)?;
dest.write_str(")")
}
}

View file

@ -8,12 +8,11 @@ use app_units::Au;
use cssparser::Parser;
use parser::ParserContext;
use properties::animated_properties::Animatable;
use std::fmt;
use style_traits::{ToCss, ParseError};
use style_traits::ParseError;
/// A generic value for the `initial-letter` property.
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
#[derive(Clone, Copy, Debug, HasViewportPercentage, PartialEq, ToComputedValue)]
#[derive(Clone, Copy, Debug, HasViewportPercentage, PartialEq, ToComputedValue, ToCss)]
pub enum InitialLetter<Number, Integer> {
/// `normal`
Normal,
@ -29,29 +28,6 @@ impl<N, I> InitialLetter<N, I> {
}
}
impl<N, I> ToCss for InitialLetter<N, I>
where
N: ToCss,
I: ToCss,
{
fn to_css<W>(&self, dest: &mut W) -> fmt::Result
where
W: fmt::Write,
{
match *self {
InitialLetter::Normal => dest.write_str("normal"),
InitialLetter::Specified(ref size, ref sink) => {
size.to_css(dest)?;
if let Some(ref sink) = *sink {
dest.write_str(" ")?;
sink.to_css(dest)?;
}
Ok(())
},
}
}
}
/// 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, ToCss)]

View file

@ -9,6 +9,20 @@ use std::fmt;
use style_traits::{HasViewportPercentage, ToCss};
use values::CSSFloat;
/// A generic 2D transformation matrix.
#[allow(missing_docs)]
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
#[derive(Clone, Copy, Debug, HasViewportPercentage, PartialEq, ToComputedValue, ToCss)]
#[css(comma, function)]
pub struct Matrix<T, U = T> {
pub a: T,
pub b: T,
pub c: T,
pub d: T,
pub e: U,
pub f: U,
}
/// A generic transform origin.
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
#[derive(Clone, Copy, Debug, HasViewportPercentage, PartialEq, ToComputedValue, ToCss)]
@ -37,10 +51,6 @@ pub enum TimingFunction<Integer, Number> {
Frames(Integer),
}
impl<I, N> HasViewportPercentage for TimingFunction<I, N> {
fn has_viewport_percentage(&self) -> bool { false }
}
define_css_keyword_enum! { TimingKeyword:
"linear" => Linear,
"ease" => Ease,
@ -67,6 +77,10 @@ impl<H, V, D> TransformOrigin<H, V, D> {
}
}
impl<I, N> HasViewportPercentage for TimingFunction<I, N> {
fn has_viewport_percentage(&self) -> bool { false }
}
impl<Integer, Number> TimingFunction<Integer, Number> {
/// `ease`
#[inline]

View file

@ -299,7 +299,7 @@ impl ToComputedValue for Color {
/// Specified color value, but resolved to just RGBA for computed value
/// with value from color property at the same context.
#[derive(Clone, PartialEq, Debug)]
#[derive(Clone, Debug, PartialEq, ToCss)]
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
pub struct RGBAColor(pub Color);
@ -311,12 +311,6 @@ impl Parse for RGBAColor {
}
}
impl ToCss for RGBAColor {
fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
self.0.to_css(dest)
}
}
impl ToComputedValue for RGBAColor {
type ComputedValue = RGBA;

View file

@ -68,7 +68,7 @@ impl Parse for TrackSize<LengthOrPercentage> {
};
input.expect_comma()?;
Ok(TrackSize::MinMax(inflexible_breadth, TrackBreadth::parse(context, input)?))
Ok(TrackSize::Minmax(inflexible_breadth, TrackBreadth::parse(context, input)?))
});
}

View file

@ -24,8 +24,8 @@ use values::computed::{Context, Position as ComputedPosition, ToComputedValue};
use values::generics::image::{Circle, CompatMode, Ellipse, ColorStop as GenericColorStop};
use values::generics::image::{EndingShape as GenericEndingShape, Gradient as GenericGradient};
use values::generics::image::{GradientItem as GenericGradientItem, GradientKind as GenericGradientKind};
use values::generics::image::{Image as GenericImage, ImageRect as GenericImageRect};
use values::generics::image::{LineDirection as GenericsLineDirection, ShapeExtent};
use values::generics::image::{Image as GenericImage, LineDirection as GenericsLineDirection};
use values::generics::image::{MozImageRect as GenericMozImageRect, ShapeExtent};
use values::generics::image::PaintWorklet;
use values::generics::position::Position as GenericPosition;
use values::specified::{Angle, Color, Length, LengthOrPercentage};
@ -38,7 +38,7 @@ pub type ImageLayer = Either<None_, Image>;
/// Specified values for an image according to CSS-IMAGES.
/// https://drafts.csswg.org/css-images/#image-values
pub type Image = GenericImage<Gradient, ImageRect>;
pub type Image = GenericImage<Gradient, MozImageRect>;
/// Specified values for a CSS gradient.
/// https://drafts.csswg.org/css-images/#gradients
@ -125,22 +125,17 @@ pub type ColorStop = GenericColorStop<RGBAColor, LengthOrPercentage>;
/// Specified values for `moz-image-rect`
/// -moz-image-rect(<uri>, top, right, bottom, left);
pub type ImageRect = GenericImageRect<NumberOrPercentage>;
pub type MozImageRect = GenericMozImageRect<NumberOrPercentage>;
impl Parse for Image {
#[cfg_attr(not(feature = "gecko"), allow(unused_mut))]
fn parse<'i, 't>(context: &ParserContext, input: &mut Parser<'i, 't>) -> Result<Image, ParseError<'i>> {
#[cfg(feature = "gecko")]
{
if let Ok(mut url) = input.try(|input| SpecifiedUrl::parse(context, input)) {
url.build_image_value();
return Ok(GenericImage::Url(url));
}
}
#[cfg(feature = "servo")]
{
if let Ok(url) = input.try(|input| SpecifiedUrl::parse(context, input)) {
return Ok(GenericImage::Url(url));
}
if let Ok(mut url) = input.try(|input| SpecifiedUrl::parse(context, input)) {
#[cfg(feature = "gecko")]
{
url.build_image_value();
}
return Ok(GenericImage::Url(url));
}
if let Ok(gradient) = input.try(|i| Gradient::parse(context, i)) {
return Ok(GenericImage::Gradient(gradient));
@ -151,20 +146,13 @@ impl Parse for Image {
return Ok(GenericImage::PaintWorklet(paint_worklet));
}
}
#[cfg(feature = "gecko")]
{
if let Ok(mut image_rect) = input.try(|input| ImageRect::parse(context, input)) {
if let Ok(mut image_rect) = input.try(|input| MozImageRect::parse(context, input)) {
#[cfg(feature = "gecko")]
{
image_rect.url.build_image_value();
return Ok(GenericImage::Rect(image_rect));
}
return Ok(GenericImage::Rect(image_rect));
}
#[cfg(feature = "servo")]
{
if let Ok(image_rect) = input.try(|input| ImageRect::parse(context, input)) {
return Ok(GenericImage::Rect(image_rect));
}
}
Ok(GenericImage::Element(Image::parse_element(input)?))
}
}
@ -897,7 +885,7 @@ impl Parse for PaintWorklet {
}
}
impl Parse for ImageRect {
impl Parse for MozImageRect {
fn parse<'i, 't>(context: &ParserContext, input: &mut Parser<'i, 't>) -> Result<Self, ParseError<'i>> {
input.try(|i| i.expect_function_matching("-moz-image-rect"))?;
input.parse_nested_block(|i| {
@ -912,7 +900,7 @@ impl Parse for ImageRect {
i.expect_comma()?;
let left = NumberOrPercentage::parse_non_negative(context, i)?;
Ok(ImageRect {
Ok(MozImageRect {
url: url,
top: top,
right: right,

View file

@ -37,7 +37,7 @@ pub use self::flex::FlexBasis;
#[cfg(feature = "gecko")]
pub use self::gecko::ScrollSnapPoint;
pub use self::image::{ColorStop, EndingShape as GradientEndingShape, Gradient};
pub use self::image::{GradientItem, GradientKind, Image, ImageRect, ImageLayer};
pub use self::image::{GradientItem, GradientKind, Image, ImageLayer, MozImageRect};
pub use self::length::{AbsoluteLength, CalcLengthOrPercentage, CharacterWidth};
pub use self::length::{FontRelativeLength, Length, LengthOrNone, LengthOrNumber};
pub use self::length::{LengthOrPercentage, LengthOrPercentageOrAuto};

View file

@ -17,6 +17,47 @@ pub fn derive(input: syn::DeriveInput) -> quote::Tokens {
let style = synstructure::BindStyle::Ref.into();
let match_body = synstructure::each_variant(&input, &style, |bindings, variant| {
let mut identifier = to_css_identifier(variant.ident.as_ref());
let mut css_attrs = variant.attrs.iter().filter(|attr| attr.name() == "css");
let (is_function, use_comma) = css_attrs.next().map_or((false, false), |attr| {
match attr.value {
syn::MetaItem::List(ref ident, ref items) if ident.as_ref() == "css" => {
let mut nested = items.iter();
let mut is_function = false;
let mut use_comma = false;
for attr in nested.by_ref() {
match *attr {
syn::NestedMetaItem::MetaItem(syn::MetaItem::Word(ref ident)) => {
match ident.as_ref() {
"function" => {
if is_function {
panic!("repeated `#[css(function)]` attribute");
}
is_function = true;
},
"comma" => {
if use_comma {
panic!("repeated `#[css(comma)]` attribute");
}
use_comma = true;
},
_ => panic!("only `#[css(function | comma)]` is supported for now"),
}
},
_ => panic!("only `#[css(<ident...>)]` is supported for now"),
}
}
if nested.next().is_some() {
panic!("only `#[css()]` or `#[css(<ident>)]` is supported for now")
}
(is_function, use_comma)
},
_ => panic!("only `#[css(...)]` is supported for now"),
}
});
if css_attrs.next().is_some() {
panic!("only a single `#[css(...)]` attribute is supported for now");
}
let separator = if use_comma { ", " } else { " " };
let mut expr = if !bindings.is_empty() {
let mut expr = quote! {};
for binding in bindings {
@ -29,7 +70,7 @@ pub fn derive(input: syn::DeriveInput) -> quote::Tokens {
};
}
quote! {{
let mut writer = ::style_traits::values::SequenceWriter::new(&mut *dest, " ");
let mut writer = ::style_traits::values::SequenceWriter::new(&mut *dest, #separator);
#expr
Ok(())
}}
@ -38,33 +79,6 @@ pub fn derive(input: syn::DeriveInput) -> quote::Tokens {
::std::fmt::Write::write_str(dest, #identifier)
}
};
let mut css_attrs = variant.attrs.iter().filter(|attr| attr.name() == "css");
let is_function = css_attrs.next().map_or(false, |attr| {
match attr.value {
syn::MetaItem::List(ref ident, ref items) if ident.as_ref() == "css" => {
let mut nested = items.iter();
let is_function = nested.next().map_or(false, |attr| {
match *attr {
syn::NestedMetaItem::MetaItem(syn::MetaItem::Word(ref ident)) => {
if ident.as_ref() != "function" {
panic!("only `#[css(function)]` is supported for now")
}
true
},
_ => panic!("only `#[css(<ident>)]` is supported for now"),
}
});
if nested.next().is_some() {
panic!("only `#[css()]` or `#[css(<ident>)]` is supported for now")
}
is_function
},
_ => panic!("only `#[css(...)]` is supported for now"),
}
});
if css_attrs.next().is_some() {
panic!("only a single `#[css(...)]` attribute is supported for now");
}
if is_function {
identifier.push_str("(");
expr = quote! {