summaryrefslogtreecommitdiffstats
path: root/WebKit
diff options
context:
space:
mode:
Diffstat (limited to 'WebKit')
-rw-r--r--WebKit/android/WebCoreSupport/FrameLoaderClientAndroid.cpp3
-rw-r--r--WebKit/android/jni/WebSettings.cpp38
-rw-r--r--WebKit/android/jni/WebViewCore.cpp78
-rw-r--r--WebKit/android/jni/WebViewCore.h9
-rw-r--r--WebKit/android/nav/WebView.cpp44
5 files changed, 135 insertions, 37 deletions
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 },