Iterate through properties in priority order when computing keyframes

This is largely just a translation of Gecko's
PropertyPriorityIterator[1] into rust with the exception that IDL sort
order is only defined for shorthands since that's all we currently
require.

[1] http://searchfox.org/mozilla-central/rev/3a3af33f513071ea829debdfbc628caebcdf6996/dom/animation/KeyframeUtils.cpp#151
This commit is contained in:
Brian Birtles 2017-07-24 13:50:18 +09:00
parent 46ffcbaf7b
commit 8e7011da8a
3 changed files with 112 additions and 5 deletions

View file

@ -83,6 +83,7 @@ use style::gecko_bindings::structs::nsCSSValueSharedList;
use style::gecko_bindings::structs::nsCompatibility;
use style::gecko_bindings::structs::nsIDocument;
use style::gecko_bindings::structs::nsStyleTransformMatrix::MatrixTransformOperator;
use style::gecko_bindings::structs::nsTArray;
use style::gecko_bindings::structs::nsresult;
use style::gecko_bindings::sugar::ownership::{FFIArcHelpers, HasFFI, HasArcFFI, HasBoxFFI};
use style::gecko_bindings::sugar::ownership::{HasSimpleFFI, Strong};
@ -94,9 +95,10 @@ use style::parallel;
use style::parser::ParserContext;
use style::properties::{ComputedValues, Importance};
use style::properties::{IS_FIELDSET_CONTENT, LonghandIdSet};
use style::properties::{PropertyDeclaration, PropertyDeclarationBlock, PropertyId};
use style::properties::{PropertyDeclaration, PropertyDeclarationBlock, PropertyId, ShorthandId};
use style::properties::{SKIP_ROOT_AND_ITEM_BASED_DISPLAY_FIXUP, SourcePropertyDeclaration, StyleBuilder};
use style::properties::animated_properties::{Animatable, AnimatableLonghand, AnimationValue};
use style::properties::animated_properties::compare_property_priority;
use style::properties::parse_one_declaration_into;
use style::rule_tree::StyleSource;
use style::selector_parser::PseudoElementCascadeType;
@ -2916,6 +2918,53 @@ fn create_context<'a>(
}
}
struct PropertyAndIndex {
property: PropertyId,
index: usize,
}
struct PrioritizedPropertyIter<'a> {
properties: &'a nsTArray<PropertyValuePair>,
sorted_property_indices: Vec<PropertyAndIndex>,
curr: usize,
}
impl<'a> PrioritizedPropertyIter<'a> {
pub fn new(properties: &'a nsTArray<PropertyValuePair>) -> PrioritizedPropertyIter {
// If we fail to convert a nsCSSPropertyID into a PropertyId we shouldn't fail outright
// but instead by treating that property as the 'all' property we make it sort last.
let all = PropertyId::Shorthand(ShorthandId::All);
let mut sorted_property_indices: Vec<PropertyAndIndex> =
properties.iter().enumerate().map(|(index, pair)| {
PropertyAndIndex {
property: PropertyId::from_nscsspropertyid(pair.mProperty)
.unwrap_or(all.clone()),
index,
}
}).collect();
sorted_property_indices.sort_by(|a, b| compare_property_priority(&a.property, &b.property));
PrioritizedPropertyIter {
properties,
sorted_property_indices,
curr: 0,
}
}
}
impl<'a> Iterator for PrioritizedPropertyIter<'a> {
type Item = &'a PropertyValuePair;
fn next(&mut self) -> Option<&'a PropertyValuePair> {
if self.curr >= self.sorted_property_indices.len() {
return None
}
self.curr += 1;
Some(&self.properties[self.sorted_property_indices[self.curr - 1].index])
}
}
#[no_mangle]
pub extern "C" fn Servo_GetComputedKeyframeValues(keyframes: RawGeckoKeyframeListBorrowed,
element: RawGeckoElementBorrowed,
@ -2946,9 +2995,8 @@ pub extern "C" fn Servo_GetComputedKeyframeValues(keyframes: RawGeckoKeyframeLis
let mut seen = LonghandIdSet::new();
let iter = keyframe.mPropertyValues.iter();
let mut property_index = 0;
for property in iter {
for property in PrioritizedPropertyIter::new(&keyframe.mPropertyValues) {
if simulate_compute_values_failure(property) {
continue;
}