Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(99)

Unified Diff: third_party/WebKit/Source/core/editing/InputMethodController.cpp

Issue 2073863003: [WIP, not for review] Workaround for setComposition styling clobber (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
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)

Powered by Google App Engine
This is Rietveld 408576698