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 0bd3b86d91b2380d6a7380e89bc63feae01cc7e0..463af6274d178db1c539603ee1ce81181d7f1886 100644 |
| --- a/third_party/WebKit/Source/core/editing/InputMethodController.cpp |
| +++ b/third_party/WebKit/Source/core/editing/InputMethodController.cpp |
| @@ -312,6 +312,39 @@ void InputMethodController::setComposition(const String& text, const Vector<Comp |
| // See https://bugs.webkit.org/show_bug.cgi?id=46868 |
| frame().document()->updateStyleAndLayoutTree(); |
| + // When the IME only wants to change a few characters at the end of the |
| + // composition, only touch those characters in order to preserve rich text |
| + // substructure. |
| + String composing = composingText(); |
| + bool appending = composing.length() > 0 && composing == text.left(composing.length()); |
| + bool backspacing = text.length() > 0 && text == composing.left(text.length()); |
|
Changwan Ryu
2016/09/07 04:14:39
FYI, this workaround is not going to work for Kore
aelias_OOO_until_Jul13
2016/09/07 05:11:49
OK. It looks like I can just use std::distance an
|
| + if (appending || backspacing) { |
| + const EphemeralRange range = compositionEphemeralRange(); |
| + Element* editable = frame().selection().rootEditableElement(); |
| + if (!editable) |
| + return; |
| + |
| + // Move selection to the end of the composition. |
| + PlainTextRange compositionPlainOffsets = PlainTextRange::create(*editable, range); |
| + VisibleSelection selection; |
| + selection.setWithoutValidation(range.endPosition(), range.endPosition()); |
| + frame().selection().setSelection(selection, 0); |
| + clear(); |
| + |
| + // Apply the incremental change. |
| + if (appending) |
| + confirmCompositionOrInsertText(text.substring(composing.length()), DoNotKeepSelection); |
| + else if (backspacing) |
| + extendSelectionAndDelete(composing.length() - text.length(), 0); |
| + |
| + // Now recreate the composition starting at its original start, and |
| + // apply the specified final selection offsets. |
| + setCompositionFromExistingText(underlines, compositionPlainOffsets.start(), compositionPlainOffsets.start() + text.length()); |
| + selectComposition(); |
| + setSelectionRangeForSetComposition(selectionStart, selectionEnd); |
| + return; |
| + } |
| + |
| selectComposition(); |
| if (frame().selection().isNone()) |
| @@ -390,6 +423,24 @@ void InputMethodController::setComposition(const String& text, const Vector<Comp |
| if (baseNode->layoutObject()) |
| baseNode->layoutObject()->setShouldDoFullPaintInvalidation(); |
| + setSelectionRangeForSetComposition(selectionStart, selectionEnd); |
| + |
| + if (underlines.isEmpty()) { |
| + frame().document()->markers().addCompositionMarker(m_compositionRange->startPosition(), m_compositionRange->endPosition(), Color::black, false, LayoutTheme::theme().platformDefaultCompositionBackgroundColor()); |
| + return; |
| + } |
| + for (const auto& underline : underlines) { |
| + unsigned underlineStart = baseOffset + underline.startOffset; |
| + unsigned underlineEnd = baseOffset + underline.endOffset; |
| + EphemeralRange ephemeralLineRange = EphemeralRange(Position(baseNode, underlineStart), Position(baseNode, underlineEnd)); |
| + if (ephemeralLineRange.isNull()) |
| + continue; |
| + frame().document()->markers().addCompositionMarker(ephemeralLineRange.startPosition(), ephemeralLineRange.endPosition(), underline.color, underline.thick, underline.backgroundColor); |
| + } |
| +} |
| + |
| +void InputMethodController::setSelectionRangeForSetComposition(int selectionStart, int selectionEnd) |
| +{ |
| // In case of exceeding the left boundary. |
| int selectionOffsetsStart = static_cast<int>(getSelectionOffsets().start()); |
| int start = std::max(selectionOffsetsStart + selectionStart, 0); |
| @@ -415,19 +466,6 @@ void InputMethodController::setComposition(const String& text, const Vector<Comp |
| const Position& endPosition = endRange.endPosition(); |
| const EphemeralRange selectedRange(startPosition, endPosition); |
| frame().selection().setSelectedRange(selectedRange, TextAffinity::Downstream, SelectionDirectionalMode::NonDirectional, NotUserTriggered); |
| - |
| - if (underlines.isEmpty()) { |
| - frame().document()->markers().addCompositionMarker(m_compositionRange->startPosition(), m_compositionRange->endPosition(), Color::black, false, LayoutTheme::theme().platformDefaultCompositionBackgroundColor()); |
| - return; |
| - } |
| - for (const auto& underline : underlines) { |
| - unsigned underlineStart = baseOffset + underline.startOffset; |
| - unsigned underlineEnd = baseOffset + underline.endOffset; |
| - EphemeralRange ephemeralLineRange = EphemeralRange(Position(baseNode, underlineStart), Position(baseNode, underlineEnd)); |
| - if (ephemeralLineRange.isNull()) |
| - continue; |
| - frame().document()->markers().addCompositionMarker(ephemeralLineRange.startPosition(), ephemeralLineRange.endPosition(), underline.color, underline.thick, underline.backgroundColor); |
| - } |
| } |
| void InputMethodController::setCompositionFromExistingText(const Vector<CompositionUnderline>& underlines, unsigned compositionStart, unsigned compositionEnd) |