diff options
| -rw-r--r-- | core/java/android/webkit/FindActionModeCallback.java | 39 | ||||
| -rw-r--r-- | core/java/android/webkit/WebView.java | 92 | ||||
| -rw-r--r-- | core/java/android/webkit/WebViewCore.java | 49 |
3 files changed, 122 insertions, 58 deletions
diff --git a/core/java/android/webkit/FindActionModeCallback.java b/core/java/android/webkit/FindActionModeCallback.java index fffa90b5518a..10b0885359db 100644 --- a/core/java/android/webkit/FindActionModeCallback.java +++ b/core/java/android/webkit/FindActionModeCallback.java @@ -43,7 +43,9 @@ class FindActionModeCallback implements ActionMode.Callback, TextWatcher, private Resources mResources; private boolean mMatchesFound; private int mNumberOfMatches; + private int mActiveMatchIndex; private ActionMode mActionMode; + private String mLastFind; FindActionModeCallback(Context context) { mCustomView = LayoutInflater.from(context).inflate( @@ -132,16 +134,13 @@ class FindActionModeCallback implements ActionMode.Callback, TextWatcher, mWebView.clearMatches(); mMatches.setVisibility(View.GONE); mMatchesFound = false; + mLastFind = null; } else { mMatchesFound = true; - mMatches.setVisibility(View.VISIBLE); - mNumberOfMatches = mWebView.findAll(find.toString()); - if (0 == mNumberOfMatches) { - mMatches.setText(mResources.getString( - com.android.internal.R.string.no_matches)); - } else { - updateMatchesString(); - } + mMatches.setVisibility(View.INVISIBLE); + mNumberOfMatches = 0; + mLastFind = find.toString(); + mWebView.findAllAsync(mLastFind); } } @@ -151,17 +150,31 @@ class FindActionModeCallback implements ActionMode.Callback, TextWatcher, mInput.showSoftInput(mEditText, 0); } + public void updateMatchCount(int matchIndex, int matchCount, + String findText) { + if (mLastFind != null && mLastFind.equals(findText)) { + mNumberOfMatches = matchCount; + mActiveMatchIndex = matchIndex; + updateMatchesString(); + } else { + mMatches.setVisibility(View.INVISIBLE); + mNumberOfMatches = 0; + } + } + /* * Update the string which tells the user how many matches were found, and * which match is currently highlighted. - * Not to be called when mNumberOfMatches is 0. */ private void updateMatchesString() { - String template = mResources.getQuantityString( + if (mNumberOfMatches == 0) { + mMatches.setText(com.android.internal.R.string.no_matches); + } else { + mMatches.setText(mResources.getQuantityString( com.android.internal.R.plurals.matches_found, mNumberOfMatches, - mWebView.findIndex() + 1, mNumberOfMatches); - - mMatches.setText(template); + mActiveMatchIndex + 1, mNumberOfMatches)); + } + mMatches.setVisibility(View.VISIBLE); } // OnLongClickListener implementation diff --git a/core/java/android/webkit/WebView.java b/core/java/android/webkit/WebView.java index a35106a67833..2304c250ab8a 100644 --- a/core/java/android/webkit/WebView.java +++ b/core/java/android/webkit/WebView.java @@ -914,7 +914,7 @@ public class WebView extends AbsoluteLayout static final int REPLACE_BASE_CONTENT = 123; static final int FORM_DID_BLUR = 124; static final int RETURN_LABEL = 125; - static final int FIND_AGAIN = 126; + static final int UPDATE_MATCH_COUNT = 126; static final int CENTER_FIT_RECT = 127; static final int REQUEST_KEYBOARD_WITH_SELECTION_MSG_ID = 128; static final int SET_SCROLLBAR_MODES = 129; @@ -979,7 +979,7 @@ public class WebView extends AbsoluteLayout "REPLACE_BASE_CONTENT", // = 123; "FORM_DID_BLUR", // = 124; "RETURN_LABEL", // = 125; - "FIND_AGAIN", // = 126; + "UPDATE_MATCH_COUNT", // = 126; "CENTER_FIT_RECT", // = 127; "REQUEST_KEYBOARD_WITH_SELECTION_MSG_ID", // = 128; "SET_SCROLLBAR_MODES", // = 129; @@ -1021,9 +1021,8 @@ public class WebView extends AbsoluteLayout // keep these in sync with their counterparts in WebView.cpp private static final int DRAW_EXTRAS_NONE = 0; - private static final int DRAW_EXTRAS_FIND = 1; - private static final int DRAW_EXTRAS_SELECTION = 2; - private static final int DRAW_EXTRAS_CURSOR_RING = 3; + private static final int DRAW_EXTRAS_SELECTION = 1; + private static final int DRAW_EXTRAS_CURSOR_RING = 2; // keep this in sync with WebCore:ScrollbarMode in WebKit private static final int SCROLLBAR_AUTO = 0; @@ -3711,7 +3710,7 @@ public class WebView extends AbsoluteLayout public void findNext(boolean forward) { checkThread(); if (0 == mNativeClass) return; // client isn't initialized - nativeFindNext(forward); + mWebViewCore.sendMessage(EventHub.FIND_NEXT, forward ? 1 : 0); } /* @@ -3721,13 +3720,40 @@ public class WebView extends AbsoluteLayout * that were found. */ public int findAll(String find) { + return findAllBody(find, false); + } + + /** + * @hide + */ + public void findAllAsync(String find) { + findAllBody(find, true); + } + + private int findAllBody(String find, boolean isAsync) { checkThread(); if (0 == mNativeClass) return 0; // client isn't initialized - int result = find != null ? nativeFindAll(find.toLowerCase(), - find.toUpperCase(), find.equalsIgnoreCase(mLastFind)) : 0; - invalidate(); mLastFind = find; - return result; + mWebViewCore.removeMessages(EventHub.FIND_ALL); + WebViewCore.FindAllRequest request = new + WebViewCore.FindAllRequest(find); + if (isAsync) { + mWebViewCore.sendMessage(EventHub.FIND_ALL, request); + return 0; // no need to wait for response + } + synchronized(request) { + try { + mWebViewCore.sendMessageAtFrontOfQueue(EventHub.FIND_ALL, + request); + while (request.mMatchCount == -1) { + request.wait(); + } + } + catch (InterruptedException e) { + return 0; + } + } + return request.mMatchCount; } /** @@ -3763,6 +3789,7 @@ public class WebView extends AbsoluteLayout } if (text != null) { mFindCallback.setText(text); + mFindCallback.findAll(); } return true; } @@ -3782,14 +3809,6 @@ public class WebView extends AbsoluteLayout nativeSetFindIsUp(isUp); } - /** - * Return the index of the currently highlighted match. - */ - int findIndex() { - if (0 == mNativeClass) return -1; - return nativeFindIndex(); - } - // Used to know whether the find dialog is open. Affects whether // or not we draw the highlights for matches. private boolean mFindIsUp; @@ -3856,10 +3875,11 @@ public class WebView extends AbsoluteLayout checkThread(); if (mNativeClass == 0) return; - nativeSetFindIsEmpty(); - invalidate(); + mWebViewCore.removeMessages(EventHub.FIND_ALL); + mWebViewCore.sendMessage(EventHub.FIND_ALL, null); } + /** * Called when the find ActionMode ends. */ @@ -4954,12 +4974,12 @@ public class WebView extends AbsoluteLayout // decide which adornments to draw int extras = DRAW_EXTRAS_NONE; - if (mFindIsUp) { - extras = DRAW_EXTRAS_FIND; - } else if (mSelectingText) { - extras = DRAW_EXTRAS_SELECTION; - } else if (drawCursorRing) { - extras = DRAW_EXTRAS_CURSOR_RING; + if (!mFindIsUp) { + if (mSelectingText) { + extras = DRAW_EXTRAS_SELECTION; + } else if (drawCursorRing) { + extras = DRAW_EXTRAS_CURSOR_RING; + } } if (DebugFlags.WEB_VIEW) { Log.v(LOGTAG, "mFindIsUp=" + mFindIsUp @@ -8884,13 +8904,6 @@ public class WebView extends AbsoluteLayout } break; - case FIND_AGAIN: - // Ignore if find has been dismissed. - if (mFindIsUp && mFindCallback != null) { - mFindCallback.findAll(); - } - break; - case DRAG_HELD_MOTIONLESS: mHeldMotionless = MOTIONLESS_TRUE; invalidate(); @@ -9095,6 +9108,14 @@ public class WebView extends AbsoluteLayout break; } + case UPDATE_MATCH_COUNT: { + if (mFindCallback != null) { + mFindCallback.updateMatchCount(msg.arg1, msg.arg2, + (String) msg.obj); + } + break; + } + default: super.handleMessage(msg); break; @@ -9931,9 +9952,6 @@ public class WebView extends AbsoluteLayout private native void nativeUpdateDrawGLFunction(Rect rect, Rect viewRect, RectF visibleRect, float scale); private native void nativeExtendSelection(int x, int y); - private native int nativeFindAll(String findLower, String findUpper, - boolean sameAsLastSearch); - private native void nativeFindNext(boolean forward); /* package */ native int nativeFocusCandidateFramePointer(); /* package */ native boolean nativeFocusCandidateHasNextTextfield(); /* package */ native boolean nativeFocusCandidateIsPassword(); @@ -9991,9 +10009,7 @@ public class WebView extends AbsoluteLayout private native boolean nativePointInNavCache(int x, int y, int slop); private native void nativeSelectBestAt(Rect rect); private native void nativeSelectAt(int x, int y); - private native int nativeFindIndex(); private native void nativeSetExtendSelection(); - private native void nativeSetFindIsEmpty(); private native void nativeSetFindIsUp(boolean isUp); private native void nativeSetHeightCanMeasure(boolean measure); private native boolean nativeSetBaseLayer(int nativeInstance, diff --git a/core/java/android/webkit/WebViewCore.java b/core/java/android/webkit/WebViewCore.java index b6c5612c7e6d..4b1ae370a6b6 100644 --- a/core/java/android/webkit/WebViewCore.java +++ b/core/java/android/webkit/WebViewCore.java @@ -1001,6 +1001,15 @@ public final class WebViewCore { "REMOVE_JS_INTERFACE", // = 149; }; + static class FindAllRequest { + public FindAllRequest(String text) { + mSearchText = text; + mMatchCount = -1; + } + public String mSearchText; + public int mMatchCount; + } + /** * @hide */ @@ -1142,6 +1151,10 @@ public final class WebViewCore { // for updating state on trust storage change static final int TRUST_STORAGE_UPDATED = 220; + // find-on-page controls + static final int FIND_ALL = 220; + static final int FIND_NEXT = 221; + // Private handler for WebCore messages. private Handler mHandler; // Message queue for containing messages before the WebCore thread is @@ -1785,6 +1798,22 @@ public final class WebViewCore { case SELECT_ALL: nativeSelectAll(mNativeClass); break; + case FIND_ALL: { + FindAllRequest request = (FindAllRequest) msg.obj; + if (request == null) { + nativeFindAll(mNativeClass, null); + } else { + request.mMatchCount = nativeFindAll( + mNativeClass, request.mSearchText); + synchronized(request) { + request.notify(); + } + } + break; + } + case FIND_NEXT: + nativeFindNext(mNativeClass, msg.arg1 != 0); + break; } } }; @@ -2783,13 +2812,6 @@ public final class WebViewCore { } // called by JNI - private void sendFindAgain() { - if (mWebView == null) return; - Message.obtain(mWebView.mPrivateHandler, - WebView.FIND_AGAIN).sendToTarget(); - } - - // called by JNI private void initEditField(int pointer, String text, int start, int end) { if (mWebView == null) { return; @@ -2802,6 +2824,17 @@ public final class WebViewCore { .sendToTarget(); } + // called by JNI + private void updateMatchCount(int matchIndex, int matchCount, + String findText) { + if (mWebView == null) { + return; + } + Message.obtain(mWebView.mPrivateHandler, + WebView.UPDATE_MATCH_COUNT, matchIndex, matchCount, + findText).sendToTarget(); + } + private native void nativeUpdateFrameCacheIfLoading(int nativeClass); private native void nativeRevealSelection(int nativeClass); private native String nativeRequestLabel(int nativeClass, int framePtr, @@ -3055,6 +3088,8 @@ public final class WebViewCore { private native void nativeAutoFillForm(int nativeClass, int queryId); private native void nativeScrollLayer(int nativeClass, int layer, Rect rect); + private native int nativeFindAll(int nativeClass, String text); + private native void nativeFindNext(int nativeClass, boolean forward); /** * Deletes editable text between two points. Note that the selection may |