Auto merge of #13163 - Manishearth:conditional-compilation, r=bholley

Use conditional compilation for stylo properties; output unimplemented logs for all properties

Till now we were only emitting unimplemented property logs for properties which servo implements but stylo doesn't.
This list is getting smaller, and we really should be emitting this for any unexpected property we encounter.

I also made it so that longhands which stylo does not implement will not be compiled in stylo builds; instead of what we currently do,
which is to parse them and then basically ignore the result.

There are still a few exceptions -- we generate stubs for properties that are parts of shorthands because otherwise we'd have to add fiddly conditional compilation to the shorthand code.

r? @bholley

cc @emilio

<!-- 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/13163)
<!-- Reviewable:end -->
This commit is contained in:
bors-servo 2016-09-02 21:45:08 -05:00 committed by GitHub
commit 58205f1a78
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='')"> <%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())] if not (skip_longhands == "*" or x.name in skip_longhands.split())]
# #
# Make a list of types we can't auto-generate. # Make a list of types we can't auto-generate.
# #
force_stub = []; force_stub = [];
# These are currently being shuffled to a different style struct on the gecko side. # These are currently being shuffled to a different style struct on the gecko side.
force_stub += ["backface-visibility", "transform-box", "transform-style"] force_stub += ["backface-visibility", "transform-box", "transform-style"]
# These live in an nsFont member in Gecko. Should be straightforward to do manually. # These live in an nsFont member in Gecko. Should be straightforward to do manually.
force_stub += ["font-kerning", "font-stretch", "font-variant"] force_stub += ["font-kerning", "font-stretch", "font-variant"]
# These have unusual representations in gecko. # These have unusual representations in gecko.
force_stub += ["list-style-type", "text-overflow"] force_stub += ["list-style-type", "text-overflow"]
# In a nsTArray, have to be done manually, but probably not too much work # In a nsTArray, have to be done manually, but probably not too much work
# (the "filling them", not the "making them work") # (the "filling them", not the "making them work")
force_stub += ["animation-name", "animation-duration", force_stub += ["animation-name", "animation-duration",
"animation-timing-function", "animation-iteration-count", "animation-timing-function", "animation-iteration-count",
"animation-direction", "animation-play-state", "animation-direction", "animation-play-state",
"animation-fill-mode", "animation-delay"] "animation-fill-mode", "animation-delay"]
# Types used with predefined_type()-defined properties that we can auto-generate. # These are part of shorthands so we must include them in stylo builds,
predefined_types = { # 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, "LengthOrPercentage": impl_style_coord,
"LengthOrPercentageOrAuto": impl_style_coord, "LengthOrPercentageOrAuto": impl_style_coord,
"LengthOrPercentageOrNone": impl_style_coord, "LengthOrPercentageOrNone": impl_style_coord,
"Number": impl_simple, "Number": impl_simple,
"Opacity": impl_simple, "Opacity": impl_simple,
} }
keyword_longhands = [x for x in longhands if x.keyword and not x.name in force_stub] keyword_longhands = [x for x in longhands if x.keyword and not x.name in force_stub]
predefined_longhands = [x for x in longhands predefined_longhands = [x for x in longhands
if x.predefined_type in predefined_types and not x.name in force_stub] 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} { impl ${style_struct.gecko_struct_name} {
/* /*

View file

@ -9,18 +9,12 @@ use properties::PropertyDeclaration;
use properties::longhands; use properties::longhands;
use properties::longhands::background_position::computed_value::T as BackgroundPosition; use properties::longhands::background_position::computed_value::T as BackgroundPosition;
use properties::longhands::background_size::computed_value::T as BackgroundSize; 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::font_weight::computed_value::T as FontWeight;
use properties::longhands::line_height::computed_value::T as LineHeight; 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::T as TextShadowList;
use properties::longhands::text_shadow::computed_value::TextShadow; use properties::longhands::text_shadow::computed_value::TextShadow;
use properties::longhands::box_shadow::computed_value::T as BoxShadowList; 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::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::vertical_align::computed_value::T as VerticalAlign;
use properties::longhands::visibility::computed_value::T as Visibility; use properties::longhands::visibility::computed_value::T as Visibility;
use properties::longhands::z_index::computed_value::T as ZIndex; 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::{CalcLengthOrPercentage, LengthOrPercentage};
use values::computed::position::Position; use values::computed::position::Position;
// NB: This needs to be here because it needs all the longhands generated // NB: This needs to be here because it needs all the longhands generated
// beforehand. // beforehand.
#[derive(Copy, Clone, Debug, PartialEq)] #[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 { impl Interpolate for BackgroundSize {
#[inline] #[inline]
fn interpolate(&self, other: &Self, time: f64) -> Result<Self, ()> { 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 /// https://drafts.csswg.org/css-transitions/#animtype-simple-list
impl Interpolate for Position { impl Interpolate for Position {
#[inline] #[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 { impl Interpolate for BoxShadowList {
#[inline] #[inline]
@ -780,42 +619,173 @@ impl Interpolate for LengthOrNone {
} }
} }
impl Interpolate for TransformOrigin { % if product == "servo":
fn interpolate(&self, other: &Self, time: f64) -> Result<Self, ()> { use properties::longhands::transform::computed_value::ComputedMatrix;
Ok(TransformOrigin { use properties::longhands::transform::computed_value::ComputedOperation as TransformOperation;
horizontal: try!(self.horizontal.interpolate(&other.horizontal, time)), use properties::longhands::transform::computed_value::T as TransformList;
vertical: try!(self.vertical.interpolate(&other.vertical, time)),
depth: try!(self.depth.interpolate(&other.depth, time)),
})
}
}
/// https://drafts.csswg.org/css-transforms/#interpolation-of-transforms /// Check if it's possible to do a direct numerical interpolation
impl Interpolate for TransformList { /// between these two transform lists.
#[inline] /// http://dev.w3.org/csswg/css-transforms/#transform-transform-animation
fn interpolate(&self, other: &TransformList, time: f64) -> Result<Self, ()> { fn can_interpolate_list(from_list: &[TransformOperation],
// http://dev.w3.org/csswg/css-transforms/#interpolation-of-transforms to_list: &[TransformOperation]) -> bool {
let result = match (&self.0, &other.0) { // Lists must be equal length
(&Some(ref from_list), &Some(ref to_list)) => { if from_list.len() != to_list.len() {
// Two lists of transforms return false;
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) // 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> </%helpers:longhand>
// FIXME: This prop should be animatable. // 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 cssparser::ToCss;
use std::fmt; use std::fmt;
use values::LocalToCss; use values::LocalToCss;

View file

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

View file

@ -175,7 +175,7 @@ ${helpers.predefined_type("opacity",
</%helpers:vector_longhand> </%helpers:vector_longhand>
// FIXME: This prop should be animatable // FIXME: This prop should be animatable
<%helpers:longhand name="clip" animatable="False"> <%helpers:longhand name="clip" products="servo" animatable="False">
use cssparser::ToCss; use cssparser::ToCss;
use std::fmt; use std::fmt;
use values::LocalToCss; use values::LocalToCss;
@ -185,6 +185,7 @@ ${helpers.predefined_type("opacity",
pub mod computed_value { pub mod computed_value {
use app_units::Au; use app_units::Au;
use properties::animated_properties::Interpolate;
#[derive(Clone, PartialEq, Eq, Copy, Debug)] #[derive(Clone, PartialEq, Eq, Copy, Debug)]
#[cfg_attr(feature = "servo", derive(HeapSizeOf))] #[cfg_attr(feature = "servo", derive(HeapSizeOf))]
@ -198,6 +199,20 @@ ${helpers.predefined_type("opacity",
#[derive(Debug, Clone, PartialEq)] #[derive(Debug, Clone, PartialEq)]
#[cfg_attr(feature = "servo", derive(HeapSizeOf))] #[cfg_attr(feature = "servo", derive(HeapSizeOf))]
pub struct T(pub Option<ClipRect>); 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 { impl ToCss for computed_value::T {
@ -364,7 +379,7 @@ ${helpers.predefined_type("opacity",
</%helpers:longhand> </%helpers:longhand>
// FIXME: This prop should be animatable // 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; //pub use self::computed_value::T as SpecifiedValue;
use cssparser::ToCss; use cssparser::ToCss;
use std::fmt; use std::fmt;
@ -617,7 +632,7 @@ ${helpers.predefined_type("opacity",
} }
</%helpers:longhand> </%helpers:longhand>
<%helpers:longhand name="transform" animatable="True"> <%helpers:longhand name="transform" products="servo" animatable="True">
use app_units::Au; use app_units::Au;
use values::CSSFloat; use values::CSSFloat;
use values::HasViewportPercentage; use values::HasViewportPercentage;
@ -1196,7 +1211,7 @@ ${helpers.single_keyword("transform-style",
"auto flat preserve-3d", "auto flat preserve-3d",
animatable=False)} animatable=False)}
<%helpers:longhand name="transform-origin" animatable="True"> <%helpers:longhand name="transform-origin" products="servo" animatable="True">
use app_units::Au; use app_units::Au;
use values::LocalToCss; use values::LocalToCss;
use values::HasViewportPercentage; use values::HasViewportPercentage;
@ -1206,6 +1221,7 @@ ${helpers.single_keyword("transform-style",
use std::fmt; use std::fmt;
pub mod computed_value { pub mod computed_value {
use properties::animated_properties::Interpolate;
use values::computed::{Length, LengthOrPercentage}; use values::computed::{Length, LengthOrPercentage};
#[derive(Clone, Copy, Debug, PartialEq)] #[derive(Clone, Copy, Debug, PartialEq)]
@ -1215,6 +1231,16 @@ ${helpers.single_keyword("transform-style",
pub vertical: LengthOrPercentage, pub vertical: LengthOrPercentage,
pub depth: Length, 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 { impl HasViewportPercentage for SpecifiedValue {
@ -1288,10 +1314,11 @@ ${helpers.single_keyword("transform-style",
${helpers.predefined_type("perspective", ${helpers.predefined_type("perspective",
"LengthOrNone", "LengthOrNone",
"computed::LengthOrNone::None", "computed::LengthOrNone::None",
products="servo",
animatable=True)} animatable=True)}
// FIXME: This prop should be animatable // 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::HasViewportPercentage;
use values::specified::{LengthOrPercentage, Percentage}; use values::specified::{LengthOrPercentage, Percentage};

View file

@ -40,7 +40,7 @@ ${helpers.single_keyword("color-adjust",
"economy exact", products="gecko", "economy exact", products="gecko",
animatable=False)} animatable=False)}
<%helpers:longhand name="image-rendering" animatable="False"> <%helpers:longhand name="image-rendering" products="servo" animatable="False">
pub mod computed_value { pub mod computed_value {
use cssparser::ToCss; use cssparser::ToCss;
use std::fmt; 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", extra_gecko_values="right left top-outside bottom-outside",
animatable=False)} animatable=False)}
<%helpers:longhand name="border-spacing" animatable="False"> <%helpers:longhand name="border-spacing" products="servo" animatable="False">
use app_units::Au; use app_units::Au;
use values::LocalToCss; use values::LocalToCss;
use values::HasViewportPercentage; use values::HasViewportPercentage;
@ -26,6 +26,7 @@ ${helpers.single_keyword("caption-side", "top bottom",
pub mod computed_value { pub mod computed_value {
use app_units::Au; use app_units::Au;
use properties::animated_properties::Interpolate;
#[derive(Clone, Copy, Debug, PartialEq, RustcEncodable)] #[derive(Clone, Copy, Debug, PartialEq, RustcEncodable)]
#[cfg_attr(feature = "servo", derive(HeapSizeOf))] #[cfg_attr(feature = "servo", derive(HeapSizeOf))]
@ -33,6 +34,17 @@ ${helpers.single_keyword("caption-side", "top bottom",
pub horizontal: Au, pub horizontal: Au,
pub vertical: 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 { impl HasViewportPercentage for SpecifiedValue {

View file

@ -192,7 +192,7 @@
</%helpers:longhand> </%helpers:longhand>
// FIXME: This prop should be animatable. // 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 cssparser::ToCss;
use std::fmt; use std::fmt;
use values::LocalToCss; use values::LocalToCss;

View file

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

View file

@ -78,4 +78,4 @@ ${helpers.predefined_type("outline-color", "CSSColor", "::cssparser::Color::Curr
animatable=False)} animatable=False)}
% endfor % 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)} animatable=False)}
// https://drafts.csswg.org/css-flexbox/#propdef-order // 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; use values::computed::ComputedValueAsSpecified;
impl ComputedValueAsSpecified for SpecifiedValue {} impl ComputedValueAsSpecified for SpecifiedValue {}

View file

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