- Revision
- 261470
- Author
- grao...@webkit.org
- Date
- 2020-05-11 02:14:37 -0700 (Mon, 11 May 2020)
Log Message
[Web Animations] Refactor animation comparison by composite order in a single utility function
https://bugs.webkit.org/show_bug.cgi?id=211695
Reviewed by Darin Adler.
We used to split sorting of animations by composite order across several functions and files. Specifically,
DocumentTimeline::getAnimations() would first collect animations by class (CSS Transitions, then CSS
Animations, then JS-originated animations), and then sort each class, calling into the static function
compareDeclarativeAnimationOwningElementPositionsInDocumentTreeOrder() in some cases and into the
WebAnimationUtilities compareAnimationsByCompositeOrder() function in other.
Since we need to be able to sort animations by composite order in other situations, for instance when sorting
events when updating animations and sending events (which we will do in a future patch), we refactor all
of the comparison logic into compareAnimationsByCompositeOrder(), removing the need to provide an AnimationList,
which is specific to the case where we know we are comparing CSSAnimation objects targeting a shared element.
This effectively empties DocumentTimeline::getAnimations() so we remove this function and filter relevant
animations in Document::matchingAnimations() and call compareAnimationsByCompositeOrder() before returning
the compiled animations.
No new tests since there is no change of behavior.
* animation/DocumentTimeline.cpp:
(WebCore::compareDeclarativeAnimationOwningElementPositionsInDocumentTreeOrder): Deleted.
(WebCore::DocumentTimeline::getAnimations const): Deleted.
* animation/DocumentTimeline.h:
* animation/KeyframeEffectStack.cpp:
(WebCore::KeyframeEffectStack::ensureEffectsAreSorted):
* animation/WebAnimation.cpp:
(WebCore::WebAnimation::commitStyles):
* animation/WebAnimationUtilities.cpp:
(WebCore::compareDeclarativeAnimationOwningElementPositionsInDocumentTreeOrder):
(WebCore::compareCSSTransitions):
(WebCore::compareCSSAnimations):
(WebCore::compareAnimationsByCompositeOrder):
* animation/WebAnimationUtilities.h:
* dom/Document.cpp:
(WebCore::Document::matchingAnimations):
Modified Paths
Diff
Modified: trunk/Source/WebCore/ChangeLog (261469 => 261470)
--- trunk/Source/WebCore/ChangeLog 2020-05-11 09:05:01 UTC (rev 261469)
+++ trunk/Source/WebCore/ChangeLog 2020-05-11 09:14:37 UTC (rev 261470)
@@ -1,3 +1,44 @@
+2020-05-10 Antoine Quint <grao...@apple.com>
+
+ [Web Animations] Refactor animation comparison by composite order in a single utility function
+ https://bugs.webkit.org/show_bug.cgi?id=211695
+
+ Reviewed by Darin Adler.
+
+ We used to split sorting of animations by composite order across several functions and files. Specifically,
+ DocumentTimeline::getAnimations() would first collect animations by class (CSS Transitions, then CSS
+ Animations, then JS-originated animations), and then sort each class, calling into the static function
+ compareDeclarativeAnimationOwningElementPositionsInDocumentTreeOrder() in some cases and into the
+ WebAnimationUtilities compareAnimationsByCompositeOrder() function in other.
+
+ Since we need to be able to sort animations by composite order in other situations, for instance when sorting
+ events when updating animations and sending events (which we will do in a future patch), we refactor all
+ of the comparison logic into compareAnimationsByCompositeOrder(), removing the need to provide an AnimationList,
+ which is specific to the case where we know we are comparing CSSAnimation objects targeting a shared element.
+
+ This effectively empties DocumentTimeline::getAnimations() so we remove this function and filter relevant
+ animations in Document::matchingAnimations() and call compareAnimationsByCompositeOrder() before returning
+ the compiled animations.
+
+ No new tests since there is no change of behavior.
+
+ * animation/DocumentTimeline.cpp:
+ (WebCore::compareDeclarativeAnimationOwningElementPositionsInDocumentTreeOrder): Deleted.
+ (WebCore::DocumentTimeline::getAnimations const): Deleted.
+ * animation/DocumentTimeline.h:
+ * animation/KeyframeEffectStack.cpp:
+ (WebCore::KeyframeEffectStack::ensureEffectsAreSorted):
+ * animation/WebAnimation.cpp:
+ (WebCore::WebAnimation::commitStyles):
+ * animation/WebAnimationUtilities.cpp:
+ (WebCore::compareDeclarativeAnimationOwningElementPositionsInDocumentTreeOrder):
+ (WebCore::compareCSSTransitions):
+ (WebCore::compareCSSAnimations):
+ (WebCore::compareAnimationsByCompositeOrder):
+ * animation/WebAnimationUtilities.h:
+ * dom/Document.cpp:
+ (WebCore::Document::matchingAnimations):
+
2020-05-11 Charlie Turner <ctur...@igalia.com>
[WPE] Layout test media/encrypted-media/mock-MediaKeySystemAccess.html is crashing
Modified: trunk/Source/WebCore/animation/DocumentTimeline.cpp (261469 => 261470)
--- trunk/Source/WebCore/animation/DocumentTimeline.cpp 2020-05-11 09:05:01 UTC (rev 261469)
+++ trunk/Source/WebCore/animation/DocumentTimeline.cpp 2020-05-11 09:14:37 UTC (rev 261470)
@@ -27,7 +27,6 @@
#include "DocumentTimeline.h"
#include "AnimationEventBase.h"
-#include "CSSAnimation.h"
#include "CSSTransition.h"
#include "DeclarativeAnimation.h"
#include "Document.h"
@@ -38,7 +37,6 @@
#include "KeyframeEffectStack.h"
#include "Node.h"
#include "Page.h"
-#include "PseudoElement.h"
#include "RenderElement.h"
#include "RenderLayer.h"
#include "RenderLayerBacking.h"
@@ -100,114 +98,6 @@
m_document = nullptr;
}
-static inline bool compareDeclarativeAnimationOwningElementPositionsInDocumentTreeOrder(Element* lhsOwningElement, Element* rhsOwningElement)
-{
- // With regard to pseudo-elements, the sort order is as follows:
- // - element
- // - ::before
- // - ::after
- // - element children
-
- // We could be comparing two pseudo-elements that are hosted on the same element.
- if (is<PseudoElement>(lhsOwningElement) && is<PseudoElement>(rhsOwningElement)) {
- auto* lhsPseudoElement = downcast<PseudoElement>(lhsOwningElement);
- auto* rhsPseudoElement = downcast<PseudoElement>(rhsOwningElement);
- if (lhsPseudoElement->hostElement() == rhsPseudoElement->hostElement())
- return lhsPseudoElement->isBeforePseudoElement();
- }
-
- // Or comparing a pseudo-element that is compared to another non-pseudo element, in which case
- // we want to see if it's hosted on that other element, and if not use its host element to compare.
- if (is<PseudoElement>(lhsOwningElement)) {
- auto* lhsHostElement = downcast<PseudoElement>(lhsOwningElement)->hostElement();
- if (rhsOwningElement == lhsHostElement)
- return false;
- lhsOwningElement = lhsHostElement;
- }
-
- if (is<PseudoElement>(rhsOwningElement)) {
- auto* rhsHostElement = downcast<PseudoElement>(rhsOwningElement)->hostElement();
- if (lhsOwningElement == rhsHostElement)
- return true;
- rhsOwningElement = rhsHostElement;
- }
-
- return lhsOwningElement->compareDocumentPosition(*rhsOwningElement) & Node::DOCUMENT_POSITION_FOLLOWING;
-}
-
-Vector<RefPtr<WebAnimation>> DocumentTimeline::getAnimations() const
-{
- ASSERT(m_document);
-
- Vector<RefPtr<WebAnimation>> cssTransitions;
- Vector<RefPtr<WebAnimation>> cssAnimations;
- Vector<RefPtr<WebAnimation>> webAnimations;
-
- // First, let's get all qualifying animations in their right group.
- for (const auto& animation : m_animations) {
- if (!animation || !animation->isRelevant() || animation->timeline() != this || !is<KeyframeEffect>(animation->effect()))
- continue;
-
- auto* target = downcast<KeyframeEffect>(animation->effect())->target();
- if (!target || !target->isDescendantOf(*m_document))
- continue;
-
- if (is<CSSTransition>(animation.get()) && downcast<CSSTransition>(animation.get())->owningElement())
- cssTransitions.append(animation);
- else if (is<CSSAnimation>(animation.get()) && downcast<CSSAnimation>(animation.get())->owningElement())
- cssAnimations.append(animation);
- else
- webAnimations.append(animation);
- }
-
- // Now sort CSS Transitions by their composite order.
- std::stable_sort(cssTransitions.begin(), cssTransitions.end(), [](auto& lhs, auto& rhs) {
- // https://drafts.csswg.org/css-transitions-2/#animation-composite-order
- auto* lhsTransition = downcast<CSSTransition>(lhs.get());
- auto* rhsTransition = downcast<CSSTransition>(rhs.get());
-
- auto* lhsOwningElement = lhsTransition->owningElement();
- auto* rhsOwningElement = rhsTransition->owningElement();
-
- // If the owning element of A and B differs, sort A and B by tree order of their corresponding owning elements.
- if (lhsOwningElement != rhsOwningElement)
- return compareDeclarativeAnimationOwningElementPositionsInDocumentTreeOrder(lhsOwningElement, rhsOwningElement);
-
- // Otherwise, if A and B have different transition generation values, sort by their corresponding transition generation in ascending order.
- if (lhsTransition->generationTime() != rhsTransition->generationTime())
- return lhsTransition->generationTime() < rhsTransition->generationTime();
-
- // Otherwise, sort A and B in ascending order by the Unicode codepoints that make up the expanded transition property name of each transition
- // (i.e. without attempting case conversion and such that ‘-moz-column-width’ sorts before ‘column-width’).
- return lhsTransition->transitionProperty().utf8() < rhsTransition->transitionProperty().utf8();
- });
-
- // Now sort CSS Animations by their composite order.
- std::stable_sort(cssAnimations.begin(), cssAnimations.end(), [](auto& lhs, auto& rhs) {
- // https://drafts.csswg.org/css-animations-2/#animation-composite-order
- auto* lhsOwningElement = downcast<CSSAnimation>(lhs.get())->owningElement();
- auto* rhsOwningElement = downcast<CSSAnimation>(rhs.get())->owningElement();
-
- // If the owning element of A and B differs, sort A and B by tree order of their corresponding owning elements.
- if (lhsOwningElement != rhsOwningElement)
- return compareDeclarativeAnimationOwningElementPositionsInDocumentTreeOrder(lhsOwningElement, rhsOwningElement);
-
- // Otherwise, sort A and B based on their position in the computed value of the animation-name property of the (common) owning element.
- return compareAnimationsByCompositeOrder(*lhs, *rhs, lhsOwningElement->ensureKeyframeEffectStack().cssAnimationList());
- });
-
- std::stable_sort(webAnimations.begin(), webAnimations.end(), [](auto& lhs, auto& rhs) {
- return lhs->globalPosition() < rhs->globalPosition();
- });
-
- // Finally, we can concatenate the sorted CSS Transitions, CSS Animations and Web Animations in their relative composite order.
- Vector<RefPtr<WebAnimation>> animations;
- animations.appendRange(cssTransitions.begin(), cssTransitions.end());
- animations.appendRange(cssAnimations.begin(), cssAnimations.end());
- animations.appendRange(webAnimations.begin(), webAnimations.end());
- return animations;
-}
-
Seconds DocumentTimeline::animationInterval() const
{
if (!m_document || !m_document->page())
Modified: trunk/Source/WebCore/animation/DocumentTimeline.h (261469 => 261470)
--- trunk/Source/WebCore/animation/DocumentTimeline.h 2020-05-11 09:05:01 UTC (rev 261469)
+++ trunk/Source/WebCore/animation/DocumentTimeline.h 2020-05-11 09:14:37 UTC (rev 261470)
@@ -46,8 +46,6 @@
bool isDocumentTimeline() const final { return true; }
- Vector<RefPtr<WebAnimation>> getAnimations() const;
-
Document* document() const { return m_document.get(); }
Optional<Seconds> currentTime() override;
Modified: trunk/Source/WebCore/animation/KeyframeEffectStack.cpp (261469 => 261470)
--- trunk/Source/WebCore/animation/KeyframeEffectStack.cpp 2020-05-11 09:05:01 UTC (rev 261469)
+++ trunk/Source/WebCore/animation/KeyframeEffectStack.cpp 2020-05-11 09:14:37 UTC (rev 261470)
@@ -98,7 +98,7 @@
RELEASE_ASSERT(lhsAnimation);
RELEASE_ASSERT(rhsAnimation);
- return compareAnimationsByCompositeOrder(*lhsAnimation, *rhsAnimation, m_cssAnimationList.get());
+ return compareAnimationsByCompositeOrder(*lhsAnimation, *rhsAnimation);
});
m_isSorted = true;
Modified: trunk/Source/WebCore/animation/WebAnimation.cpp (261469 => 261470)
--- trunk/Source/WebCore/animation/WebAnimation.cpp 2020-05-11 09:05:01 UTC (rev 261469)
+++ trunk/Source/WebCore/animation/WebAnimation.cpp 2020-05-11 09:14:37 UTC (rev 261470)
@@ -1415,7 +1415,6 @@
inlineStyle->setCssText(styledElement.getAttribute("style"));
auto& keyframeStack = styledElement.ensureKeyframeEffectStack();
- auto* cssAnimationList = keyframeStack.cssAnimationList();
// 2.5 For each property, property, in targeted properties:
for (auto property : effect->animatedProperties()) {
@@ -1432,7 +1431,7 @@
// effect stack and stop when we've found this animation's effect or when we've found an effect associated with an animation with a higher composite order.
auto animatedStyle = RenderStyle::clonePtr(style);
for (const auto& effectInStack : keyframeStack.sortedEffects()) {
- if (effectInStack->animation() != this && !compareAnimationsByCompositeOrder(*effectInStack->animation(), *this, cssAnimationList))
+ if (effectInStack->animation() != this && !compareAnimationsByCompositeOrder(*effectInStack->animation(), *this))
break;
if (effectInStack->animatedProperties().contains(property))
effectInStack->animation()->resolve(*animatedStyle);
Modified: trunk/Source/WebCore/animation/WebAnimationUtilities.cpp (261469 => 261470)
--- trunk/Source/WebCore/animation/WebAnimationUtilities.cpp 2020-05-11 09:05:01 UTC (rev 261469)
+++ trunk/Source/WebCore/animation/WebAnimationUtilities.cpp 2020-05-11 09:14:37 UTC (rev 261470)
@@ -31,71 +31,134 @@
#include "CSSAnimation.h"
#include "CSSTransition.h"
#include "DeclarativeAnimation.h"
+#include "Element.h"
+#include "KeyframeEffectStack.h"
+#include "PseudoElement.h"
#include "WebAnimation.h"
namespace WebCore {
-bool compareAnimationsByCompositeOrder(WebAnimation& lhsAnimation, WebAnimation& rhsAnimation, const AnimationList* cssAnimationList)
+static bool compareDeclarativeAnimationOwningElementPositionsInDocumentTreeOrder(Element& a, Element& b)
{
- // We should not ever be calling this function with two WebAnimation objects that are the same. If that were the case,
- // then comparing objects of this kind would yield inconsistent results when comparing A == B and B == A. As such,
- // this function should be called with std::stable_sort().
- RELEASE_ASSERT_WITH_SECURITY_IMPLICATION(&lhsAnimation != &rhsAnimation);
+ // We should not ever be calling this function with two Elements that are the same. If that were the case,
+ // then comparing objects of this kind would yield inconsistent results when comparing A == B and B == A.
+ // As such, this function should be called with std::stable_sort().
+ RELEASE_ASSERT_WITH_SECURITY_IMPLICATION(&a != &b);
- bool lhsHasOwningElement = is<DeclarativeAnimation>(lhsAnimation) && downcast<DeclarativeAnimation>(lhsAnimation).owningElement();
- bool rhsHasOwningElement = is<DeclarativeAnimation>(rhsAnimation) && downcast<DeclarativeAnimation>(rhsAnimation).owningElement();
+ // With regard to pseudo-elements, the sort order is as follows:
+ // - element
+ // - ::before
+ // - ::after
+ // - element children
- // CSS Transitions sort first.
- bool lhsIsCSSTransition = lhsHasOwningElement && is<CSSTransition>(lhsAnimation);
- bool rhsIsCSSTransition = rhsHasOwningElement && is<CSSTransition>(rhsAnimation);
- if (lhsIsCSSTransition || rhsIsCSSTransition) {
- if (lhsIsCSSTransition != rhsIsCSSTransition)
- return !rhsIsCSSTransition;
+ enum SortingIndex : uint8_t { NotPseudo, Before, After };
- // Sort transitions first by their generation time, and then by transition-property.
- // https://drafts.csswg.org/css-transitions-2/#animation-composite-order
- auto& lhsCSSTransition = downcast<CSSTransition>(lhsAnimation);
- auto& rhsCSSTransition = downcast<CSSTransition>(rhsAnimation);
- if (lhsCSSTransition.generationTime() != rhsCSSTransition.generationTime())
- return lhsCSSTransition.generationTime() < rhsCSSTransition.generationTime();
- auto lhsCSSTransitionProperty = lhsCSSTransition.transitionProperty().utf8();
- auto rhsCSSTransitionProperty = rhsCSSTransition.transitionProperty().utf8();
- if (lhsCSSTransitionProperty != rhsCSSTransitionProperty)
- return lhsCSSTransitionProperty < rhsCSSTransitionProperty;
+ int aSortingIndex = NotPseudo;
+ Element* aReferenceElement = &a;
+ if (is<PseudoElement>(a)) {
+ auto& aPseudo = downcast<PseudoElement>(a);
+ aSortingIndex = aPseudo.isBeforePseudoElement() ? Before : After;
+ aReferenceElement = aPseudo.hostElement();
+ ASSERT(aReferenceElement);
}
- // CSS Animations sort next.
- bool lhsIsCSSAnimation = lhsHasOwningElement && is<CSSAnimation>(lhsAnimation);
- bool rhsIsCSSAnimation = rhsHasOwningElement && is<CSSAnimation>(rhsAnimation);
- if (lhsIsCSSAnimation || rhsIsCSSAnimation) {
- if (lhsIsCSSAnimation != rhsIsCSSAnimation)
- return !rhsIsCSSAnimation;
+ int bSortingIndex = NotPseudo;
+ Element* bReferenceElement = &b;
+ if (is<PseudoElement>(b)) {
+ auto& bPseudo = downcast<PseudoElement>(b);
+ bSortingIndex = bPseudo.isBeforePseudoElement() ? Before : After;
+ bReferenceElement = bPseudo.hostElement();
+ ASSERT(bReferenceElement);
+ }
- // We must have a list of CSS Animations if we have CSS Animations to sort through.
- ASSERT(cssAnimationList);
- ASSERT(!cssAnimationList->isEmpty());
+ if (aReferenceElement == bReferenceElement)
+ return aSortingIndex < bSortingIndex;
+ return aReferenceElement->compareDocumentPosition(*bReferenceElement) & Node::DOCUMENT_POSITION_FOLLOWING;
+}
- // https://drafts.csswg.org/css-animations-2/#animation-composite-order
- // Sort A and B based on their position in the computed value of the animation-name property of the (common) owning element.
- auto& lhsBackingAnimation = downcast<CSSAnimation>(lhsAnimation).backingAnimation();
- auto& rhsBackingAnimation = downcast<CSSAnimation>(rhsAnimation).backingAnimation();
+static bool compareCSSTransitions(const CSSTransition& a, const CSSTransition& b)
+{
+ ASSERT(a.owningElement());
+ ASSERT(b.owningElement());
+ auto& aOwningElement = *a.owningElement();
+ auto& bOwningElement = *b.owningElement();
- for (size_t i = 0; i < cssAnimationList->size(); ++i) {
- auto& animation = cssAnimationList->animation(i);
- if (animation == lhsBackingAnimation)
- return true;
- if (animation == rhsBackingAnimation)
- return false;
- }
+ // If the owning element of A and B differs, sort A and B by tree order of their corresponding owning elements.
+ if (&aOwningElement != &bOwningElement)
+ return compareDeclarativeAnimationOwningElementPositionsInDocumentTreeOrder(aOwningElement, bOwningElement);
- // We should have found either of those CSS animations in the CSS animations list.
- RELEASE_ASSERT_NOT_REACHED();
+ // Otherwise, if A and B have different transition generation values, sort by their corresponding transition generation in ascending order.
+ if (a.generationTime() != b.generationTime())
+ return a.generationTime() < b.generationTime();
+
+ // Otherwise, sort A and B in ascending order by the Unicode codepoints that make up the expanded transition property name of each transition
+ // (i.e. without attempting case conversion and such that ‘-moz-column-width’ sorts before ‘column-width’).
+ return a.transitionProperty().utf8() < b.transitionProperty().utf8();
+}
+
+static bool compareCSSAnimations(const CSSAnimation& a, const CSSAnimation& b)
+{
+ // https://drafts.csswg.org/css-animations-2/#animation-composite-order
+ ASSERT(a.owningElement());
+ ASSERT(b.owningElement());
+ auto& aOwningElement = *a.owningElement();
+ auto& bOwningElement = *b.owningElement();
+
+ // If the owning element of A and B differs, sort A and B by tree order of their corresponding owning elements.
+ if (&aOwningElement != &bOwningElement)
+ return compareDeclarativeAnimationOwningElementPositionsInDocumentTreeOrder(aOwningElement, bOwningElement);
+
+ // Sort A and B based on their position in the computed value of the animation-name property of the (common) owning element.
+ auto* cssAnimationList = aOwningElement.ensureKeyframeEffectStack().cssAnimationList();
+ ASSERT(cssAnimationList);
+ ASSERT(!cssAnimationList->isEmpty());
+
+ auto& aBackingAnimation = a.backingAnimation();
+ auto& bBackingAnimation = b.backingAnimation();
+ for (size_t i = 0; i < cssAnimationList->size(); ++i) {
+ auto& animation = cssAnimationList->animation(i);
+ if (animation == aBackingAnimation)
+ return true;
+ if (animation == bBackingAnimation)
+ return false;
}
+ // We should have found either of those CSS animations in the CSS animations list.
+ RELEASE_ASSERT_NOT_REACHED();
+}
+
+bool compareAnimationsByCompositeOrder(const WebAnimation& a, const WebAnimation& b)
+{
+ // We should not ever be calling this function with two WebAnimation objects that are the same. If that were the case,
+ // then comparing objects of this kind would yield inconsistent results when comparing A == B and B == A. As such,
+ // this function should be called with std::stable_sort().
+ RELEASE_ASSERT_WITH_SECURITY_IMPLICATION(&a != &b);
+
+ bool aHasOwningElement = is<DeclarativeAnimation>(a) && downcast<DeclarativeAnimation>(a).owningElement();
+ bool bHasOwningElement = is<DeclarativeAnimation>(b) && downcast<DeclarativeAnimation>(b).owningElement();
+
+ // CSS Transitions sort first.
+ bool aIsCSSTransition = aHasOwningElement && is<CSSTransition>(a);
+ bool bIsCSSTransition = bHasOwningElement && is<CSSTransition>(b);
+ if (aIsCSSTransition || bIsCSSTransition) {
+ if (aIsCSSTransition == bIsCSSTransition)
+ return compareCSSTransitions(downcast<CSSTransition>(a), downcast<CSSTransition>(b));
+ return !bIsCSSTransition;
+ }
+
+ // CSS Animations sort next.
+ bool aIsCSSAnimation = aHasOwningElement && is<CSSAnimation>(a);
+ bool bIsCSSAnimation = bHasOwningElement && is<CSSAnimation>(b);
+ if (aIsCSSAnimation || bIsCSSAnimation) {
+ if (aIsCSSAnimation == bIsCSSAnimation)
+ return compareCSSAnimations(downcast<CSSAnimation>(a), downcast<CSSAnimation>(b));
+ return !bIsCSSAnimation;
+ }
+
// JS-originated animations sort last based on their position in the global animation list.
// https://drafts.csswg.org/web-animations-1/#animation-composite-order
- RELEASE_ASSERT(lhsAnimation.globalPosition() != rhsAnimation.globalPosition() || &lhsAnimation == &rhsAnimation);
- return lhsAnimation.globalPosition() < rhsAnimation.globalPosition();
+ RELEASE_ASSERT(a.globalPosition() != b.globalPosition());
+ return a.globalPosition() < b.globalPosition();
}
} // namespace WebCore
Modified: trunk/Source/WebCore/animation/WebAnimationUtilities.h (261469 => 261470)
--- trunk/Source/WebCore/animation/WebAnimationUtilities.h 2020-05-11 09:05:01 UTC (rev 261469)
+++ trunk/Source/WebCore/animation/WebAnimationUtilities.h 2020-05-11 09:14:37 UTC (rev 261470)
@@ -31,7 +31,7 @@
namespace WebCore {
-class AnimationList;
+class Element;
class WebAnimation;
inline double secondsToWebAnimationsAPITime(const Seconds time)
@@ -50,7 +50,7 @@
const auto timeEpsilon = Seconds::fromMilliseconds(0.001);
-bool compareAnimationsByCompositeOrder(WebAnimation&, WebAnimation&, const AnimationList*);
+bool compareAnimationsByCompositeOrder(const WebAnimation&, const WebAnimation&);
} // namespace WebCore
Modified: trunk/Source/WebCore/dom/Document.cpp (261469 => 261470)
--- trunk/Source/WebCore/dom/Document.cpp 2020-05-11 09:05:01 UTC (rev 261469)
+++ trunk/Source/WebCore/dom/Document.cpp 2020-05-11 09:14:37 UTC (rev 261470)
@@ -233,6 +233,7 @@
#include "VisitedLinkState.h"
#include "VisualViewport.h"
#include "WebAnimation.h"
+#include "WebAnimationUtilities.h"
#include "WheelEvent.h"
#include "WindowEventLoop.h"
#include "WindowFeatures.h"
@@ -8132,14 +8133,19 @@
return { };
Vector<RefPtr<WebAnimation>> animations;
- for (auto& animation : m_timeline->getAnimations()) {
- auto* effect = animation->effect();
- ASSERT(is<KeyframeEffect>(animation->effect()));
- auto* target = downcast<KeyframeEffect>(*effect).targetElementOrPseudoElement();
- ASSERT(target);
- if (function(*target))
+ for (auto& animation : m_timeline->relevantAnimations()) {
+ if (!animation || !animation->isRelevant() || !is<KeyframeEffect>(animation->effect()))
+ continue;
+
+ auto* target = downcast<KeyframeEffect>(*animation->effect()).targetElementOrPseudoElement();
+ if (target && target->isDescendantOf(this) && function(*target))
animations.append(animation);
}
+
+ std::stable_sort(animations.begin(), animations.end(), [](auto& lhs, auto& rhs) {
+ return compareAnimationsByCompositeOrder(*lhs, *rhs);
+ });
+
return animations;
}