Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 |
| OLD | NEW |