diff --git a/ports/geckolib/glue.rs b/ports/geckolib/glue.rs index 09199f6d93f..fc4110626aa 100644 --- a/ports/geckolib/glue.rs +++ b/ports/geckolib/glue.rs @@ -2863,32 +2863,56 @@ pub extern "C" fn Servo_GetComputedKeyframeValues(keyframes: RawGeckoKeyframeLis let mut seen = LonghandIdSet::new(); - // mServoDeclarationBlock is null in the case where we have an invalid css property. - let iter = keyframe.mPropertyValues.iter() - .filter(|&property| !property.mServoDeclarationBlock.mRawPtr.is_null()); + let iter = keyframe.mPropertyValues.iter(); let mut property_index = 0; for property in iter { if simulate_compute_values_failure(property) { continue; } + let mut maybe_append_animation_value = |property: AnimatableLonghand, + value: Option| { + if seen.has_animatable_longhand_bit(&property) { + return; + } + seen.set_animatable_longhand_bit(&property); + + // This is safe since we immediately write to the uninitialized values. + unsafe { animation_values.set_len((property_index + 1) as u32) }; + animation_values[property_index].mProperty = (&property).into(); + // We only make sure we have enough space for this variable, + // but didn't construct a default value for StyleAnimationValue, + // so we should zero it to avoid getting undefined behaviors. + animation_values[property_index].mValue.mGecko = unsafe { mem::zeroed() }; + match value { + Some(v) => { + animation_values[property_index].mValue.mServo.set_arc_leaky(Arc::new(v)); + }, + None => { + animation_values[property_index].mValue.mServo.mRawPtr = ptr::null_mut(); + }, + } + property_index += 1; + }; + + if property.mServoDeclarationBlock.mRawPtr.is_null() { + let animatable_longhand = + AnimatableLonghand::from_nscsspropertyid(property.mProperty); + // |keyframes.mPropertyValues| should only contain animatable + // properties, but we check the result from_nscsspropertyid + // just in case. + if let Some(property) = animatable_longhand { + maybe_append_animation_value(property, None); + } + continue; + } + let declarations = unsafe { &*property.mServoDeclarationBlock.mRawPtr.clone() }; let declarations = Locked::::as_arc(&declarations); let guard = declarations.read_with(&guard); for anim in guard.to_animation_value_iter(&mut context, &default_values) { - if !seen.has_animatable_longhand_bit(&anim.0) { - // This is safe since we immediately write to the uninitialized values. - unsafe { animation_values.set_len((property_index + 1) as u32) }; - seen.set_animatable_longhand_bit(&anim.0); - animation_values[property_index].mProperty = (&anim.0).into(); - // We only make sure we have enough space for this variable, - // but didn't construct a default value for StyleAnimationValue, - // so we should zero it to avoid getting undefined behaviors. - animation_values[property_index].mValue.mGecko = unsafe { mem::zeroed() }; - animation_values[property_index].mValue.mServo.set_arc_leaky(Arc::new(anim.1)); - property_index += 1; - } + maybe_append_animation_value(anim.0, Some(anim.1)); } } }