| 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 343e89aad7a0aaf3644dca5f79449d6d75138bc9..87be0a49ab231a98cf63b3f8359e59efa48aba81 100644
|
| --- a/third_party/WebKit/Source/core/editing/InputMethodController.cpp
|
| +++ b/third_party/WebKit/Source/core/editing/InputMethodController.cpp
|
| @@ -185,10 +185,10 @@ void InputMethodController::selectComposition() const
|
|
|
| bool InputMethodController::confirmComposition()
|
| {
|
| - return confirmComposition(composingText());
|
| + return replaceComposition(composingText(), KeepSelection);
|
| }
|
|
|
| -bool InputMethodController::confirmComposition(const String& text, ConfirmCompositionBehavior confirmBehavior)
|
| +bool InputMethodController::replaceComposition(const String& text, ConfirmCompositionBehavior confirmBehavior)
|
| {
|
| if (!hasComposition())
|
| return false;
|
| @@ -233,29 +233,83 @@ bool InputMethodController::confirmComposition(const String& text, ConfirmCompos
|
| return true;
|
| }
|
|
|
| -bool InputMethodController::confirmCompositionOrInsertText(const String& text, ConfirmCompositionBehavior confirmBehavior)
|
| +bool InputMethodController::confirmComposition(const String& text)
|
| {
|
| - if (!hasComposition()) {
|
| - if (!text.length())
|
| + if (!hasComposition())
|
| + return insertText(text);
|
| +
|
| + if (text.length()) {
|
| + replaceComposition(text, KeepSelection);
|
| + return true;
|
| + }
|
| +
|
| + SelectionOffsetsScope selectionOffsetsScope(this);
|
| + return confirmComposition();
|
| +}
|
| +
|
| +bool InputMethodController::confirmCompositionWithCursor(const String& text, int relativeCursorPosition)
|
| +{
|
| + // The relativeCursorPosition is relative to the composing text if any, or
|
| + // relative to the selection if no composing text.
|
| + // This is to match Android behavior. See:
|
| + // https://developer.android.com/reference/android/view/inputmethod/InputConnection.html#commitText(java.lang.CharSequence, int)
|
| + int textStart, textLength;
|
| + if (hasComposition()) {
|
| + Element* rootEditableElement = frame().selection().rootEditableElement();
|
| + if (!rootEditableElement)
|
| return false;
|
| + PlainTextRange compositionRange = PlainTextRange::create(*rootEditableElement, *m_compositionRange);
|
|
|
| - if (dispatchBeforeInputInsertText(frame().document()->focusedElement(), text) != DispatchEventResult::NotCanceled)
|
| + textStart = compositionRange.start();
|
| +
|
| + // If |text| is empty, we will confirm the composing text; otherwise, we
|
| + // will insert the |text|.
|
| + textLength = text.length() ? text.length() : compositionRange.length();
|
| + } else {
|
| + PlainTextRange selectionRange = getSelectionOffsets();
|
| + if (selectionRange.isNull())
|
| return false;
|
|
|
| - editor().insertText(text, 0);
|
| - return true;
|
| + textStart = getSelectionOffsets().start();
|
| + textLength = text.length();
|
| }
|
|
|
| - if (text.length()) {
|
| - confirmComposition(text);
|
| - return true;
|
| + // If relativeCursorPosition > 0, it's relative to the end of the text - 1;
|
| + // if relativeCursorPosition <= 0, it is relative to the start of the text.
|
| + // This is also to match Android behavior.
|
| + if (relativeCursorPosition > 0)
|
| + relativeCursorPosition += textLength - 1;
|
| + int absoluteCursorPosition = textStart + relativeCursorPosition;
|
| +
|
| + bool result = false;
|
| + if (!hasComposition()) {
|
| + result = insertText(text);
|
| + } else if (text.length()) {
|
| + result = replaceComposition(text, DoNotKeepSelection);
|
| + } else {
|
| + result = replaceComposition(composingText(), DoNotKeepSelection);
|
| }
|
| + if (!result)
|
| + return false;
|
|
|
| - if (confirmBehavior == DoNotKeepSelection)
|
| - return confirmComposition(composingText(), DoNotKeepSelection);
|
| + frame().document()->updateStyleAndLayoutIgnorePendingStylesheets();
|
|
|
| - SelectionOffsetsScope selectionOffsetsScope(this);
|
| - return confirmComposition();
|
| + PlainTextRange selectedRange = createRangeForSelection(absoluteCursorPosition, absoluteCursorPosition, 0);
|
| + if (selectedRange.isNull())
|
| + return false;
|
| + return setEditableSelectionOffsets(selectedRange);
|
| +}
|
| +
|
| +bool InputMethodController::insertText(const String& text)
|
| +{
|
| + if (!text.length())
|
| + return false;
|
| +
|
| + if (dispatchBeforeInputInsertText(frame().document()->focusedElement(), text) != DispatchEventResult::NotCanceled)
|
| + return false;
|
| +
|
| + editor().insertText(text, 0);
|
| + return true;
|
| }
|
|
|
| void InputMethodController::cancelComposition()
|
| @@ -343,7 +397,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.
|
|
|