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 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
132 * selection. | 131 * selection. |
133 * @param isNonImeChange True when the update was caused by non-IME (e.g. Ja vascript). | 132 * @param isNonImeChange True when the update was caused by non-IME (e.g. Ja vascript). |
134 */ | 133 */ |
135 @VisibleForTesting | 134 @VisibleForTesting |
136 public void updateState(String text, int selectionStart, int selectionEnd, i nt compositionStart, | 135 public void updateState(String text, int selectionStart, int selectionEnd, i nt compositionStart, |
137 int compositionEnd, boolean isNonImeChange) { | 136 int compositionEnd, boolean isNonImeChange) { |
138 if (DEBUG) { | 137 if (DEBUG) { |
139 Log.w(TAG, "updateState [" + text + "] [" + selectionStart + " " + s electionEnd + "] [" | 138 Log.w(TAG, "updateState [" + text + "] [" + selectionStart + " " + s electionEnd + "] [" |
140 + compositionStart + " " + compositionEnd + "] [" + isNonIme Change + "]"); | 139 + compositionStart + " " + compositionEnd + "] [" + isNonIme Change + "]"); |
141 } | 140 } |
141 | |
aurimas (slooooooooow)
2014/07/22 16:25:43
Undo this new line change.
bcwhite
2014/07/22 17:28:33
Done.
| |
142 // If this update is from the IME, no further state modification is nece ssary because the | 142 // If this update is from the IME, no further state modification is nece ssary because the |
143 // state should have been updated already by the IM framework directly. | 143 // state should have been updated already by the IM framework directly. |
144 if (!isNonImeChange) return; | 144 if (!isNonImeChange) return; |
145 | 145 |
146 // Non-breaking spaces can cause the IME to get confused. Replace with n ormal spaces. | 146 // Non-breaking spaces can cause the IME to get confused. Replace with n ormal spaces. |
147 text = text.replace('\u00A0', ' '); | 147 text = text.replace('\u00A0', ' '); |
148 | 148 |
149 selectionStart = Math.min(selectionStart, text.length()); | 149 selectionStart = Math.min(selectionStart, text.length()); |
150 selectionEnd = Math.min(selectionEnd, text.length()); | 150 selectionEnd = Math.min(selectionEnd, text.length()); |
151 compositionStart = Math.min(compositionStart, text.length()); | 151 compositionStart = Math.min(compositionStart, text.length()); |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
206 mLastUpdateCompositionStart = compositionStart; | 206 mLastUpdateCompositionStart = compositionStart; |
207 mLastUpdateCompositionEnd = compositionEnd; | 207 mLastUpdateCompositionEnd = compositionEnd; |
208 } | 208 } |
209 | 209 |
210 /** | 210 /** |
211 * @see BaseInputConnection#setComposingText(java.lang.CharSequence, int) | 211 * @see BaseInputConnection#setComposingText(java.lang.CharSequence, int) |
212 */ | 212 */ |
213 @Override | 213 @Override |
214 public boolean setComposingText(CharSequence text, int newCursorPosition) { | 214 public boolean setComposingText(CharSequence text, int newCursorPosition) { |
215 if (DEBUG) Log.w(TAG, "setComposingText [" + text + "] [" + newCursorPos ition + "]"); | 215 if (DEBUG) Log.w(TAG, "setComposingText [" + text + "] [" + newCursorPos ition + "]"); |
216 if (maybePerformEmptyCompositionWorkaround(text)) return true; | |
217 super.setComposingText(text, newCursorPosition); | 216 super.setComposingText(text, newCursorPosition); |
218 updateSelectionIfRequired(); | 217 updateSelectionIfRequired(); |
219 return mImeAdapter.checkCompositionQueueAndCallNative(text, newCursorPos ition, false); | 218 return mImeAdapter.checkCompositionQueueAndCallNative(text, newCursorPos ition, false); |
220 } | 219 } |
221 | 220 |
222 /** | 221 /** |
223 * @see BaseInputConnection#commitText(java.lang.CharSequence, int) | 222 * @see BaseInputConnection#commitText(java.lang.CharSequence, int) |
224 */ | 223 */ |
225 @Override | 224 @Override |
226 public boolean commitText(CharSequence text, int newCursorPosition) { | 225 public boolean commitText(CharSequence text, int newCursorPosition) { |
227 if (DEBUG) Log.w(TAG, "commitText [" + text + "] [" + newCursorPosition + "]"); | 226 if (DEBUG) Log.w(TAG, "commitText [" + text + "] [" + newCursorPosition + "]"); |
228 if (maybePerformEmptyCompositionWorkaround(text)) return true; | |
229 super.commitText(text, newCursorPosition); | 227 super.commitText(text, newCursorPosition); |
230 updateSelectionIfRequired(); | 228 updateSelectionIfRequired(); |
231 return mImeAdapter.checkCompositionQueueAndCallNative(text, newCursorPos ition, | 229 return mImeAdapter.checkCompositionQueueAndCallNative(text, newCursorPos ition, |
232 text.length() > 0); | 230 text.length() > 0); |
233 } | 231 } |
234 | 232 |
235 /** | 233 /** |
236 * @see BaseInputConnection#performEditorAction(int) | 234 * @see BaseInputConnection#performEditorAction(int) |
237 */ | 235 */ |
238 @Override | 236 @Override |
(...skipping 214 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
453 if (b < 0) b = 0; | 451 if (b < 0) b = 0; |
454 if (a > textLength) a = textLength; | 452 if (a > textLength) a = textLength; |
455 if (b > textLength) b = textLength; | 453 if (b > textLength) b = textLength; |
456 | 454 |
457 if (a == b) { | 455 if (a == b) { |
458 removeComposingSpans(mEditable); | 456 removeComposingSpans(mEditable); |
459 } else { | 457 } else { |
460 super.setComposingRegion(a, b); | 458 super.setComposingRegion(a, b); |
461 } | 459 } |
462 updateSelectionIfRequired(); | 460 updateSelectionIfRequired(); |
463 return mImeAdapter.setComposingRegion(a, b); | 461 |
462 CharSequence regionText = null; | |
463 if (b > a) { | |
464 regionText = mEditable.subSequence(start, end); | |
465 } | |
466 return mImeAdapter.setComposingRegion(regionText, a, b); | |
464 } | 467 } |
465 | 468 |
466 boolean isActive() { | 469 boolean isActive() { |
467 return getInputMethodManagerWrapper().isActive(mInternalView); | 470 return getInputMethodManagerWrapper().isActive(mInternalView); |
468 } | 471 } |
469 | 472 |
470 private InputMethodManagerWrapper getInputMethodManagerWrapper() { | 473 private InputMethodManagerWrapper getInputMethodManagerWrapper() { |
471 return mImeAdapter.getInputMethodManagerWrapper(); | 474 return mImeAdapter.getInputMethodManagerWrapper(); |
472 } | 475 } |
473 | 476 |
474 /** | |
475 * This method works around the issue crbug.com/373934 where Blink does not cancel | |
476 * the composition when we send a commit with the empty text. | |
477 * | |
478 * TODO(aurimas) Remove this once crbug.com/373934 is fixed. | |
479 * | |
480 * @param text Text that software keyboard requested to commit. | |
481 * @return Whether the workaround was performed. | |
482 */ | |
483 private boolean maybePerformEmptyCompositionWorkaround(CharSequence text) { | |
aurimas (slooooooooow)
2014/07/22 16:25:43
I was under impression that you did not want to re
bcwhite
2014/07/22 17:28:33
I wasn't going to. But apparently I must have tri
aurimas (slooooooooow)
2014/07/22 17:48:10
Let's land it as a separate CL in case it needs to
| |
484 int selectionStart = Selection.getSelectionStart(mEditable); | |
485 int selectionEnd = Selection.getSelectionEnd(mEditable); | |
486 int compositionStart = getComposingSpanStart(mEditable); | |
487 int compositionEnd = getComposingSpanEnd(mEditable); | |
488 if (TextUtils.isEmpty(text) && (selectionStart == selectionEnd) | |
489 && compositionStart != INVALID_COMPOSITION | |
490 && compositionEnd != INVALID_COMPOSITION) { | |
491 beginBatchEdit(); | |
492 finishComposingText(); | |
493 int selection = Selection.getSelectionStart(mEditable); | |
494 deleteSurroundingText(selection - compositionStart, selection - comp ositionEnd); | |
495 endBatchEdit(); | |
496 return true; | |
497 } | |
498 return false; | |
499 } | |
500 | |
501 @VisibleForTesting | 477 @VisibleForTesting |
502 static class ImeState { | 478 static class ImeState { |
503 public final String text; | 479 public final String text; |
504 public final int selectionStart; | 480 public final int selectionStart; |
505 public final int selectionEnd; | 481 public final int selectionEnd; |
506 public final int compositionStart; | 482 public final int compositionStart; |
507 public final int compositionEnd; | 483 public final int compositionEnd; |
508 | 484 |
509 public ImeState(String text, int selectionStart, int selectionEnd, | 485 public ImeState(String text, int selectionStart, int selectionEnd, |
510 int compositionStart, int compositionEnd) { | 486 int compositionStart, int compositionEnd) { |
511 this.text = text; | 487 this.text = text; |
512 this.selectionStart = selectionStart; | 488 this.selectionStart = selectionStart; |
513 this.selectionEnd = selectionEnd; | 489 this.selectionEnd = selectionEnd; |
514 this.compositionStart = compositionStart; | 490 this.compositionStart = compositionStart; |
515 this.compositionEnd = compositionEnd; | 491 this.compositionEnd = compositionEnd; |
516 } | 492 } |
517 } | 493 } |
518 | 494 |
519 @VisibleForTesting | 495 @VisibleForTesting |
520 ImeState getImeStateForTesting() { | 496 ImeState getImeStateForTesting() { |
521 String text = mEditable.toString(); | 497 String text = mEditable.toString(); |
522 int selectionStart = Selection.getSelectionStart(mEditable); | 498 int selectionStart = Selection.getSelectionStart(mEditable); |
523 int selectionEnd = Selection.getSelectionEnd(mEditable); | 499 int selectionEnd = Selection.getSelectionEnd(mEditable); |
524 int compositionStart = getComposingSpanStart(mEditable); | 500 int compositionStart = getComposingSpanStart(mEditable); |
525 int compositionEnd = getComposingSpanEnd(mEditable); | 501 int compositionEnd = getComposingSpanEnd(mEditable); |
526 return new ImeState(text, selectionStart, selectionEnd, compositionStart , compositionEnd); | 502 return new ImeState(text, selectionStart, selectionEnd, compositionStart , compositionEnd); |
527 } | 503 } |
528 } | 504 } |
OLD | NEW |