Index: webkit/glue/webplugin_impl.cc |
=================================================================== |
--- webkit/glue/webplugin_impl.cc (revision 25087) |
+++ webkit/glue/webplugin_impl.cc (working copy) |
@@ -1,58 +1,45 @@ |
-// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. |
+// Copyright (c) 2006-2009 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 "config.h" |
- |
-#include "Document.h" |
-#include "DocumentLoader.h" |
-#include "FormState.h" |
-#include "Frame.h" |
-#include "FrameLoader.h" |
-#include "FrameLoadRequest.h" |
-#include "HTMLFormElement.h" |
-#include "KURL.h" |
-#include "PlatformString.h" |
-#include "ResourceResponse.h" |
-#include "ScriptController.h" |
-#include "ScriptValue.h" |
-#include "Widget.h" |
- |
-#undef LOG |
#include "base/gfx/rect.h" |
#include "base/logging.h" |
#include "base/message_loop.h" |
#include "base/string_util.h" |
#include "net/base/escape.h" |
+#include "skia/ext/platform_canvas.h" |
+#if defined(OS_WIN) |
+#include "webkit/activex_shim/activex_shared.h" |
+#endif |
#include "webkit/api/public/WebConsoleMessage.h" |
+#include "webkit/api/public/WebCString.h" |
#include "webkit/api/public/WebCursorInfo.h" |
#include "webkit/api/public/WebData.h" |
+#include "webkit/api/public/WebFrame.h" |
#include "webkit/api/public/WebHTTPBody.h" |
#include "webkit/api/public/WebHTTPHeaderVisitor.h" |
#include "webkit/api/public/WebInputEvent.h" |
#include "webkit/api/public/WebKit.h" |
#include "webkit/api/public/WebKitClient.h" |
+#include "webkit/api/public/WebPluginContainer.h" |
+#include "webkit/api/public/WebPluginParams.h" |
#include "webkit/api/public/WebRect.h" |
-#include "webkit/api/public/WebString.h" |
#include "webkit/api/public/WebURL.h" |
#include "webkit/api/public/WebURLLoader.h" |
#include "webkit/api/public/WebURLLoaderClient.h" |
#include "webkit/api/public/WebURLResponse.h" |
-#include "webkit/api/public/WebVector.h" |
-#include "webkit/api/src/WebPluginContainerImpl.h" |
-#include "webkit/glue/chrome_client_impl.h" |
-#include "webkit/glue/glue_util.h" |
#include "webkit/glue/multipart_response_delegate.h" |
-#include "webkit/glue/webkit_glue.h" |
#include "webkit/glue/webplugin_impl.h" |
#include "webkit/glue/plugins/plugin_host.h" |
#include "webkit/glue/plugins/plugin_instance.h" |
#include "webkit/glue/webplugin_delegate.h" |
-#include "webkit/glue/webview_impl.h" |
+#include "webkit/glue/webplugin_page_delegate.h" |
+#include "webkit/glue/webview.h" |
#include "googleurl/src/gurl.h" |
using WebKit::WebCanvas; |
using WebKit::WebConsoleMessage; |
+using WebKit::WebCString; |
using WebKit::WebCursorInfo; |
using WebKit::WebData; |
using WebKit::WebDataSource; |
@@ -63,7 +50,7 @@ |
using WebKit::WebKeyboardEvent; |
using WebKit::WebMouseEvent; |
using WebKit::WebPluginContainer; |
-using WebKit::WebPluginContainerImpl; |
+using WebKit::WebPluginParams; |
using WebKit::WebRect; |
using WebKit::WebString; |
using WebKit::WebURL; |
@@ -75,6 +62,7 @@ |
using WebKit::WebVector; |
using webkit_glue::MultipartResponseDelegate; |
+namespace webkit_glue { |
namespace { |
// This class handles individual multipart responses. It is instantiated when |
@@ -209,61 +197,88 @@ |
} |
} |
+// Utility function to convert a vector to an array of char*'s. |
+// Caller is responsible to free memory with DeleteArray(). |
+static char** ToArray(const WebVector<WebString>& input) { |
+ char** array = new char*[input.size() + 1]; |
+ size_t index; |
+ for (index = 0; index < input.size(); ++index) { |
+ const WebCString& src = input[index].utf8(); |
+ array[index] = new char[src.length() + 1]; |
+ base::strlcpy(array[index], src.data(), src.length() + 1); |
+ array[index][src.length()] = '\0'; |
+ } |
+ array[index] = 0; |
+ return array; |
+} |
+ |
+static void DeleteArray(char** array) { |
+ char** ptr = array; |
+ while (*ptr) { |
+ delete[] *ptr; |
+ ++ptr; |
+ } |
+ delete[] array; |
+} |
+ |
} // namespace |
-PassRefPtr<WebCore::Widget> WebPluginImpl::Create( |
- const GURL& url, |
- char** argn, |
- char** argv, |
- int argc, |
- WebCore::HTMLPlugInElement* element, |
- WebFrameImpl* frame, |
- WebPluginDelegate* delegate, |
- bool load_manually, |
- const std::string& mime_type) { |
- // NOTE: frame contains element |
+// WebKit::WebPlugin ---------------------------------------------------------- |
- WebPluginImpl* webplugin = new WebPluginImpl( |
- frame, delegate, url, load_manually, mime_type, argc, argn, argv); |
+bool WebPluginImpl::initialize(WebPluginContainer* container) { |
+ if (!page_delegate_) |
+ return false; |
- if (!delegate->Initialize(url, argn, argv, argc, webplugin, load_manually)) { |
- delegate->PluginDestroyed(); |
- delete webplugin; |
- return NULL; |
+ // Get the classid and version from attributes of the object. |
+ std::string combined_clsid; |
+#if defined(OS_WIN) |
+ std::string clsid, version; |
+ if (activex_shim::IsMimeTypeActiveX(mime_type_)) { |
+ for (size_t i = 0; i < arg_count_; i++) { |
+ const char* param_name = arg_names_[i]; |
+ const char* param_value = arg_values_[i]; |
+ if (base::strcasecmp(param_name, "classid") == 0) { |
+ activex_shim::GetClsidFromClassidAttribute(param_value, &clsid); |
+ } else if (base::strcasecmp(param_name, "codebase") == 0) { |
+ version = activex_shim::GetVersionFromCodebaseAttribute(param_value); |
+ } |
+ } |
+ |
+ // Attempt to map this clsid to a known NPAPI mime type if possible, failing |
+ // which we attempt to load the activex shim for the clsid. |
+ if (!activex_shim::GetMimeTypeForClsid(clsid, &mime_type_)) { |
+ // We need to pass the combined clsid + version to PluginsList, so that it |
+ // would detect if the requested version is installed. If not, it needs |
+ // to use the default plugin to update the control. |
+ if (!version.empty()) |
+ combined_clsid = clsid + "#" + version; |
+ else |
+ combined_clsid = clsid; |
+ } |
} |
+#endif |
- PassRefPtr<WebPluginContainerImpl> container = |
- WebPluginContainerImpl::create(element, webplugin); |
- webplugin->SetContainer(container.get()); |
- return container; |
-} |
+ std::string actual_mime_type; |
+ WebPluginDelegate* plugin_delegate = page_delegate_->CreatePluginDelegate( |
+ plugin_url_, mime_type_, combined_clsid, &actual_mime_type); |
+ if (!plugin_delegate) |
+ return NULL; |
-WebPluginImpl::WebPluginImpl(WebFrameImpl* webframe, |
- WebPluginDelegate* delegate, |
- const GURL& plugin_url, |
- bool load_manually, |
- const std::string& mime_type, |
- int arg_count, |
- char** arg_names, |
- char** arg_values) |
- : windowless_(false), |
- window_(NULL), |
- webframe_(webframe), |
- delegate_(delegate), |
- container_(NULL), |
- plugin_url_(plugin_url), |
- load_manually_(load_manually), |
- first_geometry_update_(true), |
- ignore_response_error_(false), |
- mime_type_(mime_type), |
- ALLOW_THIS_IN_INITIALIZER_LIST(method_factory_(this)) { |
+ bool ok = plugin_delegate->Initialize( |
+ plugin_url_, arg_names_, arg_values_, arg_count_, this, load_manually_); |
+ if (!ok) { |
+ plugin_delegate->PluginDestroyed(); |
+ return false; |
+ } |
- ArrayToVector(arg_count, arg_names, &arg_names_); |
- ArrayToVector(arg_count, arg_values, &arg_values_); |
+ if (!actual_mime_type.empty()) |
+ mime_type_ = actual_mime_type; |
+ delegate_ = plugin_delegate; |
+ |
+ SetContainer(container); |
+ return true; |
} |
-// WebKit::WebPlugin ----------------------------------------------------------- |
- |
void WebPluginImpl::destroy() { |
SetContainer(NULL); |
MessageLoop::current()->DeleteSoon(FROM_HERE, this); |
@@ -291,23 +306,20 @@ |
void WebPluginImpl::updateGeometry( |
const WebRect& window_rect, const WebRect& clip_rect, |
const WebVector<WebRect>& cutout_rects, bool is_visible) { |
- if (window_) { |
- WebViewDelegate* view_delegate = GetWebViewDelegate(); |
- if (view_delegate) { |
- // Notify the window hosting the plugin (the WebViewDelegate) that |
- // it needs to adjust the plugin, so that all the HWNDs can be moved |
- // at the same time. |
- WebPluginGeometry move; |
- move.window = window_; |
- move.window_rect = window_rect; |
- move.clip_rect = clip_rect; |
- for (size_t i = 0; i < cutout_rects.size(); ++i) |
- move.cutout_rects.push_back(cutout_rects[i]); |
- move.rects_valid = true; |
- move.visible = is_visible; |
+ if (window_ && page_delegate_) { |
+ // Notify the window hosting the plugin (the WebViewDelegate) that |
+ // it needs to adjust the plugin, so that all the HWNDs can be moved |
+ // at the same time. |
+ WebPluginGeometry move; |
+ move.window = window_; |
+ move.window_rect = window_rect; |
+ move.clip_rect = clip_rect; |
+ for (size_t i = 0; i < cutout_rects.size(); ++i) |
+ move.cutout_rects.push_back(cutout_rects[i]); |
+ move.rects_valid = true; |
+ move.visible = is_visible; |
- view_delegate->DidMovePlugin(move); |
- } |
+ page_delegate_->DidMovePlugin(move); |
} |
if (first_geometry_update_ || window_rect != window_rect_ || |
@@ -343,13 +355,9 @@ |
} |
void WebPluginImpl::updateVisibility(bool visible) { |
- if (!window_) |
+ if (!window_ || !page_delegate_) |
return; |
- WebViewDelegate* view_delegate = GetWebViewDelegate(); |
- if (!view_delegate) |
- return; |
- |
WebPluginGeometry move; |
move.window = window_; |
move.window_rect = gfx::Rect(); |
@@ -357,7 +365,7 @@ |
move.rects_valid = false; |
move.visible = visible; |
- view_delegate->DidMovePlugin(move); |
+ page_delegate_->DidMovePlugin(move); |
} |
bool WebPluginImpl::acceptsInputEvents() { |
@@ -415,19 +423,43 @@ |
// ----------------------------------------------------------------------------- |
+WebPluginImpl::WebPluginImpl( |
+ WebFrame* webframe, const WebPluginParams& params, |
+ const base::WeakPtr<WebPluginPageDelegate>& page_delegate) |
+ : windowless_(false), |
+ window_(NULL), |
+ page_delegate_(page_delegate), |
+ webframe_(webframe), |
+ delegate_(NULL), |
+ container_(NULL), |
+ plugin_url_(params.url), |
+ load_manually_(params.loadManually), |
+ first_geometry_update_(true), |
+ ignore_response_error_(false), |
+ mime_type_(params.mimeType.utf8()), |
+ arg_names_(ToArray(params.attributeNames)), |
+ arg_values_(ToArray(params.attributeValues)), |
+ arg_count_(params.attributeNames.size()), |
+ ALLOW_THIS_IN_INITIALIZER_LIST(method_factory_(this)) { |
+ DCHECK_EQ(params.attributeNames.size(), params.attributeValues.size()); |
+ StringToLowerASCII(&mime_type_); |
+} |
+ |
WebPluginImpl::~WebPluginImpl() { |
+ if (arg_names_) |
+ DeleteArray(arg_names_); |
+ if (arg_values_) |
+ DeleteArray(arg_values_); |
} |
- |
void WebPluginImpl::SetWindow(gfx::PluginWindowHandle window) { |
if (window) { |
DCHECK(!windowless_); // Make sure not called twice. |
window_ = window; |
- WebViewDelegate* view_delegate = GetWebViewDelegate(); |
- if (view_delegate) { |
+ if (page_delegate_) { |
// Tell the view delegate that the plugin window was created, so that it |
// can create necessary container widgets. |
- view_delegate->CreatedPluginWindow(window); |
+ page_delegate_->CreatedPluginWindow(window); |
} |
} else { |
DCHECK(!window_); // Make sure not called twice. |
@@ -438,10 +470,8 @@ |
void WebPluginImpl::WillDestroyWindow(gfx::PluginWindowHandle window) { |
DCHECK_EQ(window, window_); |
window_ = NULL; |
- WebViewDelegate* view_delegate = GetWebViewDelegate(); |
- if (!view_delegate) |
- return; |
- view_delegate->WillDestroyPluginWindow(window); |
+ if (page_delegate_) |
+ page_delegate_->WillDestroyPluginWindow(window); |
} |
GURL WebPluginImpl::CompleteURL(const char* url) { |
@@ -475,8 +505,8 @@ |
bool rv = NPAPI::PluginHost::SetPostData(buf, length, &names, &values, &body); |
for (size_t i = 0; i < names.size(); ++i) { |
- request->addHTTPHeaderField(webkit_glue::StdStringToWebString(names[i]), |
- webkit_glue::StdStringToWebString(values[i])); |
+ request->addHTTPHeaderField(WebString::fromUTF8(names[i]), |
+ WebString::fromUTF8(values[i])); |
} |
WebString content_type_header = WebString::fromUTF8("Content-Type"); |
@@ -498,13 +528,16 @@ |
return rv; |
} |
-RoutingStatus WebPluginImpl::RouteToFrame(const char *method, |
- bool is_javascript_url, |
- const char* target, unsigned int len, |
- const char* buf, bool is_file_data, |
- bool notify_needed, |
- intptr_t notify_data, |
- const char* url, GURL* unused) { |
+WebPluginImpl::RoutingStatus WebPluginImpl::RouteToFrame( |
+ const char *method, |
+ bool is_javascript_url, |
+ const char* target, |
+ unsigned int len, |
+ const char* buf, |
+ bool is_file_data, |
+ bool notify_needed, |
+ intptr_t notify_data, |
+ const char* url) { |
// If there is no target, there is nothing to do |
if (!target) |
return NOT_ROUTED; |
@@ -594,10 +627,9 @@ |
void WebPluginImpl::ShowModalHTMLDialog(const GURL& url, int width, int height, |
const std::string& json_arguments, |
std::string* json_retval) { |
- WebViewDelegate* view_delegate = GetWebViewDelegate(); |
- if (view_delegate) { |
- view_delegate->ShowModalHTMLDialog( |
- url, width, height, json_arguments, json_retval); |
+ if (page_delegate_) { |
+ page_delegate_->ShowModalHTMLDialogForPlugin( |
+ url, gfx::Size(width, height), json_arguments, json_retval); |
} |
} |
@@ -767,9 +799,8 @@ |
if (index != multi_part_response_map_.end()) { |
delete (*index).second; |
multi_part_response_map_.erase(index); |
- |
- WebView* webview = webframe_->GetWebViewImpl(); |
- webview->GetDelegate()->DidStopLoading(webview); |
+ if (page_delegate_) |
+ page_delegate_->DidStopLoadingForPlugin(); |
} |
loader->setDefersLoading(true); |
WebPluginResourceClient* resource_client = client_info->client; |
@@ -807,9 +838,8 @@ |
} |
void WebPluginImpl::SetContainer(WebPluginContainer* container) { |
- if (container == NULL) { |
+ if (!container) |
TearDownPluginInstance(NULL); |
- } |
container_ = container; |
} |
@@ -836,10 +866,9 @@ |
// case in that the request is a javascript url and the target is "_self", |
// in which case we route the output to the plugin rather than routing it |
// to the plugin's frame. |
- GURL complete_url; |
- int routing_status = RouteToFrame(method, is_javascript_url, target, len, |
- buf, is_file_data, notify, notify_data, |
- url, &complete_url); |
+ RoutingStatus routing_status = |
+ RouteToFrame(method, is_javascript_url, target, len, buf, is_file_data, |
+ notify, notify_data, url); |
if (routing_status == ROUTED) |
return; |
@@ -931,9 +960,9 @@ |
} |
void WebPluginImpl::CancelDocumentLoad() { |
- if (frame()->loader()->activeDocumentLoader()) { |
+ if (webframe_) { |
ignore_response_error_ = true; |
- frame()->loader()->activeDocumentLoader()->stopLoading(); |
+ webframe_->stopLoading(); |
} |
} |
@@ -988,8 +1017,8 @@ |
return; |
} |
- WebView* webview = webframe_->GetWebViewImpl(); |
- webview->GetDelegate()->DidStartLoading(webview); |
+ if (page_delegate_) |
+ page_delegate_->DidStartLoadingForPlugin(); |
MultiPartResponseClient* multi_part_response_client = |
new MultiPartResponseClient(client); |
@@ -1003,11 +1032,11 @@ |
bool WebPluginImpl::ReinitializePluginForResponse( |
WebURLLoader* loader) { |
- WebFrameImpl* webframe = webframe_; |
+ WebFrame* webframe = webframe_; |
if (!webframe) |
return false; |
- WebViewImpl* webview = webframe->GetWebViewImpl(); |
+ WebView* webview = webframe->view(); |
if (!webview) |
return false; |
@@ -1019,28 +1048,14 @@ |
container_ = container_widget; |
webframe_ = webframe; |
- WebViewDelegate* webview_delegate = webview->GetDelegate(); |
std::string actual_mime_type; |
- WebPluginDelegate* plugin_delegate = |
- webview_delegate->CreatePluginDelegate(webview, plugin_url_, |
- mime_type_, std::string(), |
- &actual_mime_type); |
+ WebPluginDelegate* plugin_delegate = page_delegate_->CreatePluginDelegate( |
+ plugin_url_, mime_type_, std::string(), &actual_mime_type); |
- char** arg_names = new char*[arg_names_.size()]; |
- char** arg_values = new char*[arg_values_.size()]; |
+ bool ok = plugin_delegate->Initialize( |
+ plugin_url_, arg_names_, arg_values_, arg_count_, this, load_manually_); |
- for (unsigned int index = 0; index < arg_names_.size(); ++index) { |
- arg_names[index] = const_cast<char*>(arg_names_[index].c_str()); |
- arg_values[index] = const_cast<char*>(arg_values_[index].c_str()); |
- } |
- |
- bool init_ok = plugin_delegate->Initialize(plugin_url_, arg_names, |
- arg_values, arg_names_.size(), |
- this, load_manually_); |
- delete[] arg_names; |
- delete[] arg_values; |
- |
- if (!init_ok) { |
+ if (!ok) { |
container_ = NULL; |
// TODO(iyengar) Should we delete the current plugin instance here? |
return false; |
@@ -1050,8 +1065,9 @@ |
delegate_ = plugin_delegate; |
// Force a geometry update to occur to ensure that the plugin becomes |
- // visible. TODO(darin): Avoid this cast! |
- static_cast<WebPluginContainerImpl*>(container_)->frameRectsChanged(); |
+ // visible. |
+ container_->reportGeometry(); |
+ |
// The plugin move sequences accumulated via DidMove are sent to the browser |
// whenever the renderer paints. Force a paint here to ensure that changes |
// to the plugin window are propagated to the browser. |
@@ -1059,25 +1075,13 @@ |
return true; |
} |
-void WebPluginImpl::ArrayToVector(int total_values, char** values, |
- std::vector<std::string>* value_vector) { |
- DCHECK(value_vector != NULL); |
- for (int index = 0; index < total_values; ++index) { |
- value_vector->push_back(values[index]); |
- } |
-} |
- |
void WebPluginImpl::TearDownPluginInstance( |
WebURLLoader* loader_to_ignore) { |
- // The frame maintains a list of JSObjects which are related to this |
- // plugin. Tell the frame we're gone so that it can invalidate all |
- // of those sub JSObjects. |
- if (frame()) { |
- ASSERT(container_); |
- // TODO(darin): Avoid this cast! |
- frame()->script()->cleanupScriptObjectsForPlugin( |
- static_cast<WebKit::WebPluginContainerImpl*>(container_)); |
- } |
+ // The container maintains a list of JSObjects which are related to this |
+ // plugin. Tell the frame we're gone so that it can invalidate all of |
+ // those sub JSObjects. |
+ if (container_) |
+ container_->clearScriptObjects(); |
if (delegate_) { |
// Call PluginDestroyed() first to prevent the plugin from calling us back |
@@ -1109,9 +1113,4 @@ |
method_factory_.RevokeAll(); |
} |
-WebViewDelegate* WebPluginImpl::GetWebViewDelegate() { |
- if (!webframe_) |
- return NULL; |
- WebViewImpl* webview = webframe_->GetWebViewImpl(); |
- return webview ? webview->delegate() : NULL; |
-} |
+} // namespace webkit_glue |