summaryrefslogtreecommitdiffstats
path: root/WebKit/android/jni/WebViewCore.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'WebKit/android/jni/WebViewCore.cpp')
-rw-r--r--WebKit/android/jni/WebViewCore.cpp140
1 files changed, 77 insertions, 63 deletions
diff --git a/WebKit/android/jni/WebViewCore.cpp b/WebKit/android/jni/WebViewCore.cpp
index 64bfd8f..12dc9ef 100644
--- a/WebKit/android/jni/WebViewCore.cpp
+++ b/WebKit/android/jni/WebViewCore.cpp
@@ -280,6 +280,7 @@ void WebViewCore::reset(bool fromConstructor)
m_useReplay = false;
m_skipContentDraw = false;
m_findIsUp = false;
+ m_domtree_version = 0;
}
static bool layoutIfNeededRecursive(WebCore::Frame* f)
@@ -382,16 +383,19 @@ void WebViewCore::recordPictureSet(PictureSet* content)
m_frameCacheOutOfDate = true;
WebCore::IntRect oldBounds = oldFocusNode ?
oldFocusNode->getRect() : WebCore::IntRect(0,0,0,0);
- DBG_NAV_LOGD_THROTTLE("m_lastFocused=%p oldFocusNode=%p"
+ DBG_NAV_LOGD("m_lastFocused=%p oldFocusNode=%p"
" m_lastFocusedBounds={%d,%d,%d,%d} oldBounds={%d,%d,%d,%d}",
m_lastFocused, oldFocusNode,
m_lastFocusedBounds.x(), m_lastFocusedBounds.y(), m_lastFocusedBounds.width(), m_lastFocusedBounds.height(),
oldBounds.x(), oldBounds.y(), oldBounds.width(), oldBounds.height());
+ unsigned latestVersion = m_mainFrame->document()->domTreeVersion();
if (m_lastFocused != oldFocusNode || m_lastFocusedBounds != oldBounds
- || m_findIsUp) {
+ || m_findIsUp || latestVersion != m_domtree_version) {
m_lastFocused = oldFocusNode;
m_lastFocusedBounds = oldBounds;
- DBG_NAV_LOG("call updateFrameCache");
+ DBG_NAV_LOGD("call updateFrameCache m_domtree_version=%d latest=%d",
+ m_domtree_version, latestVersion);
+ m_domtree_version = latestVersion;
updateFrameCache();
}
}
@@ -508,8 +512,8 @@ void WebViewCore::rebuildPictureSet(PictureSet* pictureSet)
if (pictureSet->upToDate(index))
continue;
const SkIRect& inval = pictureSet->bounds(index);
- DBG_SET_LOGD("draw [%d] {%d,%d,w=%d,h=%d}", index, inval.fLeft,
- inval.fTop, inval.width(), inval.height());
+ DBG_SET_LOGD("pictSet=%p [%d] {%d,%d,w=%d,h=%d}", pictureSet, index,
+ inval.fLeft, inval.fTop, inval.width(), inval.height());
pictureSet->setPicture(index, rebuildPicture(inval));
}
pictureSet->validate(__FUNCTION__);
@@ -599,21 +603,13 @@ void WebViewCore::sendRecomputeFocus()
checkException(env);
}
-void WebViewCore::viewInvalidate(const SkIRect& rect)
-{
- LOG_ASSERT(m_javaGlue->m_obj, "A Java widget was not associated with this view bridge!");
- JNIEnv* env = JSC::Bindings::getJNIEnv();
- env->CallVoidMethod(m_javaGlue->object(env).get(), m_javaGlue->m_sendViewInvalidate,
- rect.fLeft, rect.fTop, rect.fRight, rect.fBottom);
- checkException(env);
-}
-
void WebViewCore::viewInvalidate(const WebCore::IntRect& rect)
-{
+{
LOG_ASSERT(m_javaGlue->m_obj, "A Java widget was not associated with this view bridge!");
JNIEnv* env = JSC::Bindings::getJNIEnv();
- env->CallVoidMethod(m_javaGlue->object(env).get(), m_javaGlue->m_sendViewInvalidate,
- rect.x(), rect.y(), rect.right(), rect.bottom());
+ env->CallVoidMethod(m_javaGlue->object(env).get(),
+ m_javaGlue->m_sendViewInvalidate,
+ rect.x(), rect.y(), rect.right(), rect.bottom());
checkException(env);
}
@@ -749,12 +745,12 @@ void WebViewCore::setScrollOffset(int dx, int dy)
if (m_scrollOffsetX != dx || m_scrollOffsetY != dy) {
m_scrollOffsetX = dx;
m_scrollOffsetY = dy;
- m_mainFrame->sendScrollEvent();
// The visible rect is located within our coordinate space so it
// contains the actual scroll position. Setting the location makes hit
// testing work correctly.
m_mainFrame->view()->platformWidget()->setLocation(m_scrollOffsetX,
m_scrollOffsetY);
+ m_mainFrame->sendScrollEvent();
}
}
@@ -1011,7 +1007,10 @@ void WebViewCore::drawPlugins()
if (!inval.isEmpty()) {
// inval.getBounds() is our rectangle
- this->viewInvalidate(inval.getBounds());
+ const SkIRect& bounds = inval.getBounds();
+ WebCore::IntRect r(bounds.fLeft, bounds.fTop,
+ bounds.width(), bounds.height());
+ this->viewInvalidate(r);
}
}
@@ -1021,7 +1020,7 @@ void WebViewCore::setFinalFocus(WebCore::Frame* frame, WebCore::Node* node,
int x, int y, bool block)
{
DBG_NAV_LOGD("frame=%p node=%p x=%d y=%d", frame, node, x, y);
- bool result = finalKitFocus(frame, node, x, y);
+ bool result = finalKitFocus(frame, node, x, y, false);
if (block) {
m_blockFocusChange = true;
if (!result && node)
@@ -1082,12 +1081,16 @@ bool WebViewCore::commonKitFocus(int generation, int buildGeneration,
releaseFrameCache(newCache);
if (!node && ignoreNullFocus)
return true;
- finalKitFocus(frame, node, x, y);
+ finalKitFocus(frame, node, x, y, false);
return true;
}
+// Update mouse position and may change focused node.
+// If donotChangeDOMFocus is true, the function does not changed focused node
+// in the DOM tree. Changing the focus in DOM may trigger onblur event
+// handler on the current focused node before firing mouse up and down events.
bool WebViewCore::finalKitFocus(WebCore::Frame* frame, WebCore::Node* node,
- int x, int y)
+ int x, int y, bool donotChangeDOMFocus)
{
if (!frame)
frame = m_mainFrame;
@@ -1103,41 +1106,48 @@ bool WebViewCore::finalKitFocus(WebCore::Frame* frame, WebCore::Node* node,
WebCore::MouseEventMoved, 1, false, false, false, false, WebCore::currentTime());
frame->eventHandler()->handleMouseMoveEvent(mouseEvent);
}
- WebCore::Document* oldDoc = oldFocusNode ? oldFocusNode->document() : 0;
- if (!node) {
- if (oldFocusNode)
- oldDoc->setFocusedNode(0);
- return false;
- } else if (!valid) {
- DBG_NAV_LOGD("sendMarkNodeInvalid node=%p", node);
- sendMarkNodeInvalid(node);
- if (oldFocusNode)
+
+ if (!donotChangeDOMFocus) {
+ WebCore::Document* oldDoc = oldFocusNode ? oldFocusNode->document() : 0;
+ if (!node) {
+ if (oldFocusNode)
+ oldDoc->setFocusedNode(0);
+ return false;
+ } else if (!valid) {
+ DBG_NAV_LOGD("sendMarkNodeInvalid node=%p", node);
+ sendMarkNodeInvalid(node);
+ if (oldFocusNode)
+ oldDoc->setFocusedNode(0);
+ return false;
+ }
+ // If we jump frames (docs), kill the focus on the old doc
+ if (oldFocusNode && node->document() != oldDoc) {
oldDoc->setFocusedNode(0);
- return false;
- }
- // If we jump frames (docs), kill the focus on the old doc
- builder.setLastFocus(node);
- if (oldFocusNode && node->document() != oldDoc) {
- oldDoc->setFocusedNode(0);
- }
- if (!node->isTextNode())
- static_cast<WebCore::Element*>(node)->focus(false);
- if (node->document()->focusedNode() != node) {
- // This happens when Element::focus() fails as we may try to set the
- // focus to a node which WebCore doesn't recognize as a focusable node.
- // So we need to do some extra work, as it does in Element::focus(),
- // besides calling Document::setFocusedNode.
- if (oldFocusNode) {
- // copied from clearSelectionIfNeeded in FocusController.cpp
- WebCore::SelectionController* s = oldDoc->frame()->selection();
- if (!s->isNone())
- s->clear();
}
- //setFocus on things that WebCore doesn't recognize as supporting focus
- //for instance, if there is an onclick element that does not support focus
- node->document()->setFocusedNode(node);
+ if (!node->isTextNode())
+ static_cast<WebCore::Element*>(node)->focus(false);
+ if (node->document()->focusedNode() != node) {
+ // This happens when Element::focus() fails as we may try to set the
+ // focus to a node which WebCore doesn't recognize as a focusable node.
+ // So we need to do some extra work, as it does in Element::focus(),
+ // besides calling Document::setFocusedNode.
+ if (oldFocusNode) {
+ // copied from clearSelectionIfNeeded in FocusController.cpp
+ WebCore::SelectionController* s = oldDoc->frame()->selection();
+ if (!s->isNone())
+ s->clear();
+ }
+ //setFocus on things that WebCore doesn't recognize as supporting focus
+ //for instance, if there is an onclick element that does not support focus
+ node->document()->setFocusedNode(node);
+ }
+ } else { // !donotChangeDOMFocus
+ if (!node || !valid)
+ return false;
}
+
DBG_NAV_LOGD("setFocusedNode node=%p", node);
+ builder.setLastFocus(node);
m_lastFocused = node;
m_lastFocusedBounds = node->getRect();
return true;
@@ -1175,7 +1185,7 @@ WebCore::Frame* WebViewCore::changedKitFocus(WebCore::Frame* frame,
WebCore::Node* current = FrameLoaderClientAndroid::get(m_mainFrame)->getCacheBuilder().currentFocus();
if (current == node)
return frame;
- return finalKitFocus(frame, node, x, y) ? frame : m_mainFrame;
+ return finalKitFocus(frame, node, x, y, false) ? frame : m_mainFrame;
}
static int findTextBoxIndex(WebCore::Node* node, const WebCore::IntPoint& pt)
@@ -1470,6 +1480,10 @@ public:
// index is listIndex of the selected item, or -1 if nothing is selected.
virtual void replyInt(int index)
{
+ if (-2 == index) {
+ // Special value for cancel. Do nothing.
+ return;
+ }
// If the select element no longer exists, do to a page change, etc, silently return.
if (!m_select || !FrameLoaderClientAndroid::get(m_viewImpl->m_mainFrame)->getCacheBuilder().validNode(m_frame, m_select))
return;
@@ -1493,8 +1507,8 @@ public:
}
// Response if the listbox allows multiple selection. array stores the listIndices
- // of selected positions.
- virtual void replyIntArray(const int* array, int count)
+ // of selected positions.
+ virtual void replyIntArray(const int* array, int count)
{
// If the select element no longer exists, do to a page change, etc, silently return.
if (!m_select || !FrameLoaderClientAndroid::get(m_viewImpl->m_mainFrame)->getCacheBuilder().validNode(m_frame, m_select))
@@ -1540,9 +1554,9 @@ static jobjectArray makeLabelArray(JNIEnv* env, const uint16_t** labels, size_t
void WebViewCore::listBoxRequest(WebCoreReply* reply, const uint16_t** labels, size_t count, const int enabled[], size_t enabledCount,
bool multiple, const int selected[], size_t selectedCountOrSelection)
{
- // Reuse m_popupReply
- Release(m_popupReply);
- m_popupReply = 0;
+ // If m_popupReply is not null, then we already have a list showing.
+ if (m_popupReply != 0)
+ return;
LOG_ASSERT(m_javaGlue->m_obj, "No java widget associated with this view!");
@@ -1661,7 +1675,7 @@ void WebViewCore::touchUp(int touchGeneration, int buildGeneration,
return; // short circuit if a newer touch has been generated
}
if (retry)
- finalKitFocus(frame, node, x, y);
+ finalKitFocus(frame, node, x, y, true); // don't change DOM focus
else if (!commonKitFocus(touchGeneration, buildGeneration,
frame, node, x, y, false)) {
return;
@@ -1692,7 +1706,7 @@ bool WebViewCore::handleMouseClick(WebCore::Frame* framePtr, WebCore::Node* node
// so when attempting to get the default, the point chosen would be follow the wrong link.
if (nodePtr->hasTagName(WebCore::HTMLNames::areaTag)) {
webFrame->setUserInitiatedClick(true);
- WebCore::EventTargetNodeCast(nodePtr)->dispatchSimulatedClick(0,
+ WebCore::EventTargetNodeCast(nodePtr)->dispatchSimulatedClick(0,
true, true);
webFrame->setUserInitiatedClick(false);
return true;
@@ -1940,7 +1954,7 @@ static void SetScrollOffset(JNIEnv *env, jobject obj, jint dx, jint dy)
viewImpl->setScrollOffset(dx, dy);
}
-static void SetGlobalBounds(JNIEnv *env, jobject obj, jint x, jint y, jint h,
+static void SetGlobalBounds(JNIEnv *env, jobject obj, jint x, jint y, jint h,
jint v)
{
WebViewCore* viewImpl = GET_NATIVE_VIEW(env, obj);
@@ -1949,7 +1963,7 @@ static void SetGlobalBounds(JNIEnv *env, jobject obj, jint x, jint y, jint h,
viewImpl->setGlobalBounds(x, y, h, v);
}
-static jboolean Key(JNIEnv *env, jobject obj, jint keyCode, jint unichar,
+static jboolean Key(JNIEnv *env, jobject obj, jint keyCode, jint unichar,
jint repeatCount, jboolean isShift, jboolean isAlt, jboolean isDown)
{
#ifdef ANDROID_INSTRUMENT