diff options
author | Emilio Cobos Álvarez <me@emiliocobos.me> | 2016-06-30 16:50:09 -0700 |
---|---|---|
committer | Emilio Cobos Álvarez <me@emiliocobos.me> | 2016-07-01 14:22:52 -0700 |
commit | ba53c4ea8db7f9d2028f73db3873b7565f55567a (patch) | |
tree | c9746c178a3fc554d9b2f8a5867f205b245e7e5f | |
parent | 07da4e4ea24deeb9af76a1a5cf284f51650edc60 (diff) | |
download | servo-ba53c4ea8db7f9d2028f73db3873b7565f55567a.tar.gz servo-ba53c4ea8db7f9d2028f73db3873b7565f55567a.zip |
style: Add a generic way to deal with lists of values, ditch all uses of as_servo in style/animations.rs
-rw-r--r-- | components/style/animation.rs | 63 | ||||
-rw-r--r-- | components/style/properties/data.py | 3 | ||||
-rw-r--r-- | components/style/properties/helpers.mako.rs | 2 | ||||
-rw-r--r-- | components/style/properties/longhand/box.mako.rs | 34 | ||||
-rw-r--r-- | components/style/properties/properties.mako.rs | 65 | ||||
-rw-r--r-- | ports/geckolib/properties.mako.rs | 6 |
6 files changed, 120 insertions, 53 deletions
diff --git a/components/style/animation.rs b/components/style/animation.rs index ba833937f6b..594623de06c 100644 --- a/components/style/animation.rs +++ b/components/style/animation.rs @@ -253,10 +253,10 @@ impl PropertyAnimation { new_style: &mut C) -> Vec<PropertyAnimation> { let mut result = vec![]; - let box_style = new_style.as_servo().get_box(); - let transition_property = box_style.transition_property.0[transition_index]; - let timing_function = *box_style.transition_timing_function.0.get_mod(transition_index); - let duration = *box_style.transition_duration.0.get_mod(transition_index); + let box_style = new_style.get_box(); + let transition_property = box_style.transition_property_at(transition_index); + let timing_function = box_style.transition_timing_function_mod(transition_index); + let duration = box_style.transition_duration_mod(transition_index); if transition_property != TransitionProperty::All { @@ -333,23 +333,6 @@ impl PropertyAnimation { } } -/// Accesses an element of an array, "wrapping around" using modular arithmetic. This is needed -/// to handle [repeatable lists][lists] of differing lengths. -/// -/// [lists]: https://drafts.csswg.org/css-transitions/#animtype-repeatable-list -pub trait GetMod { - type Item; - fn get_mod(&self, i: usize) -> &Self::Item; -} - -impl<T> GetMod for Vec<T> { - type Item = T; - #[inline] - fn get_mod(&self, i: usize) -> &T { - &(*self)[i % self.len()] - } -} - /// Inserts transitions into the queue of running animations as applicable for /// the given style difference. This is called from the layout worker threads. /// Returns true if any animations were kicked off and false otherwise. @@ -362,7 +345,7 @@ pub fn start_transitions_if_applicable<Impl: SelectorImplExt>(new_animations_sen new_style: &mut Arc<Impl::ComputedValues>) -> bool { let mut had_animations = false; - for i in 0..new_style.get_box().transition_count() { + for i in 0..new_style.get_box().transition_property_count() { // Create any property animations, if applicable. let property_animations = PropertyAnimation::from_transition(i, old_style, Arc::make_mut(new_style)); for property_animation in property_animations { @@ -372,14 +355,14 @@ pub fn start_transitions_if_applicable<Impl: SelectorImplExt>(new_animations_sen property_animation.update(Arc::get_mut(new_style).unwrap(), 0.0); // Kick off the animation. + let box_style = new_style.get_box(); let now = time::precise_time_s(); - let box_style = new_style.as_servo().get_box(); let start_time = - now + (box_style.transition_delay.0.get_mod(i).seconds() as f64); + now + (box_style.transition_delay_mod(i).seconds() as f64); new_animations_sender .lock().unwrap() .send(Animation::Transition(node, start_time, AnimationFrame { - duration: box_style.transition_duration.0.get_mod(i).seconds() as f64, + duration: box_style.transition_duration_mod(i).seconds() as f64, property_animation: property_animation, }, /* is_expired = */ false)).unwrap(); @@ -427,10 +410,10 @@ pub fn maybe_start_animations<Impl: SelectorImplExt>(context: &SharedStyleContex return false; } - let box_style = new_style.as_servo().get_box(); - for (i, name) in box_style.animation_name.0.iter().enumerate() { + let box_style = new_style.get_box(); + for (i, name) in box_style.animation_name_iter().enumerate() { debug!("maybe_start_animations: name={}", name); - let total_duration = box_style.animation_duration.0.get_mod(i).seconds(); + let total_duration = box_style.animation_duration_mod(i).seconds(); if total_duration == 0. { continue } @@ -446,16 +429,16 @@ pub fn maybe_start_animations<Impl: SelectorImplExt>(context: &SharedStyleContex continue; } - let delay = box_style.animation_delay.0.get_mod(i).seconds(); + let delay = box_style.animation_delay_mod(i).seconds(); let now = time::precise_time_s(); let animation_start = now + delay as f64; - let duration = box_style.animation_duration.0.get_mod(i).seconds(); - let iteration_state = match *box_style.animation_iteration_count.0.get_mod(i) { + let duration = box_style.animation_duration_mod(i).seconds(); + let iteration_state = match box_style.animation_iteration_count_mod(i) { AnimationIterationCount::Infinite => KeyframesIterationState::Infinite, AnimationIterationCount::Number(n) => KeyframesIterationState::Finite(0, n), }; - let animation_direction = *box_style.animation_direction.0.get_mod(i); + let animation_direction = box_style.animation_direction_mod(i); let initial_direction = match animation_direction { AnimationDirection::normal | @@ -464,7 +447,7 @@ pub fn maybe_start_animations<Impl: SelectorImplExt>(context: &SharedStyleContex AnimationDirection::alternate_reverse => AnimationDirection::reverse, }; - let running_state = match *box_style.animation_play_state.0.get_mod(i) { + let running_state = match box_style.animation_play_state_mod(i) { AnimationPlayState::paused => KeyframesRunningState::Paused(0.), AnimationPlayState::running => KeyframesRunningState::Running, }; @@ -556,9 +539,9 @@ where Impl: SelectorImplExt, debug_assert!(!animation.steps.is_empty()); - let maybe_index = style.as_servo() - .get_box().animation_name.0.iter() - .position(|animation_name| name == animation_name); + let maybe_index = style.get_box() + .animation_name_iter() + .position(|animation_name| *name == animation_name); let index = match maybe_index { Some(index) => index, @@ -568,7 +551,7 @@ where Impl: SelectorImplExt, } }; - let total_duration = style.as_servo().get_box().animation_duration.0.get_mod(index).seconds() as f64; + let total_duration = style.get_box().animation_duration_mod(index).seconds() as f64; if total_duration == 0. { debug!("update_style_for_animation: zero duration for animation {:?}", name); return; @@ -648,9 +631,9 @@ where Impl: SelectorImplExt, // NB: The spec says that the timing function can be overwritten // from the keyframe style. - let mut timing_function = *style.as_servo().get_box().animation_timing_function.0.get_mod(index); - if !from_style.as_servo().get_box().animation_timing_function.0.is_empty() { - timing_function = from_style.as_servo().get_box().animation_timing_function.0[0]; + let mut timing_function = style.get_box().animation_timing_function_mod(index); + if from_style.get_box().animation_timing_function_count() != 0 { + timing_function = from_style.get_box().animation_timing_function_at(0); } let target_style = compute_style_for_animation_step(context, diff --git a/components/style/properties/data.py b/components/style/properties/data.py index 04da7ad225b..3baa5780823 100644 --- a/components/style/properties/data.py +++ b/components/style/properties/data.py @@ -47,7 +47,7 @@ class Keyword(object): class Longhand(object): def __init__(self, style_struct, name, animatable=None, derived_from=None, keyword=None, predefined_type=None, custom_cascade=False, experimental=False, internal=False, - need_clone=False, gecko_ffi_name=None): + need_clone=False, need_index=False, gecko_ffi_name=None): self.name = name self.keyword = keyword self.predefined_type = predefined_type @@ -58,6 +58,7 @@ class Longhand(object): self.custom_cascade = custom_cascade self.internal = internal self.need_clone = need_clone + self.need_index = need_index self.gecko_ffi_name = gecko_ffi_name or "m" + self.camel_case self.derived_from = (derived_from or "").split() diff --git a/components/style/properties/helpers.mako.rs b/components/style/properties/helpers.mako.rs index b704ef9784b..cd85567c856 100644 --- a/components/style/properties/helpers.mako.rs +++ b/components/style/properties/helpers.mako.rs @@ -225,6 +225,8 @@ } } + pub use self::${to_camel_case(name)} as SingleComputedValue; + define_css_keyword_enum! { ${to_camel_case(name)}: % for value in data.longhands_by_name[name].keyword.values_for(product): "${value}" => ${to_rust_ident(value)}, diff --git a/components/style/properties/longhand/box.mako.rs b/components/style/properties/longhand/box.mako.rs index ecfba4e34d9..9ec51e960cd 100644 --- a/components/style/properties/longhand/box.mako.rs +++ b/components/style/properties/longhand/box.mako.rs @@ -7,8 +7,7 @@ <% data.new_style_struct("Box", inherited=False, - gecko_name="Display", - additional_methods=[Method("transition_count", "usize")]) %> + gecko_name="Display") %> // TODO(SimonSapin): don't parse `inline-table`, since we don't support it <%helpers:longhand name="display" @@ -285,7 +284,9 @@ ${helpers.single_keyword("overflow-x", "visible hidden scroll auto", </%helpers:longhand> // TODO(pcwalton): Multiple transitions. -<%helpers:longhand name="transition-duration" animatable="False"> +<%helpers:longhand name="transition-duration" + need_index="True" + animatable="False"> use values::computed::ComputedValueAsSpecified; use values::specified::Time; @@ -343,7 +344,9 @@ ${helpers.single_keyword("overflow-x", "visible hidden scroll auto", // TODO(pcwalton): Lots more timing functions. // TODO(pcwalton): Multiple transitions. -<%helpers:longhand name="transition-timing-function" animatable="False"> +<%helpers:longhand name="transition-timing-function" + need_index="True" + animatable="False"> use self::computed_value::{StartEnd, TransitionTimingFunction}; use euclid::point::Point2D; @@ -541,7 +544,9 @@ ${helpers.single_keyword("overflow-x", "visible hidden scroll auto", } </%helpers:longhand> -<%helpers:longhand name="transition-property" animatable="False"> +<%helpers:longhand name="transition-property" + need_index="True" + animatable="False"> pub use self::computed_value::SingleComputedValue as SingleSpecifiedValue; pub use self::computed_value::T as SpecifiedValue; @@ -592,7 +597,9 @@ ${helpers.single_keyword("overflow-x", "visible hidden scroll auto", } </%helpers:longhand> -<%helpers:longhand name="transition-delay" animatable="False"> +<%helpers:longhand name="transition-delay" + need_index="True" + animatable="False"> pub use properties::longhands::transition_duration::{SingleSpecifiedValue, SpecifiedValue}; pub use properties::longhands::transition_duration::{computed_value}; pub use properties::longhands::transition_duration::{get_initial_single_value}; @@ -600,6 +607,7 @@ ${helpers.single_keyword("overflow-x", "visible hidden scroll auto", </%helpers:longhand> <%helpers:longhand name="animation-name" + need_index="True" animatable="False"> use values::computed::ComputedValueAsSpecified; @@ -608,6 +616,8 @@ ${helpers.single_keyword("overflow-x", "visible hidden scroll auto", use std::fmt; use string_cache::Atom; + pub use string_cache::Atom as SingleComputedValue; + #[derive(Debug, Clone, PartialEq, HeapSizeOf)] pub struct T(pub Vec<Atom>); @@ -647,6 +657,7 @@ ${helpers.single_keyword("overflow-x", "visible hidden scroll auto", </%helpers:longhand> <%helpers:longhand name="animation-duration" + need_index="True" animatable="False"> pub use super::transition_duration::computed_value; pub use super::transition_duration::{parse, get_initial_value}; @@ -654,19 +665,24 @@ ${helpers.single_keyword("overflow-x", "visible hidden scroll auto", </%helpers:longhand> <%helpers:longhand name="animation-timing-function" + need_index="True" animatable="False"> pub use super::transition_timing_function::computed_value; pub use super::transition_timing_function::{parse, get_initial_value}; pub use super::transition_timing_function::SpecifiedValue; </%helpers:longhand> -<%helpers:longhand name="animation-iteration-count" animatable="False"> +<%helpers:longhand name="animation-iteration-count" + need_index="True" + animatable="False"> use values::computed::ComputedValueAsSpecified; pub mod computed_value { use cssparser::ToCss; use std::fmt; + pub use self::AnimationIterationCount as SingleComputedValue; + #[derive(Debug, Clone, PartialEq, HeapSizeOf)] pub enum AnimationIterationCount { Number(u32), @@ -731,18 +747,22 @@ ${helpers.single_keyword("overflow-x", "visible hidden scroll auto", ${helpers.keyword_list("animation-direction", "normal reverse alternate alternate-reverse", + need_index=True, animatable=False)} ${helpers.keyword_list("animation-play-state", "running paused", need_clone=True, + need_index=True, animatable=False)} ${helpers.keyword_list("animation-fill-mode", "none forwards backwards both", + need_index=True, animatable=False)} <%helpers:longhand name="animation-delay" + need_index="True" animatable="False"> pub use super::transition_duration::computed_value; pub use super::transition_duration::{parse, get_initial_value}; diff --git a/components/style/properties/properties.mako.rs b/components/style/properties/properties.mako.rs index 0744252cc06..3269b89a46b 100644 --- a/components/style/properties/properties.mako.rs +++ b/components/style/properties/properties.mako.rs @@ -1082,12 +1082,61 @@ pub mod style_struct_traits { #[allow(non_snake_case)] fn clone_${longhand.ident}(&self) -> longhands::${longhand.ident}::computed_value::T; % endif + % if longhand.need_index: + #[allow(non_snake_case)] + fn ${longhand.ident}_count(&self) -> usize; + + #[allow(non_snake_case)] + fn ${longhand.ident}_at(&self, index: usize) + -> longhands::${longhand.ident}::computed_value::SingleComputedValue; + + #[allow(non_snake_case)] + #[inline] + fn ${longhand.ident}_iter<'a>(&'a self) + -> ${longhand.camel_case}Iter<'a, Self> { + ${longhand.camel_case}Iter { + style_struct: self, + current: 0, + max: self.${longhand.ident}_count(), + } + } + + #[allow(non_snake_case)] + #[inline] + fn ${longhand.ident}_mod(&self, index: usize) + -> longhands::${longhand.ident}::computed_value::SingleComputedValue { + self.${longhand.ident}_at(index % self.${longhand.ident}_count()) + } + % endif % endfor % for additional in style_struct.additional_methods: #[allow(non_snake_case)] ${additional.declare()} % endfor } + + % for longhand in style_struct.longhands: + % if longhand.need_index: + pub struct ${longhand.camel_case}Iter<'a, S: ${style_struct.trait_name} + 'static> { + style_struct: &'a S, + current: usize, + max: usize, + } + + impl<'a, S: ${style_struct.trait_name} + 'static> Iterator for ${longhand.camel_case}Iter<'a, S> { + type Item = longhands::${longhand.ident}::computed_value::SingleComputedValue; + + fn next(&mut self) -> Option<Self::Item> { + self.current += 1; + if self.current <= self.max { + Some(self.style_struct.${longhand.ident}_at(self.current - 1)) + } else { + None + } + } + } + % endif + % endfor % endfor } @@ -1140,6 +1189,17 @@ pub mod style_structs { self.${longhand.ident}.clone() } % endif + + % if longhand.need_index: + fn ${longhand.ident}_count(&self) -> usize { + self.${longhand.ident}.0.len() + } + + fn ${longhand.ident}_at(&self, index: usize) + -> longhands::${longhand.ident}::computed_value::SingleComputedValue { + self.${longhand.ident}.0[index].clone() + } + % endif % endfor % if style_struct.trait_name == "Border": % for side in ["top", "right", "bottom", "left"]: @@ -1147,11 +1207,6 @@ pub mod style_structs { self.border_${side}_width != ::app_units::Au(0) } % endfor - % elif style_struct.trait_name == "Box": - #[inline] - fn transition_count(&self) -> usize { - self.transition_property.0.len() - } % elif style_struct.trait_name == "Font": fn compute_font_hash(&mut self) { // Corresponds to the fields in `gfx::font_template::FontTemplateDescriptor`. diff --git a/ports/geckolib/properties.mako.rs b/ports/geckolib/properties.mako.rs index c66598fa0d3..40c10ea160e 100644 --- a/ports/geckolib/properties.mako.rs +++ b/ports/geckolib/properties.mako.rs @@ -447,6 +447,12 @@ impl ${style_struct.trait_name} for ${style_struct.gecko_struct_name} { unimplemented!() } % endif + % if longhand.need_index: + fn ${longhand.ident}_count(&self) -> usize { 0 } + fn ${longhand.ident}_at(&self, _index: usize) -> longhands::${longhand.ident}::computed_value::SingleComputedValue { + unimplemented!() + } + % endif % endfor <% additionals = [x for x in style_struct.additional_methods if skip_additionals != "*" and not x.name in skip_additionals.split()] %> |