Closed Bug 537449 Opened 14 years ago Closed 14 years ago

opening new (chrome) windows is broken after canceling window.onbeforeunload event (e.g. Google Docs, Mibbit)

Categories

(Toolkit :: Startup and Profile System, defect)

1.9.2 Branch
x86
Windows 7
defect
Not set
normal

Tracking

()

RESOLVED FIXED
mozilla1.9.3a1
Tracking Status
blocking1.9.2 --- .2+
status1.9.2 --- .2-fixed

People

(Reporter: alice0775, Assigned: mossop)

References

()

Details

(4 keywords, Whiteboard: [3.6.x])

Attachments

(2 files, 2 obsolete files)

User-Agent:       Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.2b6pre) Gecko/20091231 Firefox/3.5.5
Build Identifier: Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.2b6pre) Gecko/20091231 Namoroka/3.6b6pre ID:20091231052240

No new window can open after having canceled the connections close dialogue of the mibbit site.

Can not open window(dialog)
File > New Window (CTRL+N)
Help > About Namoroka
Tools > Error Console

But, can Open
Tools > Options...

Reproducible: Always

Steps to Reproduce:
1.Start Namoroka with new profile.
2.Open URL ( https://www.mibbit.com/chat/?url=irc%3A%2F%2Firc.mozilla.org%2Ffirefox ).
3.Click GO button in the page,And wait till a channel is open.
4.File > Exit (Do not use Ctrl+W).
5.Click "Cancel" button on the Confirm woindow of mibbit.
6. File > New Window (Ctrl+N) OR  Help > About Namoroka  OR  Tools > Error Console

Actual Results:  
No new window can open.

Expected Results:  
New window should open.

If you  use to close window with Ctrl+W, the issue may not happen.


This isuue happens also on trunk.
Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.3a1pre) Gecko/20100101 Minefield/3.7a1pre ID:20100101043649
Version: unspecified → 3.6 Branch
In addition to the comment #0

When Quit confirmation dialog of the browser was displayed after STEP 4,
please choose Quit.

s/Ctrl+W/Alt+F4/g
This issue does not happen on Shiretoko.
Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.8pre) Gecko/20091224 Firefox/3.5.8pre ID:20091224044156
confirmed with Mozilla/5.0 (Windows; U; Windows NT 5.1; de; rv:1.9.2b5) Gecko/20091204 Firefox/3.6b5 ID:20091204143806
OS: Windows 7 → Windows XP
Regression Window on trunk:

Works fine:
http://hg.mozilla.org/mozilla-central/rev/0ad893d220db
Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.3a1pre) Gecko/20090822 Minefield/3.7a1pre ID:20090822045824

Broken:
http://hg.mozilla.org/mozilla-central/rev/30ead1e19478
Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.3a1pre) Gecko/20090823 Minefield/3.7a1pre ID:20090823044819

Pushlog:
http://hg.mozilla.org/mozilla-central/pushloghtml?fromchange=0ad893d220db&tochange=30ead1e19478


Regression Window on branch:

Works fine:
http://hg.mozilla.org/releases/mozilla-1.9.2/rev/dbd6f214769b
Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.2a2pre) Gecko/20090904 Namoroka/3.6a2pre ID:20090904051716

Broken:
http://hg.mozilla.org/releases/mozilla-1.9.2/rev/4114e5200fbb
Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.2a2pre) Gecko/20090905 Namoroka/3.6a2pre ID:20090905053521

Pushlog:
http://hg.mozilla.org/releases/mozilla-1.9.2/pushloghtml?fromchange=dbd6f214769b&tochange=4114e5200fbb



Candidate regress bug:
Bug 480466 -  Shutdown dispatches quit-application-granted twice
OS: Windows XP → Windows 7
Component: General → Startup and Profile System
Product: Firefox → Toolkit
Version: 3.6 Branch → 1.9.2 Branch
This probrem is happens on Google Doc site too.

