| 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..12f83d59bea955d18b47bfaf93edbca5bc1d0e62 100644
|
| --- a/third_party/WebKit/Source/core/editing/commands/TypingCommand.cpp
|
| +++ b/third_party/WebKit/Source/core/editing/commands/TypingCommand.cpp
|
| @@ -46,6 +46,59 @@
|
|
|
| namespace blink {
|
|
|
| +namespace {
|
| +
|
| +InputEvent::InputType inputTypeForTypingCommand(
|
| + TypingCommand::ETypingCommand commandType,
|
| + TextGranularity granularity,
|
| + TypingCommand::TextCompositionType compositionType) {
|
| + using InputType = InputEvent::InputType;
|
| +
|
| + switch (commandType) {
|
| + case TypingCommand::DeleteSelection:
|
| + return InputType::DeleteContent;
|
| + case TypingCommand::DeleteKey:
|
| + if (compositionType != TypingCommand::TextCompositionNone)
|
| + return InputType::DeleteComposedCharacterBackward;
|
| + return deletionInputTypeFromTextGranularity(DeleteDirection::Backward,
|
| + granularity);
|
| + case TypingCommand::ForwardDeleteKey:
|
| + if (compositionType != TypingCommand::TextCompositionNone)
|
| + return InputType::DeleteComposedCharacterForward;
|
| + return deletionInputTypeFromTextGranularity(DeleteDirection::Forward,
|
| + granularity);
|
| + case TypingCommand::InsertText:
|
| + return InputType::InsertText;
|
| + case TypingCommand::InsertLineBreak:
|
| + return InputType::InsertLineBreak;
|
| + case TypingCommand::InsertParagraphSeparator:
|
| + case TypingCommand::InsertParagraphSeparatorInQuotedContent:
|
| + return InputType::InsertParagraph;
|
| + default:
|
| + return InputType::None;
|
| + }
|
| +}
|
| +
|
| +RangeVector* targetRangesFromCurrentSelectionOrExtendCaret(
|
| + const LocalFrame& frame,
|
| + SelectionDirection direction,
|
| + TextGranularity granularity) {
|
| + frame.document()->updateStyleAndLayoutIgnorePendingStylesheets();
|
| + SelectionModifier selectionModifier(frame, frame.selection().selection());
|
| + if (selectionModifier.selection().isCaret()) {
|
| + selectionModifier.modify(FrameSelection::AlterationExtend, direction,
|
| + granularity);
|
| + }
|
| + RangeVector* ranges = new RangeVector;
|
| + // We only supports single selections.
|
| + if (selectionModifier.selection().isNone())
|
| + return ranges;
|
| + ranges->append(firstRangeOf(selectionModifier.selection()));
|
| + return ranges;
|
| +}
|
| +
|
| +} // anonymous namespace
|
| +
|
| using namespace HTMLNames;
|
|
|
| TypingCommand::TypingCommand(Document& document,
|
| @@ -67,6 +120,8 @@ TypingCommand::TypingCommand(Document& document,
|
| m_shouldRetainAutocorrectionIndicator(options &
|
| RetainAutocorrectionIndicator),
|
| m_shouldPreventSpellChecking(options & PreventSpellChecking) {
|
| + m_inputType = inputTypeForTypingCommand(m_commandType, m_granularity,
|
| + m_compositionType);
|
| updatePreservesTypingStyle(m_commandType);
|
| }
|
|
|
| @@ -83,6 +138,9 @@ void TypingCommand::deleteSelection(Document& document, Options options) {
|
|
|
| lastTypingCommand->setShouldPreventSpellChecking(options &
|
| PreventSpellChecking);
|
| + if (!lastTypingCommand->willAddTypingToOpenCommand(
|
| + InputEvent::InputType::DeleteContent))
|
| + return;
|
| // InputMethodController uses this function to delete composition
|
| // selection. It won't be aborted.
|
| lastTypingCommand->deleteSelection(options & SmartDelete,
|
| @@ -108,6 +166,9 @@ void TypingCommand::deleteKeyPressed(Document& document,
|
| frame);
|
| lastTypingCommand->setShouldPreventSpellChecking(options &
|
| PreventSpellChecking);
|
| + if (!lastTypingCommand->willAddTypingToOpenCommand(
|
| + InputEvent::InputType::DeleteContentBackward))
|
| + return;
|
| EditingState editingState;
|
| lastTypingCommand->deleteKeyPressed(granularity, options & KillRing,
|
| &editingState);
|
| @@ -132,6 +193,9 @@ void TypingCommand::forwardDeleteKeyPressed(Document& document,
|
| updateSelectionIfDifferentFromCurrentSelection(lastTypingCommand, frame);
|
| lastTypingCommand->setShouldPreventSpellChecking(options &
|
| PreventSpellChecking);
|
| + if (!lastTypingCommand->willAddTypingToOpenCommand(
|
| + InputEvent::InputType::DeleteContentForward))
|
| + return;
|
| lastTypingCommand->forwardDeleteKeyPressed(
|
| granularity, options & KillRing, editingState);
|
| return;
|
| @@ -143,9 +207,39 @@ void TypingCommand::forwardDeleteKeyPressed(Document& document,
|
| }
|
|
|
| String TypingCommand::textDataForInputEvent() const {
|
| - if (m_commands.isEmpty())
|
| + if (m_inputType == InputEvent::InputType::InsertText)
|
| return m_textToInsert;
|
| - return m_commands.back()->textDataForInputEvent();
|
| + return EditCommand::textDataForInputEvent();
|
| +}
|
| +
|
| +RangeVector* TypingCommand::targetRangesForInputEvent() const {
|
| + LocalFrame* frame = document().frame();
|
| + DCHECK(frame);
|
| +
|
| + using InputType = InputEvent::InputType;
|
| +
|
| + switch (m_inputType) {
|
| + case InputType::DeleteContentBackward:
|
| + return targetRangesFromCurrentSelectionOrExtendCaret(
|
| + *frame, DirectionBackward, CharacterGranularity);
|
| + case InputType::DeleteContentForward:
|
| + return targetRangesFromCurrentSelectionOrExtendCaret(
|
| + *frame, DirectionForward, CharacterGranularity);
|
| + case InputType::DeleteWordBackward:
|
| + return targetRangesFromCurrentSelectionOrExtendCaret(
|
| + *frame, DirectionBackward, WordGranularity);
|
| + case InputType::DeleteWordForward:
|
| + return targetRangesFromCurrentSelectionOrExtendCaret(
|
| + *frame, DirectionForward, WordGranularity);
|
| + case InputType::DeleteSoftLineBackward:
|
| + return targetRangesFromCurrentSelectionOrExtendCaret(
|
| + *frame, DirectionBackward, LineGranularity);
|
| + case InputType::DeleteSoftLineForward:
|
| + return targetRangesFromCurrentSelectionOrExtendCaret(
|
| + *frame, DirectionForward, LineGranularity);
|
| + default:
|
| + return EditCommand::targetRangesForInputEvent();
|
| + }
|
| }
|
|
|
| void TypingCommand::updateSelectionIfDifferentFromCurrentSelection(
|
| @@ -226,6 +320,9 @@ void TypingCommand::insertText(Document& document,
|
| options & RetainAutocorrectionIndicator);
|
| lastTypingCommand->setShouldPreventSpellChecking(options &
|
| PreventSpellChecking);
|
| + if (!lastTypingCommand->willAddTypingToOpenCommand(
|
| + InputEvent::InputType::InsertText, text))
|
| + return;
|
| EditingState editingState;
|
| lastTypingCommand->insertText(newText, options & SelectInsertedText,
|
| &editingState);
|
| @@ -251,6 +348,9 @@ bool TypingCommand::insertLineBreak(Document& document) {
|
| if (TypingCommand* lastTypingCommand =
|
| lastTypingCommandIfStillOpenForTyping(document.frame())) {
|
| lastTypingCommand->setShouldRetainAutocorrectionIndicator(false);
|
| + if (!lastTypingCommand->willAddTypingToOpenCommand(
|
| + InputEvent::InputType::InsertLineBreak))
|
| + return false;
|
| EditingState editingState;
|
| lastTypingCommand->insertLineBreak(&editingState);
|
| return !editingState.isAborted();
|
| @@ -263,6 +363,9 @@ bool TypingCommand::insertParagraphSeparatorInQuotedContent(
|
| Document& document) {
|
| if (TypingCommand* lastTypingCommand =
|
| lastTypingCommandIfStillOpenForTyping(document.frame())) {
|
| + if (!lastTypingCommand->willAddTypingToOpenCommand(
|
| + InputEvent::InputType::InsertParagraph))
|
| + return false;
|
| EditingState editingState;
|
| lastTypingCommand->insertParagraphSeparatorInQuotedContent(&editingState);
|
| return !editingState.isAborted();
|
| @@ -277,6 +380,9 @@ bool TypingCommand::insertParagraphSeparator(Document& document) {
|
| if (TypingCommand* lastTypingCommand =
|
| lastTypingCommandIfStillOpenForTyping(document.frame())) {
|
| lastTypingCommand->setShouldRetainAutocorrectionIndicator(false);
|
| + if (!lastTypingCommand->willAddTypingToOpenCommand(
|
| + InputEvent::InputType::InsertParagraph))
|
| + return false;
|
| EditingState editingState;
|
| lastTypingCommand->insertParagraphSeparator(&editingState);
|
| return !editingState.isAborted();
|
| @@ -341,33 +447,24 @@ void TypingCommand::doApply(EditingState* editingState) {
|
| }
|
|
|
| InputEvent::InputType TypingCommand::inputType() const {
|
| - using InputType = InputEvent::InputType;
|
| + return m_inputType;
|
| +}
|
|
|
| - switch (m_commandType) {
|
| - // TODO(chongz): |DeleteSelection| is used by IME but we don't have
|
| - // direction info.
|
| - case DeleteSelection:
|
| - return InputType::DeleteContentBackward;
|
| - case DeleteKey:
|
| - if (m_compositionType != TextCompositionNone)
|
| - return InputType::DeleteComposedCharacterBackward;
|
| - return deletionInputTypeFromTextGranularity(DeleteDirection::Backward,
|
| - m_granularity);
|
| - case ForwardDeleteKey:
|
| - if (m_compositionType != TextCompositionNone)
|
| - return InputType::DeleteComposedCharacterForward;
|
| - return deletionInputTypeFromTextGranularity(DeleteDirection::Forward,
|
| - m_granularity);
|
| - case InsertText:
|
| - return InputType::InsertText;
|
| - case InsertLineBreak:
|
| - return InputType::InsertLineBreak;
|
| - case InsertParagraphSeparator:
|
| - case InsertParagraphSeparatorInQuotedContent:
|
| - return InputType::InsertParagraph;
|
| - default:
|
| - return InputType::None;
|
| - }
|
| +bool TypingCommand::willAddTypingToOpenCommand(InputEvent::InputType inputType,
|
| + const String& text) {
|
| + m_inputType = inputType;
|
| + m_textToInsert = text;
|
| +
|
| + LocalFrame* frame = document().frame();
|
| + if (!frame)
|
| + return false;
|
| + bool result = frame->editor().willApplyEditing(this);
|
| +
|
| + // TODO(xiaochengh): The use of updateStyleAndLayoutIgnorePendingStylesheets
|
| + // needs to be audited. See http://crbug.com/590369 for more details.
|
| + document().updateStyleAndLayoutIgnorePendingStylesheets();
|
| +
|
| + return result;
|
| }
|
|
|
| void TypingCommand::typingAddedToOpenCommand(
|
|
|