Fill computed property values where the propery is missing in initial and final keyframes.

@keyframes anim {
  from { opacity: 0; transform: none; }
  to { transform: none; }
}

In above case, we have to add opacity property and value in the 'to' keyframe.
This commit is contained in:
Hiroyuki Ikezoe 2017-02-22 18:50:35 +09:00
parent 501edfdbdb
commit 396db281e3
2 changed files with 39 additions and 10 deletions

View file

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

View file

@ -1435,6 +1435,9 @@ pub extern "C" fn Servo_StyleSet_FillKeyframesForName(raw_data: RawServoStyleSet
timing_function: *const nsTimingFunction, timing_function: *const nsTimingFunction,
style: ServoComputedValuesBorrowed, style: ServoComputedValuesBorrowed,
keyframes: RawGeckoKeyframeListBorrowedMut) -> bool { keyframes: RawGeckoKeyframeListBorrowedMut) -> bool {
use style::gecko_bindings::structs::Keyframe;
use style::properties::property_bit_field::PropertyBitField;
let data = PerDocumentStyleData::from_ffi(raw_data).borrow_mut(); let data = PerDocumentStyleData::from_ffi(raw_data).borrow_mut();
let name = unsafe { Atom::from(name.as_ref().unwrap().as_str_unchecked()) }; let name = unsafe { Atom::from(name.as_ref().unwrap().as_str_unchecked()) };
let style_timing_function = unsafe { timing_function.as_ref().unwrap() }; let style_timing_function = unsafe { timing_function.as_ref().unwrap() };
@ -1455,16 +1458,25 @@ pub extern "C" fn Servo_StyleSet_FillKeyframesForName(raw_data: RawServoStyleSet
&timing_function) &timing_function)
}; };
fn add_computed_property_value(keyframe: *mut Keyframe,
index: usize,
style: &ComputedValues,
property: &TransitionProperty) {
let block = style.to_declaration_block(property.clone().into());
unsafe {
(*keyframe).mPropertyValues.set_len((index + 1) as u32);
(*keyframe).mPropertyValues[index].mProperty = property.clone().into();
// FIXME. Do not set computed values once we handles missing keyframes
// with additive composition.
(*keyframe).mPropertyValues[index].mServoDeclarationBlock.set_arc_leaky(
Arc::new(RwLock::new(block)));
}
}
match step.value { match step.value {
KeyframesStepValue::ComputedValues => { KeyframesStepValue::ComputedValues => {
for (index, property) in animation.properties_changed.iter().enumerate() { for (index, property) in animation.properties_changed.iter().enumerate() {
let block = style.to_declaration_block(property.clone().into()); add_computed_property_value(keyframe, index, style, property);
unsafe {
(*keyframe).mPropertyValues.set_len((index + 1) as u32);
(*keyframe).mPropertyValues[index].mProperty = property.clone().into();
(*keyframe).mPropertyValues[index].mServoDeclarationBlock.set_arc_leaky(
Arc::new(RwLock::new(block)));
}
} }
}, },
KeyframesStepValue::Declarations { ref block } => { KeyframesStepValue::Declarations { ref block } => {
@ -1476,16 +1488,33 @@ pub extern "C" fn Servo_StyleSet_FillKeyframesForName(raw_data: RawServoStyleSet
.filter(|&&(ref declaration, _)| { .filter(|&&(ref declaration, _)| {
declaration.is_animatable() declaration.is_animatable()
}); });
let mut seen = PropertyBitField::new();
for (index, &(ref declaration, _)) in animatable.enumerate() { for (index, &(ref declaration, _)) in animatable.enumerate() {
unsafe { unsafe {
let property = TransitionProperty::from_declaration(declaration).unwrap();
(*keyframe).mPropertyValues.set_len((index + 1) as u32); (*keyframe).mPropertyValues.set_len((index + 1) as u32);
(*keyframe).mPropertyValues[index].mProperty = (*keyframe).mPropertyValues[index].mProperty = property.into();
TransitionProperty::from_declaration(declaration).unwrap().into();
(*keyframe).mPropertyValues[index].mServoDeclarationBlock.set_arc_leaky( (*keyframe).mPropertyValues[index].mServoDeclarationBlock.set_arc_leaky(
Arc::new(RwLock::new( Arc::new(RwLock::new(
PropertyDeclarationBlock { declarations: vec![ (declaration.clone(), PropertyDeclarationBlock { declarations: vec![ (declaration.clone(),
Importance::Normal) ], Importance::Normal) ],
important_count: 0 }))); important_count: 0 })));
if step.start_percentage.0 == 0. ||
step.start_percentage.0 == 1. {
seen.set_transition_property_bit(&property);
}
}
}
// Append missing property values in the initial or the finial keyframes.
if step.start_percentage.0 == 0. ||
step.start_percentage.0 == 1. {
for (index, property) in animation.properties_changed.iter().enumerate() {
if !seen.has_transition_property_bit(&property) {
add_computed_property_value(keyframe, index, style, property);
}
} }
} }
}, },