STR
1. GO http://docs.google.com/
2. Create a new document And edit the document.
4.File > Exit (Do not use Alt+F4).
5.Click "Cancel" button on the Confirm woindow of Google Doc.
6. File > New Window (Ctrl+N) OR  Help > About Namoroka  OR  Tools > Error
Console
Summary: No new window can open after having canceled the connections close dialogue of the mibbit site → No new window can open after having canceled the connections close dialogue of the mibbit site and Google Doc site
Attached file test case
1. Open test case
2. File > Exit
3. Cancel Confirm dialog of the test case.

No new window can open.
Keywords: testcase
Status: UNCONFIRMED → NEW
Ever confirmed: true
Summary: No new window can open after having canceled the connections close dialogue of the mibbit site and Google Doc site → opening new (chrome) windows is broken after canceling window.onbeforeunload event (e.g. Google Docs, Mibbit)
QA Contact: general → startup
Does the bug block Firefox3.6.1?
I'm not sure whether this should block 3.6(.0) or not, but we should definitely fix it ASAP.
Assignee: nobody → dtownsend
Flags: blocking1.9.2?
NS_ENSURE_SUCCESS(rv, rv) failed with result 0x8046001E: file c:/builds/mozilla-central/ff-debug/dom/base/../../../src/dom/base/nsGlobalWindow.cpp, line 7639
This is a game of whack-a-mole and I'm not sure there is a sane way to solve this case without changing the shutdown code more than I'd be happy with on branch.

The basic issue is that we decide we are going to shutdown and then ask all of the windows to close, which then asks all of the webpage if they are ok being closed. They can refuse but since we agreed in bug 480466 that once we have started shutting down we won't stop we are stuck in this limbo state.

The ideal fix would be to make a change such that we could fire all beforeunload handlers (and the various other things in nsGlobalWindow that can stall a window closing) before we send out quit-application-granted and then once we are shutting down just close the window without running any of the current checking that we do. This probably means splitting nsGLobalWindow::Close into different parts which is troubling.
Oh, then this is a lot like bug 511456, which I decided was too scary for 3.6 as well. Bah.
Attached patch patch rev 1 (obsolete) — Splinter Review
This patch splits out parts of nsGlobalWindow::Close into nsGlobalWindow::CanClose and nsGlobalWindow::ForceClose. The regular Close path is exactly the same in effect but this allows the shutdown code to all the beforeunload handlers in advance of actually dispatching quit-application-granted. We then use ForceClose to close all windows without dispatching beforeunload again.

This fixes this bug, bug 511456 and even bug 400479 by virtue of ignoring a couple of checks in Close which allows us to close even the parents of modal windows. Those checks were added as part of bug 334891 and it seems to me that bypassing them on shutdown wouldn't be an issue but I need to verify this.
What about backing out the original bug that caused this regression? Is there a significant impact to once again issuing two quit-application-granted events (bug 480466)
I think that this is relnote, but not a 1.9.2 blocker: you were going to quit the browser, and then realized that you wanted to finish something up first.  Once that's done, quitting works fine.  It's just "resurrecting" your browsing session that doesn't work, and the work-around is simple enough.

