Bug 1279833 - Make less use of gBrowser and content tabs in devtools. r=jwalker
authorPhilipp Kewisch [:Fallen] <philipp@bugzilla.kewis.ch>
Tue, 28 Jun 2016 11:07:09 +0200
changeset 302759 3f58f958a9827ccfb5fd4431ba9e16b09517a694
parent 302758 6b8a1c9c02517bb47d61eadece83273863cb32d5
child 302760 cdf597c785e44dff4b4de211b65c3ddf72ee11dc
push id19790
push usercbook@mozilla.com
push dateTue, 28 Jun 2016 13:32:55 +0000
treeherderfx-team@cdf597c785e4 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjwalker
bugs1279833
milestone50.0a1
Bug 1279833 - Make less use of gBrowser and content tabs in devtools. r=jwalker
devtools/client/eyedropper/eyedropper.js
devtools/client/scratchpad/scratchpad.js
devtools/client/shared/AppCacheUtils.jsm
devtools/client/shared/widgets/MdnDocsWidget.js
devtools/client/webide/content/webide.js
devtools/shared/gcli/commands/mdn.js
devtools/shared/gcli/commands/screenshot.js
--- a/devtools/client/eyedropper/eyedropper.js
+++ b/devtools/client/eyedropper/eyedropper.js
@@ -129,18 +129,20 @@ function Eyedropper(chromeWindow, opts =
 
   this._zoomArea = {
     x: 0,          // the left coordinate of the center of the inspected region
     y: 0,          // the top coordinate of the center of the inspected region
     width: CANVAS_WIDTH,      // width of canvas to draw zoomed area onto
     height: CANVAS_WIDTH      // height of canvas
   };
 
-  let mm = this._contentTab.linkedBrowser.messageManager;
-  mm.loadFrameScript("resource://devtools/client/eyedropper/eyedropper-child.js", true);
+  if (this._contentTab) {
+    let mm = this._contentTab.linkedBrowser.messageManager;
+    mm.loadFrameScript("resource://devtools/client/eyedropper/eyedropper-child.js", true);
+  }
 
   // record if this was opened via the picker or standalone
   var telemetry = new Telemetry();
   if (opts.context == "command") {
     telemetry.toolOpened("eyedropper");
   }
   else if (opts.context == "menu") {
     telemetry.toolOpened("menueyedropper");
@@ -187,26 +189,30 @@ Eyedropper.prototype = {
   get centerColor() {
     let x, y;
     x = y = (this.centerCell * this.cellSize) + (this.cellSize / 2);
     let rgb = this._ctx.getImageData(x, y, 1, 1).data;
     return rgb;
   },
 
   get _contentTab() {
-    return this._chromeWindow.gBrowser.selectedTab;
+    return this._chromeWindow.gBrowser && this._chromeWindow.gBrowser.selectedTab;
   },
 
   /**
    * Fetch a screenshot of the content.
    *
    * @return {promise}
    *         Promise that resolves with the screenshot as a dataURL
    */
   getContentScreenshot: function () {
+    if (!this._contentTab) {
+        return promise.resolve(null);
+    }
+
     let deferred = defer();
 
     let mm = this._contentTab.linkedBrowser.messageManager;
     function onScreenshot(message) {
       mm.removeMessageListener("Eyedropper:Screenshot", onScreenshot);
       deferred.resolve(message.data);
     }
     mm.addMessageListener("Eyedropper:Screenshot", onScreenshot);
@@ -219,39 +225,39 @@ Eyedropper.prototype = {
    * Start the eyedropper. Add listeners for a mouse move in the window to
    * show the eyedropper.
    */
   open: function () {
     if (this.isOpen) {
       // the eyedropper is aready open, don't create another panel.
       return promise.resolve();
     }
-    let deferred = defer();
 
     this.isOpen = true;
 
     this._showCrosshairs();
 
     // Get screenshot of content so we can inspect colors
-    this.getContentScreenshot().then((dataURL) => {
-      this._contentImage = new this._chromeWindow.Image();
-      this._contentImage.src = dataURL;
+    return this.getContentScreenshot().then((dataURL) => {
+      // The data url may be null, e.g. if there is no content tab
+      if (dataURL) {
+        this._contentImage = new this._chromeWindow.Image();
+        this._contentImage.src = dataURL;
 
-      // Wait for screenshot to load
-      this._contentImage.onload = () => {
-        // Then start showing the eyedropper UI
-        this._chromeDocument.addEventListener("mousemove", this._onFirstMouseMove);
-        deferred.resolve();
-
-        this.isStarted = true;
-        this.emit("started");
-      };
+        // Wait for screenshot to load
+        let imageLoaded = promise.defer();
+        this._contentImage.onload = imageLoaded.resolve
+        return imageLoaded.promise;
+      }
+    }).then(() => {
+      // Then start showing the eyedropper UI
+      this._chromeDocument.addEventListener("mousemove", this._onFirstMouseMove);
+      this.isStarted = true;
+      this.emit("started");
     });
-
-    return deferred.promise;
   },
 
   /**
    * Called on the first mouse move over the window. Opens the eyedropper
    * panel where the mouse is.
    */
   _onFirstMouseMove: function (event) {
     this._chromeDocument.removeEventListener("mousemove", this._onFirstMouseMove);
@@ -277,18 +283,19 @@ Eyedropper.prototype = {
    * Whether the coordinates are over the content or chrome.
    *
    * @param {number} clientX
    *        x-coordinate of mouse relative to browser window.
    * @param {number} clientY
    *        y-coordinate of mouse relative to browser window.
    */
   _isInContent: function (clientX, clientY) {
-    let box = this._contentTab.linkedBrowser.getBoundingClientRect();
-    if (clientX > box.left &&
+    let box = this._contentTab && this._contentTab.linkedBrowser.getBoundingClientRect();
+    if (box &&
+        clientX > box.left &&
         clientX < box.right &&
         clientY > box.top &&
         clientY < box.bottom) {
       return true;
     }
     return false;
   },
 
--- a/devtools/client/scratchpad/scratchpad.js
+++ b/devtools/client/scratchpad/scratchpad.js
@@ -2056,19 +2056,18 @@ var Scratchpad = {
   },
 
   /**
    * Opens the MDN documentation page for Scratchpad.
    */
   openDocumentationPage: function SP_openDocumentationPage()
   {
     let url = this.strings.GetStringFromName("help.openDocumentationPage");
-    let newTab = this.gBrowser.addTab(url);
+    this.browserWindow.openUILinkIn(url,"tab");
     this.browserWindow.focus();
-    this.gBrowser.selectedTab = newTab;
   },
 };
 
 
 /**
  * Represents the DebuggerClient connection to a specific tab as used by the
  * Scratchpad.
  *
--- a/devtools/client/shared/AppCacheUtils.jsm
+++ b/devtools/client/shared/AppCacheUtils.jsm
@@ -292,18 +292,18 @@ AppCacheUtils.prototype = {
     }
     return entries;
   },
 
   viewEntry: function ACU_viewEntry(key) {
     let wm = Cc["@mozilla.org/appshell/window-mediator;1"]
                .getService(Ci.nsIWindowMediator);
     let win = wm.getMostRecentWindow(gDevTools.chromeWindowType);
-    win.gBrowser.selectedTab = win.gBrowser.addTab(
-      "about:cache-entry?storage=appcache&context=&eid=&uri=" + key);
+    let url = "about:cache-entry?storage=appcache&context=&eid=&uri=" + key;
+    win.openUILinkIn(url, "tab");
   },
 
   clearAll: function ACU_clearAll() {
     if (!Services.prefs.getBoolPref("browser.cache.disk.enable")) {
       throw new Error(l10n.GetStringFromName("cacheDisabled"));
     }
 
     let appCacheStorage = Services.cache2.appCacheStorage(LoadContextInfo.default, null);
--- a/devtools/client/shared/widgets/MdnDocsWidget.js
+++ b/devtools/client/shared/widgets/MdnDocsWidget.js
@@ -254,18 +254,17 @@ function MdnDocsWidget(tooltipDocument) 
   this.elements.linkToMdn.textContent =
     l10n.strings.GetStringFromName("docsTooltip.visitMDN");
 
   // listen for clicks and open in the browser window instead
   let mainWindow = Services.wm.getMostRecentWindow(gDevTools.chromeWindowType);
   this.elements.linkToMdn.addEventListener("click", function (e) {
     e.stopPropagation();
     e.preventDefault();
-    let link = e.target.href;
-    mainWindow.gBrowser.addTab(link);
+    mainWindow.openUILinkIn(e.target.href, "tab", { inBackground: true });
   });
 }
 
 exports.MdnDocsWidget = MdnDocsWidget;
 
 MdnDocsWidget.prototype = {
   /**
    * This is called just before the tooltip is displayed, and is
--- a/devtools/client/webide/content/webide.js
+++ b/devtools/client/webide/content/webide.js
@@ -235,18 +235,17 @@ var UI = {
   configureSimulator: function (event, simulator) {
     UI.selectDeckPanel("simulator");
   },
 
   openInBrowser: function (url) {
     // Open a URL in a Firefox window
     let mainWindow = Services.wm.getMostRecentWindow(gDevTools.chromeWindowType);
     if (mainWindow) {
-      let gBrowser = mainWindow.gBrowser;
-      gBrowser.selectedTab = gBrowser.addTab(url);
+      mainWindow.openUILinkIn(url, "tab");
       mainWindow.focus()
     } else {
       window.open(url);
     }
   },
 
   updateTitle: function () {
     let project = AppManager.selectedProject;
--- a/devtools/shared/gcli/commands/mdn.js
+++ b/devtools/shared/gcli/commands/mdn.js
@@ -64,18 +64,18 @@ exports.items = [{
       root.appendChild(title);
 
       let link = document.createElement("p");
       link.classList.add("gcli-mdn-url");
       link.textContent = l10n.lookup("mdnCssVisitPage");
       root.appendChild(link);
 
       link.addEventListener("click", () => {
-        let gBrowser = context.environment.chromeWindow.gBrowser;
-        gBrowser.selectedTab = gBrowser.addTab(result.url);
+        let mainWindow = context.environment.chromeWindow;
+        mainWindow.openUILinkIn(result.url, "tab");
       });
 
       let summary = document.createElement("p");
       summary.textContent = result.data.summary;
       root.appendChild(summary);
     }
 
     return root;
--- a/devtools/shared/gcli/commands/screenshot.js
+++ b/devtools/shared/gcli/commands/screenshot.js
@@ -148,18 +148,18 @@ exports.items = [
         root.appendChild(image);
       }
 
       // Click handler
       if (imageSummary.href || imageSummary.filename) {
         root.style.cursor = "pointer";
         root.addEventListener("click", () => {
           if (imageSummary.href) {
-            const gBrowser = context.environment.chromeWindow.gBrowser;
-            gBrowser.selectedTab = gBrowser.addTab(imageSummary.href);
+            let mainWindow = context.environment.chromeWindow;
+            mainWindow.openUILinkIn(imageSummary.href, "tab");
           } else if (imageSummary.filename) {
             const file = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsILocalFile);
             file.initWithPath(imageSummary.filename);
             file.reveal();
           }
         });
       }