Commit ad57375e authored by Sam McNally's avatar Sam McNally Committed by Commit Bot

Add support for beforeunload for mime handler guests.

QuickOffice uses beforeunload events. When running inside a mime
handler, these beforeunload event handlers are ignored. Add a
beforeunload event handler to PluginDocument when a plugin requires it.

This event handler is controlled over a mojo interface, exposed to the
mime handler as chrome.mimeHandlerPrivate.setShowBeforeUnloadDialog().

Bug: 819761
Cq-Include-Trybots: luci.chromium.try:closure_compilation
Change-Id: Ieb61cf98ce2bf719fc128499f8d0e57d8fe7ad33
Reviewed-on: https://chromium-review.googlesource.com/1139946
Commit-Queue: Sam McNally <sammc@chromium.org>
Reviewed-by: default avatarDevlin <rdevlin.cronin@chromium.org>
Reviewed-by: default avatarAvi Drissman <avi@chromium.org>
Reviewed-by: default avatarDaniel Cheng <dcheng@chromium.org>
Cr-Commit-Position: refs/heads/master@{#576283}
parent 5c9266c5
......@@ -91,6 +91,7 @@
"dom_distiller.mojom.DistillabilityService",
"dom_distiller.mojom.DistillerJavaScriptService",
"extensions.KeepAlive",
"extensions.mime_handler.BeforeUnloadControl",
"extensions.mime_handler.MimeHandlerService",
"extensions.mojom.InlineInstall",
"media_router.mojom.MediaRouter",
......
......@@ -118,7 +118,7 @@ var tests = [
} else if (event.data == expectedMessages[messagesReceived]) {
event.source.postMessage(event.data, '*');
messagesReceived++;
} else {
} else if (event.data != 'initBeforeUnload') {
chrome.test.fail('unexpected message ' + event.data);
}
}
......@@ -246,6 +246,18 @@ var tests = [
anchor.click();
chrome.test.succeed();
},
function testBeforeUnloadNoDialog() {
checkStreamDetails('testBeforeUnloadNoDialog.csv', false);
chrome.mimeHandlerPrivate.setShowBeforeUnloadDialog(false);
chrome.test.succeed();
},
function testBeforeUnloadShowDialog() {
checkStreamDetails('testBeforeUnloadShowDialog.csv', false);
chrome.mimeHandlerPrivate.setShowBeforeUnloadDialog(true);
chrome.test.succeed();
},
];
var testsByName = {};
......
......@@ -284,6 +284,7 @@ source_set("chrome_extensions_browsertests") {
"//chrome/browser",
"//chrome/common/extensions/api",
"//chrome/renderer",
"//components/app_modal",
"//components/autofill/content/browser:risk_proto",
"//components/autofill/content/renderer:test_support",
"//components/captive_portal:test_support",
......
......@@ -42,6 +42,7 @@ include_rules = [
specific_include_rules = {
".*(test|test_util)\.(cc|h)$": [
"+components/app_modal",
"+components/user_prefs",
"+storage/browser/test",
......
......@@ -56,7 +56,6 @@ void ExtensionsGuestViewMessageFilter::OverrideThreadForMessage(
const IPC::Message& message,
BrowserThread::ID* thread) {
switch (message.type()) {
case ExtensionsGuestViewHostMsg_CreateMimeHandlerViewGuest::ID:
case ExtensionsGuestViewHostMsg_ResizeGuest::ID:
*thread = BrowserThread::UI;
break;
......@@ -71,8 +70,6 @@ bool ExtensionsGuestViewMessageFilter::OnMessageReceived(
IPC_BEGIN_MESSAGE_MAP(ExtensionsGuestViewMessageFilter, message)
IPC_MESSAGE_HANDLER(ExtensionsGuestViewHostMsg_CanExecuteContentScriptSync,
OnCanExecuteContentScript)
IPC_MESSAGE_HANDLER(ExtensionsGuestViewHostMsg_CreateMimeHandlerViewGuest,
OnCreateMimeHandlerViewGuest)
IPC_MESSAGE_HANDLER(ExtensionsGuestViewHostMsg_ResizeGuest, OnResizeGuest)
IPC_MESSAGE_UNHANDLED(
handled = GuestViewMessageFilter::OnMessageReceived(message))
......@@ -104,11 +101,26 @@ void ExtensionsGuestViewMessageFilter::OnCanExecuteContentScript(
info.content_script_ids.find(script_id) != info.content_script_ids.end();
}
void ExtensionsGuestViewMessageFilter::OnCreateMimeHandlerViewGuest(
void ExtensionsGuestViewMessageFilter::CreateMimeHandlerViewGuest(
int32_t render_frame_id,
const std::string& view_id,
int32_t element_instance_id,
const gfx::Size& element_size,
mime_handler::BeforeUnloadControlPtr before_unload_control) {
content::BrowserThread::PostTask(
content::BrowserThread::UI, FROM_HERE,
base::BindOnce(&ExtensionsGuestViewMessageFilter::
CreateMimeHandlerViewGuestOnUIThread,
this, render_frame_id, view_id, element_instance_id,
element_size, before_unload_control.PassInterface()));
}
void ExtensionsGuestViewMessageFilter::CreateMimeHandlerViewGuestOnUIThread(
int render_frame_id,
const std::string& view_id,
int element_instance_id,
const gfx::Size& element_size) {
const gfx::Size& element_size,
mime_handler::BeforeUnloadControlPtrInfo before_unload_control) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
auto* manager = GetOrCreateGuestViewManager();
......@@ -120,7 +132,7 @@ void ExtensionsGuestViewMessageFilter::OnCreateMimeHandlerViewGuest(
GuestViewManager::WebContentsCreatedCallback callback = base::BindOnce(
&ExtensionsGuestViewMessageFilter::MimeHandlerViewGuestCreatedCallback,
this, element_instance_id, render_process_id_, render_frame_id,
element_size);
element_size, std::move(before_unload_control));
base::DictionaryValue create_params;
create_params.SetString(mime_handler_view::kViewId, view_id);
......@@ -203,8 +215,8 @@ void ExtensionsGuestViewMessageFilter::CreateEmbeddedMimeHandlerViewGuest(
-1 /* frame_tree_node_id*/, render_process_id_,
render_frame_id);
OnCreateMimeHandlerViewGuest(render_frame_id, view_id, element_instance_id,
element_size);
CreateMimeHandlerViewGuestOnUIThread(
render_frame_id, view_id, element_instance_id, element_size, nullptr);
}
void ExtensionsGuestViewMessageFilter::MimeHandlerViewGuestCreatedCallback(
......@@ -212,11 +224,13 @@ void ExtensionsGuestViewMessageFilter::MimeHandlerViewGuestCreatedCallback(
int embedder_render_process_id,
int embedder_render_frame_id,
const gfx::Size& element_size,
mime_handler::BeforeUnloadControlPtrInfo before_unload_control,
WebContents* web_contents) {
auto* guest_view = MimeHandlerViewGuest::FromWebContents(web_contents);
if (!guest_view)
return;
guest_view->SetBeforeUnloadController(std::move(before_unload_control));
int guest_instance_id = guest_view->guest_instance_id();
auto* rfh = RenderFrameHost::FromID(embedder_render_process_id,
embedder_render_frame_id);
......
......@@ -76,13 +76,28 @@ class ExtensionsGuestViewMessageFilter
const gfx::Size& element_size,
content::mojom::TransferrableURLLoaderPtr transferrable_url_loader)
override;
void CreateMimeHandlerViewGuest(
int32_t render_frame_id,
const std::string& view_id,
int32_t element_instance_id,
const gfx::Size& element_size,
mime_handler::BeforeUnloadControlPtr before_unload_control) override;
void CreateMimeHandlerViewGuestOnUIThread(
int32_t render_frame_id,
const std::string& view_id,
int32_t element_instance_id,
const gfx::Size& element_size,
mime_handler::BeforeUnloadControlPtrInfo before_unload_control);
// Runs on UI thread.
void MimeHandlerViewGuestCreatedCallback(int element_instance_id,
int embedder_render_process_id,
int embedder_render_frame_id,
const gfx::Size& element_size,
content::WebContents* web_contents);
void MimeHandlerViewGuestCreatedCallback(
int element_instance_id,
int embedder_render_process_id,
int embedder_render_frame_id,
const gfx::Size& element_size,
mime_handler::BeforeUnloadControlPtrInfo before_unload_control,
content::WebContents* web_contents);
static const uint32_t kFilteredMessageClasses[];
......
......@@ -11,8 +11,10 @@
#include "base/run_loop.h"
#include "base/test/scoped_feature_list.h"
#include "chrome/browser/extensions/extension_apitest.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/test/base/ui_test_utils.h"
#include "components/app_modal/javascript_app_modal_dialog.h"
#include "components/guest_view/browser/test_guest_view_manager.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/common/content_features.h"
......@@ -230,3 +232,27 @@ IN_PROC_BROWSER_TEST_P(MimeHandlerViewTest, TargetBlankAnchor) {
GURL("about:blank"),
browser()->tab_strip_model()->GetWebContentsAt(1)->GetLastCommittedURL());
}
IN_PROC_BROWSER_TEST_P(MimeHandlerViewTest, BeforeUnload_NoDialog) {
ASSERT_NO_FATAL_FAILURE(RunTest("testBeforeUnloadNoDialog.csv"));
content::PrepContentsForBeforeUnloadTest(
browser()->tab_strip_model()->GetWebContentsAt(0));
// Try to navigate away from the page. If the beforeunload listener is
// triggered and a dialog is shown, this navigation will never complete,
// causing the test to timeout and fail.
ui_test_utils::NavigateToURL(browser(), GURL("about:blank"));
}
IN_PROC_BROWSER_TEST_P(MimeHandlerViewTest, BeforeUnload_ShowDialog) {
ASSERT_NO_FATAL_FAILURE(RunTest("testBeforeUnloadShowDialog.csv"));
auto* web_contents = browser()->tab_strip_model()->GetWebContentsAt(0);
content::PrepContentsForBeforeUnloadTest(web_contents);
web_contents->GetController().Reload(content::ReloadType::NORMAL, false);
app_modal::JavaScriptAppModalDialog* before_unload_dialog =
ui_test_utils::WaitForAppModalDialog();
EXPECT_TRUE(before_unload_dialog->is_before_unload_dialog());
EXPECT_TRUE(before_unload_dialog->is_reload());
before_unload_dialog->OnAccept(base::string16(), false);
}
......@@ -140,6 +140,11 @@ void MimeHandlerViewGuest::SetEmbedderFrame(int process_id, int routing_id) {
DCHECK_NE(MSG_ROUTING_NONE, embedder_widget_routing_id_);
}
void MimeHandlerViewGuest::SetBeforeUnloadController(
mime_handler::BeforeUnloadControlPtrInfo pending_before_unload_control) {
pending_before_unload_control_ = std::move(pending_before_unload_control);
}
const char* MimeHandlerViewGuest::GetAPINamespace() const {
return "mimeHandlerViewGuestInternal";
}
......@@ -203,6 +208,8 @@ void MimeHandlerViewGuest::CreateWebContents(
registry_.AddInterface(
base::Bind(&MimeHandlerServiceImpl::Create, stream_->GetWeakPtr()));
registry_.AddInterface(base::BindRepeating(
&MimeHandlerViewGuest::FuseBeforeUnloadControl, base::Unretained(this)));
}
void MimeHandlerViewGuest::DidAttachToEmbedder() {
......@@ -394,4 +401,13 @@ void MimeHandlerViewGuest::ReadyToCommitNavigation(
stream_->TakeTransferrableURLLoader());
}
void MimeHandlerViewGuest::FuseBeforeUnloadControl(
mime_handler::BeforeUnloadControlRequest request) {
if (!pending_before_unload_control_)
return;
mojo::FuseInterface(std::move(request),
std::move(pending_before_unload_control_));
}
} // namespace extensions
......@@ -12,6 +12,7 @@
#include "base/memory/weak_ptr.h"
#include "components/guest_view/browser/guest_view.h"
#include "content/public/common/transferrable_url_loader.mojom.h"
#include "extensions/common/api/mime_handler.mojom.h"
#include "services/service_manager/public/cpp/binder_registry.h"
namespace content {
......@@ -74,8 +75,8 @@ class StreamContainer {
DISALLOW_COPY_AND_ASSIGN(StreamContainer);
};
class MimeHandlerViewGuest :
public guest_view::GuestView<MimeHandlerViewGuest> {
class MimeHandlerViewGuest
: public guest_view::GuestView<MimeHandlerViewGuest> {
public:
static guest_view::GuestViewBase* Create(
content::WebContents* owner_web_contents);
......@@ -90,6 +91,9 @@ class MimeHandlerViewGuest :
void SetEmbedderFrame(int process_id, int routing_id);
void SetBeforeUnloadController(
mime_handler::BeforeUnloadControlPtrInfo pending_before_unload_control);
protected:
explicit MimeHandlerViewGuest(content::WebContents* owner_web_contents);
~MimeHandlerViewGuest() override;
......@@ -155,6 +159,9 @@ class MimeHandlerViewGuest :
void ReadyToCommitNavigation(
content::NavigationHandle* navigation_handle) final;
void FuseBeforeUnloadControl(
mime_handler::BeforeUnloadControlRequest request);
std::unique_ptr<MimeHandlerViewGuestDelegate> delegate_;
std::unique_ptr<StreamContainer> stream_;
......@@ -167,6 +174,8 @@ class MimeHandlerViewGuest :
bool is_guest_fullscreen_ = false;
bool is_embedder_fullscreen_ = false;
mime_handler::BeforeUnloadControlPtrInfo pending_before_unload_control_;
DISALLOW_COPY_AND_ASSIGN(MimeHandlerViewGuest);
};
......
......@@ -42,6 +42,7 @@ if (enable_extensions) {
public_deps = [
"//content/public/common:interfaces",
"//extensions/common/api:mojom",
"//mojo/public/mojom/base",
"//ui/gfx/geometry/mojo",
"//url/mojom:url_mojom_gurl",
......
......@@ -6,4 +6,7 @@ per-file *.idl=file://extensions/common/api/API_OWNERS
per-file *view*.json=file://components/guest_view/OWNERS
per-file *.mojom=set noparent
per-file *.mojom=file://ipc/SECURITY_OWNERS
# COMPONENT: Platform>Extensions>API
......@@ -37,4 +37,18 @@ interface MimeHandlerService {
// Aborts the stream associated with this service instance. This is an
// idempotent operation.
AbortStream() => ();
};
// Provides a mime handler guest with control over beforeunload event handling
// when running in a PluginDocument.
//
// For full-frame mime handler guests, an instance of this interface is passed
// from the embedding renderer to the browser when creating the mime handler
// guest. If the frame hosting the guest requests this interface from the
// browser, that instance is provided to the guest.
interface BeforeUnloadControl {
// Instructs the containing PluginDocument whether to show a beforeunload
// dialog.
SetShowBeforeUnloadDialog(bool show_dialog) => ();
};
......@@ -30,6 +30,7 @@
callback AbortCallback = void ();
callback GetStreamDetailsCallback = void (StreamInfo streamInfo);
callback SetShowBeforeUnloadDialogCallback = void ();
interface Functions {
// Returns the StreamInfo for the stream for this context if there is one.
......@@ -37,5 +38,11 @@
// Aborts the stream for this context if there is one.
[nocompile] static void abortStream(optional AbortCallback callback);
// Instructs the PluginDocument, if running in one, to show a dialog in
// response to beforeunload events.
[nocompile] static void setShowBeforeUnloadDialog(
boolean showDialog,
optional SetShowBeforeUnloadDialogCallback callback);
};
};
......@@ -35,13 +35,6 @@ IPC_SYNC_MESSAGE_CONTROL2_1(
int /* script_id */,
bool /* allowed */)
// Tells the browser to create a mime handler guest view for a plugin.
IPC_MESSAGE_CONTROL4(ExtensionsGuestViewHostMsg_CreateMimeHandlerViewGuest,
int /* render_frame_id */,
std::string /* view_id */,
int /* element_instance_id */,
gfx::Size /* element_size */)
// A renderer sends this message when it wants to resize a guest.
IPC_MESSAGE_CONTROL3(ExtensionsGuestViewHostMsg_ResizeGuest,
int /* routing_id */,
......
......@@ -5,6 +5,7 @@
module extensions.mojom;
import "content/public/common/transferrable_url_loader.mojom";
import "extensions/common/api/mime_handler.mojom";
import "ui/gfx/geometry/mojo/geometry.mojom";
import "url/mojom/url.mojom";
......@@ -19,4 +20,14 @@ interface GuestView {
int32 element_instance_id,
gfx.mojom.Size element_size,
content.mojom.TransferrableURLLoader transferrable_url_loader);
// Tells the browser to create a mime handler guest view for a plugin.
// This method is called for full-frame plugins or for all plugins when the
// network service is disabled.
CreateMimeHandlerViewGuest(
int32 render_frame_id,
string view_id,
int32 element_instance_id,
gfx.mojom.Size element_size,
extensions.mime_handler.BeforeUnloadControl? before_unload_control);
};
......@@ -35,6 +35,7 @@
#include "third_party/blink/public/web/web_associated_url_loader_options.h"
#include "third_party/blink/public/web/web_document.h"
#include "third_party/blink/public/web/web_local_frame.h"
#include "third_party/blink/public/web/web_plugin_document.h"
#include "third_party/blink/public/web/web_remote_frame.h"
#include "third_party/blink/public/web/web_view.h"
......@@ -179,6 +180,7 @@ MimeHandlerViewContainer::MimeHandlerViewContainer(
original_url_(original_url),
guest_proxy_routing_id_(-1),
guest_loaded_(false),
before_unload_control_binding_(this),
weak_factory_(this) {
DCHECK(!mime_type_.empty());
is_embedded_ = !render_frame->GetWebFrame()->GetDocument().IsPluginDocument();
......@@ -441,12 +443,28 @@ void MimeHandlerViewContainer::CreateMimeHandlerViewGuestIfNecessary() {
if (!render_frame())
return;
render_frame()->Send(
new ExtensionsGuestViewHostMsg_CreateMimeHandlerViewGuest(
render_frame()->GetRoutingID(), view_id_, element_instance_id(),
*element_size_));
mime_handler::BeforeUnloadControlPtr before_unload_control;
if (!is_embedded_) {
before_unload_control_binding_.Bind(
mojo::MakeRequest(&before_unload_control));
}
GetGuestView()->CreateMimeHandlerViewGuest(
render_frame()->GetRoutingID(), view_id_, element_instance_id(),
*element_size_, std::move(before_unload_control));
guest_created_ = true;
}
void MimeHandlerViewContainer::SetShowBeforeUnloadDialog(
bool show_dialog,
SetShowBeforeUnloadDialogCallback callback) {
DCHECK(!is_embedded_);
render_frame()
->GetWebFrame()
->GetDocument()
.To<blink::WebPluginDocument>()
.SetShowBeforeUnloadDialog(show_dialog);
std::move(callback).Run();
}
} // namespace extensions
......@@ -15,6 +15,7 @@
#include "base/optional.h"
#include "components/guest_view/renderer/guest_view_container.h"
#include "content/public/common/transferrable_url_loader.mojom.h"
#include "extensions/common/api/mime_handler.mojom.h"
#include "mojo/public/cpp/bindings/binding.h"
#include "services/network/public/mojom/url_loader.mojom.h"
#include "third_party/blink/public/web/web_associated_url_loader_client.h"
......@@ -50,7 +51,8 @@ namespace extensions {
// |didFinishLoading| (from WebAssociatedURLLoaderClient) when data is
// received and when it has finished being received.
class MimeHandlerViewContainer : public guest_view::GuestViewContainer,
public blink::WebAssociatedURLLoaderClient {
public blink::WebAssociatedURLLoaderClient,
public mime_handler::BeforeUnloadControl {
public:
MimeHandlerViewContainer(content::RenderFrame* render_frame,
const content::WebPluginInfo& info,
......@@ -112,6 +114,11 @@ class MimeHandlerViewContainer : public guest_view::GuestViewContainer,
// to are available.
void CreateMimeHandlerViewGuestIfNecessary();
// mime_handler::BeforeUnloadControl implementation.
void SetShowBeforeUnloadDialog(
bool show_dialog,
SetShowBeforeUnloadDialogCallback callback) override;
// Path of the plugin.
const std::string plugin_path_;
......@@ -157,6 +164,9 @@ class MimeHandlerViewContainer : public guest_view::GuestViewContainer,
// The size of the element.
base::Optional<gfx::Size> element_size_;
mojo::Binding<mime_handler::BeforeUnloadControl>
before_unload_control_binding_;
base::WeakPtrFactory<MimeHandlerViewContainer> weak_factory_;
DISALLOW_COPY_AND_ASSIGN(MimeHandlerViewContainer);
......
......@@ -22,6 +22,11 @@ loadScript('extensions/common/api/mime_handler.mojom');
var servicePtr = new extensions.mimeHandler.MimeHandlerServicePtr;
Mojo.bindInterface(extensions.mimeHandler.MimeHandlerService.name,
mojo.makeRequest(servicePtr).handle);
var beforeUnloadControlPtr =
new extensions.mimeHandler.BeforeUnloadControlPtr;
Mojo.bindInterface(
extensions.mimeHandler.BeforeUnloadControl.name,
mojo.makeRequest(beforeUnloadControlPtr).handle);
// Stores a promise to the GetStreamInfo() result to avoid making additional
// calls in response to getStreamInfo() calls.
......@@ -69,6 +74,12 @@ binding.registerCustomHook(function(bindingsAPI) {
function() {
return servicePtr.abortStream().then(function() {});
});
utils.handleRequestWithPromiseDoNotUse(
apiFunctions, 'mimeHandlerPrivate', 'setShowBeforeUnloadDialog',
function(showDialog) {
return beforeUnloadControlPtr.setShowBeforeUnloadDialog(showDialog);
});
});
if (!apiBridge)
......
......@@ -52,6 +52,8 @@ class WebPluginDocument final : public WebDocument {
BLINK_EXPORT WebPlugin* Plugin();
BLINK_EXPORT void SetShowBeforeUnloadDialog(bool show_dialog);
#if INSIDE_BLINK
WebPluginDocument(PluginDocument*);
WebPluginDocument& operator=(PluginDocument*);
......
......@@ -61,4 +61,12 @@ WebPluginDocument::operator PluginDocument*() const {
return static_cast<PluginDocument*>(private_.Get());
}
void WebPluginDocument::SetShowBeforeUnloadDialog(bool show_dialog) {
if (!IsPluginDocument())
return;
PluginDocument* doc = Unwrap<PluginDocument>();
doc->SetShowBeforeUnloadDialog(show_dialog);
}
} // namespace blink
......@@ -25,8 +25,11 @@
#include "third_party/blink/renderer/core/html/plugin_document.h"
#include "third_party/blink/renderer/core/css/css_color_value.h"
#include "third_party/blink/renderer/core/dom/events/event.h"
#include "third_party/blink/renderer/core/dom/raw_data_document_parser.h"
#include "third_party/blink/renderer/core/events/before_unload_event.h"
#include "third_party/blink/renderer/core/exported/web_plugin_container_impl.h"
#include "third_party/blink/renderer/core/frame/local_dom_window.h"
#include "third_party/blink/renderer/core/frame/local_frame.h"
#include "third_party/blink/renderer/core/frame/local_frame_client.h"
#include "third_party/blink/renderer/core/frame/local_frame_view.h"
......@@ -45,6 +48,39 @@ namespace blink {
using namespace HTMLNames;
class PluginDocument::BeforeUnloadEventListener : public EventListener {
public:
static BeforeUnloadEventListener* Create(PluginDocument* document) {
return new BeforeUnloadEventListener(document);
}
bool operator==(const EventListener& listener) const override {
return this == &listener;
}
void SetShowBeforeUnloadDialog(bool show_dialog) {
show_dialog_ = show_dialog;
}
void Trace(blink::Visitor* visitor) override {
visitor->Trace(doc_);
EventListener::Trace(visitor);
}
private:
explicit BeforeUnloadEventListener(PluginDocument* document)
: EventListener(kCPPEventListenerType), doc_(document) {}
void handleEvent(ExecutionContext*, Event* event) override {
DCHECK_EQ(event->type(), EventTypeNames::beforeunload);
if (show_dialog_)
ToBeforeUnloadEvent(event)->setReturnValue(g_empty_string);
}
Member<PluginDocument> doc_;
bool show_dialog_;
};
// FIXME: Share more code with MediaDocumentParser.
class PluginDocumentParser : public RawDataDocumentParser {
public:
......@@ -186,14 +222,28 @@ WebPluginContainerImpl* PluginDocument::GetPluginView() {
return plugin_node_ ? plugin_node_->OwnedPlugin() : nullptr;
}
void PluginDocument::SetShowBeforeUnloadDialog(bool show_dialog) {
if (!before_unload_event_listener_) {
if (!show_dialog)
return;
before_unload_event_listener_ = BeforeUnloadEventListener::Create(this);
domWindow()->addEventListener(EventTypeNames::beforeunload,
before_unload_event_listener_, false);
}
before_unload_event_listener_->SetShowBeforeUnloadDialog(show_dialog);
}
void PluginDocument::Shutdown() {
// Release the plugin node so that we don't have a circular reference.
plugin_node_ = nullptr;
before_unload_event_listener_ = nullptr;
HTMLDocument::Shutdown();
}
void PluginDocument::Trace(blink::Visitor* visitor) {
visitor->Trace(plugin_node_);
visitor->Trace(before_unload_event_listener_);
HTMLDocument::Trace(visitor);
}
......
......@@ -48,16 +48,22 @@ class CORE_EXPORT PluginDocument final : public HTMLDocument {
WebPluginContainerImpl* GetPluginView();
void SetShowBeforeUnloadDialog(bool show_dialog);
void Shutdown() override;
void Trace(blink::Visitor*) override;
private:
class BeforeUnloadEventListener;
PluginDocument(const DocumentInit&, Color background_color);
DocumentParser* CreateParser() override;
Member<HTMLPlugInElement> plugin_node_;
Member<BeforeUnloadEventListener> before_unload_event_listener_;
const Color background_color_;
};
......
// Copyright 2017 The Chromium Authors. All rights reserved.
// Copyright 2018 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.
// This file was generated by:
// tools/json_schema_compiler/compiler.py.
// NOTE: The format of types has changed. 'FooType' is now
// 'chrome.mimeHandlerPrivate.FooType'.
// Please run the closure compiler before committing changes.
// See https://chromium.googlesource.com/chromium/src/+/master/docs/closure_compilation.md
/** @fileoverview Externs generated from namespace: mimeHandlerPrivate */
/** @const */
/**
* @const
*/
chrome.mimeHandlerPrivate = {};
/**
* @typedef {?{
* embedded: boolean,
* @typedef {{
* mimeType: string,
* originalUrl: string,
* responseHeaders: !Object,
* streamUrl: string,
* tabId: number
* tabId: number,
* responseHeaders: Object,
* embedded: boolean
* }}
*/
chrome.mimeHandlerPrivate.StreamInfo;
/**
* @param {function(!chrome.mimeHandlerPrivate.StreamInfo): void} callback
* Returns the StreamInfo for the stream for this context if there is one.
* @param {function(!chrome.mimeHandlerPrivate.StreamInfo):void} callback
*/
chrome.mimeHandlerPrivate.getStreamInfo = function(callback) {};
/**
* Aborts the stream for this context if there is one.
* @param {function():void=} callback
*/
chrome.mimeHandlerPrivate.getStreamInfo = function(callback) {}
chrome.mimeHandlerPrivate.abortStream = function(callback) {};
/**
* @param {function(): void=} opt_callback
* Instructs the PluginDocument, if running in one, to show a dialog in response
* to beforeunload events.
* @param {boolean} showDialog
* @param {function():void=} callback
*/
chrome.mimeHandlerPrivate.abortStream = function(opt_callback) {}
chrome.mimeHandlerPrivate.setShowBeforeUnloadDialog = function(showDialog, callback) {};
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment