Chromium Code Reviews| Index: third_party/WebKit/Source/core/editing/commands/TypingCommand.cpp |
| diff --git a/third_party/WebKit/Source/core/editing/commands/TypingCommand.cpp b/third_party/WebKit/Source/core/editing/commands/TypingCommand.cpp |
| index 68aee201cbbe8b3e2226b5d4b3e667d7bc59ff60..e1ff7420ec7ec23d3bd77ba3ad33cf9b448e121e 100644 |
| --- a/third_party/WebKit/Source/core/editing/commands/TypingCommand.cpp |
| +++ b/third_party/WebKit/Source/core/editing/commands/TypingCommand.cpp |
| @@ -31,15 +31,18 @@ |
| #include "core/dom/ElementTraversal.h" |
| #include "core/editing/EditingUtilities.h" |
| #include "core/editing/Editor.h" |
| +#include "core/editing/PlainTextRange.h" |
| #include "core/editing/SelectionModifier.h" |
| #include "core/editing/VisiblePosition.h" |
| #include "core/editing/VisibleUnits.h" |
| #include "core/editing/commands/BreakBlockquoteCommand.h" |
| +#include "core/editing/commands/InsertIncrementalTextCommand.h" |
| #include "core/editing/commands/InsertLineBreakCommand.h" |
| #include "core/editing/commands/InsertParagraphSeparatorCommand.h" |
| #include "core/editing/commands/InsertTextCommand.h" |
| #include "core/editing/spellcheck/SpellChecker.h" |
| #include "core/events/BeforeTextInsertedEvent.h" |
| +#include "core/events/TextEvent.h" |
| #include "core/frame/LocalFrame.h" |
| #include "core/html/HTMLBRElement.h" |
| #include "core/layout/LayoutObject.h" |
| @@ -47,16 +50,17 @@ |
| namespace blink { |
| using namespace HTMLNames; |
| +bool TypingCommand::m_isIncrementalInsertion = false; |
| TypingCommand::TypingCommand(Document& document, |
| ETypingCommand commandType, |
| - const String& textToInsert, |
| + const String& text, |
| Options options, |
| TextGranularity granularity, |
| TextCompositionType compositionType) |
| : CompositeEditCommand(document), |
| m_commandType(commandType), |
| - m_textToInsert(textToInsert), |
| + m_text(text), |
| m_openForMoreTyping(true), |
| m_selectInsertedText(options & SelectInsertedText), |
| m_smartDelete(options & SmartDelete), |
| @@ -143,8 +147,8 @@ void TypingCommand::forwardDeleteKeyPressed(Document& document, |
| } |
| String TypingCommand::textDataForInputEvent() const { |
| - if (m_commands.isEmpty()) |
| - return m_textToInsert; |
| + if (m_commands.isEmpty() || isIncrementalInsertion()) |
| + return m_text; |
| return m_commands.back()->textDataForInputEvent(); |
| } |
| @@ -162,11 +166,7 @@ void TypingCommand::updateSelectionIfDifferentFromCurrentSelection( |
| static String dispatchBeforeTextInsertedEvent( |
| const String& text, |
| - const VisibleSelection& selectionForInsertion, |
| - bool insertionIsForUpdatingComposition) { |
| - if (insertionIsForUpdatingComposition) |
| - return text; |
| - |
| + const VisibleSelection& selectionForInsertion) { |
| String newText = text; |
| if (Node* startNode = selectionForInsertion.start().computeContainerNode()) { |
| if (rootEditableElement(*startNode)) { |
| @@ -180,10 +180,24 @@ static String dispatchBeforeTextInsertedEvent( |
| return newText; |
| } |
| +static String dispatchTextInputEvent(LocalFrame* frame, const String& text) { |
| + String newText = text; |
| + if (Element* target = frame->document()->focusedElement()) { |
| + // Send TextInputEvent. The event handler will update text if necessary. |
| + TextEvent* event = |
| + TextEvent::create(frame->domWindow(), text, TextEventInputDrop); |
| + event->setUnderlyingEvent(nullptr); |
| + target->dispatchEvent(event); |
| + newText = event->data(); |
|
chongz
2016/12/02 20:34:44
We don't need to retrieve |data| again as |TextEve
yabinh
2016/12/05 08:09:39
Done.
|
| + } |
| + return newText; |
| +} |
| + |
| void TypingCommand::insertText(Document& document, |
| const String& text, |
| Options options, |
| - TextCompositionType composition) { |
| + TextCompositionType composition, |
| + bool isIncrementalInsertion) { |
| LocalFrame* frame = document.frame(); |
| DCHECK(frame); |
| @@ -191,6 +205,7 @@ void TypingCommand::insertText(Document& document, |
| document.frame()->spellChecker().updateMarkersForWordsAffectedByEditing( |
| isSpaceOrNewline(text[0])); |
| + m_isIncrementalInsertion = isIncrementalInsertion; |
| insertText(document, text, frame->selection().selection(), options, |
| composition); |
| } |
| @@ -207,8 +222,20 @@ void TypingCommand::insertText(Document& document, |
| VisibleSelection currentSelection = frame->selection().selection(); |
| - String newText = dispatchBeforeTextInsertedEvent( |
| - text, selectionForInsertion, compositionType == TextCompositionUpdate); |
| + String newText = text; |
| + if (compositionType != TextCompositionUpdate) |
| + newText = dispatchBeforeTextInsertedEvent(text, selectionForInsertion); |
| + |
| + if (compositionType == TextCompositionConfirm) |
| + newText = dispatchTextInputEvent(frame, newText); |
| + |
| + // TODO(xiaochengh): The use of updateStyleAndLayoutIgnorePendingStylesheets |
| + // needs to be audited. see http://crbug.com/590369 for more details. |
| + document.updateStyleAndLayoutIgnorePendingStylesheets(); |
| + |
| + // Do nothing if no need to delete and insert. |
| + if (selectionForInsertion.isCaret() && newText.isEmpty()) |
| + return; |
| // Set the starting and ending selection appropriately if we are using a |
| // selection that is different from the current selection. In the future, we |
| @@ -333,7 +360,7 @@ void TypingCommand::doApply(EditingState* editingState) { |
| insertParagraphSeparatorInQuotedContent(editingState); |
| return; |
| case InsertText: |
| - insertText(m_textToInsert, m_selectInsertedText, editingState); |
| + insertText(m_text, m_selectInsertedText, editingState); |
| return; |
| } |
| @@ -419,23 +446,36 @@ void TypingCommand::insertText(const String& text, |
| return; |
| } |
| - if (text.length() > offset) |
| + if (text.length() > offset) { |
| insertTextRunWithoutNewlines(text.substring(offset, text.length() - offset), |
| selectInsertedText, editingState); |
| + } |
| } |
| void TypingCommand::insertTextRunWithoutNewlines(const String& text, |
| bool selectInsertedText, |
| EditingState* editingState) { |
| - InsertTextCommand* command = InsertTextCommand::create( |
| - document(), text, selectInsertedText, |
| - m_compositionType == TextCompositionNone |
| - ? InsertTextCommand::RebalanceLeadingAndTrailingWhitespaces |
| - : InsertTextCommand::RebalanceAllWhitespaces); |
| + CompositeEditCommand* command; |
| + if (isIncrementalInsertion()) { |
| + command = InsertIncrementalTextCommand::create( |
| + document(), text, selectInsertedText, |
| + m_compositionType == TextCompositionNone |
| + ? InsertIncrementalTextCommand:: |
| + RebalanceLeadingAndTrailingWhitespaces |
| + : InsertIncrementalTextCommand::RebalanceAllWhitespaces); |
| + } else { |
| + command = InsertTextCommand::create( |
| + document(), text, selectInsertedText, |
| + m_compositionType == TextCompositionNone |
| + ? InsertTextCommand::RebalanceLeadingAndTrailingWhitespaces |
| + : InsertTextCommand::RebalanceAllWhitespaces); |
| + } |
| applyCommandToComposite(command, endingSelection(), editingState); |
| if (editingState->isAborted()) |
| return; |
| + |
| + m_text = text; |
| typingAddedToOpenCommand(InsertText); |
| } |