mirror of
https://github.com/servo/servo.git
synced 2025-08-06 06:00:15 +01:00
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:
commit
f9fad3d959
18 changed files with 332 additions and 553 deletions
|
@ -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'
|
||||
|
|
|
@ -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>)
|
||||
|
|
|
@ -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);
|
||||
},
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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),
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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)),
|
||||
|
|
|
@ -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(")")
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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)]
|
||||
|
|
|
@ -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]
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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)?))
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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};
|
||||
|
|
|
@ -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! {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue