Auto merge of #14913 - canaltinova:box-longhands, r=Manishearth

Refactor box longhands

<!-- Please describe your changes on the following line: -->
Converted some longhands into `vector_longhand` to reduce some repeated codes.
Also some of longhands with same `SpecifiedValue` and `computed_value::T` changed. Re-exported SpecifiedValue instead of computed_value::T. Normally a computed_value can't have a parse function.

---
<!-- Thank you for contributing to Servo! Please replace each `[ ]` by `[X]` when the step is complete, and replace `__` with appropriate data: -->
- [X] `./mach build -d` does not report any errors
- [X] `./mach test-tidy` does not report any errors

<!-- Either: -->
- [X] These changes do not require tests because they're not changing the behavior of the longhands.

<!-- Pull requests that do not address these steps are welcome, but they will require additional verification as part of the review process. -->

<!-- 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/14913)
<!-- Reviewable:end -->
This commit is contained in:
bors-servo 2017-01-08 06:24:02 -08:00 committed by GitHub
commit 0d5e021537
6 changed files with 222 additions and 397 deletions

View file

@ -14,10 +14,10 @@ use keyframes::{KeyframesStep, KeyframesStepValue};
use properties::{self, CascadeFlags, ComputedValues, Importance}; use properties::{self, CascadeFlags, ComputedValues, Importance};
use properties::animated_properties::{AnimatedProperty, TransitionProperty}; use properties::animated_properties::{AnimatedProperty, TransitionProperty};
use properties::longhands::animation_direction::computed_value::single_value::T as AnimationDirection; use properties::longhands::animation_direction::computed_value::single_value::T as AnimationDirection;
use properties::longhands::animation_iteration_count::computed_value::AnimationIterationCount; use properties::longhands::animation_iteration_count::single_value::computed_value::T as AnimationIterationCount;
use properties::longhands::animation_play_state::computed_value::single_value::T as AnimationPlayState; use properties::longhands::animation_play_state::computed_value::single_value::T as AnimationPlayState;
use properties::longhands::transition_timing_function::computed_value::StartEnd; use properties::longhands::transition_timing_function::single_value::computed_value::StartEnd;
use properties::longhands::transition_timing_function::computed_value::TransitionTimingFunction; use properties::longhands::transition_timing_function::single_value::computed_value::T as TransitionTimingFunction;
use std::sync::Arc; use std::sync::Arc;
use std::sync::mpsc::Sender; use std::sync::mpsc::Sender;
use timer::Timer; use timer::Timer;

View file

