summaryrefslogtreecommitdiffstats
path: root/components/plugins
diff options
context:
space:
mode:
authortommycli <tommycli@chromium.org>2015-06-11 15:20:14 -0700
committerCommit bot <commit-bot@chromium.org>2015-06-11 22:21:17 +0000
commit425d6965196e7448a2ba9180a3fd2f5b08f5b329 (patch)
tree0799c08a8aa683b6196ebbf7f3963b29731abbcc /components/plugins
parent60b17299b23088c43179c092a26977cdb294b0da (diff)
downloadchromium_src-425d6965196e7448a2ba9180a3fd2f5b08f5b329.zip
chromium_src-425d6965196e7448a2ba9180a3fd2f5b08f5b329.tar.gz
chromium_src-425d6965196e7448a2ba9180a3fd2f5b08f5b329.tar.bz2
Reland: Plugin Placeholders: Refactor for platforms that don't support plugins
This patch removes a lot of plugin placeholder code from builds that don't support plugins (enable_plugins==0). This is a reland of https://codereview.chromium.org/1126073003/. See patchsets for fixes of the crashes. BUG=493889 TBR= Review URL: https://codereview.chromium.org/1161923004 Cr-Commit-Position: refs/heads/master@{#334054}
Diffstat (limited to 'components/plugins')
-rw-r--r--components/plugins/renderer/BUILD.gn10
-rw-r--r--components/plugins/renderer/loadable_plugin_placeholder.cc129
-rw-r--r--components/plugins/renderer/loadable_plugin_placeholder.h34
-rw-r--r--components/plugins/renderer/mobile_youtube_plugin.cc34
-rw-r--r--components/plugins/renderer/mobile_youtube_plugin.h14
-rw-r--r--components/plugins/renderer/plugin_placeholder.cc120
-rw-r--r--components/plugins/renderer/plugin_placeholder.h60
-rw-r--r--components/plugins/renderer/webview_plugin.cc17
-rw-r--r--components/plugins/renderer/webview_plugin.h7
9 files changed, 215 insertions, 210 deletions
diff --git a/components/plugins/renderer/BUILD.gn b/components/plugins/renderer/BUILD.gn
index ef7e8f1..446ad99 100644
--- a/components/plugins/renderer/BUILD.gn
+++ b/components/plugins/renderer/BUILD.gn
@@ -2,15 +2,21 @@
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
+import("//build/config/features.gni")
+
static_library("renderer") {
sources = [
- "loadable_plugin_placeholder.cc",
- "loadable_plugin_placeholder.h",
"plugin_placeholder.cc",
"plugin_placeholder.h",
"webview_plugin.cc",
"webview_plugin.h",
]
+ if (enable_plugins) {
+ sources += [
+ "loadable_plugin_placeholder.cc",
+ "loadable_plugin_placeholder.h",
+ ]
+ }
if (is_android) {
sources += [
"mobile_youtube_plugin.cc",
diff --git a/components/plugins/renderer/loadable_plugin_placeholder.cc b/components/plugins/renderer/loadable_plugin_placeholder.cc
index ea288e2..a41c9ea 100644
--- a/components/plugins/renderer/loadable_plugin_placeholder.cc
+++ b/components/plugins/renderer/loadable_plugin_placeholder.cc
@@ -9,7 +9,6 @@
#include "base/command_line.h"
#include "base/json/string_escape.h"
#include "base/strings/string_piece.h"
-#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
#include "base/thread_task_runner_handle.h"
#include "base/values.h"
@@ -29,24 +28,13 @@
#include "third_party/WebKit/public/web/WebScriptSource.h"
#include "third_party/WebKit/public/web/WebSerializedScriptValue.h"
#include "third_party/WebKit/public/web/WebView.h"
-#include "third_party/re2/re2/re2.h"
using base::UserMetricsAction;
-using blink::WebElement;
-using blink::WebLocalFrame;
-using blink::WebMouseEvent;
-using blink::WebNode;
-using blink::WebPlugin;
-using blink::WebPluginContainer;
-using blink::WebPluginParams;
-using blink::WebScriptSource;
-using blink::WebURLRequest;
using content::PluginInstanceThrottler;
using content::RenderThread;
namespace plugins {
-#if defined(ENABLE_PLUGINS)
// TODO(tommycli): After an unthrottling size update, re-check the size after
// this delay, as Blink can report incorrect sizes to plugins while the
// compositing state is dirty. Chosen because it seems to work.
@@ -69,26 +57,19 @@ void LoadablePluginPlaceholder::SetPremadePlugin(
DCHECK(!premade_throttler_);
premade_throttler_ = throttler;
}
-#endif
LoadablePluginPlaceholder::LoadablePluginPlaceholder(
content::RenderFrame* render_frame,
- WebLocalFrame* frame,
- const WebPluginParams& params,
- const std::string& html_data,
- GURL placeholderDataUrl)
- : PluginPlaceholder(render_frame,
- frame,
- params,
- html_data,
- placeholderDataUrl),
+ blink::WebLocalFrame* frame,
+ const blink::WebPluginParams& params,
+ const std::string& html_data)
+ : PluginPlaceholderBase(render_frame, frame, params, html_data),
is_blocked_for_background_tab_(false),
is_blocked_for_prerendering_(false),
is_blocked_for_power_saver_poster_(false),
power_saver_enabled_(false),
premade_throttler_(nullptr),
- allow_loading_(false),
- hidden_(false),
+ allow_loading_(true),
finished_loading_(false),
in_size_recheck_(false),
weak_factory_(this) {
@@ -97,7 +78,6 @@ LoadablePluginPlaceholder::LoadablePluginPlaceholder(
LoadablePluginPlaceholder::~LoadablePluginPlaceholder() {
}
-#if defined(ENABLE_PLUGINS)
void LoadablePluginPlaceholder::MarkPluginEssential(
PluginInstanceThrottler::PowerSaverUnthrottleMethod method) {
if (!power_saver_enabled_)
@@ -116,39 +96,17 @@ void LoadablePluginPlaceholder::MarkPluginEssential(
LoadPlugin();
}
}
-#endif
-
-void LoadablePluginPlaceholder::BindWebFrame(blink::WebFrame* frame) {
- v8::Isolate* isolate = blink::mainThreadIsolate();
- v8::HandleScope handle_scope(isolate);
- v8::Local<v8::Context> context = frame->mainWorldScriptContext();
- DCHECK(!context.IsEmpty());
-
- v8::Context::Scope context_scope(context);
- v8::Local<v8::Object> global = context->Global();
- global->Set(gin::StringToV8(isolate, "plugin"),
- gin::CreateHandle(isolate, this).ToV8());
-}
-
-gin::ObjectTemplateBuilder LoadablePluginPlaceholder::GetObjectTemplateBuilder(
- v8::Isolate* isolate) {
- return gin::Wrappable<PluginPlaceholder>::GetObjectTemplateBuilder(isolate)
- .SetMethod("load", &LoadablePluginPlaceholder::LoadCallback)
- .SetMethod("hide", &LoadablePluginPlaceholder::HideCallback)
- .SetMethod("didFinishLoading",
- &LoadablePluginPlaceholder::DidFinishLoadingCallback);
-}
-void LoadablePluginPlaceholder::ReplacePlugin(WebPlugin* new_plugin) {
+void LoadablePluginPlaceholder::ReplacePlugin(blink::WebPlugin* new_plugin) {
CHECK(plugin());
if (!new_plugin)
return;
- WebPluginContainer* container = plugin()->container();
+ blink::WebPluginContainer* container = plugin()->container();
// Set the new plugin on the container before initializing it.
container->setPlugin(new_plugin);
// Save the element in case the plugin is removed from the page during
// initialization.
- WebElement element = container->element();
+ blink::WebElement element = container->element();
bool plugin_needs_initialization =
!premade_throttler_ || new_plugin != premade_throttler_->GetWebPlugin();
if (plugin_needs_initialization && !new_plugin->initialize(container)) {
@@ -176,54 +134,6 @@ void LoadablePluginPlaceholder::ReplacePlugin(WebPlugin* new_plugin) {
plugin()->destroy();
}
-void LoadablePluginPlaceholder::HidePlugin() {
- hidden_ = true;
- if (!plugin())
- return;
- 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 heuristic 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);
- }
- base::TrimWhitespace(width_str, base::TRIM_TRAILING, &width_str);
- width_str += "[\\s]*px";
- 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);
- }
- base::TrimWhitespace(height_str, base::TRIM_TRAILING, &height_str);
- height_str += "[\\s]*px";
- WebNode parent = element;
- while (!parent.parentNode().isNull()) {
- parent = parent.parentNode();
- if (!parent.isElementNode())
- continue;
- element = parent.toConst<WebElement>();
- if (element.hasAttribute("style")) {
- std::string style_str = element.getAttribute("style").utf8();
- if (RE2::PartialMatch(style_str, width_str) &&
- RE2::PartialMatch(style_str, height_str))
- element.setAttribute("style", "display: none;");
- }
- }
- }
-}
-
void LoadablePluginPlaceholder::SetMessage(const base::string16& message) {
message_ = message;
if (finished_loading_)
@@ -236,11 +146,10 @@ void LoadablePluginPlaceholder::UpdateMessage() {
std::string script =
"window.setMessage(" + base::GetQuotedJSONString(message_) + ")";
plugin()->web_view()->mainFrame()->executeScript(
- WebScriptSource(base::UTF8ToUTF16(script)));
+ blink::WebScriptSource(base::UTF8ToUTF16(script)));
}
void LoadablePluginPlaceholder::PluginDestroyed() {
-#if defined(ENABLE_PLUGINS)
if (power_saver_enabled_) {
if (premade_throttler_) {
// Since the premade plugin has been detached from the container, it will
@@ -256,23 +165,19 @@ void LoadablePluginPlaceholder::PluginDestroyed() {
// Prevent processing subsequent calls to MarkPluginEssential.
power_saver_enabled_ = false;
}
-#endif
- PluginPlaceholder::PluginDestroyed();
+ PluginPlaceholderBase::PluginDestroyed();
}
v8::Local<v8::Object> LoadablePluginPlaceholder::GetV8ScriptableObject(
v8::Isolate* isolate) const {
-#if defined(ENABLE_PLUGINS)
// Pass through JavaScript access to the underlying throttled plugin.
if (premade_throttler_ && premade_throttler_->GetWebPlugin()) {
return premade_throttler_->GetWebPlugin()->v8ScriptableObject(isolate);
}
-#endif
return v8::Local<v8::Object>();
}
-#if defined(ENABLE_PLUGINS)
void LoadablePluginPlaceholder::OnUnobscuredSizeUpdate(
const gfx::Size& unobscured_size) {
DCHECK(
@@ -304,7 +209,6 @@ void LoadablePluginPlaceholder::OnUnobscuredSizeUpdate(
size_update_timer_.Stop();
}
}
-#endif // defined(ENABLE_PLUGINS)
void LoadablePluginPlaceholder::WasShown() {
if (is_blocked_for_background_tab_) {
@@ -337,7 +241,7 @@ void LoadablePluginPlaceholder::OnSetIsPrerendering(bool is_prerendering) {
void LoadablePluginPlaceholder::LoadPlugin() {
// This is not strictly necessary but is an important defense in case the
// event propagation changes between "close" vs. "click-to-play".
- if (hidden_)
+ if (hidden())
return;
if (!plugin())
return;
@@ -357,19 +261,12 @@ void LoadablePluginPlaceholder::LoadPlugin() {
void LoadablePluginPlaceholder::LoadCallback() {
RenderThread::Get()->RecordAction(UserMetricsAction("Plugin_Load_Click"));
-#if defined(ENABLE_PLUGINS)
// If the user specifically clicks on the plugin content's placeholder,
// disable power saver throttling for this instance.
MarkPluginEssential(PluginInstanceThrottler::UNTHROTTLE_METHOD_BY_CLICK);
-#endif
LoadPlugin();
}
-void LoadablePluginPlaceholder::HideCallback() {
- RenderThread::Get()->RecordAction(UserMetricsAction("Plugin_Hide_Click"));
- HidePlugin();
-}
-
void LoadablePluginPlaceholder::DidFinishLoadingCallback() {
finished_loading_ = true;
if (message_.length() > 0)
@@ -384,7 +281,7 @@ void LoadablePluginPlaceholder::DidFinishLoadingCallback() {
// placeholder to be ready to receive simulated user input.
if (base::CommandLine::ForCurrentProcess()->HasSwitch(
switches::kEnablePluginPlaceholderTesting)) {
- WebElement element = plugin()->container()->element();
+ blink::WebElement element = plugin()->container()->element();
element.setAttribute("placeholderLoaded", "true");
scoped_ptr<content::V8ValueConverter> converter(
@@ -430,7 +327,6 @@ bool LoadablePluginPlaceholder::LoadingBlocked() const {
is_blocked_for_prerendering_;
}
-#if defined(ENABLE_PLUGINS)
void LoadablePluginPlaceholder::RecheckSizeAndMaybeUnthrottle() {
DCHECK(
content::RenderThread::Get()->GetTaskRunner()->BelongsToCurrentThread());
@@ -448,6 +344,5 @@ void LoadablePluginPlaceholder::RecheckSizeAndMaybeUnthrottle() {
in_size_recheck_ = false;
}
-#endif // defined(ENABLE_PLUGINS)
} // namespace plugins
diff --git a/components/plugins/renderer/loadable_plugin_placeholder.h b/components/plugins/renderer/loadable_plugin_placeholder.h
index 0111dff..13b903d 100644
--- a/components/plugins/renderer/loadable_plugin_placeholder.h
+++ b/components/plugins/renderer/loadable_plugin_placeholder.h
@@ -10,11 +10,12 @@
#include "components/plugins/renderer/plugin_placeholder.h"
#include "content/public/common/webplugininfo.h"
#include "content/public/renderer/plugin_instance_throttler.h"
+#include "content/public/renderer/render_thread.h"
namespace plugins {
// Placeholders can be used if a plugin is missing or not available
// (blocked or disabled).
-class LoadablePluginPlaceholder : public PluginPlaceholder {
+class LoadablePluginPlaceholder : public PluginPlaceholderBase {
public:
void set_blocked_for_background_tab(bool blocked_for_background_tab) {
is_blocked_for_background_tab_ = blocked_for_background_tab;
@@ -24,7 +25,6 @@ class LoadablePluginPlaceholder : public PluginPlaceholder {
is_blocked_for_prerendering_ = blocked_for_prerendering;
}
-#if defined(ENABLE_PLUGINS)
bool power_saver_enabled() const { return power_saver_enabled_; }
void set_power_saver_enabled(bool power_saver_enabled) {
@@ -36,23 +36,19 @@ class LoadablePluginPlaceholder : public PluginPlaceholder {
// When we load the plugin, use this already-created plugin, not a new one.
void SetPremadePlugin(content::PluginInstanceThrottler* throttler);
-#endif
- void set_allow_loading(bool allow_loading) { allow_loading_ = allow_loading; }
+ void DisallowLoading() { allow_loading_ = false; }
protected:
LoadablePluginPlaceholder(content::RenderFrame* render_frame,
blink::WebLocalFrame* frame,
const blink::WebPluginParams& params,
- const std::string& html_data,
- GURL placeholderDataUrl);
+ const std::string& html_data);
~LoadablePluginPlaceholder() override;
-#if defined(ENABLE_PLUGINS)
void MarkPluginEssential(
content::PluginInstanceThrottler::PowerSaverUnthrottleMethod method);
-#endif
void OnLoadBlockedPlugins(const std::string& identifier);
void OnSetIsPrerendering(bool is_prerendering);
@@ -68,42 +64,27 @@ class LoadablePluginPlaceholder : public PluginPlaceholder {
// a placeholder again).
void ReplacePlugin(blink::WebPlugin* new_plugin);
- // Hide this placeholder.
- void HidePlugin();
-
// Load the blocked plugin.
void LoadPlugin();
- // WebViewPlugin::Delegate (via PluginPlaceholder) method
- void BindWebFrame(blink::WebFrame* frame) override;
-
- // gin::Wrappable method:
- gin::ObjectTemplateBuilder GetObjectTemplateBuilder(
- v8::Isolate* isolate) override;
+ // Javascript callbacks:
+ void LoadCallback();
+ void DidFinishLoadingCallback();
private:
// WebViewPlugin::Delegate methods:
void PluginDestroyed() override;
v8::Local<v8::Object> GetV8ScriptableObject(
v8::Isolate* isolate) const override;
-#if defined(ENABLE_PLUGINS)
void OnUnobscuredSizeUpdate(const gfx::Size& unobscured_size) override;
-#endif
// RenderFrameObserver methods:
void WasShown() override;
- // Javascript callbacks:
- void LoadCallback();
- void HideCallback();
- void DidFinishLoadingCallback();
-
void UpdateMessage();
bool LoadingBlocked() const;
-#if defined(ENABLE_PLUGINS)
void RecheckSizeAndMaybeUnthrottle();
-#endif
// Plugin creation is embedder-specific.
virtual blink::WebPlugin* CreatePlugin() = 0;
@@ -132,7 +113,6 @@ class LoadablePluginPlaceholder : public PluginPlaceholder {
bool allow_loading_;
- bool hidden_;
bool finished_loading_;
std::string identifier_;
diff --git a/components/plugins/renderer/mobile_youtube_plugin.cc b/components/plugins/renderer/mobile_youtube_plugin.cc
index 6db102a..9745a0a 100644
--- a/components/plugins/renderer/mobile_youtube_plugin.cc
+++ b/components/plugins/renderer/mobile_youtube_plugin.cc
@@ -11,10 +11,8 @@
#include "base/values.h"
#include "content/public/common/content_constants.h"
#include "content/public/renderer/render_frame.h"
-#include "gin/handle.h"
#include "gin/object_template_builder.h"
#include "third_party/WebKit/public/web/WebFrame.h"
-#include "third_party/WebKit/public/web/WebKit.h"
#include "ui/base/webui/jstemplate_builder.h"
using blink::WebFrame;
@@ -73,16 +71,17 @@ bool IsValidYouTubeVideo(const std::string& path) {
namespace plugins {
+gin::WrapperInfo MobileYouTubePlugin::kWrapperInfo = {gin::kEmbedderNativeGin};
+
MobileYouTubePlugin::MobileYouTubePlugin(content::RenderFrame* render_frame,
blink::WebLocalFrame* frame,
const blink::WebPluginParams& params,
- base::StringPiece& template_html,
- GURL placeholderDataUrl)
- : PluginPlaceholder(render_frame,
- frame,
- params,
- HtmlData(params, template_html),
- placeholderDataUrl) {}
+ base::StringPiece& template_html)
+ : PluginPlaceholderBase(render_frame,
+ frame,
+ params,
+ HtmlData(params, template_html)) {
+}
MobileYouTubePlugin::~MobileYouTubePlugin() {}
@@ -108,22 +107,15 @@ void MobileYouTubePlugin::OpenYoutubeUrlCallback() {
GetFrame(), request, blink::WebNavigationPolicyNewForegroundTab);
}
-void MobileYouTubePlugin::BindWebFrame(WebFrame* frame) {
- v8::Isolate* isolate = blink::mainThreadIsolate();
- v8::HandleScope handle_scope(isolate);
- v8::Local<v8::Context> context = frame->mainWorldScriptContext();
- DCHECK(!context.IsEmpty());
-
- v8::Context::Scope context_scope(context);
- v8::Local<v8::Object> global = context->Global();
- global->Set(gin::StringToV8(isolate, "plugin"),
- gin::CreateHandle(isolate, this).ToV8());
+v8::Local<v8::Value> MobileYouTubePlugin::GetV8Handle(v8::Isolate* isolate) {
+ return gin::CreateHandle(isolate, this).ToV8();
}
gin::ObjectTemplateBuilder MobileYouTubePlugin::GetObjectTemplateBuilder(
v8::Isolate* isolate) {
- return PluginPlaceholder::GetObjectTemplateBuilder(isolate)
- .SetMethod("openYoutubeURL", &MobileYouTubePlugin::OpenYoutubeUrlCallback);
+ return gin::Wrappable<MobileYouTubePlugin>::GetObjectTemplateBuilder(isolate)
+ .SetMethod("openYoutubeURL",
+ &MobileYouTubePlugin::OpenYoutubeUrlCallback);
}
} // namespace plugins
diff --git a/components/plugins/renderer/mobile_youtube_plugin.h b/components/plugins/renderer/mobile_youtube_plugin.h
index 99a6213..9d46700 100644
--- a/components/plugins/renderer/mobile_youtube_plugin.h
+++ b/components/plugins/renderer/mobile_youtube_plugin.h
@@ -14,13 +14,15 @@ namespace plugins {
// of http://www.youtube.com/v/VIDEO_ID. This placeholder replaces the url with
// a simple html page and clicking the play image redirects the user to the
// mobile youtube app.
-class MobileYouTubePlugin : public PluginPlaceholder {
+class MobileYouTubePlugin final : public PluginPlaceholderBase,
+ public gin::Wrappable<MobileYouTubePlugin> {
public:
+ static gin::WrapperInfo kWrapperInfo;
+
MobileYouTubePlugin(content::RenderFrame* render_frame,
blink::WebLocalFrame* frame,
const blink::WebPluginParams& params,
- base::StringPiece& template_html,
- GURL placeholderDataUrl);
+ base::StringPiece& template_html);
// Whether this is a youtube url.
static bool IsYouTubeURL(const GURL& url, const std::string& mime_type);
@@ -31,12 +33,12 @@ class MobileYouTubePlugin : public PluginPlaceholder {
// Opens a youtube app in the current tab.
void OpenYoutubeUrlCallback();
- // WebViewPlugin::Delegate (via PluginPlaceholder) method
- void BindWebFrame(blink::WebFrame* frame) override;
+ // WebViewPlugin::Delegate methods:
+ v8::Local<v8::Value> GetV8Handle(v8::Isolate* isolate) override;
// gin::Wrappable (via PluginPlaceholder) method
gin::ObjectTemplateBuilder GetObjectTemplateBuilder(
- v8::Isolate* isolate) override;
+ v8::Isolate* isolate) final;
DISALLOW_COPY_AND_ASSIGN(MobileYouTubePlugin);
};
diff --git a/components/plugins/renderer/plugin_placeholder.cc b/components/plugins/renderer/plugin_placeholder.cc
index 180e913..98fc8cb 100644
--- a/components/plugins/renderer/plugin_placeholder.cc
+++ b/components/plugins/renderer/plugin_placeholder.cc
@@ -4,18 +4,26 @@
#include "components/plugins/renderer/plugin_placeholder.h"
+#include "base/strings/string_util.h"
#include "content/public/common/web_preferences.h"
#include "content/public/renderer/render_frame.h"
+#include "content/public/renderer/render_thread.h"
+#include "gin/object_template_builder.h"
+#include "third_party/WebKit/public/web/WebElement.h"
+#include "third_party/WebKit/public/web/WebPluginContainer.h"
+#include "third_party/re2/re2/re2.h"
namespace plugins {
-gin::WrapperInfo PluginPlaceholder::kWrapperInfo = {gin::kEmbedderNativeGin};
+// The placeholder is loaded in normal web renderer processes, so it should not
+// have a chrome:// scheme that might let it be confused with a WebUI page.
+const char kPluginPlaceholderDataURL[] = "data:text/html,pluginplaceholderdata";
-PluginPlaceholder::PluginPlaceholder(content::RenderFrame* render_frame,
- blink::WebLocalFrame* frame,
- const blink::WebPluginParams& params,
- const std::string& html_data,
- GURL placeholderDataUrl)
+PluginPlaceholderBase::PluginPlaceholderBase(
+ content::RenderFrame* render_frame,
+ blink::WebLocalFrame* frame,
+ const blink::WebPluginParams& params,
+ const std::string& html_data)
: content::RenderFrameObserver(render_frame),
frame_(frame),
plugin_params_(params),
@@ -24,36 +32,116 @@ PluginPlaceholder::PluginPlaceholder(content::RenderFrame* render_frame,
? render_frame->GetWebkitPreferences()
: content::WebPreferences(),
html_data,
- placeholderDataUrl)) {
- DCHECK(placeholderDataUrl.is_valid())
- << "Blink requires the placeholder to have a valid URL.";
+ GURL(kPluginPlaceholderDataURL))),
+ hidden_(false) {
}
-PluginPlaceholder::~PluginPlaceholder() {}
+PluginPlaceholderBase::~PluginPlaceholderBase() {
+}
-const blink::WebPluginParams& PluginPlaceholder::GetPluginParams() const {
+const blink::WebPluginParams& PluginPlaceholderBase::GetPluginParams() const {
return plugin_params_;
}
-void PluginPlaceholder::ShowContextMenu(const blink::WebMouseEvent& event) {
+void PluginPlaceholderBase::ShowContextMenu(const blink::WebMouseEvent& event) {
// Does nothing by default. Will be overridden if a specific browser wants
// a context menu.
return;
}
-void PluginPlaceholder::PluginDestroyed() {
+void PluginPlaceholderBase::PluginDestroyed() {
plugin_ = NULL;
}
-v8::Local<v8::Object> PluginPlaceholder::GetV8ScriptableObject(
+v8::Local<v8::Object> PluginPlaceholderBase::GetV8ScriptableObject(
v8::Isolate* isolate) const {
return v8::Local<v8::Object>();
}
-void PluginPlaceholder::OnDestruct() {
+void PluginPlaceholderBase::HidePlugin() {
+ hidden_ = true;
+ if (!plugin())
+ return;
+ blink::WebPluginContainer* container = plugin()->container();
+ blink::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 heuristic 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);
+ }
+ base::TrimWhitespace(width_str, base::TRIM_TRAILING, &width_str);
+ width_str += "[\\s]*px";
+ 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);
+ }
+ base::TrimWhitespace(height_str, base::TRIM_TRAILING, &height_str);
+ height_str += "[\\s]*px";
+ blink::WebNode parent = element;
+ while (!parent.parentNode().isNull()) {
+ parent = parent.parentNode();
+ if (!parent.isElementNode())
+ continue;
+ element = parent.toConst<blink::WebElement>();
+ if (element.hasAttribute("style")) {
+ std::string style_str = element.getAttribute("style").utf8();
+ if (RE2::PartialMatch(style_str, width_str) &&
+ RE2::PartialMatch(style_str, height_str))
+ element.setAttribute("style", "display: none;");
+ }
+ }
+ }
+}
+
+void PluginPlaceholderBase::HideCallback() {
+ content::RenderThread::Get()->RecordAction(
+ base::UserMetricsAction("Plugin_Hide_Click"));
+ HidePlugin();
+}
+
+void PluginPlaceholderBase::OnDestruct() {
frame_ = NULL;
}
-blink::WebLocalFrame* PluginPlaceholder::GetFrame() { return frame_; }
+blink::WebLocalFrame* PluginPlaceholderBase::GetFrame() {
+ return frame_;
+}
+
+// static
+gin::WrapperInfo PluginPlaceholder::kWrapperInfo = {gin::kEmbedderNativeGin};
+
+PluginPlaceholder::PluginPlaceholder(content::RenderFrame* render_frame,
+ blink::WebLocalFrame* frame,
+ const blink::WebPluginParams& params,
+ const std::string& html_data)
+ : PluginPlaceholderBase(render_frame, frame, params, html_data) {
+}
+
+PluginPlaceholder::~PluginPlaceholder() {
+}
+
+v8::Local<v8::Value> PluginPlaceholder::GetV8Handle(v8::Isolate* isolate) {
+ return gin::CreateHandle(isolate, this).ToV8();
+}
+
+gin::ObjectTemplateBuilder PluginPlaceholder::GetObjectTemplateBuilder(
+ v8::Isolate* isolate) {
+ return gin::Wrappable<PluginPlaceholder>::GetObjectTemplateBuilder(isolate)
+ .SetMethod<void (plugins::PluginPlaceholder::*)()>(
+ "hide", &PluginPlaceholder::HideCallback);
+}
} // namespace plugins
diff --git a/components/plugins/renderer/plugin_placeholder.h b/components/plugins/renderer/plugin_placeholder.h
index 5d9caa1..63a1d08 100644
--- a/components/plugins/renderer/plugin_placeholder.h
+++ b/components/plugins/renderer/plugin_placeholder.h
@@ -8,30 +8,29 @@
#include "base/memory/weak_ptr.h"
#include "components/plugins/renderer/webview_plugin.h"
#include "content/public/renderer/render_frame_observer.h"
+#include "gin/handle.h"
#include "gin/wrappable.h"
+#include "third_party/WebKit/public/web/WebKit.h"
#include "third_party/WebKit/public/web/WebPluginParams.h"
namespace plugins {
-class PluginPlaceholder : public content::RenderFrameObserver,
- public WebViewPlugin::Delegate,
- public gin::Wrappable<PluginPlaceholder> {
+// This abstract class is the base class of all plugin placeholders.
+class PluginPlaceholderBase : public content::RenderFrameObserver,
+ public WebViewPlugin::Delegate {
public:
- static gin::WrapperInfo kWrapperInfo;
-
- WebViewPlugin* plugin() { return plugin_; }
-
- protected:
// |render_frame| and |frame| are weak pointers. If either one is going away,
// our |plugin_| will be destroyed as well and will notify us.
- PluginPlaceholder(content::RenderFrame* render_frame,
- blink::WebLocalFrame* frame,
- const blink::WebPluginParams& params,
- const std::string& html_data,
- GURL placeholderDataUrl);
+ PluginPlaceholderBase(content::RenderFrame* render_frame,
+ blink::WebLocalFrame* frame,
+ const blink::WebPluginParams& params,
+ const std::string& html_data);
- ~PluginPlaceholder() override;
+ ~PluginPlaceholderBase() override;
+
+ WebViewPlugin* plugin() { return plugin_; }
+ protected:
blink::WebLocalFrame* GetFrame();
const blink::WebPluginParams& GetPluginParams() const;
@@ -41,6 +40,14 @@ class PluginPlaceholder : public content::RenderFrameObserver,
v8::Local<v8::Object> GetV8ScriptableObject(
v8::Isolate* isolate) const override;
+ protected:
+ // Hide this placeholder.
+ void HidePlugin();
+ bool hidden() { return hidden_; }
+
+ // JavaScript callbacks:
+ void HideCallback();
+
private:
// RenderFrameObserver methods:
void OnDestruct() override;
@@ -49,7 +56,30 @@ class PluginPlaceholder : public content::RenderFrameObserver,
blink::WebPluginParams plugin_params_;
WebViewPlugin* plugin_;
- DISALLOW_COPY_AND_ASSIGN(PluginPlaceholder);
+ bool hidden_;
+
+ DISALLOW_COPY_AND_ASSIGN(PluginPlaceholderBase);
+};
+
+// A basic placeholder that supports only hiding.
+class PluginPlaceholder final : public PluginPlaceholderBase,
+ public gin::Wrappable<PluginPlaceholder> {
+ public:
+ static gin::WrapperInfo kWrapperInfo;
+
+ PluginPlaceholder(content::RenderFrame* render_frame,
+ blink::WebLocalFrame* frame,
+ const blink::WebPluginParams& params,
+ const std::string& html_data);
+ ~PluginPlaceholder() override;
+
+ private:
+ // WebViewPlugin::Delegate methods:
+ v8::Local<v8::Value> GetV8Handle(v8::Isolate* isolate) final;
+
+ // gin::Wrappable method:
+ gin::ObjectTemplateBuilder GetObjectTemplateBuilder(
+ v8::Isolate* isolate) override;
};
} // namespace plugins
diff --git a/components/plugins/renderer/webview_plugin.cc b/components/plugins/renderer/webview_plugin.cc
index 43cd43e..0779566 100644
--- a/components/plugins/renderer/webview_plugin.cc
+++ b/components/plugins/renderer/webview_plugin.cc
@@ -9,6 +9,7 @@
#include "base/numerics/safe_conversions.h"
#include "content/public/common/web_preferences.h"
#include "content/public/renderer/render_view.h"
+#include "gin/converter.h"
#include "skia/ext/platform_canvas.h"
#include "third_party/WebKit/public/platform/WebSize.h"
#include "third_party/WebKit/public/platform/WebURL.h"
@@ -61,6 +62,7 @@ WebViewPlugin* WebViewPlugin::Create(WebViewPlugin::Delegate* delegate,
const WebPreferences& preferences,
const std::string& html_data,
const GURL& url) {
+ DCHECK(url.is_valid()) << "Blink requires the WebView to have a valid URL.";
WebViewPlugin* plugin = new WebViewPlugin(delegate, preferences);
plugin->web_view()->mainFrame()->loadHTMLString(html_data, url);
return plugin;
@@ -264,8 +266,19 @@ void WebViewPlugin::scheduleAnimation() {
}
void WebViewPlugin::didClearWindowObject(WebLocalFrame* frame) {
- if (delegate_)
- delegate_->BindWebFrame(frame);
+ if (!delegate_)
+ return;
+
+ v8::Isolate* isolate = blink::mainThreadIsolate();
+ v8::HandleScope handle_scope(isolate);
+ v8::Local<v8::Context> context = frame->mainWorldScriptContext();
+ DCHECK(!context.IsEmpty());
+
+ v8::Context::Scope context_scope(context);
+ v8::Local<v8::Object> global = context->Global();
+
+ global->Set(gin::StringToV8(isolate, "plugin"),
+ delegate_->GetV8Handle(isolate));
}
void WebViewPlugin::didReceiveResponse(WebLocalFrame* frame,
diff --git a/components/plugins/renderer/webview_plugin.h b/components/plugins/renderer/webview_plugin.h
index 3286fae..fdb9777 100644
--- a/components/plugins/renderer/webview_plugin.h
+++ b/components/plugins/renderer/webview_plugin.h
@@ -13,6 +13,7 @@
#include "third_party/WebKit/public/platform/WebString.h"
#include "third_party/WebKit/public/platform/WebURLResponse.h"
#include "third_party/WebKit/public/web/WebFrameClient.h"
+#include "third_party/WebKit/public/web/WebKit.h"
#include "third_party/WebKit/public/web/WebPlugin.h"
#include "third_party/WebKit/public/web/WebViewClient.h"
@@ -42,10 +43,8 @@ class WebViewPlugin : public blink::WebPlugin,
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(blink::WebFrame* frame) = 0;
+ // Called to get the V8 handle used to bind the lifetime to the frame.
+ virtual v8::Local<v8::Value> GetV8Handle(v8::Isolate*) = 0;
// Called upon a context menu event.
virtual void ShowContextMenu(const blink::WebMouseEvent&) = 0;