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 |