@ -157,7 +157,7 @@
% endif % endif
} }
pub use self::single_value::computed_value::T as SingleSpecifiedValue; pub use self::single_value::SpecifiedValue as SingleSpecifiedValue;
impl ToComputedValue for SpecifiedValue { impl ToComputedValue for SpecifiedValue {
type ComputedValue = computed_value::T; type ComputedValue = computed_value::T;

View file

@ -28,32 +28,32 @@
-moz-grid-group -moz-grid-line -moz-stack -moz-inline-stack -moz-deck -moz-grid-group -moz-grid-line -moz-stack -moz-inline-stack -moz-deck
-moz-popup -moz-groupbox""".split() -moz-popup -moz-groupbox""".split()
%> %>
pub use self::computed_value::T as SpecifiedValue;
use values::computed::ComputedValueAsSpecified; use values::computed::ComputedValueAsSpecified;
use style_traits::ToCss; use style_traits::ToCss;
use values::NoViewportPercentage; use values::NoViewportPercentage;
impl NoViewportPercentage for SpecifiedValue {} impl NoViewportPercentage for SpecifiedValue {}
pub mod computed_value { pub mod computed_value {
use style_traits::ToCss; pub use super::SpecifiedValue as T;
#[allow(non_camel_case_types)] }
#[derive(Clone, Eq, PartialEq, Copy, Hash, RustcEncodable, Debug)]
#[cfg_attr(feature = "servo", derive(HeapSizeOf, Deserialize, Serialize))]
pub enum T {
% for value in values:
${to_rust_ident(value)},
% endfor
}
impl ToCss for T { #[allow(non_camel_case_types)]
fn to_css<W>(&self, dest: &mut W) -> ::std::fmt::Result #[derive(Clone, Eq, PartialEq, Copy, Hash, RustcEncodable, Debug)]
where W: ::std::fmt::Write, #[cfg_attr(feature = "servo", derive(HeapSizeOf, Deserialize, Serialize))]
{ pub enum SpecifiedValue {
match *self { % for value in values:
% for value in values: ${to_rust_ident(value)},
T::${to_rust_ident(value)} => dest.write_str("${value}"), % endfor
% endfor }
}
impl ToCss for SpecifiedValue {
fn to_css<W>(&self, dest: &mut W) -> ::std::fmt::Result
where W: ::std::fmt::Write,
{
match *self {
% for value in values:
SpecifiedValue::${to_rust_ident(value)} => dest.write_str("${value}"),
% endfor
} }
} }
} }
@ -397,8 +397,6 @@ ${helpers.single_keyword("overflow-x", "visible hidden scroll auto",
use values::computed::ComputedValueAsSpecified; use values::computed::ComputedValueAsSpecified;
use values::NoViewportPercentage; use values::NoViewportPercentage;
pub use self::computed_value::T as SpecifiedValue;
impl NoViewportPercentage for SpecifiedValue {} impl NoViewportPercentage for SpecifiedValue {}
impl ToCss for SpecifiedValue { impl ToCss for SpecifiedValue {
@ -407,18 +405,19 @@ ${helpers.single_keyword("overflow-x", "visible hidden scroll auto",
} }
} }
/// The specified and computed value for overflow-y is a wrapper on top of /// The specified and computed value for overflow-y is a wrapper on top of
/// `overflow-x`, so we re-use the logic, but prevent errors from mistakenly /// `overflow-x`, so we re-use the logic, but prevent errors from mistakenly
/// assign one to other. /// assign one to other.
/// ///
/// TODO(Manishearth, emilio): We may want to just use the same value. /// TODO(Manishearth, emilio): We may want to just use the same value.
pub mod computed_value { pub mod computed_value {
#[derive(Debug, Clone, Copy, PartialEq)] pub use super::SpecifiedValue as T;
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
pub struct T(pub super::super::overflow_x::computed_value::T);
} }
#[derive(Debug, Clone, Copy, PartialEq)]
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
pub struct SpecifiedValue(pub super::overflow_x::SpecifiedValue);
impl ComputedValueAsSpecified for SpecifiedValue {} impl ComputedValueAsSpecified for SpecifiedValue {}
#[inline] #[inline]
@ -434,112 +433,77 @@ ${helpers.single_keyword("overflow-x", "visible hidden scroll auto",
} }
</%helpers:longhand> </%helpers:longhand>
<%helpers:longhand name="transition-duration" <%helpers:vector_longhand name="transition-duration"
need_index="True" need_index="True"
animatable="False" animatable="False"
spec="https://drafts.csswg.org/css-transitions/#propdef-transition-duration"> spec="https://drafts.csswg.org/css-transitions/#propdef-transition-duration">
use values::computed::ComputedValueAsSpecified;
use values::specified::Time; use values::specified::Time;
pub use self::computed_value::T as SpecifiedValue; pub use values::specified::Time as SpecifiedValue;
pub use values::specified::Time as SingleSpecifiedValue;
use values::NoViewportPercentage; use values::NoViewportPercentage;
impl NoViewportPercentage for SpecifiedValue {} impl NoViewportPercentage for SpecifiedValue {}
pub mod computed_value { pub mod computed_value {
use std::fmt; pub use values::computed::Time as T;
use style_traits::ToCss;
use values::computed::{Context, ToComputedValue};
pub use values::computed::Time as SingleComputedValue;
#[derive(Debug, Clone, PartialEq)]
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
pub struct T(pub Vec<SingleComputedValue>);
impl ToCss for T {
fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
if self.0.is_empty() {
return dest.write_str("none")
}
for (i, value) in self.0.iter().enumerate() {
if i != 0 {
try!(dest.write_str(", "))
}
try!(value.to_css(dest))
}
Ok(())
}
}
} }
impl ComputedValueAsSpecified for SpecifiedValue {}
#[inline] #[inline]
pub fn get_initial_single_value() -> Time { pub fn get_initial_value() -> Time {
Time(0.0) Time(0.0)
} }
#[inline]
pub fn get_initial_value() -> computed_value::T {
computed_value::T(vec![get_initial_single_value()])
}
pub fn parse(context: &ParserContext, input: &mut Parser) -> Result<SpecifiedValue,()> { pub fn parse(context: &ParserContext, input: &mut Parser) -> Result<SpecifiedValue,()> {
Ok(SpecifiedValue(try!(input.parse_comma_separated(|i| Time::parse(context, i))))) Time::parse(context, input)
} }
</%helpers:longhand> </%helpers:vector_longhand>
// TODO(pcwalton): Lots more timing functions. // TODO(pcwalton): Lots more timing functions.
<%helpers:longhand name="transition-timing-function" <%helpers:vector_longhand name="transition-timing-function"
need_index="True" need_index="True"
animatable="False" animatable="False"
spec="https://drafts.csswg.org/css-transitions/#propdef-transition-timing-function"> spec="https://drafts.csswg.org/css-transitions/#propdef-transition-timing-function">
use self::computed_value::StartEnd; use self::computed_value::StartEnd;
use self::computed_value::TransitionTimingFunction as ComputedTransitionTimingFunction;
use euclid::point::{Point2D, TypedPoint2D}; use euclid::point::{Point2D, TypedPoint2D};
use std::fmt; use std::fmt;
use std::marker::PhantomData; use std::marker::PhantomData;
use style_traits::ToCss; use style_traits::ToCss;
pub use self::TransitionTimingFunction as SingleSpecifiedValue;
// FIXME: This could use static variables and const functions when they are available. // FIXME: This could use static variables and const functions when they are available.
#[inline(always)] #[inline(always)]
fn ease() -> ComputedTransitionTimingFunction { fn ease() -> computed_value::T {
ComputedTransitionTimingFunction::CubicBezier(TypedPoint2D::new(0.25, 0.1), computed_value::T::CubicBezier(TypedPoint2D::new(0.25, 0.1),
TypedPoint2D::new(0.25, 1.0)) TypedPoint2D::new(0.25, 1.0))
} }
#[inline(always)] #[inline(always)]
fn linear() -> ComputedTransitionTimingFunction { fn linear() -> computed_value::T {
ComputedTransitionTimingFunction::CubicBezier(TypedPoint2D::new(0.0, 0.0), computed_value::T::CubicBezier(TypedPoint2D::new(0.0, 0.0),
TypedPoint2D::new(1.0, 1.0)) TypedPoint2D::new(1.0, 1.0))
} }
#[inline(always)] #[inline(always)]
fn ease_in() -> ComputedTransitionTimingFunction { fn ease_in() -> computed_value::T {
ComputedTransitionTimingFunction::CubicBezier(TypedPoint2D::new(0.42, 0.0), computed_value::T::CubicBezier(TypedPoint2D::new(0.42, 0.0),
TypedPoint2D::new(1.0, 1.0)) TypedPoint2D::new(1.0, 1.0))
} }
#[inline(always)] #[inline(always)]
fn ease_out() -> ComputedTransitionTimingFunction { fn ease_out() -> computed_value::T {
ComputedTransitionTimingFunction::CubicBezier(TypedPoint2D::new(0.0, 0.0), computed_value::T::CubicBezier(TypedPoint2D::new(0.0, 0.0),
TypedPoint2D::new(0.58, 1.0)) TypedPoint2D::new(0.58, 1.0))
} }
#[inline(always)] #[inline(always)]
fn ease_in_out() -> ComputedTransitionTimingFunction { fn ease_in_out() -> computed_value::T {
ComputedTransitionTimingFunction::CubicBezier(TypedPoint2D::new(0.42, 0.0), computed_value::T::CubicBezier(TypedPoint2D::new(0.42, 0.0),
TypedPoint2D::new(0.58, 1.0)) TypedPoint2D::new(0.58, 1.0))
} }
static STEP_START: ComputedTransitionTimingFunction = static STEP_START: computed_value::T =
ComputedTransitionTimingFunction::Steps(1, StartEnd::Start); computed_value::T::Steps(1, StartEnd::Start);
static STEP_END: ComputedTransitionTimingFunction = static STEP_END: computed_value::T =
ComputedTransitionTimingFunction::Steps(1, StartEnd::End); computed_value::T::Steps(1, StartEnd::End);
pub mod computed_value { pub mod computed_value {
use euclid::point::Point2D; use euclid::point::Point2D;
@ -547,20 +511,19 @@ ${helpers.single_keyword("overflow-x", "visible hidden scroll auto",
use std::fmt; use std::fmt;
use style_traits::ToCss; use style_traits::ToCss;
pub use self::TransitionTimingFunction as SingleComputedValue;
pub use super::parse; pub use super::parse;
#[derive(Copy, Clone, Debug, PartialEq)] #[derive(Copy, Clone, Debug, PartialEq)]
#[cfg_attr(feature = "servo", derive(HeapSizeOf))] #[cfg_attr(feature = "servo", derive(HeapSizeOf))]
pub enum TransitionTimingFunction { pub enum T {
CubicBezier(Point2D<f32>, Point2D<f32>), CubicBezier(Point2D<f32>, Point2D<f32>),
Steps(u32, StartEnd), Steps(u32, StartEnd),
} }
impl ToCss for TransitionTimingFunction { impl ToCss for T {
fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write { fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
match *self { match *self {
TransitionTimingFunction::CubicBezier(p1, p2) => { T::CubicBezier(p1, p2) => {
try!(dest.write_str("cubic-bezier(")); try!(dest.write_str("cubic-bezier("));
try!(p1.x.to_css(dest)); try!(p1.x.to_css(dest));
try!(dest.write_str(", ")); try!(dest.write_str(", "));
@ -571,7 +534,7 @@ ${helpers.single_keyword("overflow-x", "visible hidden scroll auto",
try!(p2.y.to_css(dest)); try!(p2.y.to_css(dest));
dest.write_str(")") dest.write_str(")")
} }
TransitionTimingFunction::Steps(steps, start_end) => { T::Steps(steps, start_end) => {
super::serialize_steps(dest, steps, start_end) super::serialize_steps(dest, steps, start_end)
} }
} }
@ -593,25 +556,6 @@ ${helpers.single_keyword("overflow-x", "visible hidden scroll auto",
} }
} }
} }
#[derive(Clone, Debug, PartialEq)]
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
pub struct T(pub Vec<TransitionTimingFunction>);
impl ToCss for T {
fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
if self.0.is_empty() {
return dest.write_str("none")
}
for (i, value) in self.0.iter().enumerate() {
if i != 0 {
try!(dest.write_str(", "))
}
try!(value.to_css(dest))
}
Ok(())
}
}
} }
define_css_keyword_enum!(FunctionKeyword: define_css_keyword_enum!(FunctionKeyword:
@ -625,17 +569,13 @@ ${helpers.single_keyword("overflow-x", "visible hidden scroll auto",
#[derive(Copy, Clone, Debug, PartialEq)] #[derive(Copy, Clone, Debug, PartialEq)]
#[cfg_attr(feature = "servo", derive(HeapSizeOf))] #[cfg_attr(feature = "servo", derive(HeapSizeOf))]
pub enum TransitionTimingFunction { pub enum SpecifiedValue {
CubicBezier(Point2D<f32>, Point2D<f32>), CubicBezier(Point2D<f32>, Point2D<f32>),
Steps(u32, StartEnd), Steps(u32, StartEnd),
Keyword(FunctionKeyword), Keyword(FunctionKeyword),
} }
#[derive(Clone, Debug, PartialEq)] impl Parse for SpecifiedValue {
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
pub struct SpecifiedValue(pub Vec<TransitionTimingFunction>);
impl Parse for TransitionTimingFunction {
fn parse(_context: &ParserContext, input: &mut ::cssparser::Parser) -> Result<Self, ()> { fn parse(_context: &ParserContext, input: &mut ::cssparser::Parser) -> Result<Self, ()> {
if let Ok(function_name) = input.try(|input| input.expect_function()) { if let Ok(function_name) = input.try(|input| input.expect_function()) {
return match_ignore_ascii_case! { function_name, return match_ignore_ascii_case! { function_name,
@ -652,7 +592,7 @@ ${helpers.single_keyword("overflow-x", "visible hidden scroll auto",
Ok(()) Ok(())
})); }));
let (p1, p2) = (Point2D::new(p1x, p1y), Point2D::new(p2x, p2y)); let (p1, p2) = (Point2D::new(p1x, p1y), Point2D::new(p2x, p2y));
Ok(TransitionTimingFunction::CubicBezier(p1, p2)) Ok(SpecifiedValue::CubicBezier(p1, p2))
}, },
"steps" => { "steps" => {
let (mut step_count, mut start_end) = (0, StartEnd::End); let (mut step_count, mut start_end) = (0, StartEnd::End);
@ -668,12 +608,12 @@ ${helpers.single_keyword("overflow-x", "visible hidden scroll auto",
} }
Ok(()) Ok(())
})); }));
Ok(TransitionTimingFunction::Steps(step_count as u32, start_end)) Ok(SpecifiedValue::Steps(step_count as u32, start_end))
}, },
_ => Err(()) _ => Err(())
} }
} }
Ok(TransitionTimingFunction::Keyword(try!(FunctionKeyword::parse(input)))) Ok(SpecifiedValue::Keyword(try!(FunctionKeyword::parse(input))))
} }
} }
@ -688,10 +628,10 @@ ${helpers.single_keyword("overflow-x", "visible hidden scroll auto",
} }
// https://drafts.csswg.org/css-transitions/#serializing-a-timing-function // https://drafts.csswg.org/css-transitions/#serializing-a-timing-function
impl ToCss for TransitionTimingFunction { impl ToCss for SpecifiedValue {
fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write { fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
match *self { match *self {
TransitionTimingFunction::CubicBezier(p1, p2) => { SpecifiedValue::CubicBezier(p1, p2) => {
try!(dest.write_str("cubic-bezier(")); try!(dest.write_str("cubic-bezier("));
try!(p1.x.to_css(dest)); try!(p1.x.to_css(dest));
try!(dest.write_str(", ")); try!(dest.write_str(", "));
@ -702,10 +642,10 @@ ${helpers.single_keyword("overflow-x", "visible hidden scroll auto",
try!(p2.y.to_css(dest)); try!(p2.y.to_css(dest));
dest.write_str(")") dest.write_str(")")
}, },
TransitionTimingFunction::Steps(steps, start_end) => { SpecifiedValue::Steps(steps, start_end) => {
serialize_steps(dest, steps, start_end) serialize_steps(dest, steps, start_end)
}, },
TransitionTimingFunction::Keyword(keyword) => { SpecifiedValue::Keyword(keyword) => {
match keyword { match keyword {
FunctionKeyword::StepStart => { FunctionKeyword::StepStart => {
serialize_steps(dest, 1, StartEnd::Start) serialize_steps(dest, 1, StartEnd::Start)
@ -722,19 +662,19 @@ ${helpers.single_keyword("overflow-x", "visible hidden scroll auto",
} }
} }
impl ToComputedValue for TransitionTimingFunction { impl ToComputedValue for SpecifiedValue {
type ComputedValue = ComputedTransitionTimingFunction; type ComputedValue = computed_value::T;
#[inline] #[inline]
fn to_computed_value(&self, _context: &Context) -> ComputedTransitionTimingFunction { fn to_computed_value(&self, _context: &Context) -> computed_value::T {
match *self { match *self {
TransitionTimingFunction::CubicBezier(p1, p2) => { SpecifiedValue::CubicBezier(p1, p2) => {
ComputedTransitionTimingFunction::CubicBezier(p1, p2) computed_value::T::CubicBezier(p1, p2)
}, },
TransitionTimingFunction::Steps(count, start_end) => { SpecifiedValue::Steps(count, start_end) => {
ComputedTransitionTimingFunction::Steps(count, start_end) computed_value::T::Steps(count, start_end)
}, },
TransitionTimingFunction::Keyword(keyword) => { SpecifiedValue::Keyword(keyword) => {
match keyword { match keyword {
FunctionKeyword::Ease => ease(), FunctionKeyword::Ease => ease(),
FunctionKeyword::Linear => linear(), FunctionKeyword::Linear => linear(),
@ -748,44 +688,15 @@ ${helpers.single_keyword("overflow-x", "visible hidden scroll auto",
} }
} }
#[inline] #[inline]
fn from_computed_value(computed: &ComputedTransitionTimingFunction) -> Self {
match *computed {
computed_value::TransitionTimingFunction::CubicBezier(p1, p2) => {
TransitionTimingFunction::CubicBezier(p1, p2)
},
computed_value::TransitionTimingFunction::Steps(count, start_end) => {
TransitionTimingFunction::Steps(count, start_end)
},
}
}
}
impl ToCss for SpecifiedValue {
fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
if self.0.is_empty() {
return dest.write_str("none")
}
for (i, value) in self.0.iter().enumerate() {
if i != 0 {
try!(dest.write_str(", "))
}
try!(value.to_css(dest))
}
Ok(())
}
}
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.iter().map(|f| f.to_computed_value(context)).collect())
}
#[inline]
fn from_computed_value(computed: &computed_value::T) -> Self { fn from_computed_value(computed: &computed_value::T) -> Self {
SpecifiedValue(computed.0.iter().map(|f| ToComputedValue::from_computed_value(f)) match *computed {
.collect()) computed_value::T::CubicBezier(p1, p2) => {
SpecifiedValue::CubicBezier(p1, p2)
},
computed_value::T::Steps(count, start_end) => {
SpecifiedValue::Steps(count, start_end)
},
}
} }
} }
@ -793,280 +704,192 @@ ${helpers.single_keyword("overflow-x", "visible hidden scroll auto",
impl NoViewportPercentage for SpecifiedValue {} impl NoViewportPercentage for SpecifiedValue {}
#[inline] #[inline]
pub fn get_initial_single_value() -> ComputedTransitionTimingFunction { pub fn get_initial_value() -> computed_value::T {
ease() ease()
} }
#[inline] #[inline]
pub fn get_initial_specified_single_value() -> TransitionTimingFunction { pub fn get_initial_specified_value() -> SpecifiedValue {
ToComputedValue::from_computed_value(&ease()) ToComputedValue::from_computed_value(&ease())
} }
#[inline]
pub fn get_initial_value() -> computed_value::T {
computed_value::T(vec![get_initial_single_value()])
}
pub fn parse(context: &ParserContext, input: &mut Parser) -> Result<SpecifiedValue,()> { pub fn parse(context: &ParserContext, input: &mut Parser) -> Result<SpecifiedValue,()> {
Ok(SpecifiedValue(try!(input.parse_comma_separated(|i| { SpecifiedValue::parse(context, input)
TransitionTimingFunction::parse(context, i)
}))))
} }
</%helpers:longhand> </%helpers:vector_longhand>
<%helpers:longhand name="transition-property" <%helpers:vector_longhand name="transition-property"
need_index="True" allow_empty="True"
animatable="False" need_index="True"
spec="https://drafts.csswg.org/css-transitions/#propdef-transition-property"> animatable="False"
spec="https://drafts.csswg.org/css-transitions/#propdef-transition-property">
use values::computed::ComputedValueAsSpecified; use values::computed::ComputedValueAsSpecified;
pub use self::computed_value::SingleComputedValue as SingleSpecifiedValue; pub use properties::animated_properties::TransitionProperty;
pub use self::computed_value::T as SpecifiedValue; pub use properties::animated_properties::TransitionProperty as SpecifiedValue;
pub mod computed_value { pub mod computed_value {
use std::fmt; use std::fmt;
use style_traits::ToCss; use style_traits::ToCss;
// NB: Can't generate the type here because it needs all the longhands // NB: Can't generate the type here because it needs all the longhands
// generated beforehand. // generated beforehand.
pub use properties::animated_properties::TransitionProperty; pub use super::SpecifiedValue as T;
pub use properties::animated_properties::TransitionProperty as SingleComputedValue;
#[derive(Clone, Debug, PartialEq)]
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
pub struct T(pub Vec<SingleComputedValue>);
impl ToCss for T {
fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
if self.0.is_empty() {
return dest.write_str("none")
}
for (i, value) in self.0.iter().enumerate() {
if i != 0 {
try!(dest.write_str(", "))
}
try!(value.to_css(dest))
}
Ok(())
}
}
}
#[inline]
pub fn get_initial_value() -> computed_value::T {
computed_value::T(Vec::new())
} }
pub fn parse(_context: &ParserContext, input: &mut Parser) -> Result<SpecifiedValue,()> { pub fn parse(_context: &ParserContext, input: &mut Parser) -> Result<SpecifiedValue,()> {
Ok(SpecifiedValue(try!(input.parse_comma_separated(SingleSpecifiedValue::parse)))) SpecifiedValue::parse(input)
} }
use values::NoViewportPercentage; use values::NoViewportPercentage;
impl NoViewportPercentage for SpecifiedValue {} impl NoViewportPercentage for SpecifiedValue {}
impl ComputedValueAsSpecified for SpecifiedValue { } impl ComputedValueAsSpecified for SpecifiedValue { }
</%helpers:longhand> </%helpers:vector_longhand>
<%helpers:longhand name="transition-delay" <%helpers:vector_longhand name="transition-delay"
need_index="True" need_index="True"
animatable="False" animatable="False"
spec="https://drafts.csswg.org/css-transitions/#propdef-transition-delay"> spec="https://drafts.csswg.org/css-transitions/#propdef-transition-delay">
pub use properties::longhands::transition_duration::{SingleSpecifiedValue, SpecifiedValue}; pub use properties::longhands::transition_duration::single_value::SpecifiedValue;
pub use properties::longhands::transition_duration::computed_value; pub use properties::longhands::transition_duration::single_value::computed_value;
pub use properties::longhands::transition_duration::{get_initial_value, get_initial_single_value, parse}; pub use properties::longhands::transition_duration::single_value::{get_initial_value, parse};
</%helpers:longhand> </%helpers:vector_longhand>
<%helpers:longhand name="animation-name" <%helpers:vector_longhand name="animation-name"
need_index="True" allow_empty="True"
animatable="False", need_index="True"
allowed_in_keyframe_block="False" animatable="False",
spec="https://drafts.csswg.org/css-animations/#propdef-animation-name"> allowed_in_keyframe_block="False"
spec="https://drafts.csswg.org/css-animations/#propdef-animation-name">
use Atom;
use std::fmt;
use std::ops::Deref;
use style_traits::ToCss;
use values::computed::ComputedValueAsSpecified; use values::computed::ComputedValueAsSpecified;
use values::NoViewportPercentage; use values::NoViewportPercentage;
pub mod computed_value { pub mod computed_value {
use Atom; pub use super::SpecifiedValue as T;
use parser::{Parse, ParserContext}; }
use std::fmt;
use std::ops::Deref;
use style_traits::ToCss;
#[derive(Clone, Debug, Hash, Eq, PartialEq)] #[derive(Clone, Debug, Hash, Eq, PartialEq)]
#[cfg_attr(feature = "servo", derive(HeapSizeOf))] #[cfg_attr(feature = "servo", derive(HeapSizeOf))]
pub struct AnimationName(pub Atom); pub struct SpecifiedValue(pub Atom);
impl fmt::Display for AnimationName { impl fmt::Display for SpecifiedValue {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
self.0.fmt(f) self.0.fmt(f)
}
}
pub use self::AnimationName as SingleComputedValue;
impl Parse for AnimationName {
fn parse(_context: &ParserContext, input: &mut ::cssparser::Parser) -> Result<Self, ()> {
use cssparser::Token;
Ok(match input.next() {
Ok(Token::Ident(ref value)) if value != "none" => AnimationName(Atom::from(&**value)),
Ok(Token::QuotedString(value)) => AnimationName(Atom::from(&*value)),
_ => return Err(()),
})
}
}
#[derive(Debug, Clone, PartialEq)]
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
pub struct T(pub Vec<AnimationName>);
impl ToCss for T {
fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
if self.0.is_empty() {
return dest.write_str("none")
}
for (i, name) in self.0.iter().enumerate() {
if i != 0 {
try!(dest.write_str(", "));
}
// NB: to_string() needed due to geckolib backend.
try!(dest.write_str(&*name.to_string()));
}
Ok(())
}
} }
} }
pub use self::computed_value::T as SpecifiedValue; impl ToCss for SpecifiedValue {
fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
dest.write_str(&*self.0.to_string())
}
}
impl Parse for SpecifiedValue {
fn parse(_context: &ParserContext, input: &mut ::cssparser::Parser) -> Result<Self, ()> {
use cssparser::Token;
Ok(match input.next() {
Ok(Token::Ident(ref value)) if value != "none" => SpecifiedValue(Atom::from(&**value)),
Ok(Token::QuotedString(value)) => SpecifiedValue(Atom::from(&*value)),
_ => return Err(()),
})
}
}
impl NoViewportPercentage for SpecifiedValue {} impl NoViewportPercentage for SpecifiedValue {}
pub use self::computed_value::SingleComputedValue as SingleSpecifiedValue;
#[inline]
pub fn get_initial_value() -> computed_value::T {
computed_value::T(vec![])
}
pub fn parse(context: &ParserContext, input: &mut Parser) -> Result<SpecifiedValue,()> { pub fn parse(context: &ParserContext, input: &mut Parser) -> Result<SpecifiedValue,()> {
use std::borrow::Cow; SpecifiedValue::parse(context, input)
Ok(SpecifiedValue(try!(input.parse_comma_separated(|i| SingleSpecifiedValue::parse(context, i)))))
} }
impl ComputedValueAsSpecified for SpecifiedValue {} impl ComputedValueAsSpecified for SpecifiedValue {}
</%helpers:longhand> </%helpers:vector_longhand>
<%helpers:longhand name="animation-duration" <%helpers:vector_longhand name="animation-duration"
need_index="True" need_index="True"
animatable="False", animatable="False",
spec="https://drafts.csswg.org/css-animations/#propdef-animation-duration", spec="https://drafts.csswg.org/css-animations/#propdef-animation-duration",
allowed_in_keyframe_block="False"> allowed_in_keyframe_block="False">
pub use super::transition_duration::computed_value; pub use properties::longhands::transition_duration::single_value::computed_value;
pub use super::transition_duration::{get_initial_value, get_initial_single_value, parse}; pub use properties::longhands::transition_duration::single_value::{get_initial_value, parse};
pub use super::transition_duration::SpecifiedValue; pub use properties::longhands::transition_duration::single_value::SpecifiedValue;
pub use super::transition_duration::SingleSpecifiedValue; </%helpers:vector_longhand>
</%helpers:longhand>
<%helpers:longhand name="animation-timing-function" <%helpers:vector_longhand name="animation-timing-function"
need_index="True" need_index="True"
animatable="False", animatable="False",
spec="https://drafts.csswg.org/css-animations/#propdef-animation-timing-function", spec="https://drafts.csswg.org/css-animations/#propdef-animation-timing-function",
allowed_in_keyframe_block="False"> allowed_in_keyframe_block="False">
pub use super::transition_timing_function::computed_value; pub use properties::longhands::transition_timing_function::single_value::computed_value;
pub use super::transition_timing_function::{get_initial_value, get_initial_single_value}; pub use properties::longhands::transition_timing_function::single_value::get_initial_value;
pub use super::transition_timing_function::{get_initial_specified_single_value, parse}; pub use properties::longhands::transition_timing_function::single_value::get_initial_specified_value;
pub use super::transition_timing_function::SpecifiedValue; pub use properties::longhands::transition_timing_function::single_value::parse;
pub use super::transition_timing_function::SingleSpecifiedValue; pub use properties::longhands::transition_timing_function::single_value::SpecifiedValue;
</%helpers:longhand> </%helpers:vector_longhand>
<%helpers:longhand name="animation-iteration-count" <%helpers:vector_longhand name="animation-iteration-count"
need_index="True" need_index="True"
animatable="False", animatable="False",
spec="https://drafts.csswg.org/css-animations/#propdef-animation-iteration-count", spec="https://drafts.csswg.org/css-animations/#propdef-animation-iteration-count",
allowed_in_keyframe_block="False"> allowed_in_keyframe_block="False">
use std::fmt;
use style_traits::ToCss;
use values::computed::ComputedValueAsSpecified; use values::computed::ComputedValueAsSpecified;
use values::NoViewportPercentage; use values::NoViewportPercentage;
pub mod computed_value { pub mod computed_value {
use parser::{Parse, ParserContext}; pub use super::SpecifiedValue as T;
use std::fmt; }
use style_traits::ToCss;
pub use self::AnimationIterationCount as SingleComputedValue; // https://drafts.csswg.org/css-animations/#animation-iteration-count
#[derive(Debug, Clone, PartialEq)]
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
pub enum SpecifiedValue {
Number(f32),
Infinite,
}
// https://drafts.csswg.org/css-animations/#animation-iteration-count impl Parse for SpecifiedValue {
#[derive(Debug, Clone, PartialEq)] fn parse(_context: &ParserContext, input: &mut ::cssparser::Parser) -> Result<Self, ()> {
#[cfg_attr(feature = "servo", derive(HeapSizeOf))] if input.try(|input| input.expect_ident_matching("infinite")).is_ok() {
pub enum AnimationIterationCount { return Ok(SpecifiedValue::Infinite)
Number(f32),
Infinite,
}
impl Parse for AnimationIterationCount {
fn parse(_context: &ParserContext, input: &mut ::cssparser::Parser) -> Result<Self, ()> {
if input.try(|input| input.expect_ident_matching("infinite")).is_ok() {
return Ok(AnimationIterationCount::Infinite)
}
let number = try!(input.expect_number());
if number < 0.0 {
return Err(());
}
Ok(AnimationIterationCount::Number(number))
} }
}
impl ToCss for AnimationIterationCount { let number = try!(input.expect_number());
fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write { if number < 0.0 {
match *self { return Err(());
AnimationIterationCount::Number(n) => write!(dest, "{}", n),
AnimationIterationCount::Infinite => dest.write_str("infinite"),
}
} }
Ok(SpecifiedValue::Number(number))
} }
}
#[derive(Debug, Clone, PartialEq)] impl ToCss for SpecifiedValue {
#[cfg_attr(feature = "servo", derive(HeapSizeOf))] fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
pub struct T(pub Vec<AnimationIterationCount>); match *self {
SpecifiedValue::Number(n) => write!(dest, "{}", n),
impl ToCss for T { SpecifiedValue::Infinite => dest.write_str("infinite"),
fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
if self.0.is_empty() {
return dest.write_str("none")
}
for (i, value) in self.0.iter().enumerate() {
if i != 0 {
try!(dest.write_str(", "))
}
try!(value.to_css(dest))
}
Ok(())
} }
} }
} }
pub use self::computed_value::AnimationIterationCount;
pub use self::computed_value::AnimationIterationCount as SingleSpecifiedValue;
pub use self::computed_value::T as SpecifiedValue;
impl NoViewportPercentage for SpecifiedValue {} impl NoViewportPercentage for SpecifiedValue {}
#[inline] #[inline]
pub fn get_initial_single_value() -> AnimationIterationCount { pub fn get_initial_value() -> computed_value::T {
AnimationIterationCount::Number(1.0) computed_value::T::Number(1.0)
} }
#[inline] #[inline]
pub fn parse(context: &ParserContext, input: &mut Parser) -> Result<SpecifiedValue, ()> { pub fn parse(context: &ParserContext, input: &mut Parser) -> Result<SpecifiedValue, ()> {
Ok(SpecifiedValue(try!(input.parse_comma_separated(|i| { SpecifiedValue::parse(context, input)
AnimationIterationCount::parse(context, i)
}))))
}
#[inline]
pub fn get_initial_value() -> computed_value::T {
computed_value::T(vec![get_initial_single_value()])
} }
impl ComputedValueAsSpecified for SpecifiedValue {} impl ComputedValueAsSpecified for SpecifiedValue {}
</%helpers:longhand> </%helpers:vector_longhand>
${helpers.single_keyword("animation-direction", ${helpers.single_keyword("animation-direction",
"normal reverse alternate alternate-reverse", "normal reverse alternate alternate-reverse",
@ -1095,16 +918,15 @@ ${helpers.single_keyword("animation-fill-mode",
spec="https://drafts.csswg.org/css-animations/#propdef-animation-fill-mode", spec="https://drafts.csswg.org/css-animations/#propdef-animation-fill-mode",
allowed_in_keyframe_block=False)} allowed_in_keyframe_block=False)}
<%helpers:longhand name="animation-delay" <%helpers:vector_longhand name="animation-delay"
need_index="True" need_index="True"
animatable="False", animatable="False",
spec="https://drafts.csswg.org/css-animations/#propdef-animation-delay", spec="https://drafts.csswg.org/css-animations/#propdef-animation-delay",
allowed_in_keyframe_block="False"> allowed_in_keyframe_block="False">
pub use super::transition_duration::computed_value; pub use properties::longhands::transition_duration::single_value::computed_value;
pub use super::transition_duration::{get_initial_value, get_initial_single_value, parse}; pub use properties::longhands::transition_duration::single_value::{get_initial_value, parse};
pub use super::transition_duration::SpecifiedValue; pub use properties::longhands::transition_duration::single_value::SpecifiedValue;
pub use super::transition_duration::SingleSpecifiedValue; </%helpers:vector_longhand>
</%helpers:longhand>
<%helpers:longhand products="gecko" name="scroll-snap-points-y" animatable="False" <%helpers:longhand products="gecko" name="scroll-snap-points-y" animatable="False"
spec="Nonstandard (https://www.w3.org/TR/2015/WD-css-snappoints-1-20150326/#scroll-snap-points)"> spec="Nonstandard (https://www.w3.org/TR/2015/WD-css-snappoints-1-20150326/#scroll-snap-points)">

View file

@ -127,11 +127,12 @@ macro_rules! try_parse_one {
Ok(SingleTransition { Ok(SingleTransition {
transition_property: property, transition_property: property,
transition_duration: transition_duration:
duration.unwrap_or_else(transition_duration::get_initial_single_value), duration.unwrap_or_else(transition_duration::single_value::get_initial_value),
transition_timing_function: transition_timing_function:
timing_function.unwrap_or_else(transition_timing_function::get_initial_specified_single_value), timing_function.unwrap_or_else(transition_timing_function::single_value
::get_initial_specified_value),
transition_delay: transition_delay:
delay.unwrap_or_else(transition_delay::get_initial_single_value), delay.unwrap_or_else(transition_delay::single_value::get_initial_value),
}) })
} else { } else {
Err(()) Err(())
@ -238,13 +239,14 @@ macro_rules! try_parse_one {
Ok(SingleAnimation { Ok(SingleAnimation {
animation_name: name, animation_name: name,
animation_duration: animation_duration:
duration.unwrap_or_else(animation_duration::get_initial_single_value), duration.unwrap_or_else(animation_duration::single_value::get_initial_value),
animation_timing_function: animation_timing_function:
timing_function.unwrap_or_else(animation_timing_function::get_initial_specified_single_value), timing_function.unwrap_or_else(animation_timing_function::single_value
::get_initial_specified_value),
animation_delay: animation_delay:
delay.unwrap_or_else(animation_delay::get_initial_single_value), delay.unwrap_or_else(animation_delay::single_value::get_initial_value),
animation_iteration_count: animation_iteration_count:
iteration_count.unwrap_or_else(animation_iteration_count::get_initial_single_value), iteration_count.unwrap_or_else(animation_iteration_count::single_value::get_initial_value),
animation_direction: animation_direction:
direction.unwrap_or_else(animation_direction::single_value::get_initial_value), direction.unwrap_or_else(animation_direction::single_value::get_initial_value),
animation_fill_mode: animation_fill_mode:

View file

@ -6,7 +6,7 @@ use cssparser::Parser;
use media_queries::CSSErrorReporterTest; use media_queries::CSSErrorReporterTest;
use parsing::parse; use parsing::parse;
use style::parser::{Parse, ParserContext}; use style::parser::{Parse, ParserContext};
use style::properties::longhands::animation_iteration_count::computed_value::AnimationIterationCount; use style::properties::longhands::animation_iteration_count::single_value::computed_value::T as AnimationIterationCount;
use style::stylesheets::Origin; use style::stylesheets::Origin;
use style_traits::ToCss; use style_traits::ToCss;

View file

@ -536,10 +536,10 @@ mod shorthand_serialization {
fn transition_should_serialize_all_available_properties() { fn transition_should_serialize_all_available_properties() {
use euclid::point::Point2D; use euclid::point::Point2D;
use style::properties::animated_properties::TransitionProperty; use style::properties::animated_properties::TransitionProperty;
use style::properties::longhands::transition_delay::SpecifiedValue as DelayContainer;
use style::properties::longhands::transition_duration::SpecifiedValue as DurationContainer; use style::properties::longhands::transition_duration::SpecifiedValue as DurationContainer;
use style::properties::longhands::transition_property::SpecifiedValue as PropertyContainer; use style::properties::longhands::transition_property::SpecifiedValue as PropertyContainer;
use style::properties::longhands::transition_timing_function::SpecifiedValue as TimingContainer; use style::properties::longhands::transition_timing_function;
use style::properties::longhands::transition_timing_function::TransitionTimingFunction;
use style::values::specified::Time as TimeContainer; use style::values::specified::Time as TimeContainer;
let property_name = DeclaredValue::Value( let property_name = DeclaredValue::Value(
@ -551,12 +551,13 @@ mod shorthand_serialization {
); );
let delay = DeclaredValue::Value( let delay = DeclaredValue::Value(
DurationContainer(vec![TimeContainer(4f32)]) DelayContainer(vec![TimeContainer(4f32)])
); );
let timing_function = DeclaredValue::Value( let timing_function = DeclaredValue::Value(
TimingContainer(vec![ transition_timing_function::SpecifiedValue(vec![
TransitionTimingFunction::CubicBezier(Point2D::new(0f32, 5f32), Point2D::new(5f32, 10f32)) transition_timing_function::single_value::SpecifiedValue::CubicBezier(
Point2D::new(0f32, 5f32), Point2D::new(5f32, 10f32))
]) ])
); );