OLD | NEW |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 package org.chromium.content.browser.input; | 5 package org.chromium.content.browser.input; |
6 | 6 |
7 import android.os.SystemClock; | 7 import android.os.SystemClock; |
8 import android.text.Editable; | 8 import android.text.Editable; |
9 import android.text.InputType; | 9 import android.text.InputType; |
10 import android.text.Selection; | 10 import android.text.Selection; |
11 import android.text.TextUtils; | |
12 import android.util.Log; | 11 import android.util.Log; |
13 import android.view.KeyEvent; | 12 import android.view.KeyEvent; |
14 import android.view.View; | 13 import android.view.View; |
15 import android.view.inputmethod.BaseInputConnection; | 14 import android.view.inputmethod.BaseInputConnection; |
16 import android.view.inputmethod.EditorInfo; | 15 import android.view.inputmethod.EditorInfo; |
17 import android.view.inputmethod.ExtractedText; | 16 import android.view.inputmethod.ExtractedText; |
18 import android.view.inputmethod.ExtractedTextRequest; | 17 import android.view.inputmethod.ExtractedTextRequest; |
19 | 18 |
20 import com.google.common.annotations.VisibleForTesting; | 19 import com.google.common.annotations.VisibleForTesting; |
21 | 20 |
(...skipping 184 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
206 mLastUpdateCompositionStart = compositionStart; | 205 mLastUpdateCompositionStart = compositionStart; |
207 mLastUpdateCompositionEnd = compositionEnd; | 206 mLastUpdateCompositionEnd = compositionEnd; |
208 } | 207 } |
209 | 208 |
210 /** | 209 /** |
211 * @see BaseInputConnection#setComposingText(java.lang.CharSequence, int) | 210 * @see BaseInputConnection#setComposingText(java.lang.CharSequence, int) |
212 */ | 211 */ |
213 @Override | 212 @Override |
214 public boolean setComposingText(CharSequence text, int newCursorPosition) { | 213 public boolean setComposingText(CharSequence text, int newCursorPosition) { |
215 if (DEBUG) Log.w(TAG, "setComposingText [" + text + "] [" + newCursorPos
ition + "]"); | 214 if (DEBUG) Log.w(TAG, "setComposingText [" + text + "] [" + newCursorPos
ition + "]"); |
216 if (maybePerformEmptyCompositionWorkaround(text)) return true; | |
217 super.setComposingText(text, newCursorPosition); | 215 super.setComposingText(text, newCursorPosition); |
218 updateSelectionIfRequired(); | 216 updateSelectionIfRequired(); |
219 return mImeAdapter.checkCompositionQueueAndCallNative(text, newCursorPos
ition, false); | 217 return mImeAdapter.checkCompositionQueueAndCallNative(text, newCursorPos
ition, false); |
220 } | 218 } |
221 | 219 |
222 /** | 220 /** |
223 * @see BaseInputConnection#commitText(java.lang.CharSequence, int) | 221 * @see BaseInputConnection#commitText(java.lang.CharSequence, int) |
224 */ | 222 */ |
225 @Override | 223 @Override |
226 public boolean commitText(CharSequence text, int newCursorPosition) { | 224 public boolean commitText(CharSequence text, int newCursorPosition) { |
227 if (DEBUG) Log.w(TAG, "commitText [" + text + "] [" + newCursorPosition
+ "]"); | 225 if (DEBUG) Log.w(TAG, "commitText [" + text + "] [" + newCursorPosition
+ "]"); |
228 if (maybePerformEmptyCompositionWorkaround(text)) return true; | |
229 super.commitText(text, newCursorPosition); | 226 super.commitText(text, newCursorPosition); |
230 updateSelectionIfRequired(); | 227 updateSelectionIfRequired(); |
231 return mImeAdapter.checkCompositionQueueAndCallNative(text, newCursorPos
ition, | 228 return mImeAdapter.checkCompositionQueueAndCallNative(text, newCursorPos
ition, |
232 text.length() > 0); | 229 text.length() > 0); |
233 } | 230 } |
234 | 231 |
235 /** | 232 /** |
236 * @see BaseInputConnection#performEditorAction(int) | 233 * @see BaseInputConnection#performEditorAction(int) |
237 */ | 234 */ |
238 @Override | 235 @Override |
(...skipping 191 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
430 if (b < 0) b = 0; | 427 if (b < 0) b = 0; |
431 if (a > textLength) a = textLength; | 428 if (a > textLength) a = textLength; |
432 if (b > textLength) b = textLength; | 429 if (b > textLength) b = textLength; |
433 | 430 |
434 if (a == b) { | 431 if (a == b) { |
435 removeComposingSpans(mEditable); | 432 removeComposingSpans(mEditable); |
436 } else { | 433 } else { |
437 super.setComposingRegion(a, b); | 434 super.setComposingRegion(a, b); |
438 } | 435 } |
439 updateSelectionIfRequired(); | 436 updateSelectionIfRequired(); |
440 return mImeAdapter.setComposingRegion(a, b); | 437 |
| 438 CharSequence regionText = null; |
| 439 if (b > a) { |
| 440 regionText = mEditable.subSequence(start, end); |
| 441 } |
| 442 return mImeAdapter.setComposingRegion(regionText, a, b); |
441 } | 443 } |
442 | 444 |
443 boolean isActive() { | 445 boolean isActive() { |
444 return getInputMethodManagerWrapper().isActive(mInternalView); | 446 return getInputMethodManagerWrapper().isActive(mInternalView); |
445 } | 447 } |
446 | 448 |
447 private InputMethodManagerWrapper getInputMethodManagerWrapper() { | 449 private InputMethodManagerWrapper getInputMethodManagerWrapper() { |
448 return mImeAdapter.getInputMethodManagerWrapper(); | 450 return mImeAdapter.getInputMethodManagerWrapper(); |
449 } | 451 } |
450 | 452 |
451 /** | |
452 * This method works around the issue crbug.com/373934 where Blink does not
cancel | |
453 * the composition when we send a commit with the empty text. | |
454 * | |
455 * TODO(aurimas) Remove this once crbug.com/373934 is fixed. | |
456 * | |
457 * @param text Text that software keyboard requested to commit. | |
458 * @return Whether the workaround was performed. | |
459 */ | |
460 private boolean maybePerformEmptyCompositionWorkaround(CharSequence text) { | |
461 int selectionStart = Selection.getSelectionStart(mEditable); | |
462 int selectionEnd = Selection.getSelectionEnd(mEditable); | |
463 int compositionStart = getComposingSpanStart(mEditable); | |
464 int compositionEnd = getComposingSpanEnd(mEditable); | |
465 if (TextUtils.isEmpty(text) && (selectionStart == selectionEnd) | |
466 && compositionStart != INVALID_COMPOSITION | |
467 && compositionEnd != INVALID_COMPOSITION) { | |
468 beginBatchEdit(); | |
469 finishComposingText(); | |
470 int selection = Selection.getSelectionStart(mEditable); | |
471 deleteSurroundingText(selection - compositionStart, selection - comp
ositionEnd); | |
472 endBatchEdit(); | |
473 return true; | |
474 } | |
475 return false; | |
476 } | |
477 | |
478 @VisibleForTesting | 453 @VisibleForTesting |
479 static class ImeState { | 454 static class ImeState { |
480 public final String text; | 455 public final String text; |
481 public final int selectionStart; | 456 public final int selectionStart; |
482 public final int selectionEnd; | 457 public final int selectionEnd; |
483 public final int compositionStart; | 458 public final int compositionStart; |
484 public final int compositionEnd; | 459 public final int compositionEnd; |
485 | 460 |
486 public ImeState(String text, int selectionStart, int selectionEnd, | 461 public ImeState(String text, int selectionStart, int selectionEnd, |
487 int compositionStart, int compositionEnd) { | 462 int compositionStart, int compositionEnd) { |
488 this.text = text; | 463 this.text = text; |
489 this.selectionStart = selectionStart; | 464 this.selectionStart = selectionStart; |
490 this.selectionEnd = selectionEnd; | 465 this.selectionEnd = selectionEnd; |
491 this.compositionStart = compositionStart; | 466 this.compositionStart = compositionStart; |
492 this.compositionEnd = compositionEnd; | 467 this.compositionEnd = compositionEnd; |
493 } | 468 } |
494 } | 469 } |
495 | 470 |
496 @VisibleForTesting | 471 @VisibleForTesting |
497 ImeState getImeStateForTesting() { | 472 ImeState getImeStateForTesting() { |
498 String text = mEditable.toString(); | 473 String text = mEditable.toString(); |
499 int selectionStart = Selection.getSelectionStart(mEditable); | 474 int selectionStart = Selection.getSelectionStart(mEditable); |
500 int selectionEnd = Selection.getSelectionEnd(mEditable); | 475 int selectionEnd = Selection.getSelectionEnd(mEditable); |
501 int compositionStart = getComposingSpanStart(mEditable); | 476 int compositionStart = getComposingSpanStart(mEditable); |
502 int compositionEnd = getComposingSpanEnd(mEditable); | 477 int compositionEnd = getComposingSpanEnd(mEditable); |
503 return new ImeState(text, selectionStart, selectionEnd, compositionStart
, compositionEnd); | 478 return new ImeState(text, selectionStart, selectionEnd, compositionStart
, compositionEnd); |
504 } | 479 } |
505 } | 480 } |
OLD | NEW |