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

Unified Diff: third_party/WebKit/Source/core/editing/commands/CompositeEditCommand.cpp

Issue 2558643003: [InputEvent] Move 'beforeinput' logic into |CompositeEditCommand::willApplyEditing()| (3/3) (Closed)
Patch Set: Rebase on EditCommandSource and willApply() CLs 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/commands/CompositeEditCommand.cpp
diff --git a/third_party/WebKit/Source/core/editing/commands/CompositeEditCommand.cpp b/third_party/WebKit/Source/core/editing/commands/CompositeEditCommand.cpp
index ee81dce271d7319aab59e5652f6a218db8f031a0..5702b3bbc81c4eed9754786df090bca029fbba18 100644
--- a/third_party/WebKit/Source/core/editing/commands/CompositeEditCommand.cpp
+++ b/third_party/WebKit/Source/core/editing/commands/CompositeEditCommand.cpp
@@ -77,28 +77,71 @@
namespace blink {
+namespace {
+
+bool dispatchBeforeInputEvent(EditCommandSource source,
+ LocalFrame* frame,
+ Node* target,
+ InputEvent::InputType inputType,
+ const String& data,
+ DataTransfer* dataTransfer,
+ InputEvent::EventCancelable isCancelable,
+ InputEvent::EventIsComposing isComposing,
+ const RangeVector* ranges) {
+ // Don't fire 'beforeinput', return true to continue.
+ if (source != EditCommandSource::kMenuOrKeyBinding ||
+ inputType == InputEvent::InputType::None)
+ return true;
+ if (!RuntimeEnabledFeatures::inputEventEnabled())
+ return true;
+ if (!frame || !target || !target->isConnected())
+ return true;
+
+ 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);
+ }
+
+ DispatchEventResult result = target->dispatchEvent(beforeInputEvent);
+ // 'beforeinput' event handler may destroy target frame.
+ if (frame->document()->frame() != frame)
+ return false;
+ return result == DispatchEventResult::NotCanceled;
+}
+
+} // anonymous namespace
+
using namespace HTMLNames;
EditCommandComposition* EditCommandComposition::create(
Document* document,
const VisibleSelection& startingSelection,
- const VisibleSelection& endingSelection,
- InputEvent::InputType inputType) {
+ const VisibleSelection& endingSelection) {
return new EditCommandComposition(document, startingSelection,
- endingSelection, inputType);
+ endingSelection);
}
EditCommandComposition::EditCommandComposition(
Document* document,
const VisibleSelection& startingSelection,
- const VisibleSelection& endingSelection,
- InputEvent::InputType inputType)
+ const VisibleSelection& endingSelection)
: m_document(document),
m_startingSelection(startingSelection),
m_endingSelection(endingSelection),
m_startingRootEditableElement(startingSelection.rootEditableElement()),
- m_endingRootEditableElement(endingSelection.rootEditableElement()),
- m_inputType(inputType) {}
+ m_endingRootEditableElement(endingSelection.rootEditableElement()) {}
bool EditCommandComposition::belongsTo(const LocalFrame& frame) const {
DCHECK(m_document);
@@ -152,18 +195,18 @@ void EditCommandComposition::reapply(EditCommandSource source) {
frame->editor().reappliedEditing(this);
}
-bool EditCommandComposition::willUnapply(EditCommandSource) {
- // TODO(chongz): Fire 'beforeinput' for 'historyUndo'.
- return true;
-}
-
-bool EditCommandComposition::willReapply(EditCommandSource) {
- // TODO(chongz): Fire 'beforeinput' for 'historyRedo'.
- return true;
+bool EditCommandComposition::willUnapply(EditCommandSource source) {
+ return dispatchBeforeInputEvent(source, m_document->frame(), m_document,
+ InputEvent::InputType::HistoryUndo, nullAtom,
+ nullptr, InputEvent::IsCancelable,
+ InputEvent::NotComposing, nullptr);
}
-InputEvent::InputType EditCommandComposition::inputType() const {
- return m_inputType;
+bool EditCommandComposition::willReapply(EditCommandSource source) {
+ return dispatchBeforeInputEvent(source, m_document->frame(), m_document,
+ InputEvent::InputType::HistoryRedo, nullAtom,
+ nullptr, InputEvent::IsCancelable,
+ InputEvent::NotComposing, nullptr);
}
void EditCommandComposition::append(SimpleEditCommand* command) {
@@ -232,6 +275,11 @@ bool CompositeEditCommand::apply(EditCommandSource source) {
}
ensureComposition();
+ // Covers the initial TypingCommand and other top-level commands.
+ // TypingCommand::willAddTypingToOpenCommand() also calls willApplyEditing().
+ if (!willApplyEditing(source))
+ return false;
+
// Changes to the document may have been made since the last editing operation
// that require a layout, as in <rdar://problem/5658603>. Low level
// operations, like RemoveNodeCommand, don't require a layout because the high
@@ -239,9 +287,6 @@ bool CompositeEditCommand::apply(EditCommandSource source) {
// the creation of VisiblePositions).
document().updateStyleAndLayoutIgnorePendingStylesheets();
- if (!willApplyEditing(source))
- return false;
-
LocalFrame* frame = document().frame();
DCHECK(frame);
EditingState editingState;
@@ -262,15 +307,37 @@ EditCommandComposition* CompositeEditCommand::ensureComposition() {
CompositeEditCommand* command = this;
while (command && command->parent())
command = command->parent();
- if (!command->m_composition)
+ if (!command->m_composition) {
command->m_composition = EditCommandComposition::create(
- &document(), startingSelection(), endingSelection(), inputType());
+ &document(), startingSelection(), endingSelection());
+ }
return command->m_composition.get();
}
-bool CompositeEditCommand::willApplyEditing(EditCommandSource) {
- // TODO(chongz): Move all the 'beforeinput' dispatching logic here.
- return true;
+bool CompositeEditCommand::willApplyEditing(EditCommandSource source) {
+ return dispatchBeforeInputEvent(
+ source, document().frame(), eventTargetNodeForDocument(&document()),
+ inputType(), textDataForInputEvent(), dataTransferForInputEvent(),
+ isCancelableFromCommand(this), isComposingFromCommand(this),
+ targetRangesForInputEvent());
+}
+
+InputEvent::InputType CompositeEditCommand::inputType() const {
+ return InputEvent::InputType::None;
+}
+
+String CompositeEditCommand::textDataForInputEvent() const {
+ return nullAtom;
+}
+
+DataTransfer* CompositeEditCommand::dataTransferForInputEvent() const {
+ return nullptr;
+}
+
+RangeVector* CompositeEditCommand::targetRangesForInputEvent() const {
+ if (!document().frame()->editor().canEditRichly())
+ return nullptr;
+ return new RangeVector(1, document().frame()->selection().firstRange());
}
bool CompositeEditCommand::preservesTypingStyle() const {

Powered by Google App Engine
This is Rietveld 408576698