| Index: content/public/android/java/src/org/chromium/content/browser/ContentViewCore.java
|
| diff --git a/content/public/android/java/src/org/chromium/content/browser/ContentViewCore.java b/content/public/android/java/src/org/chromium/content/browser/ContentViewCore.java
|
| index 9920c9d9da33889d487627919b5275260cf1aab6..b0959b44765eb1257872c0d7c599a7c6f3a60db0 100644
|
| --- a/content/public/android/java/src/org/chromium/content/browser/ContentViewCore.java
|
| +++ b/content/public/android/java/src/org/chromium/content/browser/ContentViewCore.java
|
| @@ -29,6 +29,7 @@ import android.text.Selection;
|
| import android.text.TextUtils;
|
| import android.util.Pair;
|
| import android.util.TypedValue;
|
| +import android.view.ActionMode;
|
| import android.view.HapticFeedbackConstants;
|
| import android.view.InputDevice;
|
| import android.view.KeyEvent;
|
| @@ -519,6 +520,7 @@ public class ContentViewCore implements
|
| // whether the last selected text is still highlighted.
|
| private boolean mHasSelection;
|
| private boolean mHasInsertion;
|
| + private boolean mDraggingSelection;
|
| private String mLastSelectedText;
|
| private boolean mFocusedNodeEditable;
|
| private WebActionMode mActionMode;
|
| @@ -1273,6 +1275,7 @@ public class ContentViewCore implements
|
| mGestureStateListenersIterator.next().onFlingStartGesture(
|
| vx, vy, computeVerticalScrollOffset(), computeVerticalScrollExtent());
|
| }
|
| + updateActionModeVisibility();
|
| }
|
|
|
| @SuppressWarnings("unused")
|
| @@ -1294,6 +1297,7 @@ public class ContentViewCore implements
|
| hidePastePopup();
|
| mZoomControlsDelegate.invokeZoomPicker();
|
| updateGestureStateListener(GestureEventType.SCROLL_START);
|
| + updateActionModeVisibility();
|
| }
|
|
|
| @SuppressWarnings("unused")
|
| @@ -1312,6 +1316,7 @@ public class ContentViewCore implements
|
| if (!mTouchScrollInProgress) return;
|
| mTouchScrollInProgress = false;
|
| updateGestureStateListener(GestureEventType.SCROLL_END);
|
| + updateActionModeVisibility();
|
| }
|
|
|
| @SuppressWarnings("unused")
|
| @@ -1678,6 +1683,7 @@ public class ContentViewCore implements
|
| */
|
| public void onWindowFocusChanged(boolean hasWindowFocus) {
|
| if (!hasWindowFocus) resetGestureDetection();
|
| + if (mActionMode != null) mActionMode.onWindowFocusChanged(hasWindowFocus);
|
| }
|
|
|
| public void onFocusChanged(boolean gainFocus) {
|
| @@ -2120,7 +2126,10 @@ public class ContentViewCore implements
|
|
|
| @Override
|
| public void onGetContentRect(Rect outRect) {
|
| + // The selection coordinates are relative to the content viewport, but we need
|
| + // coordinates relative to the containing View.
|
| outRect.set(mSelectionRect);
|
| + outRect.offset(0, (int) mRenderCoordinates.getContentOffsetYPix());
|
| }
|
|
|
| @Override
|
| @@ -2150,15 +2159,9 @@ public class ContentViewCore implements
|
| // On ICS, startActionMode throws an NPE when getParent() is null.
|
| if (mContainerView.getParent() != null) {
|
| assert mWebContents != null;
|
| - boolean tryCreateFloatingActionMode = supportsFloatingActionMode();
|
| - mActionMode = getContentViewClient().startActionMode(
|
| - mContainerView, mActionHandler, tryCreateFloatingActionMode);
|
| - if (tryCreateFloatingActionMode && mActionMode == null) {
|
| - mFloatingActionModeCreationFailed = true;
|
| - if (!allowFallbackIfFloatingActionModeCreationFails) return;
|
| - mActionMode = getContentViewClient().startActionMode(
|
| - mContainerView, mActionHandler, false);
|
| - }
|
| + ActionMode actionMode =
|
| + startActionMode(allowFallbackIfFloatingActionModeCreationFails);
|
| + if (actionMode != null) mActionMode = new WebActionMode(actionMode, mContainerView);
|
| }
|
| mUnselectAllOnActionModeDismiss = true;
|
| if (mActionMode == null) {
|
| @@ -2170,14 +2173,41 @@ public class ContentViewCore implements
|
| }
|
|
|
| private boolean supportsFloatingActionMode() {
|
| - return !mFloatingActionModeCreationFailed
|
| - && getContentViewClient().supportsFloatingActionMode();
|
| + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) return false;
|
| + return !mFloatingActionModeCreationFailed;
|
| + }
|
| +
|
| + private ActionMode startActionMode(boolean allowFallbackIfFloatingActionModeCreationFails) {
|
| + WebActionModeCallback callback = getContentViewClient().getWebActionModeCallback(
|
| + mContainerView.getContext(), mActionHandler);
|
| + if (supportsFloatingActionMode()) {
|
| + ActionMode actionMode = startFloatingActionMode(callback);
|
| + if (actionMode != null) return actionMode;
|
| + mFloatingActionModeCreationFailed = true;
|
| + if (!allowFallbackIfFloatingActionModeCreationFails) return null;
|
| + }
|
| + return startDefaultActionMode(callback);
|
| + }
|
| +
|
| + private ActionMode startDefaultActionMode(WebActionModeCallback callback) {
|
| + return mContainerView.startActionMode(callback);
|
| + }
|
| +
|
| + @TargetApi(Build.VERSION_CODES.M)
|
| + private ActionMode startFloatingActionMode(WebActionModeCallback callback) {
|
| + ActionMode.Callback2 callback2 = new FloatingWebActionModeCallback(callback);
|
| + return mContainerView.startActionMode(callback2, ActionMode.TYPE_FLOATING);
|
| }
|
|
|
| private void invalidateActionModeContentRect() {
|
| if (mActionMode != null) mActionMode.invalidateContentRect();
|
| }
|
|
|
| + private void updateActionModeVisibility() {
|
| + if (mActionMode == null) return;
|
| + mActionMode.hide(mDraggingSelection || isScrollInProgress());
|
| + }
|
| +
|
| /**
|
| * Clears the current text selection.
|
| */
|
| @@ -2234,15 +2264,20 @@ public class ContentViewCore implements
|
|
|
| case SelectionEventType.SELECTION_HANDLES_CLEARED:
|
| mHasSelection = false;
|
| + mDraggingSelection = false;
|
| mUnselectAllOnActionModeDismiss = false;
|
| hideSelectActionMode();
|
| mSelectionRect.setEmpty();
|
| break;
|
|
|
| case SelectionEventType.SELECTION_HANDLE_DRAG_STARTED:
|
| + mDraggingSelection = true;
|
| + updateActionModeVisibility();
|
| break;
|
|
|
| case SelectionEventType.SELECTION_HANDLE_DRAG_STOPPED:
|
| + mDraggingSelection = false;
|
| + updateActionModeVisibility();
|
| break;
|
|
|
| case SelectionEventType.INSERTION_HANDLE_SHOWN:
|
| @@ -2606,6 +2641,8 @@ public class ContentViewCore implements
|
| }
|
|
|
| private void hidePastePopup() {
|
| + // TODO(jdduke): Create a generic interface for the legacy PastePopupMenu and the
|
| + // new ActionMode-based paste popup menu.
|
| if (mPastePopupMenu != null) {
|
| assert !supportsFloatingActionMode();
|
| mPastePopupMenu.hide();
|
| @@ -2633,8 +2670,10 @@ public class ContentViewCore implements
|
| }
|
|
|
| @VisibleForTesting
|
| - public PastePopupMenu getPastePopupForTest() {
|
| - return getPastePopup();
|
| + public boolean isPastePopupShowingForTest() {
|
| + if (mPastePopupMenu != null) return mPastePopupMenu.isShowing();
|
| + if (supportsFloatingActionMode() && mHasInsertion && mActionMode != null) return true;
|
| + return false;
|
| }
|
|
|
| private boolean canPaste() {
|
| @@ -3156,6 +3195,7 @@ public class ContentViewCore implements
|
|
|
| if (touchScrollInProgress) updateGestureStateListener(GestureEventType.SCROLL_END);
|
| if (potentiallyActiveFlingCount > 0) updateGestureStateListener(GestureEventType.FLING_END);
|
| + updateActionModeVisibility();
|
| }
|
|
|
| private float getWheelScrollFactorInPixels() {
|
| @@ -3192,6 +3232,7 @@ public class ContentViewCore implements
|
| if (mPotentiallyActiveFlingCount <= 0) return;
|
| mPotentiallyActiveFlingCount--;
|
| updateGestureStateListener(GestureEventType.FLING_END);
|
| + updateActionModeVisibility();
|
| }
|
|
|
| @Override
|
|
|