We could take for a 1.9.2.1 or so, but this code is tangled enough that it seems unlikely we would avoid regression, and need time to find them and build more complete tests to give us confidence in changes to this area of code.
Suggested relnote: When quitting the browser, if you allow a web page to cancel that action you may end up in a state where some features of the browser will no longer function properly. If you restart the browser, it will function normally.
Whiteboard: [3.6.x][needs tests]
Status: NEW → ASSIGNED
Flags: in-testsuite?
Blocks: 511456, 400479
Attached patch patch rev 2 (obsolete) — Splinter Review
Added automated tests for this and bug 511456
Attachment #421494 - Attachment is obsolete: true
Let's do continue to move along with this; who can review?
Flags: wanted1.9.2+
Flags: blocking1.9.2?
Flags: blocking1.9.2-
(In reply to comment #17)
> Let's do continue to move along with this; who can review?

Running a final iteration of this through the try server now then I'll upload and request review, probably in the next hour or so
Attached patch patch rev 3Splinter Review
Final patch for review. This patch should leave nsGlobalWindow::Close doing exactly the same as it did before and adds a method nsGlobalWindow::ForceClose that has the following differences:

* Doesn't check IsInModalState, this was only in place to fix bug 334891, something I believe we can safely skip during shutdown.
* Doesn't check mBlockScriptedClosingFlag, if we're shutting down the user probably doesn't care about blocked popups.
* Doesn't check that the script caller is trusted, ForceClose isn't available to scripts.
* Doesn't call the content viewer's PermitUnload and RequestWindowClose, these are made available in the new CanClose method that we call earlier in the shutdown.
* Does dispatch the DOMWindowClose event but ignores whether a listener tried to prevent the default action.

I think this patch is safer than I originally expected it to be and doesn't change APIs in a way that would break extensions so I think it is safe for the branch too.
Attachment #421663 - Attachment is obsolete: true
Attachment #421918 - Flags: review?(jst)
Attachment #421918 - Flags: review?(benjamin)
Whiteboard: [3.6.x][needs tests] → [3.6.x]
blocking1.9.2: --- → ?
blocking1.9.2: ? → .1+
mozilla1.9.2.1 = Firefox 1.0 for Maemo, moving this to .2+
blocking1.9.2: .1+ → .2+
Comment on attachment 421918 [details] [diff] [review]
patch rev 3

- In nsGlobalWindow::CanClose():

+{
+  // Ask the content viewer whether the toplevel window can close.
+  // If the content viewer returns false, it is responsible for calling
+  // Close() as soon as it is possible for the window to close.
+  // This allows us to not close the window while printing is happening.
+
+  nsCOMPtr<nsIContentViewer> cv;
+  mDocShell->GetContentViewer(getter_AddRefs(cv));

Given that this is a public method on nsGlobalWindow, I'd say it should protect itself against the case where mDocShell is null (already, or still).

r=jst with that for the DOM changes here.
Attachment #421918 - Flags: review?(jst) → review+
Comment on attachment 421918 [details] [diff] [review]
patch rev 3

>diff --git a/toolkit/components/startup/Makefile.in b/toolkit/components/startup/Makefile.in

>+ifdef ENABLE_TESTS
>+	DIRS += tests
>+endif

nit, no tabs please

>diff --git a/toolkit/components/startup/src/nsAppStartup.cpp b/toolkit/components/startup/src/nsAppStartup.cpp
>--- a/toolkit/components/startup/src/nsAppStartup.cpp
>+++ b/toolkit/components/startup/src/nsAppStartup.cpp
>@@ -37,16 +37,17 @@
>  * the provisions above, a recipient may use your version of this file under
>  * the terms of any one of the MPL, the GPL or the LGPL.
>  *
>  * ***** END LICENSE BLOCK ***** */
> 
> #include "nsAppStartup.h"
> 
> #include "nsIAppShellService.h"
>+#include "nsPIDOMWindow.h"
> #include "nsIDOMWindowInternal.h"
> #include "nsIInterfaceRequestor.h"
> #include "nsILocalFile.h"
> #include "nsIObserverService.h"
> #include "nsIPrefBranch.h"
> #include "nsIPrefService.h"
> #include "nsIProfileChangeStatus.h"
> #include "nsIPromptService.h"
>@@ -226,23 +227,41 @@ nsAppStartup::Quit(PRUint32 aMode)
>       if (!hiddenWindow || usefulHiddenWindow)
>         return NS_OK;
> 
>       ferocity = eAttemptQuit;
>     }
> #endif
>   }
> 
>-  mShuttingDown = PR_TRUE;
>-  if (!mRestart) 
>-      mRestart = (aMode & eRestart) != 0;
>-
>   nsCOMPtr<nsIObserverService> obsService;
>   if (ferocity == eAttemptQuit || ferocity == eForceQuit) {
> 
>+    nsCOMPtr<nsISimpleEnumerator> windowEnumerator;
>+    nsCOMPtr<nsIWindowMediator> mediator (do_GetService(NS_WINDOWMEDIATOR_CONTRACTID));
>+    if (mediator) {
>+      mediator->GetEnumerator(nsnull, getter_AddRefs(windowEnumerator));
>+      if (windowEnumerator) {
>+        PRBool more;
>+        while (windowEnumerator->HasMoreElements(&more), more) {
>+          nsCOMPtr<nsISupports> window;
>+          windowEnumerator->GetNext(getter_AddRefs(window));
>+          nsCOMPtr<nsPIDOMWindow> domWindow(do_QueryInterface(window));
>+          if (domWindow) {
>+            if (!domWindow->CanClose())
>+              return NS_OK;
>+          }
>+        }
>+      }
>+    }
>+
>+    mShuttingDown = PR_TRUE;
>+    if (!mRestart)
>+      mRestart = (aMode & eRestart) != 0;
>+
>     obsService = do_GetService("@mozilla.org/observer-service;1");
> 
>     if (!mAttemptingQuit) {
>       mAttemptingQuit = PR_TRUE;
> #ifdef XP_MACOSX
>       // now even the Mac wants to quit when the last window is closed
>       ExitLastWindowClosingSurvivalArea();
> #endif
>@@ -251,22 +270,18 @@ nsAppStartup::Quit(PRUint32 aMode)
>     }
> 
>     /* Enumerate through each open window and close it. It's important to do
>        this before we forcequit because this can control whether we really quit
>        at all. e.g. if one of these windows has an unload handler that
>        opens a new window. Ugh. I know. */
>     CloseAllWindows();
> 
>-    nsCOMPtr<nsIWindowMediator> mediator
>-      (do_GetService(NS_WINDOWMEDIATOR_CONTRACTID));
>     if (mediator) {
>       if (ferocity == eAttemptQuit) {
>-        nsCOMPtr<nsISimpleEnumerator> windowEnumerator;
>-
>         ferocity = eForceQuit; // assume success
> 
>         /* Were we able to immediately close all windows? if not, eAttemptQuit
>            failed. This could happen for a variety of reasons; in fact it's
>            very likely. Perhaps we're being called from JS and the window->Close
>            method hasn't had a chance to wrap itself up yet. So give up.
>            We'll return (with eConsiderQuit) as the remaining windows are
>            closed. */
>@@ -346,20 +361,20 @@ nsAppStartup::CloseAllWindows()
>     return;
> 
>   PRBool more;
>   while (NS_SUCCEEDED(windowEnumerator->HasMoreElements(&more)) && more) {
>     nsCOMPtr<nsISupports> isupports;
>     if (NS_FAILED(windowEnumerator->GetNext(getter_AddRefs(isupports))))
>       break;
> 
>-    nsCOMPtr<nsIDOMWindowInternal> window = do_QueryInterface(isupports);
>-    NS_ASSERTION(window, "not an nsIDOMWindowInternal");
>+    nsCOMPtr<nsPIDOMWindow> window = do_QueryInterface(isupports);
>+    NS_ASSERTION(window, "not an nsPIDOMWindow");
>     if (window)
>-      window->Close();
>+      window->ForceClose();
>   }
> }
> 
> NS_IMETHODIMP
> nsAppStartup::EnterLastWindowClosingSurvivalArea(void)
> {
>   ++mConsiderQuitStopper;
>   return NS_OK;
>diff --git a/toolkit/components/startup/tests/Makefile.in b/toolkit/components/startup/tests/Makefile.in
>new file mode 100644
>--- /dev/null
>+++ b/toolkit/components/startup/tests/Makefile.in
>@@ -0,0 +1,49 @@
>+# ***** BEGIN LICENSE BLOCK *****
>+# Version: MPL 1.1/GPL 2.0/LGPL 2.1
>+#
>+# The contents of this file are subject to the Mozilla Public License Version
>+# 1.1 (the "License"); you may not use this file except in compliance with
>+# the License. You may obtain a copy of the License at
>+# http://www.mozilla.org/MPL/
>+#
>+# Software distributed under the License is distributed on an "AS IS" basis,
>+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
>+# for the specific language governing rights and limitations under the
>+# License.
>+#
>+# The Original Code is mozilla.org code.
>+#
>+# The Initial Developer of the Original Code is
>+# Mozilla.org.
>+# Portions created by the Initial Developer are Copyright (C) 2010
>+# the Initial Developer. All Rights Reserved.
>+#
>+# Contributor(s):
>+#     Dave Townsend <dtownsend@oxymoronical.com>  (Original author)
>+#
>+# Alternatively, the contents of this file may be used under the terms of
>+# either of the GNU General Public License Version 2 or later (the "GPL"),
>+# or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
>+# in which case the provisions of the GPL or the LGPL are applicable instead
>+# of those above. If you wish to allow use of your version of this file only
>+# under the terms of either the GPL or the LGPL, and not to allow others to
>+# use your version of this file under the terms of the MPL, indicate your
>+# decision by deleting the provisions above and replace them with the notice
>+# and other provisions required by the GPL or the LGPL. If you do not delete
>+# the provisions above, a recipient may use your version of this file under
>+# the terms of any one of the MPL, the GPL or the LGPL.
>+#
>+# ***** END LICENSE BLOCK *****
>+
>+DEPTH		= ../../../..
>+topsrcdir	= @top_srcdir@
>+srcdir		= @srcdir@
>+VPATH		= @srcdir@
>+
>+include $(DEPTH)/config/autoconf.mk
>+
>+DIRS = \
>+	browser \
>+	$(NULL)
>+
>+include $(topsrcdir)/config/rules.mk
>diff --git a/toolkit/components/startup/tests/browser/Makefile.in b/toolkit/components/startup/tests/browser/Makefile.in
>new file mode 100644
>--- /dev/null
>+++ b/toolkit/components/startup/tests/browser/Makefile.in
>@@ -0,0 +1,54 @@
>+# ***** BEGIN LICENSE BLOCK *****
>+# Version: MPL 1.1/GPL 2.0/LGPL 2.1
>+#
>+# The contents of this file are subject to the Mozilla Public License Version
>+# 1.1 (the "License"); you may not use this file except in compliance with
>+# the License. You may obtain a copy of the License at
>+# http://www.mozilla.org/MPL/
>+#
>+# Software distributed under the License is distributed on an "AS IS" basis,
>+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
>+# for the specific language governing rights and limitations under the
>+# License.
>+#
>+# The Original Code is mozilla.org code.
>+#
>+# The Initial Developer of the Original Code is
>+# Mozilla Corporation.
>+# Portions created by the Initial Developer are Copyright (C) 2010
>+# the Initial Developer. All Rights Reserved.
>+#
>+# Contributor(s):
>+#   Dave Townsend <dtownsend@oxymoronical.com> (Original Author)
>+#
>+# Alternatively, the contents of this file may be used under the terms of
>+# either of the GNU General Public License Version 2 or later (the "GPL"),
>+# or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
>+# in which case the provisions of the GPL or the LGPL are applicable instead
>+# of those above. If you wish to allow use of your version of this file only
>+# under the terms of either the GPL or the LGPL, and not to allow others to
>+# use your version of this file under the terms of the MPL, indicate your
>+# decision by deleting the provisions above and replace them with the notice
>+# and other provisions required by the GPL or the LGPL. If you do not delete
>+# the provisions above, a recipient may use your version of this file under
>+# the terms of any one of the MPL, the GPL or the LGPL.
>+#
>+# ***** END LICENSE BLOCK *****
>+
>+DEPTH		= ../../../../..
>+topsrcdir	= @top_srcdir@
>+srcdir		= @srcdir@
>+VPATH		= @srcdir@
>+relativesrcdir  = toolkit/components/startup/tests/browser
>+
>+include $(DEPTH)/config/autoconf.mk
>+include $(topsrcdir)/config/rules.mk
>+
>+_BROWSER_FILES = \
>+	browser_bug511456.js \
>+	browser_bug537449.js \
>+	beforeunload.html \
>+	$(NULL)
>+
>+libs:: $(_BROWSER_FILES)
>+	$(INSTALL) $(foreach f,$^,"$f") $(DEPTH)/_tests/testing/mochitest/browser/$(relativesrcdir)
>diff --git a/toolkit/components/startup/tests/browser/beforeunload.html b/toolkit/components/startup/tests/browser/beforeunload.html
>new file mode 100644
>--- /dev/null
>+++ b/toolkit/components/startup/tests/browser/beforeunload.html
>@@ -0,0 +1,10 @@
>+<html>
>+  <script>
>+  window.onbeforeunload = function(event){
>+    event.returnValue = 'Test beforeunload handler';
>+  }
>+  </script>
>+  <body>
>+    Test page
>+  </body>
>+</html>
>diff --git a/toolkit/components/startup/tests/browser/browser_bug511456.js b/toolkit/components/startup/tests/browser/browser_bug511456.js
>new file mode 100644
>--- /dev/null
>+++ b/toolkit/components/startup/tests/browser/browser_bug511456.js
>@@ -0,0 +1,123 @@
>+/* ***** BEGIN LICENSE BLOCK *****
>+ *   Version: MPL 1.1/GPL 2.0/LGPL 2.1
>+ *
>+ * The contents of this file are subject to the Mozilla Public License Version
>+ * 1.1 (the "License"); you may not use this file except in compliance with
>+ * the License. You may obtain a copy of the License at
>+ * http://www.mozilla.org/MPL/
>+ * 
>+ * Software distributed under the License is distributed on an "AS IS" basis,
>+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
>+ * for the specific language governing rights and limitations under the
>+ * License.
>+ *
>+ * The Original Code is mozilla.org code.
>+ *
>+ * The Initial Developer of the Original Code is
>+ * Mozilla Corporation.
>+ * Portions created by the Initial Developer are Copyright (C) 2010
>+ * the Initial Developer. All Rights Reserved.
>+ *
>+ * Contributor(s):
>+ *   Dave Townsend <dtownsend@oxymoronical.com> (Original Author)
>+ *
>+ * Alternatively, the contents of this file may be used under the terms of
>+ * either the GNU General Public License Version 2 or later (the "GPL"), or
>+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
>+ * in which case the provisions of the GPL or the LGPL are applicable instead
>+ * of those above. If you wish to allow use of your version of this file only
>+ * under the terms of either the GPL or the LGPL, and not to allow others to
>+ * use your version of this file under the terms of the MPL, indicate your
>+ * decision by deleting the provisions above and replace them with the notice
>+ * and other provisions required by the GPL or the LGPL. If you do not delete
>+ * the provisions above, a recipient may use your version of this file under
>+ * the terms of any one of the MPL, the GPL or the LGPL.
>+ * 
>+ * ***** END LICENSE BLOCK ***** */
>+
>+const Cc = Components.classes;
>+const Ci = Components.interfaces;
>+
>+const PROMPT_URL = "chrome://global/content/commonDialog.xul";
>+const TEST_URL = "http://example.com/browser/toolkit/components/startup/tests/browser/beforeunload.html";
>+
>+var Watcher = {
>+  seen: false,
>+  allowClose: false,
>+
>+  // Window open handling
>+  windowLoad: function(win) {
>+    // Allow any other load handlers to execute
>+    var self = this;
>+    executeSoon(function() { self.windowReady(win); } );
>+  },
>+
>+  windowReady: function(win) {
>+    if (win.document.location.href != PROMPT_URL)
>+      return;
>+    this.seen = true;
>+    if (this.allowClose)
>+      win.document.documentElement.acceptDialog();
>+    else
>+      win.document.documentElement.cancelDialog();
>+  },
>+
>+  // nsIWindowMediatorListener
>+
>+  onWindowTitleChange: function(win, title) {
>+  },
>+
>+  onOpenWindow: function(win) {
>+    var domwindow = win.QueryInterface(Components.interfaces.nsIInterfaceRequestor)
>+                       .getInterface(Components.interfaces.nsIDOMWindowInternal);
>+    var self = this;
>+    domwindow.addEventListener("load", function() {
>+      self.windowLoad(domwindow);
>+    }, false);
>+  },
>+
>+  onCloseWindow: function(win) {
>+  },
>+
>+  QueryInterface: function(iid) {
>+    if (iid.equals(Components.interfaces.nsIWindowMediatorListener) ||
>+        iid.equals(Components.interfaces.nsISupports))
>+      return this;
>+
>+    throw Components.results.NS_ERROR_NO_INTERFACE;
>+  }
>+}
>+
>+function test() {
>+  waitForExplicitFinish();
>+
>+  var wm = Components.classes["@mozilla.org/appshell/window-mediator;1"]
>+                     .getService(Components.interfaces.nsIWindowMediator);
>+  wm.addListener(Watcher);
>+
>+  var win2 = OpenBrowserWindow();
>+  win2.addEventListener("load", function() {
>+    win2.removeEventListener("load", arguments.callee, false);
>+    gBrowser.selectedTab = gBrowser.addTab(TEST_URL);
>+    gBrowser.addEventListener("load", function() {
>+      if (window.content.location.href != TEST_URL)
>+        return;
>+      gBrowser.removeEventListener("load", arguments.callee, false);
>+      Watcher.seen = false;
>+      goQuitApplication();
>+      Watcher.allowClose = true;
>+      ok(Watcher.seen, "Should have seen a prompt dialog");
>+      ok(!win2.closed, "Shouldn't have closed the additional window");
>+      win2.close();
>+      gBrowser.removeTab(gBrowser.selectedTab);
>+      finish_test();
>+    }, false);
>+  }, false);
>+}
>+
>+function finish_test() {
>+  var wm = Components.classes["@mozilla.org/appshell/window-mediator;1"]
>+                     .getService(Components.interfaces.nsIWindowMediator);
>+  wm.removeListener(Watcher);
>+  finish();
>+}
>diff --git a/toolkit/components/startup/tests/browser/browser_bug537449.js b/toolkit/components/startup/tests/browser/browser_bug537449.js
>new file mode 100644
>--- /dev/null
>+++ b/toolkit/components/startup/tests/browser/browser_bug537449.js
>@@ -0,0 +1,124 @@
>+/* ***** BEGIN LICENSE BLOCK *****
>+ *   Version: MPL 1.1/GPL 2.0/LGPL 2.1
>+ *
>+ * The contents of this file are subject to the Mozilla Public License Version
>+ * 1.1 (the "License"); you may not use this file except in compliance with
>+ * the License. You may obtain a copy of the License at
>+ * http://www.mozilla.org/MPL/
>+ * 
>+ * Software distributed under the License is distributed on an "AS IS" basis,
>+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
>+ * for the specific language governing rights and limitations under the
>+ * License.
>+ *
>+ * The Original Code is mozilla.org code.
>+ *
>+ * The Initial Developer of the Original Code is
>+ * Mozilla Corporation.
>+ * Portions created by the Initial Developer are Copyright (C) 2010
>+ * the Initial Developer. All Rights Reserved.
>+ *
>+ * Contributor(s):
>+ *   Dave Townsend <dtownsend@oxymoronical.com> (Original Author)
>+ *
>+ * Alternatively, the contents of this file may be used under the terms of
>+ * either the GNU General Public License Version 2 or later (the "GPL"), or
>+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
>+ * in which case the provisions of the GPL or the LGPL are applicable instead
>+ * of those above. If you wish to allow use of your version of this file only
>+ * under the terms of either the GPL or the LGPL, and not to allow others to
>+ * use your version of this file under the terms of the MPL, indicate your
>+ * decision by deleting the provisions above and replace them with the notice
>+ * and other provisions required by the GPL or the LGPL. If you do not delete
>+ * the provisions above, a recipient may use your version of this file under
>+ * the terms of any one of the MPL, the GPL or the LGPL.
>+ * 
>+ * ***** END LICENSE BLOCK ***** */
>+
>+const Cc = Components.classes;
>+const Ci = Components.interfaces;
>+
>+const PROMPT_URL = "chrome://global/content/commonDialog.xul";
>+const TEST_URL = "http://example.com/browser/toolkit/components/startup/tests/browser/beforeunload.html";
>+
>+var Watcher = {
>+  seen: false,
>+  allowClose: false,
>+
>+  // Window open handling
>+  windowLoad: function(win) {
>+    // Allow any other load handlers to execute
>+    var self = this;
>+    executeSoon(function() { self.windowReady(win); } );
>+  },
>+
>+  windowReady: function(win) {
>+    if (win.document.location.href != PROMPT_URL)
>+      return;
>+    this.seen = true;
>+    if (this.allowClose)
>+      win.document.documentElement.acceptDialog();
>+    else
>+      win.document.documentElement.cancelDialog();
>+  },
>+
>+  // nsIWindowMediatorListener
>+
>+  onWindowTitleChange: function(win, title) {
>+  },
>+
>+  onOpenWindow: function(win) {
>+    var domwindow = win.QueryInterface(Components.interfaces.nsIInterfaceRequestor)
>+                       .getInterface(Components.interfaces.nsIDOMWindowInternal);
>+    var self = this;
>+    domwindow.addEventListener("load", function() {
>+      self.windowLoad(domwindow);
>+    }, false);
>+  },
>+
>+  onCloseWindow: function(win) {
>+  },
>+
>+  QueryInterface: function(iid) {
>+    if (iid.equals(Components.interfaces.nsIWindowMediatorListener) ||
>+        iid.equals(Components.interfaces.nsISupports))
>+      return this;
>+
>+    throw Components.results.NS_ERROR_NO_INTERFACE;
>+  }
>+}
>+
>+function test() {
>+  waitForExplicitFinish();
>+
>+  var wm = Components.classes["@mozilla.org/appshell/window-mediator;1"]
>+                     .getService(Components.interfaces.nsIWindowMediator);
>+  wm.addListener(Watcher);
>+
>+  gBrowser.selectedTab = gBrowser.addTab(TEST_URL);
>+  gBrowser.addEventListener("load", function() {
>+    if (window.content.location.href != TEST_URL)
>+      return;
>+    gBrowser.removeEventListener("load", arguments.callee, false);
>+    Watcher.seen = false;
>+    goQuitApplication();
>+    Watcher.allowClose = true;
>+    ok(Watcher.seen, "Should have seen a prompt dialog");
>+    ok(!window.closed, "Shouldn't have closed the window");
>+    var win2 = OpenBrowserWindow();
>+    ok(win2 != null, "Should have been able to open a new window");
>+    win2.addEventListener("load", function() {
>+      win2.removeEventListener("load", arguments.callee, false);
>+      win2.close();
>+      gBrowser.removeTab(gBrowser.selectedTab);
>+      finish_test();
>+    }, false);
>+  }, false);
>+}
>+
>+function finish_test() {
>+  var wm = Components.classes["@mozilla.org/appshell/window-mediator;1"]
>+                     .getService(Components.interfaces.nsIWindowMediator);
>+  wm.removeListener(Watcher);
>+  finish();
>+}
Attachment #421918 - Flags: review?(benjamin) → review+
Landed on trunk: http://hg.mozilla.org/mozilla-central/rev/234146dafae3
Status: ASSIGNED → RESOLVED
Closed: 14 years ago
Resolution: --- → FIXED
Target Milestone: --- → mozilla1.9.3a1
Depends on: 542950
Dave: does this patch apply cleanly to 1.9.2? If so, can you nominate for approval?
Attachment #421918 - Flags: approval1.9.2.2?
Comment on attachment 421918 [details] [diff] [review]
patch rev 3

a1922=beltzner
Attachment #421918 - Flags: approval1.9.2.2? → approval1.9.2.2+
verified with: Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.2.3pre) Gecko/20100322 Namoroka/3.6.3pre
Keywords: verified1.9.2
You need to log in before you can comment on or make changes to this bug.