Loading core/java/android/webkit/WebView.java +96 −30 Original line number Diff line number Diff line Loading @@ -908,14 +908,22 @@ public class WebView extends AbsoluteLayout // know to handle Shift and arrows natively first private boolean mAccessibilityScriptInjected; /** * How long the caret handle will last without being touched. */ private static final long CARET_HANDLE_STAMINA_MS = 3000; private Drawable mSelectHandleLeft; private Drawable mSelectHandleRight; private Drawable mSelectHandleCenter; private Rect mSelectCursorBase = new Rect(); private int mSelectCursorBaseLayerId; private Rect mSelectCursorExtent = new Rect(); private int mSelectCursorExtentLayerId; private Rect mSelectDraggingCursor; private Point mSelectDraggingOffset = new Point(); private boolean mIsCaretSelection; static final int HANDLE_ID_START = 0; static final int HANDLE_ID_END = 1; static final int HANDLE_ID_BASE = 2; Loading Loading @@ -1012,6 +1020,7 @@ public class WebView extends AbsoluteLayout static final int COPY_TO_CLIPBOARD = 141; static final int INIT_EDIT_FIELD = 142; static final int REPLACE_TEXT = 143; static final int CLEAR_CARET_HANDLE = 144; private static final int FIRST_PACKAGE_MSG_ID = SCROLL_TO_MSG_ID; private static final int LAST_PACKAGE_MSG_ID = HIT_TEST_RESULT; Loading Loading @@ -5108,16 +5117,29 @@ public class WebView extends AbsoluteLayout } private void drawTextSelectionHandles(Canvas canvas) { if (mSelectHandleLeft == null) { mSelectHandleLeft = mContext.getResources().getDrawable( com.android.internal.R.drawable.text_select_handle_left); } int[] handles = new int[4]; getSelectionHandles(handles); int start_x = contentToViewDimension(handles[0]); int start_y = contentToViewDimension(handles[1]); int end_x = contentToViewDimension(handles[2]); int end_y = contentToViewDimension(handles[3]); if (mIsCaretSelection) { if (mSelectHandleCenter == null) { mSelectHandleCenter = mContext.getResources().getDrawable( com.android.internal.R.drawable.text_select_handle_middle); } // Caret handle is centered start_x -= (mSelectHandleCenter.getIntrinsicWidth() / 2); mSelectHandleCenter.setBounds(start_x, start_y, start_x + mSelectHandleCenter.getIntrinsicWidth(), start_y + mSelectHandleCenter.getIntrinsicHeight()); mSelectHandleCenter.draw(canvas); } else { if (mSelectHandleLeft == null) { mSelectHandleLeft = mContext.getResources().getDrawable( com.android.internal.R.drawable.text_select_handle_left); } // Magic formula copied from TextView start_x -= (mSelectHandleLeft.getIntrinsicWidth() * 3) / 4; mSelectHandleLeft.setBounds(start_x, start_y, Loading @@ -5134,6 +5156,7 @@ public class WebView extends AbsoluteLayout mSelectHandleLeft.draw(canvas); mSelectHandleRight.draw(canvas); } } /** * Takes an int[4] array as an output param with the values being Loading Loading @@ -5554,6 +5577,9 @@ public class WebView extends AbsoluteLayout + "keyCode=" + keyCode + ", " + event + ", unicode=" + event.getUnicodeChar()); } if (mIsCaretSelection) { selectionDone(); } if (mBlockWebkitViewMessages) { return false; } Loading Loading @@ -5866,6 +5892,7 @@ public class WebView extends AbsoluteLayout private boolean startSelectActionMode() { mSelectCallback = new SelectActionModeCallback(); mSelectCallback.setTextSelected(!mIsCaretSelection); mSelectCallback.setWebView(this); if (startActionMode(mSelectCallback) == null) { // There is no ActionMode, so do not allow the user to modify a Loading @@ -5886,10 +5913,14 @@ public class WebView extends AbsoluteLayout private boolean setupWebkitSelect() { syncSelectionCursors(); ClipboardManager cm = (ClipboardManager)(mContext .getSystemService(Context.CLIPBOARD_SERVICE)); if (!mIsCaretSelection || cm.hasPrimaryClip()) { if (!startSelectActionMode()) { selectionDone(); return false; } } mSelectingText = true; mTouchMode = TOUCH_DRAG_MODE; return true; Loading @@ -5897,6 +5928,9 @@ public class WebView extends AbsoluteLayout private void updateWebkitSelection() { int[] handles = null; if (mIsCaretSelection) { mSelectCursorExtent.set(mSelectCursorBase); } if (mSelectingText) { handles = new int[4]; handles[0] = mSelectCursorBase.centerX(); Loading @@ -5910,6 +5944,14 @@ public class WebView extends AbsoluteLayout mWebViewCore.sendMessageAtFrontOfQueue(EventHub.SELECT_TEXT, handles); } private void resetCaretTimer() { mPrivateHandler.removeMessages(CLEAR_CARET_HANDLE); if (!mSelectionStarted) { mPrivateHandler.sendEmptyMessageDelayed(CLEAR_CARET_HANDLE, CARET_HANDLE_STAMINA_MS); } } /** * Use this method to put the WebView into text selection mode. * Do not rely on this functionality; it will be deprecated in the future. Loading Loading @@ -5937,9 +5979,14 @@ public class WebView extends AbsoluteLayout mSelectingText = false; // finish is idempotent, so this is fine even if selectionDone was // called by mSelectCallback.onDestroyActionMode if (mSelectCallback != null) { mSelectCallback.finish(); mSelectCallback = null; } if (!mIsCaretSelection) { updateWebkitSelection(); } mIsCaretSelection = false; invalidate(); // redraw without selection mAutoScrollX = 0; mAutoScrollY = 0; Loading Loading @@ -6553,18 +6600,26 @@ public class WebView extends AbsoluteLayout (eventTime - mLastTouchUpTime), eventTime); } mSelectionStarted = false; if (mSelectingText && mSelectHandleLeft != null && mSelectHandleRight != null) { if (mSelectingText) { int shiftedY = y - getTitleHeight() + mScrollY; int shiftedX = x + mScrollX; if (mSelectHandleLeft.getBounds() if (mSelectHandleCenter != null && mSelectHandleCenter.getBounds() .contains(shiftedX, shiftedY)) { mSelectionStarted = true; mSelectDraggingCursor = mSelectCursorBase; } else if (mSelectHandleRight.getBounds() mPrivateHandler.removeMessages(CLEAR_CARET_HANDLE); } else if (mSelectHandleLeft != null && mSelectHandleLeft.getBounds() .contains(shiftedX, shiftedY)) { mSelectionStarted = true; mSelectDraggingCursor = mSelectCursorBase; } else if (mSelectHandleRight != null && mSelectHandleRight.getBounds() .contains(shiftedX, shiftedY)) { mSelectionStarted = true; mSelectDraggingCursor = mSelectCursorExtent; } else if (mIsCaretSelection) { selectionDone(); } if (mSelectDraggingCursor != null) { mSelectDraggingOffset.set( Loading Loading @@ -7215,6 +7270,9 @@ public class WebView extends AbsoluteLayout if (mSelectingText) { mSelectionStarted = false; if (mIsCaretSelection) { resetCaretTimer(); } syncSelectionCursors(); invalidate(); } Loading Loading @@ -9173,6 +9231,9 @@ public class WebView extends AbsoluteLayout } break; } case CLEAR_CARET_HANDLE: selectionDone(); break; default: super.handleMessage(msg); Loading Loading @@ -9423,14 +9484,19 @@ public class WebView extends AbsoluteLayout mInputConnection.setSelection(data.mStart, data.mEnd); } } nativeSetTextSelection(mNativeClass, data.mSelectTextPtr); if (data.mSelectTextPtr != 0) { mIsCaretSelection = (mFieldPointer == nodePointer) && (mFieldPointer != 0) && (data.mStart == data.mEnd); if (!mSelectingText) { setupWebkitSelect(); } else if (!mSelectionStarted) { syncSelectionCursors(); } if (mIsCaretSelection) { resetCaretTimer(); } } else { selectionDone(); } Loading core/java/android/webkit/WebViewCore.java +2 −2 Original line number Diff line number Diff line Loading @@ -2834,7 +2834,7 @@ 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) { String label, int start, int end, int selectionPtr) { if (mWebView == null) { return; } Loading @@ -2844,7 +2844,7 @@ public final class WebViewCore { WebView.INIT_EDIT_FIELD, initData).sendToTarget(); Message.obtain(mWebView.mPrivateHandler, WebView.REQUEST_KEYBOARD_WITH_SELECTION_MSG_ID, pointer, 0, new TextSelectionData(start, end, 0)) 0, new TextSelectionData(start, end, selectionPtr)) .sendToTarget(); } Loading core/res/res/values/public.xml +1 −0 Original line number Diff line number Diff line Loading @@ -962,6 +962,7 @@ <java-symbol type="drawable" name="tab_bottom_right_v4" /> <java-symbol type="drawable" name="tab_indicator_v4" /> <java-symbol type="drawable" name="text_select_handle_left" /> <java-symbol type="drawable" name="text_select_handle_middle" /> <java-symbol type="drawable" name="text_select_handle_right" /> <java-symbol type="drawable" name="unknown_image" /> <java-symbol type="drawable" name="unlock_default" /> Loading Loading
core/java/android/webkit/WebView.java +96 −30 Original line number Diff line number Diff line Loading @@ -908,14 +908,22 @@ public class WebView extends AbsoluteLayout // know to handle Shift and arrows natively first private boolean mAccessibilityScriptInjected; /** * How long the caret handle will last without being touched. */ private static final long CARET_HANDLE_STAMINA_MS = 3000; private Drawable mSelectHandleLeft; private Drawable mSelectHandleRight; private Drawable mSelectHandleCenter; private Rect mSelectCursorBase = new Rect(); private int mSelectCursorBaseLayerId; private Rect mSelectCursorExtent = new Rect(); private int mSelectCursorExtentLayerId; private Rect mSelectDraggingCursor; private Point mSelectDraggingOffset = new Point(); private boolean mIsCaretSelection; static final int HANDLE_ID_START = 0; static final int HANDLE_ID_END = 1; static final int HANDLE_ID_BASE = 2; Loading Loading @@ -1012,6 +1020,7 @@ public class WebView extends AbsoluteLayout static final int COPY_TO_CLIPBOARD = 141; static final int INIT_EDIT_FIELD = 142; static final int REPLACE_TEXT = 143; static final int CLEAR_CARET_HANDLE = 144; private static final int FIRST_PACKAGE_MSG_ID = SCROLL_TO_MSG_ID; private static final int LAST_PACKAGE_MSG_ID = HIT_TEST_RESULT; Loading Loading @@ -5108,16 +5117,29 @@ public class WebView extends AbsoluteLayout } private void drawTextSelectionHandles(Canvas canvas) { if (mSelectHandleLeft == null) { mSelectHandleLeft = mContext.getResources().getDrawable( com.android.internal.R.drawable.text_select_handle_left); } int[] handles = new int[4]; getSelectionHandles(handles); int start_x = contentToViewDimension(handles[0]); int start_y = contentToViewDimension(handles[1]); int end_x = contentToViewDimension(handles[2]); int end_y = contentToViewDimension(handles[3]); if (mIsCaretSelection) { if (mSelectHandleCenter == null) { mSelectHandleCenter = mContext.getResources().getDrawable( com.android.internal.R.drawable.text_select_handle_middle); } // Caret handle is centered start_x -= (mSelectHandleCenter.getIntrinsicWidth() / 2); mSelectHandleCenter.setBounds(start_x, start_y, start_x + mSelectHandleCenter.getIntrinsicWidth(), start_y + mSelectHandleCenter.getIntrinsicHeight()); mSelectHandleCenter.draw(canvas); } else { if (mSelectHandleLeft == null) { mSelectHandleLeft = mContext.getResources().getDrawable( com.android.internal.R.drawable.text_select_handle_left); } // Magic formula copied from TextView start_x -= (mSelectHandleLeft.getIntrinsicWidth() * 3) / 4; mSelectHandleLeft.setBounds(start_x, start_y, Loading @@ -5134,6 +5156,7 @@ public class WebView extends AbsoluteLayout mSelectHandleLeft.draw(canvas); mSelectHandleRight.draw(canvas); } } /** * Takes an int[4] array as an output param with the values being Loading Loading @@ -5554,6 +5577,9 @@ public class WebView extends AbsoluteLayout + "keyCode=" + keyCode + ", " + event + ", unicode=" + event.getUnicodeChar()); } if (mIsCaretSelection) { selectionDone(); } if (mBlockWebkitViewMessages) { return false; } Loading Loading @@ -5866,6 +5892,7 @@ public class WebView extends AbsoluteLayout private boolean startSelectActionMode() { mSelectCallback = new SelectActionModeCallback(); mSelectCallback.setTextSelected(!mIsCaretSelection); mSelectCallback.setWebView(this); if (startActionMode(mSelectCallback) == null) { // There is no ActionMode, so do not allow the user to modify a Loading @@ -5886,10 +5913,14 @@ public class WebView extends AbsoluteLayout private boolean setupWebkitSelect() { syncSelectionCursors(); ClipboardManager cm = (ClipboardManager)(mContext .getSystemService(Context.CLIPBOARD_SERVICE)); if (!mIsCaretSelection || cm.hasPrimaryClip()) { if (!startSelectActionMode()) { selectionDone(); return false; } } mSelectingText = true; mTouchMode = TOUCH_DRAG_MODE; return true; Loading @@ -5897,6 +5928,9 @@ public class WebView extends AbsoluteLayout private void updateWebkitSelection() { int[] handles = null; if (mIsCaretSelection) { mSelectCursorExtent.set(mSelectCursorBase); } if (mSelectingText) { handles = new int[4]; handles[0] = mSelectCursorBase.centerX(); Loading @@ -5910,6 +5944,14 @@ public class WebView extends AbsoluteLayout mWebViewCore.sendMessageAtFrontOfQueue(EventHub.SELECT_TEXT, handles); } private void resetCaretTimer() { mPrivateHandler.removeMessages(CLEAR_CARET_HANDLE); if (!mSelectionStarted) { mPrivateHandler.sendEmptyMessageDelayed(CLEAR_CARET_HANDLE, CARET_HANDLE_STAMINA_MS); } } /** * Use this method to put the WebView into text selection mode. * Do not rely on this functionality; it will be deprecated in the future. Loading Loading @@ -5937,9 +5979,14 @@ public class WebView extends AbsoluteLayout mSelectingText = false; // finish is idempotent, so this is fine even if selectionDone was // called by mSelectCallback.onDestroyActionMode if (mSelectCallback != null) { mSelectCallback.finish(); mSelectCallback = null; } if (!mIsCaretSelection) { updateWebkitSelection(); } mIsCaretSelection = false; invalidate(); // redraw without selection mAutoScrollX = 0; mAutoScrollY = 0; Loading Loading @@ -6553,18 +6600,26 @@ public class WebView extends AbsoluteLayout (eventTime - mLastTouchUpTime), eventTime); } mSelectionStarted = false; if (mSelectingText && mSelectHandleLeft != null && mSelectHandleRight != null) { if (mSelectingText) { int shiftedY = y - getTitleHeight() + mScrollY; int shiftedX = x + mScrollX; if (mSelectHandleLeft.getBounds() if (mSelectHandleCenter != null && mSelectHandleCenter.getBounds() .contains(shiftedX, shiftedY)) { mSelectionStarted = true; mSelectDraggingCursor = mSelectCursorBase; } else if (mSelectHandleRight.getBounds() mPrivateHandler.removeMessages(CLEAR_CARET_HANDLE); } else if (mSelectHandleLeft != null && mSelectHandleLeft.getBounds() .contains(shiftedX, shiftedY)) { mSelectionStarted = true; mSelectDraggingCursor = mSelectCursorBase; } else if (mSelectHandleRight != null && mSelectHandleRight.getBounds() .contains(shiftedX, shiftedY)) { mSelectionStarted = true; mSelectDraggingCursor = mSelectCursorExtent; } else if (mIsCaretSelection) { selectionDone(); } if (mSelectDraggingCursor != null) { mSelectDraggingOffset.set( Loading Loading @@ -7215,6 +7270,9 @@ public class WebView extends AbsoluteLayout if (mSelectingText) { mSelectionStarted = false; if (mIsCaretSelection) { resetCaretTimer(); } syncSelectionCursors(); invalidate(); } Loading Loading @@ -9173,6 +9231,9 @@ public class WebView extends AbsoluteLayout } break; } case CLEAR_CARET_HANDLE: selectionDone(); break; default: super.handleMessage(msg); Loading Loading @@ -9423,14 +9484,19 @@ public class WebView extends AbsoluteLayout mInputConnection.setSelection(data.mStart, data.mEnd); } } nativeSetTextSelection(mNativeClass, data.mSelectTextPtr); if (data.mSelectTextPtr != 0) { mIsCaretSelection = (mFieldPointer == nodePointer) && (mFieldPointer != 0) && (data.mStart == data.mEnd); if (!mSelectingText) { setupWebkitSelect(); } else if (!mSelectionStarted) { syncSelectionCursors(); } if (mIsCaretSelection) { resetCaretTimer(); } } else { selectionDone(); } Loading
core/java/android/webkit/WebViewCore.java +2 −2 Original line number Diff line number Diff line Loading @@ -2834,7 +2834,7 @@ 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) { String label, int start, int end, int selectionPtr) { if (mWebView == null) { return; } Loading @@ -2844,7 +2844,7 @@ public final class WebViewCore { WebView.INIT_EDIT_FIELD, initData).sendToTarget(); Message.obtain(mWebView.mPrivateHandler, WebView.REQUEST_KEYBOARD_WITH_SELECTION_MSG_ID, pointer, 0, new TextSelectionData(start, end, 0)) 0, new TextSelectionData(start, end, selectionPtr)) .sendToTarget(); } Loading
core/res/res/values/public.xml +1 −0 Original line number Diff line number Diff line Loading @@ -962,6 +962,7 @@ <java-symbol type="drawable" name="tab_bottom_right_v4" /> <java-symbol type="drawable" name="tab_indicator_v4" /> <java-symbol type="drawable" name="text_select_handle_left" /> <java-symbol type="drawable" name="text_select_handle_middle" /> <java-symbol type="drawable" name="text_select_handle_right" /> <java-symbol type="drawable" name="unknown_image" /> <java-symbol type="drawable" name="unlock_default" /> Loading