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

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

Issue 2617443002: Implement ThreadedInputConnection.deleteSurroundingTextInCodePoints() (Closed)
Patch Set: Add more comments Created 3 years, 12 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 4debf150004b75497f83efa480177e71d5c8a50a..e01fa4f435e3948bf3434306b9cddab1b97cbdad 100644
--- a/third_party/WebKit/Source/core/editing/InputMethodController.cpp
+++ b/third_party/WebKit/Source/core/editing/InputMethodController.cpp
@@ -184,6 +184,83 @@ AtomicString getInputModeAttribute(Element* element) {
return element->fastGetAttribute(HTMLNames::inputmodeAttr).lower();
}
+bool hasInvalidSurrogatePair(const UChar* text,
+ const int start,
+ const int end) {
+ for (int i = start; i < end; i++) {
+ if (U_IS_SURROGATE(text[i])) {
+ const bool isValidSurrogatePair =
+ U16_IS_LEAD(text[i]) && i + 1 < end && U16_IS_TRAIL(text[i + 1]);
+ if (!isValidSurrogatePair)
+ return true;
+ i++;
+ }
+ }
+ return false;
+}
+
+bool hasInvalidSurrogatePair(const LChar* text,
Changwan Ryu 2017/01/11 06:44:33 This is somewhat weird. UTF-8 does not have surrog
yabinh 2017/01/24 11:39:56 Done. This function has been removed. We can simp
+ const int start,
+ const int end) {
+ for (int i = start; i < end; i++) {
+ if (!U8_IS_SINGLE(text[i])) {
+ const bool isValidSurrogatePair =
+ U8_IS_LEAD(text[i]) && i + 1 < end && U8_IS_TRAIL(text[i + 1]);
+ if (!isValidSurrogatePair)
+ return true;
+ i++;
+ }
+ }
+ return false;
+}
+
+std::pair<int, int> invalidDeletionLength() {
+ return std::make_pair(-1, -1);
+}
+
+bool isInvalidDeletionLength(const std::pair<int, int>& lengthPair) {
+ return lengthPair.first == -1 && lengthPair.second == -1;
+}
+
+std::pair<int, int> convertDeletionLengthForDeleteSurroundingTextInCodePoints(
+ const String& text,
+ const int beforeLengthInCodePoints,
+ const int afterLengthInCodePoints,
+ const int selectionStart,
+ const int selectionEnd) {
+ int deletionStart = selectionStart;
Changwan Ryu 2017/01/11 06:44:33 Are selectionStart / selectionEnd in code points?
yabinh 2017/01/24 11:39:56 No, it's in Java length. But we don't need convert
+ int deletionEnd = selectionEnd;
+ const int length = static_cast<int>(text.length());
+
+ if (text.is8Bit()) {
+ const LChar* LText = text.characters8();
+ U8_BACK_N(LText, 0, deletionStart, beforeLengthInCodePoints);
+
+ // Return an invalid value if there are one or more invalid surrogate pairs
+ // in the requested range
+ if (hasInvalidSurrogatePair(LText, deletionStart, selectionStart))
+ return invalidDeletionLength();
+
+ U8_FWD_N(LText, deletionEnd, length, afterLengthInCodePoints);
+ if (hasInvalidSurrogatePair(LText, selectionEnd, deletionEnd))
+ return invalidDeletionLength();
+ } else {
+ const UChar* UText = text.characters16();
+
+ U16_BACK_N(UText, 0, deletionStart, beforeLengthInCodePoints);
+ if (hasInvalidSurrogatePair(UText, deletionStart, selectionStart))
+ return invalidDeletionLength();
Changwan Ryu 2017/01/11 06:44:33 I think it should be ok to delete the range even w
yabinh 2017/01/24 11:39:56 This is to follow the specification: ''' This met
+
+ U16_FWD_N(UText, deletionEnd, length, afterLengthInCodePoints);
+ if (hasInvalidSurrogatePair(UText, selectionEnd, deletionEnd))
+ return invalidDeletionLength();
+ }
+
+ const int beforeLengthInJavaChars = selectionStart - deletionStart;
Changwan Ryu 2017/01/11 02:00:27 WebKit should not know about JavaChars. Also it do
yabinh 2017/01/24 11:39:56 Done.
+ const int afterLengthInJavaChars = deletionEnd - selectionEnd;
+ return std::make_pair(beforeLengthInJavaChars, afterLengthInJavaChars);
+}
+
} // anonymous namespace
InputMethodController* InputMethodController::create(LocalFrame& frame) {
@@ -849,6 +926,35 @@ void InputMethodController::deleteSurroundingText(int before, int after) {
setSelectionOffsets(PlainTextRange(selectionStart, selectionEnd));
}
+void InputMethodController::deleteSurroundingTextInCodePoints(int before,
+ int after) {
+ DCHECK_GE(before, 0);
+ DCHECK_GE(after, 0);
+ if (!editor().canEdit())
+ return;
+ const PlainTextRange selectionOffsets(getSelectionOffsets());
+ if (selectionOffsets.isNull())
+ return;
+ Element* const rootEditableElement =
+ frame().selection().rootEditableElement();
+ if (!rootEditableElement)
+ return;
+
+ const int selectionStart = static_cast<int>(selectionOffsets.start());
+ const int selectionEnd = static_cast<int>(selectionOffsets.end());
+ const String& text =
+ plainText(EphemeralRange::rangeOfContents(*rootEditableElement),
+ TextIteratorEmitsObjectReplacementCharacter);
+ std::pair<int, int> deletionLengthPair =
+ convertDeletionLengthForDeleteSurroundingTextInCodePoints(
+ text, before, after, selectionStart, selectionEnd);
+ if (isInvalidDeletionLength(deletionLengthPair))
+ return;
+
+ return deleteSurroundingText(deletionLengthPair.first,
+ deletionLengthPair.second);
+}
+
WebTextInputInfo InputMethodController::textInputInfo() const {
WebTextInputInfo info;
if (!isAvailable())

Powered by Google App Engine
This is Rietveld 408576698