Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Staticize CASCADE_PROPERTIES, (temporarily) fix stylo path for animations, and introduce the long-term path to follow #11972

Merged
merged 5 commits into from Jul 3, 2016

style: Add a generic way to deal with lists of values, ditch all uses…

… of as_servo in style/animations.rs
  • Loading branch information
emilio committed Jul 1, 2016
commit ba53c4ea8db7f9d2028f73db3873b7565f55567a
@@ -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,
@@ -47,7 +47,7 @@ def gecko_constant(self, value):
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 @@ def __init__(self, style_struct, name, animatable=None, derived_from=None, keywo
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()

@@ -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)},
@@ -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">

This comment has been minimized.

@bholley

bholley Jul 1, 2016

Contributor

Nit - the order here isn't consistent.

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,14 +597,17 @@ ${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};
pub use properties::longhands::transition_duration::{get_initial_value, parse, parse_one};
</%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,26 +657,32 @@ ${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};
pub use super::transition_duration::SpecifiedValue;
</%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};
@@ -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,18 +1189,24 @@ 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"]:
fn border_${side}_has_nonzero_width(&self) -> bool {
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`.
ProTip! Use n and p to navigate between commits in a pull request.
You can’t perform that action at this time.