Bug 896748 - Electrolysis: Html 5 notification permission request box doesn't open. r=felipe
authorTom Schuster <evilpies@gmail.com>
Mon, 22 Jul 2013 20:24:11 -0400
changeset 143959 7ca66a4c4c5eef600c7f368b75a8214776d23853
parent 143958 7475b29219347debfb282f68ea0862e7964476f3
child 143960 4d2adaf69288e5f9cbd3a69ef1bc7aa6d22bde17
push id25144
push userryanvm@gmail.com
push dateFri, 23 Aug 2013 00:46:32 +0000
treeherdermozilla-central@581251a392cd [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersfelipe
bugs896748
milestone26.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 896748 - Electrolysis: Html 5 notification permission request box doesn't open. r=felipe
browser/components/nsBrowserGlue.js
toolkit/modules/PopupNotifications.jsm
--- a/browser/components/nsBrowserGlue.js
+++ b/browser/components/nsBrowserGlue.js
@@ -1762,26 +1762,30 @@ ContentPermissionPrompt.prototype = {
   _showPrompt: function CPP_showPrompt(aRequest, aMessage, aPermission, aActions,
                                        aNotificationId, aAnchorId, aOptions) {
     function onFullScreen() {
       popup.remove();
     }
 
     var browserBundle = Services.strings.createBundle("chrome://browser/locale/browser.properties");
 
-    var requestingWindow = aRequest.window.top;
-    var chromeWin = this._getChromeWindow(requestingWindow).wrappedJSObject;
-    var browser = chromeWin.gBrowser.getBrowserForDocument(requestingWindow.document);
+    var browser;
+    try {
+      // "element" is only defined in e10s mode, otherwise it throws.
+      browser = aRequest.element;
+    } catch (e) {}
     if (!browser) {
+      var requestingWindow = aRequest.window.top;
       // find the requesting browser or iframe
       browser = requestingWindow.QueryInterface(Ci.nsIInterfaceRequestor)
                                   .getInterface(Ci.nsIWebNavigation)
                                   .QueryInterface(Ci.nsIDocShell)
                                   .chromeEventHandler;
     }
+    var chromeWin = browser.ownerDocument.defaultView;
     var requestPrincipal = aRequest.principal;
 
     // Transform the prompt actions into PopupNotification actions.
     var popupNotificationActions = [];
     for (var i = 0; i < aActions.length; i++) {
       let promptAction = aActions[i];
 
       // Don't offer action in PB mode if the action remembers permission for more than a session.
--- a/toolkit/modules/PopupNotifications.jsm
+++ b/toolkit/modules/PopupNotifications.jsm
@@ -263,32 +263,33 @@ PopupNotifications.prototype = {
 
     let existingNotification = this.getNotification(id, browser);
     if (existingNotification)
       this._remove(existingNotification);
 
     let notifications = this._getNotificationsForBrowser(browser);
     notifications.push(notification);
 
+    let isActive = this._isActiveBrowser(browser);
     let fm = Cc["@mozilla.org/focus-manager;1"].getService(Ci.nsIFocusManager);
-    if (browser.docShell.isActive && fm.activeWindow == this.window) {
+    if (isActive && fm.activeWindow == this.window) {
       // show panel now
       this._update(notifications, notification.anchorElement, true);
     } else {
       // Otherwise, update() will display the notification the next time the
       // relevant tab/window is selected.
 
       // If the tab is selected but the window is in the background, let the OS
       // tell the user that there's a notification waiting in that window.
       // At some point we might want to do something about background tabs here
       // too. When the user switches to this window, we'll show the panel if
       // this browser is a tab (thus showing the anchor icon). For
       // non-tabbrowser browsers, we need to make the icon visible now or the
       // user will not be able to open the panel.
-      if (!notification.dismissed && browser.docShell.isActive) {
+      if (!notification.dismissed && isActive) {
         this.window.getAttention();
         if (notification.anchorElement.parentNode != this.iconBox) {
           notification.anchorElement.setAttribute(ICON_ATTRIBUTE_SHOWING, "true");
         }
       }
 
       // Notify observers that we're not showing the popup (useful for testing)
       this._notify("backgroundShow");
@@ -342,17 +343,17 @@ PopupNotifications.prototype = {
       }
 
       this._fireCallback(notification, NOTIFICATION_EVENT_REMOVED);
       return false;
     }, this);
 
     this._setNotificationsForBrowser(aBrowser, notifications);
 
-    if (aBrowser.docShell.isActive) {
+    if (this._isActiveBrowser(aBrowser)) {
       // get the anchor element if the browser has defined one so it will
       // _update will handle both the tabs iconBox and non-tab permission
       // anchors.
       let anchorElement = notifications.length > 0 ? notifications[0].anchorElement : null;
       if (!anchorElement)
         anchorElement = getAnchorFromBrowser(aBrowser);
       this._update(notifications, anchorElement);
     }
@@ -360,18 +361,18 @@ PopupNotifications.prototype = {
 
   /**
    * Removes a Notification.
    * @param notification
    *        The Notification object to remove.
    */
   remove: function PopupNotifications_remove(notification) {
     this._remove(notification);
-    
-    if (notification.browser.docShell.isActive) {
+
+    if (this._isActiveBrowser(notification.browser)) {
       let notifications = this._getNotificationsForBrowser(notification.browser);
       this._update(notifications, notification.anchorElement);
     }
   },
 
   handleEvent: function (aEvent) {
     switch (aEvent.type) {
       case "popuphidden":
@@ -413,17 +414,17 @@ PopupNotifications.prototype = {
     let notifications = this._getNotificationsForBrowser(notification.browser);
     if (!notifications)
       return;
 
     var index = notifications.indexOf(notification);
     if (index == -1)
       return;
 
-    if (notification.browser.docShell.isActive)
+    if (this._isActiveBrowser(notification.browser))
       notification.anchorElement.removeAttribute(ICON_ATTRIBUTE_SHOWING);
 
     // remove the notification
     notifications.splice(index, 1);
     this._fireCallback(notification, NOTIFICATION_EVENT_REMOVED);
   },
 
   /**
@@ -699,16 +700,24 @@ PopupNotifications.prototype = {
     }
     return notifications;
   },
   _setNotificationsForBrowser: function PopupNotifications_setNotifications(browser, notifications) {
     popupNotificationsMap.set(browser, notifications);
     return notifications;
   },
 
+  _isActiveBrowser: function (browser) {
+    // Note: This helper only exists, because in e10s builds,
+    // we can't access the docShell of a browser from chrome.
+    return browser.docShell
+      ? browser.docShell.isActive
+      : (this.window.gBrowser.selectedBrowser == browser);
+  },
+
   _onIconBoxCommand: function PopupNotifications_onIconBoxCommand(event) {
     // Left click, space or enter only
     let type = event.type;
     if (type == "click" && event.button != 0)
       return;
 
     if (type == "keypress" &&
         !(event.charCode == Ci.nsIDOMKeyEvent.DOM_VK_SPACE ||