Auto merge of #13228 - Manishearth:uncompute, r=heycam

Add uncompute functionality (WIP)

As discussed in Taipei we plan to do animations in Stylo on the Rust side. For cascading properly, we need to "uncompute" these,
i.e. convert them into a cascadeable specified value which when computed gets us the same thing again.

This patch starts work on this. Before writing uncompute code for everything, I'd like to check that this is an acceptable amount of mako magic,
and that the general design is okay (to avoid having to rewrite everything once it's done).

Preliminary r? @SimonSapin @birtles

<!-- 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/13228)
<!-- Reviewable:end -->
This commit is contained in:
bors-servo 2016-09-22 23:14:48 -05:00 committed by GitHub
commit fb52bb7c8d
19 changed files with 576 additions and 50 deletions

View file

@ -147,6 +147,12 @@
fn to_computed_value(&self, context: &Context) -> computed_value::T {
computed_value::T(self.0.iter().map(|x| x.to_computed_value(context)).collect())
}
#[inline]
fn from_computed_value(computed: &computed_value::T) -> Self {
SpecifiedValue(computed.0.iter()
.map(|x| ToComputedValue::from_computed_value(x))
.collect())
}
}
% else:
${caller.body()}

View file

@ -74,6 +74,15 @@ ${helpers.predefined_type("background-color", "CSSColor",
computed_value::T(Some(image.to_computed_value(context))),
}
}
#[inline]
fn from_computed_value(computed: &computed_value::T) -> Self {
match *computed {
computed_value::T(None) => SpecifiedValue(None),
computed_value::T(Some(ref image)) =>
SpecifiedValue(Some(ToComputedValue::from_computed_value(image))),
}
}
}
</%helpers:vector_longhand>
@ -191,7 +200,7 @@ ${helpers.single_keyword("background-origin",
}
}
impl HasViewportPercentage for SpecifiedExplicitSize {
impl HasViewportPercentage for ExplicitSize {
fn has_viewport_percentage(&self) -> bool {
return self.width.has_viewport_percentage() || self.height.has_viewport_percentage();
}
@ -199,12 +208,12 @@ ${helpers.single_keyword("background-origin",
#[derive(Clone, PartialEq, Debug)]
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
pub struct SpecifiedExplicitSize {
pub struct ExplicitSize {
pub width: specified::LengthOrPercentageOrAuto,
pub height: specified::LengthOrPercentageOrAuto,
}
impl ToCss for SpecifiedExplicitSize {
impl ToCss for ExplicitSize {
fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
try!(self.width.to_css(dest));
try!(dest.write_str(" "));
@ -232,7 +241,7 @@ ${helpers.single_keyword("background-origin",
#[derive(Clone, PartialEq, Debug)]
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
pub enum SpecifiedValue {
Explicit(SpecifiedExplicitSize),
Explicit(ExplicitSize),
Cover,
Contain,
}
@ -263,6 +272,19 @@ ${helpers.single_keyword("background-origin",
SpecifiedValue::Contain => computed_value::T::Contain,
}
}
#[inline]
fn from_computed_value(computed: &computed_value::T) -> Self {
match *computed {
computed_value::T::Explicit(ref size) => {
SpecifiedValue::Explicit(ExplicitSize {
width: ToComputedValue::from_computed_value(&size.width),
height: ToComputedValue::from_computed_value(&size.height),
})
}
computed_value::T::Cover => SpecifiedValue::Cover,
computed_value::T::Contain => SpecifiedValue::Contain,
}
}
}
#[inline]
@ -274,7 +296,7 @@ ${helpers.single_keyword("background-origin",
}
#[inline]
pub fn get_initial_specified_value() -> SpecifiedValue {
SpecifiedValue::Explicit(SpecifiedExplicitSize {
SpecifiedValue::Explicit(ExplicitSize {
width: specified::LengthOrPercentageOrAuto::Auto,
height: specified::LengthOrPercentageOrAuto::Auto,
})
@ -311,7 +333,7 @@ ${helpers.single_keyword("background-origin",
height = try!(specified::LengthOrPercentageOrAuto::parse(input));
}
Ok(SpecifiedValue::Explicit(SpecifiedExplicitSize {
Ok(SpecifiedValue::Explicit(ExplicitSize {
width: width,
height: height,
}))

View file

@ -65,6 +65,11 @@
fn to_computed_value(&self, context: &Context) -> computed_value::T {
self.0.to_computed_value(context)
}
#[inline]
fn from_computed_value(computed: &computed_value::T) -> Self {
SpecifiedValue(ToComputedValue::from_computed_value(computed))
}
}
</%helpers:longhand>
% endfor

View file

@ -115,6 +115,10 @@ ${helpers.single_keyword("position", "static absolute relative fixed",
*self
}
}
#[inline]
fn from_computed_value(computed: &computed_value::T) -> SpecifiedValue {
*computed
}
}
</%helpers:single_keyword_computed>
@ -240,6 +244,20 @@ ${helpers.single_keyword("clear", "none left right both",
computed_value::T::LengthOrPercentage(value.to_computed_value(context)),
}
}
#[inline]
fn from_computed_value(computed: &computed_value::T) -> Self {
match *computed {
% for keyword in vertical_align_keywords:
computed_value::T::${to_rust_ident(keyword)} => {
SpecifiedValue::${to_rust_ident(keyword)}
}
% endfor
computed_value::T::LengthOrPercentage(value) =>
SpecifiedValue::LengthOrPercentage(
ToComputedValue::from_computed_value(&value)
),
}
}
}
</%helpers:longhand>
@ -266,6 +284,7 @@ ${helpers.single_keyword("overflow-x", "visible hidden scroll auto",
use cssparser::ToCss;
use std::fmt;
use values::computed::ComputedValueAsSpecified;
pub use self::computed_value::T as SpecifiedValue;
@ -284,14 +303,7 @@ ${helpers.single_keyword("overflow-x", "visible hidden scroll auto",
pub struct T(pub super::super::overflow_x::computed_value::T);
}
impl ToComputedValue for SpecifiedValue {
type ComputedValue = computed_value::T;
#[inline]
fn to_computed_value(&self, context: &Context) -> computed_value::T {
computed_value::T(self.0.to_computed_value(context))
}
}
impl ComputedValueAsSpecified for SpecifiedValue {}
pub fn get_initial_value() -> computed_value::T {
computed_value::T(overflow_x::get_initial_value())
@ -372,6 +384,7 @@ ${helpers.single_keyword("overflow-x", "visible hidden scroll auto",
use euclid::point::{Point2D, TypedPoint2D};
use std::marker::PhantomData;
use values::computed::ComputedValueAsSpecified;
pub use self::computed_value::SingleComputedValue as SingleSpecifiedValue;
pub use self::computed_value::T as SpecifiedValue;
@ -416,6 +429,7 @@ ${helpers.single_keyword("overflow-x", "visible hidden scroll auto",
use cssparser::ToCss;
use euclid::point::Point2D;
use std::fmt;
use values::computed::ComputedValueAsSpecified;
pub use self::TransitionTimingFunction as SingleComputedValue;
@ -490,14 +504,7 @@ ${helpers.single_keyword("overflow-x", "visible hidden scroll auto",
use values::NoViewportPercentage;
impl NoViewportPercentage for SpecifiedValue {}
impl ToComputedValue for SpecifiedValue {
type ComputedValue = computed_value::T;
#[inline]
fn to_computed_value(&self, _: &Context) -> computed_value::T {
(*self).clone()
}
}
impl ComputedValueAsSpecified for SpecifiedValue {}
#[inline]
pub fn get_initial_value() -> computed_value::T {
@ -567,6 +574,9 @@ ${helpers.single_keyword("overflow-x", "visible hidden scroll auto",
<%helpers:longhand name="transition-property"
need_index="True"
animatable="False">
use values::computed::ComputedValueAsSpecified;
pub use self::computed_value::SingleComputedValue as SingleSpecifiedValue;
pub use self::computed_value::T as SpecifiedValue;
@ -616,14 +626,7 @@ ${helpers.single_keyword("overflow-x", "visible hidden scroll auto",
use values::NoViewportPercentage;
impl NoViewportPercentage for SpecifiedValue {}
impl ToComputedValue for SpecifiedValue {
type ComputedValue = computed_value::T;
#[inline]
fn to_computed_value(&self, _: &Context) -> computed_value::T {
(*self).clone()
}
}
impl ComputedValueAsSpecified for SpecifiedValue { }
</%helpers:longhand>
<%helpers:longhand name="transition-delay"

View file

@ -18,6 +18,14 @@
fn to_computed_value(&self, _context: &Context) -> computed_value::T {
self.parsed
}
#[inline]
fn from_computed_value(computed: &computed_value::T) -> Self {
CSSRGBA {
parsed: *computed,
authored: None,
}
}
}
pub type SpecifiedValue = CSSRGBA;

View file

@ -70,6 +70,14 @@
computed_value::T(Some(l.to_computed_value(context)))
}
}
#[inline]
fn from_computed_value(computed: &computed_value::T) -> Self {
match *computed {
computed_value::T(None) => SpecifiedValue::Auto,
computed_value::T(Some(l)) =>
SpecifiedValue::Specified(ToComputedValue::from_computed_value(&l))
}
}
}
pub fn parse(_context: &ParserContext, input: &mut Parser) -> Result<SpecifiedValue, ()> {
@ -136,6 +144,15 @@
computed_value::T(Some(count))
}
}
#[inline]
fn from_computed_value(computed: &computed_value::T) -> Self {
match *computed {
computed_value::T(None) => SpecifiedValue::Auto,
computed_value::T(Some(count)) =>
SpecifiedValue::Specified(count)
}
}
}
pub fn parse(_context: &ParserContext, input: &mut Parser) -> Result<SpecifiedValue, ()> {
@ -216,6 +233,14 @@
computed_value::T(Some(l.to_computed_value(context)))
}
}
#[inline]
fn from_computed_value(computed: &computed_value::T) -> Self {
match *computed {
computed_value::T(None) => SpecifiedValue::Normal,
computed_value::T(Some(l)) =>
SpecifiedValue::Specified(ToComputedValue::from_computed_value(&l))
}
}
}
pub fn parse(_context: &ParserContext, input: &mut Parser) -> Result<SpecifiedValue, ()> {

View file

@ -111,6 +111,18 @@ ${helpers.predefined_type("opacity",
inset: self.inset,
}
}
#[inline]
fn from_computed_value(computed: &computed_value::T) -> Self {
SpecifiedValue {
offset_x: ToComputedValue::from_computed_value(&computed.offset_x),
offset_y: ToComputedValue::from_computed_value(&computed.offset_y),
blur_radius: ToComputedValue::from_computed_value(&computed.blur_radius),
spread_radius: ToComputedValue::from_computed_value(&computed.spread_radius),
color: Some(ToComputedValue::from_computed_value(&computed.color)),
inset: computed.inset,
}
}
}
pub fn parse(_context: &ParserContext, input: &mut Parser) -> Result<SpecifiedValue, ()> {
@ -329,6 +341,16 @@ ${helpers.predefined_type("opacity",
left: value.left.to_computed_value(context),
}))
}
#[inline]
fn from_computed_value(computed: &computed_value::T) -> Self {
SpecifiedValue(computed.0.map(|value| SpecifiedClipRect {
top: ToComputedValue::from_computed_value(&value.top),
right: value.right.map(|right| ToComputedValue::from_computed_value(&right)),
bottom: value.bottom.map(|bottom| ToComputedValue::from_computed_value(&bottom)),
left: ToComputedValue::from_computed_value(&value.left),
}))
}
}
pub fn parse(_context: &ParserContext, input: &mut Parser) -> Result<SpecifiedValue, ()> {
@ -629,6 +651,23 @@ ${helpers.predefined_type("opacity",
}
}).collect() }
}
fn from_computed_value(computed: &computed_value::T) -> Self {
SpecifiedValue(computed.filters.iter().map(|value| {
match *value {
computed_value::Filter::Blur(factor) =>
SpecifiedFilter::Blur(ToComputedValue::from_computed_value(&factor)),
computed_value::Filter::Brightness(factor) => SpecifiedFilter::Brightness(factor),
computed_value::Filter::Contrast(factor) => SpecifiedFilter::Contrast(factor),
computed_value::Filter::Grayscale(factor) => SpecifiedFilter::Grayscale(factor),
computed_value::Filter::HueRotate(factor) => SpecifiedFilter::HueRotate(factor),
computed_value::Filter::Invert(factor) => SpecifiedFilter::Invert(factor),
computed_value::Filter::Opacity(factor) => SpecifiedFilter::Opacity(factor),
computed_value::Filter::Saturate(factor) => SpecifiedFilter::Saturate(factor),
computed_value::Filter::Sepia(factor) => SpecifiedFilter::Sepia(factor),
}
}).collect())
}
}
</%helpers:longhand>
@ -1113,6 +1152,43 @@ ${helpers.predefined_type("opacity",
computed_value::T(Some(result))
}
#[inline]
fn from_computed_value(computed: &computed_value::T) -> Self {
SpecifiedValue(computed.0.as_ref().map(|computed| {
let mut result = vec!();
for operation in computed {
match *operation {
computed_value::ComputedOperation::Matrix(ref matrix) => {
result.push(SpecifiedOperation::Matrix(*matrix));
}
computed_value::ComputedOperation::Translate(ref tx, ref ty, ref tz) => {
// XXXManishearth we lose information here; perhaps we should try to
// recover the original function? Not sure if this can be observed.
result.push(SpecifiedOperation::Translate(TranslateKind::Translate,
ToComputedValue::from_computed_value(tx),
ToComputedValue::from_computed_value(ty),
ToComputedValue::from_computed_value(tz)));
}
computed_value::ComputedOperation::Scale(sx, sy, sz) => {
result.push(SpecifiedOperation::Scale(sx, sy, sz));
}
computed_value::ComputedOperation::Rotate(ax, ay, az, theta) => {
result.push(SpecifiedOperation::Rotate(ax, ay, az, theta));
}
computed_value::ComputedOperation::Skew(theta_x, theta_y) => {
result.push(SpecifiedOperation::Skew(theta_x, theta_y));
}
computed_value::ComputedOperation::Perspective(ref d) => {
result.push(SpecifiedOperation::Perspective(
ToComputedValue::from_computed_value(d)
));
}
};
}
result
}).unwrap_or(Vec::new()))
}
}
</%helpers:longhand>
@ -1309,6 +1385,15 @@ ${helpers.single_keyword("transform-style",
depth: self.depth.to_computed_value(context),
}
}
#[inline]
fn from_computed_value(computed: &computed_value::T) -> Self {
SpecifiedValue {
horizontal: ToComputedValue::from_computed_value(&computed.horizontal),
vertical: ToComputedValue::from_computed_value(&computed.vertical),
depth: ToComputedValue::from_computed_value(&computed.depth),
}
}
}
</%helpers:longhand>
@ -1395,6 +1480,14 @@ ${helpers.predefined_type("perspective",
vertical: self.vertical.to_computed_value(context),
}
}
#[inline]
fn from_computed_value(computed: &computed_value::T) -> Self {
SpecifiedValue {
horizontal: ToComputedValue::from_computed_value(&computed.horizontal),
vertical: ToComputedValue::from_computed_value(&computed.vertical),
}
}
}
</%helpers:longhand>

View file

@ -249,6 +249,15 @@ ${helpers.single_keyword("font-variant",
},
}
}
#[inline]
fn from_computed_value(computed: &computed_value::T) -> Self {
match *computed {
% for weight in range(100, 901, 100):
computed_value::T::Weight${weight} => SpecifiedValue::Weight${weight},
% endfor
}
}
}
</%helpers:longhand>
@ -310,6 +319,13 @@ ${helpers.single_keyword("font-variant",
}
}
}
#[inline]
fn from_computed_value(computed: &computed_value::T) -> Self {
SpecifiedValue(LengthOrPercentage::Length(
ToComputedValue::from_computed_value(computed)
))
}
}
/// <length> | <percentage> | <absolute-size> | <relative-size>
pub fn parse(_context: &ParserContext, input: &mut Parser) -> Result<SpecifiedValue, ()> {

View file

@ -88,14 +88,8 @@ ${helpers.single_keyword("color-adjust",
}
}
impl ToComputedValue for SpecifiedValue {
type ComputedValue = computed_value::T;
#[inline]
fn to_computed_value(&self, _: &Context) -> computed_value::T {
*self
}
}
use values::computed::ComputedValueAsSpecified;
impl ComputedValueAsSpecified for SpecifiedValue { }
</%helpers:longhand>
// Used in the bottom-up flow construction traversal to avoid constructing flows for

View file

@ -94,6 +94,14 @@ ${helpers.single_keyword("caption-side", "top bottom",
vertical: self.vertical.to_computed_value(context),
}
}
#[inline]
fn from_computed_value(computed: &computed_value::T) -> Self {
SpecifiedValue {
horizontal: ToComputedValue::from_computed_value(&computed.horizontal),
vertical: ToComputedValue::from_computed_value(&computed.vertical),
}
}
}
pub fn parse(_: &ParserContext, input: &mut Parser) -> Result<SpecifiedValue,()> {

View file

@ -127,6 +127,22 @@
}
}
}
#[inline]
fn from_computed_value(computed: &computed_value::T) -> Self {
match *computed {
computed_value::T::Normal => SpecifiedValue::Normal,
% if product == "gecko":
computed_value::T::MozBlockHeight => SpecifiedValue::MozBlockHeight,
% endif
computed_value::T::Number(value) => SpecifiedValue::Number(value),
computed_value::T::Length(au) => {
SpecifiedValue::LengthOrPercentage(specified::LengthOrPercentage::Length(
ToComputedValue::from_computed_value(&au)
))
}
}
}
}
</%helpers:longhand>
@ -255,6 +271,13 @@
computed_value::T(Some(l.to_computed_value(context)))
}
}
#[inline]
fn from_computed_value(computed: &computed_value::T) -> Self {
computed.0.map(|ref au| {
SpecifiedValue::Specified(ToComputedValue::from_computed_value(au))
}).unwrap_or(SpecifiedValue::Normal)
}
}
pub fn parse(_context: &ParserContext, input: &mut Parser) -> Result<SpecifiedValue, ()> {
@ -329,6 +352,13 @@
computed_value::T(Some(l.to_computed_value(context))),
}
}
#[inline]
fn from_computed_value(computed: &computed_value::T) -> Self {
computed.0.map(|ref lop| {
SpecifiedValue::Specified(ToComputedValue::from_computed_value(lop))
}).unwrap_or(SpecifiedValue::Normal)
}
}
pub fn parse(_context: &ParserContext, input: &mut Parser) -> Result<SpecifiedValue, ()> {
@ -688,6 +718,17 @@ ${helpers.single_keyword("text-justify",
}
}).collect())
}
fn from_computed_value(computed: &computed_value::T) -> Self {
SpecifiedValue(computed.0.iter().map(|value| {
SpecifiedTextShadow {
offset_x: ToComputedValue::from_computed_value(&value.offset_x),
offset_y: ToComputedValue::from_computed_value(&value.offset_y),
blur_radius: ToComputedValue::from_computed_value(&value.blur_radius),
color: Some(ToComputedValue::from_computed_value(&value.color)),
}
}).collect())
}
}
</%helpers:longhand>

