mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
921e155863
Currently AnimationTimeline stores animations in a hashmap which means that when we go to iterate over those animations to tick them we will visit them in an order that is non-deterministic. Although many of the observable effects of ticking an animation (e.g. CSS animation/transition events, mutation observer events) are later sorted so that the result does not depend on the order in which animations are ticked, this is not true for in all cases. In particular, the order in which Animation.finished promises are resolved will vary depending on the order in which animations are ticked. Likewise, for Animation finish events. Furthermore, it seems generally desirable to have a deterministic order for visiting animations in order to aid reproducing bugs. To achieve this, this patch switches the storage of animations in AnimationTimeline to use an array instead. However, when adding animations we need to determine if the animation to add already exists. To this end we also maintain a hashmap of the animations so we can quickly determine if the animation to add is a duplicate or not.
78 lines
2.5 KiB
C++
78 lines
2.5 KiB
C++
/* -*- 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 "AnimationTimeline.h"
|
|
#include "mozilla/AnimationComparator.h"
|
|
|
|
namespace mozilla {
|
|
namespace dom {
|
|
|
|
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(AnimationTimeline, mWindow,
|
|
mAnimationOrder)
|
|
|
|
NS_IMPL_CYCLE_COLLECTING_ADDREF(AnimationTimeline)
|
|
NS_IMPL_CYCLE_COLLECTING_RELEASE(AnimationTimeline)
|
|
|
|
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(AnimationTimeline)
|
|
NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
|
|
NS_INTERFACE_MAP_ENTRY(nsISupports)
|
|
NS_INTERFACE_MAP_END
|
|
|
|
void
|
|
AnimationTimeline::GetAnimations(AnimationSequence& aAnimations)
|
|
{
|
|
nsCOMPtr<nsPIDOMWindow> window = do_QueryInterface(mWindow);
|
|
if (mWindow) {
|
|
nsIDocument* doc = window->GetDoc();
|
|
if (doc) {
|
|
doc->FlushPendingNotifications(Flush_Style);
|
|
}
|
|
}
|
|
|
|
aAnimations.SetCapacity(mAnimationOrder.Length());
|
|
|
|
for (Animation* animation : mAnimationOrder) {
|
|
|
|
// Skip animations which are no longer relevant or which have been
|
|
// associated with another timeline. These animations will be removed
|
|
// on the next tick.
|
|
if (!animation->IsRelevant() || animation->GetTimeline() != this) {
|
|
continue;
|
|
}
|
|
|
|
// Bug 1174575: Until we implement a suitable PseudoElement interface we
|
|
// don't have anything to return for the |target| attribute of
|
|
// KeyframeEffect(ReadOnly) objects that refer to pseudo-elements.
|
|
// Rather than return some half-baked version of these objects (e.g.
|
|
// we a null effect attribute) we simply don't provide access to animations
|
|
// whose effect refers to a pseudo-element until we can support them
|
|
// properly.
|
|
Element* target;
|
|
nsCSSPseudoElements::Type pseudoType;
|
|
animation->GetEffect()->GetTarget(target, pseudoType);
|
|
if (pseudoType == nsCSSPseudoElements::ePseudo_NotPseudoElement) {
|
|
aAnimations.AppendElement(animation);
|
|
}
|
|
}
|
|
|
|
// Sort animations by priority
|
|
aAnimations.Sort(AnimationPtrComparator<nsRefPtr<Animation>>());
|
|
}
|
|
|
|
void
|
|
AnimationTimeline::NotifyAnimationUpdated(Animation& aAnimation)
|
|
{
|
|
if (mAnimations.Contains(&aAnimation)) {
|
|
return;
|
|
}
|
|
|
|
mAnimations.PutEntry(&aAnimation);
|
|
mAnimationOrder.AppendElement(&aAnimation);
|
|
}
|
|
|
|
} // namespace dom
|
|
} // namespace mozilla
|