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

Commit 0caa4cef authored by George Mount's avatar George Mount
Browse files

Use a node pointer to identify content-editable fields.

 Bug 5946645
 Webkit change: I915b49c6161fc0604e584699ec96cc86ba96ac79

Change-Id: I0b1c52a6c78f2a2bc16a69fa97f21655af3209d3
parent 175df115
Loading
Loading
Loading
Loading
+58 −21
Original line number Diff line number Diff line
@@ -367,11 +367,51 @@ public class WebView extends AbsoluteLayout
    private class WebViewInputConnection extends BaseInputConnection {
        // Used for mapping characters to keys typed.
        private KeyCharacterMap mKeyCharacterMap;
        private boolean mIsKeySentByMe;

        public WebViewInputConnection() {
            super(WebView.this, true);
        }

        @Override
        public boolean sendKeyEvent(KeyEvent event) {
            // Latin IME occasionally sends delete codes directly using
            // sendKeyEvents. WebViewInputConnection should treat this
            // as a deleteSurroundingText.
            if (!mIsKeySentByMe
                    && event.getKeyCode() == KeyEvent.KEYCODE_DEL) {
                Editable editable = getEditable();
                int selectionStart = Selection.getSelectionStart(editable);
                int selectionEnd = Selection.getSelectionEnd(editable);
                if (selectionEnd > 0 && (selectionStart == selectionEnd)) {
                    int action = event.getAction();
                    if (action == KeyEvent.ACTION_UP) {
                        return deleteSurroundingText(1, 0);
                    } else if (action == KeyEvent.ACTION_DOWN) {
                        return true; // the delete will happen in ACTION_UP
                    }
                }
            }
            return super.sendKeyEvent(event);
        }

        public void setTextAndKeepSelection(CharSequence text) {
            Editable editable = getEditable();
            int selectionStart = Selection.getSelectionStart(editable);
            int selectionEnd = Selection.getSelectionEnd(editable);
            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);
            }
            // Keep the previous selection.
            selectionStart = Math.min(selectionStart, editable.length());
            selectionEnd = Math.min(selectionEnd, editable.length());
            setSelection(selectionStart, selectionEnd);
        }

        @Override
        public boolean setComposingText(CharSequence text, int newCursorPosition) {
            Editable editable = getEditable();
@@ -393,7 +433,8 @@ public class WebView extends AbsoluteLayout
        @Override
        public boolean commitText(CharSequence text, int newCursorPosition) {
            setComposingText(text, newCursorPosition);
            finishComposingText();
            int cursorPosition = Selection.getSelectionEnd(getEditable());
            setComposingRegion(cursorPosition, cursorPosition);
            return true;
        }

@@ -417,6 +458,7 @@ public class WebView extends AbsoluteLayout
         * @param text The new text to replace the changed text.
         */
        private void setNewText(int start, int end, CharSequence text) {
            mIsKeySentByMe = true;
            Editable editable = getEditable();
            CharSequence original = editable.subSequence(start, end);
            boolean isCharacterAdd = false;
@@ -434,10 +476,8 @@ public class WebView extends AbsoluteLayout
            }
            if (isCharacterAdd) {
                sendCharacter(text.charAt(textLength - 1));
                mTextGeneration++;
            } else if (isCharacterDelete) {
                sendDeleteKey();
                mTextGeneration++;
            } else if (textLength != originalLength ||
                    !TextUtils.regionMatches(text, 0, original, 0,
                            textLength)) {
@@ -447,6 +487,7 @@ public class WebView extends AbsoluteLayout
                        REPLACE_TEXT, start,  end, text.toString());
                mPrivateHandler.sendMessage(replaceMessage);
            }
            mIsKeySentByMe = false;
        }

        /**
@@ -509,7 +550,7 @@ public class WebView extends AbsoluteLayout
    private final RectF mVisibleContentRect = new RectF();
    private boolean mGLViewportEmpty = false;
    WebViewInputConnection mInputConnection = null;

    private int mFieldPointer;

    /**
     *  Transportation object for returning WebView across thread boundaries.
@@ -8653,14 +8694,17 @@ public class WebView extends AbsoluteLayout
                case UPDATE_TEXTFIELD_TEXT_MSG_ID:
                    // Make sure that the textfield is currently focused
                    // and representing the same node as the pointer.
                    if (inEditingMode() &&
                            mWebTextView.isSameTextField(msg.arg1)) {
                    if (msg.arg2 == mTextGeneration) {
                        String text = (String) msg.obj;
                        if (null == text) {
                            text = "";
                        }
                        if (inEditingMode() &&
                                mWebTextView.isSameTextField(msg.arg1)) {
                            mWebTextView.setTextAndKeepSelection(text);
                        } else if (mInputConnection != null &&
                                mFieldPointer == msg.arg1) {
                            mInputConnection.setTextAndKeepSelection(text);
                        }
                    }
                    break;
@@ -8951,15 +8995,8 @@ public class WebView extends AbsoluteLayout
                case INIT_EDIT_FIELD:
                    if (mInputConnection != null) {
                        mTextGeneration = 0;
                        String text = (String)msg.obj;
                        mInputConnection.beginBatchEdit();
                        Editable editable = mInputConnection.getEditable();
                        editable.replace(0, editable.length(), text);
                        int start = msg.arg1;
                        int end = msg.arg2;
                        mInputConnection.setComposingRegion(end, end);
                        mInputConnection.setSelection(start, end);
                        mInputConnection.endBatchEdit();
                        mFieldPointer = msg.arg1;
                        mInputConnection.setTextAndKeepSelection((String) msg.obj);
                    }
                    break;

@@ -9102,7 +9139,7 @@ public class WebView extends AbsoluteLayout
            if (inEditingMode()
                    && mWebTextView.isSameTextField(nodePointer)) {
                mWebTextView.setSelectionFromWebKit(data.mStart, data.mEnd);
            } else if (mInputConnection != null){
            } else if (mInputConnection != null && mFieldPointer == nodePointer) {
                mInputConnection.setSelection(data.mStart, data.mEnd);
            }
        }
+6 −13
Original line number Diff line number Diff line
@@ -2746,12 +2746,16 @@ public final class WebViewCore {
    }

    // called by JNI
    private void initEditField(String text, int start, int end) {
    private void initEditField(int pointer, String text, int start, int end) {
        if (mWebView == null) {
            return;
        }
        Message.obtain(mWebView.mPrivateHandler,
                WebView.INIT_EDIT_FIELD, start, end, text).sendToTarget();
                WebView.INIT_EDIT_FIELD, pointer, 0, text).sendToTarget();
        Message.obtain(mWebView.mPrivateHandler,
                WebView.REQUEST_KEYBOARD_WITH_SELECTION_MSG_ID, pointer,
                0, new TextSelectionData(start, end, 0))
                .sendToTarget();
    }

    private native void nativeUpdateFrameCacheIfLoading(int nativeClass);
@@ -2788,17 +2792,6 @@ public final class WebViewCore {

    }

    // called by JNI
    private void requestKeyboardWithSelection(int pointer, int selStart,
            int selEnd, int textGeneration) {
        if (mWebView != null) {
            Message.obtain(mWebView.mPrivateHandler,
                    WebView.REQUEST_KEYBOARD_WITH_SELECTION_MSG_ID, pointer,
                    textGeneration, new TextSelectionData(selStart, selEnd, 0))
                    .sendToTarget();
        }
    }

    // called by JNI
    private void requestKeyboard(boolean showKeyboard) {
        if (mWebView != null) {