Use conditional compilation for stylo properties

This commit is contained in:
Manish Goregaokar 2016-09-02 15:24:22 +05:30
parent 92c3961743
commit c965beb3d9
No known key found for this signature in database
GPG key ID: 3BBF4D3E2EF79F98
12 changed files with 279 additions and 234 deletions

View file

@ -468,39 +468,70 @@ impl Debug for ${style_struct.gecko_struct_name} {
<%def name="raw_impl_trait(style_struct, skip_longhands='', skip_additionals='')">
<%
longhands = [x for x in style_struct.longhands
longhands = [x for x in style_struct.longhands
if not (skip_longhands == "*" or x.name in skip_longhands.split())]
#
# Make a list of types we can't auto-generate.
#
force_stub = [];
# These are currently being shuffled to a different style struct on the gecko side.
force_stub += ["backface-visibility", "transform-box", "transform-style"]
# These live in an nsFont member in Gecko. Should be straightforward to do manually.
force_stub += ["font-kerning", "font-stretch", "font-variant"]
# These have unusual representations in gecko.
force_stub += ["list-style-type", "text-overflow"]
# In a nsTArray, have to be done manually, but probably not too much work
# (the "filling them", not the "making them work")
force_stub += ["animation-name", "animation-duration",
#
# Make a list of types we can't auto-generate.
#
force_stub = [];
# These are currently being shuffled to a different style struct on the gecko side.
force_stub += ["backface-visibility", "transform-box", "transform-style"]
# These live in an nsFont member in Gecko. Should be straightforward to do manually.
force_stub += ["font-kerning", "font-stretch", "font-variant"]
# These have unusual representations in gecko.
force_stub += ["list-style-type", "text-overflow"]
# In a nsTArray, have to be done manually, but probably not too much work
# (the "filling them", not the "making them work")
force_stub += ["animation-name", "animation-duration",
"animation-timing-function", "animation-iteration-count",
"animation-direction", "animation-play-state",
"animation-fill-mode", "animation-delay"]
# Types used with predefined_type()-defined properties that we can auto-generate.
predefined_types = {
# These are part of shorthands so we must include them in stylo builds,
# but we haven't implemented the stylo glue for the longhand
# so we generate a stub
force_stub += ["list-style-image", # box
"flex-basis", # position
# transition
"transition-duration", "transition-timing-function",
"transition-property", "transition-delay",
"background-size", # background
"column-count", # column
]
# Types used with predefined_type()-defined properties that we can auto-generate.
predefined_types = {
"LengthOrPercentage": impl_style_coord,
"LengthOrPercentageOrAuto": impl_style_coord,
"LengthOrPercentageOrNone": impl_style_coord,
"Number": impl_simple,
"Opacity": impl_simple,
}
}
keyword_longhands = [x for x in longhands if x.keyword and not x.name in force_stub]
predefined_longhands = [x for x in longhands
keyword_longhands = [x for x in longhands if x.keyword and not x.name in force_stub]
predefined_longhands = [x for x in longhands
if x.predefined_type in predefined_types and not x.name in force_stub]
stub_longhands = [x for x in longhands if x not in keyword_longhands + predefined_longhands]
stub_longhands = [x for x in longhands if x not in keyword_longhands + predefined_longhands]
# If one of the longhands is not handled
# by either:
# - being a keyword
# - being a predefined longhand
# - being a longhand with manual glue code (i.e. in skip_longhands)
# - being generated as a stub
#
# then we raise an error here.
#
# If you hit this error, please add `product="servo"` to the longhand.
# In case the longhand is used in a shorthand, add it to the force_stub
# list above.
for stub in stub_longhands:
if stub.name not in force_stub:
raise Exception("Don't know what to do with longhand %s in style struct %s"
% (stub.name,style_struct. gecko_struct_name))
%>
impl ${style_struct.gecko_struct_name} {
/*

View file

@ -9,18 +9,12 @@ use properties::PropertyDeclaration;
use properties::longhands;
use properties::longhands::background_position::computed_value::T as BackgroundPosition;
use properties::longhands::background_size::computed_value::T as BackgroundSize;
use properties::longhands::border_spacing::computed_value::T as BorderSpacing;
use properties::longhands::clip::computed_value::ClipRect;
use properties::longhands::font_weight::computed_value::T as FontWeight;
use properties::longhands::line_height::computed_value::T as LineHeight;
use properties::longhands::text_shadow::computed_value::T as TextShadowList;
use properties::longhands::text_shadow::computed_value::TextShadow;
use properties::longhands::box_shadow::computed_value::T as BoxShadowList;
use properties::longhands::box_shadow::single_value::computed_value::T as BoxShadow;
use properties::longhands::transform::computed_value::ComputedMatrix;
use properties::longhands::transform::computed_value::ComputedOperation as TransformOperation;
use properties::longhands::transform::computed_value::T as TransformList;
use properties::longhands::transform_origin::computed_value::T as TransformOrigin;
use properties::longhands::vertical_align::computed_value::T as VerticalAlign;
use properties::longhands::visibility::computed_value::T as Visibility;
use properties::longhands::z_index::computed_value::T as ZIndex;
@ -32,6 +26,8 @@ use values::computed::{BorderRadiusSize, LengthOrNone};
use values::computed::{CalcLengthOrPercentage, LengthOrPercentage};
use values::computed::position::Position;
// NB: This needs to be here because it needs all the longhands generated
// beforehand.
#[derive(Copy, Clone, Debug, PartialEq)]
@ -296,18 +292,6 @@ impl Interpolate for VerticalAlign {
}
}
}
/// https://drafts.csswg.org/css-transitions/#animtype-simple-list
impl Interpolate for BorderSpacing {
#[inline]
fn interpolate(&self, other: &Self, time: f64) -> Result<Self, ()> {
Ok(BorderSpacing {
horizontal: try!(self.horizontal.interpolate(&other.horizontal, time)),
vertical: try!(self.vertical.interpolate(&other.vertical, time)),
})
}
}
impl Interpolate for BackgroundSize {
#[inline]
fn interpolate(&self, other: &Self, time: f64) -> Result<Self, ()> {
@ -492,19 +476,6 @@ impl Interpolate for FontWeight {
}
}
/// https://drafts.csswg.org/css-transitions/#animtype-rect
impl Interpolate for ClipRect {
#[inline]
fn interpolate(&self, other: &Self, time: f64) -> Result<Self, ()> {
Ok(ClipRect {
top: try!(self.top.interpolate(&other.top, time)),
right: try!(self.right.interpolate(&other.right, time)),
bottom: try!(self.bottom.interpolate(&other.bottom, time)),
left: try!(self.left.interpolate(&other.left, time)),
})
}
}
/// https://drafts.csswg.org/css-transitions/#animtype-simple-list
impl Interpolate for Position {
#[inline]
@ -573,138 +544,6 @@ impl Interpolate for TextShadowList {
}
}
/// Check if it's possible to do a direct numerical interpolation
/// between these two transform lists.
/// http://dev.w3.org/csswg/css-transforms/#transform-transform-animation
fn can_interpolate_list(from_list: &[TransformOperation],
to_list: &[TransformOperation]) -> bool {
// Lists must be equal length
if from_list.len() != to_list.len() {
return false;
}
// Each transform operation must match primitive type in other list
for (from, to) in from_list.iter().zip(to_list) {
match (from, to) {
(&TransformOperation::Matrix(..), &TransformOperation::Matrix(..)) |
(&TransformOperation::Skew(..), &TransformOperation::Skew(..)) |
(&TransformOperation::Translate(..), &TransformOperation::Translate(..)) |
(&TransformOperation::Scale(..), &TransformOperation::Scale(..)) |
(&TransformOperation::Rotate(..), &TransformOperation::Rotate(..)) |
(&TransformOperation::Perspective(..), &TransformOperation::Perspective(..)) => {}
_ => {
return false;
}
}
}
true
}
/// Interpolate two transform lists.
/// http://dev.w3.org/csswg/css-transforms/#interpolation-of-transforms
fn interpolate_transform_list(from_list: &[TransformOperation],
to_list: &[TransformOperation],
time: f64) -> TransformList {
let mut result = vec![];
if can_interpolate_list(from_list, to_list) {
for (from, to) in from_list.iter().zip(to_list) {
match (from, to) {
(&TransformOperation::Matrix(from),
&TransformOperation::Matrix(_to)) => {
// TODO(gw): Implement matrix decomposition and interpolation
result.push(TransformOperation::Matrix(from));
}
(&TransformOperation::Skew(fx, fy),
&TransformOperation::Skew(tx, ty)) => {
let ix = fx.interpolate(&tx, time).unwrap();
let iy = fy.interpolate(&ty, time).unwrap();
result.push(TransformOperation::Skew(ix, iy));
}
(&TransformOperation::Translate(fx, fy, fz),
&TransformOperation::Translate(tx, ty, tz)) => {
let ix = fx.interpolate(&tx, time).unwrap();
let iy = fy.interpolate(&ty, time).unwrap();
let iz = fz.interpolate(&tz, time).unwrap();
result.push(TransformOperation::Translate(ix, iy, iz));
}
(&TransformOperation::Scale(fx, fy, fz),
&TransformOperation::Scale(tx, ty, tz)) => {
let ix = fx.interpolate(&tx, time).unwrap();
let iy = fy.interpolate(&ty, time).unwrap();
let iz = fz.interpolate(&tz, time).unwrap();
result.push(TransformOperation::Scale(ix, iy, iz));
}
(&TransformOperation::Rotate(fx, fy, fz, fa),
&TransformOperation::Rotate(tx, ty, tz, ta)) => {
let norm_f = ((fx * fx) + (fy * fy) + (fz * fz)).sqrt();
let norm_t = ((tx * tx) + (ty * ty) + (tz * tz)).sqrt();
let (fx, fy, fz) = (fx / norm_f, fy / norm_f, fz / norm_f);
let (tx, ty, tz) = (tx / norm_t, ty / norm_t, tz / norm_t);
if fx == tx && fy == ty && fz == tz {
let ia = fa.interpolate(&ta, time).unwrap();
result.push(TransformOperation::Rotate(fx, fy, fz, ia));
} else {
// TODO(gw): Implement matrix decomposition and interpolation
result.push(TransformOperation::Rotate(fx, fy, fz, fa));
}
}
(&TransformOperation::Perspective(fd),
&TransformOperation::Perspective(_td)) => {
// TODO(gw): Implement matrix decomposition and interpolation
result.push(TransformOperation::Perspective(fd));
}
_ => {
// This should be unreachable due to the can_interpolate_list() call.
unreachable!();
}
}
}
} else {
// TODO(gw): Implement matrix decomposition and interpolation
result.extend_from_slice(from_list);
}
TransformList(Some(result))
}
/// Build an equivalent 'identity transform function list' based
/// on an existing transform list.
/// http://dev.w3.org/csswg/css-transforms/#none-transform-animation
fn build_identity_transform_list(list: &[TransformOperation]) -> Vec<TransformOperation> {
let mut result = vec!();
for operation in list {
match *operation {
TransformOperation::Matrix(..) => {
let identity = ComputedMatrix::identity();
result.push(TransformOperation::Matrix(identity));
}
TransformOperation::Skew(..) => {
result.push(TransformOperation::Skew(Angle(0.0), Angle(0.0)));
}
TransformOperation::Translate(..) => {
result.push(TransformOperation::Translate(LengthOrPercentage::zero(),
LengthOrPercentage::zero(),
Au(0)));
}
TransformOperation::Scale(..) => {
result.push(TransformOperation::Scale(1.0, 1.0, 1.0));
}
TransformOperation::Rotate(..) => {
result.push(TransformOperation::Rotate(0.0, 0.0, 1.0, Angle(0.0)));
}
TransformOperation::Perspective(..) => {
// http://dev.w3.org/csswg/css-transforms/#identity-transform-function
let identity = ComputedMatrix::identity();
result.push(TransformOperation::Matrix(identity));
}
}
}
result
}
impl Interpolate for BoxShadowList {
#[inline]
@ -780,42 +619,173 @@ impl Interpolate for LengthOrNone {
}
}
impl Interpolate for TransformOrigin {
fn interpolate(&self, other: &Self, time: f64) -> Result<Self, ()> {
Ok(TransformOrigin {
horizontal: try!(self.horizontal.interpolate(&other.horizontal, time)),
vertical: try!(self.vertical.interpolate(&other.vertical, time)),
depth: try!(self.depth.interpolate(&other.depth, time)),
})
}
}
% if product == "servo":
use properties::longhands::transform::computed_value::ComputedMatrix;
use properties::longhands::transform::computed_value::ComputedOperation as TransformOperation;
use properties::longhands::transform::computed_value::T as TransformList;
/// https://drafts.csswg.org/css-transforms/#interpolation-of-transforms
impl Interpolate for TransformList {
#[inline]
fn interpolate(&self, other: &TransformList, time: f64) -> Result<Self, ()> {
// http://dev.w3.org/csswg/css-transforms/#interpolation-of-transforms
let result = match (&self.0, &other.0) {
(&Some(ref from_list), &Some(ref to_list)) => {
// Two lists of transforms
interpolate_transform_list(from_list, &to_list, time)
}
(&Some(ref from_list), &None) => {
// http://dev.w3.org/csswg/css-transforms/#none-transform-animation
let to_list = build_identity_transform_list(from_list);
interpolate_transform_list(from_list, &to_list, time)
}
(&None, &Some(ref to_list)) => {
// http://dev.w3.org/csswg/css-transforms/#none-transform-animation
let from_list = build_identity_transform_list(to_list);
interpolate_transform_list(&from_list, to_list, time)
}
_ => {
// http://dev.w3.org/csswg/css-transforms/#none-none-animation
TransformList(None)
}
};
/// Check if it's possible to do a direct numerical interpolation
/// between these two transform lists.
/// http://dev.w3.org/csswg/css-transforms/#transform-transform-animation
fn can_interpolate_list(from_list: &[TransformOperation],
to_list: &[TransformOperation]) -> bool {
// Lists must be equal length
if from_list.len() != to_list.len() {
return false;
}
Ok(result)
// Each transform operation must match primitive type in other list
for (from, to) in from_list.iter().zip(to_list) {
match (from, to) {
(&TransformOperation::Matrix(..), &TransformOperation::Matrix(..)) |
(&TransformOperation::Skew(..), &TransformOperation::Skew(..)) |
(&TransformOperation::Translate(..), &TransformOperation::Translate(..)) |
(&TransformOperation::Scale(..), &TransformOperation::Scale(..)) |
(&TransformOperation::Rotate(..), &TransformOperation::Rotate(..)) |
(&TransformOperation::Perspective(..), &TransformOperation::Perspective(..)) => {}
_ => {
return false;
}
}
}
true
}
}
/// Build an equivalent 'identity transform function list' based
/// on an existing transform list.
/// http://dev.w3.org/csswg/css-transforms/#none-transform-animation
fn build_identity_transform_list(list: &[TransformOperation]) -> Vec<TransformOperation> {
let mut result = vec!();
for operation in list {
match *operation {
TransformOperation::Matrix(..) => {
let identity = ComputedMatrix::identity();
result.push(TransformOperation::Matrix(identity));
}
TransformOperation::Skew(..) => {
result.push(TransformOperation::Skew(Angle(0.0), Angle(0.0)));
}
TransformOperation::Translate(..) => {
result.push(TransformOperation::Translate(LengthOrPercentage::zero(),
LengthOrPercentage::zero(),
Au(0)));
}
TransformOperation::Scale(..) => {
result.push(TransformOperation::Scale(1.0, 1.0, 1.0));
}
TransformOperation::Rotate(..) => {
result.push(TransformOperation::Rotate(0.0, 0.0, 1.0, Angle(0.0)));
}
TransformOperation::Perspective(..) => {
// http://dev.w3.org/csswg/css-transforms/#identity-transform-function
let identity = ComputedMatrix::identity();
result.push(TransformOperation::Matrix(identity));
}
}
}
result
}
/// Interpolate two transform lists.
/// http://dev.w3.org/csswg/css-transforms/#interpolation-of-transforms
fn interpolate_transform_list(from_list: &[TransformOperation],
to_list: &[TransformOperation],
time: f64) -> TransformList {
let mut result = vec![];
if can_interpolate_list(from_list, to_list) {
for (from, to) in from_list.iter().zip(to_list) {
match (from, to) {
(&TransformOperation::Matrix(from),
&TransformOperation::Matrix(_to)) => {
// TODO(gw): Implement matrix decomposition and interpolation
result.push(TransformOperation::Matrix(from));
}
(&TransformOperation::Skew(fx, fy),
&TransformOperation::Skew(tx, ty)) => {
let ix = fx.interpolate(&tx, time).unwrap();
let iy = fy.interpolate(&ty, time).unwrap();
result.push(TransformOperation::Skew(ix, iy));
}
(&TransformOperation::Translate(fx, fy, fz),
&TransformOperation::Translate(tx, ty, tz)) => {
let ix = fx.interpolate(&tx, time).unwrap();
let iy = fy.interpolate(&ty, time).unwrap();
let iz = fz.interpolate(&tz, time).unwrap();
result.push(TransformOperation::Translate(ix, iy, iz));
}
(&TransformOperation::Scale(fx, fy, fz),
&TransformOperation::Scale(tx, ty, tz)) => {
let ix = fx.interpolate(&tx, time).unwrap();
let iy = fy.interpolate(&ty, time).unwrap();
let iz = fz.interpolate(&tz, time).unwrap();
result.push(TransformOperation::Scale(ix, iy, iz));
}
(&TransformOperation::Rotate(fx, fy, fz, fa),
&TransformOperation::Rotate(tx, ty, tz, ta)) => {
let norm_f = ((fx * fx) + (fy * fy) + (fz * fz)).sqrt();
let norm_t = ((tx * tx) + (ty * ty) + (tz * tz)).sqrt();
let (fx, fy, fz) = (fx / norm_f, fy / norm_f, fz / norm_f);
let (tx, ty, tz) = (tx / norm_t, ty / norm_t, tz / norm_t);
if fx == tx && fy == ty && fz == tz {
let ia = fa.interpolate(&ta, time).unwrap();
result.push(TransformOperation::Rotate(fx, fy, fz, ia));
} else {
// TODO(gw): Implement matrix decomposition and interpolation
result.push(TransformOperation::Rotate(fx, fy, fz, fa));
}
}
(&TransformOperation::Perspective(fd),
&TransformOperation::Perspective(_td)) => {
// TODO(gw): Implement matrix decomposition and interpolation
result.push(TransformOperation::Perspective(fd));
}
_ => {
// This should be unreachable due to the can_interpolate_list() call.
unreachable!();
}
}
}
} else {
// TODO(gw): Implement matrix decomposition and interpolation
result.extend_from_slice(from_list);
}
TransformList(Some(result))
}
/// https://drafts.csswg.org/css-transforms/#interpolation-of-transforms
impl Interpolate for TransformList {
#[inline]
fn interpolate(&self, other: &TransformList, time: f64) -> Result<Self, ()> {
// http://dev.w3.org/csswg/css-transforms/#interpolation-of-transforms
let result = match (&self.0, &other.0) {
(&Some(ref from_list), &Some(ref to_list)) => {
// Two lists of transforms
interpolate_transform_list(from_list, &to_list, time)
}
(&Some(ref from_list), &None) => {
// http://dev.w3.org/csswg/css-transforms/#none-transform-animation
let to_list = build_identity_transform_list(from_list);
interpolate_transform_list(from_list, &to_list, time)
}
(&None, &Some(ref to_list)) => {
// http://dev.w3.org/csswg/css-transforms/#none-transform-animation
let from_list = build_identity_transform_list(to_list);
interpolate_transform_list(&from_list, to_list, time)
}
_ => {
// http://dev.w3.org/csswg/css-transforms/#none-none-animation
TransformList(None)
}
};
Ok(result)
}
}
% endif

View file

@ -153,7 +153,7 @@
</%helpers:longhand>
// FIXME: This prop should be animatable.
<%helpers:longhand name="column-gap" experimental="True" animatable="False">
<%helpers:longhand name="column-gap" experimental="True" products="servo" animatable="False">
use cssparser::ToCss;
use std::fmt;
use values::LocalToCss;

View file

@ -173,7 +173,7 @@
}
</%helpers:longhand>
<%helpers:longhand name="counter-increment" animatable="False">
<%helpers:longhand name="counter-increment" products="servo" animatable="False">
use std::fmt;
use super::content;
use values::NoViewportPercentage;
@ -245,7 +245,7 @@
}
</%helpers:longhand>
<%helpers:longhand name="counter-reset" animatable="False">
<%helpers:longhand name="counter-reset" products="servo" animatable="False">
pub use super::counter_increment::{SpecifiedValue, computed_value, get_initial_value};
use super::counter_increment::{parse_common};

View file

@ -175,7 +175,7 @@ ${helpers.predefined_type("opacity",
</%helpers:vector_longhand>
// FIXME: This prop should be animatable
<%helpers:longhand name="clip" animatable="False">
<%helpers:longhand name="clip" products="servo" animatable="False">
use cssparser::ToCss;
use std::fmt;
use values::LocalToCss;
@ -185,6 +185,7 @@ ${helpers.predefined_type("opacity",
pub mod computed_value {
use app_units::Au;
use properties::animated_properties::Interpolate;
#[derive(Clone, PartialEq, Eq, Copy, Debug)]
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
@ -198,6 +199,20 @@ ${helpers.predefined_type("opacity",
#[derive(Debug, Clone, PartialEq)]
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
pub struct T(pub Option<ClipRect>);
/// https://drafts.csswg.org/css-transitions/#animtype-rect
impl Interpolate for ClipRect {
#[inline]
fn interpolate(&self, other: &Self, time: f64) -> Result<Self, ()> {
Ok(ClipRect {
top: try!(self.top.interpolate(&other.top, time)),
right: try!(self.right.interpolate(&other.right, time)),
bottom: try!(self.bottom.interpolate(&other.bottom, time)),
left: try!(self.left.interpolate(&other.left, time)),
})
}
}
}
impl ToCss for computed_value::T {
@ -364,7 +379,7 @@ ${helpers.predefined_type("opacity",
</%helpers:longhand>
// FIXME: This prop should be animatable
<%helpers:longhand name="filter" animatable="False">
<%helpers:longhand name="filter" products="servo" animatable="False">
//pub use self::computed_value::T as SpecifiedValue;
use cssparser::ToCss;
use std::fmt;
@ -617,7 +632,7 @@ ${helpers.predefined_type("opacity",
}
</%helpers:longhand>
<%helpers:longhand name="transform" animatable="True">
<%helpers:longhand name="transform" products="servo" animatable="True">
use app_units::Au;
use values::CSSFloat;
use values::HasViewportPercentage;
@ -1196,7 +1211,7 @@ ${helpers.single_keyword("transform-style",
"auto flat preserve-3d",
animatable=False)}
<%helpers:longhand name="transform-origin" animatable="True">
<%helpers:longhand name="transform-origin" products="servo" animatable="True">
use app_units::Au;
use values::LocalToCss;
use values::HasViewportPercentage;
@ -1206,6 +1221,7 @@ ${helpers.single_keyword("transform-style",
use std::fmt;
pub mod computed_value {
use properties::animated_properties::Interpolate;
use values::computed::{Length, LengthOrPercentage};
#[derive(Clone, Copy, Debug, PartialEq)]
@ -1215,6 +1231,16 @@ ${helpers.single_keyword("transform-style",
pub vertical: LengthOrPercentage,
pub depth: Length,
}
impl Interpolate for T {
fn interpolate(&self, other: &Self, time: f64) -> Result<Self, ()> {
Ok(T {
horizontal: try!(self.horizontal.interpolate(&other.horizontal, time)),
vertical: try!(self.vertical.interpolate(&other.vertical, time)),
depth: try!(self.depth.interpolate(&other.depth, time)),
})
}
}
}
impl HasViewportPercentage for SpecifiedValue {
@ -1288,10 +1314,11 @@ ${helpers.single_keyword("transform-style",
${helpers.predefined_type("perspective",
"LengthOrNone",
"computed::LengthOrNone::None",
products="servo",
animatable=True)}
// FIXME: This prop should be animatable
<%helpers:longhand name="perspective-origin" animatable="False">
<%helpers:longhand name="perspective-origin" products="servo" animatable="False">
use values::HasViewportPercentage;
use values::specified::{LengthOrPercentage, Percentage};

View file

@ -40,7 +40,7 @@ ${helpers.single_keyword("color-adjust",
"economy exact", products="gecko",
animatable=False)}
<%helpers:longhand name="image-rendering" animatable="False">
<%helpers:longhand name="image-rendering" products="servo" animatable="False">
pub mod computed_value {
use cssparser::ToCss;
use std::fmt;

View file

@ -16,7 +16,7 @@ ${helpers.single_keyword("caption-side", "top bottom",
extra_gecko_values="right left top-outside bottom-outside",
animatable=False)}
<%helpers:longhand name="border-spacing" animatable="False">
<%helpers:longhand name="border-spacing" products="servo" animatable="False">
use app_units::Au;
use values::LocalToCss;
use values::HasViewportPercentage;
@ -26,6 +26,7 @@ ${helpers.single_keyword("caption-side", "top bottom",
pub mod computed_value {
use app_units::Au;
use properties::animated_properties::Interpolate;
#[derive(Clone, Copy, Debug, PartialEq, RustcEncodable)]
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
@ -33,6 +34,17 @@ ${helpers.single_keyword("caption-side", "top bottom",
pub horizontal: Au,
pub vertical: Au,
}
/// https://drafts.csswg.org/css-transitions/#animtype-simple-list
impl Interpolate for T {
#[inline]
fn interpolate(&self, other: &Self, time: f64) -> Result<Self, ()> {
Ok(T {
horizontal: try!(self.horizontal.interpolate(&other.horizontal, time)),
vertical: try!(self.vertical.interpolate(&other.vertical, time)),
})
}
}
}
impl HasViewportPercentage for SpecifiedValue {

View file

@ -192,7 +192,7 @@
</%helpers:longhand>
// FIXME: This prop should be animatable.
<%helpers:longhand name="letter-spacing" animatable="False">
<%helpers:longhand name="letter-spacing" products="servo" animatable="False">
use cssparser::ToCss;
use std::fmt;
use values::LocalToCss;

View file

@ -96,7 +96,7 @@ ${helpers.single_keyword("list-style-type", """
}
</%helpers:longhand>
<%helpers:longhand name="quotes" animatable="False">
<%helpers:longhand name="quotes" products="servo" animatable="False">
use std::borrow::Cow;
use std::fmt;
use values::NoViewportPercentage;

View file

@ -78,4 +78,4 @@ ${helpers.predefined_type("outline-color", "CSSColor", "::cssparser::Color::Curr
animatable=False)}
% endfor
${helpers.predefined_type("outline-offset", "Length", "Au(0)", animatable=True)}
${helpers.predefined_type("outline-offset", "Length", "Au(0)", products="servo", animatable=True)}

View file

@ -110,7 +110,7 @@ ${helpers.single_keyword("align-self", "auto stretch flex-start flex-end center
animatable=False)}
// https://drafts.csswg.org/css-flexbox/#propdef-order
<%helpers:longhand name="order" animatable="True">
<%helpers:longhand name="order" products="servo" animatable="True">
use values::computed::ComputedValueAsSpecified;
impl ComputedValueAsSpecified for SpecifiedValue {}

View file

@ -1152,7 +1152,12 @@ impl PropertyDeclaration {
},
% endfor
_ => PropertyDeclarationParseResult::UnknownProperty
_ => {
if cfg!(all(debug_assertions, feature = "gecko")) && !name.starts_with('-') {
println!("stylo: Unimplemented property setter: {}", name);
}
PropertyDeclarationParseResult::UnknownProperty
}
}
}