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; |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
70 | EditorInfo.TYPE_TEXT_VARIATION_WEB_EDIT_TEXT; | 70 | EditorInfo.TYPE_TEXT_VARIATION_WEB_EDIT_TEXT; |
71 | 71 |
72 int inputType = imeAdapter.getTextInputType(); | 72 int inputType = imeAdapter.getTextInputType(); |
73 int inputFlags = imeAdapter.getTextInputFlags(); | 73 int inputFlags = imeAdapter.getTextInputFlags(); |
74 if ((inputFlags & WebTextInputFlags.AutocompleteOff) != 0) { | 74 if ((inputFlags & WebTextInputFlags.AutocompleteOff) != 0) { |
75 outAttrs.inputType |= EditorInfo.TYPE_TEXT_FLAG_NO_SUGGESTIONS; | 75 outAttrs.inputType |= EditorInfo.TYPE_TEXT_FLAG_NO_SUGGESTIONS; |
76 } | 76 } |
77 | 77 |
78 if (inputType == TextInputType.TEXT) { | 78 if (inputType == TextInputType.TEXT) { |
79 // Normal text field | 79 // Normal text field |
80 outAttrs.imeOptions |= EditorInfo.IME_ACTION_GO; | |
81 if ((inputFlags & WebTextInputFlags.AutocorrectOff) == 0) { | 80 if ((inputFlags & WebTextInputFlags.AutocorrectOff) == 0) { |
82 outAttrs.inputType |= EditorInfo.TYPE_TEXT_FLAG_AUTO_CORRECT; | 81 outAttrs.inputType |= EditorInfo.TYPE_TEXT_FLAG_AUTO_CORRECT; |
83 } | 82 } |
84 } else if (inputType == TextInputType.TEXT_AREA | 83 } else if (inputType == TextInputType.TEXT_AREA |
85 || inputType == TextInputType.CONTENT_EDITABLE) { | 84 || inputType == TextInputType.CONTENT_EDITABLE) { |
86 outAttrs.inputType |= EditorInfo.TYPE_TEXT_FLAG_MULTI_LINE; | 85 outAttrs.inputType |= EditorInfo.TYPE_TEXT_FLAG_MULTI_LINE; |
87 if ((inputFlags & WebTextInputFlags.AutocorrectOff) == 0) { | 86 if ((inputFlags & WebTextInputFlags.AutocorrectOff) == 0) { |
88 outAttrs.inputType |= EditorInfo.TYPE_TEXT_FLAG_AUTO_CORRECT; | 87 outAttrs.inputType |= EditorInfo.TYPE_TEXT_FLAG_AUTO_CORRECT; |
89 } | 88 } |
90 outAttrs.imeOptions |= EditorInfo.IME_ACTION_NONE; | |
91 mSingleLine = false; | 89 mSingleLine = false; |
92 } else if (inputType == TextInputType.PASSWORD) { | 90 } else if (inputType == TextInputType.PASSWORD) { |
93 // Password | 91 // Password |
94 outAttrs.inputType = InputType.TYPE_CLASS_TEXT | 92 outAttrs.inputType = InputType.TYPE_CLASS_TEXT |
95 | InputType.TYPE_TEXT_VARIATION_WEB_PASSWORD; | 93 | InputType.TYPE_TEXT_VARIATION_WEB_PASSWORD; |
96 outAttrs.imeOptions |= EditorInfo.IME_ACTION_GO; | |
97 } else if (inputType == TextInputType.SEARCH) { | 94 } else if (inputType == TextInputType.SEARCH) { |
98 // Search | 95 // Search |
99 outAttrs.imeOptions |= EditorInfo.IME_ACTION_SEARCH; | 96 outAttrs.imeOptions |= EditorInfo.IME_ACTION_SEARCH; |
100 } else if (inputType == TextInputType.URL) { | 97 } else if (inputType == TextInputType.URL) { |
101 // Url | 98 // Url |
102 outAttrs.inputType = InputType.TYPE_CLASS_TEXT | 99 outAttrs.inputType = InputType.TYPE_CLASS_TEXT |
103 | InputType.TYPE_TEXT_VARIATION_URI; | 100 | InputType.TYPE_TEXT_VARIATION_URI; |
104 outAttrs.imeOptions |= EditorInfo.IME_ACTION_GO; | |
105 } else if (inputType == TextInputType.EMAIL) { | 101 } else if (inputType == TextInputType.EMAIL) { |
106 // Email | 102 // Email |
107 outAttrs.inputType = InputType.TYPE_CLASS_TEXT | 103 outAttrs.inputType = InputType.TYPE_CLASS_TEXT |
108 | InputType.TYPE_TEXT_VARIATION_WEB_EMAIL_ADDRESS; | 104 | InputType.TYPE_TEXT_VARIATION_WEB_EMAIL_ADDRESS; |
109 outAttrs.imeOptions |= EditorInfo.IME_ACTION_GO; | |
110 } else if (inputType == TextInputType.TELEPHONE) { | 105 } else if (inputType == TextInputType.TELEPHONE) { |
111 // Telephone | 106 // Telephone |
112 // Number and telephone do not have both a Tab key and an | 107 // Number and telephone do not have both a Tab key and an |
113 // action in default OSK, so set the action to NEXT | 108 // action in default OSK, so set the action to NEXT |
114 outAttrs.inputType = InputType.TYPE_CLASS_PHONE; | 109 outAttrs.inputType = InputType.TYPE_CLASS_PHONE; |
115 outAttrs.imeOptions |= EditorInfo.IME_ACTION_NEXT; | |
116 } else if (inputType == TextInputType.NUMBER) { | 110 } else if (inputType == TextInputType.NUMBER) { |
117 // Number | 111 // Number |
118 outAttrs.inputType = InputType.TYPE_CLASS_NUMBER | 112 outAttrs.inputType = InputType.TYPE_CLASS_NUMBER |
119 | InputType.TYPE_NUMBER_VARIATION_NORMAL | 113 | InputType.TYPE_NUMBER_VARIATION_NORMAL |
120 | InputType.TYPE_NUMBER_FLAG_DECIMAL; | 114 | InputType.TYPE_NUMBER_FLAG_DECIMAL; |
| 115 } |
| 116 |
| 117 if ((inputFlags & WebTextInputFlags.HaveNextFocusableElement) != 0) { |
121 outAttrs.imeOptions |= EditorInfo.IME_ACTION_NEXT; | 118 outAttrs.imeOptions |= EditorInfo.IME_ACTION_NEXT; |
122 } | 119 } |
| 120 if ((inputFlags & WebTextInputFlags.HavePreviousFocusableElement) != 0)
{ |
| 121 outAttrs.imeOptions |= EditorInfo.IME_ACTION_PREVIOUS; |
| 122 } |
| 123 if (mSingleLine && (inputFlags & WebTextInputFlags.ListeningToKeyboardEv
ents) == 0) { |
| 124 // TODO(ajith.v) Find an option to remove Enter Key from IME (assume
by default |
| 125 // ENTER key is shown) |
| 126 // TODO(ajith.v) For text area with implicit form submission how do
we handle, |
| 127 // we need to show both GO and ENTER key at same time. |
| 128 outAttrs.imeOptions |= EditorInfo.IME_ACTION_GO; |
| 129 } |
123 | 130 |
124 // Handling of autocapitalize. Blink will send the flag taking into acco
unt the element's | 131 // Handling of autocapitalize. Blink will send the flag taking into acco
unt the element's |
125 // type. This is not using AutocapitalizeNone because Android does not a
utocapitalize by | 132 // type. This is not using AutocapitalizeNone because Android does not a
utocapitalize by |
126 // default and there is no way to express no capitalization. | 133 // default and there is no way to express no capitalization. |
127 // Autocapitalize is meant as a hint to the virtual keyboard. | 134 // Autocapitalize is meant as a hint to the virtual keyboard. |
128 if ((inputFlags & WebTextInputFlags.AutocapitalizeCharacters) != 0) { | 135 if ((inputFlags & WebTextInputFlags.AutocapitalizeCharacters) != 0) { |
129 outAttrs.inputType |= InputType.TYPE_TEXT_FLAG_CAP_CHARACTERS; | 136 outAttrs.inputType |= InputType.TYPE_TEXT_FLAG_CAP_CHARACTERS; |
130 } else if ((inputFlags & WebTextInputFlags.AutocapitalizeWords) != 0) { | 137 } else if ((inputFlags & WebTextInputFlags.AutocapitalizeWords) != 0) { |
131 outAttrs.inputType |= InputType.TYPE_TEXT_FLAG_CAP_WORDS; | 138 outAttrs.inputType |= InputType.TYPE_TEXT_FLAG_CAP_WORDS; |
132 } else if ((inputFlags & WebTextInputFlags.AutocapitalizeSentences) != 0
) { | 139 } else if ((inputFlags & WebTextInputFlags.AutocapitalizeSentences) != 0
) { |
(...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
274 return mImeAdapter.checkCompositionQueueAndCallNative(text, newCursorPos
ition, | 281 return mImeAdapter.checkCompositionQueueAndCallNative(text, newCursorPos
ition, |
275 text.length() > 0); | 282 text.length() > 0); |
276 } | 283 } |
277 | 284 |
278 /** | 285 /** |
279 * @see BaseInputConnection#performEditorAction(int) | 286 * @see BaseInputConnection#performEditorAction(int) |
280 */ | 287 */ |
281 @Override | 288 @Override |
282 public boolean performEditorAction(int actionCode) { | 289 public boolean performEditorAction(int actionCode) { |
283 if (DEBUG) Log.w(TAG, "performEditorAction [" + actionCode + "]"); | 290 if (DEBUG) Log.w(TAG, "performEditorAction [" + actionCode + "]"); |
284 if (actionCode == EditorInfo.IME_ACTION_NEXT) { | 291 switch (actionCode) { |
285 restartInput(); | 292 case EditorInfo.IME_ACTION_NEXT: |
286 // Send TAB key event | 293 restartInput(); |
287 long timeStampMs = SystemClock.uptimeMillis(); | 294 mImeAdapter.advanceFocusInForm(true); |
288 mImeAdapter.sendSyntheticKeyEvent( | 295 break; |
289 WebInputEventType.RawKeyDown, timeStampMs, KeyEvent.KEYCODE_
TAB, 0, 0); | 296 case EditorInfo.IME_ACTION_PREVIOUS: |
290 } else { | 297 restartInput(); |
291 mImeAdapter.sendKeyEventWithKeyCode(KeyEvent.KEYCODE_ENTER, | 298 mImeAdapter.advanceFocusInForm(false); |
292 KeyEvent.FLAG_SOFT_KEYBOARD | KeyEvent.FLAG_KEEP_TOUCH_MODE | 299 break; |
293 | KeyEvent.FLAG_EDITOR_ACTION); | 300 default: |
| 301 mImeAdapter.sendKeyEventWithKeyCode( |
| 302 KeyEvent.KEYCODE_ENTER, KeyEvent.FLAG_SOFT_KEYBOARD |
| 303 | KeyEvent.FLAG_KEEP_TOUCH_MODE | KeyEvent.FLAG_
EDITOR_ACTION); |
| 304 break; |
294 } | 305 } |
295 return true; | 306 return true; |
296 } | 307 } |
297 | 308 |
298 /** | 309 /** |
299 * @see BaseInputConnection#performContextMenuAction(int) | 310 * @see BaseInputConnection#performContextMenuAction(int) |
300 */ | 311 */ |
301 @Override | 312 @Override |
302 public boolean performContextMenuAction(int id) { | 313 public boolean performContextMenuAction(int id) { |
303 if (DEBUG) Log.w(TAG, "performContextMenuAction [" + id + "]"); | 314 if (DEBUG) Log.w(TAG, "performContextMenuAction [" + id + "]"); |
(...skipping 318 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
622 @VisibleForTesting | 633 @VisibleForTesting |
623 ImeState getImeStateForTesting() { | 634 ImeState getImeStateForTesting() { |
624 String text = mEditable.toString(); | 635 String text = mEditable.toString(); |
625 int selectionStart = Selection.getSelectionStart(mEditable); | 636 int selectionStart = Selection.getSelectionStart(mEditable); |
626 int selectionEnd = Selection.getSelectionEnd(mEditable); | 637 int selectionEnd = Selection.getSelectionEnd(mEditable); |
627 int compositionStart = getComposingSpanStart(mEditable); | 638 int compositionStart = getComposingSpanStart(mEditable); |
628 int compositionEnd = getComposingSpanEnd(mEditable); | 639 int compositionEnd = getComposingSpanEnd(mEditable); |
629 return new ImeState(text, selectionStart, selectionEnd, compositionStart
, compositionEnd); | 640 return new ImeState(text, selectionStart, selectionEnd, compositionStart
, compositionEnd); |
630 } | 641 } |
631 } | 642 } |
OLD | NEW |