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

Unified Diff: third_party/WebKit/Source/core/editing/Editor.cpp

Issue 2558643003: [InputEvent] Move 'beforeinput' logic into |CompositeEditCommand::willApplyEditing()| (3/3) (Closed)
Patch Set: yosin's review, fix nits Created 4 years 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
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 c1d7b1601c31f25d33007acffabad03502910b9f..3ee2d287a2a898919defb77bf55789baad84c1a7 100644
--- a/third_party/WebKit/Source/core/editing/Editor.cpp
+++ b/third_party/WebKit/Source/core/editing/Editor.cpp
@@ -86,6 +86,7 @@
#include "core/page/Page.h"
#include "core/svg/SVGImageElement.h"
#include "platform/KillRing.h"
+#include "platform/clipboard/ClipboardMimeTypes.h"
#include "platform/weborigin/KURL.h"
#include "wtf/PtrUtil.h"
#include "wtf/text/CharacterNames.h"
@@ -98,18 +99,48 @@ using namespace Unicode;
namespace {
+DispatchEventResult dispatchBeforeInputEvent(
+ Node* target,
+ InputEvent::InputType inputType,
+ const String& data,
+ DataTransfer* dataTransfer,
+ InputEvent::EventCancelable isCancelable,
+ InputEvent::EventIsComposing isComposing,
+ const RangeVector* ranges) {
+ if (!RuntimeEnabledFeatures::inputEventEnabled())
+ return DispatchEventResult::NotCanceled;
+ if (!target || !target->isConnected())
+ return DispatchEventResult::NotCanceled;
+
+ if (!hasRichlyEditableStyle(*target)) {
+ // Plain-text only elements (<input>, <textarea>, etc.) don't support
+ // DataTransfer or Range.
+ dataTransfer = nullptr;
+ ranges = nullptr;
+ }
+
+ InputEvent* beforeInputEvent;
+
+ if (dataTransfer) {
+ beforeInputEvent = InputEvent::createBeforeInput(
+ inputType, dataTransfer, isCancelable, isComposing, ranges);
+ } else {
+ beforeInputEvent = InputEvent::createBeforeInput(
+ inputType, data, isCancelable, isComposing, ranges);
+ }
+ return target->dispatchEvent(beforeInputEvent);
+}
+
void dispatchInputEvent(Element* target,
InputEvent::InputType inputType,
const String& data,
InputEvent::EventIsComposing isComposing) {
if (!RuntimeEnabledFeatures::inputEventEnabled())
return;
- if (!target)
+ if (!target || !target->isConnected())
return;
- // TODO(chongz): Pass appreciate |ranges| after it's defined on spec.
- // http://w3c.github.io/editing/input-events.html#dom-inputevent-inputtype
InputEvent* inputEvent =
- InputEvent::createInput(inputType, data, isComposing, nullptr);
+ InputEvent::createInput(inputType, data, isComposing);
target->dispatchScopedEvent(inputEvent);
}
@@ -130,8 +161,17 @@ InputEvent::EventIsComposing isComposingFromCommand(
if (command->isTypingCommand() &&
toTypingCommand(command)->compositionType() !=
TypingCommand::TextCompositionNone)
- return InputEvent::EventIsComposing::IsComposing;
- return InputEvent::EventIsComposing::NotComposing;
+ return InputEvent::IsComposing;
+ return InputEvent::NotComposing;
+}
+
+InputEvent::EventCancelable isCancelableFromCommand(
+ const CompositeEditCommand* command) {
+ if (command->isTypingCommand() &&
+ toTypingCommand(command)->compositionType() ==
+ TypingCommand::TextCompositionUpdate)
+ return InputEvent::NotCancelable;
+ return InputEvent::IsCancelable;
}
} // anonymous namespace
@@ -610,62 +650,6 @@ void Editor::replaceSelectionAfterDragging(DocumentFragment* fragment,
->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() {
return frame().selection().selection().toNormalizedEphemeralRange();
}
@@ -802,6 +786,24 @@ static void dispatchEditableContentChangedEvents(Element* startRoot,
Event::create(EventTypeNames::webkitEditableContentChanged));
}
+bool Editor::willApplyEditing(CompositeEditCommand* cmd) {
+ // Don't fire 'beforeinput', return true to continue.
+ if (m_executingCommandFromDOM ||
+ cmd->inputType() == InputEvent::InputType::None)
+ return true;
+
+ DispatchEventResult result = dispatchBeforeInputEvent(
+ eventTargetNodeForDocument(m_frame->document()), cmd->inputType(),
+ cmd->textDataForInputEvent(), cmd->dataTransferForInputEvent(),
+ isCancelableFromCommand(cmd), isComposingFromCommand(cmd),
+ cmd->targetRangesForInputEvent());
+
+ // 'beforeinput' event handler may destroy target frame.
+ if (m_frame->document()->frame() != m_frame)
+ return false;
+ return result == DispatchEventResult::NotCanceled;
+}
+
void Editor::appliedEditing(CompositeEditCommand* cmd) {
DCHECK(!cmd->isCommandGroupWrapper());
EventQueueScope scope;
@@ -933,7 +935,8 @@ Editor::Editor(LocalFrame& frame)
m_killRing(wrapUnique(new KillRing)),
m_areMarkedTextMatchesHighlighted(false),
m_defaultParagraphSeparator(EditorParagraphSeparatorIsDiv),
- m_overwriteModeEnabled(false) {}
+ m_overwriteModeEnabled(false),
+ m_executingCommandFromDOM(false) {}
Editor::~Editor() {}
@@ -1042,16 +1045,6 @@ void Editor::cut(EditorCommandSource source) {
writeSelectionToPasteboard();
}
- if (source == CommandFromMenuOrKeyBinding) {
- if (dispatchBeforeInputDataTransfer(findEventTargetFromSelection(),
- InputEvent::InputType::DeleteByCut,
- nullptr, nullptr) !=
- DispatchEventResult::NotCanceled)
- return;
- // 'beforeinput' event handler may destroy target frame.
- if (m_frame->document()->frame() != m_frame)
- return;
- }
deleteSelectionWithSmartDelete(
canSmartCopyOrDelete() ? DeleteMode::Smart : DeleteMode::Simple,
InputEvent::InputType::DeleteByCut);
@@ -1100,21 +1093,6 @@ void Editor::paste(EditorCommandSource source) {
? AllMimeTypes
: PlainTextOnly;
- if (source == CommandFromMenuOrKeyBinding) {
- DataTransfer* dataTransfer =
- DataTransfer::create(DataTransfer::CopyAndPaste, DataTransferReadable,
- DataObject::createFromPasteboard(pasteMode));
-
- if (dispatchBeforeInputDataTransfer(findEventTargetFromSelection(),
- InputEvent::InputType::InsertFromPaste,
- dataTransfer, nullptr) !=
- DispatchEventResult::NotCanceled)
- return;
- // 'beforeinput' event handler may destroy target frame.
- if (m_frame->document()->frame() != m_frame)
- return;
- }
-
if (pasteMode == AllMimeTypes)
pasteWithPasteboard(Pasteboard::generalPasteboard());
else
@@ -1231,6 +1209,17 @@ bool Editor::canUndo() {
}
void Editor::undo() {
+ if (!m_executingCommandFromDOM) {
+ if (dispatchBeforeInputEvent(
+ m_frame->document(), InputEvent::InputType::HistoryUndo, nullAtom,
+ nullptr, InputEvent::IsCancelable, InputEvent::NotComposing,
+ nullptr) != DispatchEventResult::NotCanceled)
+ return;
+
+ // 'beforeinput' event handler may destroy target frame.
+ if (m_frame->document()->frame() != m_frame)
+ return;
+ }
m_undoStack->undo();
}
@@ -1239,6 +1228,17 @@ bool Editor::canRedo() {
}
void Editor::redo() {
+ if (!m_executingCommandFromDOM) {
+ if (dispatchBeforeInputEvent(
+ m_frame->document(), InputEvent::InputType::HistoryRedo, nullAtom,
+ nullptr, InputEvent::IsCancelable, InputEvent::NotComposing,
+ nullptr) != DispatchEventResult::NotCanceled)
+ return;
+
+ // 'beforeinput' event handler may destroy target frame.
+ if (m_frame->document()->frame() != m_frame)
+ return;
+ }
m_undoStack->redo();
}
@@ -1268,7 +1268,7 @@ void Editor::setBaseWritingDirection(WritingDirection direction) {
void Editor::revealSelectionAfterEditingOperation(
const ScrollAlignment& alignment,
RevealExtentOption revealExtentOption) {
- if (m_preventRevealSelection)
+ if (m_preventRevealSelection || !m_frame->selection().isAvailable())
return;
frame().selection().revealSelection(alignment, revealExtentOption);
}

Powered by Google App Engine
This is Rietveld 408576698