| 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
|
|
|