Chromium Code Reviews| Index: third_party/WebKit/Source/core/editing/InputMethodController.cpp |
| diff --git a/third_party/WebKit/Source/core/editing/InputMethodController.cpp b/third_party/WebKit/Source/core/editing/InputMethodController.cpp |
| index 52ca9872ba6f6ea500f043b3f90a4409f62a71f8..84f8246aca9d5c0fb105cdc7e370d0e6db5d6033 100644 |
| --- a/third_party/WebKit/Source/core/editing/InputMethodController.cpp |
| +++ b/third_party/WebKit/Source/core/editing/InputMethodController.cpp |
| @@ -183,12 +183,35 @@ void InputMethodController::selectComposition() const |
| frame().selection().setSelection(selection, 0); |
| } |
| -bool InputMethodController::confirmComposition() |
| +bool InputMethodController::finishComposingText(ConfirmCompositionBehavior confirmBehavior) |
| { |
| - return confirmComposition(composingText()); |
| + if (!hasComposition()) |
| + return false; |
| + |
| + if (confirmBehavior == KeepSelection) { |
| + SelectionOffsetsScope selectionOffsetsScope(this); |
| + return replaceComposition(composingText(), KeepSelection); |
| + } |
| + |
| + return replaceCompositionAndMoveCaret(composingText(), 0); |
| } |
| -bool InputMethodController::confirmComposition(const String& text, ConfirmCompositionBehavior confirmBehavior) |
| +bool InputMethodController::commitText(const String& text, int relativeCaretPosition) |
| +{ |
| + if (!hasComposition()) { |
| + // We should do nothing in this case, because: |
| + // 1. No need to insert text when text is empty. |
| + // 2. Shouldn't move caret when relativeCaretPosition == 0 to avoid |
| + // duplicate selection change event. |
| + if (!text.length() && !relativeCaretPosition) |
| + return false; |
| + return insertTextAndMoveCaret(text, relativeCaretPosition); |
| + } |
| + |
| + return replaceCompositionAndMoveCaret(text, relativeCaretPosition); |
|
yosin_UTC9
2016/09/07 07:19:20
nit: It is better to switch if's condition to redu
yabinh
2016/09/07 10:27:15
Done.
|
| +} |
| + |
| +bool InputMethodController::replaceComposition(const String& text, ConfirmCompositionBehavior confirmBehavior) |
| { |
| if (!hasComposition()) |
| return false; |
| @@ -233,29 +256,51 @@ bool InputMethodController::confirmComposition(const String& text, ConfirmCompos |
| return true; |
| } |
| -bool InputMethodController::confirmCompositionOrInsertText(const String& text, ConfirmCompositionBehavior confirmBehavior) |
| +// relativeCaretPosition is relative to the end of the text. |
| +static int computeAbsoluteCaretPosition(size_t textStart, size_t textLength, int relativeCaretPosition) |
| { |
| - if (!hasComposition()) { |
| - if (!text.length()) |
| - return false; |
| + return textStart + textLength + relativeCaretPosition; |
| +} |
| - if (dispatchBeforeInputInsertText(frame().document()->focusedElement(), text) != DispatchEventResult::NotCanceled) |
| - return false; |
| +bool InputMethodController::replaceCompositionAndMoveCaret(const String& text, int relativeCaretPosition) |
| +{ |
| + Element* rootEditableElement = frame().selection().rootEditableElement(); |
| + if (!rootEditableElement) |
| + return false; |
| + PlainTextRange compositionRange = PlainTextRange::create(*rootEditableElement, *m_compositionRange); |
| + if (compositionRange.isNull()) |
| + return false; |
| + int textStart = compositionRange.start(); |
| - editor().insertText(text, 0); |
| - return true; |
| - } |
| + if (!replaceComposition(text, DoNotKeepSelection)) |
| + return false; |
| + |
| + int absoluteCaretPosition = computeAbsoluteCaretPosition(textStart, text.length(), relativeCaretPosition); |
| + return moveCaret(absoluteCaretPosition); |
| +} |
| + |
| +bool InputMethodController::insertText(const String& text) |
| +{ |
| + if (dispatchBeforeInputInsertText(frame().document()->focusedElement(), text) != DispatchEventResult::NotCanceled) |
| + return false; |
| + editor().insertText(text, 0); |
| + return true; |
| +} |
| + |
| +bool InputMethodController::insertTextAndMoveCaret(const String& text, int relativeCaretPosition) |
| +{ |
| + PlainTextRange selectionRange = getSelectionOffsets(); |
| + if (selectionRange.isNull()) |
| + return false; |
| + int textStart = selectionRange.start(); |
| if (text.length()) { |
| - confirmComposition(text); |
| - return true; |
| + if (!insertText(text)) |
| + return false; |
| } |
| - if (confirmBehavior == DoNotKeepSelection) |
| - return confirmComposition(composingText(), DoNotKeepSelection); |
| - |
| - SelectionOffsetsScope selectionOffsetsScope(this); |
| - return confirmComposition(); |
| + int absoluteCaretPosition = computeAbsoluteCaretPosition(textStart, text.length(), relativeCaretPosition); |
| + return moveCaret(absoluteCaretPosition); |
| } |
| void InputMethodController::cancelComposition() |
| @@ -343,7 +388,7 @@ void InputMethodController::setComposition(const String& text, const Vector<Comp |
| // !hasComposition() && test.isEmpty(). |
| if (text.isEmpty()) { |
| if (hasComposition()) { |
| - confirmComposition(emptyString()); |
| + replaceComposition(emptyString(), KeepSelection); |
| } else { |
| // It's weird to call |setComposition()| with empty text outside composition, however some IME |
| // (e.g. Japanese IBus-Anthy) did this, so we simply delete selection without sending extra events. |
| @@ -544,6 +589,15 @@ PlainTextRange InputMethodController::createRangeForSelection(int start, int end |
| return PlainTextRange(start, end); |
| } |
| +bool InputMethodController::moveCaret(int newCaretPosition) |
| +{ |
| + frame().document()->updateStyleAndLayoutIgnorePendingStylesheets(); |
| + PlainTextRange selectedRange = createRangeForSelection(newCaretPosition, newCaretPosition, 0); |
| + if (selectedRange.isNull()) |
| + return false; |
| + return setEditableSelectionOffsets(selectedRange); |
| +} |
| + |
| void InputMethodController::extendSelectionAndDelete(int before, int after) |
| { |
| if (!editor().canEdit()) |