Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1018)

Unified Diff: Source/core/page/DragController.cpp

Issue 50433002: Fix dragging text inside a input element nested in a draggable element. (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Better names and comments Created 7 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « Source/core/page/DragController.h ('k') | Source/core/page/EventHandler.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: Source/core/page/DragController.cpp
diff --git a/Source/core/page/DragController.cpp b/Source/core/page/DragController.cpp
index 3dc03d21ba91ea2e7244b7eee0649b39065a37fd..8e0b8c7b3045e8595b62221de001df3998a1b596 100644
--- a/Source/core/page/DragController.cpp
+++ b/Source/core/page/DragController.cpp
@@ -620,45 +620,77 @@ bool DragController::tryDHTMLDrag(DragData* dragData, DragOperation& operation)
return true;
}
-Node* DragController::draggableNode(const Frame* src, Node* startNode, const IntPoint& dragOrigin, DragState& state) const
+Node* DragController::draggableNode(const Frame* src, Node* startNode, const IntPoint& dragOrigin, SelectionDragPolicy selectionDragPolicy, DragSourceAction& dragType) const
{
- state.m_dragType = (src->selection().contains(dragOrigin)) ? DragSourceActionSelection : DragSourceActionNone;
+ if (src->selection().contains(dragOrigin)) {
+ dragType = DragSourceActionSelection;
+ if (selectionDragPolicy == ImmediateSelectionDragResolution)
+ return startNode;
+ } else {
+ dragType = DragSourceActionNone;
+ }
+ Node* node = 0;
+ DragSourceAction candidateDragType = DragSourceActionNone;
for (const RenderObject* renderer = startNode->renderer(); renderer; renderer = renderer->parent()) {
- Node* node = renderer->nonPseudoNode();
- if (!node)
+ node = renderer->nonPseudoNode();
+ if (!node) {
// Anonymous render blocks don't correspond to actual DOM nodes, so we skip over them
// for the purposes of finding a draggable node.
continue;
- if (!(state.m_dragType & DragSourceActionSelection) && node->isTextNode() && node->canStartSelection())
+ }
+ if (dragType != DragSourceActionSelection && node->isTextNode() && node->canStartSelection()) {
// In this case we have a click in the unselected portion of text. If this text is
// selectable, we want to start the selection process instead of looking for a parent
// to try to drag.
return 0;
+ }
if (node->isElementNode()) {
EUserDrag dragMode = renderer->style()->userDrag();
if (dragMode == DRAG_NONE)
continue;
+ // Even if the image is part of a selection, we always only drag the image in this case.
if (renderer->isImage()
&& src->settings()
&& src->settings()->loadsImagesAutomatically()) {
- state.m_dragType = static_cast<DragSourceAction>(state.m_dragType | DragSourceActionImage);
+ dragType = DragSourceActionImage;
return node;
}
+ // Other draggable elements are considered unselectable.
if (isHTMLAnchorElement(node)
&& toHTMLAnchorElement(node)->isLiveLink()) {
- state.m_dragType = static_cast<DragSourceAction>(state.m_dragType | DragSourceActionLink);
- return node;
+ candidateDragType = DragSourceActionLink;
+ break;
}
if (dragMode == DRAG_ELEMENT) {
- state.m_dragType = static_cast<DragSourceAction>(state.m_dragType | DragSourceActionDHTML);
- return node;
+ candidateDragType = DragSourceActionDHTML;
+ break;
}
}
}
- // We either have nothing to drag or we have a selection and we're not over a draggable element.
- return (state.m_dragType & DragSourceActionSelection) ? startNode : 0;
+ if (candidateDragType == DragSourceActionNone) {
+ // Either:
+ // 1) Nothing under the cursor is considered draggable, so we bail out.
+ // 2) There was a selection under the cursor but selectionDragPolicy is set to
+ // DelayedSelectionDragResolution and no other draggable element could be found, so bail
+ // out and allow text selection to start at the cursor instead.
+ return 0;
+ }
+
+ ASSERT(node);
+ if (dragType == DragSourceActionSelection) {
+ // Dragging unselectable elements in a selection has special behavior if selectionDragPolicy
+ // is DelayedSelectionDragResolution and this drag was flagged as a potential selection
+ // drag. In that case, don't allow selection and just drag the entire selection instead.
+ ASSERT(selectionDragPolicy == DelayedSelectionDragResolution);
+ node = startNode;
+ } else {
+ // If the cursor isn't over a selection, then just drag the node we found earlier.
+ ASSERT(dragType == DragSourceActionNone);
+ dragType = candidateDragType;
+ }
+ return node;
}
static ImageResource* getImageResource(Element* element)
@@ -699,7 +731,7 @@ bool DragController::populateDragClipboard(Frame* src, const DragState& state, c
if (!src->view() || !src->contentRenderer())
return false;
- HitTestResult hitTestResult = src->eventHandler().hitTestResultAtPoint(dragOrigin, HitTestRequest::ReadOnly | HitTestRequest::Active);
+ HitTestResult hitTestResult = src->eventHandler().hitTestResultAtPoint(dragOrigin);
// FIXME: Can this even happen? I guess it's possible, but should verify
// with a layout test.
if (!state.m_dragSrc->contains(hitTestResult.innerNode())) {
@@ -820,11 +852,12 @@ bool DragController::startDrag(Frame* src, const DragState& state, const Platfor
return false;
HitTestResult hitTestResult = src->eventHandler().hitTestResultAtPoint(dragOrigin);
- if (!state.m_dragSrc->contains(hitTestResult.innerNode()))
+ if (!state.m_dragSrc->contains(hitTestResult.innerNode())) {
// The original node being dragged isn't under the drag origin anymore... maybe it was
// hidden or moved out from under the cursor. Regardless, we don't want to start a drag on
// something that's not actually under the drag origin.
return false;
+ }
const KURL& linkURL = hitTestResult.absoluteLinkURL();
const KURL& imageURL = hitTestResult.absoluteImageURL();
« no previous file with comments | « Source/core/page/DragController.h ('k') | Source/core/page/EventHandler.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698