summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--chrome/browser/ui/extensions/shell_window.cc2
-rw-r--r--chrome/common/extensions/extension_messages.h3
-rw-r--r--chrome/renderer/extensions/extension_helper.cc11
-rw-r--r--chrome/renderer/extensions/extension_helper.h1
-rw-r--r--chrome/renderer/resources/extensions/app_window_custom_bindings.js7
-rw-r--r--chrome/test/data/extensions/platform_apps/windows_api/test.js13
6 files changed, 37 insertions, 0 deletions
diff --git a/chrome/browser/ui/extensions/shell_window.cc b/chrome/browser/ui/extensions/shell_window.cc
index cbfb9b8..8d546a4 100644
--- a/chrome/browser/ui/extensions/shell_window.cc
+++ b/chrome/browser/ui/extensions/shell_window.cc
@@ -295,6 +295,8 @@ void ShellWindow::HandleKeyboardEvent(
void ShellWindow::OnNativeClose() {
extensions::ShellWindowRegistry::Get(profile_)->RemoveShellWindow(this);
+ content::RenderViewHost* rvh = web_contents_->GetRenderViewHost();
+ rvh->Send(new ExtensionMsg_AppWindowClosed(rvh->GetRoutingID()));
delete this;
}
diff --git a/chrome/common/extensions/extension_messages.h b/chrome/common/extensions/extension_messages.h
index b287b82..7c45d26 100644
--- a/chrome/common/extensions/extension_messages.h
+++ b/chrome/common/extensions/extension_messages.h
@@ -387,6 +387,9 @@ IPC_MESSAGE_ROUTED2(ExtensionMsg_AddMessageToConsole,
content::ConsoleMessageLevel /* level */,
std::string /* message */)
+// Notify the renderer that its window has closed.
+IPC_MESSAGE_ROUTED0(ExtensionMsg_AppWindowClosed)
+
// Messages sent from the renderer to the browser.
// A renderer sends this message when an extension process starts an API
diff --git a/chrome/renderer/extensions/extension_helper.cc b/chrome/renderer/extensions/extension_helper.cc
index 957360a..893c0f1 100644
--- a/chrome/renderer/extensions/extension_helper.cc
+++ b/chrome/renderer/extensions/extension_helper.cc
@@ -221,6 +221,8 @@ bool ExtensionHelper::OnMessageReceived(const IPC::Message& message) {
OnNotifyRendererViewType)
IPC_MESSAGE_HANDLER(ExtensionMsg_AddMessageToConsole,
OnAddMessageToConsole)
+ IPC_MESSAGE_HANDLER(ExtensionMsg_AppWindowClosed,
+ OnAppWindowClosed);
IPC_MESSAGE_UNHANDLED(handled = false)
IPC_END_MESSAGE_MAP()
return handled;
@@ -410,6 +412,15 @@ void ExtensionHelper::OnAddMessageToConsole(ConsoleMessageLevel level,
AddMessageToRootConsole(level, UTF8ToUTF16(message));
}
+void ExtensionHelper::OnAppWindowClosed() {
+ v8::HandleScope scope;
+ v8::Handle<v8::Context> script_context =
+ render_view()->GetWebView()->mainFrame()->mainWorldScriptContext();
+ ChromeV8Context* chrome_v8_context =
+ dispatcher_->v8_context_set().GetByV8Context(script_context);
+ chrome_v8_context->CallChromeHiddenMethod("OnAppWindowClosed", 0, NULL, NULL);
+}
+
void ExtensionHelper::DidDownloadApplicationDefinition(
const WebKit::WebURLResponse& response,
const std::string& data) {
diff --git a/chrome/renderer/extensions/extension_helper.h b/chrome/renderer/extensions/extension_helper.h
index cf9d4e2..b976511 100644
--- a/chrome/renderer/extensions/extension_helper.h
+++ b/chrome/renderer/extensions/extension_helper.h
@@ -99,6 +99,7 @@ class ExtensionHelper
void OnUpdateBrowserWindowId(int window_id);
void OnAddMessageToConsole(content::ConsoleMessageLevel level,
const std::string& message);
+ void OnAppWindowClosed();
// Callback triggered when we finish downloading the application definition
// file.
diff --git a/chrome/renderer/resources/extensions/app_window_custom_bindings.js b/chrome/renderer/resources/extensions/app_window_custom_bindings.js
index f38af8b..add512d4 100644
--- a/chrome/renderer/resources/extensions/app_window_custom_bindings.js
+++ b/chrome/renderer/resources/extensions/app_window_custom_bindings.js
@@ -46,6 +46,12 @@ chromeHidden.registerCustomHook('app.window', function(bindingsAPI) {
return chromeHidden.currentAppWindow;
});
+ chromeHidden.OnAppWindowClosed = function() {
+ if (!chromeHidden.currentAppWindow)
+ return;
+ chromeHidden.currentAppWindow.onClose.dispatch();
+ }
+
// This is an internal function, but needs to be bound with setHandleRequest
// because it is called from a different JS context
apiFunctions.setHandleRequest('initializeAppWindow', function(params) {
@@ -57,6 +63,7 @@ chromeHidden.registerCustomHook('app.window', function(bindingsAPI) {
AppWindow.prototype.moveTo = window.moveTo.bind(window);
AppWindow.prototype.resizeTo = window.resizeTo.bind(window);
AppWindow.prototype.contentWindow = window;
+ AppWindow.prototype.onClose = new chrome.Event;
Object.defineProperty(AppWindow.prototype, 'id', {get: function() {
return chromeHidden.appWindowData.id;
diff --git a/chrome/test/data/extensions/platform_apps/windows_api/test.js b/chrome/test/data/extensions/platform_apps/windows_api/test.js
index cd178da..3b70244 100644
--- a/chrome/test/data/extensions/platform_apps/windows_api/test.js
+++ b/chrome/test/data/extensions/platform_apps/windows_api/test.js
@@ -17,6 +17,7 @@ chrome.app.runtime.onLaunched.addListener(function() {
var cw = win.contentWindow.chrome.app.window.current();
chrome.test.assertEq(cw, win);
chrome.test.assertEq('testId', cw.id);
+ win.contentWindow.close();
}));
},
@@ -35,6 +36,8 @@ chrome.app.runtime.onLaunched.addListener(function() {
chrome.test.assertTrue(cw1 === win1);
chrome.test.assertTrue(cw2 === win2);
chrome.test.assertFalse(cw1 === cw2);
+ win1.contentWindow.close();
+ win2.contentWindow.close();
}));
}));
},
@@ -50,9 +53,19 @@ chrome.app.runtime.onLaunched.addListener(function() {
win.contentWindow.resizeBy(-256, 0);
chrome.test.assertEq(oldWidth - 256, win.contentWindow.outerWidth);
chrome.test.assertEq(oldHeight, win.contentWindow.outerHeight);
+ win.contentWindow.close();
}));
},
+ function testOnCloseEvent() {
+ chrome.app.window.create('test.html', callbackPass(function(win) {
+ win.onClose.addListener(callbackPass(function() {
+ // Mission accomplished.
+ }));
+ win.contentWindow.close();
+ }));
+ },
+
/*function testMaximize() {
chrome.app.window.create('test.html', {width: 200, height: 200},
callbackPass(function(win) {