Title: [139762] trunk
Revision
139762
Author
[email protected]
Date
2013-01-15 11:17:42 -0800 (Tue, 15 Jan 2013)

Log Message

Unprefixed transitionend event doesn't seem to be implemented, which breaks many sites
https://bugs.webkit.org/show_bug.cgi?id=105647

Reviewed by Julien Chaffraix.

Source/WebCore:

Add support for transitionend event delivery as part as the unprefixing
work on CSS Transitions. This patch adds some code in EventTarget to
figure out if the current event to dispatch has a prefixed version or
not. Then from the list of listeners we deduce which event should be delivered
(prefixed or unprefixed).

In the case of the CSS Transitions, WebKit will now behave as follow :
if an event listener is attached to the prefixed version of the
transition end event then only the prefixed event will be send.
If an event listener is attached to the unprefixed version
of the transition end event then only the unprefixed event will be
send. If there are event listeners on both unprefixed and prefixed
events then only the unprefixed event will be send.

The behavior was discussed here :
http://lists.webkit.org/pipermail/webkit-dev/2013-January/023301.html.

Tests: transitions/transition-end-event-unprefixed-01.html
       transitions/transition-end-event-unprefixed-02.html

* dom/Document.cpp:
(WebCore::Document::addListenerTypeIfNeeded): Register the prefixed
listener too as transitionend listeners so that we properly dispatch
events for them.
* dom/EventNames.h:
(WebCore): Add the new transitionend name.
* dom/EventTarget.cpp:
(WebCore::createMatchingPrefixedEvent):
(WebCore::prefixedType):
(WebCore::EventTarget::fireEventListeners): Find out if somebody is
listening for unprefixed events, if so we always send the unprefixed
event, if not then we create a prefixed event and send it.
* page/animation/AnimationController.cpp:
(WebCore::AnimationControllerPrivate::fireEventsAndUpdateStyle):
* page/animation/ImplicitAnimation.cpp:
(WebCore::ImplicitAnimation::sendTransitionEvent): Always create by
default unprefixed events.

LayoutTests:

Cover that event delivery is correct : we received unprefixed events.

* transitions/transition-end-event-helpers.js:
(recordTransitionEndEvent):
* transitions/transition-end-event-unprefixed-01-expected.txt: Added.
* transitions/transition-end-event-unprefixed-01.html: Added.
* transitions/transition-end-event-unprefixed-02-expected.txt: Added.
* transitions/transition-end-event-unprefixed-02.html: Added.

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (139761 => 139762)


--- trunk/LayoutTests/ChangeLog	2013-01-15 19:17:09 UTC (rev 139761)
+++ trunk/LayoutTests/ChangeLog	2013-01-15 19:17:42 UTC (rev 139762)
@@ -1,3 +1,19 @@
+2013-01-15  Alexis Menard  <[email protected]>
+
+        Unprefixed transitionend event doesn't seem to be implemented, which breaks many sites
+        https://bugs.webkit.org/show_bug.cgi?id=105647
+
+        Reviewed by Julien Chaffraix.
+
+        Cover that event delivery is correct : we received unprefixed events.
+
+        * transitions/transition-end-event-helpers.js:
+        (recordTransitionEndEvent):
+        * transitions/transition-end-event-unprefixed-01-expected.txt: Added.
+        * transitions/transition-end-event-unprefixed-01.html: Added.
+        * transitions/transition-end-event-unprefixed-02-expected.txt: Added.
+        * transitions/transition-end-event-unprefixed-02.html: Added.
+
 2013-01-15  Zan Dobersek  <[email protected]>
 
         Unreviewed GTK gardening.

Modified: trunk/LayoutTests/transitions/transition-end-event-helpers.js (139761 => 139762)


