Commit 3c6ea8a1 authored by eric@webkit.org's avatar eric@webkit.org

2009-06-05 Eric Seidel <eric@webkit.org>

        Reviewed by Oliver Hunt.

        https://bugs.webkit.org/show_bug.cgi?id=25922
        Fix dropEffect = "none" to work as expected.

        * fast/events/drag-to-navigate-expected.txt: Copied from LayoutTests/editing/selection/doubleclick-whitespace-img-crash-expected.txt.
        * fast/events/drag-to-navigate.html: Added.
        * fast/events/prevent-drag-to-navigate-expected.txt: Copied from LayoutTests/editing/selection/doubleclick-whitespace-img-crash-expected.txt.
        * fast/events/prevent-drag-to-navigate.html: Added.
        * fast/events/resources/file-for-drag-to-navigate.html: Added.
        * fast/events/resources/file-for-prevent-drag-to-navigate.html: Added.

2009-06-05  Eric Seidel  <eric@webkit.org>

        Reviewed by Oliver Hunt.

        https://bugs.webkit.org/show_bug.cgi?id=25922
        JS setting dropEffect = "none" causes tryDHTMLDrag
        to return DragOperationNone.  Which is also the value
        tryDHTMLDrag previously used to indicate JS did not
        want to handle the drag.

        Make it possible for the DragController::try* methods
        to return a bool to indicate if javascript accepted
        or rejected the drag event, separate from the DragOperation.

        Tests:
        - fast/events/drag-to-navigate.html
        - fast/events/prevent-drag-to-navigate.html

        * page/DragController.cpp:
        (WebCore::DragController::dragEnteredOrUpdated):
        (WebCore::DragController::tryDocumentDrag):
        (WebCore::defaultOperationForDrag):
        (WebCore::DragController::tryDHTMLDrag):
        * page/DragController.h:

