Auto merge of #15683 - hiikezoe:fill-missing-property-in-keyframe, r=emilio

Fill missing property in keyframe

<!-- Please describe your changes on the following line: -->
This is a PR of https://bugzilla.mozilla.org/show_bug.cgi?id=1340961
All patches has been reviewed by @emilio.

Thanks!

---
<!-- 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
- [ ] These changes fix #__ (github issue number if applicable).

<!-- Either: -->
- [X] There are tests for these changes

<!-- 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/15683)
<!-- Reviewable:end -->
This commit is contained in:
bors-servo 2017-02-22 08:17:18 -08:00 committed by GitHub
commit 4f7e422054
5 changed files with 262 additions and 25 deletions

View file

@ -15,6 +15,7 @@ use properties::{PropertyDeclarationId, LonghandId, DeclaredValue};
use properties::PropertyDeclarationParseResult;
use properties::animated_properties::TransitionProperty;
use properties::longhands::transition_timing_function::single_value::SpecifiedValue as SpecifiedTimingFunction;
use properties::property_bit_field::PropertyBitField;
use std::fmt;
use std::sync::Arc;
use style_traits::ToCss;
@ -244,21 +245,23 @@ pub struct KeyframesAnimation {
pub properties_changed: Vec<TransitionProperty>,
}
/// Get all the animated properties in a keyframes animation. Note that it's not
/// defined what happens when a property is not on a keyframe, so we only peek
/// the props of the first one.
///
/// In practice, browsers seem to try to do their best job at it, so we might
/// want to go through all the actual keyframes and deduplicate properties.
fn get_animated_properties(keyframe: &Keyframe) -> Vec<TransitionProperty> {
/// Get all the animated properties in a keyframes animation.
fn get_animated_properties(keyframes: &[Arc<RwLock<Keyframe>>]) -> Vec<TransitionProperty> {
let mut ret = vec![];
let mut seen = PropertyBitField::new();
// NB: declarations are already deduplicated, so we don't have to check for
// it here.
for &(ref declaration, importance) in keyframe.block.read().declarations.iter() {
assert!(!importance.important());
for keyframe in keyframes {
let keyframe = keyframe.read();
for &(ref declaration, importance) in keyframe.block.read().declarations.iter() {
assert!(!importance.important());
if let Some(property) = TransitionProperty::from_declaration(declaration) {
ret.push(property);
if let Some(property) = TransitionProperty::from_declaration(declaration) {
if !seen.has_transition_property_bit(&property) {
ret.push(property);
seen.set_transition_property_bit(&property);
}
}
}
}
@ -284,7 +287,7 @@ impl KeyframesAnimation {
return result;
}
result.properties_changed = get_animated_properties(&keyframes[0].read());
result.properties_changed = get_animated_properties(keyframes);
if result.properties_changed.is_empty() {
return result;
}

View file

@ -43,7 +43,7 @@ use values::specified::Angle as SpecifiedAngle;
/// property.
// NB: This needs to be here because it needs all the longhands generated
// beforehand.
#[derive(Copy, Clone, Debug, PartialEq)]
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
pub enum TransitionProperty {
/// All, any animatable property changing should generate a transition.

View file

@ -181,8 +181,10 @@ pub mod animated_properties {
// TODO(SimonSapin): Convert this to a syntax extension rather than a Mako template.
// Maybe submit for inclusion in libstd?
mod property_bit_field {
#[allow(missing_docs)]
pub mod property_bit_field {
use logical_geometry::WritingMode;
use properties::animated_properties::TransitionProperty;
/// A bitfield for all longhand properties, in order to quickly test whether
/// we've seen one of them.
@ -213,7 +215,7 @@ mod property_bit_field {
pub fn get_${property.ident}(&self) -> bool {
self.get(${i})
}
#[allow(non_snake_case)]
#[allow(non_snake_case, missing_docs)]
#[inline]
pub fn set_${property.ident}(&mut self) {
self.set(${i})
@ -238,6 +240,32 @@ mod property_bit_field {
}
% endif
% endfor
/// Set the corresponding bit of TransitionProperty.
/// This function will panic if TransitionProperty::All is given.
pub fn set_transition_property_bit(&mut self, property: &TransitionProperty) {
match *property {
% for i, prop in enumerate(data.longhands):
% if prop.animatable:
TransitionProperty::${prop.camel_case} => self.set(${i}),
% endif
% endfor
TransitionProperty::All => unreachable!("Tried to set TransitionProperty::All in a PropertyBitfield"),
}
}
/// Return true if the corresponding bit of TransitionProperty is set.
/// This function will panic if TransitionProperty::All is given.
pub fn has_transition_property_bit(&self, property: &TransitionProperty) -> bool {
match *property {
% for i, prop in enumerate(data.longhands):
% if prop.animatable:
TransitionProperty::${prop.camel_case} => self.get(${i}),
% endif
% endfor
TransitionProperty::All => unreachable!("Tried to get TransitionProperty::All in a PropertyBitfield"),
}
}
}
}