Commit 23a723be authored by oliver@apple.com's avatar oliver@apple.com

<rdar://problem/6156755> onMouseOver events do not fire properly for cross frame drag and drop

Reviewed by Adele Peterson.

This problem was caused by incorrectly ignoring whether or not the
default behaviour of the mousedown event was suppressed.  If a
mousedown handler in a frame prevents default handling then the
subsequent mousemove events fired for the drag should not be
captured by that frame, should the mouse move out of its bounds.

Test: fast/events/mouse-drag-from-frame.html


git-svn-id: http://svn.webkit.org/repository/webkit/trunk@40845 268f45cc-cd09-0410-ab3c-d52691b4dbfc
parent 8c630eff
2009-02-10 Oliver Hunt <oliver@apple.com>
Reviewed by Adele Peterson.
<rdar://problem/6156755> onMouseOver events do not fire properly for cross frame drag and drop
Simple testcase to ensure that a subframe does not incorrectly capture mousemove events
when the mousedown handler has prevented default handling.
* fast/events/mouse-drag-from-frame-expected.txt: Added.
* fast/events/mouse-drag-from-frame.html: Added.
* fast/events/resources/mouse-drag-from-frame-subframe.html: Added.
2009-02-08 Sam Weinig <sam@webkit.org>
Reviewed by David Hyatt.
......
This tests that dragging from an element that returns false from its mousedown handler will not let the subsequent mousemove events be captured by the containing frame.
Drag started
Received mouse move
Received mouseup event
PASS!
<!DOCTYPE html>
<html>
<head>
<script>
if (window.layoutTestController) {
layoutTestController.waitUntilDone();
layoutTestController.dumpAsText();
}
function log(msg) {
var msgNode = document.createTextNode(msg);
var li = document.createElement("li");
li.appendChild(msgNode);
document.getElementById("log").appendChild(li);
}
var dragging = false;
var waitingForUp = false;
function dragStarted() {
if (dragging || waitingForUp) {
log("Unexpected drag start");
return;
}
log("Drag started");
dragging = true;
}
window.onmousedown = function() {
log("Unexpected mousedown");
}
window.onmousemove = function() {
if (!dragging || waitingForUp)
return;
log("Received mouse move");
waitingForUp = true;
}
window.onmouseup = function() {
if (!waitingForUp) {
log("Unexpected mouseup");
return;
}
log("Received mouseup event")
log("PASS!");
}
window.onload = function() {
try {
if (!frames[0] || !frames[0].document || !frames[0].document.getElementById("dragSource")) {
log("Window.onload fired before subframe completed load.");
}
if (!window.layoutTestController) {
log("This test needs to be run in DRT. To test manually drag from the text 'Drag Me!' out into the parent frame.");
return;
}
var dragSource = frames[0].document.getElementById("dragSource");
var sourceFrame = document.getElementById("sourceFrame");
var x = dragSource.offsetLeft + sourceFrame.offsetLeft + 10;
var y = dragSource.offsetTop + sourceFrame.offsetTop + dragSource.offsetHeight / 2;
eventSender.mouseMoveTo(x,y);
eventSender.mouseDown();
eventSender.mouseMoveTo(120, 120);
eventSender.mouseUp();
} finally {
if (window.layoutTestController)
layoutTestController.notifyDone();
}
}
</script>
</head>
<body>
<div>This tests that dragging from an element that returns <emph>false</emph> from its mousedown handler will not let the subsequent mousemove events be captured by the containing frame.</div>
<iframe id="sourceFrame" style="width: 100px; height: 50px;" src="resources/mouse-drag-from-frame-subframe.html"></iframe>
<ul id="log">
</ul>
</body>
</html>
<div id="dragSource" onmousedown="parent.dragStarted(); return false;" onmouseup="parent.log('Unexpected mouseup event')">Drag Me!</div>
2009-02-10 Oliver Hunt <oliver@apple.com>
Reviewed by Adele Peterson.
<rdar://problem/6156755> onMouseOver events do not fire properly for cross frame drag and drop
This problem was caused by incorrectly ignoring whether or not the
default behaviour of the mousedown event was suppressed. If a
mousedown handler in a frame prevents default handling then the
subsequent mousemove events fired for the drag should not be
captured by that frame, should the mouse move out of its bounds.
Test: fast/events/mouse-drag-from-frame.html
* page/EventHandler.cpp:
(WebCore::EventHandler::EventHandler):
(WebCore::EventHandler::clear):
(WebCore::EventHandler::handleMouseReleaseEvent):
Reset new m_capturesDragging flag
(WebCore::EventHandler::handleMousePressEvent):
Respect the m_capturesDragging flag when we propagate
a mousedown event to a subframe.
* page/EventHandler.h:
(WebCore::EventHandler::capturesDragging):
2009-02-10 Kevin Ollivier <kevino@theolliviers.com>
wx build fixes for recent changes to TransformationMatrix and DOMElement.
......@@ -122,6 +122,7 @@ static inline void scrollAndAcceptEvent(float delta, ScrollDirection positiveDir
EventHandler::EventHandler(Frame* frame)
: m_frame(frame)
, m_mousePressed(false)
, m_capturesDragging(false)
, m_mouseDownMayStartSelect(false)
, m_mouseDownMayStartDrag(false)
, m_mouseDownWasSingleClickInSelection(false)
......@@ -179,6 +180,7 @@ void EventHandler::clear()
m_currentMousePosition = IntPoint();
m_mousePressNode = 0;
m_mousePressed = false;
m_capturesDragging = false;
m_capturingMouseEventsNode = 0;
}
......@@ -546,6 +548,7 @@ bool EventHandler::handleMouseReleaseEvent(const MouseEventWithHitTestResults& e
// the mouse is pressed again.
m_frame->selection()->setCaretBlinkingSuspended(false);
m_mousePressed = false;
m_capturesDragging = false;
m_mouseDownMayStartDrag = false;
m_mouseDownMayStartSelect = false;
m_mouseDownMayStartAutoscroll = false;
......@@ -1003,6 +1006,7 @@ bool EventHandler::handleMousePressEvent(const PlatformMouseEvent& mouseEvent)
RefPtr<FrameView> protector(m_frame->view());
m_mousePressed = true;
m_capturesDragging = true;
m_currentMousePosition = mouseEvent.pos();
m_mouseDownTimestamp = mouseEvent.timestamp();
m_mouseDownMayStartDrag = false;
......@@ -1032,7 +1036,8 @@ bool EventHandler::handleMousePressEvent(const PlatformMouseEvent& mouseEvent)
if (subframe && passMousePressEventToSubframe(mev, subframe)) {
// Start capturing future events for this frame. We only do this if we didn't clear
// the m_mousePressed flag, which may happen if an AppKit widget entered a modal event loop.
if (m_mousePressed)
m_capturesDragging = subframe->eventHandler()->capturesDragging();
if (m_mousePressed && m_capturesDragging)
m_capturingMouseEventsNode = mev.targetNode();
invalidateClick();
return true;
......@@ -1078,6 +1083,7 @@ bool EventHandler::handleMousePressEvent(const PlatformMouseEvent& mouseEvent)
}
bool swallowEvent = dispatchMouseEvent(eventNames().mousedownEvent, mev.targetNode(), true, m_clickCount, mouseEvent, true);
m_capturesDragging = !swallowEvent;
// If the hit testing originally determined the event was in a scrollbar, refetch the MouseEventWithHitTestResults
// in case the scrollbar widget was destroyed when the mouse event was handled.
......
......@@ -288,9 +288,12 @@ private:
void updateSelectionForMouseDrag(Node* targetNode, const IntPoint& localPoint);
bool capturesDragging() const { return m_capturesDragging; }
Frame* m_frame;
bool m_mousePressed;
bool m_capturesDragging;
RefPtr<Node> m_mousePressNode;
bool m_mouseDownMayStartSelect;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment