Bug 1136291 - Better handle an unexpected (eg, the hidden DOM window) being the window opener when initializing the sidebar. r=Unfocused, a=gavin
authorMark Hammond <mhammond@skippinet.com.au>
Wed, 25 Feb 2015 20:51:21 +1100
changeset 257444 8a0d1a42bb4c04d308a3c5bf73652e92041c1d6e
parent 257443 256f560409edd6a4c1aba13d7f5bacecb03a433d
child 257445 72eb85afdde6e9d0382859727cd64b28beba26e3
push id4610
push userjlund@mozilla.com
push dateMon, 30 Mar 2015 18:32:55 +0000
treeherdermozilla-beta@4df54044d9ef [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersUnfocused, gavin
bugs1136291
milestone38.0a2
Bug 1136291 - Better handle an unexpected (eg, the hidden DOM window) being the window opener when initializing the sidebar. r=Unfocused, a=gavin
browser/base/content/browser-sidebar.js
--- a/browser/base/content/browser-sidebar.js
+++ b/browser/base/content/browser-sidebar.js
@@ -27,21 +27,17 @@ let SidebarUI = {
   _splitter: null,
 
   init() {
     this._box = document.getElementById("sidebar-box");
     this.browser = document.getElementById("sidebar");
     this._title = document.getElementById("sidebar-title");
     this._splitter = document.getElementById("sidebar-splitter");
 
-    if (window.opener && !window.opener.closed &&
-        window.opener.document.documentURIObject.schemeIs("chrome") &&
-        PrivateBrowsingUtils.isWindowPrivate(window) == PrivateBrowsingUtils.isWindowPrivate(window.opener)) {
-      this.adoptFromWindow(window.opener);
-    } else {
+    if (!this.adoptFromWindow(window.opener)) {
       let commandID = this._box.getAttribute("sidebarcommand");
       if (commandID) {
         let command = document.getElementById(commandID);
         if (command) {
           this._delayedLoad = true;
           this._box.hidden = false;
           this._splitter.hidden = false;
           command.setAttribute("checked", "true");
@@ -62,50 +58,67 @@ let SidebarUI = {
       document.persist("sidebar-box", "sidebarcommand");
       document.persist("sidebar-box", "width");
       document.persist("sidebar-box", "src");
       document.persist("sidebar-title", "value");
     }
   },
 
   /**
-   * Adopt the status of the sidebar from another window.
+   * Try and adopt the status of the sidebar from another window.
    * @param {Window} sourceWindow - Window to use as a source for sidebar status.
+   * @return true if we adopted the state, or false if the caller should
+   * initialize the state itself.
    */
   adoptFromWindow(sourceWindow) {
+    // No source window, or it being closed, or not chrome, or in a different
+    // private-browsing context means we can't adopt.
+    if (!sourceWindow || sourceWindow.closed ||
+        !sourceWindow.document.documentURIObject.schemeIs("chrome") ||
+        PrivateBrowsingUtils.isWindowPrivate(window) != PrivateBrowsingUtils.isWindowPrivate(sourceWindow)) {
+      return false;
+    }
+
     // If the opener had a sidebar, open the same sidebar in our window.
     // The opener can be the hidden window too, if we're coming from the state
     // where no windows are open, and the hidden window has no sidebar box.
     let sourceUI = sourceWindow.SidebarUI;
-    if (!sourceUI || sourceUI._box.hidden) {
-      return;
+    if (!sourceUI || !sourceUI._box) {
+      // no source UI or no _box means we also can't adopt the state.
+      return false;
+    }
+    if (sourceUI._box.hidden) {
+      // just hidden means we have adopted the hidden state.
+      return true;
     }
 
     let commandID = sourceUI._box.getAttribute("sidebarcommand");
     let commandElem = document.getElementById(commandID);
 
-    // dynamically generated sidebars will fail this check.
+    // dynamically generated sidebars will fail this check, but we still
+    // consider it adopted.
     if (!commandElem) {
-      return;
+      return true;
     }
 
     this._title.setAttribute("value",
                              sourceUI._title.getAttribute("value"));
     this._box.setAttribute("width", sourceUI._box.boxObject.width);
 
     this._box.setAttribute("sidebarcommand", commandID);
     // Note: we're setting 'src' on this._box, which is a <vbox>, not on
     // the <browser id="sidebar">. This lets us delay the actual load until
     // delayedStartup().
     this._box.setAttribute("src", sourceUI.browser.getAttribute("src"));
     this._delayedLoad = true;
 
     this._box.hidden = false;
     this._splitter.hidden = false;
     commandElem.setAttribute("checked", "true");
+    return true;
   },
 
   /**
    * If loading a sidebar was delayed on startup, start the load now.
    */
   startDelayedLoad() {
     if (!this._delayedLoad) {
       return;