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

Side by Side 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 unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « Source/core/page/DragController.h ('k') | Source/core/page/EventHandler.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2007, 2009, 2010 Apple Inc. All rights reserved. 2 * Copyright (C) 2007, 2009, 2010 Apple Inc. All rights reserved.
3 * Copyright (C) 2008 Google Inc. 3 * Copyright (C) 2008 Google Inc.
4 * 4 *
5 * Redistribution and use in source and binary forms, with or without 5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions 6 * modification, are permitted provided that the following conditions
7 * are met: 7 * are met:
8 * 1. Redistributions of source code must retain the above copyright 8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer. 9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright 10 * 2. Redistributions in binary form must reproduce the above copyright
(...skipping 602 matching lines...) Expand 10 before | Expand all | Expand 10 after
613 operation = defaultOperationForDrag(srcOpMask); 613 operation = defaultOperationForDrag(srcOpMask);
614 else if (!(srcOpMask & operation)) { 614 else if (!(srcOpMask & operation)) {
615 // The element picked an operation which is not supported by the source 615 // The element picked an operation which is not supported by the source
616 operation = DragOperationNone; 616 operation = DragOperationNone;
617 } 617 }
618 618
619 clipboard->setAccessPolicy(ClipboardNumb); // invalidate clipboard here f or security 619 clipboard->setAccessPolicy(ClipboardNumb); // invalidate clipboard here f or security
620 return true; 620 return true;
621 } 621 }
622 622
623 Node* DragController::draggableNode(const Frame* src, Node* startNode, const Int Point& dragOrigin, DragState& state) const 623 Node* DragController::draggableNode(const Frame* src, Node* startNode, const Int Point& dragOrigin, SelectionDragPolicy selectionDragPolicy, DragSourceAction& dr agType) const
624 { 624 {
625 state.m_dragType = (src->selection().contains(dragOrigin)) ? DragSourceActio nSelection : DragSourceActionNone; 625 if (src->selection().contains(dragOrigin)) {
626 dragType = DragSourceActionSelection;
627 if (selectionDragPolicy == ImmediateSelectionDragResolution)
628 return startNode;
629 } else {
630 dragType = DragSourceActionNone;
631 }
626 632
633 Node* node = 0;
634 DragSourceAction candidateDragType = DragSourceActionNone;
627 for (const RenderObject* renderer = startNode->renderer(); renderer; rendere r = renderer->parent()) { 635 for (const RenderObject* renderer = startNode->renderer(); renderer; rendere r = renderer->parent()) {
628 Node* node = renderer->nonPseudoNode(); 636 node = renderer->nonPseudoNode();
629 if (!node) 637 if (!node) {
630 // Anonymous render blocks don't correspond to actual DOM nodes, so we skip over them 638 // Anonymous render blocks don't correspond to actual DOM nodes, so we skip over them
631 // for the purposes of finding a draggable node. 639 // for the purposes of finding a draggable node.
632 continue; 640 continue;
633 if (!(state.m_dragType & DragSourceActionSelection) && node->isTextNode( ) && node->canStartSelection()) 641 }
642 if (dragType != DragSourceActionSelection && node->isTextNode() && node- >canStartSelection()) {
634 // In this case we have a click in the unselected portion of text. I f this text is 643 // In this case we have a click in the unselected portion of text. I f this text is
635 // selectable, we want to start the selection process instead of loo king for a parent 644 // selectable, we want to start the selection process instead of loo king for a parent
636 // to try to drag. 645 // to try to drag.
637 return 0; 646 return 0;
647 }
638 if (node->isElementNode()) { 648 if (node->isElementNode()) {
639 EUserDrag dragMode = renderer->style()->userDrag(); 649 EUserDrag dragMode = renderer->style()->userDrag();
640 if (dragMode == DRAG_NONE) 650 if (dragMode == DRAG_NONE)
641 continue; 651 continue;
652 // Even if the image is part of a selection, we always only drag the image in this case.
642 if (renderer->isImage() 653 if (renderer->isImage()
643 && src->settings() 654 && src->settings()
644 && src->settings()->loadsImagesAutomatically()) { 655 && src->settings()->loadsImagesAutomatically()) {
645 state.m_dragType = static_cast<DragSourceAction>(state.m_dragTyp e | DragSourceActionImage); 656 dragType = DragSourceActionImage;
646 return node; 657 return node;
647 } 658 }
659 // Other draggable elements are considered unselectable.
648 if (isHTMLAnchorElement(node) 660 if (isHTMLAnchorElement(node)
649 && toHTMLAnchorElement(node)->isLiveLink()) { 661 && toHTMLAnchorElement(node)->isLiveLink()) {
650 state.m_dragType = static_cast<DragSourceAction>(state.m_dragTyp e | DragSourceActionLink); 662 candidateDragType = DragSourceActionLink;
651 return node; 663 break;
652 } 664 }
653 if (dragMode == DRAG_ELEMENT) { 665 if (dragMode == DRAG_ELEMENT) {
654 state.m_dragType = static_cast<DragSourceAction>(state.m_dragTyp e | DragSourceActionDHTML); 666 candidateDragType = DragSourceActionDHTML;
655 return node; 667 break;
656 } 668 }
657 } 669 }
658 } 670 }
659 671
660 // We either have nothing to drag or we have a selection and we're not over a draggable element. 672 if (candidateDragType == DragSourceActionNone) {
661 return (state.m_dragType & DragSourceActionSelection) ? startNode : 0; 673 // Either:
674 // 1) Nothing under the cursor is considered draggable, so we bail out.
675 // 2) There was a selection under the cursor but selectionDragPolicy is set to
676 // DelayedSelectionDragResolution and no other draggable element coul d be found, so bail
677 // out and allow text selection to start at the cursor instead.
678 return 0;
679 }
680
681 ASSERT(node);
682 if (dragType == DragSourceActionSelection) {
683 // Dragging unselectable elements in a selection has special behavior if selectionDragPolicy
684 // is DelayedSelectionDragResolution and this drag was flagged as a pote ntial selection
685 // drag. In that case, don't allow selection and just drag the entire se lection instead.
686 ASSERT(selectionDragPolicy == DelayedSelectionDragResolution);
687 node = startNode;
688 } else {
689 // If the cursor isn't over a selection, then just drag the node we foun d earlier.
690 ASSERT(dragType == DragSourceActionNone);
691 dragType = candidateDragType;
692 }
693 return node;
662 } 694 }
663 695
664 static ImageResource* getImageResource(Element* element) 696 static ImageResource* getImageResource(Element* element)
665 { 697 {
666 ASSERT(element); 698 ASSERT(element);
667 RenderObject* renderer = element->renderer(); 699 RenderObject* renderer = element->renderer();
668 if (!renderer || !renderer->isImage()) 700 if (!renderer || !renderer->isImage())
669 return 0; 701 return 0;
670 RenderImage* image = toRenderImage(renderer); 702 RenderImage* image = toRenderImage(renderer);
671 return image->cachedImage(); 703 return image->cachedImage();
(...skipping 20 matching lines...) Expand all
692 clipboard->declareAndWriteDragImage(node, !linkURL.isEmpty() ? linkURL : ima geURL, label); 724 clipboard->declareAndWriteDragImage(node, !linkURL.isEmpty() ? linkURL : ima geURL, label);
693 } 725 }
694 726
695 bool DragController::populateDragClipboard(Frame* src, const DragState& state, c onst IntPoint& dragOrigin) 727 bool DragController::populateDragClipboard(Frame* src, const DragState& state, c onst IntPoint& dragOrigin)
696 { 728 {
697 ASSERT(dragTypeIsValid(state.m_dragType)); 729 ASSERT(dragTypeIsValid(state.m_dragType));
698 ASSERT(src); 730 ASSERT(src);
699 if (!src->view() || !src->contentRenderer()) 731 if (!src->view() || !src->contentRenderer())
700 return false; 732 return false;
701 733
702 HitTestResult hitTestResult = src->eventHandler().hitTestResultAtPoint(dragO rigin, HitTestRequest::ReadOnly | HitTestRequest::Active); 734 HitTestResult hitTestResult = src->eventHandler().hitTestResultAtPoint(dragO rigin);
703 // FIXME: Can this even happen? I guess it's possible, but should verify 735 // FIXME: Can this even happen? I guess it's possible, but should verify
704 // with a layout test. 736 // with a layout test.
705 if (!state.m_dragSrc->contains(hitTestResult.innerNode())) { 737 if (!state.m_dragSrc->contains(hitTestResult.innerNode())) {
706 // The original node being dragged isn't under the drag origin anymore.. . maybe it was 738 // The original node being dragged isn't under the drag origin anymore.. . maybe it was
707 // hidden or moved out from under the cursor. Regardless, we don't want to start a drag on 739 // hidden or moved out from under the cursor. Regardless, we don't want to start a drag on
708 // something that's not actually under the drag origin. 740 // something that's not actually under the drag origin.
709 return false; 741 return false;
710 } 742 }
711 const KURL& linkURL = hitTestResult.absoluteLinkURL(); 743 const KURL& linkURL = hitTestResult.absoluteLinkURL();
712 const KURL& imageURL = hitTestResult.absoluteImageURL(); 744 const KURL& imageURL = hitTestResult.absoluteImageURL();
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after
813 } 845 }
814 846
815 bool DragController::startDrag(Frame* src, const DragState& state, const Platfor mMouseEvent& dragEvent, const IntPoint& dragOrigin) 847 bool DragController::startDrag(Frame* src, const DragState& state, const Platfor mMouseEvent& dragEvent, const IntPoint& dragOrigin)
816 { 848 {
817 ASSERT(dragTypeIsValid(state.m_dragType)); 849 ASSERT(dragTypeIsValid(state.m_dragType));
818 ASSERT(src); 850 ASSERT(src);
819 if (!src->view() || !src->contentRenderer()) 851 if (!src->view() || !src->contentRenderer())
820 return false; 852 return false;
821 853
822 HitTestResult hitTestResult = src->eventHandler().hitTestResultAtPoint(dragO rigin); 854 HitTestResult hitTestResult = src->eventHandler().hitTestResultAtPoint(dragO rigin);
823 if (!state.m_dragSrc->contains(hitTestResult.innerNode())) 855 if (!state.m_dragSrc->contains(hitTestResult.innerNode())) {
824 // The original node being dragged isn't under the drag origin anymore.. . maybe it was 856 // The original node being dragged isn't under the drag origin anymore.. . maybe it was
825 // hidden or moved out from under the cursor. Regardless, we don't want to start a drag on 857 // hidden or moved out from under the cursor. Regardless, we don't want to start a drag on
826 // something that's not actually under the drag origin. 858 // something that's not actually under the drag origin.
827 return false; 859 return false;
860 }
828 const KURL& linkURL = hitTestResult.absoluteLinkURL(); 861 const KURL& linkURL = hitTestResult.absoluteLinkURL();
829 const KURL& imageURL = hitTestResult.absoluteImageURL(); 862 const KURL& imageURL = hitTestResult.absoluteImageURL();
830 863
831 IntPoint mouseDraggedPoint = src->view()->windowToContents(dragEvent.positio n()); 864 IntPoint mouseDraggedPoint = src->view()->windowToContents(dragEvent.positio n());
832 865
833 IntPoint dragLocation; 866 IntPoint dragLocation;
834 IntPoint dragOffset; 867 IntPoint dragOffset;
835 868
836 Clipboard* clipboard = state.m_dragClipboard.get(); 869 Clipboard* clipboard = state.m_dragClipboard.get();
837 // We allow DHTML/JS to set the drag image, even if its a link, image or tex t we're dragging. 870 // We allow DHTML/JS to set the drag image, even if its a link, image or tex t we're dragging.
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after
928 return false; 961 return false;
929 #endif 962 #endif
930 } 963 }
931 964
932 void DragController::cleanupAfterSystemDrag() 965 void DragController::cleanupAfterSystemDrag()
933 { 966 {
934 } 967 }
935 968
936 } // namespace WebCore 969 } // namespace WebCore
937 970
OLDNEW
« 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