Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 6012edec authored by George Mount's avatar George Mount
Browse files

Add support for maxlength text fields to WebViewInputConnection.

 Bug 6083776
 While WebKit limits the length of a field with maxlength, the
 InputConnection can get out of sync with it when it doesn't
 recognize that the characters haven't been changed. Adds
 maximum field length to WebViewInputConnection to limit the
 characters typed.
 WebKit Change: Ie02f82a3f5b3527c378938d93bac2dece802af26

Change-Id: I135871db7809e8dc28a3ad8d3aa852976a274555
parent cbd01c31
Loading
Loading
Loading
Loading
+42 −14
Original line number Diff line number Diff line
@@ -378,6 +378,7 @@ public class WebView extends AbsoluteLayout
        private int mInputType;
        private int mImeOptions;
        private String mHint;
        private int mMaxLength;

        public WebViewInputConnection() {
            super(WebView.this, true);
@@ -412,13 +413,9 @@ public class WebView extends AbsoluteLayout
            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 @@ public class WebView extends AbsoluteLayout
            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 @@ public class WebView extends AbsoluteLayout
                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
@@ -541,6 +545,7 @@ public class WebView extends AbsoluteLayout
            mHint = initData.mLabel;
            mInputType = inputType;
            mImeOptions = imeOptions;
            mMaxLength = initData.mMaxLength;
        }

        public void setupEditorInfo(EditorInfo outAttrs) {
@@ -626,6 +631,29 @@ public class WebView extends AbsoluteLayout
                    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 {
+6 −3
Original line number Diff line number Diff line
@@ -923,13 +923,14 @@ public final class WebViewCore {
    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 @@ public final class WebViewCore {
        boolean mIsSpellCheckEnabled;
        boolean mIsTextFieldNext;
        String mLabel;
        int mMaxLength;
    }

    // mAction of TouchEventData can be MotionEvent.getAction() which uses the
@@ -2826,12 +2828,13 @@ public final class WebViewCore {
    // 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,