--- a/layout/style/nsAnimationManager.cpp
+++ b/layout/style/nsAnimationManager.cpp
@@ -2,16 +2,17 @@
/* 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 "nsAnimationManager.h"
#include "nsTransitionManager.h"
#include "mozilla/dom/CSSAnimationBinding.h"
+#include "mozilla/AnimationTarget.h"
#include "mozilla/EffectCompositor.h"
#include "mozilla/EffectSet.h"
#include "mozilla/MemoryReporting.h"
#include "mozilla/ServoStyleSet.h"
#include "mozilla/StyleAnimationValue.h"
#include "mozilla/dom/DocumentTimeline.h"
#include "mozilla/dom/KeyframeEffectReadOnly.h"
@@ -410,53 +411,54 @@ nsAnimationManager::UpdateAnimations(nsS
mozilla::dom::Element* aElement)
{
MOZ_ASSERT(mPresContext->IsDynamic(),
"Should not update animations for print or print preview");
MOZ_ASSERT(aElement->IsInComposedDoc(),
"Should not update animations that are not attached to the "
"document tree");
+ NonOwningAnimationTarget target(aElement, aStyleContext->GetPseudoType());
+
// Everything that causes our animation data to change triggers a
// style change, which in turn triggers a non-animation restyle.
// Likewise, when we initially construct frames, we're not in a
// style change, but also not in an animation restyle.
const nsStyleDisplay* disp = aStyleContext->StyleDisplay();
CSSAnimationCollection* collection =
- CSSAnimationCollection::GetAnimationCollection(aElement,
- aStyleContext->
- GetPseudoType());
+ CSSAnimationCollection::GetAnimationCollection(target.mElement,
+ target.mPseudoType);
if (!collection &&
disp->mAnimationNameCount == 1 &&
disp->mAnimations[0].GetName().IsEmpty()) {
return;
}
nsAutoAnimationMutationBatch mb(aElement->OwnerDoc());
// Build the updated animations list, extracting matching animations from
// the existing collection as we go.
OwningCSSAnimationPtrArray newAnimations;
if (!aStyleContext->IsInDisplayNoneSubtree()) {
- BuildAnimations(aStyleContext, aElement, collection, newAnimations);
+ BuildAnimations(aStyleContext, target, collection, newAnimations);
}
if (newAnimations.IsEmpty()) {
if (collection) {
collection->Destroy();
}
return;
}
if (!collection) {
bool createdCollection = false;
collection =
CSSAnimationCollection::GetOrCreateAnimationCollection(
- aElement, aStyleContext->GetPseudoType(), &createdCollection);
+ target.mElement, target.mPseudoType, &createdCollection);
if (!collection) {
MOZ_ASSERT(!createdCollection, "outparam should agree with return value");
NS_WARNING("allocating collection failed");
return;
}
if (createdCollection) {
AddElementCollection(collection);
@@ -528,22 +530,22 @@ ResolvedStyleCache::Get(nsPresContext *a
result = resultStrong;
}
return result;
}
class MOZ_STACK_CLASS CSSAnimationBuilder final {
public:
CSSAnimationBuilder(nsStyleContext* aStyleContext,
- dom::Element* aTarget)
+ const NonOwningAnimationTarget& aTarget)
: mStyleContext(aStyleContext)
, mTarget(aTarget)
{
MOZ_ASSERT(aStyleContext);
- MOZ_ASSERT(aTarget);
+ MOZ_ASSERT(aTarget.mElement);
}
nsTArray<Keyframe> BuildAnimationFrames(nsPresContext* aPresContext,
const StyleAnimation& aSrc,
const nsCSSKeyframesRule* aRule);
private:
Maybe<ComputedTimingFunction> GetKeyframeTimingFunction(
nsPresContext* aPresContext,
@@ -562,32 +564,32 @@ private:
nsTArray<Keyframe>& aKeyframes);
void AppendProperty(nsPresContext* aPresContext,
nsCSSPropertyID aProperty,
nsTArray<PropertyValuePair>& aPropertyValues);
nsCSSValue GetComputedValue(nsPresContext* aPresContext,
nsCSSPropertyID aProperty);
RefPtr<nsStyleContext> mStyleContext;
- RefPtr<dom::Element> mTarget;
+ NonOwningAnimationTarget mTarget;
ResolvedStyleCache mResolvedStyles;
RefPtr<nsStyleContext> mStyleWithoutAnimation;
};
static Maybe<ComputedTimingFunction>
ConvertTimingFunction(const nsTimingFunction& aTimingFunction);
// Returns a new animation set up with given StyleAnimation.
// Or returns an existing animation matching StyleAnimation's name updated
// with the new StyleAnimation.
static already_AddRefed<CSSAnimation>
BuildAnimation(nsPresContext* aPresContext,
nsStyleContext* aStyleContext,
- dom::Element* aTarget,
+ const NonOwningAnimationTarget& aTarget,
const StyleAnimation& aSrc,
CSSAnimationBuilder& aBuilder,
nsAnimationManager::CSSAnimationCollection* aCollection)
{
MOZ_ASSERT(aPresContext);
nsTArray<Keyframe> keyframes;
if (aPresContext->StyleSet()->IsServo()) {
@@ -640,31 +642,31 @@ BuildAnimation(nsPresContext* aPresConte
Move(keyframes),
isStylePaused,
aStyleContext);
return oldAnim.forget();
}
// mTarget is non-null here, so we emplace it directly.
Maybe<OwningAnimationTarget> target;
- target.emplace(aTarget, aStyleContext->GetPseudoType());
+ target.emplace(aTarget.mElement, aTarget.mPseudoType);
KeyframeEffectParams effectOptions;
RefPtr<KeyframeEffectReadOnly> effect =
new KeyframeEffectReadOnly(aPresContext->Document(), target, timing,
effectOptions);
effect->SetKeyframes(Move(keyframes), aStyleContext);
RefPtr<CSSAnimation> animation =
new CSSAnimation(aPresContext->Document()->GetScopeObject(),
aSrc.GetName());
animation->SetOwningElement(
- OwningElementRef(*aTarget, aStyleContext->GetPseudoType()));
+ OwningElementRef(*aTarget.mElement, aTarget.mPseudoType));
- animation->SetTimelineNoUpdate(aTarget->OwnerDoc()->Timeline());
+ animation->SetTimelineNoUpdate(aTarget.mElement->OwnerDoc()->Timeline());
animation->SetEffectNoUpdate(effect);
if (isStylePaused) {
animation->PauseFromStyle();
} else {
animation->PlayFromStyle();
}
@@ -1044,17 +1046,17 @@ CSSAnimationBuilder::GetComputedValue(ns
nsCSSValue result;
StyleAnimationValue computedValue;
if (!mStyleWithoutAnimation) {
MOZ_ASSERT(aPresContext->StyleSet()->IsGecko(),
"ServoStyleSet should not use nsAnimationManager for "
"animations");
mStyleWithoutAnimation = aPresContext->StyleSet()->AsGecko()->
- ResolveStyleByRemovingAnimation(mTarget, mStyleContext,
+ ResolveStyleByRemovingAnimation(mTarget.mElement, mStyleContext,
eRestyle_AllHintsWithAnimations);
}
if (StyleAnimationValue::ExtractComputedValue(aProperty,
mStyleWithoutAnimation,
computedValue)) {
DebugOnly<bool> uncomputeResult =
StyleAnimationValue::UncomputeValue(aProperty, Move(computedValue),
@@ -1068,17 +1070,17 @@ CSSAnimationBuilder::GetComputedValue(ns
// a StyleAnimationValue.
MOZ_ASSERT(result.GetUnit() != eCSSUnit_Null, "Got null computed value");
return result;
}
void
nsAnimationManager::BuildAnimations(nsStyleContext* aStyleContext,
- dom::Element* aTarget,
+ const NonOwningAnimationTarget& aTarget,
CSSAnimationCollection* aCollection,
OwningCSSAnimationPtrArray& aAnimations)
{
MOZ_ASSERT(aAnimations.IsEmpty(), "expect empty array");
const nsStyleDisplay *disp = aStyleContext->StyleDisplay();
CSSAnimationBuilder builder(aStyleContext, aTarget);
--- a/layout/style/nsAnimationManager.h
+++ b/layout/style/nsAnimationManager.h
@@ -21,16 +21,17 @@ namespace css {
class Declaration;
} /* namespace css */
namespace dom {
class KeyframeEffectReadOnly;
class Promise;
} /* namespace dom */
enum class CSSPseudoElementType : uint8_t;
+struct NonOwningAnimationTarget;
struct AnimationEventInfo {
RefPtr<dom::Element> mElement;
RefPtr<dom::Animation> mAnimation;
InternalAnimationEvent mEvent;
TimeStamp mTimeStamp;
AnimationEventInfo(dom::Element* aElement,
@@ -351,16 +352,16 @@ public:
mozilla::CSSPseudoElementType aPseudoType);
protected:
~nsAnimationManager() override = default;
private:
void BuildAnimations(nsStyleContext* aStyleContext,
- mozilla::dom::Element* aTarget,
+ const mozilla::NonOwningAnimationTarget& aTarget,
CSSAnimationCollection* aCollection,
OwningCSSAnimationPtrArray& aAnimations);
mozilla::DelayedEventDispatcher<mozilla::AnimationEventInfo> mEventDispatcher;
};
#endif /* !defined(nsAnimationManager_h_) */