| OLD | NEW |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 |
| OLD | NEW |