Bug 332195 - part 6: make an exception for beforeunload events while tabview is open, r=mconley
authorGijs Kruitbosch <gijskruitbosch@gmail.com>
Mon, 26 Oct 2015 14:17:16 +0100
changeset 304756 31033f04e561f64b6bb2a86e065d5b226616cfe4
parent 304755 a60f220db385060583af460764abd87cd628c01e
child 304757 18427d3815fc527f9c334a20aca678f03952691b
push id1001
push userraliiev@mozilla.com
push dateMon, 18 Jan 2016 19:06:03 +0000
treeherdermozilla-release@8b89261f3ac4 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmconley
bugs332195
milestone44.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 332195 - part 6: make an exception for beforeunload events while tabview is open, r=mconley
browser/base/content/tabbrowser.xml
browser/modules/RemotePrompt.jsm
toolkit/components/prompts/src/nsPrompter.js
--- a/browser/base/content/tabbrowser.xml
+++ b/browser/base/content/tabbrowser.xml
@@ -4341,17 +4341,21 @@
           let tabForEvent = targetIsWindow ?
                             this._getTabForContentWindow(event.target.top) :
                             this.getTabForBrowser(event.originalTarget);
 
           // Don't need to act if the tab is already selected:
           if (tabForEvent.selected)
             return;
 
+          // If this is a tabprompt, and we're not in tabview/panorama with
+          // the prompt being a beforeunload one, we won't switch tabs
+          // (unless this behaviour has been disabled entirely using the pref).
           if (event.detail && event.detail.tabPrompt &&
+              !(event.detail.inPermitUnload && ("TabView" in window) && TabView.isVisible()) &&
               Services.prefs.getBoolPref("browser.tabs.dontfocusfordialogs")) {
             let docPrincipal = targetIsWindow ? event.target.document.nodePrincipal : null;
             // At least one of these should/will be non-null:
             let promptPrincipal = event.detail.promptPrincipal || docPrincipal ||
                                   tabForEvent.linkedBrowser.contentPrincipal;
             // For null principals, we bail immediately and don't show the checkbox:
             if (!promptPrincipal || promptPrincipal.isNullPrincipal) {
               tabForEvent.setAttribute("attention", "true");
--- a/browser/modules/RemotePrompt.jsm
+++ b/browser/modules/RemotePrompt.jsm
@@ -58,17 +58,21 @@ var RemotePrompt = {
       browser.messageManager.removeMessageListener("Prompt:ForceClose", listener);
 
       if (newPrompt) {
         newPrompt.abortPrompt();
       }
     });
 
     try {
-      let eventDetail = {tabPrompt: true, promptPrincipal: args.promptPrincipal};
+      let eventDetail = {
+        tabPrompt: true,
+        promptPrincipal: args.promptPrincipal,
+        inPermitUnload: args.inPermitUnload,
+      };
       PromptUtils.fireDialogEvent(window, "DOMWillOpenModalDialog", browser, eventDetail);
 
       args.promptActive = true;
 
       newPrompt = tabPrompt.appendPrompt(args, onPromptClose);
 
       // TODO since we don't actually open a window, need to check if
       // there's other stuff in nsWindowWatcher::OpenWindowInternal
--- a/toolkit/components/prompts/src/nsPrompter.js
+++ b/toolkit/components/prompts/src/nsPrompter.js
@@ -366,17 +366,20 @@ function openModalWindow(domWin, uri, ar
     // Note that we don't need to fire DOMWillOpenModalDialog and
     // DOMModalDialogClosed events here, wwatcher's OpenWindowInternal
     // will do that. Similarly for enterModalState / leaveModalState.
 
     Services.ww.openWindow(domWin, uri, "_blank", "centerscreen,chrome,modal,titlebar", args);
 }
 
 function openTabPrompt(domWin, tabPrompt, args) {
-    let eventDetail = Cu.cloneInto({tabPrompt: true}, domWin);
+    let docShell = domWin.QueryInterface(Ci.nsIInterfaceRequestor)
+                         .getInterface(Ci.nsIDocShell);
+    let inPermitUnload = docShell.contentViewer && docShell.contentViewer.inPermitUnload;
+    let eventDetail = Cu.cloneInto({tabPrompt: true, inPermitUnload}, domWin);
     PromptUtils.fireDialogEvent(domWin, "DOMWillOpenModalDialog", null, eventDetail);
 
     let winUtils = domWin.QueryInterface(Ci.nsIInterfaceRequestor)
                          .getInterface(Ci.nsIDOMWindowUtils);
     winUtils.enterModalState();
 
     // We provide a callback so the prompt can close itself. We don't want to
     // wait for this event loop to return... Otherwise the presence of other
@@ -429,24 +432,24 @@ function openTabPrompt(domWin, tabPrompt
     } finally {
         // If the prompt unexpectedly failed to invoke the callback, do so here.
         if (!callbackInvoked)
             onPromptClose(true);
     }
 }
 
 function openRemotePrompt(domWin, args, tabPrompt) {
-    let messageManager = domWin.QueryInterface(Ci.nsIInterfaceRequestor)
-                         .getInterface(Ci.nsIWebNavigation)
-                         .QueryInterface(Ci.nsIDocShell)
-                         .QueryInterface(Ci.nsIInterfaceRequestor)
-                         .getInterface(Ci.nsITabChild)
-                         .messageManager;
+    let docShell = domWin.QueryInterface(Ci.nsIInterfaceRequestor)
+                         .getInterface(Ci.nsIDocShell);
+    let messageManager = docShell.QueryInterface(Ci.nsIInterfaceRequestor)
+                                 .getInterface(Ci.nsITabChild)
+                                 .messageManager;
 
-    let eventDetail = Cu.cloneInto({tabPrompt}, domWin);
+    let inPermitUnload = docShell.contentViewer && docShell.contentViewer.inPermitUnload;
+    let eventDetail = Cu.cloneInto({tabPrompt, inPermitUnload}, domWin);
     PromptUtils.fireDialogEvent(domWin, "DOMWillOpenModalDialog", null, eventDetail);
 
     let winUtils = domWin.QueryInterface(Ci.nsIInterfaceRequestor)
                          .getInterface(Ci.nsIDOMWindowUtils);
     winUtils.enterModalState();
     let closed = false;
 
     // It should be hard or impossible to cause a window to create multiple