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 |