| 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 b70befe6440a692d856ddb169fc145088ea45c63..69588e7fff7c376f02939a3e310771da840c4a06 100644
|
| --- a/third_party/WebKit/Source/core/editing/InputMethodController.cpp
|
| +++ b/third_party/WebKit/Source/core/editing/InputMethodController.cpp
|
| @@ -489,6 +489,77 @@ void InputMethodController::extendSelectionAndDelete(int before, int after)
|
| TypingCommand::deleteSelection(*frame().document());
|
| }
|
|
|
| +void InputMethodController::deleteSurroundingText(size_t before, size_t after)
|
| +{
|
| + if (!editor().canEdit())
|
| + return;
|
| + PlainTextRange selectionOffsets(getSelectionOffsets());
|
| + if (selectionOffsets.isNull())
|
| + return;
|
| + size_t selectionStart = selectionOffsets.start();
|
| + size_t selectionEnd = selectionOffsets.end();
|
| + Element* rootEditableElement = frame().selection().rootEditableElement();
|
| + if (!rootEditableElement)
|
| + return;
|
| +
|
| + bool deleteBeforeText = before > 0u && selectionStart > 0u;
|
| + bool deleteAftertext = after > 0u;
|
| +
|
| + if (deleteBeforeText) {
|
| + // In case of exceeding the left boundary.
|
| + int deletionStart = selectionStart - std::min(selectionStart, before);
|
| +
|
| + // Delete the text before selectionStart.
|
| + // For multi-code text, we can't delete it successfully if we only
|
| + // delete the right half of it. So we need to adjust the start of
|
| + // deletion.
|
| + const EphemeralRange& startRange = PlainTextRange(0, deletionStart).createRange(*rootEditableElement);
|
| + const Position& startPosition = startRange.endPosition();
|
| + Node* anchorNode = startPosition.anchorNode();
|
| + int deletionStartInContainerNode = startPosition.computeOffsetInContainerNode();
|
| +
|
| + const Position position(anchorNode, deletionStartInContainerNode + 1);
|
| + const Position& adjustedPosition = previousPositionOf(position, PositionMoveType::GraphemeCluster);
|
| + int adjustedDeletionStart = adjustedPosition.computeOffsetInContainerNode();
|
| +
|
| + Range* deletedRange = Range::create(*frame().document(), adjustedPosition, frame().selection().start());
|
| + deletedRange->deleteContents(ASSERT_NO_EXCEPTION);
|
| +
|
| + size_t deletedLength = selectionStart - static_cast<size_t>(deletionStart + deletionStartInContainerNode - adjustedDeletionStart);
|
| + selectionEnd = selectionEnd - deletedLength;
|
| + }
|
| +
|
| + if (deleteAftertext) {
|
| + // In case of exceeding the right boundary.
|
| + PlainTextRange range(static_cast<int>(selectionEnd), static_cast<int>(selectionEnd + after));
|
| + if (range.isNull())
|
| + return;
|
| + const EphemeralRange adjustedRange = range.createRange(*rootEditableElement);
|
| + if (adjustedRange.isNull())
|
| + return;
|
| +
|
| + const Position& endPosition = adjustedRange.endPosition();
|
| + Node* anchorNode = endPosition.anchorNode();
|
| + int deletionEndInContainerNode = endPosition.computeOffsetInContainerNode();
|
| +
|
| + // Delete the text after selectionEnd.
|
| + // We also need to adjust the end of deletion for multi-code text.
|
| + Position position(anchorNode, deletionEndInContainerNode - 1);
|
| + Position adjustedPosition = nextPositionOf(position, PositionMoveType::GraphemeCluster);
|
| +
|
| + Range* deletedRange = Range::create(*frame().document(), frame().selection().end(), adjustedPosition);
|
| + deletedRange->deleteContents(ASSERT_NO_EXCEPTION);
|
| + }
|
| +
|
| + if (deleteBeforeText || deleteAftertext) {
|
| + rootEditableElement->dispatchEvent(Event::create(EventTypeNames::webkitEditableContentChanged));
|
| + }
|
| +
|
| + if (deleteBeforeText) {
|
| + rootEditableElement->dispatchEvent(Event::create(EventTypeNames::selectionchange));
|
| + }
|
| +}
|
| +
|
| DEFINE_TRACE(InputMethodController)
|
| {
|
| visitor->trace(m_frame);
|
|
|