123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170 |
- // Copyright 2013 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 "components/plugins/renderer/plugin_placeholder.h"
- #include "base/metrics/user_metrics_action.h"
- #include "base/strings/string_util.h"
- #include "content/public/renderer/render_frame.h"
- #include "content/public/renderer/render_thread.h"
- #include "content/public/renderer/v8_value_converter.h"
- #include "gin/object_template_builder.h"
- #include "third_party/blink/public/common/web_preferences/web_preferences.h"
- #include "third_party/blink/public/web/blink.h"
- #include "third_party/blink/public/web/web_dom_message_event.h"
- #include "third_party/blink/public/web/web_element.h"
- #include "third_party/blink/public/web/web_local_frame.h"
- #include "third_party/blink/public/web/web_plugin_container.h"
- #include "third_party/blink/public/web/web_script_source.h"
- #include "third_party/blink/public/web/web_serialized_script_value.h"
- #include "third_party/re2/src/re2/re2.h"
- namespace plugins {
- // 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";
- PluginPlaceholderBase::PluginPlaceholderBase(
- content::RenderFrame* render_frame,
- const blink::WebPluginParams& params,
- const std::string& html_data)
- : content::RenderFrameObserver(render_frame),
- plugin_params_(params),
- plugin_(WebViewPlugin::Create(render_frame->GetWebFrame()->View(),
- this,
- render_frame
- ? render_frame->GetBlinkPreferences()
- : blink::web_pref::WebPreferences(),
- html_data,
- GURL(kPluginPlaceholderDataURL))),
- hidden_(false) {}
- PluginPlaceholderBase::~PluginPlaceholderBase() {
- }
- const blink::WebPluginParams& PluginPlaceholderBase::GetPluginParams() const {
- return plugin_params_;
- }
- void PluginPlaceholderBase::ShowContextMenu(const blink::WebMouseEvent& event) {
- // Does nothing by default. Will be overridden if a specific browser wants
- // a context menu.
- return;
- }
- void PluginPlaceholderBase::PluginDestroyed() {
- plugin_ = nullptr;
- }
- v8::Local<v8::Object> PluginPlaceholderBase::GetV8ScriptableObject(
- v8::Isolate* isolate) const {
- return v8::Local<v8::Object>();
- }
- void PluginPlaceholderBase::HidePlugin() {
- hidden_ = true;
- if (!plugin())
- return;
- blink::WebPluginContainer* container = plugin()->Container();
- blink::WebElement element = container->GetElement();
- 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();
- if (base::EndsWith(width_str, "px", base::CompareCase::INSENSITIVE_ASCII)) {
- width_str = width_str.substr(0, width_str.length() - 2);
- }
- base::TrimWhitespaceASCII(width_str, base::TRIM_TRAILING, &width_str);
- width_str += "[\\s]*px";
- std::string height_str("height:[\\s]*");
- height_str += element.GetAttribute("height").Utf8();
- if (base::EndsWith(height_str, "px",
- base::CompareCase::INSENSITIVE_ASCII)) {
- height_str = height_str.substr(0, height_str.length() - 2);
- }
- base::TrimWhitespaceASCII(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.To<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::NotifyPlaceholderReadyForTestingCallback() {
- if (!plugin())
- return;
- // Set an attribute and post an event, so browser tests can wait for the
- // placeholder to be ready to receive simulated user input.
- blink::WebElement element = plugin()->Container()->GetElement();
- element.SetAttribute("placeholderReady", "true");
- base::Value value("placeholderReady");
- blink::WebSerializedScriptValue message_data =
- blink::WebSerializedScriptValue::Serialize(
- blink::MainThreadIsolate(),
- content::V8ValueConverter::Create()->ToV8Value(
- value,
- element.GetDocument().GetFrame()->MainWorldScriptContext()));
- blink::WebDOMMessageEvent msg_event(message_data);
- plugin()->Container()->EnqueueMessageEvent(msg_event);
- }
- void PluginPlaceholderBase::OnDestruct() {}
- // static
- gin::WrapperInfo PluginPlaceholder::kWrapperInfo = {gin::kEmbedderNativeGin};
- PluginPlaceholder::PluginPlaceholder(content::RenderFrame* render_frame,
- const blink::WebPluginParams& params,
- const std::string& html_data)
- : PluginPlaceholderBase(render_frame, params, html_data) {}
- PluginPlaceholder::~PluginPlaceholder() {
- }
- v8::Local<v8::Value> PluginPlaceholder::GetV8Handle(v8::Isolate* isolate) {
- return gin::CreateHandle(isolate, this).ToV8();
- }
- bool PluginPlaceholderBase::IsErrorPlaceholder() {
- return false;
- }
- gin::ObjectTemplateBuilder PluginPlaceholder::GetObjectTemplateBuilder(
- v8::Isolate* isolate) {
- return gin::Wrappable<PluginPlaceholder>::GetObjectTemplateBuilder(isolate)
- .SetMethod<void (plugins::PluginPlaceholder::*)()>(
- "hide", &PluginPlaceholder::HideCallback);
- }
- } // namespace plugins
|