Bug 1244590 - Part 6: Refactor the calculation of StyleAnimationValue.
We want to reuse the StyleAnimationValues of properties of each keyframe when
applying spacing and building animation property segments, so refactor this
part.
MozReview-Commit-ID: 8G56C3BU3FR
--- a/dom/animation/KeyframeEffect.cpp
+++ b/dom/animation/KeyframeEffect.cpp
@@ -515,21 +515,23 @@ KeyframeEffectReadOnly::HasAnimationOfPr
void
KeyframeEffectReadOnly::UpdateProperties(nsStyleContext* aStyleContext)
{
MOZ_ASSERT(aStyleContext);
nsTArray<AnimationProperty> properties;
if (mTarget) {
+ nsTArray<ComputedKeyframeValues> computedValues =
+ KeyframeUtils::GetComputedKeyframeValues(mKeyframes, mTarget->mElement,
+ aStyleContext);
+
properties =
- KeyframeUtils::GetAnimationPropertiesFromKeyframes(aStyleContext,
- mTarget->mElement,
- mTarget->mPseudoType,
- mKeyframes);
+ KeyframeUtils::GetAnimationPropertiesFromKeyframes(mKeyframes,
+ computedValues);
}
if (mProperties == properties) {
return;
}
// Preserve the state of mWinsInCascade and mIsRunningOnCompositor flags.
nsCSSPropertySet winningInCascadeProperties;
--- a/dom/animation/KeyframeUtils.cpp
+++ b/dom/animation/KeyframeUtils.cpp
@@ -3,16 +3,17 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "mozilla/KeyframeUtils.h"
#include "mozilla/AnimationUtils.h"
#include "mozilla/ErrorResult.h"
#include "mozilla/Move.h"
+#include "mozilla/StyleAnimationValue.h"
#include "mozilla/TimingParams.h"
#include "mozilla/dom/BaseKeyframeTypesBinding.h" // For FastBaseKeyframe etc.
#include "mozilla/dom/Element.h"
#include "mozilla/dom/KeyframeEffect.h"
#include "mozilla/dom/KeyframeEffectBinding.h"
#include "jsapi.h" // For ForOfIterator etc.
#include "nsClassHashtable.h"
#include "nsCSSParser.h"
@@ -488,30 +489,30 @@ KeyframeUtils::ApplySpacing(nsTArray<Key
// TODO
MOZ_ASSERT(false, "not implement yet");
}
keyframeA = keyframeB;
}
}
-/* static */ nsTArray<AnimationProperty>
-KeyframeUtils::GetAnimationPropertiesFromKeyframes(
- nsStyleContext* aStyleContext,
- dom::Element* aElement,
- CSSPseudoElementType aPseudoType,
- const nsTArray<Keyframe>& aFrames)
+/* static */ nsTArray<ComputedKeyframeValues>
+KeyframeUtils::GetComputedKeyframeValues(const nsTArray<Keyframe>& aKeyframes,
+ dom::Element* aElement,
+ nsStyleContext* aStyleContext)
{
MOZ_ASSERT(aStyleContext);
MOZ_ASSERT(aElement);
- nsTArray<KeyframeValueEntry> entries;
+ const size_t len = aKeyframes.Length();
+ nsTArray<ComputedKeyframeValues> result(len);
- for (const Keyframe& frame : aFrames) {
+ for (const Keyframe& frame: aKeyframes) {
nsCSSPropertySet propertiesOnThisKeyframe;
+ ComputedKeyframeValues* computedValues = result.AppendElement();
for (const PropertyValuePair& pair :
PropertyPriorityIterator(frame.mPropertyValues)) {
if (IsInvalidValuePair(pair)) {
continue;
}
// Expand each value into the set of longhands and produce
// a KeyframeValueEntry for each value.
@@ -538,30 +539,48 @@ KeyframeUtils::GetAnimationPropertiesFro
}
for (auto& value : values) {
// If we already got a value for this property on the keyframe,
// skip this one.
if (propertiesOnThisKeyframe.HasProperty(value.mProperty)) {
continue;
}
-
- KeyframeValueEntry* entry = entries.AppendElement();
- MOZ_ASSERT(frame.mComputedOffset != Keyframe::kComputedOffsetNotSet,
- "Invalid computed offset");
- entry->mOffset = frame.mComputedOffset;
- entry->mProperty = value.mProperty;
- entry->mValue = value.mValue;
- entry->mTimingFunction = frame.mTimingFunction;
-
+ computedValues->AppendElement(value);
propertiesOnThisKeyframe.AddProperty(value.mProperty);
}
}
}
+ MOZ_ASSERT(result.Length() == aKeyframes.Length(), "Array length mismatch");
+ return result;
+}
+
+/* static */ nsTArray<AnimationProperty>
+KeyframeUtils::GetAnimationPropertiesFromKeyframes(
+ const nsTArray<Keyframe>& aKeyframes,
+ const nsTArray<ComputedKeyframeValues>& aComputedValues)
+{
+ MOZ_ASSERT(aKeyframes.Length() == aComputedValues.Length(),
+ "Array length mismatch");
+
+ nsTArray<KeyframeValueEntry> entries(aKeyframes.Length());
+
+ const size_t len = aKeyframes.Length();
+ for (size_t i = 0; i < len; ++i) {
+ const Keyframe& frame = aKeyframes[i];
+ for (auto& value : aComputedValues[i]) {
+ KeyframeValueEntry* entry = entries.AppendElement();
+ entry->mOffset = frame.mComputedOffset;
+ entry->mProperty = value.mProperty;
+ entry->mValue = value.mValue;
+ entry->mTimingFunction = frame.mTimingFunction;
+ }
+ }
+
nsTArray<AnimationProperty> result;
BuildSegmentsFromValueEntries(entries, result);
return result;
}
/* static */ bool
KeyframeUtils::IsAnimatableProperty(nsCSSProperty aProperty)
--- a/dom/animation/KeyframeUtils.h
+++ b/dom/animation/KeyframeUtils.h
@@ -13,25 +13,30 @@
struct JSContext;
class JSObject;
namespace mozilla {
struct AnimationProperty;
enum class CSSPseudoElementType : uint8_t;
class ErrorResult;
struct Keyframe;
+struct PropertyStyleAnimationValuePair;
namespace dom {
class Element;
} // namespace dom
} // namespace mozilla
namespace mozilla {
+// Represents the set of property-value pairs on a Keyframe converted to
+// computed values.
+using ComputedKeyframeValues = nsTArray<PropertyStyleAnimationValuePair>;
+
/**
* Utility methods for processing keyframes.
*/
class KeyframeUtils
{
public:
/**
* Converts a JS value representing a property-indexed keyframe or a sequence
@@ -47,44 +52,68 @@ public:
* returned.
*/
static nsTArray<Keyframe>
GetKeyframesFromObject(JSContext* aCx,
JS::Handle<JSObject*> aFrames,
ErrorResult& aRv);
/**
+ * Calculate the StyleAnimationValues of properties of each keyframe.
+ * This involves expanding shorthand properties into longhand properties,
+ * removing the duplicated properties for each keyframe, and creating an
+ * array of |property:computed value| pairs for each keyframe.
+ *
+ * These computed values are used *both* when computing the final set of
+ * per-property animation values (see GetAnimationPropertiesFromKeyframes) as
+ * well when applying paced spacing. By returning these values here, we allow
+ * the result to be re-used in both operations.
+ *
+ * @param aKeyframes The input keyframes.
+ * @param aElement The context element.
+ * @param aStyleContext The style context to use when computing values.
+ * @return The set of ComputedKeyframeValues. The length will be the same as
+ * aFrames.
+ */
+ static nsTArray<ComputedKeyframeValues>
+ GetComputedKeyframeValues(const nsTArray<Keyframe>& aKeyframes,
+ dom::Element* aElement,
+ nsStyleContext* aStyleContext);
+
+ /**
* Fills in the mComputedOffset member of each keyframe in the given array
* using the specified spacing mode.
*
* https://w3c.github.io/web-animations/#spacing-keyframes
*
* @param aKeyframes The set of keyframes to adjust.
* @param aSpacingMode The spacing mode to apply.
*/
static void ApplySpacing(nsTArray<Keyframe>& aKeyframes,
SpacingMode aSpacingMode);
/**
* Converts an array of Keyframe objects into an array of AnimationProperty
- * objects. This involves expanding shorthand properties into longhand
- * properties, creating an array of computed values for each longhand
- * property and determining the offset and timing function to use for each
- * value.
+ * objects. This involves creating an array of computed values for each
+ * longhand property and determining the offset and timing function to use
+ * for each value.
*
- * @param aStyleContext The style context to use when computing values.
- * @param aFrames The input keyframes.
+ * @param aKeyframes The input keyframes.
+ * @param aComputedValues The computed keyframe values (as returned by
+ * GetComputedKeyframeValues) used to fill in the individual
+ * AnimationPropertySegment objects. Although these values could be
+ * calculated from |aKeyframes|, passing them in as a separate parameter
+ * allows the result of GetComputedKeyframeValues to be re-used both
+ * here and in ApplySpacing.
* @return The set of animation properties. If an error occurs, the returned
* array will be empty.
*/
- static nsTArray<AnimationProperty>
- GetAnimationPropertiesFromKeyframes(nsStyleContext* aStyleContext,
- dom::Element* aElement,
- CSSPseudoElementType aPseudoType,
- const nsTArray<Keyframe>& aFrames);
+ static nsTArray<AnimationProperty> GetAnimationPropertiesFromKeyframes(
+ const nsTArray<Keyframe>& aKeyframes,
+ const nsTArray<ComputedKeyframeValues>& aComputedValues);
/**
* Check if the property or, for shorthands, one or more of
* its subproperties, is animatable.
*
* @param aProperty The property we check.
* @return true if |aProperty| is animatable.
*/