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

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

Issue 2288913002: [InputEvent] Support |deleteByDrag| and |insertFromDrop| (Closed)
Patch Set: yosin's review 3, check |ownerDocument()| Created 4 years, 3 months 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 | « third_party/WebKit/Source/core/events/InputEvent.cpp ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: third_party/WebKit/Source/core/page/DragController.cpp
diff --git a/third_party/WebKit/Source/core/page/DragController.cpp b/third_party/WebKit/Source/core/page/DragController.cpp
index c0a684f1d686859f59777949014ff1a06ba3a310..00a0bdab28d5abe61a88db14636e5f997feb49c2 100644
--- a/third_party/WebKit/Source/core/page/DragController.cpp
+++ b/third_party/WebKit/Source/core/page/DragController.cpp
@@ -92,6 +92,62 @@
namespace blink {
+namespace {
+
+DataTransfer* createDraggingDataTransfer(DataTransferAccessPolicy policy, DragData* dragData)
+{
+ return DataTransfer::create(DataTransfer::DragAndDrop, policy, dragData->platformData());
+}
+
+enum class DragDropBeforeInputResult {
+ None,
+ DeleteOnly,
+ InsertOnly,
+ DeleteAndInsert,
+};
+
+DragDropBeforeInputResult dispatchDragDropBeforeInput(Element* dragTarget, Element* dropTarget, DragData* dragData, bool dragIsMove)
+{
+ LocalFrame* dragFrame = dragTarget->document().frame();
+ LocalFrame* dropFrame = dropTarget->document().frame();
+
+ // Handle DeleteByDrag.
+ bool shouldDelete = dragIsMove;
+ if (shouldDelete) {
+ DispatchEventResult dragBeforeInputResult = dispatchBeforeInputEditorCommand(dragTarget, InputEvent::InputType::DeleteByDrag, emptyString(), nullptr);
+ shouldDelete = dragBeforeInputResult == DispatchEventResult::NotCanceled;
+ }
+
+ // 'beforeinput' event handler may destroy frame.
+ if (dragFrame != dragTarget->document().frame() || dropFrame != dropTarget->document().frame())
+ return DragDropBeforeInputResult::None;
+
+ // Handle InsertFromDrop.
+ DataTransfer* dataTransfer = createDraggingDataTransfer(DataTransferReadable, dragData);
+ dataTransfer->setSourceOperation(dragData->draggingSourceOperationMask());
+ DispatchEventResult dropBeforeInputResult = dispatchBeforeInputDataTransfer(dropTarget, InputEvent::InputType::InsertFromDrop, dataTransfer, nullptr);
+ bool shouldInsert = dropBeforeInputResult == DispatchEventResult::NotCanceled;
+
+ // 'beforeinput' event handler may destroy frame.
+ if (dragFrame != dragTarget->document().frame() || dropFrame != dropTarget->document().frame())
+ return DragDropBeforeInputResult::None;
+
+ // 'beforeinput' event handler may remove element from document, editing commands won't modify disconnected elements.
+ shouldDelete = shouldDelete && dragTarget->isConnected();
+ shouldInsert = shouldInsert && dropTarget->isConnected();
+
+ // Generate dispatch result.
+ if (shouldDelete && shouldInsert)
+ return DragDropBeforeInputResult::DeleteAndInsert;
+ if (shouldDelete)
+ return DragDropBeforeInputResult::DeleteOnly;
+ if (shouldInsert)
+ return DragDropBeforeInputResult::InsertOnly;
+ return DragDropBeforeInputResult::None;
+}
+
+} // anonymous namespace
+
const int DragController::DragIconRightInset = 7;
const int DragController::DragIconBottomInset = 3;
@@ -124,11 +180,6 @@ static PlatformMouseEvent createMouseEvent(DragData* dragData)
PlatformMouseEvent::RealOrIndistinguishable, monotonicallyIncreasingTime());
}
-static DataTransfer* createDraggingDataTransfer(DataTransferAccessPolicy policy, DragData* dragData)
-{
- return DataTransfer::create(DataTransfer::DragAndDrop, policy, dragData->platformData());
-}
-
DragController::DragController(Page* page)
: m_page(page)
, m_documentUnderMouse(nullptr)
@@ -503,36 +554,59 @@ bool DragController::concludeEditDrag(DragData* dragData)
if (!range)
return false;
ResourceFetcher* fetcher = range->ownerDocument().fetcher();
- ResourceCacheValidationSuppressor validationSuppressor(fetcher);
- if (dragIsMove(innerFrame->selection(), dragData) || dragCaret.isContentRichlyEditable()) {
- bool chosePlainText = false;
- DocumentFragment* fragment = documentFragmentFromDragData(dragData, innerFrame, range, true, chosePlainText);
- if (!fragment)
- return false;
+ ResourceCacheValidationSuppressor validationSuppressorr(fetcher);
- if (dragIsMove(innerFrame->selection(), dragData)) {
- // NSTextView behavior is to always smart delete on moving a selection,
- // but only to smart insert if the selection granularity is word granularity.
- bool smartDelete = innerFrame->editor().smartInsertDeleteEnabled();
- bool smartInsert = smartDelete && innerFrame->selection().granularity() == WordGranularity && dragData->canSmartReplace();
- innerFrame->editor().moveSelectionAfterDragging(fragment, dragCaret.base(), smartInsert, smartDelete);
- } else {
+ LocalFrame* frameUnderMouse = m_documentUnderMouse->frame();
+ DCHECK(frameUnderMouse);
+ DragDropBeforeInputResult beforeInputResult = dispatchDragDropBeforeInput(innerFrame->editor().findEventTargetFromSelection(), element, dragData, dragIsMove(innerFrame->selection(), dragData));
+ // 'beforeinput' handler may destroy frame.
+ if (innerFrame->document()->frame() != innerFrame || m_documentUnderMouse->frame() != frameUnderMouse)
+ return false;
+
+ switch (beforeInputResult) {
+ case DragDropBeforeInputResult::None:
+ default:
+ return true;
+
+ case DragDropBeforeInputResult::DeleteOnly:
+ innerFrame->editor().deleteSelectionWithSmartDelete(innerFrame->editor().smartInsertDeleteEnabled(), InputEvent::InputType::DeleteByDrag);
+ break;
+
+ case DragDropBeforeInputResult::InsertOnly:
+ if (dragCaret.isContentRichlyEditable()) {
+ bool chosePlainText = false;
+ DocumentFragment* fragment = documentFragmentFromDragData(dragData, innerFrame, range, true, chosePlainText);
+ if (!fragment)
+ return false;
if (setSelectionToDragCaret(innerFrame, dragCaret, range, point)) {
- ASSERT(m_documentUnderMouse);
+ DCHECK(m_documentUnderMouse);
m_documentUnderMouse->frame()->editor().replaceSelectionAfterDragging(fragment, dragData->canSmartReplace(), chosePlainText);
}
- }
- } else {
- String text = dragData->asPlainText();
- if (text.isEmpty())
- return false;
+ } else {
+ String text = dragData->asPlainText();
+ if (text.isEmpty())
+ return false;
- if (setSelectionToDragCaret(innerFrame, dragCaret, range, point)) {
- const bool canSmartReplace = false;
- const bool chosePlainText = true;
- ASSERT(m_documentUnderMouse);
- m_documentUnderMouse->frame()->editor().replaceSelectionAfterDragging(createFragmentFromText(EphemeralRange(range), text), canSmartReplace, chosePlainText);
+ if (setSelectionToDragCaret(innerFrame, dragCaret, range, point)) {
+ const bool canSmartReplace = false;
+ const bool chosePlainText = true;
+ DCHECK(m_documentUnderMouse);
+ m_documentUnderMouse->frame()->editor().replaceSelectionAfterDragging(createFragmentFromText(EphemeralRange(range), text), canSmartReplace, chosePlainText);
+ }
}
+ break;
+
+ case DragDropBeforeInputResult::DeleteAndInsert:
+ bool chosePlainText = false;
+ DocumentFragment* fragment = documentFragmentFromDragData(dragData, innerFrame, range, true, chosePlainText);
+ if (!fragment)
+ return false;
+ // NSTextView behavior is to always smart delete on moving a selection,
+ // but only to smart insert if the selection granularity is word granularity.
+ bool smartDelete = innerFrame->editor().smartInsertDeleteEnabled();
+ bool smartInsert = smartDelete && innerFrame->selection().granularity() == WordGranularity && dragData->canSmartReplace();
+ innerFrame->editor().moveSelectionAfterDragging(fragment, dragCaret.base(), smartInsert, smartDelete);
+ break;
}
if (rootEditableElement) {
« no previous file with comments | « third_party/WebKit/Source/core/events/InputEvent.cpp ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698