Diff
Modified: trunk/LayoutTests/ChangeLog (229817 => 229818)
--- trunk/LayoutTests/ChangeLog 2018-03-21 19:33:01 UTC (rev 229817)
+++ trunk/LayoutTests/ChangeLog 2018-03-21 19:41:26 UTC (rev 229818)
@@ -1,5 +1,16 @@
2018-03-21 Antoine Quint <[email protected]>
+ [Web Animations] Dispatch DOM events for CSS Transitions and CSS Animations implemented as Web Animations
+ https://bugs.webkit.org/show_bug.cgi?id=183781
+
+ Reviewed by Dean Jackson.
+
+ New attribute-based event handlers are now exposed, update the expectations for those.
+
+ * js/dom/dom-static-property-for-in-iteration-expected.txt:
+
+2018-03-21 Antoine Quint <[email protected]>
+
[Web Animations] Import CSS Animations and CSS Transitions as Web Animations tests from Mozilla
https://bugs.webkit.org/show_bug.cgi?id=183851
Modified: trunk/LayoutTests/imported/mozilla/ChangeLog (229817 => 229818)
--- trunk/LayoutTests/imported/mozilla/ChangeLog 2018-03-21 19:33:01 UTC (rev 229817)
+++ trunk/LayoutTests/imported/mozilla/ChangeLog 2018-03-21 19:41:26 UTC (rev 229818)
@@ -1,5 +1,17 @@
2018-03-21 Antoine Quint <[email protected]>
+ [Web Animations] Dispatch DOM events for CSS Transitions and CSS Animations implemented as Web Animations
+ https://bugs.webkit.org/show_bug.cgi?id=183781
+
+ Reviewed by Dean Jackson.
+
+ Some of the Mozilla tests no longer time out and partially pass, marking the progression.
+
+ * css-animations/test_animation-starttime-expected.txt:
+ * css-animations/test_element-get-animations-expected.txt:
+
+2018-03-21 Antoine Quint <[email protected]>
+
[Web Animations] Import CSS Animations and CSS Transitions as Web Animations tests from Mozilla
https://bugs.webkit.org/show_bug.cgi?id=183851
Modified: trunk/LayoutTests/imported/mozilla/css-animations/test_animation-starttime-expected.txt (229817 => 229818)
--- trunk/LayoutTests/imported/mozilla/css-animations/test_animation-starttime-expected.txt 2018-03-21 19:33:01 UTC (rev 229817)
+++ trunk/LayoutTests/imported/mozilla/css-animations/test_animation-starttime-expected.txt 2018-03-21 19:41:26 UTC (rev 229818)
@@ -1,3 +1,22 @@
-#PID UNRESPONSIVE - com.apple.WebKit.WebContent.Development (pid 13542)
-FAIL: Timed out waiting for notifyDone to be called
+PASS startTime of a newly created (play-pending) animation is unresolved
+FAIL startTime of a newly created (pause-pending) animation is unresolved undefined is not an object (evaluating 'animation.startTime')
+PASS startTime is resolved when running
+FAIL startTime is unresolved when paused undefined is not an object (evaluating 'animation.ready')
+PASS startTime while pause-pending and play-pending
+PASS startTime while play-pending from finished state
+PASS startTime while play-pending from finished state using finish()
+FAIL Pausing should make the startTime become null assert_true: After the animation has started, startTime is greater than the time when it was started expected true got false
+PASS Sanity test to check round-tripping assigning to a new animation's startTime
+PASS Skipping forward through animation
+PASS Skipping backwards through animation
+PASS Redundant change, before -> active, then back
+PASS Redundant change, before -> after, then back
+PASS Redundant change, active -> before, then back
+PASS Redundant change, active -> after, then back
+PASS Redundant change, after -> before, then back
+PASS Redundant change, after -> active, then back
+PASS Setting startTime to null
+FAIL Animation.startTime after pausing assert_equals: Animation.playState is "paused" after pause() call expected "paused" but got "running"
+PASS Animation.startTime after cancelling
+
Modified: trunk/LayoutTests/imported/mozilla/css-animations/test_element-get-animations-expected.txt (229817 => 229818)
--- trunk/LayoutTests/imported/mozilla/css-animations/test_element-get-animations-expected.txt 2018-03-21 19:33:01 UTC (rev 229817)
+++ trunk/LayoutTests/imported/mozilla/css-animations/test_element-get-animations-expected.txt 2018-03-21 19:41:26 UTC (rev 229818)
@@ -1,3 +1,24 @@
-#PID UNRESPONSIVE - com.apple.WebKit.WebContent.Development (pid 13551)
-FAIL: Timed out waiting for notifyDone to be called
+PASS getAnimations for non-animated content
+PASS getAnimations for CSS Animations
+PASS getAnimations returns CSSAnimation objects for CSS Animations
+PASS getAnimations for multi-property animations
+FAIL getAnimations for both CSS Animations and CSS Transitions at once assert_equals: getAnimations returns Animations for both animations and transitions that run simultaneously expected 2 but got 1
+PASS getAnimations for CSS Animations that have finished
+PASS getAnimations for CSS Animations that have finished but are forwards filling
+FAIL getAnimations for CSS Animations with animation-name: none assert_equals: getAnimations returns an empty sequence for an element with animation-name: none expected 0 but got 1
+FAIL getAnimations for CSS Animations with animation-name: missing assert_equals: getAnimations returns an empty sequence for an element with animation-name: missing expected 0 but got 1
+FAIL getAnimations for CSS Animations where the @keyframes rule is added later assert_equals: getAnimations initally only returns Animations for CSS Animations whose animation-name is found expected 1 but got 2
+PASS getAnimations for CSS Animations with duplicated animation-name
+PASS getAnimations for CSS Animations with empty keyframes rule
+PASS getAnimations for CSS animations in delay phase
+PASS getAnimations for zero-duration CSS Animations
+PASS getAnimations returns objects with the same identity
+PASS getAnimations for CSS Animations that are cancelled
+FAIL getAnimations for CSS Animations follows animation-name order assert_equals: animation order after prepending to list expected "anim1" but got "anim2"
+PASS Test AnimationFilter{ subtree: false } with single element
+FAIL Test AnimationFilter{ subtree: true } with single element assert_equals: getAnimations({ subtree: true }) should return animations on pseudo-elements expected 3 but got 1
+PASS Test AnimationFilter{ subtree: false } with element that has a child
+FAIL Test AnimationFilter{ subtree: true } with element that has a child assert_equals: Should find all elements, pesudo-elements that parent has expected 6 but got 1
+FAIL Test AnimationFilter{ subtree: true } with element that has many descendant assert_equals: Should find all descendants of the element expected 5 but got 1
+
Modified: trunk/LayoutTests/js/dom/dom-static-property-for-in-iteration-expected.txt (229817 => 229818)
--- trunk/LayoutTests/js/dom/dom-static-property-for-in-iteration-expected.txt 2018-03-21 19:33:01 UTC (rev 229817)
+++ trunk/LayoutTests/js/dom/dom-static-property-for-in-iteration-expected.txt 2018-03-21 19:41:26 UTC (rev 229818)
@@ -111,9 +111,13 @@
PASS a["onvolumechange"] is null
PASS a["onwaiting"] is null
PASS a["ontransitionend"] is null
+PASS a["ontransitionrun"] is null
+PASS a["ontransitionstart"] is null
+PASS a["ontransitioncancel"] is null
PASS a["onanimationend"] is null
PASS a["onanimationiteration"] is null
PASS a["onanimationstart"] is null
+PASS a["onanimationcancel"] is null
PASS a["namespaceURI"] is http://www.w3.org/1999/xhtml
PASS a["prefix"] is null
PASS a["localName"] is a
Modified: trunk/Source/WebCore/ChangeLog (229817 => 229818)
--- trunk/Source/WebCore/ChangeLog 2018-03-21 19:33:01 UTC (rev 229817)
+++ trunk/Source/WebCore/ChangeLog 2018-03-21 19:41:26 UTC (rev 229818)
@@ -1,3 +1,47 @@
+2018-03-21 Antoine Quint <[email protected]>
+
+ [Web Animations] Dispatch DOM events for CSS Transitions and CSS Animations implemented as Web Animations
+ https://bugs.webkit.org/show_bug.cgi?id=183781
+
+ Reviewed by Dean Jackson.
+
+ Now that we've implemented CSS Animations and CSS Transitions as Web Animations (webkit.org/b/183504) we can dispatch DOM events
+ for targets of DeclarativeAnimation objects. To do that, we add a new invalidateDOMEvents() method on DeclarativeAnimations which
+ is called when the timer scheduled after the timing model has been invalidated fires in DocumentTimeline::performInvalidationTask().
+ When we check for DOM events to dispatch, we look at the last recorded phase and iteration and determine whether the state of the
+ animation has changed. We use a GenericEventQueue to enqueue the events such that they are dispatched asynchronously at a moment
+ when it is safe to evaluate script.
+
+ * animation/AnimationEffectReadOnly.h: Make currentIteration() public since we now need it in DeclarativeAnimation::invalidateDOMEvents().
+ * animation/CSSAnimation.cpp:
+ (WebCore::CSSAnimation::create): Pass the animation target to the constructor instead of its document.
+ (WebCore::CSSAnimation::CSSAnimation): Pass the animation target to the superclass instead of its document.
+ * animation/CSSAnimation.h:
+ * animation/CSSTransition.cpp:
+ (WebCore::CSSTransition::create): Pass the animation target to the constructor instead of its document.
+ (WebCore::CSSTransition::CSSTransition): Pass the animation target to the superclass instead of its document.
+ * animation/CSSTransition.h:
+ * animation/DeclarativeAnimation.cpp:
+ (WebCore::DeclarativeAnimation::DeclarativeAnimation): Expect an Element instead of a Document and use that element as the target of the
+ GenericEventQueue that we initialize. We also register this element as our m_target.
+ (WebCore::DeclarativeAnimation::~DeclarativeAnimation): Close the GenericEventQueue member upon destruction.
+ (WebCore::DeclarativeAnimation::initialize): We need to call pause() for declarative animations that aren't playing so that the animation's
+ playState is set correctly and the animation is not idle.
+ (WebCore::DeclarativeAnimation::phaseWithoutEffect const): Because we may need to get an animation's current phase in invalidateDOMEvents()
+ after an animation's effect has been removed, we provide an alternate way to compute the phase just by looking at the animation's current time.
+ (WebCore::DeclarativeAnimation::invalidateDOMEvents): Based on the previous and current pending state, iteration and phase, we enqueue animation
+ and transition DOM events as specified by the CSS Animations Level 2 and CSS Transitions Level 2 specifications.
+ (WebCore::DeclarativeAnimation::enqueueDOMEvent): Enqueue an event on the GenericEventQueue based on the animation type.
+ * animation/DeclarativeAnimation.h:
+ * animation/DocumentTimeline.cpp:
+ (WebCore::DocumentTimeline::performInvalidationTask): We call invalidateDOMEvents() on all declarative animations registered with this timeline
+ now that the timing model has been invalidated.
+ * dom/EventNames.h: Add the names of newly-implemented events (animationcancel, transitioncancel, transitionrun and transitionstart).
+ * dom/GlobalEventHandlers.idl: Add new attribute-based event handlers for the newly-implemented events.
+ * html/HTMLAttributeNames.in: Add new attribute-based event handlers for the newly-implemented events.
+ * html/HTMLElement.cpp:
+ (WebCore::HTMLElement::createEventHandlerNameMap): Add new attribute-based event handlers for the newly-implemented events.
+
2018-03-21 Per Arne Vollan <[email protected]>
Compile error when not using IOSurface canvas backing store.
Modified: trunk/Source/WebCore/animation/AnimationEffectReadOnly.h (229817 => 229818)
--- trunk/Source/WebCore/animation/AnimationEffectReadOnly.h 2018-03-21 19:33:01 UTC (rev 229817)
+++ trunk/Source/WebCore/animation/AnimationEffectReadOnly.h 2018-03-21 19:41:26 UTC (rev 229818)
@@ -53,6 +53,7 @@
std::optional<Seconds> localTime() const;
std::optional<Seconds> activeTime() const;
std::optional<double> iterationProgress() const;
+ std::optional<double> currentIteration() const;
enum class Phase { Before, Active, After, Idle };
Phase phase() const;
@@ -76,7 +77,6 @@
std::optional<double> overallProgress() const;
std::optional<double> simpleIterationProgress() const;
- std::optional<double> currentIteration() const;
AnimationEffectReadOnly::ComputedDirection currentDirection() const;
std::optional<double> directedProgress() const;
std::optional<double> transformedProgress() const;
Modified: trunk/Source/WebCore/animation/CSSAnimation.cpp (229817 => 229818)
--- trunk/Source/WebCore/animation/CSSAnimation.cpp 2018-03-21 19:33:01 UTC (rev 229817)
+++ trunk/Source/WebCore/animation/CSSAnimation.cpp 2018-03-21 19:41:26 UTC (rev 229818)
@@ -33,14 +33,14 @@
Ref<CSSAnimation> CSSAnimation::create(Element& target, const Animation& backingAnimation)
{
- auto result = adoptRef(*new CSSAnimation(target.document(), backingAnimation));
+ auto result = adoptRef(*new CSSAnimation(target, backingAnimation));
result->m_animationName = backingAnimation.name();
result->initialize(target);
return result;
}
-CSSAnimation::CSSAnimation(Document& document, const Animation& backingAnimation)
- : DeclarativeAnimation(document, backingAnimation)
+CSSAnimation::CSSAnimation(Element& element, const Animation& backingAnimation)
+ : DeclarativeAnimation(element, backingAnimation)
{
}
Modified: trunk/Source/WebCore/animation/CSSAnimation.h (229817 => 229818)
--- trunk/Source/WebCore/animation/CSSAnimation.h 2018-03-21 19:33:01 UTC (rev 229817)
+++ trunk/Source/WebCore/animation/CSSAnimation.h 2018-03-21 19:41:26 UTC (rev 229818)
@@ -46,7 +46,7 @@
void syncPropertiesWithBackingAnimation() final;
private:
- CSSAnimation(Document&, const Animation&);
+ CSSAnimation(Element&, const Animation&);
String m_animationName;
Modified: trunk/Source/WebCore/animation/CSSTransition.cpp (229817 => 229818)
--- trunk/Source/WebCore/animation/CSSTransition.cpp 2018-03-21 19:33:01 UTC (rev 229817)
+++ trunk/Source/WebCore/animation/CSSTransition.cpp 2018-03-21 19:41:26 UTC (rev 229818)
@@ -34,7 +34,7 @@
Ref<CSSTransition> CSSTransition::create(Element& target, const Animation& backingAnimation, const RenderStyle* oldStyle, const RenderStyle& newStyle)
{
- auto result = adoptRef(*new CSSTransition(target.document(), backingAnimation));
+ auto result = adoptRef(*new CSSTransition(target, backingAnimation));
result->m_transitionProperty = backingAnimation.property();
result->initialize(target);
downcast<KeyframeEffectReadOnly>(result->effect())->computeCSSTransitionBlendingKeyframes(oldStyle, newStyle);
@@ -41,8 +41,8 @@
return result;
}
-CSSTransition::CSSTransition(Document& document, const Animation& backingAnimation)
- : DeclarativeAnimation(document, backingAnimation)
+CSSTransition::CSSTransition(Element& element, const Animation& backingAnimation)
+ : DeclarativeAnimation(element, backingAnimation)
{
}
Modified: trunk/Source/WebCore/animation/CSSTransition.h (229817 => 229818)
--- trunk/Source/WebCore/animation/CSSTransition.h 2018-03-21 19:33:01 UTC (rev 229817)
+++ trunk/Source/WebCore/animation/CSSTransition.h 2018-03-21 19:41:26 UTC (rev 229818)
@@ -47,7 +47,7 @@
bool canBeListed() const final;
private:
- CSSTransition(Document&, const Animation&);
+ CSSTransition(Element&, const Animation&);
CSSPropertyID m_transitionProperty;
Modified: trunk/Source/WebCore/animation/DeclarativeAnimation.cpp (229817 => 229818)
--- trunk/Source/WebCore/animation/DeclarativeAnimation.cpp 2018-03-21 19:33:01 UTC (rev 229817)
+++ trunk/Source/WebCore/animation/DeclarativeAnimation.cpp 2018-03-21 19:41:26 UTC (rev 229818)
@@ -28,17 +28,28 @@
#include "Animation.h"
#include "AnimationEffectTimingReadOnly.h"
+#include "AnimationEvent.h"
#include "Element.h"
+#include "EventNames.h"
#include "KeyframeEffectReadOnly.h"
+#include "PseudoElement.h"
+#include "TransitionEvent.h"
namespace WebCore {
-DeclarativeAnimation::DeclarativeAnimation(Document& document, const Animation& backingAnimation)
- : WebAnimation(document)
+DeclarativeAnimation::DeclarativeAnimation(Element& target, const Animation& backingAnimation)
+ : WebAnimation(target.document())
+ , m_target(target)
, m_backingAnimation(const_cast<Animation&>(backingAnimation))
+ , m_eventQueue(target)
{
}
+DeclarativeAnimation::~DeclarativeAnimation()
+{
+ m_eventQueue.close();
+}
+
void DeclarativeAnimation::setBackingAnimation(const Animation& backingAnimation)
{
m_backingAnimation = const_cast<Animation&>(backingAnimation);
@@ -73,4 +84,106 @@
unsuspendEffectInvalidation();
}
+AnimationEffectReadOnly::Phase DeclarativeAnimation::phaseWithoutEffect() const
+{
+ // This shouldn't be called if we actually have an effect.
+ ASSERT(!effect());
+
+ auto animationCurrentTime = currentTime();
+ if (!animationCurrentTime)
+ return AnimationEffectReadOnly::Phase::Idle;
+
+ // Since we don't have an effect, the duration will be zero so the phase is 'before' if the current time is less than zero.
+ return animationCurrentTime.value() < 0_s ? AnimationEffectReadOnly::Phase::Before : AnimationEffectReadOnly::Phase::After;
+}
+
+void DeclarativeAnimation::invalidateDOMEvents()
+{
+ auto* animationEffect = effect();
+
+ auto isPending = pending();
+ auto iteration = animationEffect ? animationEffect->currentIteration().value() : 0;
+ auto currentPhase = animationEffect ? animationEffect->phase() : phaseWithoutEffect();
+
+ bool wasActive = m_previousPhase == AnimationEffectReadOnly::Phase::Active;
+ bool wasAfter = m_previousPhase == AnimationEffectReadOnly::Phase::After;
+ bool wasBefore = m_previousPhase == AnimationEffectReadOnly::Phase::Before;
+ bool wasIdle = m_previousPhase == AnimationEffectReadOnly::Phase::Idle;
+
+ bool isActive = currentPhase == AnimationEffectReadOnly::Phase::Active;
+ bool isAfter = currentPhase == AnimationEffectReadOnly::Phase::After;
+ bool isBefore = currentPhase == AnimationEffectReadOnly::Phase::Before;
+ bool isIdle = currentPhase == AnimationEffectReadOnly::Phase::Idle;
+
+ auto* effectTiming = animationEffect ? animationEffect->timing() : nullptr;
+ auto intervalStart = effectTiming ? std::max(0_s, std::min(-effectTiming->delay(), effectTiming->activeDuration())) : 0_s;
+ auto intervalEnd = effectTiming ? std::max(0_s, std::min(effectTiming->endTime() - effectTiming->delay(), effectTiming->activeDuration())) : 0_s;
+
+ if (is<CSSAnimation>(this)) {
+ // https://drafts.csswg.org/css-animations-2/#events
+ if ((wasIdle || wasBefore) && isActive)
+ enqueueDOMEvent(eventNames().animationstartEvent, intervalStart);
+ else if ((wasIdle || wasBefore) && isAfter) {
+ enqueueDOMEvent(eventNames().animationstartEvent, intervalStart);
+ enqueueDOMEvent(eventNames().animationendEvent, intervalEnd);
+ } else if (wasActive && isBefore)
+ enqueueDOMEvent(eventNames().animationendEvent, intervalStart);
+ else if (wasActive && isActive && m_previousIteration != iteration) {
+ auto iterationBoundary = iteration;
+ if (m_previousIteration > iteration)
+ iterationBoundary++;
+ auto elapsedTime = effectTiming ? effectTiming->iterationDuration() * (iterationBoundary - effectTiming->iterationStart()) : 0_s;
+ enqueueDOMEvent(eventNames().animationiterationEvent, elapsedTime);
+ } else if (wasActive && isAfter)
+ enqueueDOMEvent(eventNames().animationendEvent, intervalEnd);
+ else if (wasAfter && isActive)
+ enqueueDOMEvent(eventNames().animationstartEvent, intervalEnd);
+ else if (wasAfter && isBefore) {
+ enqueueDOMEvent(eventNames().animationstartEvent, intervalEnd);
+ enqueueDOMEvent(eventNames().animationendEvent, intervalStart);
+ } else if ((!wasIdle && !wasAfter) && isIdle)
+ enqueueDOMEvent(eventNames().animationcancelEvent, 0_s);
+ } else if (is<CSSTransition>(this)) {
+ // https://drafts.csswg.org/css-transitions-2/#transition-events
+ if (wasIdle && (isPending || isBefore))
+ enqueueDOMEvent(eventNames().transitionrunEvent, intervalStart);
+ else if (wasIdle && isActive) {
+ enqueueDOMEvent(eventNames().transitionrunEvent, intervalStart);
+ enqueueDOMEvent(eventNames().transitionstartEvent, intervalStart);
+ } else if (wasIdle && isAfter) {
+ enqueueDOMEvent(eventNames().transitionrunEvent, intervalStart);
+ enqueueDOMEvent(eventNames().transitionstartEvent, intervalStart);
+ enqueueDOMEvent(eventNames().transitionendEvent, intervalEnd);
+ } else if ((m_wasPending || wasBefore) && isActive)
+ enqueueDOMEvent(eventNames().transitionstartEvent, intervalStart);
+ else if ((m_wasPending || wasBefore) && isAfter) {
+ enqueueDOMEvent(eventNames().transitionstartEvent, intervalStart);
+ enqueueDOMEvent(eventNames().transitionendEvent, intervalEnd);
+ } else if (wasActive && isAfter)
+ enqueueDOMEvent(eventNames().transitionendEvent, intervalEnd);
+ else if (wasActive && isBefore)
+ enqueueDOMEvent(eventNames().transitionendEvent, intervalStart);
+ else if (wasAfter && isActive)
+ enqueueDOMEvent(eventNames().transitionstartEvent, intervalEnd);
+ else if (wasAfter && isBefore) {
+ enqueueDOMEvent(eventNames().transitionstartEvent, intervalEnd);
+ enqueueDOMEvent(eventNames().transitionendEvent, intervalStart);
+ } else if ((!wasIdle && !wasAfter) && isIdle)
+ enqueueDOMEvent(eventNames().transitioncancelEvent, 0_s);
+ }
+
+ m_wasPending = isPending;
+ m_previousPhase = currentPhase;
+ m_previousIteration = iteration;
+}
+
+void DeclarativeAnimation::enqueueDOMEvent(const AtomicString& eventType, Seconds elapsedTime)
+{
+ auto time = secondsToWebAnimationsAPITime(elapsedTime) / 1000;
+ if (is<CSSAnimation>(this))
+ m_eventQueue.enqueueEvent(AnimationEvent::create(eventType, downcast<CSSAnimation>(this)->animationName(), time));
+ else if (is<CSSTransition>(this))
+ m_eventQueue.enqueueEvent(TransitionEvent::create(eventType, downcast<CSSTransition>(this)->transitionProperty(), time, PseudoElement::pseudoElementNameForEvents(m_target.pseudoId())));
+}
+
} // namespace WebCore
Modified: trunk/Source/WebCore/animation/DeclarativeAnimation.h (229817 => 229818)
--- trunk/Source/WebCore/animation/DeclarativeAnimation.h 2018-03-21 19:33:01 UTC (rev 229817)
+++ trunk/Source/WebCore/animation/DeclarativeAnimation.h 2018-03-21 19:41:26 UTC (rev 229818)
@@ -25,6 +25,8 @@
#pragma once
+#include "AnimationEffectReadOnly.h"
+#include "GenericEventQueue.h"
#include "WebAnimation.h"
#include <wtf/Ref.h>
@@ -35,22 +37,30 @@
class DeclarativeAnimation : public WebAnimation {
public:
- ~DeclarativeAnimation() = default;
+ ~DeclarativeAnimation();
bool isDeclarativeAnimation() const final { return true; }
const Animation& backingAnimation() const { return m_backingAnimation; }
void setBackingAnimation(const Animation&);
+ void invalidateDOMEvents();
protected:
- DeclarativeAnimation(Document&, const Animation&);
+ DeclarativeAnimation(Element&, const Animation&);
virtual void initialize(const Element&);
virtual void syncPropertiesWithBackingAnimation();
private:
+ AnimationEffectReadOnly::Phase phaseWithoutEffect() const;
+ void enqueueDOMEvent(const AtomicString&, Seconds);
+
+ Element& m_target;
Ref<Animation> m_backingAnimation;
-
+ bool m_wasPending { false };
+ AnimationEffectReadOnly::Phase m_previousPhase { AnimationEffectReadOnly::Phase::Idle };
+ double m_previousIteration;
+ GenericEventQueue m_eventQueue;
};
} // namespace WebCore
Modified: trunk/Source/WebCore/animation/DocumentTimeline.cpp (229817 => 229818)
--- trunk/Source/WebCore/animation/DocumentTimeline.cpp 2018-03-21 19:33:01 UTC (rev 229817)
+++ trunk/Source/WebCore/animation/DocumentTimeline.cpp 2018-03-21 19:41:26 UTC (rev 229818)
@@ -30,6 +30,7 @@
#include "Chrome.h"
#include "ChromeClient.h"
#include "DOMWindow.h"
+#include "DeclarativeAnimation.h"
#include "DisplayRefreshMonitor.h"
#include "DisplayRefreshMonitorManager.h"
#include "Document.h"
@@ -109,6 +110,12 @@
void DocumentTimeline::performInvalidationTask()
{
+ // Now that the timing model has changed we can see if there are DOM events to dispatch for declarative animations.
+ for (auto& animation : animations()) {
+ if (is<DeclarativeAnimation>(animation))
+ downcast<DeclarativeAnimation>(*animation).invalidateDOMEvents();
+ }
+
updateAnimationSchedule();
m_cachedCurrentTime = std::nullopt;
}
Modified: trunk/Source/WebCore/dom/EventNames.h (229817 => 229818)
--- trunk/Source/WebCore/dom/EventNames.h 2018-03-21 19:33:01 UTC (rev 229817)
+++ trunk/Source/WebCore/dom/EventNames.h 2018-03-21 19:41:26 UTC (rev 229818)
@@ -59,6 +59,7 @@
macro(addsourcebuffer) \
macro(addstream) \
macro(addtrack) \
+ macro(animationcancel) \
macro(animationend) \
macro(animationiteration) \
macro(animationstart) \
@@ -249,7 +250,10 @@
macro(touchmove) \
macro(touchstart) \
macro(track) \
+ macro(transitioncancel) \
macro(transitionend) \
+ macro(transitionrun) \
+ macro(transitionstart) \
macro(unhandledrejection) \
macro(unload) \
macro(unmute) \
Modified: trunk/Source/WebCore/dom/GlobalEventHandlers.idl (229817 => 229818)
--- trunk/Source/WebCore/dom/GlobalEventHandlers.idl 2018-03-21 19:33:01 UTC (rev 229817)
+++ trunk/Source/WebCore/dom/GlobalEventHandlers.idl 2018-03-21 19:41:26 UTC (rev 229818)
@@ -97,15 +97,15 @@
// Extensions from CSS Transitions API (https://drafts.csswg.org/css-transitions/#interface-globaleventhandlers-idl).
attribute EventHandler ontransitionend;
- // attribute EventHandler ontransitionrun;
- // attribute EventHandler ontransitionstart;
- // attribute EventHandler ontransitioncancel;
+ attribute EventHandler ontransitionrun;
+ attribute EventHandler ontransitionstart;
+ attribute EventHandler ontransitioncancel;
// Event handlers from CSS Animations API (https://drafts.csswg.org/css-animations/#interface-globaleventhandlers-idl).
attribute EventHandler onanimationend;
attribute EventHandler onanimationiteration;
attribute EventHandler onanimationstart;
- // attribute EventHandler onanimationcancel;
+ attribute EventHandler onanimationcancel;
// Additions that are not yet part of the standard.
Modified: trunk/Source/WebCore/html/HTMLAttributeNames.in (229817 => 229818)
--- trunk/Source/WebCore/html/HTMLAttributeNames.in 2018-03-21 19:33:01 UTC (rev 229817)
+++ trunk/Source/WebCore/html/HTMLAttributeNames.in 2018-03-21 19:41:26 UTC (rev 229818)
@@ -193,6 +193,7 @@
onanimationstart
onanimationiteration
onanimationend
+onanimationcancel
onautocomplete
onautocompleteerror
onbeforecopy
@@ -282,7 +283,10 @@
ontouchmove
ontouchend
ontouchcancel
+ontransitioncancel
ontransitionend
+ontransitionrun
+ontransitionstart
onunload
onvolumechange
onwaiting
Modified: trunk/Source/WebCore/html/HTMLElement.cpp (229817 => 229818)
--- trunk/Source/WebCore/html/HTMLElement.cpp 2018-03-21 19:33:01 UTC (rev 229817)
+++ trunk/Source/WebCore/html/HTMLElement.cpp 2018-03-21 19:41:26 UTC (rev 229818)
@@ -229,6 +229,7 @@
&onanimationendAttr.get(),
&onanimationiterationAttr.get(),
&onanimationstartAttr.get(),
+ &onanimationcancelAttr.get(),
&onautocompleteAttr.get(),
&onautocompleteerrorAttr.get(),
&onbeforecopyAttr.get(),
@@ -303,7 +304,10 @@
&ontouchforcechangeAttr.get(),
&ontouchmoveAttr.get(),
&ontouchstartAttr.get(),
+ &ontransitioncancelAttr.get(),
&ontransitionendAttr.get(),
+ &ontransitionrunAttr.get(),
+ &ontransitionstartAttr.get(),
&onvolumechangeAttr.get(),
&onwaitingAttr.get(),
&onwebkitbeginfullscreenAttr.get(),