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
+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.
--- /dev/null
+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
+
--- /dev/null
+<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>
+
+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.
PassRefPtr<Event> underlyingEvent)
{
ASSERT(!eventDispatchForbidden());
+
+ if (m_dispatchingSimulatedEvent)
+ return;
bool ctrlKey = false;
bool altKey = false;
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());
m_hovered(false),
m_inActiveChain(false),
m_inDetach(false),
+ m_dispatchingSimulatedEvent(false),
m_inSubtreeMark(false)
{
#ifndef NDEBUG
bool m_inActiveChain : 1;
bool m_inDetach : 1;
+ bool m_dispatchingSimulatedEvent : 1;
public:
bool m_inSubtreeMark : 1;
+ // 0 bits left
private:
Element* ancestorElement() const;