aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ports/geckolib/glue.rs37
1 files changed, 28 insertions, 9 deletions
diff --git a/ports/geckolib/glue.rs b/ports/geckolib/glue.rs
index 7978c367d6f..f3c6b680f41 100644
--- a/ports/geckolib/glue.rs
+++ b/ports/geckolib/glue.rs
@@ -62,6 +62,7 @@ use style::gecko_bindings::structs;
use style::gecko_bindings::structs::{RawServoStyleRule, ServoStyleSheet};
use style::gecko_bindings::structs::{SheetParsingMode, nsIAtom, nsCSSPropertyID};
use style::gecko_bindings::structs::{nsRestyleHint, nsChangeHint, nsCSSFontFaceRule};
+use style::gecko_bindings::structs::CompositeOperation;
use style::gecko_bindings::structs::Loader;
use style::gecko_bindings::structs::RawGeckoPresContextOwned;
use style::gecko_bindings::structs::ServoElementSnapshotTable;
@@ -325,12 +326,16 @@ pub extern "C" fn Servo_AnimationCompose(raw_value_map: RawServoAnimationValueMa
let property: TransitionProperty = css_property.into();
let value_map = AnimationValueMap::from_ffi_mut(raw_value_map);
+ let need_underlying_value = segment.mFromValue.mServo.mRawPtr.is_null() ||
+ segment.mToValue.mServo.mRawPtr.is_null() ||
+ segment.mFromComposite != CompositeOperation::Replace ||
+ segment.mToComposite != CompositeOperation::Replace;
+
// If either of the segment endpoints are null, get the underlying value to
// use from the current value in the values map (set by a lower-priority
// effect), or, if there is no current value, look up the cached base value
// for this property.
- let underlying_value = if segment.mFromValue.mServo.mRawPtr.is_null() ||
- segment.mToValue.mServo.mRawPtr.is_null() {
+ let underlying_value = if need_underlying_value {
let previous_composed_value = value_map.get(&property).cloned();
previous_composed_value.or_else(|| {
let raw_base_style = unsafe { Gecko_AnimationGetBaseStyle(base_values, css_property) };
@@ -340,26 +345,40 @@ pub extern "C" fn Servo_AnimationCompose(raw_value_map: RawServoAnimationValueMa
None
};
- if (segment.mFromValue.mServo.mRawPtr.is_null() ||
- segment.mToValue.mServo.mRawPtr.is_null()) &&
- underlying_value.is_none() {
- warn!("Underlying value should be valid in the case where either 'from' value or 'to' value is null");
+ if need_underlying_value && underlying_value.is_none() {
+ warn!("Underlying value should be valid when we expect to use it");
return;
}
- // Declare for making derefenced raw pointer alive outside the if block.
+ // Temporaries used in the following if-block whose lifetimes we need to prlong.
let raw_from_value;
+ let from_composite_result;
let from_value = if !segment.mFromValue.mServo.mRawPtr.is_null() {
raw_from_value = unsafe { &*segment.mFromValue.mServo.mRawPtr };
- AnimationValue::as_arc(&raw_from_value).as_ref()
+ match segment.mFromComposite {
+ CompositeOperation::Add => {
+ let value_to_composite = AnimationValue::as_arc(&raw_from_value).as_ref();
+ from_composite_result = underlying_value.as_ref().unwrap().add(value_to_composite);
+ from_composite_result.as_ref().unwrap_or(value_to_composite)
+ }
+ _ => { AnimationValue::as_arc(&raw_from_value) }
+ }
} else {
underlying_value.as_ref().unwrap()
};
let raw_to_value;
+ let to_composite_result;
let to_value = if !segment.mToValue.mServo.mRawPtr.is_null() {
raw_to_value = unsafe { &*segment.mToValue.mServo.mRawPtr };
- AnimationValue::as_arc(&raw_to_value).as_ref()
+ match segment.mToComposite {
+ CompositeOperation::Add => {
+ let value_to_composite = AnimationValue::as_arc(&raw_to_value).as_ref();
+ to_composite_result = underlying_value.as_ref().unwrap().add(value_to_composite);
+ to_composite_result.as_ref().unwrap_or(value_to_composite)
+ }
+ _ => { AnimationValue::as_arc(&raw_to_value) }
+ }
} else {
underlying_value.as_ref().unwrap()
};