Index: third_party/WebKit/Source/core/editing/Editor.cpp |
diff --git a/third_party/WebKit/Source/core/editing/Editor.cpp b/third_party/WebKit/Source/core/editing/Editor.cpp |
index fb4d38efb0921a32a6cbb6442e0da96eb1549ef5..2d30326c1e590b217b0a4b476bbd06f1117c5b5f 100644 |
--- a/third_party/WebKit/Source/core/editing/Editor.cpp |
+++ b/third_party/WebKit/Source/core/editing/Editor.cpp |
@@ -81,6 +81,7 @@ |
#include "core/layout/HitTestResult.h" |
#include "core/layout/LayoutImage.h" |
#include "core/loader/EmptyClients.h" |
+#include "core/page/DragData.h" |
#include "core/page/EditorClient.h" |
#include "core/page/FocusController.h" |
#include "core/page/Page.h" |
@@ -348,7 +349,7 @@ bool Editor::deleteWithDirection(DeleteDirection direction, TextGranularity gran |
return true; |
} |
-void Editor::deleteSelectionWithSmartDelete(bool smartDelete, InputEvent::InputType inputType) |
+void Editor::deleteSelectionWithSmartDelete(bool smartDelete, InputEvent::InputType inputType, const Position& referenceMovePosition) |
{ |
if (frame().selection().isNone()) |
return; |
@@ -357,7 +358,7 @@ void Editor::deleteSelectionWithSmartDelete(bool smartDelete, InputEvent::InputT |
const bool kExpandForSpecialElements = false; |
const bool kSanitizeMarkup = true; |
DCHECK(frame().document()); |
- DeleteSelectionCommand::create(*frame().document(), smartDelete, kMergeBlocksAfterDelete, kExpandForSpecialElements, kSanitizeMarkup, inputType)->apply(); |
+ DeleteSelectionCommand::create(*frame().document(), smartDelete, kMergeBlocksAfterDelete, kExpandForSpecialElements, kSanitizeMarkup, inputType, referenceMovePosition)->apply(); |
} |
void Editor::pasteAsPlainText(const String& pastingText, bool smartReplace) |
@@ -551,12 +552,45 @@ void Editor::replaceSelectionAfterDragging(DocumentFragment* fragment, bool smar |
if (plainText) |
options |= ReplaceSelectionCommand::MatchStyle; |
DCHECK(frame().document()); |
- ReplaceSelectionCommand::create(*frame().document(), fragment, options, InputEvent::InputType::Drag)->apply(); |
+ ReplaceSelectionCommand::create(*frame().document(), fragment, options, InputEvent::InputType::InsertFromDrop)->apply(); |
} |
-void Editor::moveSelectionAfterDragging(DocumentFragment* fragment, const Position& pos, bool smartInsert, bool smartDelete) |
+bool Editor::deleteSelectionAfterDraggingWithEvents(Element* dragSource, SmartDelete smartDelete, const Position& referenceMovePosition) |
{ |
- MoveSelectionCommand::create(fragment, pos, smartInsert, smartDelete)->apply(); |
+ if (!dragSource || !dragSource->isConnected()) |
+ return true; |
+ |
+ // Dispatch 'beforeinput'. |
+ const bool shouldDelete = dispatchBeforeInputEditorCommand(dragSource, InputEvent::InputType::DeleteByDrag, nullptr) == DispatchEventResult::NotCanceled; |
+ |
+ // 'beforeinput' event handler may destroy frame, return false to cancel remaining actions; |
+ if (m_frame->document()->frame() != m_frame) |
+ return false; |
+ |
+ if (shouldDelete && dragSource->isConnected()) |
+ deleteSelectionWithSmartDelete(smartDelete == SmartDelete::Yes, InputEvent::InputType::DeleteByDrag, referenceMovePosition); |
+ |
+ return true; |
+} |
+ |
+bool Editor::replaceSelectionAfterDraggingWithEvents(Element* dropTarget, DragData* dragData, DocumentFragment* fragment, Range* dropCaretRange, SmartInsert smartInsert, ChosePlainText chosePlainText) |
+{ |
+ if (!dropTarget || !dropTarget->isConnected()) |
+ return true; |
+ |
+ // Dispatch 'beforeinput'. |
+ DataTransfer* dataTransfer = DataTransfer::create(DataTransfer::DragAndDrop, DataTransferReadable, dragData->platformData()); |
+ dataTransfer->setSourceOperation(dragData->draggingSourceOperationMask()); |
+ const bool shouldInsert = dispatchBeforeInputDataTransfer(dropTarget, InputEvent::InputType::InsertFromDrop, dataTransfer, nullptr) == DispatchEventResult::NotCanceled; |
+ |
+ // 'beforeinput' event handler may destroy frame, return false to cancel remaining actions; |
+ if (m_frame->document()->frame() != m_frame) |
+ return false; |
+ |
+ if (shouldInsert && dropTarget->isConnected()) |
+ replaceSelectionAfterDragging(fragment, smartInsert == SmartInsert::Yes, chosePlainText == ChosePlainText::Yes); |
+ |
+ return true; |
} |
EphemeralRange Editor::selectedRange() |
@@ -601,6 +635,12 @@ void Editor::removeFormattingAndStyle() |
RemoveFormatCommand::create(*frame().document())->apply(); |
} |
+void Editor::registerCommandGroup(CompositeEditCommand* commandGroupWrapper) |
+{ |
+ DCHECK(commandGroupWrapper->isCommandGroupWrapper()); |
+ m_lastEditCommand = commandGroupWrapper; |
+} |
+ |
void Editor::clearLastEditCommand() |
{ |
m_lastEditCommand.clear(); |
@@ -697,6 +737,7 @@ static void dispatchEditableContentChangedEvents(Element* startRoot, Element* en |
void Editor::appliedEditing(CompositeEditCommand* cmd) |
{ |
+ DCHECK(!cmd->isCommandGroupWrapper()); |
EventQueueScope scope; |
frame().document()->updateStyleAndLayout(); |
@@ -719,6 +760,11 @@ void Editor::appliedEditing(CompositeEditCommand* cmd) |
// Command will be equal to last edit command only in the case of typing |
if (m_lastEditCommand.get() == cmd) { |
DCHECK(cmd->isTypingCommand()); |
+ } else if (m_lastEditCommand && m_lastEditCommand->isDragAndDropCommand() && (cmd->inputType() == InputEvent::InputType::DeleteByDrag || cmd->inputType() == InputEvent::InputType::InsertFromDrop)) { |
+ // Only register undo entry when combined with other commands. |
+ if (!m_lastEditCommand->composition()) |
+ m_undoStack->registerUndoStep(m_lastEditCommand->ensureComposition()); |
+ m_lastEditCommand->appendCommandToComposite(cmd); |
} else { |
// Only register a new undo command if the command passed in is |
// different from the last command |