Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "components/plugins/renderer/plugin_placeholder.h" | 5 #include "components/plugins/renderer/plugin_placeholder.h" |
| 6 | 6 |
| 7 #include "base/strings/string_util.h" | |
| 7 #include "content/public/renderer/render_frame.h" | 8 #include "content/public/renderer/render_frame.h" |
| 9 #include "content/public/renderer/render_thread.h" | |
| 10 #include "gin/object_template_builder.h" | |
| 11 #include "third_party/WebKit/public/web/WebElement.h" | |
| 12 #include "third_party/WebKit/public/web/WebPluginContainer.h" | |
| 13 #include "third_party/re2/re2/re2.h" | |
| 8 | 14 |
| 9 namespace plugins { | 15 namespace plugins { |
| 10 | 16 |
| 17 namespace { | |
|
Bernhard Bauer
2015/05/16 00:22:21
Nit: The anonymous namespace isn't necessary here,
tommycli
2015/05/18 21:12:42
Done.
| |
| 18 // The placeholder is loaded in normal web renderer processes, so it should not | |
| 19 // have a chrome:// scheme that might let it be confused with a WebUI page. | |
| 20 const char kPluginPlaceholderDataURL[] = "data:text/html,pluginplaceholderdata"; | |
| 21 } // namespace | |
| 22 | |
| 11 gin::WrapperInfo PluginPlaceholder::kWrapperInfo = {gin::kEmbedderNativeGin}; | 23 gin::WrapperInfo PluginPlaceholder::kWrapperInfo = {gin::kEmbedderNativeGin}; |
| 12 | 24 |
| 13 PluginPlaceholder::PluginPlaceholder(content::RenderFrame* render_frame, | 25 PluginPlaceholder::PluginPlaceholder(content::RenderFrame* render_frame, |
| 14 blink::WebLocalFrame* frame, | 26 blink::WebLocalFrame* frame, |
| 15 const blink::WebPluginParams& params, | 27 const blink::WebPluginParams& params, |
| 16 const std::string& html_data, | 28 const std::string& html_data) |
| 17 GURL placeholderDataUrl) | |
| 18 : content::RenderFrameObserver(render_frame), | 29 : content::RenderFrameObserver(render_frame), |
| 19 frame_(frame), | 30 frame_(frame), |
| 20 plugin_params_(params), | 31 plugin_params_(params), |
| 21 plugin_(WebViewPlugin::Create(this, | 32 plugin_(WebViewPlugin::Create(this, |
| 22 render_frame->GetWebkitPreferences(), | 33 render_frame->GetWebkitPreferences(), |
| 23 html_data, | 34 html_data, |
| 24 placeholderDataUrl)) { | 35 GURL(kPluginPlaceholderDataURL))), |
| 25 DCHECK(placeholderDataUrl.is_valid()) | 36 hidden_(false) { |
| 26 << "Blink requires the placeholder to have a valid URL."; | |
| 27 } | 37 } |
| 28 | 38 |
| 29 PluginPlaceholder::~PluginPlaceholder() {} | 39 PluginPlaceholder::~PluginPlaceholder() {} |
| 30 | 40 |
| 31 const blink::WebPluginParams& PluginPlaceholder::GetPluginParams() const { | 41 const blink::WebPluginParams& PluginPlaceholder::GetPluginParams() const { |
| 32 return plugin_params_; | 42 return plugin_params_; |
| 33 } | 43 } |
| 34 | 44 |
| 45 void PluginPlaceholder::BindWebFrame(blink::WebFrame* frame) { | |
| 46 v8::Isolate* isolate = blink::mainThreadIsolate(); | |
| 47 v8::HandleScope handle_scope(isolate); | |
| 48 v8::Local<v8::Context> context = frame->mainWorldScriptContext(); | |
| 49 DCHECK(!context.IsEmpty()); | |
| 50 | |
| 51 v8::Context::Scope context_scope(context); | |
| 52 v8::Local<v8::Object> global = context->Global(); | |
| 53 global->Set(gin::StringToV8(isolate, "plugin"), | |
| 54 gin::CreateHandle(isolate, this).ToV8()); | |
| 55 } | |
| 56 | |
| 35 void PluginPlaceholder::ShowContextMenu(const blink::WebMouseEvent& event) { | 57 void PluginPlaceholder::ShowContextMenu(const blink::WebMouseEvent& event) { |
| 36 // Does nothing by default. Will be overridden if a specific browser wants | 58 // Does nothing by default. Will be overridden if a specific browser wants |
| 37 // a context menu. | 59 // a context menu. |
| 38 return; | 60 return; |
| 39 } | 61 } |
| 40 | 62 |
| 41 void PluginPlaceholder::PluginDestroyed() { | 63 void PluginPlaceholder::PluginDestroyed() { |
| 42 plugin_ = NULL; | 64 plugin_ = NULL; |
| 43 } | 65 } |
| 44 | 66 |
| 45 v8::Local<v8::Object> PluginPlaceholder::GetV8ScriptableObject( | 67 v8::Local<v8::Object> PluginPlaceholder::GetV8ScriptableObject( |
| 46 v8::Isolate* isolate) const { | 68 v8::Isolate* isolate) const { |
| 47 return v8::Local<v8::Object>(); | 69 return v8::Local<v8::Object>(); |
| 48 } | 70 } |
| 49 | 71 |
| 72 gin::ObjectTemplateBuilder PluginPlaceholder::GetObjectTemplateBuilder( | |
| 73 v8::Isolate* isolate) { | |
| 74 return gin::Wrappable<PluginPlaceholder>::GetObjectTemplateBuilder(isolate) | |
| 75 .SetMethod("hide", &PluginPlaceholder::HideCallback); | |
| 76 } | |
| 77 | |
| 78 void PluginPlaceholder::HidePlugin() { | |
| 79 hidden_ = true; | |
| 80 if (!plugin()) | |
| 81 return; | |
| 82 blink::WebPluginContainer* container = plugin()->container(); | |
| 83 blink::WebElement element = container->element(); | |
| 84 element.setAttribute("style", "display: none;"); | |
| 85 // If we have a width and height, search for a parent (often <div>) with the | |
| 86 // same dimensions. If we find such a parent, hide that as well. | |
| 87 // This makes much more uncovered page content usable (including clickable) | |
| 88 // as opposed to merely visible. | |
| 89 // TODO(cevans) -- it's a foul heuristic but we're going to tolerate it for | |
| 90 // now for these reasons: | |
| 91 // 1) Makes the user experience better. | |
| 92 // 2) Foulness is encapsulated within this single function. | |
| 93 // 3) Confidence in no fasle positives. | |
| 94 // 4) Seems to have a good / low false negative rate at this time. | |
| 95 if (element.hasAttribute("width") && element.hasAttribute("height")) { | |
| 96 std::string width_str("width:[\\s]*"); | |
| 97 width_str += element.getAttribute("width").utf8().data(); | |
| 98 if (EndsWith(width_str, "px", false)) { | |
| 99 width_str = width_str.substr(0, width_str.length() - 2); | |
| 100 } | |
| 101 base::TrimWhitespace(width_str, base::TRIM_TRAILING, &width_str); | |
| 102 width_str += "[\\s]*px"; | |
| 103 std::string height_str("height:[\\s]*"); | |
| 104 height_str += element.getAttribute("height").utf8().data(); | |
| 105 if (EndsWith(height_str, "px", false)) { | |
| 106 height_str = height_str.substr(0, height_str.length() - 2); | |
| 107 } | |
| 108 base::TrimWhitespace(height_str, base::TRIM_TRAILING, &height_str); | |
| 109 height_str += "[\\s]*px"; | |
| 110 blink::WebNode parent = element; | |
| 111 while (!parent.parentNode().isNull()) { | |
| 112 parent = parent.parentNode(); | |
| 113 if (!parent.isElementNode()) | |
| 114 continue; | |
| 115 element = parent.toConst<blink::WebElement>(); | |
| 116 if (element.hasAttribute("style")) { | |
| 117 std::string style_str = element.getAttribute("style").utf8(); | |
| 118 if (RE2::PartialMatch(style_str, width_str) && | |
| 119 RE2::PartialMatch(style_str, height_str)) | |
| 120 element.setAttribute("style", "display: none;"); | |
| 121 } | |
| 122 } | |
| 123 } | |
| 124 } | |
| 125 | |
| 50 void PluginPlaceholder::OnDestruct() { | 126 void PluginPlaceholder::OnDestruct() { |
| 51 frame_ = NULL; | 127 frame_ = NULL; |
| 52 } | 128 } |
| 53 | 129 |
| 130 void PluginPlaceholder::HideCallback() { | |
| 131 content::RenderThread::Get()->RecordAction( | |
| 132 base::UserMetricsAction("Plugin_Hide_Click")); | |
| 133 HidePlugin(); | |
| 134 } | |
| 135 | |
| 54 blink::WebLocalFrame* PluginPlaceholder::GetFrame() { return frame_; } | 136 blink::WebLocalFrame* PluginPlaceholder::GetFrame() { return frame_; } |
| 55 | 137 |
| 56 } // namespace plugins | 138 } // namespace plugins |
| OLD | NEW |