--- a/dom/animation/KeyframeEffect.cpp
+++ b/dom/animation/KeyframeEffect.cpp
@@ -5,19 +5,17 @@
* You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "mozilla/dom/KeyframeEffect.h"
#include "mozilla/dom/KeyframeAnimationOptionsBinding.h"
// For UnrestrictedDoubleOrKeyframeAnimationOptions
#include "mozilla/dom/AnimationEffectTiming.h"
#include "mozilla/dom/KeyframeEffectBinding.h"
-#include "mozilla/KeyframeUtils.h"
#include "nsDOMMutationObserver.h" // For nsAutoAnimationMutationBatch
-#include "nsIScriptError.h"
namespace mozilla {
namespace dom {
KeyframeEffect::KeyframeEffect(nsIDocument* aDocument,
const Maybe<OwningAnimationTarget>& aTarget,
const TimingParams& aTiming,
const KeyframeEffectParams& aOptions)
@@ -108,31 +106,26 @@ KeyframeEffect::SetTarget(const Nullable
mTarget = newTarget;
if (mTarget) {
UpdateTargetRegistration();
RefPtr<nsStyleContext> styleContext = GetTargetStyleContext();
if (styleContext) {
UpdateProperties(styleContext);
- } else if (mEffectOptions.mSpacingMode == SpacingMode::paced) {
- KeyframeUtils::ApplyDistributeSpacing(mKeyframes);
}
MaybeUpdateFrameForCompositor();
RequestRestyle(EffectCompositor::RestyleType::Layer);
nsAutoAnimationMutationBatch mb(mTarget->mElement->OwnerDoc());
if (mAnimation) {
nsNodeUtils::AnimationAdded(mAnimation);
}
- } else if (mEffectOptions.mSpacingMode == SpacingMode::paced) {
- // New target is null, so fall back to distribute spacing.
- KeyframeUtils::ApplyDistributeSpacing(mKeyframes);
}
// If the new target frame is also oversized we should probably record that
// too so we have a more complete picture of the type of frame sizes we
// encounter, hence we reset the telemetry flag here.
mRecordedContentTooLarge = false;
mRecordedFrameSize = false;
}
@@ -176,66 +169,10 @@ KeyframeEffect::SetComposite(const Compo
if (mTarget) {
RefPtr<nsStyleContext> styleContext = GetTargetStyleContext();
if (styleContext) {
UpdateProperties(styleContext);
}
}
}
-void
-KeyframeEffect::SetSpacing(JSContext* aCx,
- const nsAString& aSpacing,
- CallerType aCallerType,
- ErrorResult& aRv)
-{
- SpacingMode spacingMode = SpacingMode::distribute;
- nsCSSPropertyID pacedProperty = eCSSProperty_UNKNOWN;
- nsAutoString invalidPacedProperty;
- KeyframeEffectParams::ParseSpacing(aSpacing,
- spacingMode,
- pacedProperty,
- invalidPacedProperty,
- aCallerType,
- aRv);
- if (aRv.Failed()) {
- return;
- }
-
- if (!invalidPacedProperty.IsEmpty()) {
- const char16_t* params[] = { invalidPacedProperty.get() };
- nsIDocument* doc = AnimationUtils::GetCurrentRealmDocument(aCx);
- nsContentUtils::ReportToConsole(nsIScriptError::warningFlag,
- NS_LITERAL_CSTRING("Animation"),
- doc,
- nsContentUtils::eDOM_PROPERTIES,
- "UnanimatablePacedProperty",
- params, ArrayLength(params));
- }
-
- if (mEffectOptions.mSpacingMode == spacingMode &&
- mEffectOptions.mPacedProperty == pacedProperty) {
- return;
- }
-
- mEffectOptions.mSpacingMode = spacingMode;
- mEffectOptions.mPacedProperty = pacedProperty;
-
- // Apply spacing. We apply distribute here. If the new spacing is paced,
- // UpdateProperties() will apply it.
- if (mEffectOptions.mSpacingMode == SpacingMode::distribute) {
- KeyframeUtils::ApplyDistributeSpacing(mKeyframes);
- }
-
- if (mAnimation && mAnimation->IsRelevant()) {
- nsNodeUtils::AnimationChanged(mAnimation);
- }
-
- if (mTarget) {
- RefPtr<nsStyleContext> styleContext = GetTargetStyleContext();
- if (styleContext) {
- UpdateProperties(styleContext);
- }
- }
-}
-
} // namespace dom
} // namespace mozilla
--- a/dom/animation/KeyframeEffect.h
+++ b/dom/animation/KeyframeEffect.h
@@ -67,22 +67,16 @@ public:
// This method calls GetTargetStyleContext which is not safe to use when
// we are in the middle of updating style. If we need to use this when
// updating style, we should pass the nsStyleContext into this method and use
// that to update the properties rather than calling
// GetStyleContext.
void SetTarget(const Nullable<ElementOrCSSPseudoElement>& aTarget);
- void GetSpacing(nsString& aRetVal, CallerType aCallerType)
- {
- KeyframeEffectReadOnly::GetSpacing(aRetVal);
- }
- void SetSpacing(JSContext* aCx, const nsAString& aSpacing,
- CallerType aCallerType, ErrorResult& aRv);
IterationCompositeOperation IterationComposite(CallerType aCallerType)
{
return KeyframeEffectReadOnly::IterationComposite();
}
void SetIterationComposite(
const IterationCompositeOperation& aIterationComposite,
CallerType aCallerType);
void SetComposite(const CompositeOperation& aComposite);
deleted file mode 100644
--- a/dom/animation/KeyframeEffectParams.cpp
+++ /dev/null
@@ -1,174 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim: set ts=8 sts=2 et sw=2 tw=80: */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * 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/KeyframeEffectParams.h"
-
-#include "mozilla/AnimationUtils.h"
-#include "mozilla/ErrorResult.h"
-#include "mozilla/KeyframeUtils.h"
-#include "mozilla/RangedPtr.h"
-#include "nsReadableUtils.h"
-
-namespace mozilla {
-
-static inline bool
-IsLetter(char16_t aCh)
-{
- return (0x41 <= aCh && aCh <= 0x5A) || (0x61 <= aCh && aCh <= 0x7A);
-}
-
-static inline bool
-IsDigit(char16_t aCh)
-{
- return 0x30 <= aCh && aCh <= 0x39;
-}
-
-static inline bool
-IsNameStartCode(char16_t aCh)
-{
- return IsLetter(aCh) || aCh >= 0x80 || aCh == '_';
-}
-
-static inline bool
-IsNameCode(char16_t aCh)
-{
- return IsNameStartCode(aCh) || IsDigit(aCh) || aCh == '-';
-}
-
-static inline bool
-IsNewLine(char16_t aCh)
-{
- // 0x0A (LF), 0x0C (FF), 0x0D (CR), or pairs of CR followed by LF are
- // replaced by LF.
- return aCh == 0x0A || aCh == 0x0C || aCh == 0x0D;
-}
-
-static inline bool
-IsValidEscape(char16_t aFirst, char16_t aSecond)
-{
- return aFirst == '\\' && !IsNewLine(aSecond);
-}
-
-static bool
-IsIdentStart(RangedPtr<const char16_t> aIter,
- const char16_t* const aEnd)
-{
- if (aIter == aEnd) {
- return false;
- }
-
- if (*aIter == '-') {
- if (aIter + 1 == aEnd) {
- return false;
- }
- char16_t second = *(aIter + 1);
- return IsNameStartCode(second) ||
- second == '-' ||
- (aIter + 2 != aEnd && IsValidEscape(second, *(aIter + 2)));
- }
- return IsNameStartCode(*aIter) ||
- (aIter + 1 != aEnd && IsValidEscape(*aIter, *(aIter + 1)));
-}
-
-static void
-ConsumeIdentToken(RangedPtr<const char16_t>& aIter,
- const char16_t* const aEnd,
- nsAString& aResult)
-{
- aResult.Truncate();
-
- // Check if it starts with an identifier.
- if (!IsIdentStart(aIter, aEnd)) {
- return;
- }
-
- // Start to consume.
- while (aIter != aEnd) {
- if (IsNameCode(*aIter)) {
- aResult.Append(*aIter);
- } else if (*aIter == '\\') {
- const RangedPtr<const char16_t> secondChar = aIter + 1;
- if (secondChar == aEnd || !IsValidEscape(*aIter, *secondChar)) {
- break;
- }
- // Consume '\\' and append the character following this '\\'.
- ++aIter;
- aResult.Append(*aIter);
- } else {
- break;
- }
- ++aIter;
- }
-}
-
-/* static */ void
-KeyframeEffectParams::ParseSpacing(const nsAString& aSpacing,
- SpacingMode& aSpacingMode,
- nsCSSPropertyID& aPacedProperty,
- nsAString& aInvalidPacedProperty,
- dom::CallerType aCallerType,
- ErrorResult& aRv)
-{
- aInvalidPacedProperty.Truncate();
-
- // Ignore spacing if the core API is not enabled since it is not yet ready to
- // ship.
- if (!AnimationUtils::IsCoreAPIEnabledForCaller(aCallerType)) {
- aSpacingMode = SpacingMode::distribute;
- return;
- }
-
- // Parse spacing.
- // distribute | paced({ident})
- // https://w3c.github.io/web-animations/#dom-keyframeeffectreadonly-spacing
- // 1. distribute spacing.
- if (aSpacing.EqualsLiteral("distribute")) {
- aSpacingMode = SpacingMode::distribute;
- return;
- }
-
- // 2. paced spacing.
- static const nsLiteralString kPacedPrefix = NS_LITERAL_STRING("paced(");
- if (!StringBeginsWith(aSpacing, kPacedPrefix)) {
- aRv.ThrowTypeError<dom::MSG_INVALID_SPACING_MODE_ERROR>(aSpacing);
- return;
- }
-
- RangedPtr<const char16_t> iter(aSpacing.Data() + kPacedPrefix.Length(),
- aSpacing.Data(), aSpacing.Length());
- const char16_t* const end = aSpacing.EndReading();
-
- nsAutoString identToken;
- ConsumeIdentToken(iter, end, identToken);
- if (identToken.IsEmpty()) {
- aRv.ThrowTypeError<dom::MSG_INVALID_SPACING_MODE_ERROR>(aSpacing);
- return;
- }
-
- aPacedProperty =
- nsCSSProps::LookupProperty(identToken, CSSEnabledState::eForAllContent);
- if (aPacedProperty == eCSSProperty_UNKNOWN ||
- aPacedProperty == eCSSPropertyExtra_variable ||
- // We just unconditionally pass Gecko as the backend type here since
- // Servo doesn't support paced timing and this feature will soon be
- // removed (bug 1339690).
- !KeyframeUtils::IsAnimatableProperty(aPacedProperty,
- StyleBackendType::Gecko)) {
- aPacedProperty = eCSSProperty_UNKNOWN;
- aInvalidPacedProperty = identToken;
- }
-
- if (end - iter.get() != 1 || *iter != ')') {
- aRv.ThrowTypeError<dom::MSG_INVALID_SPACING_MODE_ERROR>(aSpacing);
- return;
- }
-
- aSpacingMode = aPacedProperty == eCSSProperty_UNKNOWN
- ? SpacingMode::distribute
- : SpacingMode::paced;
-}
-
-} // namespace mozilla
--- a/dom/animation/KeyframeEffectParams.h
+++ b/dom/animation/KeyframeEffectParams.h
@@ -2,69 +2,26 @@
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* 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/. */
#ifndef mozilla_KeyframeEffectParams_h
#define mozilla_KeyframeEffectParams_h
-#include "nsCSSProps.h"
-#include "nsString.h"
// X11 has a #define for None
#ifdef None
#undef None
#endif
#include "mozilla/dom/KeyframeEffectBinding.h" // IterationCompositeOperation
-#include "mozilla/dom/BindingDeclarations.h" // CallerType
namespace mozilla {
-class ErrorResult;
-
-enum class SpacingMode
-{
- distribute,
- paced
-};
-
struct KeyframeEffectParams
{
- void GetSpacingAsString(nsAString& aSpacing) const
- {
- if (mSpacingMode == SpacingMode::distribute) {
- aSpacing.AssignLiteral("distribute");
- } else {
- aSpacing.AssignLiteral("paced(");
- aSpacing.AppendASCII(nsCSSProps::GetStringValue(mPacedProperty).get());
- aSpacing.AppendLiteral(")");
- }
- }
-
- /**
- * Parse spacing string.
- *
- * @param aSpacing The input spacing string.
- * @param [out] aSpacingMode The parsed spacing mode.
- * @param [out] aPacedProperty The parsed CSS property if using paced spacing.
- * @param [out] aInvalidPacedProperty A string that, if we parsed a string of
- * the form 'paced(<ident>)' where <ident>
- * is not a recognized animatable property,
- * will be set to <ident>.
- * @param [out] aRv The error result.
- */
- static void ParseSpacing(const nsAString& aSpacing,
- SpacingMode& aSpacingMode,
- nsCSSPropertyID& aPacedProperty,
- nsAString& aInvalidPacedProperty,
- dom::CallerType aCallerType,
- ErrorResult& aRv);
-
dom::IterationCompositeOperation mIterationComposite =
dom::IterationCompositeOperation::Replace;
dom::CompositeOperation mComposite = dom::CompositeOperation::Replace;
- SpacingMode mSpacingMode = SpacingMode::distribute;
- nsCSSPropertyID mPacedProperty = eCSSProperty_UNKNOWN;
};
} // namespace mozilla
#endif // mozilla_KeyframeEffectParams_h
--- a/dom/animation/KeyframeEffectReadOnly.cpp
+++ b/dom/animation/KeyframeEffectReadOnly.cpp
@@ -18,17 +18,16 @@
#include "mozilla/FloatingPoint.h" // For IsFinite
#include "mozilla/LookAndFeel.h" // For LookAndFeel::GetInt
#include "mozilla/KeyframeUtils.h"
#include "mozilla/ServoBindings.h"
#include "mozilla/Telemetry.h"
#include "mozilla/TypeTraits.h"
#include "Layers.h" // For Layer
#include "nsComputedDOMStyle.h" // nsComputedDOMStyle::GetStyleContext
-#include "nsContentUtils.h" // nsContentUtils::ReportToConsole
#include "nsCSSPropertyIDSet.h"
#include "nsCSSProps.h" // For nsCSSProps::PropHasFlags
#include "nsCSSPseudoElements.h" // For CSSPseudoElementType
#include "nsIPresShell.h"
#include "nsIScriptError.h"
namespace mozilla {
@@ -213,20 +212,16 @@ KeyframeEffectReadOnly::DoSetKeyframes(n
"StyleType should be nsStyleContext* or "
"const ServoComputedValues*");
if (KeyframesEqualIgnoringComputedOffsets(aKeyframes, mKeyframes)) {
return;
}
mKeyframes = Move(aKeyframes);
- // Apply distribute spacing irrespective of the spacing mode. We will apply
- // the specified spacing mode when we generate computed animation property
- // values from the keyframes since both operations require a style context
- // and need to be performed whenever the style context changes.
KeyframeUtils::ApplyDistributeSpacing(mKeyframes);
if (mAnimation && mAnimation->IsRelevant()) {
nsNodeUtils::AnimationChanged(mAnimation);
}
// We need to call UpdateProperties() if the StyleType is not nullptr.
if (aStyle) {
@@ -783,37 +778,30 @@ KeyframeEffectOptionsFromUnion(
{
MOZ_ASSERT(aOptions.IsKeyframeAnimationOptions());
return aOptions.GetAsKeyframeAnimationOptions();
}
template <class OptionsType>
static KeyframeEffectParams
KeyframeEffectParamsFromUnion(const OptionsType& aOptions,
- nsAString& aInvalidPacedProperty,
- CallerType aCallerType,
- ErrorResult& aRv)
+ CallerType aCallerType)
{
KeyframeEffectParams result;
- if (!aOptions.IsUnrestrictedDouble()) {
- const KeyframeEffectOptions& options =
- KeyframeEffectOptionsFromUnion(aOptions);
- KeyframeEffectParams::ParseSpacing(options.mSpacing,
- result.mSpacingMode,
- result.mPacedProperty,
- aInvalidPacedProperty,
- aCallerType,
- aRv);
- // Ignore iterationComposite if the Web Animations API is not enabled,
- // then the default value 'Replace' will be used.
- if (AnimationUtils::IsCoreAPIEnabledForCaller(aCallerType)) {
- result.mIterationComposite = options.mIterationComposite;
- result.mComposite = options.mComposite;
- }
+ if (aOptions.IsUnrestrictedDouble() ||
+ // Ignore iterationComposite if the Web Animations API is not enabled,
+ // then the default value 'Replace' will be used.
+ !AnimationUtils::IsCoreAPIEnabledForCaller(aCallerType)) {
+ return result;
}
+
+ const KeyframeEffectOptions& options =
+ KeyframeEffectOptionsFromUnion(aOptions);
+ result.mIterationComposite = options.mIterationComposite;
+ result.mComposite = options.mComposite;
return result;
}
/* static */ Maybe<OwningAnimationTarget>
KeyframeEffectReadOnly::ConvertTarget(
const Nullable<ElementOrCSSPseudoElement>& aTarget)
{
// Return value optimization.
@@ -852,33 +840,18 @@ KeyframeEffectReadOnly::ConstructKeyfram
}
TimingParams timingParams =
TimingParams::FromOptionsUnion(aOptions, doc, aRv);
if (aRv.Failed()) {
return nullptr;
}
- nsAutoString invalidPacedProperty;
KeyframeEffectParams effectOptions =
- KeyframeEffectParamsFromUnion(aOptions, invalidPacedProperty,
- aGlobal.CallerType(), aRv);
- if (aRv.Failed()) {
- return nullptr;
- }
-
- if (!invalidPacedProperty.IsEmpty()) {
- const char16_t* params[] = { invalidPacedProperty.get() };
- nsContentUtils::ReportToConsole(nsIScriptError::warningFlag,
- NS_LITERAL_CSTRING("Animation"),
- doc,
- nsContentUtils::eDOM_PROPERTIES,
- "UnanimatablePacedProperty",
- params, ArrayLength(params));
- }
+ KeyframeEffectParamsFromUnion(aOptions, aGlobal.CallerType());
Maybe<OwningAnimationTarget> target = ConvertTarget(aTarget);
RefPtr<KeyframeEffectType> effect =
new KeyframeEffectType(doc, target, timingParams, effectOptions);
effect->SetKeyframes(aGlobal.Context(), aKeyframes, aRv);
if (aRv.Failed()) {
return nullptr;
@@ -949,25 +922,16 @@ KeyframeEffectReadOnly::BuildProperties(
// make a copy of |mKeyframes| first and iterate over that instead.
auto keyframesCopy(mKeyframes);
nsTArray<ComputedKeyframeValues> computedValues =
KeyframeUtils::GetComputedKeyframeValues(keyframesCopy,
mTarget->mElement,
aStyle);
- // FIXME: Bug 1332633: we have to implement ComputeDistance for
- // RawServoAnimationValue.
- if (mEffectOptions.mSpacingMode == SpacingMode::paced &&
- !mDocument->IsStyledByServo()) {
- KeyframeUtils::ApplySpacing(keyframesCopy, SpacingMode::paced,
- mEffectOptions.mPacedProperty,
- computedValues, aStyle);
- }
-
result =
KeyframeUtils::GetAnimationPropertiesFromKeyframes(
keyframesCopy,
computedValues,
mEffectOptions.mComposite);
#ifdef DEBUG
MOZ_ASSERT(SpecifiedKeyframeArraysAreEqual(mKeyframes, keyframesCopy),
--- a/dom/animation/KeyframeEffectReadOnly.h
+++ b/dom/animation/KeyframeEffectReadOnly.h
@@ -153,20 +153,16 @@ public:
void GetKeyframes(JSContext*& aCx,
nsTArray<JSObject*>& aResult,
ErrorResult& aRv);
void GetProperties(nsTArray<AnimationPropertyDetails>& aProperties,
ErrorResult& aRv) const;
IterationCompositeOperation IterationComposite() const;
CompositeOperation Composite() const;
- void GetSpacing(nsString& aRetVal) const
- {
- mEffectOptions.GetSpacingAsString(aRetVal);
- }
void NotifyAnimationTimingUpdated();
void RequestRestyle(EffectCompositor::RestyleType aRestyleType);
void SetAnimation(Animation* aAnimation) override;
void SetKeyframes(JSContext* aContext, JS::Handle<JSObject*> aKeyframes,
ErrorResult& aRv);
void SetKeyframes(nsTArray<Keyframe>&& aKeyframes,
nsStyleContext* aStyleContext);
void SetKeyframes(nsTArray<Keyframe>&& aKeyframes,
--- a/dom/animation/KeyframeUtils.cpp
+++ b/dom/animation/KeyframeUtils.cpp
@@ -31,20 +31,16 @@
namespace mozilla {
// ------------------------------------------------------------------
//
// Internal data types
//
// ------------------------------------------------------------------
-// This is used while calculating paced spacing. If the keyframe is not pacable,
-// we set its cumulative distance to kNotPaceable, so we can use this to check.
-const double kNotPaceable = -1.0;
-
// For the aAllowList parameter of AppendStringOrStringSequence and
// GetPropertyValuesPairs.
enum class ListAllowance { eDisallow, eAllow };
/**
* A comparator to sort nsCSSPropertyID values such that longhands are sorted
* before shorthands, and shorthands with fewer components are sorted before
* shorthands with more components.
@@ -408,31 +404,18 @@ GetKeyframeListFromPropertyIndexedKeyfra
nsTArray<Keyframe>& aResult,
ErrorResult& aRv);
static bool
RequiresAdditiveAnimation(const nsTArray<Keyframe>& aKeyframes,
nsIDocument* aDocument);
static void
-DistributeRange(const Range<Keyframe>& aSpacingRange,
- const Range<Keyframe>& aRangeToAdjust);
-
-static void
DistributeRange(const Range<Keyframe>& aSpacingRange);
-static void
-PaceRange(const Range<Keyframe>& aKeyframes,
- const Range<double>& aCumulativeDistances);
-
-static nsTArray<double>
-GetCumulativeDistances(const nsTArray<ComputedKeyframeValues>& aValues,
- nsCSSPropertyID aProperty,
- nsStyleContext* aStyleContext);
-
// ------------------------------------------------------------------
//
// Public API
//
// ------------------------------------------------------------------
/* static */ nsTArray<Keyframe>
KeyframeUtils::GetKeyframesFromObject(JSContext* aCx,
@@ -477,42 +460,22 @@ KeyframeUtils::GetKeyframesFromObject(JS
keyframes.Clear();
aRv.Throw(NS_ERROR_DOM_ANIM_MISSING_PROPS_ERR);
}
return keyframes;
}
/* static */ void
-KeyframeUtils::ApplySpacing(nsTArray<Keyframe>& aKeyframes,
- SpacingMode aSpacingMode,
- nsCSSPropertyID aProperty,
- nsTArray<ComputedKeyframeValues>& aComputedValues,
- nsStyleContext* aStyleContext)
+KeyframeUtils::ApplyDistributeSpacing(nsTArray<Keyframe>& aKeyframes)
{
if (aKeyframes.IsEmpty()) {
return;
}
- nsTArray<double> cumulativeDistances;
- if (aSpacingMode == SpacingMode::paced) {
- // We just unconditionally pass Gecko as the backend type here since
- // Servo doesn't support paced timing and this feature will soon be removed
- // (bug 1339690).
- MOZ_ASSERT(IsAnimatableProperty(aProperty, StyleBackendType::Gecko),
- "Paced property should be animatable");
-
- cumulativeDistances = GetCumulativeDistances(aComputedValues, aProperty,
- aStyleContext);
- // Reset the computed offsets if using paced spacing.
- for (Keyframe& keyframe : aKeyframes) {
- keyframe.mComputedOffset = Keyframe::kComputedOffsetNotSet;
- }
- }
-
// If the first keyframe has an unspecified offset, fill it in with 0%.
// If there is only a single keyframe, then it gets 100%.
if (aKeyframes.Length() > 1) {
Keyframe& firstElement = aKeyframes[0];
firstElement.mComputedOffset = firstElement.mOffset.valueOr(0.0);
// We will fill in the last keyframe's offset below
} else {
Keyframe& lastElement = aKeyframes.LastElement();
@@ -527,80 +490,21 @@ KeyframeUtils::ApplySpacing(nsTArray<Key
// Find keyframe A and keyframe B *between* which we will apply spacing.
RangedPtr<Keyframe> keyframeB = keyframeA + 1;
while (keyframeB->mOffset.isNothing() && keyframeB != last) {
++keyframeB;
}
keyframeB->mComputedOffset = keyframeB->mOffset.valueOr(1.0);
// Fill computed offsets in (keyframe A, keyframe B).
- if (aSpacingMode == SpacingMode::distribute) {
- DistributeRange(Range<Keyframe>(keyframeA, keyframeB + 1));
- } else {
- // a) Find Paced A (first paceable keyframe) and
- // Paced B (last paceable keyframe) in [keyframe A, keyframe B].
- RangedPtr<Keyframe> pacedA = keyframeA;
- while (pacedA < keyframeB &&
- cumulativeDistances[pacedA - begin] == kNotPaceable) {
- ++pacedA;
- }
- RangedPtr<Keyframe> pacedB = keyframeB;
- while (pacedB > keyframeA &&
- cumulativeDistances[pacedB - begin] == kNotPaceable) {
- --pacedB;
- }
- // As spec says, if there is no paceable keyframe
- // in [keyframe A, keyframe B], we let Paced A and Paced B refer to
- // keyframe B.
- if (pacedA > pacedB) {
- pacedA = pacedB = keyframeB;
- }
- // b) Apply distributing offsets in (keyframe A, Paced A] and
- // [Paced B, keyframe B).
- DistributeRange(Range<Keyframe>(keyframeA, keyframeB + 1),
- Range<Keyframe>(keyframeA + 1, pacedA + 1));
- DistributeRange(Range<Keyframe>(keyframeA, keyframeB + 1),
- Range<Keyframe>(pacedB, keyframeB));
- // c) Apply paced offsets to each paceable keyframe in (Paced A, Paced B).
- // We pass the range [Paced A, Paced B] since PaceRange needs the end
- // points of the range in order to calculate the correct offset.
- PaceRange(Range<Keyframe>(pacedA, pacedB + 1),
- Range<double>(&cumulativeDistances[pacedA - begin],
- pacedB - pacedA + 1));
- // d) Fill in any computed offsets in (Paced A, Paced B) that are still
- // not set (e.g. because the keyframe was not paceable, or because the
- // cumulative distance between paceable properties was zero).
- for (RangedPtr<Keyframe> frame = pacedA + 1; frame < pacedB; ++frame) {
- if (frame->mComputedOffset != Keyframe::kComputedOffsetNotSet) {
- continue;
- }
-
- RangedPtr<Keyframe> start = frame - 1;
- RangedPtr<Keyframe> end = frame + 1;
- while (end < pacedB &&
- end->mComputedOffset == Keyframe::kComputedOffsetNotSet) {
- ++end;
- }
- DistributeRange(Range<Keyframe>(start, end + 1));
- frame = end;
- }
- }
+ DistributeRange(Range<Keyframe>(keyframeA, keyframeB + 1));
keyframeA = keyframeB;
}
}
-/* static */ void
-KeyframeUtils::ApplyDistributeSpacing(nsTArray<Keyframe>& aKeyframes)
-{
- nsTArray<ComputedKeyframeValues> emptyArray;
- // FIXME: Bug 1339690: below static_cast should be dropped.
- ApplySpacing(aKeyframes, SpacingMode::distribute, eCSSProperty_UNKNOWN,
- emptyArray, static_cast<nsStyleContext*>(nullptr));
-}
-
/* static */ nsTArray<ComputedKeyframeValues>
KeyframeUtils::GetComputedKeyframeValues(
const nsTArray<Keyframe>& aKeyframes,
dom::Element* aElement,
const ServoComputedValues* aComputedValues)
{
MOZ_ASSERT(aElement);
MOZ_ASSERT(aElement->IsStyledByServo());
@@ -1562,17 +1466,17 @@ RequiresAdditiveAnimation(const nsTArray
}
};
StyleBackendType styleBackend = aDocument->GetStyleBackendType();
for (size_t i = 0, len = aKeyframes.Length(); i < len; i++) {
const Keyframe& frame = aKeyframes[i];
- // We won't have called ApplySpacing when this is called so
+ // We won't have called ApplyDistributeSpacing when this is called so
// we can't use frame.mComputedOffset. Instead we do a rough version
// of that algorithm that substitutes null offsets with 0.0 for the first
// frame, 1.0 for the last frame, and 0.5 for everything else.
double computedOffset = i == len - 1
? 1.0
: i == 0 ? 0.0 : 0.5;
double offsetToUse = frame.mOffset
? frame.mOffset.value()
@@ -1615,17 +1519,17 @@ RequiresAdditiveAnimation(const nsTArray
/**
* Evenly distribute the computed offsets in (A, B).
* We pass the range keyframes in [A, B] and use A, B to calculate distributing
* computed offsets in (A, B). The second range, aRangeToAdjust, is passed, so
* we can know which keyframe we want to apply to. aRangeToAdjust should be in
* the range of aSpacingRange.
*
* @param aSpacingRange The sequence of keyframes between whose endpoints we
- * should apply distribute spacing.
+ * should apply distribute offsets.
* @param aRangeToAdjust The range of keyframes we want to apply to.
*/
static void
DistributeRange(const Range<Keyframe>& aSpacingRange,
const Range<Keyframe>& aRangeToAdjust)
{
MOZ_ASSERT(aRangeToAdjust.begin() >= aSpacingRange.begin() &&
aRangeToAdjust.end() <= aSpacingRange.end(),
@@ -1652,175 +1556,9 @@ static void
DistributeRange(const Range<Keyframe>& aSpacingRange)
{
// We don't need to apply distribute spacing to keyframe A and keyframe B.
DistributeRange(aSpacingRange,
Range<Keyframe>(aSpacingRange.begin() + 1,
aSpacingRange.end() - 1));
}
-/**
- * Apply paced spacing to all paceable keyframes in between the endpoints of the
- * given range.
- *
- * @param aKeyframes The range of keyframes between whose endpoints we should
- * apply paced spacing. Both endpoints should be paceable, i.e. the
- * corresponding elements in |aCumulativeDist| should not be kNotPaceable.
- * Within this function, we refer to the start and end points of this range
- * as Paced A and Paced B respectively in keeping with the notation used in
- * the spec.
- * @param aCumulativeDistances The sequence of cumulative distances of the paced
- * property as returned by GetCumulativeDistances(). This acts as a
- * parallel range to |aKeyframes|.
- */
-static void
-PaceRange(const Range<Keyframe>& aKeyframes,
- const Range<double>& aCumulativeDistances)
-{
- MOZ_ASSERT(aKeyframes.length() == aCumulativeDistances.length(),
- "Range length mismatch");
-
- const size_t len = aKeyframes.length();
- // If there is nothing between the end points, there is nothing to space.
- if (len < 3) {
- return;
- }
-
- const double distA = *(aCumulativeDistances.begin());
- const double distB = *(aCumulativeDistances.end() - 1);
- MOZ_ASSERT(distA != kNotPaceable && distB != kNotPaceable,
- "Both Paced A and Paced B should be paceable");
-
- // If the total distance is zero, we should fall back to distribute spacing.
- // The caller will fill-in any keyframes without a computed offset using
- // distribute spacing so we can just return here.
- if (distA == distB) {
- return;
- }
-
- const RangedPtr<Keyframe> pacedA = aKeyframes.begin();
- const RangedPtr<Keyframe> pacedB = aKeyframes.end() - 1;
- MOZ_ASSERT(pacedA->mComputedOffset != Keyframe::kComputedOffsetNotSet &&
- pacedB->mComputedOffset != Keyframe::kComputedOffsetNotSet,
- "Both Paced A and Paced B should have valid computed offsets");
-
- // Apply computed offset.
- const double offsetA = pacedA->mComputedOffset;
- const double diffOffset = pacedB->mComputedOffset - offsetA;
- const double initialDist = distA;
- const double totalDist = distB - initialDist;
- for (auto iter = pacedA + 1; iter != pacedB; ++iter) {
- size_t k = iter - aKeyframes.begin();
- if (aCumulativeDistances[k] == kNotPaceable) {
- continue;
- }
-
- double dist = aCumulativeDistances[k] - initialDist;
- iter->mComputedOffset = offsetA + diffOffset * dist / totalDist;
- }
-}
-
-/**
- * Get cumulative distances for the paced property.
- *
- * @param aValues The computed values returned by GetComputedKeyframeValues.
- * @param aPacedProperty The paced property.
- * @param aStyleContext The style context for computing distance on transform.
- * @return The cumulative distances for the paced property. The length will be
- * the same as aValues.
- */
-static nsTArray<double>
-GetCumulativeDistances(const nsTArray<ComputedKeyframeValues>& aValues,
- nsCSSPropertyID aPacedProperty,
- nsStyleContext* aStyleContext)
-{
- // a) If aPacedProperty is a shorthand property, get its components.
- // Otherwise, just add the longhand property into the set.
- size_t pacedPropertyCount = 0;
- nsCSSPropertyIDSet pacedPropertySet;
- bool isShorthand = nsCSSProps::IsShorthand(aPacedProperty);
- if (isShorthand) {
- CSSPROPS_FOR_SHORTHAND_SUBPROPERTIES(p, aPacedProperty,
- CSSEnabledState::eForAllContent) {
- pacedPropertySet.AddProperty(*p);
- ++pacedPropertyCount;
- }
- } else {
- pacedPropertySet.AddProperty(aPacedProperty);
- pacedPropertyCount = 1;
- }
-
- // b) Search each component (shorthand) or the longhand property, and
- // calculate the cumulative distances of paceable keyframe pairs.
- const size_t len = aValues.Length();
- nsTArray<double> cumulativeDistances(len);
- // cumulativeDistances is a parallel array to |aValues|, so set its length to
- // the length of |aValues|.
- cumulativeDistances.SetLength(len);
- ComputedKeyframeValues prevPacedValues;
- size_t preIdx = 0;
- for (size_t i = 0; i < len; ++i) {
- // Find computed values of the paced property.
- ComputedKeyframeValues pacedValues;
- for (const PropertyStyleAnimationValuePair& pair : aValues[i]) {
- if (pacedPropertySet.HasProperty(pair.mProperty)) {
- pacedValues.AppendElement(pair);
- }
- }
-
- // Check we have values for all the paceable longhand components.
- if (pacedValues.Length() != pacedPropertyCount) {
- // This keyframe is not paceable, assign kNotPaceable and skip it.
- cumulativeDistances[i] = kNotPaceable;
- continue;
- }
-
- // Sort the pacedValues first, so the order of subproperties of
- // pacedValues is always the same as that of prevPacedValues.
- if (isShorthand) {
- pacedValues.Sort(
- TPropertyPriorityComparator<PropertyStyleAnimationValuePair>());
- }
-
- if (prevPacedValues.IsEmpty()) {
- // This is the first paceable keyframe so its cumulative distance is 0.0.
- cumulativeDistances[i] = 0.0;
- } else {
- double dist = 0.0;
- if (isShorthand) {
- // Apply the distance by the square root of the sum of squares of
- // longhand component distances.
- for (size_t propIdx = 0; propIdx < pacedPropertyCount; ++propIdx) {
- nsCSSPropertyID prop = prevPacedValues[propIdx].mProperty;
- MOZ_ASSERT(pacedValues[propIdx].mProperty == prop,
- "Property mismatch");
-
- double componentDistance = 0.0;
- if (StyleAnimationValue::ComputeDistance(
- prop,
- prevPacedValues[propIdx].mValue.mGecko,
- pacedValues[propIdx].mValue.mGecko,
- aStyleContext,
- componentDistance)) {
- dist += componentDistance * componentDistance;
- }
- }
- dist = sqrt(dist);
- } else {
- // If the property is longhand, we just use the 1st value.
- // If ComputeDistance() fails, |dist| will remain zero so there will be
- // no distance between the previous paced value and this value.
- Unused <<
- StyleAnimationValue::ComputeDistance(aPacedProperty,
- prevPacedValues[0].mValue.mGecko,
- pacedValues[0].mValue.mGecko,
- aStyleContext,
- dist);
- }
- cumulativeDistances[i] = cumulativeDistances[preIdx] + dist;
- }
- prevPacedValues.SwapElements(pacedValues);
- preIdx = i;
- }
- return cumulativeDistances;
-}
-
} // namespace mozilla
--- a/dom/animation/KeyframeUtils.h
+++ b/dom/animation/KeyframeUtils.h
@@ -2,19 +2,20 @@
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* 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/. */
#ifndef mozilla_KeyframeUtils_h
#define mozilla_KeyframeUtils_h
+#include "mozilla/KeyframeEffectParams.h" // For CompositeOperation
+#include "nsCSSPropertyID.h"
#include "nsTArrayForwardDeclare.h" // For nsTArray
#include "js/RootingAPI.h" // For JS::Handle
-#include "mozilla/KeyframeEffectParams.h" // SpacingMode
struct JSContext;
class JSObject;
class nsIDocument;
class nsStyleContext;
struct ServoComputedValues;
struct RawServoDeclarationBlock;
@@ -86,67 +87,37 @@ public:
nsStyleContext* aStyleContext);
static nsTArray<ComputedKeyframeValues>
GetComputedKeyframeValues(const nsTArray<Keyframe>& aKeyframes,
dom::Element* aElement,
const ServoComputedValues* aComputedValues);
/**
- * 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
+ * Calculate the computed offset of keyframes by evenly distributing keyframes
+ * with a missing offset.
*
- * @param aKeyframes The set of keyframes to adjust.
- * @param aSpacingMode The spacing mode to apply.
- * @param aProperty The paced property. Only used when |aSpacingMode| is
- * SpacingMode::paced. In all other cases it is ignored and hence may be
- * any value, e.g. eCSSProperty_UNKNOWN.
- * @param aComputedValues The set of computed keyframe values as returned by
- * GetComputedKeyframeValues. Only used when |aSpacingMode| is
- * SpacingMode::paced. In all other cases this parameter is unused and may
- * be any value including an empty array.
- * @param aStyleContext The style context used for calculating paced spacing
- * on transform.
- */
- static void ApplySpacing(nsTArray<Keyframe>& aKeyframes,
- SpacingMode aSpacingMode,
- nsCSSPropertyID aProperty,
- nsTArray<ComputedKeyframeValues>& aComputedValues,
- nsStyleContext* aStyleContext);
- static void ApplySpacing(nsTArray<Keyframe>& aKeyframes,
- SpacingMode aSpacingMode,
- nsCSSPropertyID aProperty,
- nsTArray<ComputedKeyframeValues>& aComputedValues,
- const ServoComputedValues* aServoValues)
- {
- NS_WARNING("stylo: ApplySpacing not implemented yet");
- }
-
- /**
- * Wrapper for ApplySpacing to simplify using distribute spacing.
+ * @see https://w3c.github.io/web-animations/#calculating-computed-keyframes
*
* @param aKeyframes The set of keyframes to adjust.
*/
static void ApplyDistributeSpacing(nsTArray<Keyframe>& aKeyframes);
/**
* Converts an array of Keyframe objects into an array of AnimationProperty
* 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 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.
+ * allows the result of GetComputedKeyframeValues to be re-used here.
* @param aEffectComposite The composite operation specified on the effect.
* For any keyframes in |aKeyframes| that do not specify a composite
* operation, this value will be used.
* @return The set of animation properties. If an error occurs, the returned
* array will be empty.
*/
static nsTArray<AnimationProperty> GetAnimationPropertiesFromKeyframes(
const nsTArray<Keyframe>& aKeyframes,
--- a/dom/animation/moz.build
+++ b/dom/animation/moz.build
@@ -51,17 +51,16 @@ UNIFIED_SOURCES += [
'AnimationUtils.cpp',
'AnimValuesStyleRule.cpp',
'ComputedTimingFunction.cpp',
'CSSPseudoElement.cpp',
'DocumentTimeline.cpp',
'EffectCompositor.cpp',
'EffectSet.cpp',
'KeyframeEffect.cpp',
- 'KeyframeEffectParams.cpp',
'KeyframeEffectReadOnly.cpp',
'KeyframeUtils.cpp',
'PendingAnimationTracker.cpp',
'TimingParams.cpp',
]
LOCAL_INCLUDES += [
'/dom/base',
--- a/dom/bindings/Bindings.conf
+++ b/dom/bindings/Bindings.conf
@@ -553,20 +553,16 @@ DOMInterfaces = {
'nativeType': 'mozilla::dom::DOMIntersectionObserverEntry',
'headerFile': 'DOMIntersectionObserver.h',
},
'KeyEvent': {
'concrete': False
},
-'KeyframeEffect': {
- 'implicitJSContext': { 'setterOnly': [ 'spacing' ] }
-},
-
'LegacyMozTCPSocket': {
'headerFile': 'TCPSocket.h',
'wrapperCache': False,
},
'LocalMediaStream': {
'headerFile': 'DOMMediaStream.h',
'nativeType': 'mozilla::DOMLocalMediaStream'
--- a/dom/bindings/Errors.msg
+++ b/dom/bindings/Errors.msg
@@ -89,17 +89,16 @@ MSG_DEF(MSG_IS_NOT_PROMISE, 1, JSEXN_TYP
MSG_DEF(MSG_SW_INSTALL_ERROR, 2, JSEXN_TYPEERR, "ServiceWorker script at {0} for scope {1} encountered an error during installation.")
MSG_DEF(MSG_SW_SCRIPT_THREW, 2, JSEXN_TYPEERR, "ServiceWorker script at {0} for scope {1} threw an exception during script evaluation.")
MSG_DEF(MSG_TYPEDARRAY_IS_SHARED, 1, JSEXN_TYPEERR, "{0} can't be a typed array on SharedArrayBuffer")
MSG_DEF(MSG_TYPEDARRAY_IS_DETACHED, 1, JSEXN_TYPEERR, "{0} can't be a detached buffer")
MSG_DEF(MSG_CACHE_ADD_FAILED_RESPONSE, 3, JSEXN_TYPEERR, "Cache got {0} response with bad status {1} while trying to add request {2}")
MSG_DEF(MSG_SW_UPDATE_BAD_REGISTRATION, 2, JSEXN_TYPEERR, "Failed to update the ServiceWorker for scope {0} because the registration has been {1} since the update was scheduled.")
MSG_DEF(MSG_INVALID_DURATION_ERROR, 1, JSEXN_TYPEERR, "Invalid duration '{0}'.")
MSG_DEF(MSG_INVALID_EASING_ERROR, 1, JSEXN_TYPEERR, "Invalid easing '{0}'.")
-MSG_DEF(MSG_INVALID_SPACING_MODE_ERROR, 1, JSEXN_TYPEERR, "Invalid spacing '{0}'.")
MSG_DEF(MSG_USELESS_SETTIMEOUT, 1, JSEXN_TYPEERR, "Useless {0} call (missing quotes around argument?)")
MSG_DEF(MSG_TOKENLIST_NO_SUPPORTED_TOKENS, 2, JSEXN_TYPEERR, "{0} attribute of <{1}> does not define any supported tokens")
MSG_DEF(MSG_CACHE_STREAM_CLOSED, 0, JSEXN_TYPEERR, "Response body is a cache file stream that has already been closed.")
MSG_DEF(MSG_TIME_VALUE_OUT_OF_RANGE, 1, JSEXN_TYPEERR, "{0} is outside the supported range for time values.")
MSG_DEF(MSG_ONLY_IF_CACHED_WITHOUT_SAME_ORIGIN, 1, JSEXN_TYPEERR, "Request mode '{0}' was used, but request cache mode 'only-if-cached' can only be used with request mode 'same-origin'.")
MSG_DEF(MSG_THRESHOLD_RANGE_ERROR, 0, JSEXN_RANGEERR, "Threshold values must all be in the range [0, 1].")
MSG_DEF(MSG_WORKER_THREAD_SHUTTING_DOWN, 0, JSEXN_TYPEERR, "The Worker thread is shutting down.")
MSG_DEF(MSG_CACHE_OPEN_FAILED, 0, JSEXN_TYPEERR, "CacheStorage.open() failed to access the storage system.")
--- a/dom/locales/en-US/chrome/dom/dom.properties
+++ b/dom/locales/en-US/chrome/dom/dom.properties
@@ -304,18 +304,16 @@ PushMessageBadCryptoError=The ServiceWorker for scope ‘%1$S’ failed to decrypt a push message. For help with encryption, please see https://developer.mozilla.org/docs/Web/API/Push_API/Using_the_Push_API#Encryption
# LOCALIZATION NOTE: %1$S is the type of a DOM event. 'passive' is a literal parameter from the DOM spec.
PreventDefaultFromPassiveListenerWarning=Ignoring ‘preventDefault()’ call on event of type ‘%1$S’ from a listener registered as ‘passive’.
FileLastModifiedDateWarning=File.lastModifiedDate is deprecated. Use File.lastModified instead.
# LOCALIZATION NOTE: 'ImageBitmapRenderingContext.transferImageBitmap' and 'ImageBitmapRenderingContext.transferFromImageBitmap' should not be translated
ImageBitmapRenderingContext_TransferImageBitmap=ImageBitmapRenderingContext.transferImageBitmap is deprecated and will be removed soon. Use ImageBitmapRenderingContext.transferFromImageBitmap instead.
ChromeScriptedDOMParserWithoutPrincipal=Creating DOMParser without a principal is deprecated.
IIRFilterChannelCountChangeWarning=IIRFilterNode channel count changes may produce audio glitches.
BiquadFilterChannelCountChangeWarning=BiquadFilterNode channel count changes may produce audio glitches.
-# LOCALIZATION NOTE: %1$S is the unanimatable paced property.
-UnanimatablePacedProperty=Paced property ‘%1$S’ is not an animatable property.
# LOCALIZATION NOTE: Do not translate ".jpeg"
GenericImageNameJPEG=image.jpeg
# LOCALIZATION NOTE: Do not translate ".gif"
GenericImageNameGIF=image.gif
# LOCALIZATION NOTE: Do not translate ".png"
GenericImageNamePNG=image.png
GenericFileName=file
# LOCALIZATION NOTE: Do not translate "Large-Allocation", as it is a literal header name
--- a/dom/webidl/KeyframeEffect.webidl
+++ b/dom/webidl/KeyframeEffect.webidl
@@ -13,29 +13,27 @@
enum IterationCompositeOperation {
"replace",
"accumulate"
};
dictionary KeyframeEffectOptions : AnimationEffectTimingProperties {
IterationCompositeOperation iterationComposite = "replace";
CompositeOperation composite = "replace";
- DOMString spacing = "distribute";
};
[Func="nsDocument::IsWebAnimationsEnabled",
Constructor ((Element or CSSPseudoElement)? target,
object? keyframes,
optional (unrestricted double or KeyframeEffectOptions) options),
Constructor (KeyframeEffectReadOnly source)]
interface KeyframeEffectReadOnly : AnimationEffectReadOnly {
readonly attribute (Element or CSSPseudoElement)? target;
readonly attribute IterationCompositeOperation iterationComposite;
readonly attribute CompositeOperation composite;
- readonly attribute DOMString spacing;
// We use object instead of ComputedKeyframe so that we can put the
// property-value pairs on the object.
[Throws] sequence<object> getKeyframes();
};
// Non-standard extensions
dictionary AnimationPropertyValueDetails {
@@ -61,13 +59,11 @@ partial interface KeyframeEffectReadOnly
object? keyframes,
optional (unrestricted double or KeyframeEffectOptions) options),
Constructor (KeyframeEffectReadOnly source)]
interface KeyframeEffect : KeyframeEffectReadOnly {
inherit attribute (Element or CSSPseudoElement)? target;
[NeedsCallerType]
inherit attribute IterationCompositeOperation iterationComposite;
inherit attribute CompositeOperation composite;
- [SetterThrows, NeedsCallerType]
- inherit attribute DOMString spacing;
[Throws]
void setKeyframes (object? keyframes);
};