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

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

Issue 1995333002: Handle newCursorPosition correctly for Android's commitText() (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Split confirmComposition into 2 Created 4 years, 3 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 if (range.isNull()) 176 if (range.isNull())
177 return; 177 return;
178 178
179 // The composition can start inside a composed character sequence, so we hav e to override checks. 179 // The composition can start inside a composed character sequence, so we hav e to override checks.
180 // See <http://bugs.webkit.org/show_bug.cgi?id=15781> 180 // See <http://bugs.webkit.org/show_bug.cgi?id=15781>
181 VisibleSelection selection; 181 VisibleSelection selection;
182 selection.setWithoutValidation(range.startPosition(), range.endPosition()); 182 selection.setWithoutValidation(range.startPosition(), range.endPosition());
183 frame().selection().setSelection(selection, 0); 183 frame().selection().setSelection(selection, 0);
184 } 184 }
185 185
186 bool InputMethodController::confirmComposition() 186 bool InputMethodController::finishComposingText(ConfirmCompositionBehavior confi rmBehavior)
187 {
188 return confirmComposition(composingText());
189 }
190
191 bool InputMethodController::confirmComposition(const String& text, ConfirmCompos itionBehavior confirmBehavior)
192 { 187 {
193 if (!hasComposition()) 188 if (!hasComposition())
194 return false; 189 return false;
190
191 if (confirmBehavior == KeepSelection) {
192 SelectionOffsetsScope selectionOffsetsScope(this);
193 return replaceComposition(composingText(), KeepSelection);
194 }
195
196 return replaceCompositionAndMoveCaret(composingText(), 0);
197 }
198
199 bool InputMethodController::commitText(const String& text, int relativeCaretPosi tion)
200 {
201 if (!hasComposition()) {
202 // We should do nothing in this case, because:
203 // 1. No need to insert text when text is empty.
204 // 2. Shouldn't move caret when relativeCaretPosition == 0 to avoid
205 // duplicate selection change event.
206 if (!text.length() && !relativeCaretPosition)
207 return false;
208 return insertTextAndMoveCaret(text, relativeCaretPosition);
209 }
210
211 return replaceCompositionAndMoveCaret(text, relativeCaretPosition);
yosin_UTC9 2016/09/07 07:19:20 nit: It is better to switch if's condition to redu
yabinh 2016/09/07 10:27:15 Done.
212 }
213
214 bool InputMethodController::replaceComposition(const String& text, ConfirmCompos itionBehavior confirmBehavior)
215 {
216 if (!hasComposition())
217 return false;
195 218
196 Optional<Editor::RevealSelectionScope> revealSelectionScope; 219 Optional<Editor::RevealSelectionScope> revealSelectionScope;
197 if (confirmBehavior == KeepSelection) 220 if (confirmBehavior == KeepSelection)
198 revealSelectionScope.emplace(&editor()); 221 revealSelectionScope.emplace(&editor());
aelias_OOO_until_Jul13 2016/09/07 05:02:40 Please move this to finishComposingText() and remo
yabinh 2016/09/07 10:27:15 Done. Note that setComposition() will also be affe
199 222
200 // If the composition was set from existing text and didn't change, then 223 // If the composition was set from existing text and didn't change, then
201 // there's nothing to do here (and we should avoid doing anything as that 224 // there's nothing to do here (and we should avoid doing anything as that
202 // may clobber multi-node styled text). 225 // may clobber multi-node styled text).
203 if (!m_isDirty && composingText() == text) { 226 if (!m_isDirty && composingText() == text) {
204 clear(); 227 clear();
205 return true; 228 return true;
206 } 229 }
207 230
208 // Select the text that will be deleted or replaced. 231 // Select the text that will be deleted or replaced.
(...skipping 17 matching lines...) Expand all
226 // Event handler might destroy document. 249 // Event handler might destroy document.
227 if (!frame().document()) 250 if (!frame().document())
228 return false; 251 return false;
229 252
230 // No DOM update after 'compositionend'. 253 // No DOM update after 'compositionend'.
231 dispatchCompositionEndEvent(frame(), text); 254 dispatchCompositionEndEvent(frame(), text);
232 255
233 return true; 256 return true;
234 } 257 }
235 258
236 bool InputMethodController::confirmCompositionOrInsertText(const String& text, C onfirmCompositionBehavior confirmBehavior) 259 // relativeCaretPosition is relative to the end of the text.
260 static int computeAbsoluteCaretPosition(size_t textStart, size_t textLength, int relativeCaretPosition)
237 { 261 {
238 if (!hasComposition()) { 262 return textStart + textLength + relativeCaretPosition;
239 if (!text.length()) 263 }
264
265 bool InputMethodController::replaceCompositionAndMoveCaret(const String& text, i nt relativeCaretPosition)
266 {
267 Element* rootEditableElement = frame().selection().rootEditableElement();
268 if (!rootEditableElement)
269 return false;
270 PlainTextRange compositionRange = PlainTextRange::create(*rootEditableElemen t, *m_compositionRange);
271 if (compositionRange.isNull())
272 return false;
273 int textStart = compositionRange.start();
274
275 if (!replaceComposition(text, DoNotKeepSelection))
276 return false;
277
278 int absoluteCaretPosition = computeAbsoluteCaretPosition(textStart, text.len gth(), relativeCaretPosition);
279 return moveCaret(absoluteCaretPosition);
280 }
281
282 bool InputMethodController::insertText(const String& text)
283 {
284 if (dispatchBeforeInputInsertText(frame().document()->focusedElement(), text ) != DispatchEventResult::NotCanceled)
285 return false;
286 editor().insertText(text, 0);
287 return true;
288 }
289
290 bool InputMethodController::insertTextAndMoveCaret(const String& text, int relat iveCaretPosition)
291 {
292 PlainTextRange selectionRange = getSelectionOffsets();
293 if (selectionRange.isNull())
294 return false;
295 int textStart = selectionRange.start();
296
297 if (text.length()) {
298 if (!insertText(text))
240 return false; 299 return false;
241
242 if (dispatchBeforeInputInsertText(frame().document()->focusedElement(), text) != DispatchEventResult::NotCanceled)
243 return false;
244
245 editor().insertText(text, 0);
246 return true;
247 } 300 }
248 301
249 if (text.length()) { 302 int absoluteCaretPosition = computeAbsoluteCaretPosition(textStart, text.len gth(), relativeCaretPosition);
250 confirmComposition(text); 303 return moveCaret(absoluteCaretPosition);
251 return true;
252 }
253
254 if (confirmBehavior == DoNotKeepSelection)
255 return confirmComposition(composingText(), DoNotKeepSelection);
256
257 SelectionOffsetsScope selectionOffsetsScope(this);
258 return confirmComposition();
259 } 304 }
260 305
261 void InputMethodController::cancelComposition() 306 void InputMethodController::cancelComposition()
262 { 307 {
263 if (!hasComposition()) 308 if (!hasComposition())
264 return; 309 return;
265 310
266 Editor::RevealSelectionScope revealSelectionScope(&editor()); 311 Editor::RevealSelectionScope revealSelectionScope(&editor());
267 312
268 if (frame().selection().isNone()) 313 if (frame().selection().isNone())
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
336 // Sending a compositionupdate event at this time ensures that at least o ne 381 // Sending a compositionupdate event at this time ensures that at least o ne
337 // compositionupdate event is dispatched. 382 // compositionupdate event is dispatched.
338 // 2. Updating the existing composition node. 383 // 2. Updating the existing composition node.
339 // Send a compositionupdate event when this function updates the existing composition 384 // Send a compositionupdate event when this function updates the existing composition
340 // node, i.e. hasComposition() && !text.isEmpty(). 385 // node, i.e. hasComposition() && !text.isEmpty().
341 // 3. Canceling the ongoing composition. 386 // 3. Canceling the ongoing composition.
342 // Send a compositionend event when function deletes the existing composi tion node, i.e. 387 // Send a compositionend event when function deletes the existing composi tion node, i.e.
343 // !hasComposition() && test.isEmpty(). 388 // !hasComposition() && test.isEmpty().
344 if (text.isEmpty()) { 389 if (text.isEmpty()) {
345 if (hasComposition()) { 390 if (hasComposition()) {
346 confirmComposition(emptyString()); 391 replaceComposition(emptyString(), KeepSelection);
347 } else { 392 } else {
348 // It's weird to call |setComposition()| with empty text outside com position, however some IME 393 // It's weird to call |setComposition()| with empty text outside com position, however some IME
349 // (e.g. Japanese IBus-Anthy) did this, so we simply delete selectio n without sending extra events. 394 // (e.g. Japanese IBus-Anthy) did this, so we simply delete selectio n without sending extra events.
350 TypingCommand::deleteSelection(*frame().document(), TypingCommand::P reventSpellChecking); 395 TypingCommand::deleteSelection(*frame().document(), TypingCommand::P reventSpellChecking);
351 } 396 }
352 397
353 setEditableSelectionOffsets(selectedRange); 398 setEditableSelectionOffsets(selectedRange);
354 return; 399 return;
355 } 400 }
356 401
(...skipping 180 matching lines...) Expand 10 before | Expand all | Expand 10 after
537 582
538 rightBoundary += textLength; 583 rightBoundary += textLength;
539 584
540 // In case of exceeding the right boundary. 585 // In case of exceeding the right boundary.
541 start = std::min(start, rightBoundary); 586 start = std::min(start, rightBoundary);
542 end = std::min(end, rightBoundary); 587 end = std::min(end, rightBoundary);
543 588
544 return PlainTextRange(start, end); 589 return PlainTextRange(start, end);
545 } 590 }
546 591
592 bool InputMethodController::moveCaret(int newCaretPosition)
593 {
594 frame().document()->updateStyleAndLayoutIgnorePendingStylesheets();
595 PlainTextRange selectedRange = createRangeForSelection(newCaretPosition, new CaretPosition, 0);
596 if (selectedRange.isNull())
597 return false;
598 return setEditableSelectionOffsets(selectedRange);
599 }
600
547 void InputMethodController::extendSelectionAndDelete(int before, int after) 601 void InputMethodController::extendSelectionAndDelete(int before, int after)
548 { 602 {
549 if (!editor().canEdit()) 603 if (!editor().canEdit())
550 return; 604 return;
551 PlainTextRange selectionOffsets(getSelectionOffsets()); 605 PlainTextRange selectionOffsets(getSelectionOffsets());
552 if (selectionOffsets.isNull()) 606 if (selectionOffsets.isNull())
553 return; 607 return;
554 608
555 // A common call of before=1 and after=0 will fail if the last character 609 // A common call of before=1 and after=0 will fail if the last character
556 // is multi-code-word UTF-16, including both multi-16bit code-points and 610 // is multi-code-word UTF-16, including both multi-16bit code-points and
(...skipping 19 matching lines...) Expand all
576 TypingCommand::deleteSelection(*frame().document()); 630 TypingCommand::deleteSelection(*frame().document());
577 } 631 }
578 632
579 DEFINE_TRACE(InputMethodController) 633 DEFINE_TRACE(InputMethodController)
580 { 634 {
581 visitor->trace(m_frame); 635 visitor->trace(m_frame);
582 visitor->trace(m_compositionRange); 636 visitor->trace(m_compositionRange);
583 } 637 }
584 638
585 } // namespace blink 639 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698