OLD | NEW |
---|---|
1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 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; | 5 package org.chromium.content.browser; |
6 | 6 |
7 import android.annotation.TargetApi; | 7 import android.annotation.TargetApi; |
8 import android.app.Activity; | 8 import android.app.Activity; |
9 import android.app.SearchManager; | 9 import android.app.SearchManager; |
10 import android.content.ClipboardManager; | 10 import android.content.ClipboardManager; |
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
109 private String mLastSelectedText; | 109 private String mLastSelectedText; |
110 | 110 |
111 // Tracks whether a selection is currently active. When applied to selected text, indicates | 111 // Tracks whether a selection is currently active. When applied to selected text, indicates |
112 // whether the last selected text is still highlighted. | 112 // whether the last selected text is still highlighted. |
113 private boolean mHasSelection; | 113 private boolean mHasSelection; |
114 | 114 |
115 // Lazily created paste popup menu, triggered either via long press in an | 115 // Lazily created paste popup menu, triggered either via long press in an |
116 // editable region or from tapping the insertion handle. | 116 // editable region or from tapping the insertion handle. |
117 private PastePopupMenu mPastePopupMenu; | 117 private PastePopupMenu mPastePopupMenu; |
118 private boolean mWasPastePopupShowingOnInsertionDragStart; | 118 private boolean mWasPastePopupShowingOnInsertionDragStart; |
119 private boolean mSelectionHandleDragStopped; | |
aelias_OOO_until_Jul13
2017/04/21 21:42:19
I think it would be clearer to invert this, "mDrag
| |
119 | 120 |
120 // The client that processes textual selection, or null if none exists. | 121 // The client that processes textual selection, or null if none exists. |
121 private SelectionClient mSelectionClient; | 122 private SelectionClient mSelectionClient; |
122 | 123 |
123 // The classificaton result of the selected text if the selection exists and | 124 // The classificaton result of the selected text if the selection exists and |
124 // ContextSelectionProvider was able to classify it, otherwise null. | 125 // ContextSelectionProvider was able to classify it, otherwise null. |
125 private ContextSelectionProvider.Result mClassificationResult; | 126 private ContextSelectionProvider.Result mClassificationResult; |
126 | 127 |
127 // The resource ID for Assist menu item. | 128 // The resource ID for Assist menu item. |
128 private int mAssistMenuItemId; | 129 private int mAssistMenuItemId; |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
201 // True if action mode is initialized to a working (not a no-op) mode. | 202 // True if action mode is initialized to a working (not a no-op) mode. |
202 private boolean isActionModeSupported() { | 203 private boolean isActionModeSupported() { |
203 return mCallback != EMPTY_CALLBACK; | 204 return mCallback != EMPTY_CALLBACK; |
204 } | 205 } |
205 | 206 |
206 @Override | 207 @Override |
207 public void setAllowedMenuItems(int allowedMenuItems) { | 208 public void setAllowedMenuItems(int allowedMenuItems) { |
208 mAllowedMenuItems = allowedMenuItems; | 209 mAllowedMenuItems = allowedMenuItems; |
209 } | 210 } |
210 | 211 |
212 public void showSelectionMenu(int xAnchor, int yAnchor, int left, int top, i nt right, | |
213 int bottom, boolean isEditable, boolean isPasswordType, String selec tionText, | |
214 boolean canSelectAll) { | |
215 mSelectionRect.set(left, top, right, bottom); | |
216 mEditable = isEditable; | |
217 mLastSelectedText = selectionText; | |
218 mIsPasswordType = isPasswordType; | |
219 mHasSelection = selectionText.length() != 0; | |
aelias_OOO_until_Jul13
2017/04/21 21:42:19
This state is redundant now, can be replaced by bo
| |
220 mIsInsertion = selectionText.length() == 0; | |
aelias_OOO_until_Jul13
2017/04/21 21:42:19
Likewise for mIsInsertion maybe? Is there any val
| |
221 mCanSelectAllForPastePopup = canSelectAll; | |
222 mUnselectAllOnDismiss = true; | |
223 if (isInsertion()) { | |
224 createAndShowPastePopup(xAnchor, yAnchor); | |
225 } else { | |
226 if (mSelectionClient == null | |
227 || !mSelectionClient.sendsSelectionPopupUpdates(!mSelectionH andleDragStopped)) { | |
228 showActionModeOrClearOnFailure(); | |
229 } else { | |
230 // Rely on |mSelectionClient| sending a classification request a nd the request | |
231 // always calling onClassified() callback. | |
232 mPendingShowActionMode = true; | |
233 } | |
234 mSelectionHandleDragStopped = false; | |
235 } | |
236 } | |
237 | |
211 /** | 238 /** |
212 * Show (activate) android action mode by starting it. | 239 * Show (activate) android action mode by starting it. |
213 * | 240 * |
214 * <p>Action mode in floating mode is tried first, and then falls back to | 241 * <p>Action mode in floating mode is tried first, and then falls back to |
215 * a normal one. | 242 * a normal one. |
216 * <p> If the action mode cannot be created the selection is cleared. | 243 * <p> If the action mode cannot be created the selection is cleared. |
217 */ | 244 */ |
218 public void showActionModeOrClearOnFailure() { | 245 public void showActionModeOrClearOnFailure() { |
219 mPendingShowActionMode = false; | 246 mPendingShowActionMode = false; |
220 | 247 |
(...skipping 25 matching lines...) Expand all Loading... | |
246 if (!isActionModeValid()) clearSelection(); | 273 if (!isActionModeValid()) clearSelection(); |
247 } | 274 } |
248 | 275 |
249 @TargetApi(Build.VERSION_CODES.M) | 276 @TargetApi(Build.VERSION_CODES.M) |
250 private ActionMode startFloatingActionMode() { | 277 private ActionMode startFloatingActionMode() { |
251 ActionMode actionMode = mView.startActionMode( | 278 ActionMode actionMode = mView.startActionMode( |
252 new FloatingActionModeCallback(this, mCallback), ActionMode.TYPE _FLOATING); | 279 new FloatingActionModeCallback(this, mCallback), ActionMode.TYPE _FLOATING); |
253 return actionMode; | 280 return actionMode; |
254 } | 281 } |
255 | 282 |
256 void createAndShowPastePopup(int x, int y, boolean canSelectAll) { | 283 void createAndShowPastePopup(int x, int y) { |
257 if (mView.getParent() == null || mView.getVisibility() != View.VISIBLE) { | 284 if (mView.getParent() == null || mView.getVisibility() != View.VISIBLE) { |
258 return; | 285 return; |
259 } | 286 } |
260 | 287 |
261 if (!supportsFloatingActionMode() && !canPaste()) return; | 288 if (!supportsFloatingActionMode() && !canPaste()) return; |
262 destroyPastePopup(); | 289 destroyPastePopup(); |
263 mCanSelectAllForPastePopup = canSelectAll; | |
264 PastePopupMenuDelegate delegate = new PastePopupMenuDelegate() { | 290 PastePopupMenuDelegate delegate = new PastePopupMenuDelegate() { |
265 @Override | 291 @Override |
266 public void paste() { | 292 public void paste() { |
267 mWebContents.paste(); | 293 mWebContents.paste(); |
268 mWebContents.dismissTextHandles(); | 294 mWebContents.dismissTextHandles(); |
269 } | 295 } |
270 | 296 |
271 @Override | 297 @Override |
272 public boolean canPaste() { | 298 public boolean canPaste() { |
273 return SelectionPopupController.this.canPaste(); | 299 return SelectionPopupController.this.canPaste(); |
(...skipping 364 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
638 } | 664 } |
639 } | 665 } |
640 | 666 |
641 /** | 667 /** |
642 * Perform a select all action. | 668 * Perform a select all action. |
643 */ | 669 */ |
644 @VisibleForTesting | 670 @VisibleForTesting |
645 void selectAll() { | 671 void selectAll() { |
646 mWebContents.selectAll(); | 672 mWebContents.selectAll(); |
647 mClassificationResult = null; | 673 mClassificationResult = null; |
648 if (needsActionMenuUpdate()) showActionModeOrClearOnFailure(); | |
649 | |
650 // Even though the above statement logged a SelectAll user action, we wa nt to | 674 // Even though the above statement logged a SelectAll user action, we wa nt to |
651 // track whether the focus was in an editable field, so log that too. | 675 // track whether the focus was in an editable field, so log that too. |
652 if (isSelectionEditable()) { | 676 if (isSelectionEditable()) { |
653 RecordUserAction.record("MobileActionMode.SelectAllWasEditable"); | 677 RecordUserAction.record("MobileActionMode.SelectAllWasEditable"); |
654 } else { | 678 } else { |
655 RecordUserAction.record("MobileActionMode.SelectAllWasNonEditable"); | 679 RecordUserAction.record("MobileActionMode.SelectAllWasNonEditable"); |
656 } | 680 } |
657 } | 681 } |
658 | 682 |
659 /** | 683 /** |
(...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
834 // All coordinates are in DIP. | 858 // All coordinates are in DIP. |
835 void onSelectionEvent(int eventType, int xAnchor, int yAnchor, | 859 void onSelectionEvent(int eventType, int xAnchor, int yAnchor, |
836 int left, int top, int right, int bottom, boolean isScrollInProgress , | 860 int left, int top, int right, int bottom, boolean isScrollInProgress , |
837 boolean touchScrollInProgress) { | 861 boolean touchScrollInProgress) { |
838 // Ensure the provided selection coordinates form a non-empty rect, as r equired by | 862 // Ensure the provided selection coordinates form a non-empty rect, as r equired by |
839 // the selection action mode. | 863 // the selection action mode. |
840 if (left == right) ++right; | 864 if (left == right) ++right; |
841 if (top == bottom) ++bottom; | 865 if (top == bottom) ++bottom; |
842 switch (eventType) { | 866 switch (eventType) { |
843 case SelectionEventType.SELECTION_HANDLES_SHOWN: | 867 case SelectionEventType.SELECTION_HANDLES_SHOWN: |
844 mSelectionRect.set(left, top, right, bottom); | |
845 mHasSelection = true; | |
846 mUnselectAllOnDismiss = true; | |
847 if (mSelectionClient == null || !mSelectionClient.sendsSelection PopupUpdates()) { | |
848 showActionModeOrClearOnFailure(); | |
849 } else { | |
850 // Rely on |mSelectionClient| sending a classification reque st and the request | |
851 // always calling onClassified() callback. | |
852 mPendingShowActionMode = true; | |
853 } | |
854 break; | 868 break; |
855 | 869 |
856 case SelectionEventType.SELECTION_HANDLES_MOVED: | 870 case SelectionEventType.SELECTION_HANDLES_MOVED: |
857 mSelectionRect.set(left, top, right, bottom); | 871 mSelectionRect.set(left, top, right, bottom); |
858 if (mPendingShowActionMode) { | 872 if (mPendingShowActionMode) { |
859 showActionModeOrClearOnFailure(); | 873 showActionModeOrClearOnFailure(); |
860 } else { | 874 } else { |
861 invalidateContentRect(); | 875 invalidateContentRect(); |
862 } | 876 } |
863 break; | 877 break; |
864 | 878 |
865 case SelectionEventType.SELECTION_HANDLES_CLEARED: | 879 case SelectionEventType.SELECTION_HANDLES_CLEARED: |
866 mHasSelection = false; | 880 mHasSelection = false; |
867 mUnselectAllOnDismiss = false; | 881 mUnselectAllOnDismiss = false; |
868 mSelectionRect.setEmpty(); | 882 mSelectionRect.setEmpty(); |
869 finishActionMode(); | 883 finishActionMode(); |
870 break; | 884 break; |
871 | 885 |
872 case SelectionEventType.SELECTION_HANDLE_DRAG_STARTED: | 886 case SelectionEventType.SELECTION_HANDLE_DRAG_STARTED: |
887 mSelectionHandleDragStopped = false; | |
873 hideActionMode(true); | 888 hideActionMode(true); |
874 break; | 889 break; |
875 | 890 |
876 case SelectionEventType.SELECTION_HANDLE_DRAG_STOPPED: | 891 case SelectionEventType.SELECTION_HANDLE_DRAG_STOPPED: |
877 if (mSelectionClient == null || !mSelectionClient.sendsSelection PopupUpdates()) { | 892 mSelectionHandleDragStopped = true; |
878 hideActionMode(false); | 893 mWebContents.showContextMenuAtPoint(xAnchor, yAnchor); |
879 } | |
880 // Otherwise rely on |mSelectionClient| sending a classification request and the | |
881 // request always calling onClassified() callback. | |
882 break; | 894 break; |
883 | 895 |
884 case SelectionEventType.INSERTION_HANDLE_SHOWN: | 896 case SelectionEventType.INSERTION_HANDLE_SHOWN: |
885 mSelectionRect.set(left, top, right, bottom); | 897 mSelectionRect.set(left, top, right, bottom); |
886 mIsInsertion = true; | 898 mIsInsertion = true; |
887 break; | 899 break; |
888 | 900 |
889 case SelectionEventType.INSERTION_HANDLE_MOVED: | 901 case SelectionEventType.INSERTION_HANDLE_MOVED: |
890 mSelectionRect.set(left, top, right, bottom); | 902 mSelectionRect.set(left, top, right, bottom); |
891 if (!isScrollInProgress && isPastePopupShowing()) { | 903 if (!isScrollInProgress && isPastePopupShowing()) { |
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1036 | 1048 |
1037 // Remain pending until SELECTION_HANDLES_MOVED arrives. | 1049 // Remain pending until SELECTION_HANDLES_MOVED arrives. |
1038 if (mPendingShowActionMode) return; | 1050 if (mPendingShowActionMode) return; |
1039 } | 1051 } |
1040 | 1052 |
1041 // Rely on this method to clear |mHidden| and unhide the action mode . | 1053 // Rely on this method to clear |mHidden| and unhide the action mode . |
1042 showActionModeOrClearOnFailure(); | 1054 showActionModeOrClearOnFailure(); |
1043 } | 1055 } |
1044 }; | 1056 }; |
1045 } | 1057 } |
OLD | NEW |