git-svn-id: http://svn.webkit.org/repository/webkit/trunk@45064 268f45cc-cd09-0410-ab3c-d52691b4dbfc
parent e5bc7df2
2009-06-05 Eric Seidel <eric@webkit.org>
Reviewed by Oliver Hunt.
https://bugs.webkit.org/show_bug.cgi?id=25922
Fix dropEffect = "none" to work as expected.
* fast/events/drag-to-navigate-expected.txt: Copied from LayoutTests/editing/selection/doubleclick-whitespace-img-crash-expected.txt.
* fast/events/drag-to-navigate.html: Added.
* fast/events/prevent-drag-to-navigate-expected.txt: Copied from LayoutTests/editing/selection/doubleclick-whitespace-img-crash-expected.txt.
* fast/events/prevent-drag-to-navigate.html: Added.
* fast/events/resources/file-for-drag-to-navigate.html: Added.
* fast/events/resources/file-for-prevent-drag-to-navigate.html: Added.
2009-06-23 Oliver Hunt <oliver@apple.com>
Reviewed by NOBODY (missed a file).
......
<div>FAIL</div>
<script>
function doTest() {
layoutTestController.dumpAsText();
eventSender.beginDragWithFiles(["resources/file-for-drag-to-navigate.html"]);
eventSender.mouseMoveTo(10, 10);
eventSender.mouseUp();
}
if (window.eventSender) {
layoutTestController.waitUntilDone();
// The load seems to fail if we try to kick of a
// new load before this one is finished. So we wait.
window.onload = doTest();
}
</script>
<div>PASS</div>
<script>
function dragEnter() {
event.dataTransfer.dropEffect = "none";
event.preventDefault();
}
function dragOver() {
// See https://bugs.webkit.org/show_bug.cgi?id=25922
// This is the line which causes failure:
event.dataTransfer.dropEffect = "none";
event.preventDefault();
}
function dragLeave() {
event.preventDefault();
setTimeout(function() {
// Wait until after the drop to notifyDone, just to make sure
// the navigation was prevented correctly.
if (window.layoutTestController)
layoutTestController.notifyDone();
}, 0);
}
// Capture all drag events
window.addEventListener("dragenter", dragEnter, true);
window.addEventListener("dragover", dragOver, true);
// We don't get a drop event when we prevent drop, so listen for dragleave
window.addEventListener("dragleave", dragLeave, true);
function doTest() {
layoutTestController.dumpAsText();
eventSender.beginDragWithFiles(["resources/file-for-prevent-drag-to-navigate.html"]);
eventSender.mouseMoveTo(10, 10);
eventSender.mouseUp();
}
if (window.eventSender) {
layoutTestController.waitUntilDone();
// The load seems to fail (for the wrong reasons) if we try to kick of a
// new load before this one is finished. So we wait.
window.onload = doTest();
}
</script>
PASS
<script>
layoutTestController.notifyDone();
</script>
FAIL - Drag navigation occurred even though the page tried to prevent it.
<script>
// This is never called, but prevents the test from timing out if we ever fail this test.
layoutTestController.notifyDone();
</script>
2009-06-05 Eric Seidel <eric@webkit.org>
Reviewed by Oliver Hunt.
https://bugs.webkit.org/show_bug.cgi?id=25922
JS setting dropEffect = "none" causes tryDHTMLDrag
to return DragOperationNone. Which is also the value
tryDHTMLDrag previously used to indicate JS did not
want to handle the drag.
Make it possible for the DragController::try* methods
to return a bool to indicate if javascript accepted
or rejected the drag event, separate from the DragOperation.
Tests:
- fast/events/drag-to-navigate.html
- fast/events/prevent-drag-to-navigate.html
* page/DragController.cpp:
(WebCore::DragController::dragEnteredOrUpdated):
(WebCore::DragController::tryDocumentDrag):
(WebCore::defaultOperationForDrag):
(WebCore::DragController::tryDHTMLDrag):
* page/DragController.h:
2009-06-23 Oliver Hunt <oliver@apple.com> and Eric Carlson <eric.carlson@apple.com>
Reviewed by Sam Weinig and Dave Hyatt.
......
......@@ -222,17 +222,15 @@ DragOperation DragController::dragEnteredOrUpdated(DragData* dragData)
mouseMovedIntoDocument(m_page->mainFrame()->documentAtPoint(dragData->clientPosition()));
m_dragDestinationAction = m_client->actionMaskForDrag(dragData);
DragOperation operation = DragOperationNone;
if (m_dragDestinationAction == DragDestinationActionNone)
if (m_dragDestinationAction == DragDestinationActionNone) {
cancelDrag(); // FIXME: Why not call mouseMovedIntoDocument(0)?
else {
operation = tryDocumentDrag(dragData, m_dragDestinationAction);
if (operation == DragOperationNone && (m_dragDestinationAction & DragDestinationActionLoad))
return operationForLoad(dragData);
return DragOperationNone;
}
DragOperation operation = DragOperationNone;
bool handledByDocument = tryDocumentDrag(dragData, m_dragDestinationAction, operation);
if (!handledByDocument && (m_dragDestinationAction & DragDestinationActionLoad))
return operationForLoad(dragData);
return operation;
}
......@@ -256,12 +254,12 @@ static HTMLInputElement* asFileInput(Node* node)
return 0;
}
DragOperation DragController::tryDocumentDrag(DragData* dragData, DragDestinationAction actionMask)
bool DragController::tryDocumentDrag(DragData* dragData, DragDestinationAction actionMask, DragOperation& operation)
{
ASSERT(dragData);
if (!m_documentUnderMouse)
return DragOperationNone;
return false;
DragOperation operation = DragOperationNone;
if (actionMask & DragDestinationActionDHTML) {
......@@ -272,17 +270,26 @@ DragOperation DragController::tryDocumentDrag(DragData* dragData, DragDestinatio
// which could process dragleave event and reset m_documentUnderMouse in
// dragExited.
if (!m_documentUnderMouse)
return DragOperationNone;
return false;
}
m_isHandlingDrag = operation != DragOperationNone;
// It's unclear why this check is after tryDHTMLDrag.
// We send drag events in tryDHTMLDrag and that may be the reason.
RefPtr<FrameView> frameView = m_documentUnderMouse->view();
if (!frameView)
return operation;
return false;
if (m_isHandlingDrag) {
m_page->dragCaretController()->clear();
return true;
}
if ((actionMask & DragDestinationActionEdit) && !m_isHandlingDrag && canProcessDrag(dragData)) {
if (dragData->containsColor())
return DragOperationGeneric;
if (dragData->containsColor()) {
operation = DragOperationGeneric;
return true;
}
IntPoint dragPos = dragData->clientPosition();
IntPoint point = frameView->windowToContents(dragPos);
......@@ -294,11 +301,10 @@ DragOperation DragController::tryDocumentDrag(DragData* dragData, DragDestinatio
}
Frame* innerFrame = element->document()->frame();
return dragIsMove(innerFrame->selection()) ? DragOperationMove : DragOperationCopy;
}
m_page->dragCaretController()->clear();
return operation;
operation = dragIsMove(innerFrame->selection()) ? DragOperationMove : DragOperationCopy;
return true;
}
return false;
}
DragSourceAction DragController::delegateDragSourceAction(const IntPoint& windowPoint)
......@@ -461,43 +467,51 @@ bool DragController::canProcessDrag(DragData* dragData)
return true;
}
DragOperation DragController::tryDHTMLDrag(DragData* dragData)
static DragOperation defaultOperationForDrag(DragOperation srcOpMask)
{
// This is designed to match IE's operation fallback for the case where
// the page calls preventDefault() in a drag event but doesn't set dropEffect.
if (srcOpMask & DragOperationCopy)
return DragOperationCopy;
if (srcOpMask & DragOperationMove || srcOpMask & DragOperationGeneric)
return DragOperationMove;
if (srcOpMask & DragOperationLink)
return DragOperationLink;
// FIXME: Does IE really return "generic" even if no operations were allowed by the source?
return DragOperationGeneric;
}
bool DragController::tryDHTMLDrag(DragData* dragData, DragOperation& operation)
{
ASSERT(dragData);
ASSERT(m_documentUnderMouse);
DragOperation op = DragOperationNone;
RefPtr<Frame> mainFrame = m_page->mainFrame();
RefPtr<FrameView> viewProtector = mainFrame->view();
if (!viewProtector)
return DragOperationNone;
return false;
ClipboardAccessPolicy policy = m_documentUnderMouse->securityOrigin()->isLocal() ? ClipboardReadable : ClipboardTypesReadable;
RefPtr<Clipboard> clipboard = dragData->createClipboard(policy);
DragOperation srcOp = dragData->draggingSourceOperationMask();
clipboard->setSourceOperation(srcOp);
PlatformMouseEvent event = createMouseEvent(dragData);
if (mainFrame->eventHandler()->updateDragAndDrop(event, clipboard.get())) {
// *op unchanged if no source op was set
if (!clipboard->destinationOperation(op)) {
// The element accepted but they didn't pick an operation, so we pick one for them
// (as does WinIE).
if (srcOp & DragOperationCopy)
op = DragOperationCopy;
else if (srcOp & DragOperationMove || srcOp & DragOperationGeneric)
op = DragOperationMove;
else if (srcOp & DragOperationLink)
op = DragOperationLink;
else
op = DragOperationGeneric;
} else if (!(op & srcOp)) {
op = DragOperationNone;
}
DragOperation srcOpMask = dragData->draggingSourceOperationMask();
clipboard->setSourceOperation(srcOpMask);
PlatformMouseEvent event = createMouseEvent(dragData);
if (!mainFrame->eventHandler()->updateDragAndDrop(event, clipboard.get())) {
clipboard->setAccessPolicy(ClipboardNumb); // invalidate clipboard here for security
return op;
return false;
}
if (!clipboard->destinationOperation(operation)) {
// The element accepted but they didn't pick an operation, so we pick one (to match IE).
operation = defaultOperationForDrag(srcOpMask);
} else if (!(srcOpMask & operation)) {
// The element picked an operation which is not supported by the source
operation = DragOperationNone;
}
return op;
clipboard->setAccessPolicy(ClipboardNumb); // invalidate clipboard here for security
return true;
}
bool DragController::mayStartDragAtEventLocation(const Frame* frame, const IntPoint& framePos)
......
......@@ -96,8 +96,8 @@ namespace WebCore {
bool concludeEditDrag(DragData*);
DragOperation dragEnteredOrUpdated(DragData*);
DragOperation operationForLoad(DragData*);
DragOperation tryDocumentDrag(DragData*, DragDestinationAction);
DragOperation tryDHTMLDrag(DragData*);
bool tryDocumentDrag(DragData*, DragDestinationAction, DragOperation&);
bool tryDHTMLDrag(DragData*, DragOperation&);
DragOperation dragOperation(DragData*);
void cancelDrag();
bool dragIsMove(SelectionController*);
......
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