summaryrefslogtreecommitdiffstats
path: root/Source/WebKit/android
diff options
context:
space:
mode:
Diffstat (limited to 'Source/WebKit/android')
-rw-r--r--Source/WebKit/android/WebCoreSupport/ChromeClientAndroid.cpp11
-rw-r--r--Source/WebKit/android/jni/AndroidHitTestResult.cpp4
-rw-r--r--Source/WebKit/android/jni/ViewStateSerializer.cpp135
-rw-r--r--Source/WebKit/android/jni/WebViewCore.cpp51
-rw-r--r--Source/WebKit/android/jni/WebViewCore.h4
-rw-r--r--Source/WebKit/android/nav/WebView.cpp2
6 files changed, 161 insertions, 46 deletions
diff --git a/Source/WebKit/android/WebCoreSupport/ChromeClientAndroid.cpp b/Source/WebKit/android/WebCoreSupport/ChromeClientAndroid.cpp
index 1328675..5e16152 100644
--- a/Source/WebKit/android/WebCoreSupport/ChromeClientAndroid.cpp
+++ b/Source/WebKit/android/WebCoreSupport/ChromeClientAndroid.cpp
@@ -161,8 +161,15 @@ void ChromeClientAndroid::focus()
}
void ChromeClientAndroid::unfocus() { notImplemented(); }
-bool ChromeClientAndroid::canTakeFocus(FocusDirection) { notImplemented(); return false; }
-void ChromeClientAndroid::takeFocus(FocusDirection) { notImplemented(); }
+bool ChromeClientAndroid::canTakeFocus(FocusDirection direction)
+{
+ return android::WebViewCore::getWebViewCore(m_webFrame->page()->mainFrame()->view())->chromeCanTakeFocus(direction);
+}
+
+void ChromeClientAndroid::takeFocus(FocusDirection direction)
+{
+ android::WebViewCore::getWebViewCore(m_webFrame->page()->mainFrame()->view())->chromeTakeFocus(direction);
+}
void ChromeClientAndroid::focusedNodeChanged(Node* node)
{
diff --git a/Source/WebKit/android/jni/AndroidHitTestResult.cpp b/Source/WebKit/android/jni/AndroidHitTestResult.cpp
index 16dd809..9be5613 100644
--- a/Source/WebKit/android/jni/AndroidHitTestResult.cpp
+++ b/Source/WebKit/android/jni/AndroidHitTestResult.cpp
@@ -135,11 +135,15 @@ void AndroidHitTestResult::buildHighlightRects()
node = m_hitTestResult.innerNode();
if (!node || !node->renderer())
return;
+ if (!WebViewCore::nodeIsClickableOrFocusable(node))
+ return;
Frame* frame = node->document()->frame();
IntPoint frameOffset = m_webViewCore->convertGlobalContentToFrameContent(IntPoint(), frame);
RenderObject* renderer = node->renderer();
Vector<FloatQuad> quads;
renderer->absoluteFocusRingQuads(quads);
+ if (!quads.size())
+ renderer->absoluteQuads(quads); // No fancy rings, grab some backups
for (size_t i = 0; i < quads.size(); i++) {
IntRect boundingBox = quads[i].enclosingBoundingBox();
boundingBox.move(-frameOffset.x(), -frameOffset.y());
diff --git a/Source/WebKit/android/jni/ViewStateSerializer.cpp b/Source/WebKit/android/jni/ViewStateSerializer.cpp
index 6b473f5..a96b6b4 100644
--- a/Source/WebKit/android/jni/ViewStateSerializer.cpp
+++ b/Source/WebKit/android/jni/ViewStateSerializer.cpp
@@ -27,7 +27,10 @@
#include "BaseLayerAndroid.h"
#include "CreateJavaOutputStreamAdaptor.h"
+#include "FixedPositioning.h"
#include "ImagesManager.h"
+#include "IFrameContentLayerAndroid.h"
+#include "IFrameLayerAndroid.h"
#include "Layer.h"
#include "LayerAndroid.h"
#include "PictureSet.h"
@@ -49,6 +52,9 @@
#undef XLOG
#define XLOG(...)
+#undef XLOGC
+#define XLOGC(...) android_printLog(ANDROID_LOG_DEBUG, "ViewStateSerializer", __VA_ARGS__)
+
#endif // DEBUG
namespace android {
@@ -57,6 +63,7 @@ enum LayerTypes {
LTNone = 0,
LTLayerAndroid = 1,
LTScrollableLayerAndroid = 2,
+ LTFixedLayerAndroid = 3
};
static bool nativeSerializeViewState(JNIEnv* env, jobject, jint jbaseLayer,
@@ -91,8 +98,8 @@ static bool nativeSerializeViewState(JNIEnv* env, jobject, jint jbaseLayer,
return true;
}
-static BaseLayerAndroid* nativeDeserializeViewState(JNIEnv* env, jobject, jobject jstream,
- jbyteArray jstorage)
+static BaseLayerAndroid* nativeDeserializeViewState(JNIEnv* env, jobject, jint version,
+ jobject jstream, jbyteArray jstorage)
{
SkStream* stream = CreateJavaInputStreamAdaptor(env, jstream, jstorage);
if (!stream)
@@ -107,7 +114,7 @@ static BaseLayerAndroid* nativeDeserializeViewState(JNIEnv* env, jobject, jobjec
SkSafeUnref(picture);
int childCount = stream->readS32();
for (int i = 0; i < childCount; i++) {
- LayerAndroid* childLayer = deserializeLayer(stream);
+ LayerAndroid* childLayer = deserializeLayer(version, stream);
if (childLayer)
layer->addChild(childLayer);
}
@@ -253,9 +260,9 @@ void serializeLayer(LayerAndroid* layer, SkWStream* stream)
stream->write8(LTNone);
return;
}
- LayerTypes type = layer->contentIsScrollable()
- ? LTScrollableLayerAndroid
- : LTLayerAndroid;
+ LayerTypes type = LTLayerAndroid;
+ if (layer->contentIsScrollable())
+ type = LTScrollableLayerAndroid;
stream->write8(type);
// Start with Layer fields
@@ -272,20 +279,43 @@ void serializeLayer(LayerAndroid* layer, SkWStream* stream)
// Next up, LayerAndroid fields
stream->writeBool(layer->m_haveClip);
- stream->writeBool(layer->m_isFixed);
+ stream->writeBool(layer->isFixed());
stream->writeBool(layer->m_backgroundColorSet);
- stream->writeBool(layer->m_isIframe);
- writeSkLength(stream, layer->m_fixedLeft);
- writeSkLength(stream, layer->m_fixedTop);
- writeSkLength(stream, layer->m_fixedRight);
- writeSkLength(stream, layer->m_fixedBottom);
- writeSkLength(stream, layer->m_fixedMarginLeft);
- writeSkLength(stream, layer->m_fixedMarginTop);
- writeSkLength(stream, layer->m_fixedMarginRight);
- writeSkLength(stream, layer->m_fixedMarginBottom);
- writeSkRect(stream, layer->m_fixedRect);
- stream->write32(layer->m_renderLayerPos.x());
- stream->write32(layer->m_renderLayerPos.y());
+ stream->writeBool(layer->isIFrame());
+
+ // With the current LayerAndroid hierarchy, LayerAndroid doesn't have
+ // those fields anymore. Let's keep the current serialization format for
+ // now and output blank fields... not great, but probably better than
+ // dealing with multiple versions.
+ if (layer->fixedPosition()) {
+ FixedPositioning* fixedPosition = layer->fixedPosition();
+ writeSkLength(stream, fixedPosition->m_fixedLeft);
+ writeSkLength(stream, fixedPosition->m_fixedTop);
+ writeSkLength(stream, fixedPosition->m_fixedRight);
+ writeSkLength(stream, fixedPosition->m_fixedBottom);
+ writeSkLength(stream, fixedPosition->m_fixedMarginLeft);
+ writeSkLength(stream, fixedPosition->m_fixedMarginTop);
+ writeSkLength(stream, fixedPosition->m_fixedMarginRight);
+ writeSkLength(stream, fixedPosition->m_fixedMarginBottom);
+ writeSkRect(stream, fixedPosition->m_fixedRect);
+ stream->write32(fixedPosition->m_renderLayerPos.x());
+ stream->write32(fixedPosition->m_renderLayerPos.y());
+ } else {
+ SkLength length;
+ SkRect rect;
+ writeSkLength(stream, length); // fixedLeft
+ writeSkLength(stream, length); // fixedTop
+ writeSkLength(stream, length); // fixedRight
+ writeSkLength(stream, length); // fixedBottom
+ writeSkLength(stream, length); // fixedMarginLeft
+ writeSkLength(stream, length); // fixedMarginTop
+ writeSkLength(stream, length); // fixedMarginRight
+ writeSkLength(stream, length); // fixedMarginBottom
+ writeSkRect(stream, rect); // fixedRect
+ stream->write32(0); // renderLayerPos.x()
+ stream->write32(0); // renderLayerPos.y()
+ }
+
stream->writeBool(layer->m_backfaceVisibility);
stream->writeBool(layer->m_visible);
stream->write32(layer->m_backgroundColor);
@@ -327,7 +357,7 @@ void serializeLayer(LayerAndroid* layer, SkWStream* stream)
serializeLayer(layer->getChild(i), stream);
}
-LayerAndroid* deserializeLayer(SkStream* stream)
+LayerAndroid* deserializeLayer(int version, SkStream* stream)
{
int type = stream->readU8();
if (type == LTNone)
@@ -354,20 +384,55 @@ LayerAndroid* deserializeLayer(SkStream* stream)
// LayerAndroid fields
layer->m_haveClip = stream->readBool();
- layer->m_isFixed = stream->readBool();
+
+ // Keep the legacy serialization/deserialization format...
+ bool isFixed = stream->readBool();
+
layer->m_backgroundColorSet = stream->readBool();
- layer->m_isIframe = stream->readBool();
- layer->m_fixedLeft = readSkLength(stream);
- layer->m_fixedTop = readSkLength(stream);
- layer->m_fixedRight = readSkLength(stream);
- layer->m_fixedBottom = readSkLength(stream);
- layer->m_fixedMarginLeft = readSkLength(stream);
- layer->m_fixedMarginTop = readSkLength(stream);
- layer->m_fixedMarginRight = readSkLength(stream);
- layer->m_fixedMarginBottom = readSkLength(stream);
- layer->m_fixedRect = readSkRect(stream);
- layer->m_renderLayerPos.setX(stream->readS32());
- layer->m_renderLayerPos.setY(stream->readS32());
+
+ bool isIframe = stream->readBool();
+ // If we are a scrollable layer android, we are an iframe content
+ if (isIframe && type == LTScrollableLayerAndroid) {
+ IFrameContentLayerAndroid* iframeContent = new IFrameContentLayerAndroid(*layer);
+ layer->unref();
+ layer = iframeContent;
+ } else if (isIframe) { // otherwise we are just the iframe (we use it to compute offset)
+ IFrameLayerAndroid* iframe = new IFrameLayerAndroid(*layer);
+ layer->unref();
+ layer = iframe;
+ }
+
+ if (isFixed) {
+ FixedPositioning* fixedPosition = new FixedPositioning(layer);
+
+ fixedPosition->m_fixedLeft = readSkLength(stream);
+ fixedPosition->m_fixedTop = readSkLength(stream);
+ fixedPosition->m_fixedRight = readSkLength(stream);
+ fixedPosition->m_fixedBottom = readSkLength(stream);
+ fixedPosition->m_fixedMarginLeft = readSkLength(stream);
+ fixedPosition->m_fixedMarginTop = readSkLength(stream);
+ fixedPosition->m_fixedMarginRight = readSkLength(stream);
+ fixedPosition->m_fixedMarginBottom = readSkLength(stream);
+ fixedPosition->m_fixedRect = readSkRect(stream);
+ fixedPosition->m_renderLayerPos.setX(stream->readS32());
+ fixedPosition->m_renderLayerPos.setY(stream->readS32());
+
+ layer->setFixedPosition(fixedPosition);
+ } else {
+ // Not a fixed element, bypass the values in the stream
+ readSkLength(stream); // fixedLeft
+ readSkLength(stream); // fixedTop
+ readSkLength(stream); // fixedRight
+ readSkLength(stream); // fixedBottom
+ readSkLength(stream); // fixedMarginLeft
+ readSkLength(stream); // fixedMarginTop
+ readSkLength(stream); // fixedMarginRight
+ readSkLength(stream); // fixedMarginBottom
+ readSkRect(stream); // fixedRect
+ stream->readS32(); // renderLayerPos.x()
+ stream->readS32(); // renderLayerPos.y()
+ }
+
layer->m_backfaceVisibility = stream->readBool();
layer->m_visible = stream->readBool();
layer->m_backgroundColor = stream->readU32();
@@ -404,7 +469,7 @@ LayerAndroid* deserializeLayer(SkStream* stream)
}
int childCount = stream->readU32();
for (int i = 0; i < childCount; i++) {
- LayerAndroid *childLayer = deserializeLayer(stream);
+ LayerAndroid *childLayer = deserializeLayer(version, stream);
if (childLayer)
layer->addChild(childLayer);
}
@@ -419,7 +484,7 @@ LayerAndroid* deserializeLayer(SkStream* stream)
static JNINativeMethod gSerializerMethods[] = {
{ "nativeSerializeViewState", "(ILjava/io/OutputStream;[B)Z",
(void*) nativeSerializeViewState },
- { "nativeDeserializeViewState", "(Ljava/io/InputStream;[B)I",
+ { "nativeDeserializeViewState", "(ILjava/io/InputStream;[B)I",
(void*) nativeDeserializeViewState },
};
diff --git a/Source/WebKit/android/jni/WebViewCore.cpp b/Source/WebKit/android/jni/WebViewCore.cpp
index 41a8339..af25b3b 100644
--- a/Source/WebKit/android/jni/WebViewCore.cpp
+++ b/Source/WebKit/android/jni/WebViewCore.cpp
@@ -366,6 +366,8 @@ struct WebViewCore::JavaGlue {
jmethodID m_selectAt;
jmethodID m_initEditField;
jmethodID m_updateMatchCount;
+ jmethodID m_chromeCanTakeFocus;
+ jmethodID m_chromeTakeFocus;
AutoJObject object(JNIEnv* env) {
// We hold a weak reference to the Java WebViewCore to avoid memeory
// leaks due to circular references when WebView.destroy() is not
@@ -482,6 +484,8 @@ WebViewCore::WebViewCore(JNIEnv* env, jobject javaWebViewCore, WebCore::Frame* m
m_javaGlue->m_selectAt = GetJMethod(env, clazz, "selectAt", "(II)V");
m_javaGlue->m_initEditField = GetJMethod(env, clazz, "initEditField", "(ILjava/lang/String;IZZLjava/lang/String;IIII)V");
m_javaGlue->m_updateMatchCount = GetJMethod(env, clazz, "updateMatchCount", "(IILjava/lang/String;)V");
+ m_javaGlue->m_chromeCanTakeFocus = GetJMethod(env, clazz, "chromeCanTakeFocus", "(I)Z");
+ m_javaGlue->m_chromeTakeFocus = GetJMethod(env, clazz, "chromeTakeFocus", "(I)V");
env->DeleteLocalRef(clazz);
env->SetIntField(javaWebViewCore, gWebViewCoreFields.m_nativeClass, (jint)this);
@@ -1670,6 +1674,23 @@ void WebViewCore::selectText(int startX, int startY, int endX, int endY)
sc->setSelection(selection);
}
+bool WebViewCore::nodeIsClickableOrFocusable(Node* node)
+{
+ if (!node)
+ return false;
+ if (node->disabled())
+ return false;
+ if (!node->inDocument())
+ return false;
+ if (!node->renderer() || node->renderer()->style()->visibility() != VISIBLE)
+ return false;
+ return node->supportsFocus()
+ || node->hasEventListeners(eventNames().clickEvent)
+ || node->hasEventListeners(eventNames().mousedownEvent)
+ || node->hasEventListeners(eventNames().mouseupEvent)
+ || node->hasEventListeners(eventNames().mouseoverEvent);
+}
+
// get the highlight rectangles for the touch point (x, y) with the slop
AndroidHitTestResult WebViewCore::hitTestAtPoint(int x, int y, int slop, bool doMoveMouse)
{
@@ -1711,11 +1732,7 @@ AndroidHitTestResult WebViewCore::hitTestAtPoint(int x, int y, int slop, bool do
RenderObject* render = eventNode->renderer();
if (render && (render->isBody() || render->isRenderView()))
break;
- if (eventNode->supportsFocus()
- || eventNode->hasEventListeners(eventNames().clickEvent)
- || eventNode->hasEventListeners(eventNames().mousedownEvent)
- || eventNode->hasEventListeners(eventNames().mouseupEvent)
- || eventNode->hasEventListeners(eventNames().mouseoverEvent)) {
+ if (nodeIsClickableOrFocusable(eventNode)) {
found = true;
break;
}
@@ -1816,15 +1833,15 @@ AndroidHitTestResult WebViewCore::hitTestAtPoint(int x, int y, int slop, bool do
}
// now get the node's highlight rectangles in the page coordinate system
if (final.mUrlNode) {
+ // Update innerNode and innerNonSharedNode
+ androidHitResult.hitTestResult().setInnerNode(final.mInnerNode);
+ androidHitResult.hitTestResult().setInnerNonSharedNode(final.mInnerNode);
if (final.mUrlNode->isElementNode()) {
// We found a URL element. Update the hitTestResult
androidHitResult.setURLElement(static_cast<Element*>(final.mUrlNode));
} else {
androidHitResult.setURLElement(0);
}
- // Update innerNode and innerNonSharedNode
- androidHitResult.hitTestResult().setInnerNode(final.mInnerNode);
- androidHitResult.hitTestResult().setInnerNonSharedNode(final.mInnerNode);
IntPoint frameAdjust;
if (frame != m_mainFrame) {
frameAdjust = frame->view()->contentsToWindow(IntPoint());
@@ -2990,6 +3007,24 @@ bool WebViewCore::key(const PlatformKeyboardEvent& event)
return eventHandler->keyEvent(event);
}
+bool WebViewCore::chromeCanTakeFocus(FocusDirection direction)
+{
+ JNIEnv* env = JSC::Bindings::getJNIEnv();
+ AutoJObject javaObject = m_javaGlue->object(env);
+ if (!javaObject.get())
+ return false;
+ return env->CallBooleanMethod(javaObject.get(), m_javaGlue->m_chromeCanTakeFocus, direction);
+}
+
+void WebViewCore::chromeTakeFocus(FocusDirection direction)
+{
+ JNIEnv* env = JSC::Bindings::getJNIEnv();
+ AutoJObject javaObject = m_javaGlue->object(env);
+ if (!javaObject.get())
+ return;
+ env->CallVoidMethod(javaObject.get(), m_javaGlue->m_chromeTakeFocus, direction);
+}
+
// For when the user clicks the trackball, presses dpad center, or types into an
// unfocused textfield. In the latter case, 'fake' will be true
void WebViewCore::click(WebCore::Frame* frame, WebCore::Node* node, bool fake) {
diff --git a/Source/WebKit/android/jni/WebViewCore.h b/Source/WebKit/android/jni/WebViewCore.h
index 4cbc566..c5704e0 100644
--- a/Source/WebKit/android/jni/WebViewCore.h
+++ b/Source/WebKit/android/jni/WebViewCore.h
@@ -29,6 +29,7 @@
#include "DeviceMotionAndOrientationManager.h"
#include "DOMSelection.h"
#include "FileChooser.h"
+#include "FocusDirection.h"
#include "HitTestResult.h"
#include "PictureSet.h"
#include "PlatformGraphicsContext.h"
@@ -318,6 +319,8 @@ namespace android {
* @return Whether keyCode was handled by this class.
*/
bool key(const WebCore::PlatformKeyboardEvent& event);
+ bool chromeCanTakeFocus(FocusDirection direction);
+ void chromeTakeFocus(FocusDirection direction);
/**
* Handle (trackball) click event / dpad center press from Java.
@@ -509,6 +512,7 @@ namespace android {
Node** node, HitTestResult* hitTestResult);
// This does a sloppy hit test
AndroidHitTestResult hitTestAtPoint(int x, int y, int slop, bool doMoveMouse = false);
+ static bool nodeIsClickableOrFocusable(Node* node);
// Open a file chooser for selecting a file to upload
void openFileChooser(PassRefPtr<WebCore::FileChooser> );
diff --git a/Source/WebKit/android/nav/WebView.cpp b/Source/WebKit/android/nav/WebView.cpp
index 830ef4e..8b7acc5 100644
--- a/Source/WebKit/android/nav/WebView.cpp
+++ b/Source/WebKit/android/nav/WebView.cpp
@@ -313,7 +313,7 @@ PictureSet* draw(SkCanvas* canvas, SkColor bgColor, DrawExtras extras, bool spli
if (compositeLayer) {
// call this to be sure we've adjusted for any scrolling or animations
// before we actually draw
- compositeLayer->updateFixedLayersPositions(m_visibleRect);
+ compositeLayer->updateLayerPositions(m_visibleRect);
compositeLayer->updatePositions();
// We have to set the canvas' matrix on the base layer
// (to have fixed layers work as intended)