Merge "Add support for maxlength text fields to WebViewInputConnection."
diff --git a/core/java/android/webkit/WebView.java b/core/java/android/webkit/WebView.java
index 424dd6d..af3bb4d 100644
--- a/core/java/android/webkit/WebView.java
+++ b/core/java/android/webkit/WebView.java
@@ -378,6 +378,7 @@
private int mInputType;
private int mImeOptions;
private String mHint;
+ private int mMaxLength;
public WebViewInputConnection() {
super(WebView.this, true);
@@ -412,13 +413,9 @@
Editable editable = getEditable();
int selectionStart = Selection.getSelectionStart(editable);
int selectionEnd = Selection.getSelectionEnd(editable);
+ text = limitReplaceTextByMaxLength(text, editable.length());
editable.replace(0, editable.length(), text);
- InputMethodManager imm = InputMethodManager.peekInstance();
- if (imm != null) {
- // Since the text has changed, do not allow the IME to replace the
- // existing text as though it were a completion.
- imm.restartInput(WebView.this);
- }
+ restartInput();
// Keep the previous selection.
selectionStart = Math.min(selectionStart, editable.length());
selectionEnd = Math.min(selectionEnd, editable.length());
@@ -429,14 +426,10 @@
Editable editable = getEditable();
int selectionStart = Selection.getSelectionStart(editable);
int selectionEnd = Selection.getSelectionEnd(editable);
+ text = limitReplaceTextByMaxLength(text, selectionEnd - selectionStart);
setNewText(selectionStart, selectionEnd, text);
editable.replace(selectionStart, selectionEnd, text);
- InputMethodManager imm = InputMethodManager.peekInstance();
- if (imm != null) {
- // Since the text has changed, do not allow the IME to replace the
- // existing text as though it were a completion.
- imm.restartInput(WebView.this);
- }
+ restartInput();
// Move caret to the end of the new text
int newCaret = selectionStart + text.length();
setSelection(newCaret, newCaret);
@@ -456,8 +449,19 @@
end = start;
start = temp;
}
- setNewText(start, end, text);
- return super.setComposingText(text, newCursorPosition);
+ CharSequence limitedText = limitReplaceTextByMaxLength(text, end - start);
+ setNewText(start, end, limitedText);
+ if (limitedText != text) {
+ newCursorPosition -= text.length() - limitedText.length();
+ }
+ super.setComposingText(limitedText, newCursorPosition);
+ if (limitedText != text) {
+ restartInput();
+ int lastCaret = start + limitedText.length();
+ finishComposingText();
+ setSelection(lastCaret, lastCaret);
+ }
+ return true;
}
@Override
@@ -573,6 +577,7 @@
mHint = initData.mLabel;
mInputType = inputType;
mImeOptions = imeOptions;
+ mMaxLength = initData.mMaxLength;
}
public void setupEditorInfo(EditorInfo outAttrs) {
@@ -660,6 +665,29 @@
KeyCharacterMap.VIRTUAL_KEYBOARD, 0,
KeyEvent.FLAG_SOFT_KEYBOARD));
}
+
+ private CharSequence limitReplaceTextByMaxLength(CharSequence text,
+ int numReplaced) {
+ if (mMaxLength > 0) {
+ Editable editable = getEditable();
+ int maxReplace = mMaxLength - editable.length() + numReplaced;
+ if (maxReplace < text.length()) {
+ maxReplace = Math.max(maxReplace, 0);
+ // New length is greater than the maximum. trim it down.
+ text = text.subSequence(0, maxReplace);
+ }
+ }
+ return text;
+ }
+
+ private void restartInput() {
+ InputMethodManager imm = InputMethodManager.peekInstance();
+ if (imm != null) {
+ // Since the text has changed, do not allow the IME to replace the
+ // existing text as though it were a completion.
+ imm.restartInput(WebView.this);
+ }
+ }
}
private class PastePopupWindow extends PopupWindow implements OnClickListener {
diff --git a/core/java/android/webkit/WebViewCore.java b/core/java/android/webkit/WebViewCore.java
index e7da1a8..93fd92b 100644
--- a/core/java/android/webkit/WebViewCore.java
+++ b/core/java/android/webkit/WebViewCore.java
@@ -923,13 +923,14 @@
static class TextFieldInitData {
public TextFieldInitData(int fieldPointer,
String text, int type, boolean isSpellCheckEnabled,
- boolean isTextFieldNext, String label) {
+ boolean isTextFieldNext, String label, int maxLength) {
mFieldPointer = fieldPointer;
mText = text;
mType = type;
mIsSpellCheckEnabled = isSpellCheckEnabled;
mIsTextFieldNext = isTextFieldNext;
mLabel = label;
+ mMaxLength = maxLength;
}
int mFieldPointer;
String mText;
@@ -937,6 +938,7 @@
boolean mIsSpellCheckEnabled;
boolean mIsTextFieldNext;
String mLabel;
+ int mMaxLength;
}
// mAction of TouchEventData can be MotionEvent.getAction() which uses the
@@ -2826,12 +2828,13 @@
// called by JNI
private void initEditField(int pointer, String text, int inputType,
boolean isSpellCheckEnabled, boolean nextFieldIsText,
- String label, int start, int end, int selectionPtr) {
+ String label, int start, int end, int selectionPtr, int maxLength) {
if (mWebView == null) {
return;
}
TextFieldInitData initData = new TextFieldInitData(pointer,
- text, inputType, isSpellCheckEnabled, nextFieldIsText, label);
+ text, inputType, isSpellCheckEnabled, nextFieldIsText, label,
+ maxLength);
Message.obtain(mWebView.mPrivateHandler,
WebView.INIT_EDIT_FIELD, initData).sendToTarget();
Message.obtain(mWebView.mPrivateHandler,