summaryrefslogtreecommitdiffstats
path: root/WebKit
diff options
context:
space:
mode:
authorCary Clark <cary@android.com>2009-12-11 12:50:10 -0500
committerCary Clark <cary@android.com>2009-12-15 11:37:47 -0500
commitd4924af12855cd19162ba1442a6055664c98ca32 (patch)
treef5e2fcd6c7877b79aca9963126d734a5d6dff1a4 /WebKit
parent334e51bc2ff9bf7fc55fa67dc8a6d9257501a32e (diff)
downloadexternal_webkit-d4924af12855cd19162ba1442a6055664c98ca32.zip
external_webkit-d4924af12855cd19162ba1442a6055664c98ca32.tar.gz
external_webkit-d4924af12855cd19162ba1442a6055664c98ca32.tar.bz2
check to see if nav cache is up to date on tap
- WebKit/android/jni/WebViewCore.cpp - WebKit/android/jni/WebViewCore.h Add validNodeAndBounds() to determine if the clicked cached node is good. First check to see if the pointer to the frame and node still exist in the DOM. If they do, see if the hit test bounds they point to is the same as when the cache was recorded. - WebKit/android/nav/CacheBuilder.cpp - WebKit/android/nav/CachedNode.h Record the original absolute bounds for later comparison. - WebKit/android/nav/CacheBuilder.h Make getAreaRect() public so it can be called by validation. - WebKit/android/nav/WebView.cpp Enhance motionUp() with additional validation: use pointInNavCache() to see if there's a cached node; wait for message from webkit to see if bounds is unchanged; then use motionUp() to pass the original or altered click. This is a two-part change with frameworks/base. Fixes http://b/2249425
Diffstat (limited to 'WebKit')
-rw-r--r--WebKit/android/jni/WebViewCore.cpp33
-rw-r--r--WebKit/android/jni/WebViewCore.h1
-rw-r--r--WebKit/android/nav/CacheBuilder.cpp4
-rw-r--r--WebKit/android/nav/CacheBuilder.h2
-rw-r--r--WebKit/android/nav/CachedNode.h5
-rw-r--r--WebKit/android/nav/WebView.cpp60
6 files changed, 100 insertions, 5 deletions
diff --git a/WebKit/android/jni/WebViewCore.cpp b/WebKit/android/jni/WebViewCore.cpp
index 4bff8a7..e62b362 100644
--- a/WebKit/android/jni/WebViewCore.cpp
+++ b/WebKit/android/jni/WebViewCore.cpp
@@ -2632,6 +2632,21 @@ void WebViewCore::destroySurface(jobject childView)
checkException(env);
}
+bool WebViewCore::validNodeAndBounds(Frame* frame, Node* node,
+ const IntRect& originalAbsoluteBounds)
+{
+ bool valid = CacheBuilder::validNode(m_mainFrame, frame, node);
+ if (!valid)
+ return false;
+ RenderObject* renderer = node->renderer();
+ if (!renderer)
+ return false;
+ IntRect absBounds = node->hasTagName(HTMLNames::areaTag)
+ ? CacheBuilder::getAreaRect(static_cast<HTMLAreaElement*>(node))
+ : renderer->absoluteBoundingBoxRect();
+ return absBounds == originalAbsoluteBounds;
+}
+
//----------------------------------------------------------------------
// Native JNI methods
//----------------------------------------------------------------------
@@ -3219,6 +3234,22 @@ static void FullScreenPluginHidden(JNIEnv* env, jobject obj, jint npp)
plugin->exitFullScreen(false);
}
+static WebCore::IntRect jrect_to_webrect(JNIEnv* env, jobject obj)
+{
+ int L, T, R, B;
+ GraphicsJNI::get_jrect(env, obj, &L, &T, &R, &B);
+ return WebCore::IntRect(L, T, R - L, B - T);
+}
+
+static bool ValidNodeAndBounds(JNIEnv *env, jobject obj, int frame, int node,
+ jobject rect)
+{
+ IntRect nativeRect = jrect_to_webrect(env, rect);
+ return GET_NATIVE_VIEW(env, obj)->validNodeAndBounds(
+ reinterpret_cast<Frame*>(frame),
+ reinterpret_cast<Node*>(node), nativeRect);
+}
+
// ----------------------------------------------------------------------------
/*
@@ -3315,6 +3346,8 @@ static JNINativeMethod gJavaWebViewCoreMethods[] = {
(void*) ProvideVisitedHistory },
{ "nativeFullScreenPluginHidden", "(I)V",
(void*) FullScreenPluginHidden },
+ { "nativeValidNodeAndBounds", "(IILandroid/graphics/Rect;)Z",
+ (void*) ValidNodeAndBounds },
};
int register_webviewcore(JNIEnv* env)
diff --git a/WebKit/android/jni/WebViewCore.h b/WebKit/android/jni/WebViewCore.h
index 3f00f3c..21dd51b 100644
--- a/WebKit/android/jni/WebViewCore.h
+++ b/WebKit/android/jni/WebViewCore.h
@@ -397,6 +397,7 @@ namespace android {
// Destroys a SurfaceView for a plugin
void destroySurface(jobject childView);
+ bool validNodeAndBounds(Frame* , Node* , const IntRect& );
// other public functions
public:
// Open a file chooser for selecting a file to upload
diff --git a/WebKit/android/nav/CacheBuilder.cpp b/WebKit/android/nav/CacheBuilder.cpp
index f854e71..ce78c29 100644
--- a/WebKit/android/nav/CacheBuilder.cpp
+++ b/WebKit/android/nav/CacheBuilder.cpp
@@ -1005,11 +1005,13 @@ void CacheBuilder::BuildFrame(Frame* root, Frame* frame,
CachedInput cachedInput;
IntRect bounds;
IntRect absBounds;
+ IntRect originalAbsBounds;
WTF::Vector<IntRect>* columns = NULL;
if (node->hasTagName(HTMLNames::areaTag)) {
type = AREA_CACHEDNODETYPE;
HTMLAreaElement* area = static_cast<HTMLAreaElement*>(node);
bounds = getAreaRect(area);
+ originalAbsBounds = bounds;
bounds.move(globalOffsetX, globalOffsetY);
absBounds = bounds;
isUnclipped = true; // FIXME: areamaps require more effort to detect
@@ -1022,6 +1024,7 @@ void CacheBuilder::BuildFrame(Frame* root, Frame* frame,
// some common setup
absBounds = nodeRenderer->absoluteBoundingBoxRect();
+ originalAbsBounds = absBounds;
absBounds.move(globalOffsetX, globalOffsetY);
hasClip = nodeRenderer->hasOverflowClip();
@@ -1212,6 +1215,7 @@ void CacheBuilder::BuildFrame(Frame* root, Frame* frame,
cachedNode.setIsFocus(isFocus);
cachedNode.setIsTransparent(isTransparent);
cachedNode.setIsUnclipped(isUnclipped);
+ cachedNode.setOriginalAbsoluteBounds(originalAbsBounds);
cachedNode.setParentIndex(last->mCachedNodeIndex);
cachedNode.setParentGroup(ParentWithChildren(node));
cachedNode.setTabIndex(tabIndex);
diff --git a/WebKit/android/nav/CacheBuilder.h b/WebKit/android/nav/CacheBuilder.h
index 6cf1817..ff395d3 100644
--- a/WebKit/android/nav/CacheBuilder.h
+++ b/WebKit/android/nav/CacheBuilder.h
@@ -90,6 +90,7 @@ public:
mAllowableTypes & ~PHONE_CACHEDNODE_BIT); }
static FoundState FindAddress(const UChar* , unsigned length, int* start,
int* end, bool caseInsensitive);
+ static IntRect getAreaRect(const HTMLAreaElement* area);
static void GetGlobalOffset(Frame* , int* x, int * y);
static void GetGlobalOffset(Node* , int* x, int * y);
static bool validNode(Frame* startFrame, void* framePtr, void* nodePtr);
@@ -227,7 +228,6 @@ private:
static Frame* FrameAnd(CacheBuilder* focusNav);
static Frame* FrameAnd(const CacheBuilder* focusNav);
static CacheBuilder* Builder(Frame* );
- static IntRect getAreaRect(const HTMLAreaElement* area);
static Frame* HasFrame(Node* );
static bool HasOverOrOut(Node* );
static bool HasTriggerEvent(Node* );
diff --git a/WebKit/android/nav/CachedNode.h b/WebKit/android/nav/CachedNode.h
index a2e1f39..a433a47 100644
--- a/WebKit/android/nav/CachedNode.h
+++ b/WebKit/android/nav/CachedNode.h
@@ -129,6 +129,8 @@ public:
int navableRects() const { return mNavableRects; }
void* nodePointer() const { return mNode; }
bool noSecondChance() const { return mCondition > SECOND_CHANCE_END; }
+ const WebCore::IntRect& originalAbsoluteBounds() const {
+ return mOriginalAbsoluteBounds; }
const CachedNode* parent() const { return document() + mParentIndex; }
void* parentGroup() const { return mParentGroup; }
int parentIndex() const { return mParentIndex; }
@@ -143,6 +145,8 @@ public:
void setHasCursorRing(bool hasRing) { mHasCursorRing = hasRing; }
void setHasMouseOver(bool hasMouseOver) { mHasMouseOver = hasMouseOver; }
void setHitBounds(const WebCore::IntRect& bounds) { mHitBounds = bounds; }
+ void setOriginalAbsoluteBounds(const WebCore::IntRect& bounds) {
+ mOriginalAbsoluteBounds = bounds; }
void setIndex(int index) { mIndex = index; }
void setIsCursor(bool isCursor) { mIsCursor = isCursor; }
void setIsFocus(bool isFocus) { mIsFocus = isFocus; }
@@ -166,6 +170,7 @@ private:
WebCore::String mExport;
WebCore::IntRect mBounds;
WebCore::IntRect mHitBounds;
+ WebCore::IntRect mOriginalAbsoluteBounds;
WTF::Vector<WebCore::IntRect> mCursorRing;
void* mNode; // WebCore::Node*, only used to match pointers
void* mParentGroup; // WebCore::Node*, only used to match pointers
diff --git a/WebKit/android/nav/WebView.cpp b/WebKit/android/nav/WebView.cpp
index 3232a74..c29cb22 100644
--- a/WebKit/android/nav/WebView.cpp
+++ b/WebKit/android/nav/WebView.cpp
@@ -907,17 +907,32 @@ void setNavBounds(const WebCore::IntRect& rect)
root->rootHistory()->setNavBounds(rect);
}
+
+
+const CachedNode* m_cacheHitNode;
+const CachedFrame* m_cacheHitFrame;
+
+bool pointInNavCache(int x, int y, int slop)
+{
+ CachedRoot* root = getFrameCache(AllowNewer);
+ if (!root)
+ return false;
+ IntRect rect = IntRect(x - slop, y - slop, slop * 2, slop * 2);
+ int rx, ry;
+ return (m_cacheHitNode = findAt(root, rect, &m_cacheHitFrame, &rx, &ry));
+}
+
bool motionUp(int x, int y, int slop)
{
bool pageScrolled = false;
m_followedLink = false;
- const CachedFrame* frame;
- WebCore::IntRect rect = WebCore::IntRect(x - slop, y - slop, slop * 2, slop * 2);
+ IntRect rect = IntRect(x - slop, y - slop, slop * 2, slop * 2);
int rx, ry;
CachedRoot* root = getFrameCache(AllowNewer);
if (!root)
- return false;
- const CachedNode* result = findAt(root, rect, &frame, &rx, &ry);
+ return 0;
+ const CachedFrame* frame = 0;
+ const CachedNode* result = slop ? findAt(root, rect, &frame, &rx, &ry) : 0;
if (!result) {
DBG_NAV_LOGD("no nodes found root=%p", root);
setNavBounds(rect);
@@ -1372,6 +1387,29 @@ static jstring WebCoreStringToJString(JNIEnv *env, WebCore::String string)
return ret;
}
+static int nativeCacheHitFramePointer(JNIEnv *env, jobject obj)
+{
+ return reinterpret_cast<int>(GET_NATIVE_VIEW(env, obj)
+ ->m_cacheHitFrame->framePointer());
+}
+
+static jobject nativeCacheHitNodeBounds(JNIEnv *env, jobject obj)
+{
+ WebCore::IntRect bounds = GET_NATIVE_VIEW(env, obj)
+ ->m_cacheHitNode->originalAbsoluteBounds();
+ jclass rectClass = env->FindClass("android/graphics/Rect");
+ jmethodID init = env->GetMethodID(rectClass, "<init>", "(IIII)V");
+ jobject rect = env->NewObject(rectClass, init, bounds.x(),
+ bounds.y(), bounds.right(), bounds.bottom());
+ return rect;
+}
+
+static int nativeCacheHitNodePointer(JNIEnv *env, jobject obj)
+{
+ return reinterpret_cast<int>(GET_NATIVE_VIEW(env, obj)
+ ->m_cacheHitNode->nodePointer());
+}
+
static void nativeClearCursor(JNIEnv *env, jobject obj)
{
WebView* view = GET_NATIVE_VIEW(env, obj);
@@ -1782,6 +1820,12 @@ static jint nativeTextGeneration(JNIEnv *env, jobject obj)
return root ? root->textGeneration() : 0;
}
+static bool nativePointInNavCache(JNIEnv *env, jobject obj,
+ int x, int y, int slop)
+{
+ return GET_NATIVE_VIEW(env, obj)->pointInNavCache(x, y, slop);
+}
+
static bool nativeMotionUp(JNIEnv *env, jobject obj,
int x, int y, int slop)
{
@@ -2049,6 +2093,12 @@ static void nativeDumpDisplayTree(JNIEnv* env, jobject jwebview, jstring jurl)
* JNI registration
*/
static JNINativeMethod gJavaWebViewMethods[] = {
+ { "nativeCacheHitFramePointer", "()I",
+ (void*) nativeCacheHitFramePointer },
+ { "nativeCacheHitNodeBounds", "()Landroid/graphics/Rect;",
+ (void*) nativeCacheHitNodeBounds },
+ { "nativeCacheHitNodePointer", "()I",
+ (void*) nativeCacheHitNodePointer },
{ "nativeClearCursor", "()V",
(void*) nativeClearCursor },
{ "nativeCreate", "(I)V",
@@ -2145,6 +2195,8 @@ static JNINativeMethod gJavaWebViewMethods[] = {
(void*) nativeMoveGeneration },
{ "nativeMoveSelection", "(IIZ)V",
(void*) nativeMoveSelection },
+ { "nativePointInNavCache", "(III)Z",
+ (void*) nativePointInNavCache },
{ "nativeRecordButtons", "(ZZZ)V",
(void*) nativeRecordButtons },
{ "nativeSelectBestAt", "(Landroid/graphics/Rect;)V",