--- trunk/LayoutTests/transitions/transition-end-event-helpers.js	2013-01-15 19:17:09 UTC (rev 139761)
+++ trunk/LayoutTests/transitions/transition-end-event-helpers.js	2013-01-15 19:17:42 UTC (rev 139762)
@@ -10,12 +10,12 @@
 /* Call this function to record manually transition end events:
 
 Function parameters:
-    event [required]: the event passed with "webkitTransitionEnd"
+    event [required]: the event passed with "webkitTransitionEnd" or "transitionend"
 
 */
 function recordTransitionEndEvent(event)
 {
-  if (event.type != "webkitTransitionEnd")
+  if (event.type != "webkitTransitionEnd" && event.type != "transitionend" )
     throw("Invalid transition end event!");
 
   _recordedEvents.push([

Added: trunk/LayoutTests/transitions/transition-end-event-unprefixed-01-expected.txt (0 => 139762)


--- trunk/LayoutTests/transitions/transition-end-event-unprefixed-01-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/transitions/transition-end-event-unprefixed-01-expected.txt	2013-01-15 19:17:42 UTC (rev 139762)
@@ -0,0 +1,4 @@
+Initiating a transition and catching the transition unprefixed event.
+
+PASS --- [Expected] Property: left Target: box1 Elapsed Time: 0.5
+

Added: trunk/LayoutTests/transitions/transition-end-event-unprefixed-01.html (0 => 139762)


--- trunk/LayoutTests/transitions/transition-end-event-unprefixed-01.html	                        (rev 0)
+++ trunk/LayoutTests/transitions/transition-end-event-unprefixed-01.html	2013-01-15 19:17:42 UTC (rev 139762)
@@ -0,0 +1,47 @@
+<!DOCTYPE html>
+<html>
+<head>
+  <style>
+    .box {
+      position: relative;
+      left: 0;
+      height: 100px;
+      width: 100px;
+      margin: 10px;
+      background-color: blue;
+      transition-property: left;
+      transition-duration: 0.5s;
+      -webkit-transition-property: left;
+      -webkit-transition-duration: 0.5s;
+    }
+  </style>
+  <script src=""
+  <script type="text/_javascript_">
+
+    var expectedEndEvents = [
+      // [property-name, element-id, elapsed-time, listen]
+      ["left", "box1", 0.5, false]
+    ];
+
+    function setupTest()
+    {
+      var box = document.getElementById('box1');
+      document.addEventListener('transitionend', recordTransitionEndEvent, false);
+      box.style.left = '200px';
+    }
+
+    runTransitionTest(expectedEndEvents, setupTest);
+  </script>
+</head>
+<body>
+
+<p>Initiating a transition and catching the transition unprefixed event.</p>
+
+<div id="container">
+  <div id="box1" class="box"></div>
+</div>
+
+<div id="result"></div>
+
+</body>
+</html>
\ No newline at end of file

Added: trunk/LayoutTests/transitions/transition-end-event-unprefixed-02-expected.txt (0 => 139762)


--- trunk/LayoutTests/transitions/transition-end-event-unprefixed-02-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/transitions/transition-end-event-unprefixed-02-expected.txt	2013-01-15 19:17:42 UTC (rev 139762)
@@ -0,0 +1,4 @@
+Initiating a transition catching one transition event only despite listening the prefixed and unprefixed event.
+
+PASS --- [Expected] Property: left Target: box1 Elapsed Time: 0.5
+

Added: trunk/LayoutTests/transitions/transition-end-event-unprefixed-02.html (0 => 139762)


--- trunk/LayoutTests/transitions/transition-end-event-unprefixed-02.html	                        (rev 0)
+++ trunk/LayoutTests/transitions/transition-end-event-unprefixed-02.html	2013-01-15 19:17:42 UTC (rev 139762)
@@ -0,0 +1,48 @@
+<!DOCTYPE html>
+<html>
+<head>
+  <style>
+    .box {
+      position: relative;
+      left: 0;
+      height: 100px;
+      width: 100px;
+      margin: 10px;
+      background-color: blue;
+      transition-property: left;
+      transition-duration: 0.5s;
+      -webkit-transition-property: left;
+      -webkit-transition-duration: 0.5s;
+    }
+  </style>
+  <script src=""
+  <script type="text/_javascript_">
+
+    var expectedEndEvents = [
+      // [property-name, element-id, elapsed-time, listen]
+      ["left", "box1", 0.5, false]
+    ];
+
+    function setupTest()
+    {
+      var box = document.getElementById('box1');
+      document.addEventListener('webkitTransitionEnd', recordTransitionEndEvent, false);
+      document.addEventListener('transitionend', recordTransitionEndEvent, false);
+      box.style.left = '200px';
+    }
+
+    runTransitionTest(expectedEndEvents, setupTest);
+  </script>
+</head>
+<body>
+
+<p>Initiating a transition catching one transition event only despite listening the prefixed and unprefixed event.</p>
+
+<div id="container">
+  <div id="box1" class="box"></div>
+</div>
+
+<div id="result"></div>
+
+</body>
+</html>
\ No newline at end of file

Modified: trunk/Source/WebCore/ChangeLog (139761 => 139762)


--- trunk/Source/WebCore/ChangeLog	2013-01-15 19:17:09 UTC (rev 139761)
+++ trunk/Source/WebCore/ChangeLog	2013-01-15 19:17:42 UTC (rev 139762)
@@ -1,3 +1,48 @@
+2013-01-15  Alexis Menard  <[email protected]>
+
+        Unprefixed transitionend event doesn't seem to be implemented, which breaks many sites
+        https://bugs.webkit.org/show_bug.cgi?id=105647
+
+        Reviewed by Julien Chaffraix.
+
+        Add support for transitionend event delivery as part as the unprefixing
+        work on CSS Transitions. This patch adds some code in EventTarget to
+        figure out if the current event to dispatch has a prefixed version or
+        not. Then from the list of listeners we deduce which event should be delivered
+        (prefixed or unprefixed).
+
+        In the case of the CSS Transitions, WebKit will now behave as follow :
+        if an event listener is attached to the prefixed version of the
+        transition end event then only the prefixed event will be send.
+        If an event listener is attached to the unprefixed version
+        of the transition end event then only the unprefixed event will be
+        send. If there are event listeners on both unprefixed and prefixed
+        events then only the unprefixed event will be send.
+
+        The behavior was discussed here :
+        http://lists.webkit.org/pipermail/webkit-dev/2013-January/023301.html.
+
+        Tests: transitions/transition-end-event-unprefixed-01.html
+               transitions/transition-end-event-unprefixed-02.html
+
+        * dom/Document.cpp:
+        (WebCore::Document::addListenerTypeIfNeeded): Register the prefixed
+        listener too as transitionend listeners so that we properly dispatch
+        events for them.
+        * dom/EventNames.h:
+        (WebCore): Add the new transitionend name.
+        * dom/EventTarget.cpp:
+        (WebCore::createMatchingPrefixedEvent):
+        (WebCore::prefixedType):
+        (WebCore::EventTarget::fireEventListeners): Find out if somebody is
+        listening for unprefixed events, if so we always send the unprefixed
+        event, if not then we create a prefixed event and send it.
+        * page/animation/AnimationController.cpp:
+        (WebCore::AnimationControllerPrivate::fireEventsAndUpdateStyle):
+        * page/animation/ImplicitAnimation.cpp:
+        (WebCore::ImplicitAnimation::sendTransitionEvent): Always create by
+        default unprefixed events.
+
 2013-01-15  Tony Gentilcore  <[email protected]>
 
         Make AtomicMarkupTokenBase use a bare UChar* for external characters

Modified: trunk/Source/WebCore/dom/Document.cpp (139761 => 139762)


--- trunk/Source/WebCore/dom/Document.cpp	2013-01-15 19:17:09 UTC (rev 139761)
+++ trunk/Source/WebCore/dom/Document.cpp	2013-01-15 19:17:42 UTC (rev 139762)
@@ -3727,7 +3727,7 @@
         addListenerType(ANIMATIONEND_LISTENER);
     else if (eventType == eventNames().webkitAnimationIterationEvent)
         addListenerType(ANIMATIONITERATION_LISTENER);
-    else if (eventType == eventNames().webkitTransitionEndEvent)
+    else if (eventType == eventNames().webkitTransitionEndEvent || eventType == eventNames().transitionendEvent)
         addListenerType(TRANSITIONEND_LISTENER);
     else if (eventType == eventNames().beforeloadEvent)
         addListenerType(BEFORELOAD_LISTENER);

Modified: trunk/Source/WebCore/dom/EventNames.h (139761 => 139762)


--- trunk/Source/WebCore/dom/EventNames.h	2013-01-15 19:17:09 UTC (rev 139761)
+++ trunk/Source/WebCore/dom/EventNames.h	2013-01-15 19:17:42 UTC (rev 139762)
@@ -182,6 +182,7 @@
     macro(webkitAnimationIteration) \
     \
     macro(webkitTransitionEnd) \
+    macro(transitionend) \
     \
     macro(orientationchange) \
     \

Modified: trunk/Source/WebCore/dom/EventTarget.cpp (139761 => 139762)


--- trunk/Source/WebCore/dom/EventTarget.cpp	2013-01-15 19:17:09 UTC (rev 139761)
+++ trunk/Source/WebCore/dom/EventTarget.cpp	2013-01-15 19:17:42 UTC (rev 139762)
@@ -35,6 +35,7 @@
 #include "Event.h"
 #include "EventException.h"
 #include "InspectorInstrumentation.h"
+#include "WebKitTransitionEvent.h"
 #include <wtf/MainThread.h>
 #include <wtf/StdLibExtras.h>
 #include <wtf/Vector.h>
@@ -160,6 +161,28 @@
 {
 }
 
+static PassRefPtr<Event> createMatchingPrefixedEvent(const Event* event)
+{
+    if (event->type() == eventNames().transitionendEvent) {
+        const WebKitTransitionEvent* transitionEvent = static_cast<const WebKitTransitionEvent*>(event);
+        RefPtr<Event> prefixedEvent = WebKitTransitionEvent::create(eventNames().webkitTransitionEndEvent, transitionEvent->propertyName(), transitionEvent->elapsedTime());
+        prefixedEvent->setTarget(event->target());
+        prefixedEvent->setCurrentTarget(event->currentTarget());
+        prefixedEvent->setEventPhase(event->eventPhase());
+        return prefixedEvent.release();
+    }
+    ASSERT_NOT_REACHED();
+    return 0;
+}
+
+static AtomicString prefixedType(const Event* event)
+{
+    if (event->type() == eventNames().transitionendEvent)
+        return eventNames().webkitTransitionEndEvent;
+
+    return emptyString();
+}
+
 bool EventTarget::fireEventListeners(Event* event)
 {
     ASSERT(!NoEventDispatchAssertion::isEventDispatchForbidden());
@@ -169,10 +192,17 @@
     if (!d)
         return true;
 
-    EventListenerVector* listenerVector = d->eventListenerMap.find(event->type());
+    EventListenerVector* listenerPrefixedVector = 0;
+    AtomicString prefixedTypeName = prefixedType(event);
+    if (!prefixedTypeName.isEmpty())
+        listenerPrefixedVector = d->eventListenerMap.find(prefixedTypeName);
 
-    if (listenerVector)
-        fireEventListeners(event, d, *listenerVector);
+    EventListenerVector* listenerUnprefixedVector = d->eventListenerMap.find(event->type());
+
+    if (listenerUnprefixedVector)
+        fireEventListeners(event, d, *listenerUnprefixedVector);
+    else if (listenerPrefixedVector)
+        fireEventListeners(createMatchingPrefixedEvent(event).get(), d, *listenerPrefixedVector);
     
     return !event->defaultPrevented();
 }

Modified: trunk/Source/WebCore/page/animation/AnimationController.cpp (139761 => 139762)


--- trunk/Source/WebCore/page/animation/AnimationController.cpp	2013-01-15 19:17:09 UTC (rev 139761)
+++ trunk/Source/WebCore/page/animation/AnimationController.cpp	2013-01-15 19:17:42 UTC (rev 139762)
@@ -179,7 +179,7 @@
     m_eventsToDispatch.clear();
     Vector<EventToDispatch>::const_iterator eventsToDispatchEnd = eventsToDispatch.end();
     for (Vector<EventToDispatch>::const_iterator it = eventsToDispatch.begin(); it != eventsToDispatchEnd; ++it) {
-        if (it->eventType == eventNames().webkitTransitionEndEvent)
+        if (it->eventType == eventNames().transitionendEvent)
             it->element->dispatchEvent(WebKitTransitionEvent::create(it->eventType, it->name, it->elapsedTime));
         else
             it->element->dispatchEvent(WebKitAnimationEvent::create(it->eventType, it->name, it->elapsedTime));

Modified: trunk/Source/WebCore/page/animation/ImplicitAnimation.cpp (139761 => 139762)


--- trunk/Source/WebCore/page/animation/ImplicitAnimation.cpp	2013-01-15 19:17:09 UTC (rev 139761)
+++ trunk/Source/WebCore/page/animation/ImplicitAnimation.cpp	2013-01-15 19:17:42 UTC (rev 139762)
@@ -151,13 +151,13 @@
     if (keyframeAnim)
         keyframeAnim->setUnanimatedStyle(m_toStyle);
     
-    sendTransitionEvent(eventNames().webkitTransitionEndEvent, elapsedTime);
+    sendTransitionEvent(eventNames().transitionendEvent, elapsedTime);
     endAnimation();
 }
 
 bool ImplicitAnimation::sendTransitionEvent(const AtomicString& eventType, double elapsedTime)
 {
-    if (eventType == eventNames().webkitTransitionEndEvent) {
+    if (eventType == eventNames().transitionendEvent) {
         Document::ListenerType listenerType = Document::TRANSITIONEND_LISTENER;
 
         if (shouldSendEventForListener(listenerType)) {
@@ -176,7 +176,7 @@
             m_compAnim->animationController()->addEventToDispatch(element, eventType, propertyName, elapsedTime);
 
             // Restore the original (unanimated) style
-            if (eventType == eventNames().webkitTransitionEndEvent && element->renderer())
+            if (eventType == eventNames().transitionendEvent && element->renderer())
                 setNeedsStyleRecalc(element.get());
 
             return true; // Did dispatch an event
_______________________________________________
webkit-changes mailing list
[email protected]
http://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to