View file

@ -81,6 +81,14 @@ ${helpers.single_keyword("list-style-type", """
SpecifiedValue::Url(ref url) => computed_value::T(Some(url.clone())),
}
}
#[inline]
fn from_computed_value(computed: &computed_value::T) -> Self {
match *computed {
computed_value::T(None) => SpecifiedValue::None,
computed_value::T(Some(ref url)) => SpecifiedValue::Url(url.clone()),
}
}
}
pub fn parse(context: &ParserContext, input: &mut Parser) -> Result<SpecifiedValue, ()> {

View file

@ -66,6 +66,11 @@ ${helpers.predefined_type("outline-color", "CSSColor", "::cssparser::Color::Curr
fn to_computed_value(&self, context: &Context) -> computed_value::T {
self.0.to_computed_value(context)
}
#[inline]
fn from_computed_value(computed: &computed_value::T) -> Self {
SpecifiedValue(ToComputedValue::from_computed_value(computed))
}
}
</%helpers:longhand>

View file

@ -238,5 +238,16 @@ ${helpers.single_keyword("mask-composite",
computed_value::T::Url(url.clone(), data.clone()),
}
}
#[inline]
fn from_computed_value(computed: &computed_value::T) -> Self {
match *computed {
computed_value::T::None => SpecifiedValue::None,
computed_value::T::Image(ref image) =>
SpecifiedValue::Image(ToComputedValue::from_computed_value(image)),
computed_value::T::Url(ref url, ref data) =>
SpecifiedValue::Url(url.clone(), data.clone()),
}
}
}
</%helpers:vector_longhand>