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

Side by Side Diff: third_party/WebKit/Source/core/editing/InputMethodController.cpp

Issue 2617443002: Implement ThreadedInputConnection.deleteSurroundingTextInCodePoints() (Closed)
Patch Set: Convert UTF8 to UTF16 Created 3 years, 11 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 unified diff | Download patch
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2006, 2007, 2008, 2011 Apple Inc. All rights reserved. 2 * Copyright (C) 2006, 2007, 2008, 2011 Apple Inc. All rights reserved.
3 * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies) 3 * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies)
4 * 4 *
5 * Redistribution and use in source and binary forms, with or without 5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions 6 * modification, are permitted provided that the following conditions
7 * are met: 7 * are met:
8 * 1. Redistributions of source code must retain the above copyright 8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer. 9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright 10 * 2. Redistributions in binary form must reproduce the above copyright
(...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after
176 } 176 }
177 177
178 if (!queryAttribute) 178 if (!queryAttribute)
179 return AtomicString(); 179 return AtomicString();
180 180
181 // TODO(dtapuska): We may wish to restrict this to a yet to be proposed 181 // TODO(dtapuska): We may wish to restrict this to a yet to be proposed
182 // <contenteditable> or <richtext> element Mozilla discussed at TPAC 2016. 182 // <contenteditable> or <richtext> element Mozilla discussed at TPAC 2016.
183 return element->fastGetAttribute(HTMLNames::inputmodeAttr).lower(); 183 return element->fastGetAttribute(HTMLNames::inputmodeAttr).lower();
184 } 184 }
185 185
186 bool hasInvalidSurrogatePair(const UChar* text,
187 const int start,
188 const int end) {
189 for (int i = start; i < end; i++) {
190 if (U_IS_SURROGATE(text[i])) {
191 const bool isValidSurrogatePair =
192 U16_IS_LEAD(text[i]) && i + 1 < end && U16_IS_TRAIL(text[i + 1]);
193 if (!isValidSurrogatePair)
194 return true;
195 i++;
196 }
197 }
198 return false;
199 }
200
201 std::pair<int, int> invalidDeletionLength() {
202 return std::make_pair(-1, -1);
203 }
204
205 bool isInvalidDeletionLength(const std::pair<int, int>& lengthPair) {
206 return lengthPair.first == -1 && lengthPair.second == -1;
207 }
208
209 std::pair<int, int> convertDeletionLengthForDeleteSurroundingTextInCodePoints(
Changwan Ryu 2017/01/25 07:30:56 The name is a bit unnecessarily lengthy. How about
yabinh 2017/02/08 12:32:41 Done.
210 const String& text,
211 const int beforeLengthInCodePoints,
212 const int afterLengthInCodePoints,
213 const int selectionStart,
214 const int selectionEnd) {
215 int deletionStart = selectionStart;
216 int deletionEnd = selectionEnd;
217 const int length = static_cast<int>(text.length());
218
219 const UChar* UText;
220 if (text.is8Bit()) {
Changwan Ryu 2017/01/25 07:30:56 I really hope that we don't do the conversion here
yabinh 2017/02/08 12:32:41 Actually we convert utf16 to utf8 in RenderWidget:
Changwan Ryu 2017/02/09 01:06:34 Thanks for looking into it. StringImpl::create8Bit
yabinh 2017/02/09 05:21:37 Done.
221 const String& text16 = String::make16BitFrom8BitSource(
222 text.characters8(), static_cast<size_t>(length));
223 UText = text16.characters16();
224 } else {
225 UText = text.characters16();
226 }
227
228 U16_BACK_N(UText, 0, deletionStart, beforeLengthInCodePoints);
229 if (hasInvalidSurrogatePair(UText, deletionStart, selectionStart))
230 return invalidDeletionLength();
231
232 U16_FWD_N(UText, deletionEnd, length, afterLengthInCodePoints);
233 if (hasInvalidSurrogatePair(UText, selectionEnd, deletionEnd))
234 return invalidDeletionLength();
235
236 const int beforeLength = selectionStart - deletionStart;
237 const int afterLength = deletionEnd - selectionEnd;
Changwan Ryu 2017/01/25 07:30:56 could you add the following? DCHECK_GE(beforeLengt
yabinh 2017/02/08 12:32:42 Done.
238 return std::make_pair(beforeLength, afterLength);
239 }
240
186 } // anonymous namespace 241 } // anonymous namespace
187 242
188 InputMethodController* InputMethodController::create(LocalFrame& frame) { 243 InputMethodController* InputMethodController::create(LocalFrame& frame) {
189 return new InputMethodController(frame); 244 return new InputMethodController(frame);
190 } 245 }
191 246
192 InputMethodController::InputMethodController(LocalFrame& frame) 247 InputMethodController::InputMethodController(LocalFrame& frame)
193 : m_frame(&frame), m_hasComposition(false) {} 248 : m_frame(&frame), m_hasComposition(false) {}
194 249
195 InputMethodController::~InputMethodController() = default; 250 InputMethodController::~InputMethodController() = default;
(...skipping 650 matching lines...) Expand 10 before | Expand all | Expand 10 after
846 const size_t diff = computeDistanceToRightGraphemeBoundary(position); 901 const size_t diff = computeDistanceToRightGraphemeBoundary(position);
847 const int adjustedEnd = end + static_cast<int>(diff); 902 const int adjustedEnd = end + static_cast<int>(diff);
848 if (!setSelectionOffsets(PlainTextRange(selectionEnd, adjustedEnd))) 903 if (!setSelectionOffsets(PlainTextRange(selectionEnd, adjustedEnd)))
849 return; 904 return;
850 TypingCommand::deleteSelection(document()); 905 TypingCommand::deleteSelection(document());
851 } 906 }
852 907
853 setSelectionOffsets(PlainTextRange(selectionStart, selectionEnd)); 908 setSelectionOffsets(PlainTextRange(selectionStart, selectionEnd));
854 } 909 }
855 910
911 void InputMethodController::deleteSurroundingTextInCodePoints(int before,
912 int after) {
913 DCHECK_GE(before, 0);
914 DCHECK_GE(after, 0);
915 if (!editor().canEdit())
916 return;
917 const PlainTextRange selectionOffsets(getSelectionOffsets());
918 if (selectionOffsets.isNull())
919 return;
920 Element* const rootEditableElement =
921 frame().selection().rootEditableElement();
922 if (!rootEditableElement)
923 return;
924
925 const int selectionStart = static_cast<int>(selectionOffsets.start());
926 const int selectionEnd = static_cast<int>(selectionOffsets.end());
927 const String& text =
928 plainText(EphemeralRange::rangeOfContents(*rootEditableElement),
929 TextIteratorEmitsObjectReplacementCharacter);
930 std::pair<int, int> deletionLengthPair =
931 convertDeletionLengthForDeleteSurroundingTextInCodePoints(
932 text, before, after, selectionStart, selectionEnd);
933 if (isInvalidDeletionLength(deletionLengthPair))
934 return;
935
936 return deleteSurroundingText(deletionLengthPair.first,
937 deletionLengthPair.second);
938 }
939
856 WebTextInputInfo InputMethodController::textInputInfo() const { 940 WebTextInputInfo InputMethodController::textInputInfo() const {
857 WebTextInputInfo info; 941 WebTextInputInfo info;
858 if (!isAvailable()) 942 if (!isAvailable())
859 return info; 943 return info;
860 944
861 if (!frame().selection().isAvailable()) { 945 if (!frame().selection().isAvailable()) {
862 // plugins/mouse-capture-inside-shadow.html reaches here. 946 // plugins/mouse-capture-inside-shadow.html reaches here.
863 return info; 947 return info;
864 } 948 }
865 Element* element = frame().selection().rootEditableElement(); 949 Element* element = frame().selection().rootEditableElement();
(...skipping 201 matching lines...) Expand 10 before | Expand all | Expand 10 after
1067 frame().chromeClient().resetInputMethod(); 1151 frame().chromeClient().resetInputMethod();
1068 } 1152 }
1069 1153
1070 DEFINE_TRACE(InputMethodController) { 1154 DEFINE_TRACE(InputMethodController) {
1071 visitor->trace(m_frame); 1155 visitor->trace(m_frame);
1072 visitor->trace(m_compositionRange); 1156 visitor->trace(m_compositionRange);
1073 SynchronousMutationObserver::trace(visitor); 1157 SynchronousMutationObserver::trace(visitor);
1074 } 1158 }
1075 1159
1076 } // namespace blink 1160 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698