| 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 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 85 #include "wtf/CurrentTime.h" | 85 #include "wtf/CurrentTime.h" |
| 86 #include "wtf/RefPtr.h" | 86 #include "wtf/RefPtr.h" |
| 87 #include <memory> | 87 #include <memory> |
| 88 | 88 |
| 89 #if OS(WIN) | 89 #if OS(WIN) |
| 90 #include <windows.h> | 90 #include <windows.h> |
| 91 #endif | 91 #endif |
| 92 | 92 |
| 93 namespace blink { | 93 namespace blink { |
| 94 | 94 |
| 95 namespace { |
| 96 |
| 97 DataTransfer* createDraggingDataTransfer(DataTransferAccessPolicy policy, DragDa
ta* dragData) |
| 98 { |
| 99 return DataTransfer::create(DataTransfer::DragAndDrop, policy, dragData->pla
tformData()); |
| 100 } |
| 101 |
| 102 enum class DragDropBeforeInputResult { |
| 103 None, |
| 104 DeleteOnly, |
| 105 InsertOnly, |
| 106 DeleteAndInsert, |
| 107 }; |
| 108 |
| 109 DragDropBeforeInputResult dispatchDragDropBeforeInput(Element* dragTarget, Eleme
nt* dropTarget, DragData* dragData, bool dragIsMove) |
| 110 { |
| 111 LocalFrame* dragFrame = dragTarget->document().frame(); |
| 112 LocalFrame* dropFrame = dropTarget->document().frame(); |
| 113 |
| 114 // Handle DeleteByDrag. |
| 115 bool shouldDelete = dragIsMove; |
| 116 if (shouldDelete) { |
| 117 DispatchEventResult dragBeforeInputResult = dispatchBeforeInputEditorCom
mand(dragTarget, InputEvent::InputType::DeleteByDrag, emptyString(), nullptr); |
| 118 shouldDelete = dragBeforeInputResult == DispatchEventResult::NotCanceled
; |
| 119 } |
| 120 |
| 121 // 'beforeinput' event handler may destroy frame. |
| 122 if (dragFrame != dragTarget->document().frame() || dropFrame != dropTarget->
document().frame()) |
| 123 return DragDropBeforeInputResult::None; |
| 124 |
| 125 // Handle InsertFromDrop. |
| 126 DataTransfer* dataTransfer = createDraggingDataTransfer(DataTransferReadable
, dragData); |
| 127 dataTransfer->setSourceOperation(dragData->draggingSourceOperationMask()); |
| 128 DispatchEventResult dropBeforeInputResult = dispatchBeforeInputDataTransfer(
dropTarget, InputEvent::InputType::InsertFromDrop, dataTransfer, nullptr); |
| 129 bool shouldInsert = dropBeforeInputResult == DispatchEventResult::NotCancele
d; |
| 130 |
| 131 // 'beforeinput' event handler may destroy frame. |
| 132 if (dragFrame != dragTarget->document().frame() || dropFrame != dropTarget->
document().frame()) |
| 133 return DragDropBeforeInputResult::None; |
| 134 |
| 135 // 'beforeinput' event handler may remove element from document, editing com
mands won't modify disconnected elements. |
| 136 shouldDelete = shouldDelete && dragTarget->isConnected(); |
| 137 shouldInsert = shouldInsert && dropTarget->isConnected(); |
| 138 |
| 139 // Generate dispatch result. |
| 140 if (shouldDelete && shouldInsert) |
| 141 return DragDropBeforeInputResult::DeleteAndInsert; |
| 142 if (shouldDelete) |
| 143 return DragDropBeforeInputResult::DeleteOnly; |
| 144 if (shouldInsert) |
| 145 return DragDropBeforeInputResult::InsertOnly; |
| 146 return DragDropBeforeInputResult::None; |
| 147 } |
| 148 |
| 149 } // anonymous namespace |
| 150 |
| 95 const int DragController::DragIconRightInset = 7; | 151 const int DragController::DragIconRightInset = 7; |
| 96 const int DragController::DragIconBottomInset = 3; | 152 const int DragController::DragIconBottomInset = 3; |
| 97 | 153 |
| 98 static const int MaxOriginalImageArea = 1500 * 1500; | 154 static const int MaxOriginalImageArea = 1500 * 1500; |
| 99 static const int LinkDragBorderInset = 2; | 155 static const int LinkDragBorderInset = 2; |
| 100 static const float DragImageAlpha = 0.75f; | 156 static const float DragImageAlpha = 0.75f; |
| 101 | 157 |
| 102 #if ENABLE(ASSERT) | 158 #if ENABLE(ASSERT) |
| 103 static bool dragTypeIsValid(DragSourceAction action) | 159 static bool dragTypeIsValid(DragSourceAction action) |
| 104 { | 160 { |
| (...skipping 12 matching lines...) Expand all Loading... |
| 117 #endif | 173 #endif |
| 118 | 174 |
| 119 static PlatformMouseEvent createMouseEvent(DragData* dragData) | 175 static PlatformMouseEvent createMouseEvent(DragData* dragData) |
| 120 { | 176 { |
| 121 return PlatformMouseEvent(dragData->clientPosition(), dragData->globalPositi
on(), | 177 return PlatformMouseEvent(dragData->clientPosition(), dragData->globalPositi
on(), |
| 122 WebPointerProperties::Button::Left, PlatformEvent::MouseMoved, 0, | 178 WebPointerProperties::Button::Left, PlatformEvent::MouseMoved, 0, |
| 123 static_cast<PlatformEvent::Modifiers>(dragData->modifiers()), | 179 static_cast<PlatformEvent::Modifiers>(dragData->modifiers()), |
| 124 PlatformMouseEvent::RealOrIndistinguishable, monotonicallyIncreasingTime
()); | 180 PlatformMouseEvent::RealOrIndistinguishable, monotonicallyIncreasingTime
()); |
| 125 } | 181 } |
| 126 | 182 |
| 127 static DataTransfer* createDraggingDataTransfer(DataTransferAccessPolicy policy,
DragData* dragData) | |
| 128 { | |
| 129 return DataTransfer::create(DataTransfer::DragAndDrop, policy, dragData->pla
tformData()); | |
| 130 } | |
| 131 | |
| 132 DragController::DragController(Page* page) | 183 DragController::DragController(Page* page) |
| 133 : m_page(page) | 184 : m_page(page) |
| 134 , m_documentUnderMouse(nullptr) | 185 , m_documentUnderMouse(nullptr) |
| 135 , m_dragInitiator(nullptr) | 186 , m_dragInitiator(nullptr) |
| 136 , m_fileInputElementUnderMouse(nullptr) | 187 , m_fileInputElementUnderMouse(nullptr) |
| 137 , m_documentIsHandlingDrag(false) | 188 , m_documentIsHandlingDrag(false) |
| 138 , m_dragDestinationAction(DragDestinationActionNone) | 189 , m_dragDestinationAction(DragDestinationActionNone) |
| 139 , m_didInitiateDrag(false) | 190 , m_didInitiateDrag(false) |
| 140 { | 191 { |
| 141 } | 192 } |
| (...skipping 354 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 496 return false; | 547 return false; |
| 497 } | 548 } |
| 498 Range* range = createRange(dragCaret.toNormalizedEphemeralRange()); | 549 Range* range = createRange(dragCaret.toNormalizedEphemeralRange()); |
| 499 Element* rootEditableElement = innerFrame->selection().rootEditableElement()
; | 550 Element* rootEditableElement = innerFrame->selection().rootEditableElement()
; |
| 500 | 551 |
| 501 // For range to be null a WebKit client must have done something bad while | 552 // For range to be null a WebKit client must have done something bad while |
| 502 // manually controlling drag behaviour | 553 // manually controlling drag behaviour |
| 503 if (!range) | 554 if (!range) |
| 504 return false; | 555 return false; |
| 505 ResourceFetcher* fetcher = range->ownerDocument().fetcher(); | 556 ResourceFetcher* fetcher = range->ownerDocument().fetcher(); |
| 506 ResourceCacheValidationSuppressor validationSuppressor(fetcher); | 557 ResourceCacheValidationSuppressor validationSuppressorr(fetcher); |
| 507 if (dragIsMove(innerFrame->selection(), dragData) || dragCaret.isContentRich
lyEditable()) { | 558 |
| 559 LocalFrame* frameUnderMouse = m_documentUnderMouse->frame(); |
| 560 DCHECK(frameUnderMouse); |
| 561 DragDropBeforeInputResult beforeInputResult = dispatchDragDropBeforeInput(in
nerFrame->editor().findEventTargetFromSelection(), element, dragData, dragIsMove
(innerFrame->selection(), dragData)); |
| 562 // 'beforeinput' handler may destroy frame. |
| 563 if (innerFrame->document()->frame() != innerFrame || m_documentUnderMouse->f
rame() != frameUnderMouse) |
| 564 return false; |
| 565 |
| 566 switch (beforeInputResult) { |
| 567 case DragDropBeforeInputResult::None: |
| 568 default: |
| 569 return true; |
| 570 |
| 571 case DragDropBeforeInputResult::DeleteOnly: |
| 572 innerFrame->editor().deleteSelectionWithSmartDelete(innerFrame->editor()
.smartInsertDeleteEnabled(), InputEvent::InputType::DeleteByDrag); |
| 573 break; |
| 574 |
| 575 case DragDropBeforeInputResult::InsertOnly: |
| 576 if (dragCaret.isContentRichlyEditable()) { |
| 577 bool chosePlainText = false; |
| 578 DocumentFragment* fragment = documentFragmentFromDragData(dragData,
innerFrame, range, true, chosePlainText); |
| 579 if (!fragment) |
| 580 return false; |
| 581 if (setSelectionToDragCaret(innerFrame, dragCaret, range, point)) { |
| 582 DCHECK(m_documentUnderMouse); |
| 583 m_documentUnderMouse->frame()->editor().replaceSelectionAfterDra
gging(fragment, dragData->canSmartReplace(), chosePlainText); |
| 584 } |
| 585 } else { |
| 586 String text = dragData->asPlainText(); |
| 587 if (text.isEmpty()) |
| 588 return false; |
| 589 |
| 590 if (setSelectionToDragCaret(innerFrame, dragCaret, range, point)) { |
| 591 const bool canSmartReplace = false; |
| 592 const bool chosePlainText = true; |
| 593 DCHECK(m_documentUnderMouse); |
| 594 m_documentUnderMouse->frame()->editor().replaceSelectionAfterDra
gging(createFragmentFromText(EphemeralRange(range), text), canSmartReplace, chos
ePlainText); |
| 595 } |
| 596 } |
| 597 break; |
| 598 |
| 599 case DragDropBeforeInputResult::DeleteAndInsert: |
| 508 bool chosePlainText = false; | 600 bool chosePlainText = false; |
| 509 DocumentFragment* fragment = documentFragmentFromDragData(dragData, inne
rFrame, range, true, chosePlainText); | 601 DocumentFragment* fragment = documentFragmentFromDragData(dragData, inne
rFrame, range, true, chosePlainText); |
| 510 if (!fragment) | 602 if (!fragment) |
| 511 return false; | 603 return false; |
| 512 | 604 // NSTextView behavior is to always smart delete on moving a selection, |
| 513 if (dragIsMove(innerFrame->selection(), dragData)) { | 605 // but only to smart insert if the selection granularity is word granula
rity. |
| 514 // NSTextView behavior is to always smart delete on moving a selecti
on, | 606 bool smartDelete = innerFrame->editor().smartInsertDeleteEnabled(); |
| 515 // but only to smart insert if the selection granularity is word gra
nularity. | 607 bool smartInsert = smartDelete && innerFrame->selection().granularity()
== WordGranularity && dragData->canSmartReplace(); |
| 516 bool smartDelete = innerFrame->editor().smartInsertDeleteEnabled(); | 608 innerFrame->editor().moveSelectionAfterDragging(fragment, dragCaret.base
(), smartInsert, smartDelete); |
| 517 bool smartInsert = smartDelete && innerFrame->selection().granularit
y() == WordGranularity && dragData->canSmartReplace(); | 609 break; |
| 518 innerFrame->editor().moveSelectionAfterDragging(fragment, dragCaret.
base(), smartInsert, smartDelete); | |
| 519 } else { | |
| 520 if (setSelectionToDragCaret(innerFrame, dragCaret, range, point)) { | |
| 521 ASSERT(m_documentUnderMouse); | |
| 522 m_documentUnderMouse->frame()->editor().replaceSelectionAfterDra
gging(fragment, dragData->canSmartReplace(), chosePlainText); | |
| 523 } | |
| 524 } | |
| 525 } else { | |
| 526 String text = dragData->asPlainText(); | |
| 527 if (text.isEmpty()) | |
| 528 return false; | |
| 529 | |
| 530 if (setSelectionToDragCaret(innerFrame, dragCaret, range, point)) { | |
| 531 const bool canSmartReplace = false; | |
| 532 const bool chosePlainText = true; | |
| 533 ASSERT(m_documentUnderMouse); | |
| 534 m_documentUnderMouse->frame()->editor().replaceSelectionAfterDraggin
g(createFragmentFromText(EphemeralRange(range), text), canSmartReplace, chosePla
inText); | |
| 535 } | |
| 536 } | 610 } |
| 537 | 611 |
| 538 if (rootEditableElement) { | 612 if (rootEditableElement) { |
| 539 if (LocalFrame* frame = rootEditableElement->document().frame()) | 613 if (LocalFrame* frame = rootEditableElement->document().frame()) |
| 540 frame->eventHandler().updateDragStateAfterEditDragIfNeeded(rootEdita
bleElement); | 614 frame->eventHandler().updateDragStateAfterEditDragIfNeeded(rootEdita
bleElement); |
| 541 } | 615 } |
| 542 | 616 |
| 543 return true; | 617 return true; |
| 544 } | 618 } |
| 545 | 619 |
| (...skipping 451 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 997 | 1071 |
| 998 DEFINE_TRACE(DragController) | 1072 DEFINE_TRACE(DragController) |
| 999 { | 1073 { |
| 1000 visitor->trace(m_page); | 1074 visitor->trace(m_page); |
| 1001 visitor->trace(m_documentUnderMouse); | 1075 visitor->trace(m_documentUnderMouse); |
| 1002 visitor->trace(m_dragInitiator); | 1076 visitor->trace(m_dragInitiator); |
| 1003 visitor->trace(m_fileInputElementUnderMouse); | 1077 visitor->trace(m_fileInputElementUnderMouse); |
| 1004 } | 1078 } |
| 1005 | 1079 |
| 1006 } // namespace blink | 1080 } // namespace blink |
| OLD | NEW |