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

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

Issue 1999423002: tyrbot test for commitText (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: SetHasCompositionTextToTrue 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;
195 190
196 Optional<Editor::RevealSelectionScope> revealSelectionScope; 191 if (confirmBehavior == KeepSelection) {
197 if (confirmBehavior == KeepSelection) 192 SelectionOffsetsScope selectionOffsetsScope(this);
193 Optional<Editor::RevealSelectionScope> revealSelectionScope;
198 revealSelectionScope.emplace(&editor()); 194 revealSelectionScope.emplace(&editor());
195 return replaceComposition(composingText());
196 }
197
198 return replaceCompositionAndMoveCaret(composingText(), 0);
199 }
200
201 bool InputMethodController::commitText(const String& text, int relativeCaretPosi tion)
202 {
203 if (hasComposition())
204 return replaceCompositionAndMoveCaret(text, relativeCaretPosition);
205
206 // We should do nothing in this case, because:
207 // 1. No need to insert text when text is empty.
208 // 2. Shouldn't move caret when relativeCaretPosition == 0 to avoid
209 // duplicate selection change event.
210 if (!text.length() && !relativeCaretPosition)
211 return false;
212 return insertTextAndMoveCaret(text, relativeCaretPosition);
213 }
214
215 bool InputMethodController::replaceComposition(const String& text)
216 {
217 if (!hasComposition())
218 return false;
199 219
200 // If the composition was set from existing text and didn't change, then 220 // 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 221 // there's nothing to do here (and we should avoid doing anything as that
202 // may clobber multi-node styled text). 222 // may clobber multi-node styled text).
203 if (!m_isDirty && composingText() == text) { 223 if (!m_isDirty && composingText() == text) {
204 clear(); 224 clear();
205 return true; 225 return true;
206 } 226 }
207 227
208 // Select the text that will be deleted or replaced. 228 // Select the text that will be deleted or replaced.
(...skipping 17 matching lines...) Expand all
226 // Event handler might destroy document. 246 // Event handler might destroy document.
227 if (!frame().document()) 247 if (!frame().document())
228 return false; 248 return false;
229 249
230 // No DOM update after 'compositionend'. 250 // No DOM update after 'compositionend'.
231 dispatchCompositionEndEvent(frame(), text); 251 dispatchCompositionEndEvent(frame(), text);
232 252
233 return true; 253 return true;
234 } 254 }
235 255
236 bool InputMethodController::confirmCompositionOrInsertText(const String& text, C onfirmCompositionBehavior confirmBehavior) 256 // relativeCaretPosition is relative to the end of the text.
257 static int computeAbsoluteCaretPosition(size_t textStart, size_t textLength, int relativeCaretPosition)
237 { 258 {
238 if (!hasComposition()) { 259 return textStart + textLength + relativeCaretPosition;
239 if (!text.length()) 260 }
261
262 bool InputMethodController::replaceCompositionAndMoveCaret(const String& text, i nt relativeCaretPosition)
263 {
264 Element* rootEditableElement = frame().selection().rootEditableElement();
265 if (!rootEditableElement)
266 return false;
267 PlainTextRange compositionRange = PlainTextRange::create(*rootEditableElemen t, *m_compositionRange);
268 if (compositionRange.isNull())
269 return false;
270 int textStart = compositionRange.start();
271
272 if (!replaceComposition(text))
273 return false;
274
275 int absoluteCaretPosition = computeAbsoluteCaretPosition(textStart, text.len gth(), relativeCaretPosition);
276 return moveCaret(absoluteCaretPosition);
277 }
278
279 bool InputMethodController::insertText(const String& text)
280 {
281 if (dispatchBeforeInputInsertText(frame().document()->focusedElement(), text ) != DispatchEventResult::NotCanceled)
282 return false;
283 editor().insertText(text, 0);
284 return true;
285 }
286
287 bool InputMethodController::insertTextAndMoveCaret(const String& text, int relat iveCaretPosition)
288 {
289 PlainTextRange selectionRange = getSelectionOffsets();
290 if (selectionRange.isNull())
291 return false;
292 int textStart = selectionRange.start();
293
294 if (text.length()) {
295 if (!insertText(text))
240 return false; 296 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 } 297 }
248 298
249 if (text.length()) { 299 int absoluteCaretPosition = computeAbsoluteCaretPosition(textStart, text.len gth(), relativeCaretPosition);
250 confirmComposition(text); 300 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 } 301 }
260 302
261 void InputMethodController::cancelComposition() 303 void InputMethodController::cancelComposition()
262 { 304 {
263 if (!hasComposition()) 305 if (!hasComposition())
264 return; 306 return;
265 307
266 Editor::RevealSelectionScope revealSelectionScope(&editor()); 308 Editor::RevealSelectionScope revealSelectionScope(&editor());
267 309
268 if (frame().selection().isNone()) 310 if (frame().selection().isNone())
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
340 // Sending a compositionupdate event at this time ensures that at least o ne 382 // Sending a compositionupdate event at this time ensures that at least o ne
341 // compositionupdate event is dispatched. 383 // compositionupdate event is dispatched.
342 // 2. Updating the existing composition node. 384 // 2. Updating the existing composition node.
343 // Send a compositionupdate event when this function updates the existing composition 385 // Send a compositionupdate event when this function updates the existing composition
344 // node, i.e. hasComposition() && !text.isEmpty(). 386 // node, i.e. hasComposition() && !text.isEmpty().
345 // 3. Canceling the ongoing composition. 387 // 3. Canceling the ongoing composition.
346 // Send a compositionend event when function deletes the existing composi tion node, i.e. 388 // Send a compositionend event when function deletes the existing composi tion node, i.e.
347 // !hasComposition() && test.isEmpty(). 389 // !hasComposition() && test.isEmpty().
348 if (text.isEmpty()) { 390 if (text.isEmpty()) {
349 if (hasComposition()) { 391 if (hasComposition()) {
350 confirmComposition(emptyString()); 392 Optional<Editor::RevealSelectionScope> revealSelectionScope;
393 revealSelectionScope.emplace(&editor());
394 replaceComposition(emptyString());
351 } else { 395 } else {
352 // It's weird to call |setComposition()| with empty text outside com position, however some IME 396 // It's weird to call |setComposition()| with empty text outside com position, however some IME
353 // (e.g. Japanese IBus-Anthy) did this, so we simply delete selectio n without sending extra events. 397 // (e.g. Japanese IBus-Anthy) did this, so we simply delete selectio n without sending extra events.
354 TypingCommand::deleteSelection(*frame().document(), TypingCommand::P reventSpellChecking); 398 TypingCommand::deleteSelection(*frame().document(), TypingCommand::P reventSpellChecking);
355 } 399 }
356 400
357 setEditableSelectionOffsets(selectedRange); 401 setEditableSelectionOffsets(selectedRange);
358 return; 402 return;
359 } 403 }
360 404
(...skipping 180 matching lines...) Expand 10 before | Expand all | Expand 10 after
541 585
542 rightBoundary += textLength; 586 rightBoundary += textLength;
543 587
544 // In case of exceeding the right boundary. 588 // In case of exceeding the right boundary.
545 start = std::min(start, rightBoundary); 589 start = std::min(start, rightBoundary);
546 end = std::min(end, rightBoundary); 590 end = std::min(end, rightBoundary);
547 591
548 return PlainTextRange(start, end); 592 return PlainTextRange(start, end);
549 } 593 }
550 594
595 bool InputMethodController::moveCaret(int newCaretPosition)
596 {
597 frame().document()->updateStyleAndLayoutIgnorePendingStylesheets();
598 PlainTextRange selectedRange = createRangeForSelection(newCaretPosition, new CaretPosition, 0);
599 if (selectedRange.isNull())
600 return false;
601 return setEditableSelectionOffsets(selectedRange);
602 }
603
551 void InputMethodController::extendSelectionAndDelete(int before, int after) 604 void InputMethodController::extendSelectionAndDelete(int before, int after)
552 { 605 {
553 if (!editor().canEdit()) 606 if (!editor().canEdit())
554 return; 607 return;
555 PlainTextRange selectionOffsets(getSelectionOffsets()); 608 PlainTextRange selectionOffsets(getSelectionOffsets());
556 if (selectionOffsets.isNull()) 609 if (selectionOffsets.isNull())
557 return; 610 return;
558 611
559 // A common call of before=1 and after=0 will fail if the last character 612 // A common call of before=1 and after=0 will fail if the last character
560 // is multi-code-word UTF-16, including both multi-16bit code-points and 613 // is multi-code-word UTF-16, including both multi-16bit code-points and
(...skipping 19 matching lines...) Expand all
580 TypingCommand::deleteSelection(*frame().document()); 633 TypingCommand::deleteSelection(*frame().document());
581 } 634 }
582 635
583 DEFINE_TRACE(InputMethodController) 636 DEFINE_TRACE(InputMethodController)
584 { 637 {
585 visitor->trace(m_frame); 638 visitor->trace(m_frame);
586 visitor->trace(m_compositionRange); 639 visitor->trace(m_compositionRange);
587 } 640 }
588 641
589 } // namespace blink 642 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698