ASSERT(m_wheelEventHandlerCount > 0) can fire
authorabarth@webkit.org <abarth@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 25 Jun 2012 17:39:07 +0000 (17:39 +0000)
committerabarth@webkit.org <abarth@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 25 Jun 2012 17:39:07 +0000 (17:39 +0000)
https://bugs.webkit.org/show_bug.cgi?id=89856

Reviewed by Eric Seidel.

Source/WebCore:

When a node with a wheel or a touch event is moved from one document to
another, the didAddMumble/didRemoveMumble calls do not balance because
they're called on different documents. This patch twiddles the counts
appropriately in that case.

Test: fast/events/move-element-with-wheel-and-touch-event-listeners.html

* dom/EventNames.h:
(WebCore::EventNames::isTouchEventType):
(EventNames):
(WebCore::EventNames::touchEventNames):
* dom/Node.cpp:
(WebCore::Node::didMoveToNewDocument):

LayoutTests:

Test what happens when we move a node with wheel and/or touch events
from one document to another. Prior to this patch, this test triggers
ASSERT(m_wheelEventHandlerCount > 0) in Document.cpp.

* fast/events/move-element-with-wheel-and-touch-event-listeners-expected.txt: Added.
* fast/events/move-element-with-wheel-and-touch-event-listeners.html: Added.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@121166 268f45cc-cd09-0410-ab3c-d52691b4dbfc

LayoutTests/ChangeLog
LayoutTests/fast/events/move-element-with-wheel-and-touch-event-listeners-expected.txt [new file with mode: 0644]
LayoutTests/fast/events/move-element-with-wheel-and-touch-event-listeners.html [new file with mode: 0644]
Source/WebCore/ChangeLog
Source/WebCore/dom/EventNames.h
Source/WebCore/dom/Node.cpp

index 72184b3..1035f5c 100644 (file)
@@ -1,3 +1,17 @@
+2012-06-25  Adam Barth  <abarth@webkit.org>
+
+        ASSERT(m_wheelEventHandlerCount > 0) can fire
+        https://bugs.webkit.org/show_bug.cgi?id=89856
+
+        Reviewed by Eric Seidel.
+
+        Test what happens when we move a node with wheel and/or touch events
+        from one document to another. Prior to this patch, this test triggers
+        ASSERT(m_wheelEventHandlerCount > 0) in Document.cpp.
+
+        * fast/events/move-element-with-wheel-and-touch-event-listeners-expected.txt: Added.
+        * fast/events/move-element-with-wheel-and-touch-event-listeners.html: Added.
+
 2012-06-25  Shinya Kawanaka  <shinyak@chromium.org>
 
         [Shadow] Executing Italic and InsertUnorderedList in Shadow DOM causes a crash
diff --git a/LayoutTests/fast/events/move-element-with-wheel-and-touch-event-listeners-expected.txt b/LayoutTests/fast/events/move-element-with-wheel-and-touch-event-listeners-expected.txt
new file mode 100644 (file)
index 0000000..73f132b
--- /dev/null
@@ -0,0 +1,2 @@
+ This test passes if it doesn't crash.
+
diff --git a/LayoutTests/fast/events/move-element-with-wheel-and-touch-event-listeners.html b/LayoutTests/fast/events/move-element-with-wheel-and-touch-event-listeners.html
new file mode 100644 (file)
index 0000000..986941a
--- /dev/null
@@ -0,0 +1,21 @@
+<iframe src="data:text/html,<div id=foo></div>"></iframe>
+<script>
+if (window.testRunner)
+    testRunner.dumpAsText();
+
+function doNothing() {
+}
+
+addEventListener("load", function() {
+    var element = frames[0].document.getElementById("foo");
+
+    element.addEventListener("mousewheel", doNothing, false);
+    element.addEventListener("touchstart", doNothing, false);
+
+    document.body.appendChild(element);
+
+    element.removeEventListener("mousewheel", doNothing, false);
+    element.removeEventListener("touchstart", doNothing, false);
+}, false);
+</script>
+This test passes if it doesn't crash.
index 0054b30..5fe8546 100644 (file)
@@ -1,3 +1,24 @@
+2012-06-25  Adam Barth  <abarth@webkit.org>
+
+        ASSERT(m_wheelEventHandlerCount > 0) can fire
+        https://bugs.webkit.org/show_bug.cgi?id=89856
+
+        Reviewed by Eric Seidel.
+
+        When a node with a wheel or a touch event is moved from one document to
+        another, the didAddMumble/didRemoveMumble calls do not balance because
+        they're called on different documents. This patch twiddles the counts
+        appropriately in that case.
+
+        Test: fast/events/move-element-with-wheel-and-touch-event-listeners.html
+
+        * dom/EventNames.h:
+        (WebCore::EventNames::isTouchEventType):
+        (EventNames):
+        (WebCore::EventNames::touchEventNames):
+        * dom/Node.cpp:
+        (WebCore::Node::didMoveToNewDocument):
+
 2012-06-25  Eric Seidel  <eric@webkit.org>
 
         Split map* functions out of StyleResolver into a helper object
index 3056d4a..598bcdd 100644 (file)
@@ -251,7 +251,21 @@ namespace WebCore {
 
         inline bool isTouchEventType(const AtomicString& eventType) const
         {
-            return eventType == touchstartEvent || eventType == touchmoveEvent || eventType == touchendEvent || eventType == touchcancelEvent;
+            return eventType == touchstartEvent
+                || eventType == touchmoveEvent
+                || eventType == touchendEvent
+                || eventType == touchcancelEvent;
+        }
+
+        Vector<AtomicString> touchEventNames() const
+        {
+            Vector<AtomicString> names;
+            names.reserveCapacity(4);
+            names.append(touchstartEvent);
+            names.append(touchmoveEvent);
+            names.append(touchendEvent);
+            names.append(touchcancelEvent);
+            return names;
         }
     };
 
index 7446cfa..ae3945b 100644 (file)
@@ -2309,6 +2309,21 @@ void Node::didMoveToNewDocument(Document* oldDocument)
 
     // FIXME: Event listener types for this node should be set on the new owner document here.
 
+    const EventListenerVector& wheelListeners = getEventListeners(eventNames().mousewheelEvent);
+    for (size_t i = 0; i < wheelListeners.size(); ++i) {
+        oldDocument->didRemoveWheelEventHandler();
+        document()->didAddWheelEventHandler();
+    }
+
+    Vector<AtomicString> touchEventNames = eventNames().touchEventNames();
+    for (size_t i = 0; i < touchEventNames.size(); ++i) {
+        const EventListenerVector& listeners = getEventListeners(touchEventNames[i]);
+        for (size_t j = 0; j < listeners.size(); ++j) {
+            oldDocument->didRemoveTouchEventHandler();
+            document()->didAddTouchEventHandler();
+        }
+    }
+
 #if ENABLE(MUTATION_OBSERVERS)
     if (Vector<OwnPtr<MutationObserverRegistration> >* registry = mutationObserverRegistry()) {
         for (size_t i = 0; i < registry->size(); ++i) {