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 f8628dc7e842b61d332d1ad4b0a6870b9b25a253..c33fc89563ecbe453b8b527c5152a0e9a9137aac 100644 |
--- a/third_party/WebKit/Source/core/editing/InputMethodController.cpp |
+++ b/third_party/WebKit/Source/core/editing/InputMethodController.cpp |
@@ -685,6 +685,82 @@ void InputMethodController::extendSelectionAndDelete(int before, int after) { |
TypingCommand::deleteSelection(*frame().document()); |
} |
+// TODO(yabinh): We should reduce the number of selectionchange events. |
+void InputMethodController::deleteSurroundingText(int before, int after) { |
+ if (!editor().canEdit()) |
+ return; |
+ PlainTextRange selectionOffsets(getSelectionOffsets()); |
+ if (selectionOffsets.isNull()) |
+ return; |
+ Element* rootEditableElement = frame().selection().rootEditableElement(); |
+ if (!rootEditableElement) |
+ return; |
+ |
+ int selectionStart = static_cast<int>(selectionOffsets.start()); |
+ int selectionEnd = static_cast<int>(selectionOffsets.end()); |
+ |
+ if (before > 0 && selectionStart > 0) { |
+ // In case of exceeding the left boundary. |
+ int start = std::max(selectionStart - before, 0); |
+ |
+ // Select the text to be deleted before selectionStart. |
+ // We should adjust the start of selection for multi-code text(a grapheme |
+ // cluster contains more than one code point). |
+ const EphemeralRange& range = |
+ PlainTextRange(0, start).createRange(*rootEditableElement); |
+ if (range.isNull()) |
+ return; |
+ const Position& position = range.endPosition(); |
+ // TODO(yabinh): Deletion should be based on code point instead of grapheme |
+ // cluster. |
+ const Position& adjustedPosition = previousPositionOf( |
yosin_UTC9
2016/10/12 08:34:17
I saw this pattern in another CL. Can we have func
yabinh
2016/10/13 01:44:33
Done.
|
+ nextPositionOf(position, PositionMoveType::GraphemeCluster), |
+ PositionMoveType::GraphemeCluster); |
+ DCHECK_EQ(position.anchorNode(), adjustedPosition.anchorNode()); |
+ DCHECK_LE(adjustedPosition.computeOffsetInContainerNode(), |
+ position.computeOffsetInContainerNode()); |
+ const int diff = adjustedPosition.computeOffsetInContainerNode() - |
+ position.computeOffsetInContainerNode(); |
+ start = start + diff; |
yosin_UTC9
2016/10/12 08:34:17
Let's introduce new variable, e.g. |adjustedStart|
yabinh
2016/10/13 01:44:33
Done.
|
+ |
+ if (!setSelectionOffsets(PlainTextRange(start, selectionStart))) |
+ return; |
+ TypingCommand::deleteSelection(*frame().document()); |
+ |
+ selectionEnd = selectionEnd - (selectionStart - start); |
+ selectionStart = start; |
+ } |
+ |
+ if (after > 0) { |
+ // Adjust the deleted range in case of exceeding the right boundary. |
+ PlainTextRange range(0, selectionEnd + after); |
+ if (range.isNull()) |
+ return; |
+ const EphemeralRange& validRange = range.createRange(*rootEditableElement); |
+ if (validRange.isNull()) |
+ return; |
+ int end = PlainTextRange::create(*rootEditableElement, validRange).end(); |
+ |
+ // We also need to adjust the end of selection for multi-code text. |
+ const Position& position = validRange.endPosition(); |
+ const Position& adjustedPosition = nextPositionOf( |
+ previousPositionOf(position, PositionMoveType::GraphemeCluster), |
+ PositionMoveType::GraphemeCluster); |
+ DCHECK_EQ(position.anchorNode(), adjustedPosition.anchorNode()); |
+ DCHECK_GE(adjustedPosition.computeOffsetInContainerNode(), |
+ position.computeOffsetInContainerNode()); |
+ const int diff = adjustedPosition.computeOffsetInContainerNode() - |
+ position.computeOffsetInContainerNode(); |
+ end = end + diff; |
yosin_UTC9
2016/10/12 08:34:17
Let's introduce new variable, e.g. |adjustedEnd|.
yabinh
2016/10/13 01:44:33
Done.
|
+ |
+ if (!setSelectionOffsets(PlainTextRange(selectionEnd, end))) |
+ return; |
+ TypingCommand::deleteSelection(*frame().document()); |
+ } |
+ |
+ setSelectionOffsets(PlainTextRange(selectionStart, selectionEnd)); |
+} |
+ |
DEFINE_TRACE(InputMethodController) { |
visitor->trace(m_frame); |
visitor->trace(m_compositionRange); |