bool DragController::tryDocumentDrag(DragData* dragData, DragDestinationAction actionMask, DragOperation& operation) { ASSERT(dragData); if (!m_documentUnderMouse) return false; m_isHandlingDrag = false; if (actionMask & DragDestinationActionDHTML) { m_isHandlingDrag = tryDHTMLDrag(dragData, operation); // Do not continue if m_documentUnderMouse has been reset by tryDHTMLDrag. // tryDHTMLDrag fires dragenter event. The event listener that listens // to this event may create a nested message loop (open a modal dialog), // which could process dragleave event and reset m_documentUnderMouse in // dragExited. if (!m_documentUnderMouse) return false; } // 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 false; if (m_isHandlingDrag) { m_page->dragCaretController()->clear(); return true; } else if ((actionMask & DragDestinationActionEdit) && canProcessDrag(dragData)) { if (dragData->containsColor()) { operation = DragOperationGeneric; return true; } IntPoint point = frameView->windowToContents(dragData->clientPosition()); Element* element = elementUnderMouse(m_documentUnderMouse, point); if (!asFileInput(element)) { VisibleSelection dragCaret = m_documentUnderMouse->frame()->visiblePositionForPoint(point); m_page->dragCaretController()->setSelection(dragCaret); } Frame* innerFrame = element->document()->frame(); operation = dragIsMove(innerFrame->selection()) ? DragOperationMove : DragOperationCopy; return true; } // If we're not over an editable region, make sure we're clearing any prior drag cursor. m_page->dragCaretController()->clear(); return false; }
DragOperation DragController::tryDocumentDrag(DragData* dragData, DragDestinationAction actionMask) { ASSERT(dragData); if (!m_document) return DragOperationNone; DragOperation operation = DragOperationNone; if (actionMask & DragDestinationActionDHTML) operation = tryDHTMLDrag(dragData); m_isHandlingDrag = operation != DragOperationNone; RefPtr<FrameView> frameView = m_document->view(); if (!frameView) return operation; if ((actionMask & DragDestinationActionEdit) && !m_isHandlingDrag && canProcessDrag(dragData)) { if (dragData->containsColor()) return DragOperationGeneric; IntPoint dragPos = dragData->clientPosition(); IntPoint point = frameView->windowToContents(dragPos); Element* element = m_document->elementFromPoint(point.x(), point.y()); ASSERT(element); Frame* innerFrame = element->document()->frame(); ASSERT(innerFrame); if (!asFileInput(element)) { Selection dragCaret; if (Frame* frame = m_document->frame()) dragCaret = frame->visiblePositionForPoint(point); m_page->dragCaretController()->setSelection(dragCaret); } return dragIsMove(innerFrame->selection()) ? DragOperationMove : DragOperationCopy; } m_page->dragCaretController()->clear(); return operation; }
bool DragController::tryDocumentDrag(DragData* dragData, DragDestinationAction actionMask, DragSession& dragSession) { ASSERT(dragData); if (!m_documentUnderMouse) return false; if (m_dragInitiator && !m_documentUnderMouse->securityOrigin()->canReceiveDragData(m_dragInitiator->securityOrigin())) return false; m_isHandlingDrag = false; if (actionMask & DragDestinationActionDHTML) { m_isHandlingDrag = tryDHTMLDrag(dragData, dragSession.operation); // Do not continue if m_documentUnderMouse has been reset by tryDHTMLDrag. // tryDHTMLDrag fires dragenter event. The event listener that listens // to this event may create a nested message loop (open a modal dialog), // which could process dragleave event and reset m_documentUnderMouse in // dragExited. if (!m_documentUnderMouse) return false; } // 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 false; if (m_isHandlingDrag) { m_page->dragCaretController()->clear(); return true; } else if ((actionMask & DragDestinationActionEdit) && canProcessDrag(dragData)) { if (dragData->containsColor()) { dragSession.operation = DragOperationGeneric; return true; } IntPoint point = frameView->windowToContents(dragData->clientPosition()); Element* element = elementUnderMouse(m_documentUnderMouse.get(), point); if (!element) return false; HTMLInputElement* elementAsFileInput = asFileInput(element); if (m_fileInputElementUnderMouse != elementAsFileInput) { if (m_fileInputElementUnderMouse) m_fileInputElementUnderMouse->setCanReceiveDroppedFiles(false); m_fileInputElementUnderMouse = elementAsFileInput; } if (!m_fileInputElementUnderMouse) m_page->dragCaretController()->setCaretPosition(m_documentUnderMouse->frame()->visiblePositionForPoint(point)); Frame* innerFrame = element->document()->frame(); dragSession.operation = dragIsMove(innerFrame->selection(), dragData) ? DragOperationMove : DragOperationCopy; dragSession.mouseIsOverFileInput = m_fileInputElementUnderMouse; dragSession.numberOfItemsToBeAccepted = 0; unsigned numberOfFiles = dragData->numberOfFiles(); if (m_fileInputElementUnderMouse) { if (m_fileInputElementUnderMouse->disabled()) dragSession.numberOfItemsToBeAccepted = 0; else if (m_fileInputElementUnderMouse->multiple()) dragSession.numberOfItemsToBeAccepted = numberOfFiles; else if (numberOfFiles > 1) dragSession.numberOfItemsToBeAccepted = 0; else dragSession.numberOfItemsToBeAccepted = 1; if (!dragSession.numberOfItemsToBeAccepted) dragSession.operation = DragOperationNone; m_fileInputElementUnderMouse->setCanReceiveDroppedFiles(dragSession.numberOfItemsToBeAccepted); } else { // We are not over a file input element. The dragged item(s) will only // be loaded into the view the number of dragged items is 1. dragSession.numberOfItemsToBeAccepted = numberOfFiles != 1 ? 0 : 1; } return true; } // We are not over an editable region. Make sure we're clearing any prior drag cursor. m_page->dragCaretController()->clear(); if (m_fileInputElementUnderMouse) m_fileInputElementUnderMouse->setCanReceiveDroppedFiles(false); m_fileInputElementUnderMouse = 0; return false; }