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 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()) |