diff options
27 files changed, 455 insertions, 479 deletions
diff --git a/chrome/chrome_renderer.gypi b/chrome/chrome_renderer.gypi index 2945b6a..73b86fe 100644 --- a/chrome/chrome_renderer.gypi +++ b/chrome/chrome_renderer.gypi @@ -36,8 +36,8 @@ 'renderer/net_benchmarking_extension.h', 'renderer/page_load_histograms.cc', 'renderer/page_load_histograms.h', - 'renderer/plugins/chrome_plugin_placeholder.cc', - 'renderer/plugins/chrome_plugin_placeholder.h', + 'renderer/plugins/non_loadable_plugin_placeholder.cc', + 'renderer/plugins/non_loadable_plugin_placeholder.h', 'renderer/plugins/plugin_uma.cc', 'renderer/plugins/plugin_uma.h', 'renderer/plugins/shadow_dom_plugin_placeholder.cc', @@ -182,6 +182,8 @@ 'renderer/pepper/pepper_shared_memory_message_filter.h', 'renderer/pepper/pepper_uma_host.cc', 'renderer/pepper/pepper_uma_host.h', + 'renderer/plugins/chrome_plugin_placeholder.cc', + 'renderer/plugins/chrome_plugin_placeholder.h', 'renderer/plugins/plugin_preroller.cc', 'renderer/plugins/plugin_preroller.h', ], diff --git a/chrome/renderer/chrome_content_renderer_client.cc b/chrome/renderer/chrome_content_renderer_client.cc index 59de107..258817d 100644 --- a/chrome/renderer/chrome_content_renderer_client.cc +++ b/chrome/renderer/chrome_content_renderer_client.cc @@ -40,7 +40,7 @@ #include "chrome/renderer/net_benchmarking_extension.h" #include "chrome/renderer/page_load_histograms.h" #include "chrome/renderer/pepper/pepper_helper.h" -#include "chrome/renderer/plugins/chrome_plugin_placeholder.h" +#include "chrome/renderer/plugins/non_loadable_plugin_placeholder.h" #include "chrome/renderer/plugins/plugin_preroller.h" #include "chrome/renderer/plugins/plugin_uma.h" #include "chrome/renderer/plugins/shadow_dom_plugin_placeholder.h" @@ -132,6 +132,10 @@ #include "chrome/common/external_ipc_dumper.h" #endif +#if defined(ENABLE_PLUGINS) +#include "chrome/renderer/plugins/chrome_plugin_placeholder.h" +#endif + #if defined(ENABLE_PRINTING) #include "chrome/renderer/printing/chrome_print_web_view_helper_delegate.h" #include "components/printing/renderer/print_web_view_helper.h" @@ -196,6 +200,7 @@ const char* const kPredefinedAllowedCompositorOrigins[] = { }; #endif +#if defined(ENABLE_PLUGINS) void AppendParams(const std::vector<base::string16>& additional_names, const std::vector<base::string16>& additional_values, WebVector<WebString>* existing_names, @@ -223,26 +228,6 @@ void AppendParams(const std::vector<base::string16>& additional_names, existing_values->swap(values); } -#if defined(ENABLE_SPELLCHECK) -class SpellCheckReplacer : public content::RenderViewVisitor { - public: - explicit SpellCheckReplacer(SpellCheck* spellcheck) - : spellcheck_(spellcheck) {} - bool Visit(content::RenderView* render_view) override; - - private: - SpellCheck* spellcheck_; // New shared spellcheck for all views. Weak Ptr. - DISALLOW_COPY_AND_ASSIGN(SpellCheckReplacer); -}; - -bool SpellCheckReplacer::Visit(content::RenderView* render_view) { - SpellCheckProvider* provider = SpellCheckProvider::Get(render_view); - DCHECK(provider); - provider->set_spellcheck(spellcheck_); - return true; -} -#endif - // For certain sandboxed Pepper plugins, use the JavaScript Content Settings. bool ShouldUseJavaScriptSettingForPlugin(const WebPluginInfo& plugin) { if (plugin.type != WebPluginInfo::PLUGIN_TYPE_PEPPER_IN_PROCESS && @@ -266,6 +251,27 @@ bool ShouldUseJavaScriptSettingForPlugin(const WebPluginInfo& plugin) { return false; } +#endif // defined(ENABLE_PLUGINS) + +#if defined(ENABLE_SPELLCHECK) +class SpellCheckReplacer : public content::RenderViewVisitor { + public: + explicit SpellCheckReplacer(SpellCheck* spellcheck) + : spellcheck_(spellcheck) {} + bool Visit(content::RenderView* render_view) override; + + private: + SpellCheck* spellcheck_; // New shared spellcheck for all views. Weak Ptr. + DISALLOW_COPY_AND_ASSIGN(SpellCheckReplacer); +}; + +bool SpellCheckReplacer::Visit(content::RenderView* render_view) { + SpellCheckProvider* provider = SpellCheckProvider::Get(render_view); + DCHECK(provider); + provider->set_spellcheck(spellcheck_); + return true; +} +#endif #if defined(ENABLE_EXTENSIONS) void IsGuestViewApiAvailableToScriptContext( @@ -650,25 +656,39 @@ bool ChromeContentRendererClient::OverrideCreatePlugin( } #endif - ChromeViewHostMsg_GetPluginInfo_Output output; + GURL url(params.url); #if defined(ENABLE_PLUGINS) + ChromeViewHostMsg_GetPluginInfo_Output output; render_frame->Send(new ChromeViewHostMsg_GetPluginInfo( - render_frame->GetRoutingID(), GURL(params.url), - frame->top()->document().url(), orig_mime_type, &output)); - -#else - output.status = ChromeViewHostMsg_GetPluginInfo_Status::kNotFound; -#endif + render_frame->GetRoutingID(), url, frame->top()->document().url(), + orig_mime_type, &output)); *plugin = CreatePlugin(render_frame, frame, params, output); +#else // !defined(ENABLE_PLUGINS) + +#if defined(OS_ANDROID) + if (plugins::MobileYouTubePlugin::IsYouTubeURL(url, orig_mime_type)) { + base::StringPiece template_html( + ResourceBundle::GetSharedInstance().GetRawDataResource( + IDR_MOBILE_YOUTUBE_PLUGIN_HTML)); + *plugin = (new plugins::MobileYouTubePlugin(render_frame, frame, params, + template_html))->plugin(); + return true; + } +#endif // defined(OS_ANDROID) + + PluginUMAReporter::GetInstance()->ReportPluginMissing(orig_mime_type, url); + *plugin = NonLoadablePluginPlaceholder::CreateNotSupportedPlugin( + render_frame, frame, params)->plugin(); + +#endif // defined(ENABLE_PLUGINS) return true; } WebPlugin* ChromeContentRendererClient::CreatePluginReplacement( content::RenderFrame* render_frame, const base::FilePath& plugin_path) { - ChromePluginPlaceholder* placeholder = - ChromePluginPlaceholder::CreateErrorPlugin(render_frame, plugin_path); - return placeholder->plugin(); + return NonLoadablePluginPlaceholder::CreateErrorPlugin(render_frame, + plugin_path)->plugin(); } void ChromeContentRendererClient::DeferMediaLoad( @@ -689,6 +709,7 @@ void ChromeContentRendererClient::DeferMediaLoad( #endif } +#if defined(ENABLE_PLUGINS) WebPlugin* ChromeContentRendererClient::CreatePlugin( content::RenderFrame* render_frame, blink::WebLocalFrame* frame, @@ -708,22 +729,8 @@ WebPlugin* ChromeContentRendererClient::CreatePlugin( // OverrideCreatePlugin. if (status == ChromeViewHostMsg_GetPluginInfo_Status::kNotFound || orig_mime_type == content::kBrowserPluginMimeType) { -#if defined(OS_ANDROID) - if (plugins::MobileYouTubePlugin::IsYouTubeURL(url, orig_mime_type)) { - base::StringPiece template_html( - ResourceBundle::GetSharedInstance().GetRawDataResource( - IDR_MOBILE_YOUTUBE_PLUGIN_HTML)); - return (new plugins::MobileYouTubePlugin( - render_frame, - frame, - original_params, - template_html, - GURL(ChromePluginPlaceholder::kPluginPlaceholderDataURL))) - ->plugin(); - } -#endif PluginUMAReporter::GetInstance()->ReportPluginMissing(orig_mime_type, url); - placeholder = ChromePluginPlaceholder::CreateMissingPlugin( + placeholder = ChromePluginPlaceholder::CreateLoadableMissingPlugin( render_frame, frame, original_params); } else { // TODO(bauerb): This should be in content/. @@ -846,7 +853,6 @@ WebPlugin* ChromeContentRendererClient::CreatePlugin( } #endif // !defined(DISABLE_NACL) && defined(ENABLE_EXTENSIONS) -#if defined(ENABLE_PLUGINS) // Delay loading plugins if prerendering. // TODO(mmenke): In the case of prerendering, feed into // ChromeContentRendererClient::CreatePlugin instead, to @@ -881,7 +887,6 @@ WebPlugin* ChromeContentRendererClient::CreatePlugin( blocked_for_background_tab); placeholder->set_blocked_for_prerendering(is_prerendering); placeholder->set_power_saver_enabled(power_saver_enabled); - placeholder->set_allow_loading(true); break; } @@ -897,9 +902,6 @@ WebPlugin* ChromeContentRendererClient::CreatePlugin( return render_frame->CreatePlugin(frame, info, params, throttler.Pass()); -#else // !defined(ENABLE_PLUGINS) - return render_frame->CreatePlugin(frame, info, params, nullptr); -#endif // defined(ENABLE_PLUGINS) } case ChromeViewHostMsg_GetPluginInfo_Status::kNPAPINotSupported: { RenderThread::Get()->RecordAction( @@ -924,7 +926,6 @@ WebPlugin* ChromeContentRendererClient::CreatePlugin( placeholder = create_blocked_plugin( IDR_BLOCKED_PLUGIN_HTML, l10n_util::GetStringFUTF16(IDS_PLUGIN_OUTDATED, group_name)); - placeholder->set_allow_loading(true); render_frame->Send(new ChromeViewHostMsg_BlockedOutdatedPlugin( render_frame->GetRoutingID(), placeholder->CreateRoutingId(), identifier)); @@ -943,7 +944,6 @@ WebPlugin* ChromeContentRendererClient::CreatePlugin( placeholder = create_blocked_plugin( IDR_BLOCKED_PLUGIN_HTML, l10n_util::GetStringFUTF16(IDS_PLUGIN_NOT_AUTHORIZED, group_name)); - placeholder->set_allow_loading(true); if (info.type != content::WebPluginInfo::PLUGIN_TYPE_NPAPI) { render_frame->Send(new ChromeViewHostMsg_BlockedUnauthorizedPlugin( render_frame->GetRoutingID(), @@ -957,7 +957,6 @@ WebPlugin* ChromeContentRendererClient::CreatePlugin( placeholder = create_blocked_plugin( IDR_BLOCKED_PLUGIN_HTML, l10n_util::GetStringFUTF16(IDS_PLUGIN_BLOCKED, group_name)); - placeholder->set_allow_loading(true); RenderThread::Get()->RecordAction(UserMetricsAction("Plugin_Blocked")); observer->DidBlockContentType(content_type, group_name); break; @@ -967,7 +966,7 @@ WebPlugin* ChromeContentRendererClient::CreatePlugin( IDR_BLOCKED_PLUGIN_HTML, l10n_util::GetStringFUTF16(IDS_PLUGIN_BLOCKED_BY_POLICY, group_name)); - placeholder->set_allow_loading(false); + placeholder->DisallowLoading(); RenderThread::Get()->RecordAction( UserMetricsAction("Plugin_BlockedByPolicy")); observer->DidBlockContentType(content_type, group_name); @@ -978,6 +977,7 @@ WebPlugin* ChromeContentRendererClient::CreatePlugin( placeholder->SetStatus(status); return placeholder->plugin(); } +#endif // defined(ENABLE_PLUGINS) // For NaCl content handling plugins, the NaCl manifest is stored in an // additonal 'nacl' param associated with the MIME type. diff --git a/chrome/renderer/chrome_content_renderer_client.h b/chrome/renderer/chrome_content_renderer_client.h index 952e879..93fe153 100644 --- a/chrome/renderer/chrome_content_renderer_client.h +++ b/chrome/renderer/chrome_content_renderer_client.h @@ -168,11 +168,13 @@ class ChromeContentRendererClient : public content::ContentRendererClient { void SetSpellcheck(SpellCheck* spellcheck); #endif +#if defined(ENABLE_PLUGINS) static blink::WebPlugin* CreatePlugin( content::RenderFrame* render_frame, blink::WebLocalFrame* frame, const blink::WebPluginParams& params, const ChromeViewHostMsg_GetPluginInfo_Output& output); +#endif #if defined(ENABLE_PLUGINS) && defined(ENABLE_EXTENSIONS) static bool IsExtensionOrSharedModuleWhitelisted( diff --git a/chrome/renderer/plugins/chrome_plugin_placeholder.cc b/chrome/renderer/plugins/chrome_plugin_placeholder.cc index 402bfb6..165eebb 100644 --- a/chrome/renderer/plugins/chrome_plugin_placeholder.cc +++ b/chrome/renderer/plugins/chrome_plugin_placeholder.cc @@ -16,7 +16,6 @@ #include "chrome/renderer/plugins/plugin_preroller.h" #include "chrome/renderer/plugins/plugin_uma.h" #include "components/content_settings/content/common/content_settings_messages.h" -#include "content/app/strings/grit/content_strings.h" #include "content/public/common/context_menu_params.h" #include "content/public/renderer/render_frame.h" #include "content/public/renderer/render_thread.h" @@ -45,13 +44,11 @@ using content::RenderThread; using content::RenderView; namespace { -const plugins::PluginPlaceholder* g_last_active_menu = NULL; +const ChromePluginPlaceholder* g_last_active_menu = NULL; } // namespace -// 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 ChromePluginPlaceholder::kPluginPlaceholderDataURL[] = - "data:text/html,pluginplaceholderdata"; +gin::WrapperInfo ChromePluginPlaceholder::kWrapperInfo = { + gin::kEmbedderNativeGin}; ChromePluginPlaceholder::ChromePluginPlaceholder( content::RenderFrame* render_frame, @@ -62,8 +59,7 @@ ChromePluginPlaceholder::ChromePluginPlaceholder( : plugins::LoadablePluginPlaceholder(render_frame, frame, params, - html_data, - GURL(kPluginPlaceholderDataURL)), + html_data), status_(ChromeViewHostMsg_GetPluginInfo_Status::kAllowed), title_(title), #if defined(ENABLE_PLUGIN_INSTALLATION) @@ -91,7 +87,7 @@ ChromePluginPlaceholder::~ChromePluginPlaceholder() { } // static -ChromePluginPlaceholder* ChromePluginPlaceholder::CreateMissingPlugin( +ChromePluginPlaceholder* ChromePluginPlaceholder::CreateLoadableMissingPlugin( content::RenderFrame* render_frame, WebLocalFrame* frame, const WebPluginParams& params) { @@ -105,34 +101,9 @@ ChromePluginPlaceholder* ChromePluginPlaceholder::CreateMissingPlugin( std::string html_data = webui::GetI18nTemplateHtml(template_html, &values); - // |missing_plugin| will destroy itself when its WebViewPlugin is going away. - ChromePluginPlaceholder* missing_plugin = new ChromePluginPlaceholder( - render_frame, frame, params, html_data, params.mimeType); - missing_plugin->set_allow_loading(true); - return missing_plugin; -} - -// static -ChromePluginPlaceholder* ChromePluginPlaceholder::CreateErrorPlugin( - content::RenderFrame* render_frame, - const base::FilePath& file_path) { - base::DictionaryValue values; - values.SetString("message", - l10n_util::GetStringUTF8(IDS_PLUGIN_INITIALIZATION_ERROR)); - - const base::StringPiece template_html( - ResourceBundle::GetSharedInstance().GetRawDataResource( - IDR_BLOCKED_PLUGIN_HTML)); - std::string html_data = webui::GetI18nTemplateHtml(template_html, &values); - - WebPluginParams params; - // |missing_plugin| will destroy itself when its WebViewPlugin is going away. - ChromePluginPlaceholder* plugin = new ChromePluginPlaceholder( - render_frame, NULL, params, html_data, params.mimeType); - - RenderThread::Get()->Send(new ChromeViewHostMsg_CouldNotLoadPlugin( - plugin->routing_id(), file_path)); - return plugin; + // Will destroy itself when its WebViewPlugin is going away. + return new ChromePluginPlaceholder(render_frame, frame, params, html_data, + params.mimeType); } // static @@ -176,10 +147,8 @@ ChromePluginPlaceholder* ChromePluginPlaceholder::CreateBlockedPlugin( ChromePluginPlaceholder* blocked_plugin = new ChromePluginPlaceholder( render_frame, frame, params, html_data, name); -#if defined(ENABLE_PLUGINS) if (!poster_info.poster_attribute.empty()) blocked_plugin->BlockForPowerSaverPoster(); -#endif blocked_plugin->SetPluginInfo(info); blocked_plugin->SetIdentifier(identifier); return blocked_plugin; @@ -305,10 +274,8 @@ void ChromePluginPlaceholder::OnMenuAction(int request_id, unsigned action) { switch (action) { case chrome::MENU_COMMAND_PLUGIN_RUN: { RenderThread::Get()->RecordAction(UserMetricsAction("Plugin_Load_Menu")); -#if defined(ENABLE_PLUGINS) MarkPluginEssential( content::PluginInstanceThrottler::UNTHROTTLE_METHOD_BY_CLICK); -#endif LoadPlugin(); break; } @@ -327,8 +294,12 @@ void ChromePluginPlaceholder::OnMenuClosed(int request_id) { context_menu_request_id_ = 0; } +v8::Local<v8::Value> ChromePluginPlaceholder::GetV8Handle( + v8::Isolate* isolate) { + return gin::CreateHandle(isolate, this).ToV8(); +} + void ChromePluginPlaceholder::ShowContextMenu(const WebMouseEvent& event) { -#if !defined(OS_ANDROID) // The context menu is not applicable on Android. if (context_menu_request_id_) return; // Don't allow nested context menu requests. @@ -364,12 +335,10 @@ void ChromePluginPlaceholder::ShowContextMenu(const WebMouseEvent& event) { context_menu_request_id_ = render_frame()->ShowContextMenu(this, params); g_last_active_menu = this; -#endif // OS_ANDROID } blink::WebPlugin* ChromePluginPlaceholder::CreatePlugin() { scoped_ptr<content::PluginInstanceThrottler> throttler; -#if defined(ENABLE_PLUGINS) // If the plugin has already been marked essential in its placeholder form, // we shouldn't create a new throttler and start the process all over again. if (power_saver_enabled()) { @@ -380,13 +349,21 @@ blink::WebPlugin* ChromePluginPlaceholder::CreatePlugin() { l10n_util::GetStringFUTF16(IDS_PLUGIN_BLOCKED, title_), throttler.get()); } -#endif return render_frame()->CreatePlugin(GetFrame(), GetPluginInfo(), GetPluginParams(), throttler.Pass()); } gin::ObjectTemplateBuilder ChromePluginPlaceholder::GetObjectTemplateBuilder( v8::Isolate* isolate) { - return LoadablePluginPlaceholder::GetObjectTemplateBuilder(isolate).SetMethod( - "openAboutPlugins", &ChromePluginPlaceholder::OpenAboutPluginsCallback); + return gin::Wrappable<ChromePluginPlaceholder>::GetObjectTemplateBuilder( + isolate) + .SetMethod<void (ChromePluginPlaceholder::*)()>( + "hide", &ChromePluginPlaceholder::HideCallback) + .SetMethod<void (ChromePluginPlaceholder::*)()>( + "load", &ChromePluginPlaceholder::LoadCallback) + .SetMethod<void (ChromePluginPlaceholder::*)()>( + "didFinishLoading", + &ChromePluginPlaceholder::DidFinishLoadingCallback) + .SetMethod("openAboutPlugins", + &ChromePluginPlaceholder::OpenAboutPluginsCallback); } diff --git a/chrome/renderer/plugins/chrome_plugin_placeholder.h b/chrome/renderer/plugins/chrome_plugin_placeholder.h index d5fb2f9..85d49b7 100644 --- a/chrome/renderer/plugins/chrome_plugin_placeholder.h +++ b/chrome/renderer/plugins/chrome_plugin_placeholder.h @@ -28,11 +28,13 @@ struct PlaceholderPosterInfo { gfx::Size custom_poster_size; }; -class ChromePluginPlaceholder : public plugins::LoadablePluginPlaceholder, - public content::RenderProcessObserver, - public content::ContextMenuClient { +class ChromePluginPlaceholder final + : public plugins::LoadablePluginPlaceholder, + public content::RenderProcessObserver, + public content::ContextMenuClient, + public gin::Wrappable<ChromePluginPlaceholder> { public: - static const char kPluginPlaceholderDataURL[]; + static gin::WrapperInfo kWrapperInfo; static ChromePluginPlaceholder* CreateBlockedPlugin( content::RenderFrame* render_frame, @@ -46,15 +48,11 @@ class ChromePluginPlaceholder : public plugins::LoadablePluginPlaceholder, const PlaceholderPosterInfo& poster_info); // Creates a new WebViewPlugin with a MissingPlugin as a delegate. - static ChromePluginPlaceholder* CreateMissingPlugin( + static ChromePluginPlaceholder* CreateLoadableMissingPlugin( content::RenderFrame* render_frame, blink::WebLocalFrame* frame, const blink::WebPluginParams& params); - static ChromePluginPlaceholder* CreateErrorPlugin( - content::RenderFrame* render_frame, - const base::FilePath& plugin_path); - void SetStatus(ChromeViewHostMsg_GetPluginInfo_Status status); #if defined(ENABLE_PLUGIN_INSTALLATION) @@ -74,12 +72,13 @@ class ChromePluginPlaceholder : public plugins::LoadablePluginPlaceholder, // gin::Wrappable (via PluginPlaceholder) method gin::ObjectTemplateBuilder GetObjectTemplateBuilder( - v8::Isolate* isolate) override; + v8::Isolate* isolate) final; // content::RenderViewObserver (via PluginPlaceholder) override: bool OnMessageReceived(const IPC::Message& message) override; // WebViewPlugin::Delegate (via PluginPlaceholder) methods: + v8::Local<v8::Value> GetV8Handle(v8::Isolate* isolate) override; void ShowContextMenu(const blink::WebMouseEvent&) override; // content::RenderProcessObserver methods: diff --git a/chrome/renderer/plugins/non_loadable_plugin_placeholder.cc b/chrome/renderer/plugins/non_loadable_plugin_placeholder.cc new file mode 100644 index 0000000..598ad16 --- /dev/null +++ b/chrome/renderer/plugins/non_loadable_plugin_placeholder.cc @@ -0,0 +1,60 @@ +// Copyright 2015 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/non_loadable_plugin_placeholder.h" + +#include "base/files/file_path.h" +#include "base/values.h" +#include "chrome/common/render_messages.h" +#include "chrome/grit/generated_resources.h" +#include "chrome/grit/renderer_resources.h" +#include "components/plugins/renderer/plugin_placeholder.h" +#include "content/app/strings/grit/content_strings.h" +#include "content/public/renderer/render_thread.h" +#include "ui/base/l10n/l10n_util.h" +#include "ui/base/resource/resource_bundle.h" +#include "ui/base/webui/jstemplate_builder.h" + +// static +plugins::PluginPlaceholder* +NonLoadablePluginPlaceholder::CreateNotSupportedPlugin( + content::RenderFrame* render_frame, + blink::WebLocalFrame* frame, + const blink::WebPluginParams& params) { + const base::StringPiece template_html( + ResourceBundle::GetSharedInstance().GetRawDataResource( + IDR_BLOCKED_PLUGIN_HTML)); + + base::DictionaryValue values; + values.SetString("message", + l10n_util::GetStringUTF8(IDS_PLUGIN_NOT_SUPPORTED)); + + std::string html_data = webui::GetI18nTemplateHtml(template_html, &values); + + // PluginPlaceholder will destroy itself when its WebViewPlugin is going away. + return new plugins::PluginPlaceholder(render_frame, frame, params, html_data); +} + +// static +plugins::PluginPlaceholder* NonLoadablePluginPlaceholder::CreateErrorPlugin( + content::RenderFrame* render_frame, + const base::FilePath& file_path) { + base::DictionaryValue values; + values.SetString("message", + l10n_util::GetStringUTF8(IDS_PLUGIN_INITIALIZATION_ERROR)); + + const base::StringPiece template_html( + ResourceBundle::GetSharedInstance().GetRawDataResource( + IDR_BLOCKED_PLUGIN_HTML)); + std::string html_data = webui::GetI18nTemplateHtml(template_html, &values); + + blink::WebPluginParams params; + // PluginPlaceholder will destroy itself when its WebViewPlugin is going away. + plugins::PluginPlaceholder* plugin = + new plugins::PluginPlaceholder(render_frame, nullptr, params, html_data); + + content::RenderThread::Get()->Send(new ChromeViewHostMsg_CouldNotLoadPlugin( + plugin->routing_id(), file_path)); + return plugin; +} diff --git a/chrome/renderer/plugins/non_loadable_plugin_placeholder.h b/chrome/renderer/plugins/non_loadable_plugin_placeholder.h new file mode 100644 index 0000000..e872e5e --- /dev/null +++ b/chrome/renderer/plugins/non_loadable_plugin_placeholder.h @@ -0,0 +1,43 @@ +// Copyright 2015 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_NON_LOADABLE_PLUGIN_PLACEHOLDER_H_ +#define CHROME_RENDERER_PLUGINS_NON_LOADABLE_PLUGIN_PLACEHOLDER_H_ + +#include "base/macros.h" + +namespace base { +class FilePath; +} + +namespace blink { +class WebLocalFrame; +struct WebPluginParams; +} + +namespace content { +class RenderFrame; +} + +namespace plugins { +class PluginPlaceholder; +} + +class NonLoadablePluginPlaceholder { + public: + // Creates a non-loadable plugin placeholder for platforms without plugins. + static plugins::PluginPlaceholder* CreateNotSupportedPlugin( + content::RenderFrame* render_frame, + blink::WebLocalFrame* frame, + const blink::WebPluginParams& params); + + static plugins::PluginPlaceholder* CreateErrorPlugin( + content::RenderFrame* render_frame, + const base::FilePath& file_path); + + private: + DISALLOW_IMPLICIT_CONSTRUCTORS(NonLoadablePluginPlaceholder); +}; + +#endif // CHROME_RENDERER_PLUGINS_NON_LOADABLE_PLUGIN_PLACEHOLDER_H_ diff --git a/chrome/renderer/plugins/plugin_preroller.cc b/chrome/renderer/plugins/plugin_preroller.cc index 2d42f4e..6c27793 100644 --- a/chrome/renderer/plugins/plugin_preroller.cc +++ b/chrome/renderer/plugins/plugin_preroller.cc @@ -68,7 +68,6 @@ void PluginPreroller::OnThrottleStateChange() { IDR_PLUGIN_POSTER_HTML, message_, poster_info); placeholder->SetPremadePlugin(throttler_); placeholder->set_power_saver_enabled(true); - placeholder->set_allow_loading(true); blink::WebPluginContainer* container = throttler_->GetWebPlugin()->container(); diff --git a/chrome/renderer/resources/blocked_plugin.html b/chrome/renderer/resources/blocked_plugin.html index 7a92c1d..0d4dc4a 100644 --- a/chrome/renderer/resources/blocked_plugin.html +++ b/chrome/renderer/resources/blocked_plugin.html @@ -3,10 +3,8 @@ <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, user-scalable=no"> +<if expr="not is_android"> <script> -function debug(msg) { - document.getElementById('debug').textContent = msg; -} function setMessage(msg) { document.getElementById('message').textContent = msg; } @@ -15,6 +13,12 @@ function notifyDidFinishLoading() { plugin.didFinishLoading(); } </script> +</if> +<if expr="is_android"> +<script> +function notifyDidFinishLoading() {} +</script> +</if> <link rel="stylesheet" href="plugin_placeholders.css"></link> <style> body { @@ -37,7 +41,6 @@ body { <img id="plugin_icon" src="plugin_blocked_android.png"> </if> <h1 id="message" i18n-content="message"></h1> -<p id="debug"> </p> </div> <div id="close" i18n-values="title:hide" onclick="plugin.hide();"></div> </div> diff --git a/components/plugins.gypi b/components/plugins.gypi index fde25c6..9061833 100644 --- a/components/plugins.gypi +++ b/components/plugins.gypi @@ -36,14 +36,19 @@ ], 'sources': [ # Note: sources list duplicated in GN build. - 'plugins/renderer/loadable_plugin_placeholder.cc', - 'plugins/renderer/loadable_plugin_placeholder.h', 'plugins/renderer/plugin_placeholder.cc', 'plugins/renderer/plugin_placeholder.h', 'plugins/renderer/webview_plugin.cc', 'plugins/renderer/webview_plugin.h', ], 'conditions' : [ + ['enable_plugins==1', { + 'sources': [ + # Note: sources list duplicated in GN build. + 'plugins/renderer/loadable_plugin_placeholder.cc', + 'plugins/renderer/loadable_plugin_placeholder.h', + ] + }], ['OS=="android"', { 'sources': [ # Note: sources list duplicated in GN build. 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; diff --git a/content/content_shell.gypi b/content/content_shell.gypi index 2f30de3..5e65727 100644 --- a/content/content_shell.gypi +++ b/content/content_shell.gypi @@ -226,8 +226,6 @@ 'shell/renderer/layout_test/leak_detector.h', 'shell/renderer/layout_test/test_media_stream_renderer_factory.cc', 'shell/renderer/layout_test/test_media_stream_renderer_factory.h', - 'shell/renderer/layout_test/test_plugin_placeholder.cc', - 'shell/renderer/layout_test/test_plugin_placeholder.h', 'shell/renderer/layout_test/test_video_frame_provider.cc', 'shell/renderer/layout_test/test_video_frame_provider.h', 'shell/renderer/shell_content_renderer_client.cc', diff --git a/content/shell/BUILD.gn b/content/shell/BUILD.gn index d505da3..b736942 100644 --- a/content/shell/BUILD.gn +++ b/content/shell/BUILD.gn @@ -162,8 +162,6 @@ static_library("content_shell_lib") { "renderer/layout_test/leak_detector.h", "renderer/layout_test/test_media_stream_renderer_factory.cc", "renderer/layout_test/test_media_stream_renderer_factory.h", - "renderer/layout_test/test_plugin_placeholder.cc", - "renderer/layout_test/test_plugin_placeholder.h", "renderer/layout_test/test_video_frame_provider.cc", "renderer/layout_test/test_video_frame_provider.h", "renderer/shell_content_renderer_client.cc", diff --git a/content/shell/renderer/layout_test/blink_test_runner.cc b/content/shell/renderer/layout_test/blink_test_runner.cc index 009f475..ebba115 100644 --- a/content/shell/renderer/layout_test/blink_test_runner.cc +++ b/content/shell/renderer/layout_test/blink_test_runner.cc @@ -23,6 +23,7 @@ #include "base/strings/utf_string_conversions.h" #include "base/thread_task_runner_handle.h" #include "base/time/time.h" +#include "components/plugins/renderer/plugin_placeholder.h" #include "components/test_runner/app_banner_client.h" #include "components/test_runner/gamepad_controller.h" #include "components/test_runner/mock_screen_orientation_client.h" @@ -46,7 +47,6 @@ #include "content/shell/renderer/layout_test/gc_controller.h" #include "content/shell/renderer/layout_test/layout_test_render_process_observer.h" #include "content/shell/renderer/layout_test/leak_detector.h" -#include "content/shell/renderer/layout_test/test_plugin_placeholder.h" #include "net/base/filename_util.h" #include "net/base/net_errors.h" #include "skia/ext/platform_canvas.h" @@ -688,10 +688,13 @@ void BlinkTestRunner::ResolveBeforeInstallPromptPromise( blink::WebPlugin* BlinkTestRunner::CreatePluginPlaceholder( blink::WebLocalFrame* frame, const blink::WebPluginParams& params) { - if (params.mimeType == "application/x-plugin-placeholder-test") - return (new TestPluginPlaceholder(render_view()->GetMainRenderFrame(), - frame, params))->plugin(); - return 0; + if (params.mimeType != "application/x-plugin-placeholder-test") + return nullptr; + + plugins::PluginPlaceholder* placeholder = + new plugins::PluginPlaceholder(render_view()->GetMainRenderFrame(), frame, + params, "<div>Test content</div>"); + return placeholder->plugin(); } // RenderViewObserver -------------------------------------------------------- diff --git a/content/shell/renderer/layout_test/test_plugin_placeholder.cc b/content/shell/renderer/layout_test/test_plugin_placeholder.cc deleted file mode 100644 index 5b5a071..0000000 --- a/content/shell/renderer/layout_test/test_plugin_placeholder.cc +++ /dev/null @@ -1,35 +0,0 @@ -// Copyright 2015 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 "content/shell/renderer/layout_test/test_plugin_placeholder.h" - -#include "gin/handle.h" -#include "third_party/WebKit/public/web/WebKit.h" - -namespace content { - -TestPluginPlaceholder::TestPluginPlaceholder( - RenderFrame* render_frame, - blink::WebLocalFrame* frame, - const blink::WebPluginParams& params) - : PluginPlaceholder(render_frame, - frame, - params, - "<div>Test content</div>", - GURL("http://www.test.com")) { -} - -void TestPluginPlaceholder::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()); -} - -} // namespace content diff --git a/content/shell/renderer/layout_test/test_plugin_placeholder.h b/content/shell/renderer/layout_test/test_plugin_placeholder.h deleted file mode 100644 index 1424923..0000000 --- a/content/shell/renderer/layout_test/test_plugin_placeholder.h +++ /dev/null @@ -1,23 +0,0 @@ -// Copyright 2015 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 CONTENT_SHELL_RENDERER_TEST_RUNNER_TEST_PLUGIN_PLACEHOLDER_H_ -#define CONTENT_SHELL_RENDERER_TEST_RUNNER_TEST_PLUGIN_PLACEHOLDER_H_ - -#include "components/plugins/renderer/plugin_placeholder.h" - -namespace content { - -// A subclass of PluginPlaceholder for use in Blink layout tests. -class TestPluginPlaceholder : public plugins::PluginPlaceholder { - public: - TestPluginPlaceholder(RenderFrame* render_frame, - blink::WebLocalFrame* frame, - const blink::WebPluginParams& params); - - void BindWebFrame(blink::WebFrame* frame) override; -}; - -} // namespace content - -#endif // CONTENT_SHELL_RENDERER_TEST_RUNNER_TEST_PLUGIN_PLACEHOLDER_H_ diff --git a/gin/wrappable.cc b/gin/wrappable.cc index 27c58df..0fac4e0 100644 --- a/gin/wrappable.cc +++ b/gin/wrappable.cc @@ -36,7 +36,7 @@ void WrappableBase::SecondWeakCallback( } v8::Local<v8::Object> WrappableBase::GetWrapperImpl(v8::Isolate* isolate, - WrapperInfo* info) { + WrapperInfo* info) { if (!wrapper_.IsEmpty()) { return v8::Local<v8::Object>::New(isolate, wrapper_); } diff --git a/gin/wrappable.h b/gin/wrappable.h index cd4d30e..f7d82b0 100644 --- a/gin/wrappable.h +++ b/gin/wrappable.h @@ -12,15 +12,6 @@ namespace gin { -namespace internal { - -GIN_EXPORT void* FromV8Impl(v8::Isolate* isolate, - v8::Local<v8::Value> val, - WrapperInfo* info); - -} // namespace internal - - // Wrappable is a base class for C++ objects that have corresponding v8 wrapper // objects. To retain a Wrappable object on the stack, use a gin::Handle. // @@ -51,8 +42,20 @@ GIN_EXPORT void* FromV8Impl(v8::Isolate* isolate, // wrapper for the object. If clients fail to create a wrapper for a wrappable // object, the object will leak because we use the weak callback from the // wrapper as the signal to delete the wrapped object. -template<typename T> -class Wrappable; +// +// Wrappable<T> explicitly does not support further subclassing of T. +// Subclasses of Wrappable<T> should be declared final. Because Wrappable<T> +// caches the object template using &T::kWrapperInfo as the key, all subclasses +// would share a single object template. This will lead to hard to debug crashes +// that look like use-after-free errors. + +namespace internal { + +GIN_EXPORT void* FromV8Impl(v8::Isolate* isolate, + v8::Local<v8::Value> val, + WrapperInfo* info); + +} // namespace internal class ObjectTemplateBuilder; @@ -62,6 +65,7 @@ class GIN_EXPORT WrappableBase { WrappableBase(); virtual ~WrappableBase(); + // Overrides of this method should be declared final and not overridden again. virtual ObjectTemplateBuilder GetObjectTemplateBuilder(v8::Isolate* isolate); v8::Local<v8::Object> GetWrapperImpl(v8::Isolate* isolate, @@ -83,8 +87,6 @@ template<typename T> class Wrappable : public WrappableBase { public: // Retrieve (or create) the v8 wrapper object cooresponding to this object. - // To customize the wrapper created for a subclass, override GetWrapperInfo() - // instead of overriding this function. v8::Local<v8::Object> GetWrapper(v8::Isolate* isolate) { return GetWrapperImpl(isolate, &T::kWrapperInfo); } diff --git a/gin/wrappable_unittest.cc b/gin/wrappable_unittest.cc index 70cb224..07d4fb3 100644 --- a/gin/wrappable_unittest.cc +++ b/gin/wrappable_unittest.cc @@ -40,38 +40,16 @@ class MyObject : public BaseClass, protected: MyObject() : value_(0) {} - ObjectTemplateBuilder GetObjectTemplateBuilder(v8::Isolate* isolate) override; + ObjectTemplateBuilder GetObjectTemplateBuilder(v8::Isolate* isolate) final { + return Wrappable<MyObject>::GetObjectTemplateBuilder(isolate) + .SetProperty("value", &MyObject::value, &MyObject::set_value); + } ~MyObject() override {} private: int value_; }; -class MyObjectSubclass : public MyObject { - public: - static gin::Handle<MyObjectSubclass> Create(v8::Isolate* isolate) { - return CreateHandle(isolate, new MyObjectSubclass()); - } - - void SayHello(const std::string& name) { - result = std::string("Hello, ") + name; - } - - std::string result; - - private: - ObjectTemplateBuilder GetObjectTemplateBuilder( - v8::Isolate* isolate) override { - return MyObject::GetObjectTemplateBuilder(isolate) - .SetMethod("sayHello", &MyObjectSubclass::SayHello); - } - - MyObjectSubclass() { - } - - ~MyObjectSubclass() override {} -}; - class MyCallableObject : public Wrappable<MyCallableObject> { public: static WrapperInfo kWrapperInfo; @@ -83,8 +61,7 @@ class MyCallableObject : public Wrappable<MyCallableObject> { int result() { return result_; } private: - ObjectTemplateBuilder GetObjectTemplateBuilder( - v8::Isolate* isolate) override { + ObjectTemplateBuilder GetObjectTemplateBuilder(v8::Isolate* isolate) final { return Wrappable<MyCallableObject>::GetObjectTemplateBuilder(isolate) .SetCallAsFunctionHandler(&MyCallableObject::Call); } @@ -109,20 +86,9 @@ class MyObject2 : public Wrappable<MyObject2> { static WrapperInfo kWrapperInfo; }; -class MyObjectBlink : public Wrappable<MyObjectBlink> { - public: - static WrapperInfo kWrapperInfo; -}; - WrapperInfo MyObject::kWrapperInfo = { kEmbedderNativeGin }; -ObjectTemplateBuilder MyObject::GetObjectTemplateBuilder(v8::Isolate* isolate) { - return Wrappable<MyObject>::GetObjectTemplateBuilder(isolate) - .SetProperty("value", &MyObject::value, &MyObject::set_value); -} - WrapperInfo MyCallableObject::kWrapperInfo = { kEmbedderNativeGin }; WrapperInfo MyObject2::kWrapperInfo = { kEmbedderNativeGin }; -WrapperInfo MyObjectBlink::kWrapperInfo = { kEmbedderNativeGin }; typedef V8Test WrappableTest; @@ -155,12 +121,6 @@ TEST_F(WrappableTest, UnwrapFailures) { EXPECT_FALSE(ConvertFromV8(isolate, thing, &unwrapped)); EXPECT_FALSE(unwrapped); - // An object that's wrapping a C++ object from Blink. - thing.Clear(); - thing = ConvertToV8(isolate, new MyObjectBlink()); - EXPECT_FALSE(ConvertFromV8(isolate, thing, &unwrapped)); - EXPECT_FALSE(unwrapped); - // An object that's wrapping a C++ object of the wrong type. thing.Clear(); thing = ConvertToV8(isolate, new MyObject2()); @@ -200,28 +160,6 @@ TEST_F(WrappableTest, GetAndSetProperty) { EXPECT_EQ(191, obj->value()); } -TEST_F(WrappableTest, WrappableSubclass) { - v8::Isolate* isolate = instance_->isolate(); - v8::HandleScope handle_scope(isolate); - - gin::Handle<MyObjectSubclass> object(MyObjectSubclass::Create(isolate)); - v8::Local<v8::String> source = StringToV8(isolate, - "(function(obj) {" - "obj.sayHello('Lily');" - "})"); - gin::TryCatch try_catch(isolate); - v8::Local<v8::Script> script = v8::Script::Compile(source); - v8::Local<v8::Value> val = script->Run(); - v8::Local<v8::Function> func; - EXPECT_TRUE(ConvertFromV8(isolate, val, &func)); - v8::Local<v8::Value> argv[] = { - ConvertToV8(isolate, object.get()) - }; - func->Call(v8::Undefined(isolate), 1, argv); - EXPECT_FALSE(try_catch.HasCaught()); - EXPECT_EQ("Hello, Lily", object->result); -} - TEST_F(WrappableTest, CallAsFunction) { v8::Isolate* isolate = instance_->isolate(); v8::HandleScope handle_scope(isolate); |