| 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 b47f4549d04ffe0838ec485231446e109ae099e6..176f2a26a6a5f67f1c768d941acf91f66e2c5214 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"
|
| @@ -328,7 +329,7 @@ bool Editor::deleteWithDirection(DeleteDirection direction,
|
| if (killRing)
|
| addToKillRing(selectedRange());
|
| deleteSelectionWithSmartDelete(
|
| - canSmartCopyOrDelete(),
|
| + canSmartCopyOrDelete() ? DeleteMode::Smart : DeleteMode::Simple,
|
| deletionInputTypeFromTextGranularity(direction, granularity));
|
| // Implicitly calls revealSelectionAfterEditingOperation().
|
| }
|
| @@ -364,8 +365,10 @@ bool Editor::deleteWithDirection(DeleteDirection direction,
|
| return true;
|
| }
|
|
|
| -void Editor::deleteSelectionWithSmartDelete(bool smartDelete,
|
| - InputEvent::InputType inputType) {
|
| +void Editor::deleteSelectionWithSmartDelete(
|
| + DeleteMode deleteMode,
|
| + InputEvent::InputType inputType,
|
| + const Position& referenceMovePosition) {
|
| if (frame().selection().isNone())
|
| return;
|
|
|
| @@ -374,8 +377,9 @@ void Editor::deleteSelectionWithSmartDelete(bool smartDelete,
|
| const bool kSanitizeMarkup = true;
|
| DCHECK(frame().document());
|
| DeleteSelectionCommand::create(
|
| - *frame().document(), smartDelete, kMergeBlocksAfterDelete,
|
| - kExpandForSpecialElements, kSanitizeMarkup, inputType)
|
| + *frame().document(), deleteMode == DeleteMode::Smart,
|
| + kMergeBlocksAfterDelete, kExpandForSpecialElements, kSanitizeMarkup,
|
| + inputType, referenceMovePosition)
|
| ->apply();
|
| }
|
|
|
| @@ -579,27 +583,73 @@ void Editor::replaceSelectionWithText(const String& text,
|
|
|
| // TODO(xiaochengh): Merge it with |replaceSelectionWithFragment()|.
|
| void Editor::replaceSelectionAfterDragging(DocumentFragment* fragment,
|
| - bool smartReplace,
|
| - bool plainText) {
|
| + InsertMode insertMode,
|
| + DragSourceType dragSourceType) {
|
| ReplaceSelectionCommand::CommandOptions options =
|
| ReplaceSelectionCommand::SelectReplacement |
|
| ReplaceSelectionCommand::PreventNesting;
|
| - if (smartReplace)
|
| + if (insertMode == InsertMode::Smart)
|
| options |= ReplaceSelectionCommand::SmartReplace;
|
| - if (plainText)
|
| + if (dragSourceType == DragSourceType::PlainTextSource)
|
| options |= ReplaceSelectionCommand::MatchStyle;
|
| DCHECK(frame().document());
|
| ReplaceSelectionCommand::create(*frame().document(), fragment, options,
|
| - InputEvent::InputType::Drag)
|
| + InputEvent::InputType::InsertFromDrop)
|
| ->apply();
|
| }
|
|
|
| -void Editor::moveSelectionAfterDragging(DocumentFragment* fragment,
|
| - const Position& pos,
|
| - bool smartInsert,
|
| - bool smartDelete) {
|
| - MoveSelectionCommand::create(fragment, pos, smartInsert, smartDelete)
|
| - ->apply();
|
| +bool Editor::deleteSelectionAfterDraggingWithEvents(
|
| + Element* dragSource,
|
| + DeleteMode deleteMode,
|
| + const Position& referenceMovePosition) {
|
| + 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(
|
| + deleteMode, InputEvent::InputType::DeleteByDrag, referenceMovePosition);
|
| + }
|
| +
|
| + return true;
|
| +}
|
| +
|
| +bool Editor::replaceSelectionAfterDraggingWithEvents(
|
| + Element* dropTarget,
|
| + DragData* dragData,
|
| + DocumentFragment* fragment,
|
| + Range* dropCaretRange,
|
| + InsertMode insertMode,
|
| + DragSourceType dragSourceType) {
|
| + 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, insertMode, dragSourceType);
|
| +
|
| + return true;
|
| }
|
|
|
| EphemeralRange Editor::selectedRange() {
|
| @@ -640,6 +690,11 @@ 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();
|
| }
|
| @@ -740,6 +795,7 @@ static void dispatchEditableContentChangedEvents(Element* startRoot,
|
| }
|
|
|
| void Editor::appliedEditing(CompositeEditCommand* cmd) {
|
| + DCHECK(!cmd->isCommandGroupWrapper());
|
| EventQueueScope scope;
|
| frame().document()->updateStyleAndLayout();
|
|
|
| @@ -767,6 +823,13 @@ 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
|
| @@ -961,8 +1024,9 @@ void Editor::cut(EditorCommandSource source) {
|
| if (m_frame->document()->frame() != m_frame)
|
| return;
|
| }
|
| - deleteSelectionWithSmartDelete(canSmartCopyOrDelete(),
|
| - InputEvent::InputType::DeleteByCut);
|
| + deleteSelectionWithSmartDelete(
|
| + canSmartCopyOrDelete() ? DeleteMode::Smart : DeleteMode::Simple,
|
| + InputEvent::InputType::DeleteByCut);
|
| }
|
| }
|
|
|
| @@ -1037,8 +1101,9 @@ void Editor::performDelete() {
|
| addToKillRing(selectedRange());
|
| // TODO(chongz): |Editor::performDelete()| has no direction.
|
| // https://github.com/w3c/editing/issues/130
|
| - deleteSelectionWithSmartDelete(canSmartCopyOrDelete(),
|
| - InputEvent::InputType::DeleteContentBackward);
|
| + deleteSelectionWithSmartDelete(
|
| + canSmartCopyOrDelete() ? DeleteMode::Smart : DeleteMode::Simple,
|
| + InputEvent::InputType::DeleteContentBackward);
|
|
|
| // clear the "start new kill ring sequence" setting, because it was set to true
|
| // when the selection was updated by deleting the range
|
|
|