summaryrefslogtreecommitdiffstats
path: root/chrome/renderer
diff options
context:
space:
mode:
authorbauerb@chromium.org <bauerb@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-11-25 13:14:15 +0000
committerbauerb@chromium.org <bauerb@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-11-25 13:14:15 +0000
commitf5478b310ce3590b5555321cef0574f50d81bb1d (patch)
treec31f531ee6ceaee4485cf19e806a2d672d8cf3c6 /chrome/renderer
parent8ba31633bccd99b21ede99797d77933c673fe136 (diff)
downloadchromium_src-f5478b310ce3590b5555321cef0574f50d81bb1d.zip
chromium_src-f5478b310ce3590b5555321cef0574f50d81bb1d.tar.gz
chromium_src-f5478b310ce3590b5555321cef0574f50d81bb1d.tar.bz2
Clean up plug-in placeholders:
* Add separate class for missing plug-in placeholder, and factor out a common base class * Move plug-in related classes to plugins/ subdirectory * Move custom menu command IDs to a separate header file. TBR=darin@chromium.org BUG=62079 TEST=none Review URL: http://codereview.chromium.org/8461011 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@111589 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/renderer')
-rw-r--r--chrome/renderer/chrome_content_renderer_client.cc76
-rw-r--r--chrome/renderer/chrome_content_renderer_client.h11
-rw-r--r--chrome/renderer/custom_menu_commands.h18
-rw-r--r--chrome/renderer/plugins/blocked_plugin.cc (renamed from chrome/renderer/blocked_plugin.cc)186
-rw-r--r--chrome/renderer/plugins/blocked_plugin.h (renamed from chrome/renderer/blocked_plugin.h)49
-rw-r--r--chrome/renderer/plugins/missing_plugin.cc124
-rw-r--r--chrome/renderer/plugins/missing_plugin.h41
-rw-r--r--chrome/renderer/plugins/plugin_placeholder.cc126
-rw-r--r--chrome/renderer/plugins/plugin_placeholder.h56
-rw-r--r--chrome/renderer/plugins/plugin_uma.cc (renamed from chrome/renderer/plugin_uma.cc)2
-rw-r--r--chrome/renderer/plugins/plugin_uma.h (renamed from chrome/renderer/plugin_uma.h)6
-rw-r--r--chrome/renderer/plugins/plugin_uma_unittest.cc (renamed from chrome/renderer/plugin_uma_unittest.cc)2
12 files changed, 478 insertions, 219 deletions
diff --git a/chrome/renderer/chrome_content_renderer_client.cc b/chrome/renderer/chrome_content_renderer_client.cc
index 73c5543..d238d28 100644
--- a/chrome/renderer/chrome_content_renderer_client.cc
+++ b/chrome/renderer/chrome_content_renderer_client.cc
@@ -28,7 +28,6 @@
#include "chrome/renderer/autofill/password_autofill_manager.h"
#include "chrome/renderer/automation/automation_renderer_helper.h"
#include "chrome/renderer/benchmarking_extension.h"
-#include "chrome/renderer/blocked_plugin.h"
#include "chrome/renderer/chrome_ppapi_interfaces.h"
#include "chrome/renderer/chrome_render_process_observer.h"
#include "chrome/renderer/chrome_render_view_observer.h"
@@ -46,7 +45,9 @@
#include "chrome/renderer/net/renderer_net_predictor.h"
#include "chrome/renderer/page_click_tracker.h"
#include "chrome/renderer/page_load_histograms.h"
-#include "chrome/renderer/plugin_uma.h"
+#include "chrome/renderer/plugins/blocked_plugin.h"
+#include "chrome/renderer/plugins/missing_plugin.h"
+#include "chrome/renderer/plugins/plugin_uma.h"
#include "chrome/renderer/prerender/prerender_helper.h"
#include "chrome/renderer/print_web_view_helper.h"
#include "chrome/renderer/renderer_histogram_snapshots.h"
@@ -290,9 +291,7 @@ WebPlugin* ChromeContentRendererClient::CreatePlugin(
if (status.value == ChromeViewHostMsg_GetPluginInfo_Status::kNotFound) {
MissingPluginReporter::GetInstance()->ReportPluginMissing(
orig_mime_type, url);
- return CreatePluginPlaceholder(
- render_view, frame, plugin, original_params, NULL,
- IDR_BLOCKED_PLUGIN_HTML, IDS_PLUGIN_NOT_FOUND, false, false);
+ return MissingPlugin::Create(render_view, frame, original_params);
}
if (plugin.path.value() == webkit::npapi::kDefaultPluginLibraryName) {
MissingPluginReporter::GetInstance()->ReportPluginMissing(
@@ -303,8 +302,8 @@ WebPlugin* ChromeContentRendererClient::CreatePlugin(
webkit::npapi::PluginList::Singleton()->GetPluginGroup(plugin));
if (status.value == ChromeViewHostMsg_GetPluginInfo_Status::kDisabled) {
- return CreatePluginPlaceholder(
- render_view, frame, plugin, original_params, group.get(),
+ return BlockedPlugin::Create(
+ render_view, frame, original_params, plugin, group.get(),
IDR_DISABLED_PLUGIN_HTML, IDS_PLUGIN_DISABLED, false, false);
}
@@ -326,14 +325,14 @@ WebPlugin* ChromeContentRendererClient::CreatePlugin(
GURL(group->GetUpdateURL())));
}
if (status.value ==
- ChromeViewHostMsg_GetPluginInfo_Status::kOutdatedBlocked ||
+ ChromeViewHostMsg_GetPluginInfo_Status::kOutdatedBlocked ||
status.value ==
ChromeViewHostMsg_GetPluginInfo_Status::kOutdatedDisallowed) {
- return CreatePluginPlaceholder(
- render_view, frame, plugin, params, group.get(),
+ return BlockedPlugin::Create(
+ render_view, frame, params, plugin, group.get(),
IDR_BLOCKED_PLUGIN_HTML, IDS_PLUGIN_OUTDATED, false,
status.value ==
- ChromeViewHostMsg_GetPluginInfo_Status::kOutdatedBlocked);
+ ChromeViewHostMsg_GetPluginInfo_Status::kOutdatedBlocked);
}
ContentSettingsObserver* observer = ContentSettingsObserver::Get(render_view);
@@ -343,8 +342,8 @@ WebPlugin* ChromeContentRendererClient::CreatePlugin(
!observer->plugins_temporarily_allowed()) {
render_view->Send(new ChromeViewHostMsg_BlockedOutdatedPlugin(
render_view->GetRoutingId(), group->GetGroupName(), GURL()));
- return CreatePluginPlaceholder(
- render_view, frame, plugin, params, group.get(),
+ return BlockedPlugin::Create(
+ render_view, frame, params, plugin, group.get(),
IDR_BLOCKED_PLUGIN_HTML, IDS_PLUGIN_NOT_AUTHORIZED, false, true);
}
@@ -355,8 +354,8 @@ WebPlugin* ChromeContentRendererClient::CreatePlugin(
plugin.path.value() == webkit::npapi::kDefaultPluginLibraryName) {
// Delay loading plugins if prerendering.
if (prerender::PrerenderHelper::IsPrerendering(render_view)) {
- return CreatePluginPlaceholder(
- render_view, frame, plugin, params, group.get(),
+ return BlockedPlugin::Create(
+ render_view, frame, params, plugin, group.get(),
IDR_CLICK_TO_PLAY_PLUGIN_HTML, IDS_PLUGIN_LOAD, true, true);
}
@@ -381,8 +380,8 @@ WebPlugin* ChromeContentRendererClient::CreatePlugin(
is_nacl_mime_type,
is_nacl_enabled,
params)) {
- return CreatePluginPlaceholder(
- render_view, frame, plugin, params, group.get(),
+ return BlockedPlugin::Create(
+ render_view, frame, params, plugin, group.get(),
IDR_BLOCKED_PLUGIN_HTML, IDS_PLUGIN_BLOCKED, false, false);
}
}
@@ -396,14 +395,14 @@ WebPlugin* ChromeContentRendererClient::CreatePlugin(
group->identifier());
if (status.value == ChromeViewHostMsg_GetPluginInfo_Status::kClickToPlay) {
RenderThread::Get()->RecordUserMetrics("Plugin_ClickToPlay");
- return CreatePluginPlaceholder(
- render_view, frame, plugin, params, group.get(),
+ return BlockedPlugin::Create(
+ render_view, frame, params, plugin, group.get(),
IDR_CLICK_TO_PLAY_PLUGIN_HTML, IDS_PLUGIN_LOAD, false, true);
} else {
DCHECK(status.value == ChromeViewHostMsg_GetPluginInfo_Status::kBlocked);
RenderThread::Get()->RecordUserMetrics("Plugin_Blocked");
- return CreatePluginPlaceholder(
- render_view, frame, plugin, params, group.get(),
+ return BlockedPlugin::Create(
+ render_view, frame, params, plugin, group.get(),
IDR_BLOCKED_PLUGIN_HTML, IDS_PLUGIN_BLOCKED, false, true);
}
}
@@ -489,41 +488,6 @@ bool ChromeContentRendererClient::IsNaClAllowed(
return true;
}
-WebPlugin* ChromeContentRendererClient::CreatePluginPlaceholder(
- content::RenderView* render_view,
- WebFrame* frame,
- const webkit::WebPluginInfo& plugin,
- const WebPluginParams& params,
- const webkit::npapi::PluginGroup* group,
- int resource_id,
- int message_id,
- bool is_blocked_for_prerendering,
- bool allow_loading) {
- // |blocked_plugin| will delete itself when the WebViewPlugin
- // is destroyed.
- string16 name;
- string16 message;
- if (group) {
- name = group->GetGroupName();
- message = l10n_util::GetStringFUTF16(message_id, name);
- } else {
- message = l10n_util::GetStringUTF16(message_id);
- }
-
- BlockedPlugin* blocked_plugin =
- new BlockedPlugin(render_view,
- frame,
- plugin,
- params,
- render_view->GetWebkitPreferences(),
- resource_id,
- name,
- message,
- is_blocked_for_prerendering,
- allow_loading);
- return blocked_plugin->plugin();
-}
-
bool ChromeContentRendererClient::HasErrorPage(int http_status_code,
std::string* error_domain) {
// Use an internal error page, if we have one for the status code.
diff --git a/chrome/renderer/chrome_content_renderer_client.h b/chrome/renderer/chrome_content_renderer_client.h
index 26c9605..ca85a81 100644
--- a/chrome/renderer/chrome_content_renderer_client.h
+++ b/chrome/renderer/chrome_content_renderer_client.h
@@ -116,17 +116,6 @@ class ChromeContentRendererClient : public content::ContentRendererClient {
WebKit::WebFrame* frame,
const WebKit::WebPluginParams& params);
- WebKit::WebPlugin* CreatePluginPlaceholder(
- content::RenderView* render_view,
- WebKit::WebFrame* frame,
- const webkit::WebPluginInfo& plugin,
- const WebKit::WebPluginParams& params,
- const webkit::npapi::PluginGroup* group,
- int resource_id,
- int message_id,
- bool is_blocked_for_prerendering,
- bool allow_loading);
-
// Returns the extension for the given URL. Excludes extension objects for
// bookmark apps, which do not use the app process model.
const Extension* GetNonBookmarkAppExtension(const ExtensionSet* extensions,
diff --git a/chrome/renderer/custom_menu_commands.h b/chrome/renderer/custom_menu_commands.h
new file mode 100644
index 0000000..e8bf53d
--- /dev/null
+++ b/chrome/renderer/custom_menu_commands.h
@@ -0,0 +1,18 @@
+// Copyright (c) 2011 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_CUSTOM_MENU_COMMANDS_H_
+#define CHROME_RENDERER_CUSTOM_MENU_COMMANDS_H_
+#pragma once
+
+namespace chrome {
+
+enum MenuCommands {
+ MENU_COMMAND_PLUGIN_RUN = 1,
+ MENU_COMMAND_PLUGIN_HIDE = 2,
+};
+
+} // namespace chrome
+
+#endif // CHROME_RENDERER_CUSTOM_MENU_COMMANDS_H_
diff --git a/chrome/renderer/blocked_plugin.cc b/chrome/renderer/plugins/blocked_plugin.cc
index 4db472a..806e711 100644
--- a/chrome/renderer/blocked_plugin.cc
+++ b/chrome/renderer/plugins/blocked_plugin.cc
@@ -2,113 +2,105 @@
// 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 "chrome/renderer/plugins/blocked_plugin.h"
#include "base/string_piece.h"
#include "base/string_util.h"
#include "base/values.h"
#include "chrome/common/jstemplate_builder.h"
#include "chrome/common/render_messages.h"
-#include "chrome/renderer/plugin_uma.h"
+#include "chrome/renderer/custom_menu_commands.h"
#include "content/public/renderer/render_thread.h"
#include "content/public/renderer/render_view.h"
#include "grit/generated_resources.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebContextMenuData.h"
-#include "third_party/WebKit/Source/WebKit/chromium/public/WebData.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/WebInputEvent.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebMenuItemInfo.h"
-#include "third_party/WebKit/Source/WebKit/chromium/public/WebPluginContainer.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebPoint.h"
-#include "third_party/WebKit/Source/WebKit/chromium/public/WebRegularExpression.h"
-#include "third_party/WebKit/Source/WebKit/chromium/public/WebTextCaseSensitivity.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebVector.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebView.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/base/resource/resource_bundle.h"
#include "webkit/glue/webpreferences.h"
#include "webkit/plugins/npapi/plugin_group.h"
-#include "webkit/plugins/npapi/webview_plugin.h"
+#include "webkit/plugins/webview_plugin.h"
using WebKit::WebContextMenuData;
-using WebKit::WebElement;
using WebKit::WebFrame;
using WebKit::WebMenuItemInfo;
-using WebKit::WebNode;
using WebKit::WebPlugin;
-using WebKit::WebPluginContainer;
using WebKit::WebPluginParams;
using WebKit::WebPoint;
-using WebKit::WebRegularExpression;
using WebKit::WebString;
using WebKit::WebURLRequest;
using WebKit::WebVector;
using content::RenderThread;
+using webkit::WebViewPlugin;
-static const char* const kBlockedPluginDataURL = "chrome://blockedplugindata/";
-// TODO(cevans) - move these to a shared header file so that there are no
-// collisions in the longer term. Currently, blocked_plugin.cc is the only
-// user of custom menu commands (extension menu items have their own range).
-static const unsigned kMenuActionLoad = 1;
-static const unsigned kMenuActionRemove = 2;
+namespace {
+const BlockedPlugin* g_last_active_menu = NULL;
+}
+
+// static
+WebViewPlugin* BlockedPlugin::Create(content::RenderView* render_view,
+ WebFrame* frame,
+ const WebPluginParams& params,
+ const webkit::WebPluginInfo& plugin,
+ const webkit::npapi::PluginGroup* group,
+ int template_id,
+ int message_id,
+ bool is_blocked_for_prerendering,
+ bool allow_loading) {
+ string16 name = group->GetGroupName();
+ string16 message = l10n_util::GetStringFUTF16(message_id, name);
-static const BlockedPlugin* g_last_active_menu;
+ DictionaryValue values;
+ values.SetString("message", message);
+ values.SetString("name", name);
+ values.SetString("hide", l10n_util::GetStringUTF8(IDS_PLUGIN_HIDE));
+
+ const base::StringPiece template_html(
+ ResourceBundle::GetSharedInstance().GetRawDataResource(template_id));
+
+ DCHECK(!template_html.empty()) << "unable to load template. ID: "
+ << template_id;
+ // "t" is the id of the templates root node.
+ std::string html_data = jstemplate_builder::GetI18nTemplateHtml(
+ template_html, &values);
+
+ // |blocked_plugin| will destroy itself when its WebViewPlugin is going away.
+ BlockedPlugin* blocked_plugin = new BlockedPlugin(
+ render_view, frame, params, html_data, plugin, name,
+ is_blocked_for_prerendering, allow_loading);
+ return blocked_plugin->plugin();
+}
BlockedPlugin::BlockedPlugin(content::RenderView* render_view,
WebFrame* frame,
- const webkit::WebPluginInfo& info,
const WebPluginParams& params,
- const WebPreferences& preferences,
- int template_id,
+ const std::string& html_data,
+ const webkit::WebPluginInfo& info,
const string16& name,
- const string16& message,
bool is_blocked_for_prerendering,
bool allow_loading)
- : content::RenderViewObserver(render_view),
- frame_(frame),
+ : PluginPlaceholder(render_view, frame, params, html_data),
plugin_info_(info),
- plugin_params_(params),
name_(name),
is_blocked_for_prerendering_(is_blocked_for_prerendering),
hidden_(false),
allow_loading_(allow_loading) {
- const base::StringPiece template_html(
- ResourceBundle::GetSharedInstance().GetRawDataResource(template_id));
-
- DCHECK(!template_html.empty()) << "unable to load template. ID: "
- << template_id;
-
- DictionaryValue values;
- values.SetString("message", message);
- values.SetString("name", name_);
- values.SetString("hide", l10n_util::GetStringUTF8(IDS_PLUGIN_HIDE));
-
- // "t" is the id of the templates root node.
- std::string html_data = jstemplate_builder::GetI18nTemplateHtml(
- template_html, &values);
-
- plugin_ = webkit::npapi::WebViewPlugin::Create(this,
- preferences,
- html_data,
- GURL(kBlockedPluginDataURL));
}
BlockedPlugin::~BlockedPlugin() {
}
void BlockedPlugin::BindWebFrame(WebFrame* frame) {
- BindToJavascript(frame, "plugin");
+ PluginPlaceholder::BindWebFrame(frame);
BindMethod("load", &BlockedPlugin::LoadCallback);
BindMethod("hide", &BlockedPlugin::HideCallback);
BindMethod("openURL", &BlockedPlugin::OpenUrlCallback);
}
-void BlockedPlugin::WillDestroyPlugin() {
- delete this;
-}
-
void BlockedPlugin::ShowContextMenu(const WebKit::WebMouseEvent& event) {
WebContextMenuData menu_data;
@@ -129,7 +121,7 @@ void BlockedPlugin::ShowContextMenu(const WebKit::WebMouseEvent& event) {
}
WebMenuItemInfo run_item;
- run_item.action = kMenuActionLoad;
+ run_item.action = chrome::MENU_COMMAND_PLUGIN_RUN;
// Disable this menu item if the plugin is blocked by policy.
run_item.enabled = allow_loading_;
run_item.label = WebString::fromUTF8(
@@ -139,7 +131,7 @@ void BlockedPlugin::ShowContextMenu(const WebKit::WebMouseEvent& event) {
custom_items[i++] = run_item;
WebMenuItemInfo hide_item;
- hide_item.action = kMenuActionRemove;
+ hide_item.action = chrome::MENU_COMMAND_PLUGIN_HIDE;
hide_item.enabled = true;
hide_item.label = WebString::fromUTF8(
l10n_util::GetStringUTF8(IDS_CONTENT_CONTEXT_PLUGIN_HIDE).c_str());
@@ -169,12 +161,19 @@ bool BlockedPlugin::OnMessageReceived(const IPC::Message& message) {
void BlockedPlugin::ContextMenuAction(unsigned id) {
if (g_last_active_menu != this)
return;
- if (id == kMenuActionLoad) {
- RenderThread::Get()->RecordUserMetrics("Plugin_Load_Menu");
- LoadPlugin();
- } else if (id == kMenuActionRemove) {
- RenderThread::Get()->RecordUserMetrics("Plugin_Hide_Menu");
- HidePlugin();
+ switch (id) {
+ case chrome::MENU_COMMAND_PLUGIN_RUN: {
+ RenderThread::Get()->RecordUserMetrics("Plugin_Load_Menu");
+ LoadPlugin();
+ break;
+ }
+ case chrome::MENU_COMMAND_PLUGIN_HIDE: {
+ RenderThread::Get()->RecordUserMetrics("Plugin_Hide_Menu");
+ HidePlugin();
+ break;
+ }
+ default:
+ NOTREACHED();
}
}
@@ -192,28 +191,13 @@ void BlockedPlugin::OnSetIsPrerendering(bool is_prerendering) {
}
void BlockedPlugin::LoadPlugin() {
- CHECK(plugin_);
// This is not strictly necessary but is an important defense in case the
// event propagation changes between "close" vs. "click-to-play".
if (hidden_)
return;
if (!allow_loading_)
return;
- WebPluginContainer* container = plugin_->container();
- WebPlugin* new_plugin =
- render_view()->CreatePlugin(frame_, plugin_info_, plugin_params_);
- if (new_plugin && new_plugin->initialize(container)) {
- plugin_->RestoreTitleText();
- container->setPlugin(new_plugin);
- container->invalidate();
- container->reportGeometry();
- plugin_->ReplayReceivedData(new_plugin);
- plugin_->destroy();
- } else {
- MissingPluginReporter::GetInstance()->ReportPluginMissing(
- plugin_params_.mimeType.utf8(),
- plugin_params_.url);
- }
+ LoadPluginInternal(plugin_info_);
}
void BlockedPlugin::LoadCallback(const CppArgumentList& args,
@@ -244,56 +228,10 @@ void BlockedPlugin::OpenUrlCallback(const CppArgumentList& args,
request.initialize();
request.setURL(url);
render_view()->LoadURLExternally(
- frame_, request, WebKit::WebNavigationPolicyNewForegroundTab);
+ frame(), request, WebKit::WebNavigationPolicyNewForegroundTab);
}
void BlockedPlugin::HidePlugin() {
- CHECK(plugin_);
hidden_ = true;
- WebPluginContainer* container = plugin_->container();
- WebElement element = container->element();
- element.setAttribute("style", "display: none;");
- // If we have a width and height, search for a parent (often <div>) with the
- // same dimensions. If we find such a parent, hide that as well.
- // This makes much more uncovered page content usable (including clickable)
- // as opposed to merely visible.
- // TODO(cevans) -- it's a foul heurisitc but we're going to tolerate it for
- // now for these reasons:
- // 1) Makes the user experience better.
- // 2) Foulness is encapsulated within this single function.
- // 3) Confidence in no fasle positives.
- // 4) Seems to have a good / low false negative rate at this time.
- if (element.hasAttribute("width") && element.hasAttribute("height")) {
- std::string width_str("width:[\\s]*");
- width_str += element.getAttribute("width").utf8().data();
- if (EndsWith(width_str, "px", false)) {
- width_str = width_str.substr(0, width_str.length() - 2);
- }
- TrimWhitespace(width_str, TRIM_TRAILING, &width_str);
- width_str += "[\\s]*px";
- WebRegularExpression width_regex(WebString::fromUTF8(width_str.c_str()),
- WebKit::WebTextCaseSensitive);
- std::string height_str("height:[\\s]*");
- height_str += element.getAttribute("height").utf8().data();
- if (EndsWith(height_str, "px", false)) {
- height_str = height_str.substr(0, height_str.length() - 2);
- }
- TrimWhitespace(height_str, TRIM_TRAILING, &height_str);
- height_str += "[\\s]*px";
- WebRegularExpression height_regex(WebString::fromUTF8(height_str.c_str()),
- WebKit::WebTextCaseSensitive);
- WebNode parent = element;
- while (!parent.parentNode().isNull()) {
- parent = parent.parentNode();
- if (!parent.isElementNode())
- continue;
- element = parent.toConst<WebElement>();
- if (element.hasAttribute("style")) {
- WebString style_str = element.getAttribute("style");
- if (width_regex.match(style_str) >= 0 &&
- height_regex.match(style_str) >= 0)
- element.setAttribute("style", "display: none;");
- }
- }
- }
+ HidePluginInternal();
}
diff --git a/chrome/renderer/blocked_plugin.h b/chrome/renderer/plugins/blocked_plugin.h
index abff76d..597b5e7 100644
--- a/chrome/renderer/blocked_plugin.h
+++ b/chrome/renderer/plugins/blocked_plugin.h
@@ -2,41 +2,47 @@
// 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_
+#ifndef CHROME_RENDERER_PLUGINS_BLOCKED_PLUGIN_H_
+#define CHROME_RENDERER_PLUGINS_BLOCKED_PLUGIN_H_
#pragma once
-#include "content/public/renderer/render_view_observer.h"
-#include "third_party/WebKit/Source/WebKit/chromium/public/WebPluginParams.h"
-#include "webkit/glue/cpp_bound_class.h"
-#include "webkit/plugins/npapi/webview_plugin.h"
+#include "chrome/renderer/plugins/plugin_placeholder.h"
#include "webkit/plugins/webplugininfo.h"
-class BlockedPlugin : public content::RenderViewObserver,
- public CppBoundClass,
- public webkit::npapi::WebViewPlugin::Delegate {
+namespace webkit {
+namespace npapi {
+class PluginGroup;
+}
+}
+
+class BlockedPlugin : public PluginPlaceholder {
public:
+ // Creates a new WebViewPlugin with a BlockedPlugin as a delegate.
+ static webkit::WebViewPlugin* Create(content::RenderView* render_view,
+ WebKit::WebFrame* frame,
+ const WebKit::WebPluginParams& params,
+ const webkit::WebPluginInfo& info,
+ const webkit::npapi::PluginGroup* group,
+ int resource_id,
+ int message_id,
+ bool is_blocked_for_prerendering,
+ bool allow_loading);
+
+ private:
BlockedPlugin(content::RenderView* render_view,
WebKit::WebFrame* frame,
- const webkit::WebPluginInfo& info,
const WebKit::WebPluginParams& params,
- const WebPreferences& settings,
- int template_id,
+ const std::string& html_data,
+ const webkit::WebPluginInfo& info,
const string16& name,
- const string16& message,
bool is_blocked_for_prerendering,
bool allow_loading);
-
- webkit::npapi::WebViewPlugin* plugin() { return plugin_; }
+ virtual ~BlockedPlugin();
// WebViewPlugin::Delegate methods:
virtual void BindWebFrame(WebKit::WebFrame* frame) OVERRIDE;
- virtual void WillDestroyPlugin() OVERRIDE;
virtual void ShowContextMenu(const WebKit::WebMouseEvent&) OVERRIDE;
- private:
- virtual ~BlockedPlugin();
-
// RenderViewObserver methods:
virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE;
virtual void ContextMenuAction(unsigned id) OVERRIDE;
@@ -63,10 +69,7 @@ class BlockedPlugin : public content::RenderViewObserver,
// Hide the blocked plugin.
void HidePlugin();
- WebKit::WebFrame* frame_;
webkit::WebPluginInfo plugin_info_;
- WebKit::WebPluginParams plugin_params_;
- webkit::npapi::WebViewPlugin* plugin_;
// The name of the plugin that was blocked.
string16 name_;
// True iff the plugin was blocked because the page was being prerendered.
@@ -76,4 +79,4 @@ class BlockedPlugin : public content::RenderViewObserver,
bool allow_loading_;
};
-#endif // CHROME_RENDERER_BLOCKED_PLUGIN_H_
+#endif // CHROME_RENDERER_PLUGINS_BLOCKED_PLUGIN_H_
diff --git a/chrome/renderer/plugins/missing_plugin.cc b/chrome/renderer/plugins/missing_plugin.cc
new file mode 100644
index 0000000..9773414
--- /dev/null
+++ b/chrome/renderer/plugins/missing_plugin.cc
@@ -0,0 +1,124 @@
+// Copyright (c) 2011 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/plugins/missing_plugin.h"
+
+#include "base/string_piece.h"
+#include "base/string_util.h"
+#include "base/values.h"
+#include "chrome/common/jstemplate_builder.h"
+#include "chrome/renderer/custom_menu_commands.h"
+#include "content/public/renderer/render_thread.h"
+#include "content/public/renderer/render_view.h"
+#include "grit/generated_resources.h"
+#include "grit/renderer_resources.h"
+#include "third_party/WebKit/Source/WebKit/chromium/public/WebContextMenuData.h"
+#include "third_party/WebKit/Source/WebKit/chromium/public/WebInputEvent.h"
+#include "third_party/WebKit/Source/WebKit/chromium/public/WebMenuItemInfo.h"
+#include "third_party/WebKit/Source/WebKit/chromium/public/WebPoint.h"
+#include "third_party/WebKit/Source/WebKit/chromium/public/WebVector.h"
+#include "ui/base/l10n/l10n_util.h"
+#include "ui/base/resource/resource_bundle.h"
+#include "webkit/plugins/npapi/plugin_group.h"
+
+using WebKit::WebContextMenuData;
+using WebKit::WebFrame;
+using WebKit::WebMenuItemInfo;
+using WebKit::WebPlugin;
+using WebKit::WebPluginParams;
+using WebKit::WebPoint;
+using WebKit::WebString;
+using WebKit::WebVector;
+using content::RenderThread;
+using webkit::WebViewPlugin;
+
+namespace {
+const MissingPlugin* g_last_active_menu = NULL;
+}
+
+// static
+WebViewPlugin* MissingPlugin::Create(content::RenderView* render_view,
+ WebFrame* frame,
+ const WebPluginParams& params) {
+ const base::StringPiece template_html(
+ ResourceBundle::GetSharedInstance().GetRawDataResource(
+ IDR_BLOCKED_PLUGIN_HTML));
+
+ DictionaryValue values;
+ values.SetString("message", l10n_util::GetStringUTF8(IDS_PLUGIN_NOT_FOUND));
+
+ // "t" is the id of the templates root node.
+ std::string html_data =
+ jstemplate_builder::GetI18nTemplateHtml(template_html, &values);
+
+ // |missing_plugin| will destroy itself when its WebViewPlugin is going away.
+ MissingPlugin* missing_plugin = new MissingPlugin(render_view, frame, params,
+ html_data);
+ return missing_plugin->plugin();
+}
+
+MissingPlugin::MissingPlugin(content::RenderView* render_view,
+ WebFrame* frame,
+ const WebPluginParams& params,
+ const std::string& html_data)
+ : PluginPlaceholder(render_view, frame, params, html_data),
+ mime_type_(params.mimeType) {
+}
+
+MissingPlugin::~MissingPlugin() {
+}
+
+void MissingPlugin::BindWebFrame(WebFrame* frame) {
+ PluginPlaceholder::BindWebFrame(frame);
+ BindMethod("hide", &MissingPlugin::HideCallback);
+}
+
+void MissingPlugin::HideCallback(const CppArgumentList& args,
+ CppVariant* result) {
+ RenderThread::Get()->RecordUserMetrics("MissingPlugin_Hide_Click");
+ HidePluginInternal();
+}
+
+void MissingPlugin::ShowContextMenu(const WebKit::WebMouseEvent& event) {
+ WebContextMenuData menu_data;
+
+ WebVector<WebMenuItemInfo> custom_items(static_cast<size_t>(3));
+
+ size_t i = 0;
+ WebMenuItemInfo mime_type_item;
+ mime_type_item.label = mime_type_;
+ mime_type_item.hasTextDirectionOverride = false;
+ mime_type_item.textDirection = WebKit::WebTextDirectionDefault;
+ custom_items[i++] = mime_type_item;
+
+ WebMenuItemInfo separator_item;
+ separator_item.type = WebMenuItemInfo::Separator;
+ custom_items[i++] = separator_item;
+
+ WebMenuItemInfo hide_item;
+ hide_item.action = chrome::MENU_COMMAND_PLUGIN_HIDE;
+ hide_item.enabled = true;
+ hide_item.label = WebString::fromUTF8(
+ l10n_util::GetStringUTF8(IDS_CONTENT_CONTEXT_PLUGIN_HIDE).c_str());
+ hide_item.hasTextDirectionOverride = false;
+ hide_item.textDirection = WebKit::WebTextDirectionDefault;
+ custom_items[i++] = hide_item;
+
+ menu_data.customItems.swap(custom_items);
+ menu_data.mousePosition = WebPoint(event.windowX, event.windowY);
+ render_view()->ShowContextMenu(NULL, menu_data);
+ g_last_active_menu = this;
+}
+
+void MissingPlugin::ContextMenuAction(unsigned id) {
+ if (g_last_active_menu != this)
+ return;
+ if (id == chrome::MENU_COMMAND_PLUGIN_HIDE) {
+ RenderThread::Get()->RecordUserMetrics("MissingPlugin_Hide_Menu");
+ HidePluginInternal();
+ } else {
+ NOTREACHED();
+ }
+}
+
diff --git a/chrome/renderer/plugins/missing_plugin.h b/chrome/renderer/plugins/missing_plugin.h
new file mode 100644
index 0000000..7b3351f
--- /dev/null
+++ b/chrome/renderer/plugins/missing_plugin.h
@@ -0,0 +1,41 @@
+// Copyright (c) 2011 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_PLUGINS_MISSING_PLUGIN_H_
+#define CHROME_RENDERER_PLUGINS_MISSING_PLUGIN_H_
+#pragma once
+
+#include "chrome/renderer/plugins/plugin_placeholder.h"
+#include "third_party/WebKit/Source/WebKit/chromium/public/WebString.h"
+
+class MissingPlugin : public PluginPlaceholder {
+ public:
+ // Creates a new WebViewPlugin with a MissingPlugin as a delegate.
+ static webkit::WebViewPlugin* Create(
+ content::RenderView* render_view,
+ WebKit::WebFrame* frame,
+ const WebKit::WebPluginParams& params);
+
+ private:
+ MissingPlugin(content::RenderView* render_view,
+ WebKit::WebFrame* frame,
+ const WebKit::WebPluginParams& params,
+ const std::string& html_data);
+ virtual ~MissingPlugin();
+
+ // WebViewPlugin::Delegate methods:
+ virtual void BindWebFrame(WebKit::WebFrame* frame) OVERRIDE;
+ virtual void ShowContextMenu(const WebKit::WebMouseEvent&) OVERRIDE;
+
+ // content::RenderViewObserver methods:
+ virtual void ContextMenuAction(unsigned id) OVERRIDE;
+
+ void HideCallback(const CppArgumentList& args, CppVariant* result);
+
+ WebKit::WebString mime_type_;
+
+ DISALLOW_COPY_AND_ASSIGN(MissingPlugin);
+};
+
+#endif // CHROME_RENDERER_PLUGINS_MISSING_PLUGIN_H_
diff --git a/chrome/renderer/plugins/plugin_placeholder.cc b/chrome/renderer/plugins/plugin_placeholder.cc
new file mode 100644
index 0000000..4bc97a6
--- /dev/null
+++ b/chrome/renderer/plugins/plugin_placeholder.cc
@@ -0,0 +1,126 @@
+// Copyright (c) 2011 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/plugins/plugin_placeholder.h"
+
+#include "base/string_util.h"
+#include "chrome/renderer/plugins/plugin_uma.h"
+#include "content/public/renderer/render_view.h"
+#include "third_party/WebKit/Source/WebKit/chromium/public/WebData.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/WebPluginContainer.h"
+#include "third_party/WebKit/Source/WebKit/chromium/public/WebRegularExpression.h"
+#include "third_party/WebKit/Source/WebKit/chromium/public/WebTextCaseSensitivity.h"
+#include "third_party/WebKit/Source/WebKit/chromium/public/WebView.h"
+
+using WebKit::WebElement;
+using WebKit::WebFrame;
+using WebKit::WebMouseEvent;
+using WebKit::WebNode;
+using WebKit::WebPlugin;
+using WebKit::WebPluginContainer;
+using WebKit::WebPluginParams;
+using WebKit::WebRegularExpression;
+using WebKit::WebString;
+using webkit::WebPluginInfo;
+using webkit::WebViewPlugin;
+
+static const char* const kPluginPlaceholderDataURL =
+ "chrome://pluginplaceholderdata/";
+
+PluginPlaceholder::PluginPlaceholder(content::RenderView* render_view,
+ WebFrame* frame,
+ const WebPluginParams& params,
+ const std::string& html_data)
+ : content::RenderViewObserver(render_view),
+ frame_(frame),
+ plugin_params_(params),
+ plugin_(WebViewPlugin::Create(
+ this, render_view->GetWebkitPreferences(), html_data,
+ GURL(kPluginPlaceholderDataURL))) {
+}
+
+PluginPlaceholder::~PluginPlaceholder() {
+}
+
+void PluginPlaceholder::BindWebFrame(WebFrame* frame) {
+ BindToJavascript(frame, "plugin");
+}
+
+void PluginPlaceholder::LoadPluginInternal(const WebPluginInfo& plugin_info) {
+ CHECK(plugin_);
+ WebPluginContainer* container = plugin_->container();
+ WebPlugin* new_plugin =
+ render_view()->CreatePlugin(frame_, plugin_info, plugin_params_);
+ if (new_plugin && new_plugin->initialize(container)) {
+ plugin_->RestoreTitleText();
+ container->setPlugin(new_plugin);
+ container->invalidate();
+ container->reportGeometry();
+ plugin_->ReplayReceivedData(new_plugin);
+ plugin_->destroy();
+ } else {
+ MissingPluginReporter::GetInstance()->ReportPluginMissing(
+ plugin_params_.mimeType.utf8(),
+ plugin_params_.url);
+ }
+}
+
+void PluginPlaceholder::HidePluginInternal() {
+ WebPluginContainer* container = plugin_->container();
+ WebElement element = container->element();
+ element.setAttribute("style", "display: none;");
+ // If we have a width and height, search for a parent (often <div>) with the
+ // same dimensions. If we find such a parent, hide that as well.
+ // This makes much more uncovered page content usable (including clickable)
+ // as opposed to merely visible.
+ // TODO(cevans) -- it's a foul heurisitc but we're going to tolerate it for
+ // now for these reasons:
+ // 1) Makes the user experience better.
+ // 2) Foulness is encapsulated within this single function.
+ // 3) Confidence in no fasle positives.
+ // 4) Seems to have a good / low false negative rate at this time.
+ if (element.hasAttribute("width") && element.hasAttribute("height")) {
+ std::string width_str("width:[\\s]*");
+ width_str += element.getAttribute("width").utf8().data();
+ if (EndsWith(width_str, "px", false)) {
+ width_str = width_str.substr(0, width_str.length() - 2);
+ }
+ TrimWhitespace(width_str, TRIM_TRAILING, &width_str);
+ width_str += "[\\s]*px";
+ WebRegularExpression width_regex(WebString::fromUTF8(width_str.c_str()),
+ WebKit::WebTextCaseSensitive);
+ std::string height_str("height:[\\s]*");
+ height_str += element.getAttribute("height").utf8().data();
+ if (EndsWith(height_str, "px", false)) {
+ height_str = height_str.substr(0, height_str.length() - 2);
+ }
+ TrimWhitespace(height_str, TRIM_TRAILING, &height_str);
+ height_str += "[\\s]*px";
+ WebRegularExpression height_regex(WebString::fromUTF8(height_str.c_str()),
+ WebKit::WebTextCaseSensitive);
+ WebNode parent = element;
+ while (!parent.parentNode().isNull()) {
+ parent = parent.parentNode();
+ if (!parent.isElementNode())
+ continue;
+ element = parent.toConst<WebElement>();
+ if (element.hasAttribute("style")) {
+ WebString style_str = element.getAttribute("style");
+ if (width_regex.match(style_str) >= 0 &&
+ height_regex.match(style_str) >= 0)
+ element.setAttribute("style", "display: none;");
+ }
+ }
+ }
+}
+
+void PluginPlaceholder::WillDestroyPlugin() {
+ delete this;
+}
+
+void PluginPlaceholder::ShowContextMenu(const WebMouseEvent& event) {
+}
diff --git a/chrome/renderer/plugins/plugin_placeholder.h b/chrome/renderer/plugins/plugin_placeholder.h
new file mode 100644
index 0000000..009d300
--- /dev/null
+++ b/chrome/renderer/plugins/plugin_placeholder.h
@@ -0,0 +1,56 @@
+// Copyright (c) 2011 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_PLUGINS_PLUGIN_PLACEHOLDER_H_
+#define CHROME_RENDERER_PLUGINS_PLUGIN_PLACEHOLDER_H_
+#pragma once
+
+#include "content/public/renderer/render_view_observer.h"
+#include "third_party/WebKit/Source/WebKit/chromium/public/WebPluginParams.h"
+#include "webkit/glue/cpp_bound_class.h"
+#include "webkit/plugins/webview_plugin.h"
+
+namespace webkit {
+struct WebPluginInfo;
+}
+
+// Base class to share code between different plug-in placeholders
+// used in Chrome. Placeholders can be used if a plug-in is missing or not
+// available (blocked or disabled).
+class PluginPlaceholder : public content::RenderViewObserver,
+ public CppBoundClass,
+ public webkit::WebViewPlugin::Delegate {
+ protected:
+ // |render_view| and |frame| are weak pointers. If either one is going away,
+ // our |plugin_| will be destroyed as well and will notify us.
+ PluginPlaceholder(content::RenderView* render_view,
+ WebKit::WebFrame* frame,
+ const WebKit::WebPluginParams& params,
+ const std::string& html_data);
+ virtual ~PluginPlaceholder();
+
+ webkit::WebViewPlugin* plugin() { return plugin_; }
+ WebKit::WebFrame* frame() { return frame_; }
+
+ // Can be called by a subclass to replace this placeholder with an actual
+ // plugin from |plugin_info|.
+ void LoadPluginInternal(const webkit::WebPluginInfo& plugin_info);
+
+ // WebViewPlugin::Delegate methods:
+ // Can be called by a subclass to hide this placeholder.
+ void HidePluginInternal();
+
+ virtual void BindWebFrame(WebKit::WebFrame* frame) OVERRIDE;
+ virtual void WillDestroyPlugin() OVERRIDE;
+ virtual void ShowContextMenu(const WebKit::WebMouseEvent& event) OVERRIDE;
+
+ private:
+ WebKit::WebFrame* frame_;
+ WebKit::WebPluginParams plugin_params_;
+ webkit::WebViewPlugin* plugin_;
+
+ DISALLOW_COPY_AND_ASSIGN(PluginPlaceholder);
+};
+
+#endif // CHROME_RENDERER_PLUGINS_PLUGIN_PLACEHOLDER_H_
diff --git a/chrome/renderer/plugin_uma.cc b/chrome/renderer/plugins/plugin_uma.cc
index ad215b7..5f1bec1 100644
--- a/chrome/renderer/plugin_uma.cc
+++ b/chrome/renderer/plugins/plugin_uma.cc
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "chrome/renderer/plugin_uma.h"
+#include "chrome/renderer/plugins/plugin_uma.h"
#include <algorithm>
#include <cstring>
diff --git a/chrome/renderer/plugin_uma.h b/chrome/renderer/plugins/plugin_uma.h
index 411a8ae..f1eb4cf 100644
--- a/chrome/renderer/plugin_uma.h
+++ b/chrome/renderer/plugins/plugin_uma.h
@@ -2,8 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#ifndef CHROME_RENDERER_PLUGIN_UMA_H_
-#define CHROME_RENDERER_PLUGIN_UMA_H_
+#ifndef CHROME_RENDERER_PLUGINS_PLUGIN_UMA_H_
+#define CHROME_RENDERER_PLUGINS_PLUGIN_UMA_H_
#include <string>
@@ -66,5 +66,5 @@ class MissingPluginReporter {
DISALLOW_COPY_AND_ASSIGN(MissingPluginReporter);
};
-#endif // CHROME_RENDERER_PLUGIN_UMA_H_
+#endif // CHROME_RENDERER_PLUGINS_PLUGIN_UMA_H_
diff --git a/chrome/renderer/plugin_uma_unittest.cc b/chrome/renderer/plugins/plugin_uma_unittest.cc
index c59d932..46e8099 100644
--- a/chrome/renderer/plugin_uma_unittest.cc
+++ b/chrome/renderer/plugins/plugin_uma_unittest.cc
@@ -5,7 +5,7 @@
#include <gmock/gmock.h>
#include <gtest/gtest.h>
-#include "chrome/renderer/plugin_uma.h"
+#include "chrome/renderer/plugins/plugin_uma.h"
using ::testing::_;