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 866d02dfe99734e203c106c3f9c8b144b4f294f3..f451e7a5766681419c6fdf1a0fe2a622ea9c72ed 100644 |
--- a/third_party/WebKit/Source/core/editing/commands/CompositeEditCommand.cpp |
+++ b/third_party/WebKit/Source/core/editing/commands/CompositeEditCommand.cpp |
@@ -56,6 +56,7 @@ |
#include "core/editing/commands/SplitElementCommand.h" |
#include "core/editing/commands/SplitTextNodeCommand.h" |
#include "core/editing/commands/SplitTextNodeContainingElementCommand.h" |
+#include "core/editing/commands/TypingCommand.h" |
#include "core/editing/commands/WrapContentsInDummySpanCommand.h" |
#include "core/editing/iterators/TextIterator.h" |
#include "core/editing/markers/DocumentMarkerController.h" |
@@ -149,14 +150,18 @@ void EditCommandComposition::reapply(EditCommandSource source) { |
frame->editor().reappliedEditing(this); |
} |
-bool EditCommandComposition::willUnapply(EditCommandSource) { |
- // TODO(chongz): Fire 'beforeinput' for 'historyUndo'. |
- 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); |
} |
-bool EditCommandComposition::willReapply(EditCommandSource) { |
- // TODO(chongz): Fire 'beforeinput' for 'historyRedo'. |
- return true; |
+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) { |
@@ -225,6 +230,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 |
@@ -232,9 +242,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,9 +269,42 @@ EditCommandComposition* CompositeEditCommand::ensureComposition() { |
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) { |
+ // TODO(chongz): Remove the following code after we have ensured it's OK to |
+ // fire 'beforeinput' after 'compositionupdate'. |
+ // https://crbug.com/675820 |
+ if (isTypingCommand() && (toTypingCommand(this)->compositionType() == |
+ TypingCommand::TextCompositionUpdate || |
+ toTypingCommand(this)->compositionType() == |
+ TypingCommand::TextCompositionConfirm)) |
+ return true; |
+ 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 { |
+ // TODO(chongz): We should always return current selection for ContentEditable |
+ // if no better choice. |
+ // https://crbug.com/652429 |
+ if (inputType() == InputEvent::InputType::InsertReplacementText && |
+ document().frame()->editor().canEditRichly()) |
+ return new RangeVector(1, document().frame()->selection().firstRange()); |
+ return nullptr; |
} |
bool CompositeEditCommand::preservesTypingStyle() const { |