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 7c35cf9bcfab312f296560040bfdad4ebbbc9e22..eefedeb359a05198c552ca161a0b06a787368691 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 |
@@ -186,13 +186,20 @@ public class ContentViewCore implements MotionEventDelegate { |
private SelectionHandleController mSelectionHandleController; |
private InsertionHandleController mInsertionHandleController; |
+ // These offsets in document space with page scale normalized to 1.0. |
+ private final PointF mStartHandleNormalizedPoint = new PointF(); |
+ private final PointF mEndHandleNormalizedPoint = new PointF(); |
+ private final PointF mInsertionHandleNormalizedPoint = new PointF(); |
// Tracks whether a selection is currently active. When applied to selected text, indicates |
// whether the last selected text is still highlighted. |
private boolean mHasSelection; |
private String mLastSelectedText; |
private boolean mSelectionEditable; |
- private ActionMode mActionMode; |
+ // TODO(husky@chromium.org): Register the necessary resources in |
+ // ContentViewActivity so we can create an action bar for text editing. |
+ // private ActionMode mActionMode; |
+ private boolean mActionBarVisible; // Remove this when mActionMode is upstreamed. |
// The legacy webview DownloadListener. |
private DownloadListener mDownloadListener; |
@@ -903,8 +910,10 @@ public class ContentViewCore implements MotionEventDelegate { |
} |
void hideSelectActionBar() { |
- if (mActionMode != null) { |
- mActionMode.finish(); |
+ if (mActionBarVisible) { |
+ mActionBarVisible = false; |
+ mImeAdapter.unselect(); |
+ getContentViewClient().onContextualActionBarHidden(); |
} |
} |
@@ -1170,6 +1179,8 @@ public class ContentViewCore implements MotionEventDelegate { |
if (!mPopupZoomer.isShowing()) mPopupZoomer.setLastTouch(x, y); |
if (isLongPress) { |
+ getInsertionHandleController().allowAutomaticShowing(); |
+ getSelectionHandleController().allowAutomaticShowing(); |
if (mNativeContentViewCore != 0) { |
nativeLongPress(mNativeContentViewCore, timeMs, x, y, false); |
} |
@@ -1260,8 +1271,28 @@ public class ContentViewCore implements MotionEventDelegate { |
private SelectionHandleController getSelectionHandleController() { |
if (mSelectionHandleController == null) { |
- mSelectionHandleController = new SelectionHandleController(getContainerView()); |
- // TODO(olilan): add specific method implementations. |
+ mSelectionHandleController = new SelectionHandleController(getContainerView()) { |
+ @Override |
+ public void selectBetweenCoordinates(int x1, int y1, int x2, int y2) { |
+ if (mNativeContentViewCore != 0 && !(x1 == x2 && y1 == y2)) { |
+ nativeSelectBetweenCoordinates(mNativeContentViewCore, x1, y1, x2, y2); |
+ } |
+ } |
+ |
+ @Override |
+ public void showHandlesAt(int x1, int y1, int dir1, int x2, int y2, int dir2) { |
+ super.showHandlesAt(x1, y1, dir1, x2, y2, dir2); |
+ mStartHandleNormalizedPoint.set( |
+ (x1 + mNativeScrollX) / mNativePageScaleFactor, |
+ (y1 + mNativeScrollY) / mNativePageScaleFactor); |
+ mEndHandleNormalizedPoint.set( |
+ (x2 + mNativeScrollX) / mNativePageScaleFactor, |
+ (y2 + mNativeScrollY) / mNativePageScaleFactor); |
+ |
+ showSelectActionBar(); |
+ } |
+ |
+ }; |
mSelectionHandleController.hideAndDisallowAutomaticShowing(); |
} |
@@ -1271,8 +1302,35 @@ public class ContentViewCore implements MotionEventDelegate { |
private InsertionHandleController getInsertionHandleController() { |
if (mInsertionHandleController == null) { |
- mInsertionHandleController = new InsertionHandleController(getContainerView()); |
- // TODO(olilan): add specific method implementations. |
+ mInsertionHandleController = new InsertionHandleController(getContainerView()) { |
+ private static final int AVERAGE_LINE_HEIGHT = 14; |
+ |
+ @Override |
+ public void setCursorPosition(int x, int y) { |
+ if (mNativeContentViewCore != 0) { |
+ nativeSelectBetweenCoordinates(mNativeContentViewCore, x, y, x, y); |
+ } |
+ } |
+ |
+ @Override |
+ public void paste() { |
+ mImeAdapter.paste(); |
+ hideHandles(); |
+ } |
+ |
+ @Override |
+ public int getLineHeight() { |
+ return (int) (mNativePageScaleFactor * AVERAGE_LINE_HEIGHT); |
+ } |
+ |
+ @Override |
+ public void showHandleAt(int x, int y) { |
+ super.showHandleAt(x, y); |
+ mInsertionHandleNormalizedPoint.set( |
+ (x + mNativeScrollX) / mNativePageScaleFactor, |
+ (y + mNativeScrollY) / mNativePageScaleFactor); |
+ } |
+ }; |
mInsertionHandleController.hideAndDisallowAutomaticShowing(); |
} |
@@ -1280,59 +1338,39 @@ public class ContentViewCore implements MotionEventDelegate { |
return mInsertionHandleController; |
} |
- private void showSelectActionBar() { |
- if (mActionMode != null) { |
- mActionMode.invalidate(); |
- return; |
+ private void updateHandleScreenPositions() { |
+ if (mSelectionHandleController != null && mSelectionHandleController.isShowing()) { |
+ mSelectionHandleController.setStartHandlePosition( |
+ (int) (mStartHandleNormalizedPoint.x * mNativePageScaleFactor |
+ - mNativeScrollX), |
bulach
2012/10/05 12:50:59
nit: I know this is the same downstream, but I thi
olilan
2012/10/05 13:43:59
AIUI the Java style is to break lines before opera
Iain Merrick
2012/10/05 19:01:52
As there are repeated expressions here, I'll just
|
+ (int) (mStartHandleNormalizedPoint.y * mNativePageScaleFactor |
+ - mNativeScrollY)); |
+ mSelectionHandleController.setEndHandlePosition( |
+ (int) (mEndHandleNormalizedPoint.x * mNativePageScaleFactor - mNativeScrollX), |
+ (int) (mEndHandleNormalizedPoint.y * mNativePageScaleFactor - mNativeScrollY)); |
} |
- // Start a new action mode with a SelectActionModeCallback. |
olilan
2012/10/05 13:43:59
Do we need to remove this (seeing as we'll have to
Iain Merrick
2012/10/08 17:18:01
Oops, I didn't address this comment of Oli's. I'll
|
- SelectActionModeCallback.ActionHandler actionHandler = |
- new SelectActionModeCallback.ActionHandler() { |
- @Override |
- public boolean selectAll() { |
- return mImeAdapter.selectAll(); |
- } |
- |
- @Override |
- public boolean cut() { |
- return mImeAdapter.cut(); |
- } |
- |
- @Override |
- public boolean copy() { |
- return mImeAdapter.copy(); |
- } |
- |
- @Override |
- public boolean paste() { |
- return mImeAdapter.paste(); |
- } |
- |
- @Override |
- public boolean isSelectionEditable() { |
- return mSelectionEditable; |
- } |
+ if (mInsertionHandleController != null && mInsertionHandleController.isShowing()) { |
+ mInsertionHandleController.setHandlePosition( |
+ (int) (mInsertionHandleNormalizedPoint.x * mNativePageScaleFactor |
+ - mNativeScrollX), |
+ (int) (mInsertionHandleNormalizedPoint.y * mNativePageScaleFactor |
+ - mNativeScrollY)); |
+ } |
+ } |
- @Override |
- public String getSelectedText() { |
- return ContentViewCore.this.getSelectedText(); |
- } |
+ private void hideHandles() { |
+ if (mSelectionHandleController != null) { |
+ mSelectionHandleController.hideAndDisallowAutomaticShowing(); |
+ } |
+ if (mInsertionHandleController != null) { |
+ mInsertionHandleController.hideAndDisallowAutomaticShowing(); |
+ } |
+ } |
- @Override |
- public void onDestroyActionMode() { |
- mActionMode = null; |
- mImeAdapter.unselect(); |
- getContentViewClient().onContextualActionBarHidden(); |
- } |
- }; |
- mActionMode = mContainerView.startActionMode( |
- getContentViewClient().getSelectActionModeCallback(getContext(), actionHandler, |
- nativeIsIncognito(mNativeContentViewCore))); |
- if (mActionMode == null) { |
- // There is no ActionMode, so remove the selection. |
- mImeAdapter.unselect(); |
- } else { |
+ private void showSelectActionBar() { |
+ if (!mActionBarVisible) { |
+ mActionBarVisible = true; |
getContentViewClient().onContextualActionBarShown(); |
} |
} |
@@ -1451,6 +1489,56 @@ public class ContentViewCore implements MotionEventDelegate { |
@SuppressWarnings("unused") |
@CalledByNative |
+ private void onSelectionChanged(String text) { |
+ mLastSelectedText = text; |
+ } |
+ |
+ @SuppressWarnings("unused") |
+ @CalledByNative |
+ private void onSelectionBoundsChanged(Rect startRect, int dir1, Rect endRect, int dir2) { |
+ int x1 = startRect.left; |
+ int y1 = startRect.bottom; |
+ int x2 = endRect.left; |
+ int y2 = endRect.bottom; |
+ if (x1 != x2 || y1 != y2) { |
+ if (mInsertionHandleController != null) { |
+ mInsertionHandleController.hide(); |
+ } |
+ getSelectionHandleController().onSelectionChanged(x1, y1, dir1, x2, y2, dir2); |
+ mHasSelection = true; |
+ } else { |
+ hideSelectActionBar(); |
+ if (x1 != 0 && y1 != 0 |
+ && (mSelectionHandleController == null |
bulach
2012/10/05 12:50:59
nit: as above, operators in the previous lines.
Iain Merrick
2012/10/05 19:01:52
I think in this case I agree with Oli -- this is t
|
+ || !mSelectionHandleController.isDragging()) |
+ && mSelectionEditable) { |
+ // Selection is a caret, and a text field is focused. |
+ if (mSelectionHandleController != null) { |
+ mSelectionHandleController.hide(); |
+ } |
+ getInsertionHandleController().onCursorPositionChanged(x1, y1); |
+ InputMethodManager manager = (InputMethodManager) |
+ getContext().getSystemService(Context.INPUT_METHOD_SERVICE); |
+ if (manager.isWatchingCursor(mContainerView)) { |
+ manager.updateCursor(mContainerView, startRect.left, startRect.top, |
+ startRect.right, startRect.bottom); |
+ } |
+ } else { |
+ // Deselection |
+ if (mSelectionHandleController != null |
+ && !mSelectionHandleController.isDragging()) { |
+ mSelectionHandleController.hideAndDisallowAutomaticShowing(); |
+ } |
+ if (mInsertionHandleController != null) { |
+ mInsertionHandleController.hideAndDisallowAutomaticShowing(); |
+ } |
+ } |
+ mHasSelection = false; |
+ } |
+ } |
+ |
+ @SuppressWarnings("unused") |
+ @CalledByNative |
private void onEvaluateJavaScriptResult(int id, String jsonResult) { |
getContentViewClient().onEvaluateJavaScriptResult(id, jsonResult); |
} |