LayoutTests:
authorantti <antti@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 13 Jul 2007 18:55:42 +0000 (18:55 +0000)
committerantti <antti@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 13 Jul 2007 18:55:42 +0000 (18:55 +0000)
        Reviewed by Adele.

        Test for <rdar://problem/5192256>
        click() in onchange handler causes another change event (causes hang at http://forums.whirlpool.net.au/)

        * fast/events/onchange-click-hang-expected.txt: Added.
        * fast/events/onchange-click-hang.html: Added.

WebCore:

        Reviewed by Adele.

        Fix <rdar://problem/5192256>
        click() in onchange handler causes another change event (causes hang at http://forums.whirlpool.net.au/)

        Guard against generating a simulated event from within a simulated event in the same node. Try to
        match Firefox behavior.

        * dom/EventTargetNode.cpp:
        (WebCore::EventTargetNode::dispatchSimulatedMouseEvent):
        (WebCore::EventTargetNode::dispatchSimulatedClick):
        * dom/Node.cpp:
        (WebCore::Node::Node):
        * dom/Node.h:

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

LayoutTests/ChangeLog
LayoutTests/fast/events/onchange-click-hang-expected.txt [new file with mode: 0644]
LayoutTests/fast/events/onchange-click-hang.html [new file with mode: 0644]
WebCore/ChangeLog
WebCore/dom/EventTargetNode.cpp
WebCore/dom/Node.cpp
WebCore/dom/Node.h

index 2d2a04c08c74685240d17920c29700919fed1e01..7b4dd9d6c7d8bfc8a52107f77054d8f0e5fd585f 100644 (file)
@@ -1,3 +1,13 @@
+2007-07-13  Antti Koivisto  <antti@apple.com>
+
+        Reviewed by Adele.
+        
+        Test for <rdar://problem/5192256>
+        click() in onchange handler causes another change event (causes hang at http://forums.whirlpool.net.au/)
+
+        * fast/events/onchange-click-hang-expected.txt: Added.
+        * fast/events/onchange-click-hang.html: Added.
+
 2007-07-13  Antti Koivisto  <antti@apple.com>
 
         Reviewed by Darin.
diff --git a/LayoutTests/fast/events/onchange-click-hang-expected.txt b/LayoutTests/fast/events/onchange-click-hang-expected.txt
new file mode 100644 (file)
index 0000000..50e1070
--- /dev/null
@@ -0,0 +1,13 @@
+These checkboxes call their own and each others click() method from their onchange callbacks. Click the first checkbox. This should not crash or hang. This also shows that click() is protected on per-element basis.
+checkbox1 onchange enter
+checkbox1 onchange enter
+checkbox2 onchange enter
+checkbox2 onchange exit
+checkbox1 onchange exit
+checkbox2 onchange enter
+checkbox1 onchange enter
+checkbox1 onchange exit
+checkbox2 onchange exit
+checkbox1 onchange exit
+
diff --git a/LayoutTests/fast/events/onchange-click-hang.html b/LayoutTests/fast/events/onchange-click-hang.html
new file mode 100644 (file)
index 0000000..e5897a6
--- /dev/null
@@ -0,0 +1,24 @@
+<head>
+<script>
+function log(t) {
+document.getElementById('console').innerHTML += t +'<br>';
+}
+
+if (window.layoutTestController)
+    layoutTestController.dumpAsText();
+</script>
+<body>
+These checkboxes call their own and each others click() method from their onchange callbacks. Click the first checkbox. This should not crash or hang.
+This also shows that click() is protected on per-element basis.<br>
+<input id=cb type="checkbox" onchange="log('checkbox1 onchange enter');this.click();document.getElementById('cb2').click();log('checkbox1 onchange exit');">
+<input id=cb2 type="checkbox" onchange="log('checkbox2 onchange enter');document.getElementById('cb').click();log('checkbox2 onchange exit')">
+<div id=console></div>
+<script>
+    if (window.eventSender) {
+        var cb = document.getElementById('cb');
+        eventSender.mouseMoveTo(cb.offsetLeft + 5, cb.offsetTop + 5);
+        eventSender.mouseDown();
+        eventSender.mouseUp();
+    }  
+</script>
+
index af732e06d1db3353675d8d72bd5d07cb3619ecc4..1a6782b03ee65a7044ffa38290fe095f37466827 100644 (file)
@@ -1,3 +1,20 @@
+2007-07-13  Antti Koivisto  <antti@apple.com>
+
+        Reviewed by Adele.
+        
+        Fix <rdar://problem/5192256>
+        click() in onchange handler causes another change event (causes hang at http://forums.whirlpool.net.au/)
+        
+        Guard against generating a simulated event from within a simulated event in the same node. Try to
+        match Firefox behavior.
+
+        * dom/EventTargetNode.cpp:
+        (WebCore::EventTargetNode::dispatchSimulatedMouseEvent):
+        (WebCore::EventTargetNode::dispatchSimulatedClick):
+        * dom/Node.cpp:
+        (WebCore::Node::Node):
+        * dom/Node.h:
+
 2007-07-13  Antti Koivisto  <antti@apple.com>
 
         Reviewed by Darin.
index 6a6f79801e021ab703a730579c85eed5c454ca72..ddb5f73b7508f1a61f9252726be663d3369ca5a0 100644 (file)
@@ -401,6 +401,9 @@ void EventTargetNode::dispatchSimulatedMouseEvent(const AtomicString& eventType,
     PassRefPtr<Event> underlyingEvent)
 {
     ASSERT(!eventDispatchForbidden());
+    
+    if (m_dispatchingSimulatedEvent)
+        return;
 
     bool ctrlKey = false;
     bool altKey = false;
@@ -412,15 +415,22 @@ void EventTargetNode::dispatchSimulatedMouseEvent(const AtomicString& eventType,
         shiftKey = keyStateEvent->shiftKey();
         metaKey = keyStateEvent->metaKey();
     }
+    
+    m_dispatchingSimulatedEvent = true;
 
     // Like Gecko, we just pass 0 for everything when we make a fake mouse event.
     // Internet Explorer instead gives the current mouse position and state.
     dispatchMouseEvent(eventType, 0, 0, 0, 0, 0, 0,
         ctrlKey, altKey, shiftKey, metaKey, true, 0, underlyingEvent);
+    
+    m_dispatchingSimulatedEvent = false;
 }
 
 void EventTargetNode::dispatchSimulatedClick(PassRefPtr<Event> event, bool sendMouseEvents, bool showPressedLook)
 {
+    if (m_dispatchingSimulatedEvent)
+        return;
+    
     // send mousedown and mouseup before the click, if requested
     if (sendMouseEvents)
         dispatchSimulatedMouseEvent(mousedownEvent, event.get());
index 92ade9007ecd7b0e15592acd2fa17e5350180d0e..080bb958b1f7df5454374d2aaa37555d5e6375be 100644 (file)
@@ -153,6 +153,7 @@ Node::Node(Document *doc)
       m_hovered(false),
       m_inActiveChain(false),
       m_inDetach(false),
+      m_dispatchingSimulatedEvent(false),
       m_inSubtreeMark(false)
 {
 #ifndef NDEBUG
index 20180ef9cad0271bc536b7273c7a95e2c029a496..863ba100b207f73e7b84cfec0127bc6ed5a27e72 100644 (file)
@@ -482,9 +482,11 @@ protected:
     bool m_inActiveChain : 1;
 
     bool m_inDetach : 1;
+    bool m_dispatchingSimulatedEvent : 1;
 
 public:
     bool m_inSubtreeMark : 1;
+    // 0 bits left
 
 private:
     Element* ancestorElement() const;