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 bce455ebbcc63d4b2a2b92977150d405b19b892c..27cba82d19edc5181cfd440bc2ea6e2b0f7bc0cc 100644 |
--- a/third_party/WebKit/Source/core/editing/InputMethodController.cpp |
+++ b/third_party/WebKit/Source/core/editing/InputMethodController.cpp |
@@ -321,6 +321,10 @@ void InputMethodController::setComposition(const String& text, const Vector<Comp |
if (!target) |
return; |
+ int selectionOffsetsStart = static_cast<int>(getSelectionOffsets().start()); |
+ int start = selectionOffsetsStart + selectionStart; |
+ int end = selectionOffsetsStart + selectionEnd; |
+ |
// Dispatch an appropriate composition event to the focused node. |
// We check the composition status and choose an appropriate composition event since this |
// function is used for three purposes: |
@@ -339,11 +343,13 @@ void InputMethodController::setComposition(const String& text, const Vector<Comp |
if (text.isEmpty()) { |
if (hasComposition()) { |
confirmComposition(emptyString()); |
+ setEditableSelectionOffsetsWithBoundaryCheck(start, end); |
return; |
} |
// 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. |
TypingCommand::deleteSelection(*frame().document(), TypingCommand::PreventSpellChecking); |
+ setEditableSelectionOffsetsWithBoundaryCheck(start, end); |
return; |
} |
@@ -390,31 +396,7 @@ void InputMethodController::setComposition(const String& text, const Vector<Comp |
if (baseNode->layoutObject()) |
baseNode->layoutObject()->setShouldDoFullPaintInvalidation(); |
- // In case of exceeding the left boundary. |
- int selectionOffsetsStart = static_cast<int>(getSelectionOffsets().start()); |
- int start = std::max(selectionOffsetsStart + selectionStart, 0); |
- int end = std::max(selectionOffsetsStart + selectionEnd, start); |
- |
- Element* rootEditableElement = frame().selection().rootEditableElement(); |
- if (!rootEditableElement) |
- return; |
- |
- // In case of exceeding the right boundary. |
- // If both |value1| and |value2| exceed right boundary, |
- // PlainTextRange(value1, value2)::createRange() will return a default |
- // value, which is [0,0]. In order to get the correct Position in that case, |
- // we should make sure |value1| is within range at least. |
- const EphemeralRange& startRange = PlainTextRange(0, start).createRange(*rootEditableElement); |
- const EphemeralRange& endRange = PlainTextRange(0, end).createRange(*rootEditableElement); |
- |
- // TODO(yabinh): There should be a better way to create |startPosition| and |
- // |endPosition|. But for now, since we can't get |anchorNode| and |offset|, |
- // we can't create the 2 Position objects directly. So we use |
- // PlainTextRange::createRange as a workaround. |
- const Position& startPosition = startRange.endPosition(); |
- const Position& endPosition = endRange.endPosition(); |
- Range* selectedRange = Range::create(rootEditableElement->document(), startPosition, endPosition); |
- frame().selection().setSelectedRange(selectedRange, TextAffinity::Downstream, SelectionDirectionalMode::NonDirectional, NotUserTriggered); |
+ setEditableSelectionOffsetsWithBoundaryCheck(start, end); |
if (underlines.isEmpty()) { |
frame().document()->markers().addCompositionMarker(m_compositionRange->startPosition(), m_compositionRange->endPosition(), Color::black, false, LayoutTheme::theme().platformDefaultCompositionBackgroundColor()); |
@@ -515,6 +497,44 @@ bool InputMethodController::setEditableSelectionOffsets(const PlainTextRange& se |
return setSelectionOffsets(selectionOffsets); |
} |
+bool InputMethodController::setEditableSelectionOffsetsWithBoundaryCheck(int start, int end) |
Changwan Ryu
2016/05/30 08:18:22
could you check if you can replace setEditableSele
yabinh
2016/05/31 01:53:59
Please see patch set 2.
|
+{ |
+ if (!editor().canEdit()) |
+ return false; |
+ |
+ Element* rootEditableElement = frame().selection().rootEditableElement(); |
+ if (!rootEditableElement) |
+ return false; |
+ |
+ // In case of exceeding the left boundary. |
+ start = std::max(start, 0); |
+ end = std::max(end, start); |
+ |
+ // In case of exceeding the right boundary. |
+ // If both |value1| and |value2| exceed right boundary, |
+ // PlainTextRange(value1, value2)::createRange() will return a default |
+ // value, which is [0,0]. In order to get the correct Position in that case, |
+ // we should make sure |value1| is within range at least. |
+ const EphemeralRange& startRange = PlainTextRange(0, start).createRange(*rootEditableElement); |
+ if (startRange.isNull()) |
+ return false; |
+ const EphemeralRange& endRange = PlainTextRange(0, end).createRange(*rootEditableElement); |
+ if (endRange.isNull()) |
+ return false; |
+ |
+ // TODO(yabinh): There should be a better way to create |startPosition| and |
+ // |endPosition|. But for now, since we can't get |anchorNode| and |offset|, |
+ // we can't create the 2 Position objects directly. So we use |
+ // PlainTextRange::createRange as a workaround. |
+ const Position& startPosition = startRange.endPosition(); |
+ const Position& endPosition = endRange.endPosition(); |
+ const EphemeralRange& range = EphemeralRange(startPosition, endPosition); |
+ if (range.isNull()) |
+ return false; |
+ |
+ return frame().selection().setSelectedRange(range, VP_DEFAULT_AFFINITY, SelectionDirectionalMode::NonDirectional, FrameSelection::CloseTyping); |
+} |
+ |
void InputMethodController::extendSelectionAndDelete(int before, int after) |
{ |
if (!editor().canEdit()) |