diff options
author | bauerb@chromium.org <bauerb@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-07-19 11:47:40 +0000 |
---|---|---|
committer | bauerb@chromium.org <bauerb@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-07-19 11:47:40 +0000 |
commit | 00152e9ffa80198724da8705594cc14c2d7fb5e5 (patch) | |
tree | 7750ebd07097e1b0b3620e53f0730dbdbf7775bf | |
parent | bf89db9145b20cafdb4e044a023d95ebfec21478 (diff) | |
download | chromium_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.grd | 7 | ||||
-rw-r--r-- | chrome/chrome_renderer.gypi | 2 | ||||
-rw-r--r-- | chrome/renderer/blocked_plugin.cc | 85 | ||||
-rw-r--r-- | chrome/renderer/blocked_plugin.h | 39 | ||||
-rw-r--r-- | chrome/renderer/render_view.cc | 71 | ||||
-rw-r--r-- | chrome/renderer/render_view.h | 12 | ||||
-rw-r--r-- | chrome/renderer/renderer_resources.grd | 1 | ||||
-rw-r--r-- | chrome/renderer/resources/blocked_plugin.html | 57 | ||||
-rw-r--r-- | webkit/glue/plugins/webview_plugin.cc | 142 | ||||
-rw-r--r-- | webkit/glue/plugins/webview_plugin.h | 107 | ||||
-rw-r--r-- | webkit/glue/webkit_glue.gypi | 2 |
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', |