diff options
-rw-r--r-- | WebCore/loader/CachedImage.cpp | 4 | ||||
-rw-r--r-- | WebKit/android/WebCoreSupport/FrameLoaderClientAndroid.cpp | 3 | ||||
-rw-r--r-- | WebKit/android/jni/WebSettings.cpp | 38 | ||||
-rw-r--r-- | WebKit/android/jni/WebViewCore.cpp | 78 | ||||
-rw-r--r-- | WebKit/android/jni/WebViewCore.h | 9 | ||||
-rw-r--r-- | WebKit/android/nav/WebView.cpp | 44 |
6 files changed, 139 insertions, 37 deletions
diff --git a/WebCore/loader/CachedImage.cpp b/WebCore/loader/CachedImage.cpp index b915b17..3327c38 100644 --- a/WebCore/loader/CachedImage.cpp +++ b/WebCore/loader/CachedImage.cpp @@ -77,7 +77,11 @@ void CachedImage::decodedDataDeletionTimerFired(Timer<CachedImage>*) void CachedImage::load(DocLoader* docLoader) { +#ifdef ANDROID_BLOCK_NETWORK_IMAGE + if (!docLoader || (docLoader->autoLoadImages() && !docLoader->shouldBlockNetworkImage(m_url))) +#else if (!docLoader || docLoader->autoLoadImages()) +#endif CachedResource::load(docLoader, true, false, true); else m_loading = false; diff --git a/WebKit/android/WebCoreSupport/FrameLoaderClientAndroid.cpp b/WebKit/android/WebCoreSupport/FrameLoaderClientAndroid.cpp index 93dcdf4..8782132 100644 --- a/WebKit/android/WebCoreSupport/FrameLoaderClientAndroid.cpp +++ b/WebKit/android/WebCoreSupport/FrameLoaderClientAndroid.cpp @@ -991,7 +991,8 @@ ObjectContentType FrameLoaderClientAndroid::objectContentType(const KURL& url, return ObjectContentFrame; if (Image::supportsType(mimeType)) return ObjectContentImage; - return ObjectContentNone; + // Use OtherPlugin so embed and object tags draw the null plugin view + return ObjectContentOtherPlugin; } // This function allows the application to set the correct CSS media diff --git a/WebKit/android/jni/WebSettings.cpp b/WebKit/android/jni/WebSettings.cpp index 9860996..855abdd 100644 --- a/WebKit/android/jni/WebSettings.cpp +++ b/WebKit/android/jni/WebSettings.cpp @@ -279,15 +279,35 @@ public: str = (jstring)env->GetObjectField(obj, gFieldIds->mPluginsPath); if (str) { WebCore::String pluginsPath = to_string(env, str); - s->setPluginsPath(pluginsPath); - // Set the plugin directories to this single entry. - Vector< ::WebCore::String > paths(1); - paths[0] = pluginsPath; - pluginDatabase->setPluginDirectories(paths); - // Set the home directory for plugin temporary files - WebCore::sPluginPath = paths[0]; - // Reload plugins. - pluginDatabase->refresh(); + // When a new browser Tab is created, the corresponding + // Java WebViewCore object will sync (with the native + // side) its associated WebSettings at initialization + // time. However, at that point, the WebSettings object's + // mPluginsPaths member is set to the empty string. The + // real plugin path will be set later by the tab and the + // WebSettings will be synced again. + // + // There is no point in instructing WebCore's + // PluginDatabase instance to set the plugin path to the + // empty string. Furthermore, if the PluginDatabase + // instance is already initialized, setting the path to + // the empty string will cause the PluginDatabase to + // forget about the plugin files it has already + // inspected. When the path is subsequently set to the + // correct value, the PluginDatabase will attempt to load + // and initialize plugins that are already loaded and + // initialized. + if (pluginsPath.length()) { + s->setPluginsPath(pluginsPath); + // Set the plugin directories to this single entry. + Vector< ::WebCore::String > paths(1); + paths[0] = pluginsPath; + pluginDatabase->setPluginDirectories(paths); + // Set the home directory for plugin temporary files + WebCore::sPluginPath = paths[0]; + // Reload plugins. + pluginDatabase->refresh(); + } } #endif diff --git a/WebKit/android/jni/WebViewCore.cpp b/WebKit/android/jni/WebViewCore.cpp index fc32b98..ee74685 100644 --- a/WebKit/android/jni/WebViewCore.cpp +++ b/WebKit/android/jni/WebViewCore.cpp @@ -210,7 +210,7 @@ WebViewCore::WebViewCore(JNIEnv* env, jobject javaWebViewCore, WebCore::Frame* m m_javaGlue->m_obj = adoptGlobalRef(env, javaWebViewCore); m_javaGlue->m_spawnScrollTo = GetJMethod(env, clazz, "contentSpawnScrollTo", "(II)V"); m_javaGlue->m_scrollTo = GetJMethod(env, clazz, "contentScrollTo", "(II)V"); - m_javaGlue->m_scrollBy = GetJMethod(env, clazz, "contentScrollBy", "(II)V"); + m_javaGlue->m_scrollBy = GetJMethod(env, clazz, "contentScrollBy", "(IIZ)V"); m_javaGlue->m_contentDraw = GetJMethod(env, clazz, "contentDraw", "()V"); m_javaGlue->m_requestListBox = GetJMethod(env, clazz, "requestListBox", "([Ljava/lang/String;[Z[I)V"); m_javaGlue->m_requestSingleListBox = GetJMethod(env, clazz, "requestListBox", "([Ljava/lang/String;[ZI)V"); @@ -385,15 +385,21 @@ void WebViewCore::recordPictureSet(PictureSet* content) // and check to see if any already split pieces need to be redrawn. if (content->build()) rebuildPictureSet(content); - CacheBuilder& builder = FrameLoaderClientAndroid::get(m_mainFrame)->getCacheBuilder(); - WebCore::Node* oldFocusNode = builder.currentFocus(); m_frameCacheOutOfDate = true; +} + +void WebViewCore::checkNavCache() +{ + CacheBuilder& builder = FrameLoaderClientAndroid::get(m_mainFrame) + ->getCacheBuilder(); + WebCore::Node* oldFocusNode = builder.currentFocus(); WebCore::IntRect oldBounds = oldFocusNode ? oldFocusNode->getRect() : WebCore::IntRect(0,0,0,0); 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(), + 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 @@ -630,12 +636,13 @@ void WebViewCore::viewInvalidate(const WebCore::IntRect& rect) checkException(env); } -void WebViewCore::scrollBy(int dx, int dy) +void WebViewCore::scrollBy(int dx, int dy, bool animate) { if (!(dx | dy)) return; JNIEnv* env = JSC::Bindings::getJNIEnv(); - env->CallVoidMethod(m_javaGlue->object(env).get(), m_javaGlue->m_scrollBy, dx, dy); + env->CallVoidMethod(m_javaGlue->object(env).get(), m_javaGlue->m_scrollBy, + dx, dy, animate); checkException(env); } @@ -753,7 +760,7 @@ void WebViewCore::doMaxScroll(CacheBuilder::Direction dir) default: LOG_ASSERT(0, "unexpected focus selector"); } - this->scrollBy(dx, dy); + this->scrollBy(dx, dy, true); } void WebViewCore::setScrollOffset(int dx, int dy) @@ -777,25 +784,59 @@ void WebViewCore::setGlobalBounds(int x, int y, int h, int v) m_mainFrame->view()->platformWidget()->setWindowBounds(x, y, h, v); } -void WebViewCore::setSizeScreenWidthAndScale(int width, int height, int screenWidth, int scale) +void WebViewCore::setSizeScreenWidthAndScale(int width, int height, + int screenWidth, int scale, int realScreenWidth, int screenHeight) { WebCoreViewBridge* window = m_mainFrame->view()->platformWidget(); int ow = window->width(); int oh = window->height(); window->setSize(width, height); int osw = m_screenWidth; + DBG_NAV_LOGD("old:(w=%d,h=%d,sw=%d,scale=%d) new:(w=%d,h=%d,sw=%d,scale=%d)", + ow, oh, osw, m_scale, width, height, screenWidth, scale); m_screenWidth = screenWidth; m_scale = scale; m_maxXScroll = screenWidth >> 2; m_maxYScroll = (screenWidth * height / width) >> 2; - DBG_NAV_LOGD("old:(w=%d,h=%d,s=%d) new:(w=%d,h=%d,s=%d)", - ow, oh, osw, width, height, screenWidth); if (ow != width || oh != height || osw != screenWidth) { WebCore::RenderObject *r = m_mainFrame->contentRenderer(); - DBG_NAV_LOGD("renderer=%p", r); + DBG_NAV_LOGD("renderer=%p view=(w=%d,h=%d)", r, + realScreenWidth, screenHeight); if (r) { + // get current screen center position + WebCore::IntPoint screenCenter = WebCore::IntPoint( + m_scrollOffsetX + (realScreenWidth >> 1), + m_scrollOffsetY + (screenHeight >> 1)); + WebCore::HitTestResult hitTestResult = m_mainFrame->eventHandler()-> + hitTestResultAtPoint(screenCenter, false); + WebCore::Node* node = hitTestResult.innerNode(); + WebCore::IntRect bounds; + WebCore::IntPoint offset; + if (node) { + bounds = node->getRect(); + DBG_NAV_LOGD("ob:(x=%d,y=%d,w=%d,h=%d)", + bounds.x(), bounds.y(), bounds.width(), bounds.height()); + offset = WebCore::IntPoint(screenCenter.x() - bounds.x(), + screenCenter.y() - bounds.y()); + if (offset.x() < 0 || offset.x() > realScreenWidth || + offset.y() < 0 || offset.y() > screenHeight) + { + DBG_NAV_LOGD("offset out of bounds:(x=%d,y=%d)", + offset.x(), offset.y()); + node = 0; + } + } r->setNeedsLayoutAndPrefWidthsRecalc(); m_mainFrame->forceLayout(true); + // scroll to restore current screen center + if (!node) + return; + const WebCore::IntRect& newBounds = node->getRect(); + DBG_NAV_LOGD("nb:(x=%d,y=%d,w=%d," + "h=%d,ns=%d)", newBounds.x(), newBounds.y(), + newBounds.width(), newBounds.height()); + scrollBy(newBounds.x() - bounds.x(), newBounds.y() - bounds.y(), + false); } } } @@ -1948,7 +1989,7 @@ static jstring WebCoreStringToJString(JNIEnv *env, WebCore::String string) } static void SetSize(JNIEnv *env, jobject obj, jint width, jint height, - jint screenWidth, jfloat scale) + jint screenWidth, jfloat scale, jint realScreenWidth, jint screenHeight) { #ifdef ANDROID_INSTRUMENT TimeCounterAuto counter(TimeCounter::WebViewCoreTimeCounter); @@ -1962,7 +2003,8 @@ static void SetSize(JNIEnv *env, jobject obj, jint width, jint height, if (scale < 0) s = viewImpl->scale(); - viewImpl->setSizeScreenWidthAndScale(width, height, screenWidth, s); + viewImpl->setSizeScreenWidthAndScale(width, height, screenWidth, s, + realScreenWidth, screenHeight); } static void SetScrollOffset(JNIEnv *env, jobject obj, jint dx, jint dy) @@ -2331,6 +2373,12 @@ static void RegisterURLSchemeAsLocal(JNIEnv* env, jobject obj, jstring scheme) { WebCore::FrameLoader::registerURLSchemeAsLocal(to_string(env, scheme)); } +static void CheckNavCache(JNIEnv *env, jobject obj) +{ + WebViewCore* viewImpl = GET_NATIVE_VIEW(env, obj); + viewImpl->checkNavCache(); +} + static void ClearContent(JNIEnv *env, jobject obj) { WebViewCore* viewImpl = GET_NATIVE_VIEW(env, obj); @@ -2359,6 +2407,8 @@ static bool DrawContent(JNIEnv *env, jobject obj, jobject canv, jint color) * JNI registration. */ static JNINativeMethod gJavaWebViewCoreMethods[] = { + { "nativeCheckNavCache", "()V", + (void*) CheckNavCache }, { "nativeClearContent", "()V", (void*) ClearContent }, { "nativeCopyContentToPicture", "(Landroid/graphics/Picture;)V", @@ -2373,7 +2423,7 @@ static JNINativeMethod gJavaWebViewCoreMethods[] = { (void*) SendListBoxChoices }, { "nativeSendListBoxChoice", "(I)V", (void*) SendListBoxChoice }, - { "nativeSetSize", "(IIIF)V", + { "nativeSetSize", "(IIIFII)V", (void*) SetSize }, { "nativeSetScrollOffset", "(II)V", (void*) SetScrollOffset }, diff --git a/WebKit/android/jni/WebViewCore.h b/WebKit/android/jni/WebViewCore.h index 6ae0de1..3743206 100644 --- a/WebKit/android/jni/WebViewCore.h +++ b/WebKit/android/jni/WebViewCore.h @@ -105,8 +105,9 @@ namespace android { * Scroll to the point x,y relative to the current position. * @param x The relative x position. * @param y The relative y position. + * @param animate If it is true, animate to the new scroll position */ - void scrollBy(int x, int y); + void scrollBy(int x, int y, bool animate); /** * Record the invalid rectangle @@ -181,7 +182,8 @@ namespace android { // Create a single picture to represent the drawn DOM (used by navcache) void recordPicture(SkPicture* picture); - + // Rebuild the nav cache if the dom changed + void checkNavCache(); // Create a set of pictures to represent the drawn DOM, driven by // the invalidated region and the time required to draw (used to draw) void recordPictureSet(PictureSet* master); @@ -196,7 +198,8 @@ namespace android { void setGlobalBounds(int x, int y, int h, int v); - void setSizeScreenWidthAndScale(int width, int height, int screenWidth, int scale); + void setSizeScreenWidthAndScale(int width, int height, int screenWidth, + int scale, int realScreenWidth, int screenHeight); /** * Handle key events from Java. diff --git a/WebKit/android/nav/WebView.cpp b/WebKit/android/nav/WebView.cpp index 39c53aa..341a54d 100644 --- a/WebKit/android/nav/WebView.cpp +++ b/WebKit/android/nav/WebView.cpp @@ -360,6 +360,7 @@ enum OutOfFocusFix { struct JavaGlue { jobject m_obj; jmethodID m_clearTextEntry; + jmethodID m_overrideLoading; jmethodID m_scrollBy; jmethodID m_sendFinalFocus; jmethodID m_sendKitFocus; @@ -389,8 +390,9 @@ WebView(JNIEnv* env, jobject javaWebView, int viewImpl) jclass clazz = env->FindClass("android/webkit/WebView"); // m_javaGlue = new JavaGlue; m_javaGlue.m_obj = adoptGlobalRef(env, javaWebView); - m_javaGlue.m_scrollBy = GetJMethod(env, clazz, "setContentScrollBy", "(II)V"); + m_javaGlue.m_scrollBy = GetJMethod(env, clazz, "setContentScrollBy", "(IIZ)V"); m_javaGlue.m_clearTextEntry = GetJMethod(env, clazz, "clearTextEntry", "()V"); + m_javaGlue.m_overrideLoading = GetJMethod(env, clazz, "overrideLoading", "(Ljava/lang/String;)V"); m_javaGlue.m_sendFinalFocus = GetJMethod(env, clazz, "sendFinalFocus", "(IIII)V"); m_javaGlue.m_sendKitFocus = GetJMethod(env, clazz, "sendKitFocus", "()V"); m_javaGlue.m_sendMotionUp = GetJMethod(env, clazz, "sendMotionUp", "(IIIIIIIZZ)V"); @@ -500,7 +502,9 @@ void debugDump() // their subpictures according to their current focus state. // Called from the UI thread. This is the one place in the UI thread where we // access the buttons stored in the WebCore thread. -void nativeRecordButtons(bool pressed, bool invalidate) +// hasFocus keeps track of whether the WebView has focus && windowFocus. +// If not, we do not want to draw the button in a focused or pressed state +void nativeRecordButtons(bool hasFocus, bool pressed, bool invalidate) { bool focusIsButton = false; const CachedNode* cachedFocus = 0; @@ -527,7 +531,12 @@ void nativeRecordButtons(bool pressed, bool invalidate) WebCore::RenderSkinAndroid::State state; if (ptr->matches(focus)) { focusIsButton = true; - if (m_followedLink || pressed) { + // If the WebView is out of focus/window focus, set the state to + // normal, but still keep track of the fact that the focus is a + // button + if (!hasFocus) { + state = WebCore::RenderSkinAndroid::kNormal; + } else if (m_followedLink || pressed) { state = WebCore::RenderSkinAndroid::kPressed; } else { state = WebCore::RenderSkinAndroid::kFocused; @@ -1403,7 +1412,8 @@ void motionUp(int x, int y, int slop, bool isClick, bool inval, bool retry) root->setCachedFocus(const_cast<CachedFrame*>(frame), const_cast<CachedNode*>(result)); bool newNodeIsTextArea = focusIsTextArea(DontAllowNewer); - if (result->type() == NORMAL_CACHEDNODETYPE || newNodeIsTextArea) { + CachedNodeType type = result->type(); + if (type == NORMAL_CACHEDNODETYPE || newNodeIsTextArea) { sendMotionUp(root->generation(), frame ? (WebCore::Frame*) frame->framePointer() : 0, result ? (WebCore::Node*) result->nodePointer() : 0, rx, ry, @@ -1427,13 +1437,26 @@ void motionUp(int x, int y, int slop, bool isClick, bool inval, bool retry) updateTextEntry(); displaySoftKeyboard(); } else { - if (isClick) + if (isClick) { setFollowedLink(true); + if (type != NORMAL_CACHEDNODETYPE) { + overrideUrlLoading(result->getExport()); + } + } if (oldNodeIsTextArea) clearTextEntry(); } } +void overrideUrlLoading(const WebCore::String& url) +{ + JNIEnv* env = JSC::Bindings::getJNIEnv(); + jstring jName = env->NewString((jchar*) url.characters(), url.length()); + env->CallVoidMethod(m_javaGlue.object(env).get(), + m_javaGlue.m_overrideLoading, jName); + env->DeleteLocalRef(jName); +} + void setFindIsUp(bool up) { m_viewImpl->m_findIsUp = up; @@ -1695,7 +1718,8 @@ void scrollBy(int dx, int dy) LOG_ASSERT(m_javaGlue.m_obj, "A java object was not associated with this native WebView!"); JNIEnv* env = JSC::Bindings::getJNIEnv(); - env->CallVoidMethod(m_javaGlue.object(env).get(), m_javaGlue.m_scrollBy, dx, dy); + env->CallVoidMethod(m_javaGlue.object(env).get(), m_javaGlue.m_scrollBy, + dx, dy, true); checkException(env); } @@ -1994,12 +2018,12 @@ static void nativeRecomputeFocus(JNIEnv *env, jobject obj) view->recomputeFocus(); } -static void nativeRecordButtons(JNIEnv* env, jobject obj, bool pressed, - bool invalidate) +static void nativeRecordButtons(JNIEnv* env, jobject obj, bool hasFocus, + bool pressed, bool invalidate) { WebView* view = GET_NATIVE_VIEW(env, obj); LOG_ASSERT(view, "view not set in %s", __FUNCTION__); - view->nativeRecordButtons(pressed, invalidate); + view->nativeRecordButtons(hasFocus, pressed, invalidate); } static void nativeResetFocus(JNIEnv *env, jobject obj) @@ -2254,7 +2278,7 @@ static JNINativeMethod gJavaWebViewMethods[] = { (void*) nativeNotifyFocusSet }, { "nativeRecomputeFocus", "()V", (void*) nativeRecomputeFocus }, - { "nativeRecordButtons", "(ZZ)V", + { "nativeRecordButtons", "(ZZZ)V", (void*) nativeRecordButtons }, { "nativeResetFocus", "()V", (void*) nativeResetFocus }, |