diff options
author | boliu@chromium.org <boliu@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-11-08 18:34:05 +0000 |
---|---|---|
committer | boliu@chromium.org <boliu@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-11-08 18:34:05 +0000 |
commit | a7198a1f23bd0fa70e1486e4deb71c1812572e26 (patch) | |
tree | ef9457229bb64e328d7602559c479101b0a11f6b /android_webview/renderer | |
parent | 72bd37ea59cc9b056dda7005e761aaba958e9eca (diff) | |
download | chromium_src-a7198a1f23bd0fa70e1486e4deb71c1812572e26.zip chromium_src-a7198a1f23bd0fa70e1486e4deb71c1812572e26.tar.gz chromium_src-a7198a1f23bd0fa70e1486e4deb71c1812572e26.tar.bz2 |
Implement hit test related methods in Android WebView
The public Android WebView APIs are WebView.getHitTestResult,
WebView.requestFocusNodeHref, and WebView.requestImageRef.
These APIs are mostly used for creating context menus but have
become broken APIs as the Android evolved from the single
threaded initial version of WebView.
* The names are misleading since the value retrieved is based both on
a combination of touch events and FocusedNodeChanged callback
from WebKit.
* The methods are synchronous and there are inherently racy. This is
the case with with the latest version of Android WebView as well.
However this may become more of a problem as Chromium is
multi-processed.
* The methods are inefficient since work needs to be done even if the
client application never call these methods.
This is the first part of largely replicating the broken code with tests
and extensive comments. The goal is to replicate existing logic but
there are probably corner cases that are not matched.
Overall flow is on a touch event or focused node changed event, perform
a WebKit hit test, get the relevant result data and save it in the browser.
The return what is saved when apps query for the data.
Work still needs to be done after this:
* Implement updating hit test data after tab-ing to a link
* Hook up content detection code in content/
* Implement focus highlighting with DPAD controls.
BUG=
All bots are green except unrelated instrumentation tests.
AndroidWebView instrumentation tests are green.
NOTRY=true
Review URL: https://chromiumcodereview.appspot.com/11360037
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@166712 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'android_webview/renderer')
-rw-r--r-- | android_webview/renderer/DEPS | 3 | ||||
-rw-r--r-- | android_webview/renderer/aw_render_view_ext.cc | 68 | ||||
-rw-r--r-- | android_webview/renderer/aw_render_view_ext.h | 4 |
3 files changed, 74 insertions, 1 deletions
diff --git a/android_webview/renderer/DEPS b/android_webview/renderer/DEPS index 5ee0454..5b0050c 100644 --- a/android_webview/renderer/DEPS +++ b/android_webview/renderer/DEPS @@ -5,5 +5,6 @@ include_rules = [ "+content/public/renderer", - "+third_party/WebKit/Source/WebKit/chromium", + "+third_party/WebKit/Source/WebKit/chromium/public", + "+third_party/WebKit/Source/Platform/chromium/public", ] diff --git a/android_webview/renderer/aw_render_view_ext.cc b/android_webview/renderer/aw_render_view_ext.cc index 2196ffe..3369379 100644 --- a/android_webview/renderer/aw_render_view_ext.cc +++ b/android_webview/renderer/aw_render_view_ext.cc @@ -4,16 +4,21 @@ #include "android_webview/renderer/aw_render_view_ext.h" +#include "android_webview/common/aw_hit_test_data.h" #include "android_webview/common/render_view_messages.h" #include "content/public/common/url_constants.h" +#include "content/public/common/url_constants.h" #include "content/public/renderer/document_state.h" #include "content/public/renderer/render_view.h" +#include "third_party/WebKit/Source/Platform/chromium/public/WebSize.h" #include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebURL.h" #include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebVector.h" #include "third_party/WebKit/Source/WebKit/chromium/public/WebDataSource.h" #include "third_party/WebKit/Source/WebKit/chromium/public/WebDocument.h" #include "third_party/WebKit/Source/WebKit/chromium/public/WebElement.h" #include "third_party/WebKit/Source/WebKit/chromium/public/WebFrame.h" +#include "third_party/WebKit/Source/WebKit/chromium/public/WebHitTestResult.h" +#include "third_party/WebKit/Source/WebKit/chromium/public/WebNode.h" #include "third_party/WebKit/Source/WebKit/chromium/public/WebSecurityOrigin.h" #include "third_party/WebKit/Source/WebKit/chromium/public/WebView.h" @@ -35,6 +40,7 @@ bool AwRenderViewExt::OnMessageReceived(const IPC::Message& message) { bool handled = true; IPC_BEGIN_MESSAGE_MAP(AwRenderViewExt, message) IPC_MESSAGE_HANDLER(AwViewMsg_DocumentHasImages, OnDocumentHasImagesRequest) + IPC_MESSAGE_HANDLER(AwViewMsg_DoHitTest, OnDoHitTest) IPC_MESSAGE_UNHANDLED(handled = false) IPC_END_MESSAGE_MAP() return handled; @@ -79,4 +85,66 @@ void AwRenderViewExt::DidCommitProvisionalLoad(WebKit::WebFrame* frame, } } +void AwRenderViewExt::FocusedNodeChanged(const WebKit::WebNode& node) { + if (!node.isNull()) { + if (node.isTextNode() && node.isContentEditable()) { + AwHitTestData data; + data.type = AwHitTestData::EDIT_TEXT_TYPE; + Send(new AwViewHostMsg_UpdateHitTestData( + routing_id(), data)); + } else { + // TODO(boliu): Implement this path. + NOTIMPLEMENTED() << "Tab focused links not implemented"; + } + } +} + +void AwRenderViewExt::OnDoHitTest(int view_x, int view_y) { + if (!render_view() || !render_view()->GetWebView()) + return; + + const WebKit::WebHitTestResult result = + render_view()->GetWebView()->hitTestResultAt( + WebKit::WebPoint(view_x, view_y)); + AwHitTestData data; + + // Populate fixed AwHitTestData fields. + if (result.absoluteImageURL().isValid()) + data.img_src = result.absoluteImageURL(); + if (!result.urlElement().isNull()) { + data.anchor_text = result.urlElement().innerText(); + + // href is the actual 'href' attribute, which might relative if valid or can + // possibly contain garbage otherwise, so not using absoluteLinkURL here. + data.href = result.urlElement().getAttribute("href"); + } + + GURL url(result.absoluteLinkURL()); + bool is_javascript_scheme = url.SchemeIs(chrome::kJavaScriptScheme); + + // Set AwHitTestData type and extra_data_for_type. + if (result.absoluteLinkURL().isValid() && + !result.absoluteImageURL().isValid() && + !is_javascript_scheme) { + data.type = AwHitTestData::SRC_LINK_TYPE; + data.extra_data_for_type = url.spec(); + } else if (result.absoluteLinkURL().isValid() && + result.absoluteImageURL().isValid() && + !is_javascript_scheme) { + data.type = AwHitTestData::SRC_IMAGE_LINK_TYPE; + data.extra_data_for_type = data.img_src.spec(); + } else if (!result.absoluteLinkURL().isValid() && + result.absoluteImageURL().isValid()) { + data.type = AwHitTestData::IMAGE_TYPE; + data.extra_data_for_type = data.img_src.spec(); + } else if (result.isContentEditable()) { + data.type = AwHitTestData::EDIT_TEXT_TYPE; + DCHECK(data.extra_data_for_type.length() == 0); + } else { + // TODO(boliu): Do content detection here. + } + + Send(new AwViewHostMsg_UpdateHitTestData(routing_id(), data)); +} + } // namespace android_webview diff --git a/android_webview/renderer/aw_render_view_ext.h b/android_webview/renderer/aw_render_view_ext.h index d2ff20c..c6d3bba 100644 --- a/android_webview/renderer/aw_render_view_ext.h +++ b/android_webview/renderer/aw_render_view_ext.h @@ -12,6 +12,7 @@ namespace WebKit { +class WebNode; class WebURL; } // namespace WebKit @@ -34,9 +35,12 @@ class AwRenderViewExt : public content::RenderViewObserver, virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE; virtual void DidCommitProvisionalLoad(WebKit::WebFrame* frame, bool is_new_navigation) OVERRIDE; + virtual void FocusedNodeChanged(const WebKit::WebNode& node) OVERRIDE; void OnDocumentHasImagesRequest(int id); + void OnDoHitTest(int view_x, int view_y); + // WebKit::WebPermissionClient implementation. virtual bool allowImage(WebKit::WebFrame* frame, bool enabledPerSettings, |