summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorbauerb@chromium.org <bauerb@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-07-19 11:47:40 +0000
committerbauerb@chromium.org <bauerb@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-07-19 11:47:40 +0000
commit00152e9ffa80198724da8705594cc14c2d7fb5e5 (patch)
tree7750ebd07097e1b0b3620e53f0730dbdbf7775bf
parentbf89db9145b20cafdb4e044a023d95ebfec21478 (diff)
downloadchromium_src-00152e9ffa80198724da8705594cc14c2d7fb5e5.zip
chromium_src-00152e9ffa80198724da8705594cc14c2d7fb5e5.tar.gz
chromium_src-00152e9ffa80198724da8705594cc14c2d7fb5e5.tar.bz2
Add click-to-load functionality for blocked plugins.
BUG=35316 TEST=Disable plugins, go to a site with a flash animation. You should see a placeholder for the flash animation. When you click on it, the animation should load. Review URL: http://codereview.chromium.org/2862031 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@52899 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--chrome/app/generated_resources.grd7
-rw-r--r--chrome/chrome_renderer.gypi2
-rw-r--r--chrome/renderer/blocked_plugin.cc85
-rw-r--r--chrome/renderer/blocked_plugin.h39
-rw-r--r--chrome/renderer/render_view.cc71
-rw-r--r--chrome/renderer/render_view.h12
-rw-r--r--chrome/renderer/renderer_resources.grd1
-rw-r--r--chrome/renderer/resources/blocked_plugin.html57
-rw-r--r--webkit/glue/plugins/webview_plugin.cc142
-rw-r--r--webkit/glue/plugins/webview_plugin.h107
-rw-r--r--webkit/glue/webkit_glue.gypi2
11 files changed, 496 insertions, 29 deletions
diff --git a/chrome/app/generated_resources.grd b/chrome/app/generated_resources.grd
index 2298130..085a381 100644
--- a/chrome/app/generated_resources.grd
+++ b/chrome/app/generated_resources.grd
@@ -3664,7 +3664,7 @@ Keep your key file in a safe place. You will need it to create new versions of y
Chrome Web Store
</message>
- <!-- chrome://plugins page -->
+ <!-- Plugins -->
<message name="IDS_PLUGINS_TITLE" desc="Title for the chrome://plugins page.">
Plug-ins
</message>
@@ -3726,6 +3726,11 @@ Keep your key file in a safe place. You will need it to create new versions of y
Priority:
</message>
+ <!-- Click-to-load -->
+ <message name="IDS_PLUGIN_LOAD" desc="The link for loading a blocked plug-in.">
+ Load plug-in
+ </message>
+
<!-- Session Crashed Info Bar-->
<message name="IDS_SESSION_CRASHED_VIEW_RESTORE_BUTTON" desc="Title of the restore button in the session crashed view.">
Restore
diff --git a/chrome/chrome_renderer.gypi b/chrome/chrome_renderer.gypi
index b0b2532..1f98725 100644
--- a/chrome/chrome_renderer.gypi
+++ b/chrome/chrome_renderer.gypi
@@ -78,6 +78,8 @@
'renderer/about_handler.h',
'renderer/audio_message_filter.cc',
'renderer/audio_message_filter.h',
+ 'renderer/blocked_plugin.cc',
+ 'renderer/blocked_plugin.h',
'renderer/cookie_message_filter.cc',
'renderer/cookie_message_filter.h',
'renderer/devtools_agent.cc',
diff --git a/chrome/renderer/blocked_plugin.cc b/chrome/renderer/blocked_plugin.cc
new file mode 100644
index 0000000..00eae32
--- /dev/null
+++ b/chrome/renderer/blocked_plugin.cc
@@ -0,0 +1,85 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/renderer/blocked_plugin.h"
+
+#include "app/l10n_util.h"
+#include "app/resource_bundle.h"
+#include "base/string_piece.h"
+#include "chrome/common/jstemplate_builder.h"
+#include "chrome/renderer/render_view.h"
+#include "grit/generated_resources.h"
+#include "grit/renderer_resources.h"
+#include "third_party/WebKit/WebKit/chromium/public/WebData.h"
+#include "third_party/WebKit/WebKit/chromium/public/WebFrame.h"
+#include "third_party/WebKit/WebKit/chromium/public/WebPluginContainer.h"
+#include "third_party/WebKit/WebKit/chromium/public/WebURL.h"
+#include "third_party/WebKit/WebKit/chromium/public/WebView.h"
+#include "webkit/glue/plugins/webview_plugin.h"
+
+using WebKit::WebCursorInfo;
+using WebKit::WebFrame;
+using WebKit::WebPlugin;
+using WebKit::WebPluginContainer;
+using WebKit::WebPluginParams;
+using WebKit::WebURL;
+using WebKit::WebView;
+
+static const char* const kBlockedPluginDataURL = "chrome://blockedplugindata/";
+
+BlockedPlugin::BlockedPlugin(RenderView* render_view,
+ WebFrame* frame,
+ const WebPluginParams& params)
+ : render_view_(render_view),
+ frame_(frame),
+ plugin_params_(params) {
+ plugin_ = new WebViewPlugin(this);
+
+ WebView* web_view = plugin_->web_view();
+ web_view->mainFrame()->setCanHaveScrollbars(false);
+
+ int resource_id = IDR_BLOCKED_PLUGIN_HTML;
+ const base::StringPiece template_html(
+ ResourceBundle::GetSharedInstance().GetRawDataResource(resource_id));
+
+ DCHECK(!template_html.empty()) << "unable to load template. ID: "
+ << resource_id;
+
+ DictionaryValue localized_strings;
+ localized_strings.SetString(L"loadPlugin",
+ l10n_util::GetString(IDS_PLUGIN_LOAD));
+
+ // "t" is the id of the templates root node.
+ std::string htmlData = jstemplate_builder::GetTemplatesHtml(
+ template_html, &localized_strings, "t");
+
+ web_view->mainFrame()->loadHTMLString(htmlData,
+ GURL(kBlockedPluginDataURL));
+}
+
+void BlockedPlugin::BindWebFrame(WebFrame* frame) {
+ BindToJavascript(frame, L"plugin");
+ BindMethod("load", &BlockedPlugin::Load);
+}
+
+void BlockedPlugin::WillDestroyPlugin() {
+ delete this;
+}
+
+void BlockedPlugin::Load(const CppArgumentList& args, CppVariant* result) {
+ LoadPlugin();
+}
+
+void BlockedPlugin::LoadPlugin() {
+ CHECK(plugin_);
+ WebPluginContainer* container = plugin_->container();
+ WebPlugin* new_plugin =
+ render_view_->CreatePluginInternal(frame_, plugin_params_);
+ if (new_plugin && new_plugin->initialize(container)) {
+ container->setPlugin(new_plugin);
+ container->invalidate();
+ container->reportGeometry();
+ plugin_->destroy();
+ }
+}
diff --git a/chrome/renderer/blocked_plugin.h b/chrome/renderer/blocked_plugin.h
new file mode 100644
index 0000000..50a8196
--- /dev/null
+++ b/chrome/renderer/blocked_plugin.h
@@ -0,0 +1,39 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_RENDERER_BLOCKED_PLUGIN_H_
+#define CHROME_RENDERER_BLOCKED_PLUGIN_H_
+
+#include "third_party/WebKit/WebKit/chromium/public/WebPluginParams.h"
+#include "webkit/glue/cpp_bound_class.h"
+#include "webkit/glue/plugins/webview_plugin.h"
+
+class RenderView;
+
+class BlockedPlugin : public CppBoundClass,
+ public WebViewPlugin::Delegate {
+ public:
+ BlockedPlugin(RenderView* render_view,
+ WebKit::WebFrame* frame,
+ const WebKit::WebPluginParams& params);
+
+ void Load(const CppArgumentList& args, CppVariant* result);
+ void LoadPlugin();
+
+ WebViewPlugin* plugin() { return plugin_; }
+
+ // WebViewPlugin::Delegate methods:
+ virtual void BindWebFrame(WebKit::WebFrame* frame);
+ virtual void WillDestroyPlugin();
+
+ private:
+ virtual ~BlockedPlugin() { }
+
+ RenderView* render_view_;
+ WebKit::WebFrame* frame_;
+ WebKit::WebPluginParams plugin_params_;
+ WebViewPlugin* plugin_;
+};
+
+#endif // CHROME_RENDERER_BLOCKED_PLUGIN_H_
diff --git a/chrome/renderer/render_view.cc b/chrome/renderer/render_view.cc
index ffba7e6..fcaa65a 100644
--- a/chrome/renderer/render_view.cc
+++ b/chrome/renderer/render_view.cc
@@ -40,6 +40,7 @@
#include "chrome/common/window_container_type.h"
#include "chrome/renderer/about_handler.h"
#include "chrome/renderer/audio_message_filter.h"
+#include "chrome/renderer/blocked_plugin.h"
#include "chrome/renderer/devtools_agent.h"
#include "chrome/renderer/devtools_client.h"
#include "chrome/renderer/extension_groups.h"
@@ -94,6 +95,7 @@
#include "third_party/WebKit/WebKit/chromium/public/WebNodeList.h"
#include "third_party/WebKit/WebKit/chromium/public/WebPageSerializer.h"
#include "third_party/WebKit/WebKit/chromium/public/WebPlugin.h"
+#include "third_party/WebKit/WebKit/chromium/public/WebPluginContainer.h"
#include "third_party/WebKit/WebKit/chromium/public/WebPluginParams.h"
#include "third_party/WebKit/WebKit/chromium/public/WebPluginDocument.h"
#include "third_party/WebKit/WebKit/chromium/public/WebPoint.h"
@@ -102,6 +104,7 @@
#include "third_party/WebKit/WebKit/chromium/public/WebScriptSource.h"
#include "third_party/WebKit/WebKit/chromium/public/WebSearchableFormData.h"
#include "third_party/WebKit/WebKit/chromium/public/WebSecurityOrigin.h"
+#include "third_party/WebKit/WebKit/chromium/public/WebSettings.h"
#include "third_party/WebKit/WebKit/chromium/public/WebSize.h"
#include "third_party/WebKit/WebKit/chromium/public/WebStorageNamespace.h"
#include "third_party/WebKit/WebKit/chromium/public/WebString.h"
@@ -127,6 +130,7 @@
#include "webkit/glue/plugins/webplugin_delegate.h"
#include "webkit/glue/plugins/webplugin_delegate_impl.h"
#include "webkit/glue/plugins/webplugin_impl.h"
+#include "webkit/glue/plugins/webview_plugin.h"
#include "webkit/glue/site_isolation_metrics.h"
#include "webkit/glue/webdropdata.h"
#include "webkit/glue/webkit_glue.h"
@@ -187,6 +191,7 @@ using WebKit::WebNode;
using WebKit::WebPageSerializer;
using WebKit::WebPageSerializerClient;
using WebKit::WebPlugin;
+using WebKit::WebPluginContainer;
using WebKit::WebPluginParams;
using WebKit::WebPluginDocument;
using WebKit::WebPoint;
@@ -2290,28 +2295,13 @@ void RenderView::runModal() {
// WebKit::WebFrameClient -----------------------------------------------------
-WebPlugin* RenderView::createPlugin(
- WebFrame* frame, const WebPluginParams& params) {
- FilePath path;
- std::string actual_mime_type;
- render_thread_->Send(new ViewHostMsg_GetPluginPath(
- params.url, frame->top()->url(), params.mimeType.utf8(), &path,
- &actual_mime_type));
- if (path.value().empty())
- return NULL;
-
- if (actual_mime_type.empty())
- actual_mime_type = params.mimeType.utf8();
+WebPlugin* RenderView::createPlugin(WebFrame* frame,
+ const WebPluginParams& params) {
+ if (AllowContentType(CONTENT_SETTINGS_TYPE_PLUGINS))
+ return CreatePluginInternal(frame, params);
- scoped_refptr<pepper::PluginModule> pepper_module =
- PepperPluginRegistry::GetInstance()->GetModule(path);
- if (pepper_module) {
- return new pepper::WebPluginImpl(pepper_module, params,
- pepper_delegate_.AsWeakPtr());
- }
-
- return new webkit_glue::WebPluginImpl(frame, params, path, actual_mime_type,
- AsWeakPtr());
+ didNotAllowPlugins(frame);
+ return CreatePluginPlaceholder(frame, params);
}
WebWorker* RenderView::createWorker(WebFrame* frame, WebWorkerClient* client) {
@@ -2429,12 +2419,6 @@ void RenderView::willClose(WebFrame* frame) {
form_manager_.ResetFrame(frame);
}
-bool RenderView::allowPlugins(WebFrame* frame, bool enabled_per_settings) {
- if (!enabled_per_settings)
- return false;
- return AllowContentType(CONTENT_SETTINGS_TYPE_PLUGINS);
-}
-
bool RenderView::allowImages(WebFrame* frame, bool enabled_per_settings) {
if (enabled_per_settings &&
AllowContentType(CONTENT_SETTINGS_TYPE_IMAGES))
@@ -3743,6 +3727,39 @@ void RenderView::ClearBlockedContentSettings() {
content_blocked_[i] = false;
}
+WebPlugin* RenderView::CreatePluginInternal(WebFrame* frame,
+ const WebPluginParams& params) {
+ FilePath path;
+ std::string actual_mime_type;
+ render_thread_->Send(new ViewHostMsg_GetPluginPath(
+ params.url, frame->top()->url(), params.mimeType.utf8(), &path,
+ &actual_mime_type));
+ if (path.value().empty())
+ return NULL;
+
+ if (actual_mime_type.empty())
+ actual_mime_type = params.mimeType.utf8();
+
+ scoped_refptr<pepper::PluginModule> pepper_module =
+ PepperPluginRegistry::GetInstance()->GetModule(path);
+ if (pepper_module) {
+ return new pepper::WebPluginImpl(pepper_module, params,
+ pepper_delegate_.AsWeakPtr());
+ }
+
+ return new webkit_glue::WebPluginImpl(frame, params, path, actual_mime_type,
+ AsWeakPtr());
+}
+
+WebPlugin* RenderView::CreatePluginPlaceholder(WebFrame* frame,
+ const WebPluginParams& params) {
+ // |blocked_plugin| will delete itself when the WebViewPlugin is destroyed.
+ BlockedPlugin* blocked_plugin = new BlockedPlugin(this, frame, params);
+ WebViewPlugin* plugin = blocked_plugin->plugin();
+ webkit_preferences_.Apply(plugin->web_view());
+ return plugin;
+}
+
void RenderView::OnZoom(PageZoom::Function function) {
if (!webview()) // Not sure if this can happen, but no harm in being safe.
return;
diff --git a/chrome/renderer/render_view.h b/chrome/renderer/render_view.h
index 25ef1e6..f60669d 100644
--- a/chrome/renderer/render_view.h
+++ b/chrome/renderer/render_view.h
@@ -53,6 +53,7 @@
#include "third_party/WebKit/WebKit/chromium/public/WebMediaPlayerAction.h"
#include "third_party/WebKit/WebKit/chromium/public/WebNode.h"
#include "third_party/WebKit/WebKit/chromium/public/WebPageSerializerClient.h"
+#include "third_party/WebKit/WebKit/chromium/public/WebPluginParams.h"
#include "third_party/WebKit/WebKit/chromium/public/WebTextDirection.h"
#include "third_party/WebKit/WebKit/chromium/public/WebView.h"
#include "third_party/WebKit/WebKit/chromium/public/WebViewClient.h"
@@ -276,6 +277,11 @@ class RenderView : public RenderWidget,
// the plugin.
void OnPepperPluginDestroy(WebPluginDelegatePepper* pepper_plugin);
+ // Create a new plugin without checking the content settings.
+ WebKit::WebPlugin* CreatePluginInternal(
+ WebKit::WebFrame* frame,
+ const WebKit::WebPluginParams& params);
+
// Asks the browser for the CPBrowsingContext associated with this renderer.
// This is an opaque identifier associated with the renderer for sending
// messages for the given "Chrome Plugin." The Chrome Plugin API is used
@@ -430,7 +436,6 @@ class RenderView : public RenderWidget,
WebKit::WebApplicationCacheHostClient* client);
virtual WebKit::WebCookieJar* cookieJar();
virtual void willClose(WebKit::WebFrame* frame);
- virtual bool allowPlugins(WebKit::WebFrame* frame, bool enabled_per_settings);
virtual bool allowImages(WebKit::WebFrame* frame, bool enabled_per_settings);
virtual void loadURLExternally(WebKit::WebFrame* frame,
const WebKit::WebURLRequest& request,
@@ -856,6 +861,11 @@ class RenderView : public RenderWidget,
// UI that is going to be hosted by this RenderView.
void CreateDevToolsClient();
+ // Create a new placeholder for a blocked plugin.
+ WebKit::WebPlugin* CreatePluginPlaceholder(
+ WebKit::WebFrame* frame,
+ const WebKit::WebPluginParams& params);
+
// Sends an IPC notification that the specified content type was blocked.
void DidBlockContentType(ContentSettingsType settings_type);
diff --git a/chrome/renderer/renderer_resources.grd b/chrome/renderer/renderer_resources.grd
index 4b35b1f..295ccac 100644
--- a/chrome/renderer/renderer_resources.grd
+++ b/chrome/renderer/renderer_resources.grd
@@ -12,6 +12,7 @@ without changes to the corresponding grd file. fb9 -->
<release seq="1">
<includes>
<include name="IDR_BASE_JS" file="resources\base.js" type="BINDATA" />
+ <include name="IDR_BLOCKED_PLUGIN_HTML" file="resources\blocked_plugin.html" flattenhtml="true" type="BINDATA" />
<include name="IDR_DOM_AUTOMATION_JS" file="resources\dom_automation.js" type="BINDATA" />
<include name="IDR_ERROR_NO_DETAILS_HTML" file="resources\error_no_details.html" flattenhtml="true" type="BINDATA" />
<include name="IDR_EVENT_BINDINGS_JS" file="resources\event_bindings.js" type="BINDATA" />
diff --git a/chrome/renderer/resources/blocked_plugin.html b/chrome/renderer/resources/blocked_plugin.html
new file mode 100644
index 0000000..bf97d5e
--- /dev/null
+++ b/chrome/renderer/resources/blocked_plugin.html
@@ -0,0 +1,57 @@
+<!DOCTYPE html>
+<html>
+<head>
+<style>
+body {
+ background-color: rgb(252, 235, 162);
+ margin: 0;
+ text-align: center;
+ font-family: sans-serif;
+}
+
+#outer {
+ width: 100%;
+ height: 100%;
+ cursor: pointer;
+ position: absolute;
+}
+
+#inner {
+ position: relative;
+ top: 50%;
+ margin-top: -50px;
+}
+
+#top, #bottom, #left, #right {
+ background: black;
+ position: fixed;
+}
+#left, #right {
+ top: 0; bottom: 0;
+ width: 1px;
+}
+#left { left: 0; }
+#right { right: 0; }
+
+#top, #bottom {
+ left: 0; right: 0;
+ height: 1px;
+}
+#top { top: 0; }
+#bottom { bottom: 0; }
+</style>
+</head>
+
+<body id="t">
+<div id="outer" onclick="plugin.load()">
+<div id="left"></div>
+<div id="right"></div>
+<div id="top"></div>
+<div id="bottom"></div>
+<div id="inner">
+<div><img src="../../app/theme/extensions_section.png" /></div>
+<p i18n-content="loadPlugin">LOAD_PLUGIN</p>
+</div>
+</div>
+</body>
+</html>
diff --git a/webkit/glue/plugins/webview_plugin.cc b/webkit/glue/plugins/webview_plugin.cc
new file mode 100644
index 0000000..413ae10
--- /dev/null
+++ b/webkit/glue/plugins/webview_plugin.cc
@@ -0,0 +1,142 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "webkit/glue/plugins/webview_plugin.h"
+
+#include "base/message_loop.h"
+#include "third_party/WebKit/WebKit/chromium/public/WebCursorInfo.h"
+#include "third_party/WebKit/WebKit/chromium/public/WebFrame.h"
+#include "third_party/WebKit/WebKit/chromium/public/WebPluginContainer.h"
+#include "third_party/WebKit/WebKit/chromium/public/WebSettings.h"
+#include "third_party/WebKit/WebKit/chromium/public/WebSize.h"
+#include "third_party/WebKit/WebKit/chromium/public/WebURL.h"
+#include "third_party/WebKit/WebKit/chromium/public/WebURLRequest.h"
+#include "third_party/WebKit/WebKit/chromium/public/WebView.h"
+
+#if WEBKIT_USING_CG
+#include <CoreGraphics/CGContext.h>
+#elif WEBKIT_USING_SKIA
+#include "skia/ext/platform_canvas.h"
+#endif
+
+using WebKit::WebCanvas;
+using WebKit::WebCursorInfo;
+using WebKit::WebDragData;
+using WebKit::WebDragOperationsMask;
+using WebKit::WebFrame;
+using WebKit::WebImage;
+using WebKit::WebInputEvent;
+using WebKit::WebPluginContainer;
+using WebKit::WebPoint;
+using WebKit::WebRect;
+using WebKit::WebSize;
+using WebKit::WebURLError;
+using WebKit::WebURLRequest;
+using WebKit::WebVector;
+using WebKit::WebView;
+
+WebViewPlugin::WebViewPlugin(WebViewPlugin::Delegate* delegate)
+ : delegate_(delegate),
+ container_(NULL) {
+ web_view_ = WebView::create(this, NULL);
+ web_view_->initializeMainFrame(this);
+}
+
+WebViewPlugin::~WebViewPlugin() {
+ web_view_->close();
+}
+
+bool WebViewPlugin::initialize(WebPluginContainer* container) {
+ container_ = container;
+ return true;
+}
+
+void WebViewPlugin::destroy() {
+ delegate_->WillDestroyPlugin();
+ delegate_ = NULL;
+ MessageLoop::current()->DeleteSoon(FROM_HERE, this);
+}
+
+void WebViewPlugin::paint(WebCanvas* canvas, const WebRect& rect) {
+ gfx::Rect paintRect(rect_.Intersect(rect));
+ if (paintRect.IsEmpty())
+ return;
+
+ paintRect.Offset(-rect_.x(), -rect_.y());
+
+#if WEBKIT_USING_CG
+ CGContextRef context = canvas;
+ CGContextTranslateCTM(context, rect_.x(), rect_.y());
+ CGContextSaveGState(context);
+#elif WEBKIT_USING_SKIA
+ skia::PlatformCanvas* platform_canvas = canvas;
+ platform_canvas->translate(SkIntToScalar(rect_.x()),
+ SkIntToScalar(rect_.y()));
+ platform_canvas->save();
+#endif
+
+ web_view_->layout();
+ web_view_->paint(canvas, paintRect);
+
+#if WEBKIT_USING_SKIA
+ platform_canvas->restore();
+#elif WEBKIT_USING_CG
+ CGContextRestoreGState(context);
+#endif
+}
+
+// Coordinates are relative to the containing window.
+void WebViewPlugin::updateGeometry(
+ const WebRect& frame_rect, const WebRect& clip_rect,
+ const WebVector<WebRect>& cut_out_rects, bool is_visible) {
+ if (frame_rect != rect_) {
+ rect_ = frame_rect;
+ web_view_->resize(WebSize(frame_rect.width, frame_rect.height));
+ }
+}
+
+bool WebViewPlugin::handleInputEvent(const WebInputEvent& event,
+ WebCursorInfo& cursor) {
+ current_cursor_ = cursor;
+ bool handled = web_view_->handleInputEvent(event);
+ cursor = current_cursor_;
+ return handled;
+}
+
+void WebViewPlugin::startDragging(const WebDragData&,
+ WebDragOperationsMask,
+ const WebImage&,
+ const WebPoint&) {
+ // Immediately stop dragging.
+ web_view_->dragSourceSystemDragEnded();
+}
+
+void WebViewPlugin::didInvalidateRect(const WebRect& rect) {
+ if (container_)
+ container_->invalidateRect(WebRect(rect));
+}
+
+void WebViewPlugin::didChangeCursor(const WebCursorInfo& cursor) {
+ current_cursor_ = cursor;
+}
+
+void WebViewPlugin::didClearWindowObject(WebFrame* frame) {
+ delegate_->BindWebFrame(frame);
+}
+
+bool WebViewPlugin::canHandleRequest(WebFrame* frame,
+ const WebURLRequest& request) {
+ return GURL(request.url()).SchemeIs("chrome");
+}
+
+WebURLError WebViewPlugin::cancelledError(WebFrame* frame,
+ const WebURLRequest& request) {
+ // Return an error with a non-zero reason so isNull() on the corresponding
+ // ResourceError is false.
+ WebURLError error;
+ error.domain = "WebViewPlugin";
+ error.reason = -1;
+ error.unreachableURL = request.url();
+ return error;
+}
diff --git a/webkit/glue/plugins/webview_plugin.h b/webkit/glue/plugins/webview_plugin.h
new file mode 100644
index 0000000..2e41218
--- /dev/null
+++ b/webkit/glue/plugins/webview_plugin.h
@@ -0,0 +1,107 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef WEBKIT_GLUE_PLUGINS_WEBVIEW_PLUGIN_H_
+#define WEBKIT_GLUE_PLUGINS_WEBVIEW_PLUGIN_H_
+
+#include "base/scoped_ptr.h"
+#include "base/task.h"
+#include "third_party/WebKit/WebKit/chromium/public/WebCursorInfo.h"
+#include "third_party/WebKit/WebKit/chromium/public/WebPlugin.h"
+#include "third_party/WebKit/WebKit/chromium/public/WebFrameClient.h"
+#include "third_party/WebKit/WebKit/chromium/public/WebViewClient.h"
+
+// This class implements the WebPlugin interface by forwarding drawing and
+// handling input events to a WebView.
+// It can be used as a placeholder for an actual plugin, using HTML for the UI.
+// To show HTML data inside the WebViewPlugin,
+// call web_view->mainFrame()->loadHTMLString() with the HTML data and a fake
+// chrome:// URL as origin.
+
+class WebViewPlugin: public WebKit::WebPlugin, public WebKit::WebViewClient,
+ public WebKit::WebFrameClient {
+ public:
+ class Delegate {
+ public:
+ // Bind |frame| to a Javascript object, enabling the delegate to receive
+ // callback methods from Javascript inside the WebFrame.
+ // This method is called from WebFrameClient::didClearWindowObject.
+ virtual void BindWebFrame(WebKit::WebFrame* frame) = 0;
+
+ // Called before the WebViewPlugin is destroyed. The delegate should delete
+ // itself here.
+ virtual void WillDestroyPlugin() = 0;
+ };
+
+ explicit WebViewPlugin(Delegate* delegate);
+
+ virtual WebKit::WebView* web_view() { return web_view_; }
+
+ virtual WebKit::WebPluginContainer* container() { return container_; }
+
+ // WebPlugin methods:
+ virtual bool initialize(WebKit::WebPluginContainer*);
+ virtual void destroy();
+
+ virtual NPObject* scriptableObject() { return NULL; }
+
+ virtual void paint(WebKit::WebCanvas* canvas, const WebKit::WebRect& rect);
+
+ // Coordinates are relative to the containing window.
+ virtual void updateGeometry(
+ const WebKit::WebRect& frame_rect, const WebKit::WebRect& clip_rect,
+ const WebKit::WebVector<WebKit::WebRect>& cut_out_rects, bool is_visible);
+
+ virtual void updateFocus(bool) { }
+ virtual void updateVisibility(bool) { }
+
+ virtual bool acceptsInputEvents() { return true; }
+ virtual bool handleInputEvent(const WebKit::WebInputEvent& event,
+ WebKit::WebCursorInfo& cursor_info);
+
+ virtual void didReceiveResponse(const WebKit::WebURLResponse& response) { }
+ virtual void didReceiveData(const char* data, int data_length) { }
+ virtual void didFinishLoading() { }
+ virtual void didFailLoading(const WebKit::WebURLError& error) { }
+
+ // Called in response to WebPluginContainer::loadFrameRequest
+ virtual void didFinishLoadingFrameRequest(
+ const WebKit::WebURL& url, void* notifyData) { }
+ virtual void didFailLoadingFrameRequest(const WebKit::WebURL& url,
+ void* notify_data,
+ const WebKit::WebURLError& error) { }
+
+ // WebViewClient methods:
+ virtual bool acceptsLoadDrops() { return false; }
+
+ virtual void startDragging(const WebKit::WebDragData& drag_data,
+ WebKit::WebDragOperationsMask mask,
+ const WebKit::WebImage& image,
+ const WebKit::WebPoint& point);
+
+ // WebWidgetClient methods:
+ virtual void didInvalidateRect(const WebKit::WebRect&);
+ virtual void didChangeCursor(const WebKit::WebCursorInfo& cursor);
+
+ // WebFrameClient methods:
+ virtual void didClearWindowObject(WebKit::WebFrame* frame);
+
+ virtual bool canHandleRequest(WebKit::WebFrame* frame,
+ const WebKit::WebURLRequest& request);
+
+ virtual WebKit::WebURLError cancelledError(
+ WebKit::WebFrame* frame, const WebKit::WebURLRequest& request);
+
+ private:
+ friend class DeleteTask<WebViewPlugin>;
+ virtual ~WebViewPlugin();
+
+ Delegate* delegate_;
+ WebKit::WebCursorInfo current_cursor_;
+ WebKit::WebPluginContainer* container_;
+ WebKit::WebView* web_view_;
+ gfx::Rect rect_;
+};
+
+#endif // WEBKIT_GLUE_PLUGINS_WEBVIEW_PLUGIN_H_
diff --git a/webkit/glue/webkit_glue.gypi b/webkit/glue/webkit_glue.gypi
index 72927bf..49320fc 100644
--- a/webkit/glue/webkit_glue.gypi
+++ b/webkit/glue/webkit_glue.gypi
@@ -241,6 +241,8 @@
'plugins/ppb_private.h',
'plugins/quickdraw_drawing_manager_mac.h',
'plugins/quickdraw_drawing_manager_mac.cc',
+ 'plugins/webview_plugin.cc',
+ 'plugins/webview_plugin.h',
'plugins/webplugin.cc',
'plugins/webplugin.h',
'plugins/webplugin_2d_device_delegate.h',