Bug 1254419 - Fill in values sequence in getProperties(); r=heycam draft
authorBrian Birtles <birtles@gmail.com>
Tue, 15 Mar 2016 21:42:14 +0800
changeset 341463 c5466cd6b4132c69bac24af0b0b004704c311371
parent 341462 5452e8cbfb3f177985d9ea514380222895e8ee82
child 341464 c30d955d7c204149af6dc0985cd7b04c41ae00b4
push id13215
push userbbirtles@mozilla.com
push dateThu, 17 Mar 2016 02:17:54 +0000
reviewersheycam
bugs1254419
milestone48.0a1
Bug 1254419 - Fill in values sequence in getProperties(); r=heycam MozReview-Commit-ID: 1qMmy14R4DG
dom/animation/KeyframeEffect.cpp
--- a/dom/animation/KeyframeEffect.cpp
+++ b/dom/animation/KeyframeEffect.cpp
@@ -1794,16 +1794,39 @@ KeyframeEffectReadOnly::GetTarget(
       break;
 
     default:
       NS_NOTREACHED("Animation of unsupported pseudo-type");
       aRv.SetNull();
   }
 }
 
+static void
+CreatePropertyValue(nsCSSProperty aProperty,
+                    float aOffset,
+                    const Maybe<ComputedTimingFunction>& aTimingFunction,
+                    const StyleAnimationValue& aValue,
+                    AnimationPropertyValueDetails& aResult)
+{
+  aResult.mOffset.Construct(aOffset);
+
+  nsString stringValue;
+  StyleAnimationValue::UncomputeValue(aProperty, aValue, stringValue);
+  aResult.mValue.Construct(stringValue);
+
+  if (aTimingFunction) {
+    aResult.mEasing.Construct();
+    aTimingFunction->AppendToString(aResult.mEasing.Value());
+  } else {
+    aResult.mEasing.Construct(NS_LITERAL_STRING("linear"));
+  }
+
+  aResult.mComposite.Construct(CompositeOperation::Replace);
+}
+
 void
 KeyframeEffectReadOnly::GetProperties(
     nsTArray<AnimationPropertyDetails>& aProperties) const
 {
   for (const AnimationProperty& property : mProperties) {
     AnimationPropertyDetails propertyDetails;
     propertyDetails.mProperty.Construct(
       NS_ConvertASCIItoUTF16(nsCSSProps::GetStringValue(property.mProperty)));
@@ -1811,16 +1834,61 @@ KeyframeEffectReadOnly::GetProperties(
       property.mIsRunningOnCompositor);
 
     nsXPIDLString localizedString;
     if (property.mPerformanceWarning &&
         property.mPerformanceWarning->ToLocalizedString(localizedString)) {
       propertyDetails.mWarning.Construct(localizedString);
     }
 
+    propertyDetails.mValues.Construct();
+    if (!propertyDetails.mValues.Value().SetCapacity(
+          property.mSegments.Length(), mozilla::fallible)) {
+      MOZ_CRASH("Out of memory allocating values array");
+    }
+
+    for (size_t segmentIdx = 0, segmentLen = property.mSegments.Length();
+         segmentIdx < segmentLen;
+         segmentIdx++)
+    {
+      const AnimationPropertySegment& segment = property.mSegments[segmentIdx];
+
+      binding_detail::FastAnimationPropertyValueDetails fromValue;
+      CreatePropertyValue(property.mProperty, segment.mFromKey,
+                          segment.mTimingFunction, segment.mFromValue,
+                          fromValue);
+      // We don't apply timing functions for zero-length segments, so
+      // don't return one here.
+      if (segment.mFromKey == segment.mToKey) {
+        fromValue.mEasing.Reset();
+      }
+      // The following won't fail since we have already allocated the capacity
+      // above.
+      propertyDetails.mValues.Value().AppendElement(fromValue,
+                                                    mozilla::fallible);
+
+      // Normally we can ignore the to-value for this segment since it is
+      // identical to the from-value from the next segment. However, we need
+      // to add it if either:
+      // a) this is the last segment, or
+      // b) the next segment's from-value differs.
+      if (segmentIdx == segmentLen - 1 ||
+          property.mSegments[segmentIdx + 1].mFromValue != segment.mToValue) {
+        binding_detail::FastAnimationPropertyValueDetails toValue;
+        CreatePropertyValue(property.mProperty, segment.mToKey,
+                            Nothing(), segment.mToValue, toValue);
+        // It doesn't really make sense to have a timing function on the
+        // last property value or before a sudden jump so we just drop the
+        // easing property altogether.
+        toValue.mEasing.Reset();
+        propertyDetails.mValues.Value().AppendElement(toValue,
+                                                      mozilla::fallible);
+      }
+    }
+
     aProperties.AppendElement(propertyDetails);
   }
 }
 
 void
 KeyframeEffectReadOnly::GetFrames(JSContext*& aCx,
                                   nsTArray<JSObject*>& aResult,
                                   ErrorResult& aRv)