Diff
Modified: trunk/LayoutTests/ChangeLog (252910 => 252911)
--- trunk/LayoutTests/ChangeLog 2019-11-27 19:20:12 UTC (rev 252910)
+++ trunk/LayoutTests/ChangeLog 2019-11-27 19:38:43 UTC (rev 252911)
@@ -1,3 +1,15 @@
+2019-11-27 Antoine Quint <grao...@apple.com>
+
+ REGRESSION(r252455): imported/w3c/web-platform-tests/dom/events/Event-dispatch-on-disabled-elements.html fails on iOS and WK1
+ https://bugs.webkit.org/show_bug.cgi?id=204272
+ <rdar://problem/57253742>
+
+ Reviewed by Dean Jackson.
+
+ Removing this specific expectation for WK1 since it now behaves just like the other configurations.
+
+ * platform/mac-wk1/imported/w3c/web-platform-tests/dom/events/Event-dispatch-on-disabled-elements-expected.txt: Removed.
+
2019-11-27 Jonathan Bedard <jbed...@apple.com>
[WebGL] Garden dedicated queue (Part 7)
Modified: trunk/Source/WebCore/ChangeLog (252910 => 252911)
--- trunk/Source/WebCore/ChangeLog 2019-11-27 19:20:12 UTC (rev 252910)
+++ trunk/Source/WebCore/ChangeLog 2019-11-27 19:38:43 UTC (rev 252911)
@@ -1,3 +1,72 @@
+2019-11-27 Antoine Quint <grao...@apple.com>
+
+ REGRESSION(r252455): imported/w3c/web-platform-tests/dom/events/Event-dispatch-on-disabled-elements.html fails on iOS and WK1
+ https://bugs.webkit.org/show_bug.cgi?id=204272
+ <rdar://problem/57253742>
+
+ Reviewed by Dean Jackson.
+
+ Events for declarative animations are dispatched using a MainThreadGenericEventQueue which dispatches enqueued events asynchronously. When a declarative
+ animation would be canceled, AnimationTimeline::cancelDeclarativeAnimation() would be called and would enqueue a "transitioncancel" or "animationcancel"
+ event (depending on the animation type) by virtue of calling DeclarativeAnimation::cancelFromStyle(), and would also call AnimationTimeline::removeAnimation()
+ right after. However, calling AnimationTimeline::removeAnimation() could have the side effect of removing the last reference to the DeclarativeAnimation
+ object, which would destroy its attached MainThreadGenericEventQueue before it had the time to dispatch the queued "transitioncancel" or "animationcancel"
+ event.
+
+ The call to AnimationTimeline::removeAnimation() in AnimationTimeline::cancelDeclarativeAnimation() is actually unnecessary. Simply canceling the animation
+ via DeclarativeAnimation::cancelFromStyle() will end up calling AnimationTimeline::removeAnimation() the next time animations are updated, which will leave
+ time for the cancel events to be dispatched. So all we need to do is remove AnimationTimeline::cancelDeclarativeAnimation() and replace its call sites with
+ simple calls to DeclarativeAnimation::cancelFromStyle().
+
+ Making this change broke a test however: imported/w3c/web-platform-tests/css/css-animations/Document-getAnimations.tentative.html. We actually passed that
+ test by chance without implementing the feature required to make it work. We now implement the correct way to track a global position for an animation by
+ only setting one for declarative animations once they are disassociated with their owning element and have a non-idle play state.
+
+ And a few other tests broke: animations/animation-shorthand-name-order.html, imported/w3c/web-platform-tests/css/css-animations/animationevent-types.html
+ and webanimations/css-animations.html. The reason for those tests being broken was that not calling AnimationTimeline::removeAnimation() instantly as CSS
+ Animations were canceled also meant that the KeyframeEffectStack for the targeted element wasn't updated. To solve this, we added the animationTimingDidChange()
+ method on KeyframeEffect which is called whenever timing on the owning Animation changes, so for instance when cancel() is called as we cancel a CSS
+ Animation. That way we ensure we add and remove KeyframeEffect instances from the KeyframeEffectStack as the animation becomes relevant, which is now
+ an added condition checked by KeyframeEffectStack::addEffect().
+
+ Finally, this revealed an issue in KeyframeEffectStack::ensureEffectsAreSorted() where we would consider CSSTransition and CSSAnimation objects to be
+ representative of a CSS Transition or CSS Animation even after the relationship with their owning element had been severed. We now correctly check that
+ relationship is intact and otherwise consider those animations just like any other animation.
+
+ * animation/AnimationTimeline.cpp:
+ (WebCore::AnimationTimeline::animationTimingDidChange):
+ (WebCore::AnimationTimeline::updateGlobalPosition):
+ (WebCore::AnimationTimeline::removeDeclarativeAnimationFromListsForOwningElement):
+ (WebCore::AnimationTimeline::updateCSSAnimationsForElement):
+ (WebCore::AnimationTimeline::updateCSSTransitionsForElementAndProperty):
+ (WebCore::AnimationTimeline::updateCSSTransitionsForElement):
+ (WebCore::AnimationTimeline::cancelDeclarativeAnimation): Deleted.
+ * animation/AnimationTimeline.h:
+ * animation/CSSAnimation.cpp:
+ (WebCore::CSSAnimation::syncPropertiesWithBackingAnimation):
+ * animation/CSSTransition.cpp:
+ (WebCore::CSSTransition::setTimingProperties):
+ * animation/DeclarativeAnimation.cpp:
+ (WebCore::DeclarativeAnimation::canHaveGlobalPosition):
+ * animation/DeclarativeAnimation.h:
+ * animation/DocumentTimeline.cpp:
+ (WebCore::DocumentTimeline::getAnimations const):
+ * animation/KeyframeEffect.cpp:
+ (WebCore::KeyframeEffect::animationTimelineDidChange):
+ (WebCore::KeyframeEffect::animationTimingDidChange):
+ (WebCore::KeyframeEffect::updateEffectStackMembership):
+ (WebCore::KeyframeEffect::setAnimation):
+ (WebCore::KeyframeEffect::setTarget):
+ * animation/KeyframeEffect.h:
+ * animation/KeyframeEffectStack.cpp:
+ (WebCore::KeyframeEffectStack::addEffect):
+ (WebCore::KeyframeEffectStack::ensureEffectsAreSorted):
+ * animation/KeyframeEffectStack.h:
+ * animation/WebAnimation.cpp:
+ (WebCore::WebAnimation::timingDidChange):
+ * animation/WebAnimation.h:
+ (WebCore::WebAnimation::canHaveGlobalPosition):
+
2019-11-27 James Darpinian <jdarpin...@chromium.org>
Enable GPU switching with ANGLE
Modified: trunk/Source/WebCore/animation/AnimationTimeline.cpp (252910 => 252911)
--- trunk/Source/WebCore/animation/AnimationTimeline.cpp 2019-11-27 19:20:12 UTC (rev 252910)
+++ trunk/Source/WebCore/animation/AnimationTimeline.cpp 2019-11-27 19:38:43 UTC (rev 252911)
@@ -62,8 +62,9 @@
void AnimationTimeline::animationTimingDidChange(WebAnimation& animation)
{
+ updateGlobalPosition(animation);
+
if (m_animations.add(&animation)) {
- animation.setGlobalPosition(m_allAnimations.size());
m_allAnimations.append(makeWeakPtr(&animation));
auto* timeline = animation.timeline();
if (timeline && timeline != this)
@@ -71,6 +72,13 @@
}
}
+void AnimationTimeline::updateGlobalPosition(WebAnimation& animation)
+{
+ static uint64_t s_globalPosition = 0;
+ if (!animation.globalPosition() && animation.canHaveGlobalPosition())
+ animation.setGlobalPosition(++s_globalPosition);
+}
+
void AnimationTimeline::removeAnimation(WebAnimation& animation)
{
ASSERT(!animation.timeline() || animation.timeline() == this);
@@ -156,9 +164,11 @@
if (iterator != m_elementToCSSAnimationByName.end()) {
auto& cssAnimationsByName = iterator->value;
auto& name = downcast<CSSAnimation>(animation).animationName();
- cssAnimationsByName.remove(name);
- if (cssAnimationsByName.isEmpty())
- m_elementToCSSAnimationByName.remove(&element);
+ if (cssAnimationsByName.get(name) == &animation) {
+ cssAnimationsByName.remove(name);
+ if (cssAnimationsByName.isEmpty())
+ m_elementToCSSAnimationByName.remove(&element);
+ }
}
} else if (is<CSSTransition>(animation)) {
auto& transition = downcast<CSSTransition>(animation);
@@ -252,7 +262,7 @@
if (currentStyle && currentStyle->hasAnimations() && currentStyle->display() != DisplayType::None && afterChangeStyle.display() == DisplayType::None) {
if (m_elementToCSSAnimationByName.contains(&element)) {
for (const auto& cssAnimationsByNameMapItem : m_elementToCSSAnimationByName.take(&element))
- cancelDeclarativeAnimation(*cssAnimationsByNameMapItem.value);
+ cssAnimationsByNameMapItem.value->cancelFromStyle();
}
element.ensureKeyframeEffectStack().setCSSAnimationNames(WTFMove(animationNames));
return;
@@ -281,7 +291,6 @@
for (size_t i = 0; i < currentAnimations->size(); ++i) {
auto& currentAnimation = currentAnimations->animation(i);
auto& name = currentAnimation.name();
- animationNames.append(name);
if (namesOfPreviousAnimations.contains(name)) {
// We've found the name of this animation in our list of previous animations, this means we've already
// created a CSSAnimation object for it and need to ensure that this CSSAnimation is backed by the current
@@ -288,9 +297,11 @@
// animation object for this animation name.
if (auto cssAnimation = cssAnimationsByName.get(name))
cssAnimation->setBackingAnimation(currentAnimation);
+ animationNames.append(name);
} else if (shouldConsiderAnimation(element, currentAnimation)) {
// Otherwise we are dealing with a new animation name and must create a CSSAnimation for it.
cssAnimationsByName.set(name, CSSAnimation::create(element, currentAnimation, currentStyle, afterChangeStyle));
+ animationNames.append(name);
}
// Remove the name of this animation from our list since it's now known to be current.
namesOfPreviousAnimations.remove(name);
@@ -301,7 +312,7 @@
// remove the CSSAnimation object created for them.
for (const auto& nameOfAnimationToRemove : namesOfPreviousAnimations) {
if (auto animation = cssAnimationsByName.take(nameOfAnimationToRemove))
- cancelDeclarativeAnimation(*animation);
+ animation->cancelFromStyle();
}
element.ensureKeyframeEffectStack().setCSSAnimationNames(WTFMove(animationNames));
@@ -472,15 +483,15 @@
if (CSSPropertyAnimation::propertiesEqual(property, &previouslyRunningTransitionCurrentStyle, &afterChangeStyle) || !CSSPropertyAnimation::canPropertyBeInterpolated(property, ¤tStyle, &afterChangeStyle)) {
// 1. If the current value of the property in the running transition is equal to the value of the property in the after-change style,
// or if these two values cannot be interpolated, then implementations must cancel the running transition.
- cancelDeclarativeAnimation(*previouslyRunningTransition);
+ previouslyRunningTransition->cancelFromStyle();
} else if (transitionCombinedDuration(matchingBackingAnimation) <= 0.0 || !CSSPropertyAnimation::canPropertyBeInterpolated(property, &previouslyRunningTransitionCurrentStyle, &afterChangeStyle)) {
// 2. Otherwise, if the combined duration is less than or equal to 0s, or if the current value of the property in the running transition
// cannot be interpolated with the value of the property in the after-change style, then implementations must cancel the running transition.
- cancelDeclarativeAnimation(*previouslyRunningTransition);
+ previouslyRunningTransition->cancelFromStyle();
} else if (CSSPropertyAnimation::propertiesEqual(property, &previouslyRunningTransition->reversingAdjustedStartStyle(), &afterChangeStyle)) {
// 3. Otherwise, if the reversing-adjusted start value of the running transition is the same as the value of the property in the after-change
// style (see the section on reversing of transitions for why these case exists), implementations must cancel the running transition
- cancelDeclarativeAnimation(*previouslyRunningTransition);
+ previouslyRunningTransition->cancelFromStyle();
// and start a new transition whose:
// - reversing-adjusted start value is the end value of the running transition,
@@ -506,7 +517,7 @@
ensureRunningTransitionsByProperty(element).set(property, CSSTransition::create(element, property, generationTime, *matchingBackingAnimation, &previouslyRunningTransitionCurrentStyle, afterChangeStyle, delay, duration, reversingAdjustedStartStyle, reversingShorteningFactor));
} else {
// 4. Otherwise, implementations must cancel the running transition
- cancelDeclarativeAnimation(*previouslyRunningTransition);
+ previouslyRunningTransition->cancelFromStyle();
// and start a new transition whose:
// - start time is the time of the style change event plus the matching transition delay,
@@ -530,7 +541,7 @@
if (currentStyle.hasTransitions() && currentStyle.display() != DisplayType::None && afterChangeStyle.display() == DisplayType::None) {
if (m_elementToRunningCSSTransitionByCSSPropertyID.contains(&element)) {
for (const auto& cssTransitionsByCSSPropertyIDMapItem : m_elementToRunningCSSTransitionByCSSPropertyID.take(&element))
- cancelDeclarativeAnimation(*cssTransitionsByCSSPropertyIDMapItem.value);
+ cssTransitionsByCSSPropertyIDMapItem.value->cancelFromStyle();
}
return;
}
@@ -568,11 +579,4 @@
updateCSSTransitionsForElementAndProperty(element, property, currentStyle, afterChangeStyle, runningTransitionsByProperty, completedTransitionsByProperty, generationTime);
}
-void AnimationTimeline::cancelDeclarativeAnimation(DeclarativeAnimation& animation)
-{
- animation.cancelFromStyle();
- removeAnimation(animation);
- m_allAnimations.removeFirst(&animation);
-}
-
} // namespace WebCore
Modified: trunk/Source/WebCore/animation/AnimationTimeline.h (252910 => 252911)
--- trunk/Source/WebCore/animation/AnimationTimeline.h 2019-11-27 19:20:12 UTC (rev 252910)
+++ trunk/Source/WebCore/animation/AnimationTimeline.h 2019-11-27 19:38:43 UTC (rev 252911)
@@ -82,10 +82,10 @@
HashMap<Element*, PropertyToTransitionMap> m_elementToCompletedCSSTransitionByCSSPropertyID;
private:
+ void updateGlobalPosition(WebAnimation&);
RefPtr<WebAnimation> cssAnimationForElementAndProperty(Element&, CSSPropertyID);
PropertyToTransitionMap& ensureRunningTransitionsByProperty(Element&);
void updateCSSTransitionsForElementAndProperty(Element&, CSSPropertyID, const RenderStyle& currentStyle, const RenderStyle& afterChangeStyle, PropertyToTransitionMap&, PropertyToTransitionMap&, const MonotonicTime);
- void cancelDeclarativeAnimation(DeclarativeAnimation&);
ElementToAnimationsMap m_elementToAnimationsMap;
ElementToAnimationsMap m_elementToCSSAnimationsMap;
Modified: trunk/Source/WebCore/animation/CSSAnimation.cpp (252910 => 252911)
--- trunk/Source/WebCore/animation/CSSAnimation.cpp 2019-11-27 19:20:12 UTC (rev 252910)
+++ trunk/Source/WebCore/animation/CSSAnimation.cpp 2019-11-27 19:38:43 UTC (rev 252911)
@@ -97,6 +97,7 @@
animationEffect->setDelay(Seconds(animation.delay()));
animationEffect->setIterationDuration(Seconds(animation.duration()));
animationEffect->updateStaticTimingProperties();
+ effectTimingDidChange();
// Synchronize the play state
if (animation.playState() == AnimationPlayState::Playing && playState() == WebAnimation::PlayState::Paused) {
Modified: trunk/Source/WebCore/animation/CSSTransition.cpp (252910 => 252911)
--- trunk/Source/WebCore/animation/CSSTransition.cpp 2019-11-27 19:20:12 UTC (rev 252910)
+++ trunk/Source/WebCore/animation/CSSTransition.cpp 2019-11-27 19:38:43 UTC (rev 252911)
@@ -74,6 +74,7 @@
animationEffect->setIterationDuration(duration);
animationEffect->setTimingFunction(backingAnimation().timingFunction());
animationEffect->updateStaticTimingProperties();
+ effectTimingDidChange();
unsuspendEffectInvalidation();
}
Modified: trunk/Source/WebCore/animation/DeclarativeAnimation.cpp (252910 => 252911)
--- trunk/Source/WebCore/animation/DeclarativeAnimation.cpp 2019-11-27 19:20:12 UTC (rev 252910)
+++ trunk/Source/WebCore/animation/DeclarativeAnimation.cpp 2019-11-27 19:38:43 UTC (rev 252911)
@@ -71,6 +71,17 @@
}
}
+bool DeclarativeAnimation::canHaveGlobalPosition()
+{
+ // https://drafts.csswg.org/css-animations-2/#animation-composite-order
+ // https://drafts.csswg.org/css-transitions-2/#animation-composite-order
+ // CSS Animations and CSS Transitions generated using the markup defined in this specification are not added
+ // to the global animation list when they are created. Instead, these animations are appended to the global
+ // animation list at the first moment when they transition out of the idle play state after being disassociated
+ // from their owning element.
+ return !m_owningElement && playState() != WebAnimation::PlayState::Idle;
+}
+
void DeclarativeAnimation::disassociateFromOwningElement()
{
if (!m_owningElement)
Modified: trunk/Source/WebCore/animation/DeclarativeAnimation.h (252910 => 252911)
--- trunk/Source/WebCore/animation/DeclarativeAnimation.h 2019-11-27 19:20:12 UTC (rev 252910)
+++ trunk/Source/WebCore/animation/DeclarativeAnimation.h 2019-11-27 19:38:43 UTC (rev 252911)
@@ -67,6 +67,8 @@
bool needsTick() const override;
void tick() override;
+ bool canHaveGlobalPosition() final;
+
protected:
DeclarativeAnimation(Element&, const Animation&);
Modified: trunk/Source/WebCore/animation/DocumentTimeline.cpp (252910 => 252911)
--- trunk/Source/WebCore/animation/DocumentTimeline.cpp 2019-11-27 19:20:12 UTC (rev 252910)
+++ trunk/Source/WebCore/animation/DocumentTimeline.cpp 2019-11-27 19:38:43 UTC (rev 252911)
@@ -182,6 +182,10 @@
return false;
});
+ std::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());
Modified: trunk/Source/WebCore/animation/KeyframeEffect.cpp (252910 => 252911)
--- trunk/Source/WebCore/animation/KeyframeEffect.cpp 2019-11-27 19:20:12 UTC (rev 252910)
+++ trunk/Source/WebCore/animation/KeyframeEffect.cpp 2019-11-27 19:38:43 UTC (rev 252911)
@@ -996,21 +996,43 @@
return;
if (timeline)
- m_target->ensureKeyframeEffectStack().addEffect(*this);
- else
+ m_inTargetEffectStack = m_target->ensureKeyframeEffectStack().addEffect(*this);
+ else {
m_target->ensureKeyframeEffectStack().removeEffect(*this);
+ m_inTargetEffectStack = false;
+ }
}
+void KeyframeEffect::animationTimingDidChange()
+{
+ updateEffectStackMembership();
+}
+
+void KeyframeEffect::updateEffectStackMembership()
+{
+ if (!m_target)
+ return;
+
+ bool isRelevant = animation() && animation()->isRelevant();
+ if (isRelevant && !m_inTargetEffectStack)
+ m_inTargetEffectStack = m_target->ensureKeyframeEffectStack().addEffect(*this);
+ else if (!isRelevant && m_inTargetEffectStack) {
+ m_target->ensureKeyframeEffectStack().removeEffect(*this);
+ m_inTargetEffectStack = false;
+ }
+}
+
void KeyframeEffect::setAnimation(WebAnimation* animation)
{
bool animationChanged = animation != this->animation();
AnimationEffect::setAnimation(animation);
- if (m_target && animationChanged) {
- if (animation)
- m_target->ensureKeyframeEffectStack().addEffect(*this);
- else
- m_target->ensureKeyframeEffectStack().removeEffect(*this);
- }
+
+ if (!animationChanged)
+ return;
+
+ if (animation)
+ animation->updateRelevance();
+ updateEffectStackMembership();
}
void KeyframeEffect::setTarget(RefPtr<Element>&& newTarget)
@@ -1033,10 +1055,12 @@
// any animated styles are removed immediately.
invalidateElement(previousTarget.get());
- if (previousTarget)
+ if (previousTarget) {
previousTarget->ensureKeyframeEffectStack().removeEffect(*this);
+ m_inTargetEffectStack = false;
+ }
if (m_target)
- m_target->ensureKeyframeEffectStack().addEffect(*this);
+ m_inTargetEffectStack = m_target->ensureKeyframeEffectStack().addEffect(*this);
}
void KeyframeEffect::apply(RenderStyle& targetStyle)
Modified: trunk/Source/WebCore/animation/KeyframeEffect.h (252910 => 252911)
--- trunk/Source/WebCore/animation/KeyframeEffect.h 2019-11-27 19:20:12 UTC (rev 252910)
+++ trunk/Source/WebCore/animation/KeyframeEffect.h 2019-11-27 19:38:43 UTC (rev 252911)
@@ -116,6 +116,7 @@
void animationWasCanceled() final;
void animationSuspensionStateDidChange(bool) final;
void animationTimelineDidChange(AnimationTimeline*) final;
+ void animationTimingDidChange();
void applyPendingAcceleratedActions();
bool isRunningAccelerated() const { return m_lastRecordedAcceleratedAction != AcceleratedAction::Stop; }
bool hasPendingAcceleratedAction() const { return !m_pendingAcceleratedActions.isEmpty() && isRunningAccelerated(); }
@@ -147,6 +148,7 @@
enum class AcceleratedAction : uint8_t { Play, Pause, Seek, Stop };
enum class BlendingKeyframesSource : uint8_t { CSSAnimation, CSSTransition, WebAnimation };
+ void updateEffectStackMembership();
void copyPropertiesFromSource(Ref<KeyframeEffect>&&);
ExceptionOr<void> processKeyframes(JSC::JSGlobalObject&, JSC::Strong<JSC::JSObject>&&);
void addPendingAcceleratedAction(AcceleratedAction);
@@ -188,6 +190,7 @@
bool m_backdropFilterFunctionListsMatch { false };
#endif
bool m_colorFilterFunctionListsMatch { false };
+ bool m_inTargetEffectStack { false };
};
} // namespace WebCore
Modified: trunk/Source/WebCore/animation/KeyframeEffectStack.cpp (252910 => 252911)
--- trunk/Source/WebCore/animation/KeyframeEffectStack.cpp 2019-11-27 19:20:12 UTC (rev 252910)
+++ trunk/Source/WebCore/animation/KeyframeEffectStack.cpp 2019-11-27 19:38:43 UTC (rev 252911)
@@ -42,15 +42,16 @@
ASSERT(m_effects.isEmpty());
}
-void KeyframeEffectStack::addEffect(KeyframeEffect& effect)
+bool KeyframeEffectStack::addEffect(KeyframeEffect& effect)
{
- // To qualify for membership in an effect stack, an effect must have a target, an animation and a timeline.
+ // To qualify for membership in an effect stack, an effect must have a target, an animation, a timeline and be relevant.
// This method will be called in WebAnimation and KeyframeEffect as those properties change.
- if (!effect.target() || !effect.animation() || !effect.animation()->timeline())
- return;
+ if (!effect.target() || !effect.animation() || !effect.animation()->timeline() || !effect.animation()->isRelevant())
+ return false;
m_effects.append(makeWeakPtr(&effect));
m_isSorted = false;
+ return true;
}
void KeyframeEffectStack::removeEffect(KeyframeEffect& effect)
@@ -76,9 +77,12 @@
ASSERT(lhsAnimation);
ASSERT(rhsAnimation);
+ bool lhsHasOwningElement = is<DeclarativeAnimation>(lhsAnimation) && downcast<DeclarativeAnimation>(lhsAnimation)->owningElement();
+ bool rhsHasOwningElement = is<DeclarativeAnimation>(rhsAnimation) && downcast<DeclarativeAnimation>(rhsAnimation)->owningElement();
+
// CSS Transitions sort first.
- bool lhsIsCSSTransition = is<CSSTransition>(lhsAnimation);
- bool rhsIsCSSTransition = is<CSSTransition>(rhsAnimation);
+ bool lhsIsCSSTransition = lhsHasOwningElement && is<CSSTransition>(lhsAnimation);
+ bool rhsIsCSSTransition = rhsHasOwningElement && is<CSSTransition>(rhsAnimation);
if (lhsIsCSSTransition || rhsIsCSSTransition) {
if (lhsIsCSSTransition == rhsIsCSSTransition) {
// Sort transitions first by their generation time, and then by transition-property.
@@ -93,8 +97,8 @@
}
// CSS Animations sort next.
- bool lhsIsCSSAnimation = is<CSSAnimation>(lhsAnimation);
- bool rhsIsCSSAnimation = is<CSSAnimation>(rhsAnimation);
+ bool lhsIsCSSAnimation = lhsHasOwningElement && is<CSSAnimation>(lhsAnimation);
+ bool rhsIsCSSAnimation = rhsHasOwningElement && is<CSSAnimation>(rhsAnimation);
if (lhsIsCSSAnimation || rhsIsCSSAnimation) {
if (lhsIsCSSAnimation == rhsIsCSSAnimation) {
// https://drafts.csswg.org/css-animations-2/#animation-composite-order
Modified: trunk/Source/WebCore/animation/KeyframeEffectStack.h (252910 => 252911)
--- trunk/Source/WebCore/animation/KeyframeEffectStack.h 2019-11-27 19:20:12 UTC (rev 252910)
+++ trunk/Source/WebCore/animation/KeyframeEffectStack.h 2019-11-27 19:38:43 UTC (rev 252911)
@@ -38,7 +38,7 @@
explicit KeyframeEffectStack();
~KeyframeEffectStack();
- void addEffect(KeyframeEffect&);
+ bool addEffect(KeyframeEffect&);
void removeEffect(KeyframeEffect&);
bool hasEffects() const { return !m_effects.isEmpty(); }
Vector<WeakPtr<KeyframeEffect>> sortedEffects();
Modified: trunk/Source/WebCore/animation/WebAnimation.cpp (252910 => 252911)
--- trunk/Source/WebCore/animation/WebAnimation.cpp 2019-11-27 19:20:12 UTC (rev 252910)
+++ trunk/Source/WebCore/animation/WebAnimation.cpp 2019-11-27 19:38:43 UTC (rev 252911)
@@ -721,6 +721,12 @@
{
m_shouldSkipUpdatingFinishedStateWhenResolving = false;
updateFinishedState(didSeek, synchronouslyNotify);
+
+ if (is<KeyframeEffect>(m_effect)) {
+ updateRelevance();
+ downcast<KeyframeEffect>(*m_effect).animationTimingDidChange();
+ }
+
if (m_timeline)
m_timeline->animationTimingDidChange(*this);
};
Modified: trunk/Source/WebCore/animation/WebAnimation.h (252910 => 252911)
--- trunk/Source/WebCore/animation/WebAnimation.h 2019-11-27 19:20:12 UTC (rev 252910)
+++ trunk/Source/WebCore/animation/WebAnimation.h 2019-11-27 19:38:43 UTC (rev 252911)
@@ -120,6 +120,7 @@
bool isRunningAccelerated() const;
bool isRelevant() const { return m_isRelevant; }
+ void updateRelevance();
void effectTimingDidChange();
void suspendEffectInvalidation();
void unsuspendEffectInvalidation();
@@ -129,11 +130,13 @@
virtual void remove();
void enqueueAnimationPlaybackEvent(const AtomString&, Optional<Seconds>, Optional<Seconds>);
- unsigned globalPosition() const { return m_globalPosition; }
- void setGlobalPosition(unsigned globalPosition) { m_globalPosition = globalPosition; }
+ uint64_t globalPosition() const { return m_globalPosition; }
+ void setGlobalPosition(uint64_t globalPosition) { m_globalPosition = globalPosition; }
bool hasPendingActivity() const final;
+ virtual bool canHaveGlobalPosition() { return true; }
+
// ContextDestructionObserver.
ScriptExecutionContext* scriptExecutionContext() const final { return ActiveDOMObject::scriptExecutionContext(); }
void contextDestroyed() final;
@@ -169,7 +172,6 @@
void setTimelineInternal(RefPtr<AnimationTimeline>&&);
bool isEffectInvalidationSuspended() { return m_suspendCount; }
bool computeRelevance();
- void updateRelevance();
void invalidateEffect();
double effectivePlaybackRate() const;
void applyPendingPlaybackRate();
@@ -194,7 +196,7 @@
TimeToRunPendingTask m_timeToRunPendingPlayTask { TimeToRunPendingTask::NotScheduled };
TimeToRunPendingTask m_timeToRunPendingPauseTask { TimeToRunPendingTask::NotScheduled };
ReplaceState m_replaceState { ReplaceState::Active };
- unsigned m_globalPosition;
+ uint64_t m_globalPosition { 0 };
// ActiveDOMObject.
const char* activeDOMObjectName() const final;