Bug 1446940 part 3. Stop getting docshells from windows via getInterface in devtools. r=bgrins
authorBoris Zbarsky <bzbarsky@mit.edu>
Wed, 01 Aug 2018 13:07:10 -0400
changeset 429693 d0f6f26864b7ab12902a818246f64203616a46b4
parent 429692 956c6eeca8733095d0a4fe61c57238990614926c
child 429694 f5a747a896fc23b76715acc50b03aceb8f9ed09f
push id34372
push usernerli@mozilla.com
push dateThu, 02 Aug 2018 08:55:28 +0000
treeherdermozilla-central@bd79b07f57a3 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbgrins
bugs1446940
milestone63.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 1446940 part 3. Stop getting docshells from windows via getInterface in devtools. r=bgrins
devtools/client/responsive.html/test/browser/browser_device_width.js
devtools/client/shared/DOMHelpers.jsm
devtools/client/shared/test/test-actor.js
devtools/client/shared/zoom-keys.js
devtools/client/webconsole/utils/context-menu.js
devtools/client/webide/content/webide.js
devtools/client/webide/test/test_zoom.html
devtools/server/actors/addon/webextension-inspected-window.js
devtools/server/actors/highlighters.js
devtools/server/actors/reflow.js
devtools/server/actors/source.js
devtools/server/actors/targets/browsing-context.js
devtools/server/actors/targets/chrome-window.js
devtools/server/actors/targets/content-process.js
devtools/server/actors/targets/parent-process.js
devtools/server/actors/webconsole.js
devtools/server/actors/webconsole/listeners.js
devtools/server/performance/timeline.js
devtools/shared/DevToolsUtils.js
devtools/shared/gcli/commands/screenshot.js
devtools/shared/layout/utils.js
devtools/shared/webconsole/network-monitor.js
--- a/devtools/client/responsive.html/test/browser/browser_device_width.js
+++ b/devtools/client/responsive.html/test/browser/browser_device_width.js
@@ -18,19 +18,17 @@ addRDMTask(TEST_URL, async function({ ui
   info("Checking for screen props");
   await checkScreenProps(ui);
 
   info("Changing the RDM size using input keys");
   await setViewportSizeWithInputKeys(ui);
 
   info("Setting docShell.deviceSizeIsPageSize to false");
   await ContentTask.spawn(ui.getViewportBrowser(), {}, async function() {
-    const docShell = content.QueryInterface(Ci.nsIInterfaceRequestor)
-                          .getInterface(Ci.nsIWebNavigation)
-                          .QueryInterface(Ci.nsIDocShell);
+    const docShell = content.docShell;
     docShell.deviceSizeIsPageSize = false;
   });
 
   info("Checking for screen props once again.");
   await checkScreenProps2(ui);
 });
 
 async function setViewportSizeWithInputKeys(ui) {
--- a/devtools/client/shared/DOMHelpers.jsm
+++ b/devtools/client/shared/DOMHelpers.jsm
@@ -138,19 +138,17 @@ DOMHelpers.prototype = {
    * interactive (DOMContentLoaded).
    *
    * It is based on the chromeEventHandler. This is useful when
    * chrome iframes are loaded in content docshells (in Firefox
    * tabs for example).
    */
   onceDOMReady: function Helpers_onLocationChange(callback, targetURL) {
     const window = this.window;
-    const docShell = window.QueryInterface(Ci.nsIInterfaceRequestor)
-                         .getInterface(Ci.nsIWebNavigation)
-                         .QueryInterface(Ci.nsIDocShell);
+    const docShell = window.docShell;
     const onReady = function(event) {
       if (event.target == window.document) {
         docShell.chromeEventHandler.removeEventListener("DOMContentLoaded", onReady);
         // If in `callback` the URL of the window is changed and a listener to DOMContentLoaded
         // is attached, the event we just received will be also be caught by the new listener.
         // We want to avoid that so we execute the callback in the next queue.
         Services.tm.dispatchToMainThread(callback);
       }
--- a/devtools/client/shared/test/test-actor.js
+++ b/devtools/client/shared/test/test-actor.js
@@ -449,19 +449,17 @@ var TestActor = exports.TestActor = prot
       if (actorID) {
         const actor = this.conn.getActor(actorID);
         const {_highlighter: h} = actor;
         h.once("updated", resolve);
       } else {
         resolve();
       }
 
-      const docShell = this.content.QueryInterface(Ci.nsIInterfaceRequestor)
-                                 .getInterface(Ci.nsIWebNavigation)
-                                 .QueryInterface(Ci.nsIDocShell);
+      const docShell = this.content.docShell;
       docShell.contentViewer.fullZoom = level;
     });
   },
 
   /**
    * Get all box-model regions' adjusted boxquads for the given element
    * @param {String} selector The node selector to target a given element
    * @return {Object} An object with each property being a box-model region, each
--- a/devtools/client/shared/zoom-keys.js
+++ b/devtools/client/shared/zoom-keys.js
@@ -1,15 +1,14 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 "use strict";
 
-const { Ci } = require("chrome");
 const Services = require("Services");
 const KeyShortcuts = require("devtools/client/shared/key-shortcuts");
 
 const ZOOM_PREF = "devtools.toolbox.zoomValue";
 const MIN_ZOOM = 0.5;
 const MAX_ZOOM = 2;
 
 const {LocalizationHelper} = require("devtools/shared/l10n");
@@ -21,19 +20,17 @@ const L10N = new LocalizationHelper("dev
  *
  * @param {DOMWindow} The window on which we should listent to key strokes and
  *                    modify the zoom factor.
  */
 exports.register = function(window) {
   const shortcuts = new KeyShortcuts({
     window
   });
-  const docShell = window.QueryInterface(Ci.nsIInterfaceRequestor)
-    .getInterface(Ci.nsIWebNavigation)
-    .QueryInterface(Ci.nsIDocShell);
+  const docShell = window.docShell;
   const contViewer = docShell.contentViewer;
   let zoomValue = parseFloat(Services.prefs.getCharPref(ZOOM_PREF));
   const zoomIn = function(event) {
     setZoom(zoomValue + 0.1);
     event.preventDefault();
   };
 
   const zoomOut = function(event) {
--- a/devtools/client/webconsole/utils/context-menu.js
+++ b/devtools/client/webconsole/utils/context-menu.js
@@ -187,19 +187,17 @@ exports.createContextMenu = createContex
  * with docshell commands to provide the right enabled state and editor
  * functionality.
  *
  * You'll need to call menu.popup() yourself, this just returns the Menu instance.
  *
  * @returns {Menu}
  */
 function createEditContextMenu() {
-  const docshell = window.QueryInterface(Ci.nsIInterfaceRequestor)
-                         .getInterface(Ci.nsIWebNavigation)
-                         .QueryInterface(Ci.nsIDocShell);
+  const docshell = window.docShell;
   const menu = new Menu({
     id: "webconsole-menu"
   });
   menu.append(new MenuItem({
     id: "editmenu-undo",
     l10nID: "editmenu-undo",
     disabled: !docshell.isCommandEnabled("cmd_undo"),
     click: () => {
--- a/devtools/client/webide/content/webide.js
+++ b/devtools/client/webide/content/webide.js
@@ -86,20 +86,17 @@ var UI = {
       const addons = GetAvailableAddons();
       addons.adb.install();
     }
 
     Services.prefs.setBoolPref("devtools.webide.autoinstallADBHelper", false);
 
     this.setupDeck();
 
-    this.contentViewer = window.QueryInterface(Ci.nsIInterfaceRequestor)
-                               .getInterface(Ci.nsIWebNavigation)
-                               .QueryInterface(Ci.nsIDocShell)
-                               .contentViewer;
+    this.contentViewer = window.docShell.contentViewer;
     this.contentViewer.fullZoom = Services.prefs.getCharPref("devtools.webide.zoom");
 
     gDevToolsBrowser.isWebIDEInitialized.resolve();
   },
 
   destroy: function() {
     window.removeEventListener("focus", this.onfocus, true);
     AppManager.off("app-manager-update", this.appManagerUpdate);
--- a/devtools/client/webide/test/test_zoom.html
+++ b/devtools/client/webide/test/test_zoom.html
@@ -15,20 +15,17 @@
   <body>
 
     <script type="application/javascript">
       window.onload = function() {
         SimpleTest.waitForExplicitFinish();
 
         (async function() {
           let win = await openWebIDE();
-          let viewer = win.QueryInterface(Ci.nsIInterfaceRequestor)
-                            .getInterface(Ci.nsIWebNavigation)
-                            .QueryInterface(Ci.nsIDocShell)
-                            .contentViewer;
+          let viewer = win.docShell.contentViewer;
 
           win.Cmds.zoomOut();
           win.Cmds.zoomOut();
           win.Cmds.zoomOut();
           win.Cmds.zoomOut();
           win.Cmds.zoomOut();
           win.Cmds.zoomOut();
           win.Cmds.zoomOut();
@@ -50,20 +47,17 @@
           win.Cmds.zoomIn();
 
           roundZoom = Math.round(10 * viewer.fullZoom) / 10;
           is(roundZoom, 1.4, "Reach max zoom");
 
           await closeWebIDE(win);
 
           win = await openWebIDE();
-          viewer = win.QueryInterface(Ci.nsIInterfaceRequestor)
-                        .getInterface(Ci.nsIWebNavigation)
-                        .QueryInterface(Ci.nsIDocShell)
-                        .contentViewer;
+          viewer = win.docShell.contentViewer;
 
           roundZoom = Math.round(10 * viewer.fullZoom) / 10;
           is(roundZoom, 1.4, "Zoom restored");
 
           win.Cmds.resetZoom();
 
           is(viewer.fullZoom, 1, "Zoom reset");
 
--- a/devtools/server/actors/addon/webextension-inspected-window.js
+++ b/devtools/server/actors/addon/webextension-inspected-window.js
@@ -87,19 +87,17 @@ function logAccessDeniedWarning(window, 
   }
 
   error.initWithWindowID(msg, url, lineNumber, 0, 0, errorFlag, "webExtensions",
                          innerWindowId);
   Services.console.logMessage(error);
 }
 
 function CustomizedReload(params) {
-  this.docShell = params.targetActor.window
-                        .QueryInterface(Ci.nsIInterfaceRequestor)
-                        .getInterface(Ci.nsIDocShell);
+  this.docShell = params.targetActor.window.docShell;
   this.docShell.QueryInterface(Ci.nsIWebProgress);
 
   this.inspectedWindowEval = params.inspectedWindowEval;
   this.callerInfo = params.callerInfo;
 
   this.ignoreCache = params.ignoreCache;
   this.injectedScript = params.injectedScript;
   this.userAgent = params.userAgent;
@@ -168,19 +166,17 @@ CustomizedReload.prototype = {
     const document = subject;
     const window = document && document.defaultView;
 
     // Filter out non interesting documents.
     if (!document || !document.location || !window) {
       return;
     }
 
-    const subjectDocShell = window.QueryInterface(Ci.nsIInterfaceRequestor)
-                                .getInterface(Ci.nsIWebNavigation)
-                                .QueryInterface(Ci.nsIDocShell);
+    const subjectDocShell = window.docShell;
 
     // Keep track of the set of window objects where we are going to inject
     // the injectedScript: the top level window and all its descendant
     // that are still of type content (filtering out loaded XUL pages, if any).
     if (window == this.window) {
       this.customizedReloadWindows.add(window);
     } else if (subjectDocShell.sameTypeParent) {
       const parentWindow = subjectDocShell.sameTypeParent.domWindow;
--- a/devtools/server/actors/highlighters.js
+++ b/devtools/server/actors/highlighters.js
@@ -635,19 +635,17 @@ HighlighterEnvironment.prototype = {
   },
 
   get document() {
     return this.window && this.window.document;
   },
 
   get docShell() {
     return this.window &&
-           this.window.QueryInterface(Ci.nsIInterfaceRequestor)
-                      .getInterface(Ci.nsIWebNavigation)
-                      .QueryInterface(Ci.nsIDocShell);
+           this.window.docShell;
   },
 
   get webProgress() {
     return this.docShell &&
            this.docShell.QueryInterface(Ci.nsIInterfaceRequestor)
                         .getInterface(Ci.nsIWebProgress);
   },
 
--- a/devtools/server/actors/reflow.js
+++ b/devtools/server/actors/reflow.js
@@ -425,30 +425,24 @@ exports.releaseLayoutChangesObserver = r
  */
 class ReflowObserver extends Observable {
   constructor(targetActor, callback) {
     super(targetActor, callback);
   }
 
   _startListeners(windows) {
     for (const window of windows) {
-      const docshell = window.QueryInterface(Ci.nsIInterfaceRequestor)
-                     .getInterface(Ci.nsIWebNavigation)
-                     .QueryInterface(Ci.nsIDocShell);
-      docshell.addWeakReflowObserver(this);
+      window.docShell.addWeakReflowObserver(this);
     }
   }
 
   _stopListeners(windows) {
     for (const window of windows) {
       try {
-        const docshell = window.QueryInterface(Ci.nsIInterfaceRequestor)
-                       .getInterface(Ci.nsIWebNavigation)
-                       .QueryInterface(Ci.nsIDocShell);
-        docshell.removeWeakReflowObserver(this);
+        window.docShell.removeWeakReflowObserver(this);
       } catch (e) {
         // Corner cases where a global has already been freed may happen, in
         // which case, no need to remove the observer.
       }
     }
   }
 
   reflow(start, end) {
--- a/devtools/server/actors/source.js
+++ b/devtools/server/actors/source.js
@@ -397,26 +397,25 @@ const SourceActor = ActorClassWithSpec(s
       // that doesn't match the document shown in the browser.
       const loadFromCache = this.isInlineSource && this.isCacheEnabled;
 
       // Fetch the sources with the same principal as the original document
       const win = this.threadActor._parent.window;
       let principal, cacheKey;
       // On xpcshell, we don't have a window but a Sandbox
       if (!isWorker && win instanceof Ci.nsIDOMWindow) {
-        const webNav = win.QueryInterface(Ci.nsIInterfaceRequestor)
-                        .getInterface(Ci.nsIWebNavigation);
-        const channel = webNav.currentDocumentChannel;
+        const docShell = win.docShell;
+        const channel = docShell.currentDocumentChannel;
         principal = channel.loadInfo.loadingPrincipal;
 
         // Retrieve the cacheKey in order to load POST requests from cache
         // Note that chrome:// URLs don't support this interface.
         if (loadFromCache &&
-          webNav.currentDocumentChannel instanceof Ci.nsICacheInfoChannel) {
-          cacheKey = webNav.currentDocumentChannel.cacheKey;
+          docShell.currentDocumentChannel instanceof Ci.nsICacheInfoChannel) {
+          cacheKey = docShell.currentDocumentChannel.cacheKey;
         }
       }
 
       const sourceFetched = fetch(this.url, {
         principal,
         cacheKey,
         loadFromCache
       });
--- a/devtools/server/actors/targets/browsing-context.js
+++ b/devtools/server/actors/targets/browsing-context.js
@@ -390,19 +390,17 @@ const browsingContextTargetPrototype = {
    * if you want it to show information relative to the iframe that's currently
    * being inspected in the toolbox.
    */
   get originalDocShell() {
     if (!this._originalWindow) {
       return this.docShell;
     }
 
-    return this._originalWindow.QueryInterface(Ci.nsIInterfaceRequestor)
-                               .getInterface(Ci.nsIWebNavigation)
-                               .QueryInterface(Ci.nsIDocShell);
+    return this._originalWindow.docShell;
   },
 
   /**
    * Getter for the original window this actor got attached to in the first
    * place.
    * Note that your actor should normally *not* rely on this top level window if
    * you want it to show information relative to the iframe that's currently
    * being inspected in the toolbox.
@@ -419,19 +417,17 @@ const browsingContextTargetPrototype = {
       .QueryInterface(Ci.nsIInterfaceRequestor)
       .getInterface(Ci.nsIWebProgress);
   },
 
   /**
    * Getter for the nsIWebNavigation for the target.
    */
   get webNavigation() {
-    return this.docShell
-      .QueryInterface(Ci.nsIInterfaceRequestor)
-      .getInterface(Ci.nsIWebNavigation);
+    return this.docShell.QueryInterface(Ci.nsIWebNavigation);
   },
 
   /**
    * Getter for the browsing context's document.
    */
   get contentDocument() {
     return this.webNavigation.document;
   },
@@ -1211,19 +1207,17 @@ const browsingContextTargetPrototype = {
       this._windowReady(window, true);
       DevToolsUtils.executeSoon(() => {
         this._navigate(window, true);
       });
     });
   },
 
   _setWindow(window) {
-    const docShell = window.QueryInterface(Ci.nsIInterfaceRequestor)
-                         .getInterface(Ci.nsIWebNavigation)
-                         .QueryInterface(Ci.nsIDocShell);
+    const docShell = window.docShell;
     // Here is the very important call where we switch the currently targeted
     // browsing context (it will indirectly update this.window and many other
     // attributes defined from docShell).
     Object.defineProperty(this, "docShell", {
       value: docShell,
       enumerable: true,
       configurable: true
     });
--- a/devtools/server/actors/targets/chrome-window.js
+++ b/devtools/server/actors/targets/chrome-window.js
@@ -49,18 +49,17 @@ const chromeWindowTargetPrototype = exte
  * @param connection DebuggerServerConnection
  *        The connection to the client.
  * @param window DOMWindow
  *        The window.
  */
 chromeWindowTargetPrototype.initialize = function(connection, window) {
   BrowsingContextTargetActor.prototype.initialize.call(this, connection);
 
-  const docShell = window.QueryInterface(Ci.nsIInterfaceRequestor)
-                       .getInterface(Ci.nsIDocShell);
+  const docShell = window.docShell;
   Object.defineProperty(this, "docShell", {
     value: docShell,
     configurable: true
   });
 };
 
 // Bug 1266561: This setting is mysteriously named, we should split up the
 // functionality that is triggered by it.
--- a/devtools/server/actors/targets/content-process.js
+++ b/devtools/server/actors/targets/content-process.js
@@ -37,18 +37,17 @@ function ContentProcessTargetActor(conne
   });
 
   const sandboxPrototype = {
     get tabs() {
       const tabs = [];
       const windowEnumerator = Services.ww.getWindowEnumerator();
       while (windowEnumerator.hasMoreElements()) {
         const window = windowEnumerator.getNext().QueryInterface(Ci.nsIDOMWindow);
-        const tabChildGlobal = window.QueryInterface(Ci.nsIInterfaceRequestor)
-                                     .getInterface(Ci.nsIDocShell)
+        const tabChildGlobal = window.docShell
                                      .sameTypeRootTreeItem
                                      .QueryInterface(Ci.nsIInterfaceRequestor)
                                      .getInterface(Ci.nsIContentFrameMessageManager);
         tabs.push(tabChildGlobal);
       }
       return tabs;
     },
   };
--- a/devtools/server/actors/targets/parent-process.js
+++ b/devtools/server/actors/targets/parent-process.js
@@ -71,19 +71,17 @@ parentProcessTargetPrototype.initialize 
     try {
       window = Services.appShell.hiddenDOMWindow;
     } catch (e) {
       // On XPCShell, the above line will throw.
     }
   }
 
   // On XPCShell, there is no window/docshell
-  const docShell = window ? window.QueryInterface(Ci.nsIInterfaceRequestor)
-                                .getInterface(Ci.nsIDocShell)
-                        : null;
+  const docShell = window ? window.docShell : null;
   Object.defineProperty(this, "docShell", {
     value: docShell,
     configurable: true
   });
 };
 
 parentProcessTargetPrototype.isRootActor = true;
 
@@ -93,19 +91,17 @@ parentProcessTargetPrototype.isRootActor
  */
 Object.defineProperty(parentProcessTargetPrototype, "docShells", {
   get: function() {
     // Iterate over all top-level windows and all their docshells.
     let docShells = [];
     const e = Services.ww.getWindowEnumerator();
     while (e.hasMoreElements()) {
       const window = e.getNext();
-      const docShell = window.QueryInterface(Ci.nsIInterfaceRequestor)
-                           .getInterface(Ci.nsIWebNavigation)
-                           .QueryInterface(Ci.nsIDocShell);
+      const docShell = window.docShell;
       docShells = docShells.concat(getChildDocShells(docShell));
     }
 
     return docShells;
   }
 });
 
 parentProcessTargetPrototype.observe = function(subject, topic, data) {
@@ -133,19 +129,17 @@ parentProcessTargetPrototype._attach = f
   // Listen for any new/destroyed chrome docshell
   Services.obs.addObserver(this, "chrome-webnavigation-create");
   Services.obs.addObserver(this, "chrome-webnavigation-destroy");
 
   // Iterate over all top-level windows.
   const e = Services.ww.getWindowEnumerator();
   while (e.hasMoreElements()) {
     const window = e.getNext();
-    const docShell = window.QueryInterface(Ci.nsIInterfaceRequestor)
-                         .getInterface(Ci.nsIWebNavigation)
-                         .QueryInterface(Ci.nsIDocShell);
+    const docShell = window.docShell;
     if (docShell == this.docShell) {
       continue;
     }
     this._progressListener.watch(docShell);
   }
   return undefined;
 };
 
@@ -156,19 +150,17 @@ parentProcessTargetPrototype._detach = f
 
   Services.obs.removeObserver(this, "chrome-webnavigation-create");
   Services.obs.removeObserver(this, "chrome-webnavigation-destroy");
 
   // Iterate over all top-level windows.
   const e = Services.ww.getWindowEnumerator();
   while (e.hasMoreElements()) {
     const window = e.getNext();
-    const docShell = window.QueryInterface(Ci.nsIInterfaceRequestor)
-                         .getInterface(Ci.nsIWebNavigation)
-                         .QueryInterface(Ci.nsIDocShell);
+    const docShell = window.docShell;
     if (docShell == this.docShell) {
       continue;
     }
     this._progressListener.unwatch(docShell);
   }
 
   BrowsingContextTargetActor.prototype._detach.call(this);
   return undefined;
--- a/devtools/server/actors/webconsole.js
+++ b/devtools/server/actors/webconsole.js
@@ -1917,19 +1917,17 @@ WebConsoleActor.prototype =
    * Find the XUL window that owns the content window.
    *
    * @return Window
    *         The XUL window that owns the content window.
    */
   chromeWindow: function() {
     let window = null;
     try {
-      window = this.window.QueryInterface(Ci.nsIInterfaceRequestor)
-             .getInterface(Ci.nsIWebNavigation).QueryInterface(Ci.nsIDocShell)
-             .chromeEventHandler.ownerGlobal;
+      window = this.window.docShell.chromeEventHandler.ownerGlobal;
     } catch (ex) {
       // The above can fail because chromeEventHandler is not available for all
       // kinds of |this.window|.
     }
 
     return window;
   },
 
--- a/devtools/server/actors/webconsole/listeners.js
+++ b/devtools/server/actors/webconsole/listeners.js
@@ -374,19 +374,17 @@ ConsoleAPIListener.prototype =
  * @param object window
  *        The window for which we need to track reflow.
  * @param object owner
  *        The listener owner which needs to implement:
  *        - onReflowActivity(reflowInfo)
  */
 
 function ConsoleReflowListener(window, listener) {
-  this.docshell = window.QueryInterface(Ci.nsIInterfaceRequestor)
-                         .getInterface(Ci.nsIWebNavigation)
-                         .QueryInterface(Ci.nsIDocShell);
+  this.docshell = window.docShell;
   this.listener = listener;
   this.docshell.addWeakReflowObserver(this);
 }
 
 exports.ConsoleReflowListener = ConsoleReflowListener;
 
 ConsoleReflowListener.prototype =
 {
--- a/devtools/server/performance/timeline.js
+++ b/devtools/server/performance/timeline.js
@@ -310,19 +310,17 @@ Timeline.prototype = {
   },
 
   /**
    * When a new window becomes available in the targetActor, start recording its
    * markers if we were recording.
    */
   _onWindowReady: function({ window }) {
     if (this._isRecording) {
-      const docShell = window.QueryInterface(Ci.nsIInterfaceRequestor)
-                           .getInterface(Ci.nsIWebNavigation)
-                           .QueryInterface(Ci.nsIDocShell);
+      const docShell = window.docShell;
       docShell.recordProfileTimelineMarkers = true;
     }
   },
 
   /**
    * Fired when the Memory component emits a `garbage-collection` event. Used to
    * take the data and make it look like the rest of our markers.
    *
--- a/devtools/shared/DevToolsUtils.js
+++ b/devtools/shared/DevToolsUtils.js
@@ -541,18 +541,17 @@ function mainThreadFetch(urlIn, aOptions
   // SHEntry and offer ways to restore POST requests from cache.
   if (aOptions.loadFromCache &&
       aOptions.cacheKey != 0 && channel instanceof Ci.nsICacheInfoChannel) {
     channel.cacheKey = aOptions.cacheKey;
   }
 
   if (aOptions.window) {
     // Respect private browsing.
-    channel.loadGroup = aOptions.window.QueryInterface(Ci.nsIInterfaceRequestor)
-                          .getInterface(Ci.nsIWebNavigation)
+    channel.loadGroup = aOptions.window.docShell
                           .QueryInterface(Ci.nsIDocumentLoader)
                           .loadGroup;
   }
 
   const deferred = defer();
   const onResponse = (stream, status, request) => {
     if (!components.isSuccessCode(status)) {
       deferred.reject(new Error(`Failed to fetch ${url}. Code ${status}.`));
--- a/devtools/shared/gcli/commands/screenshot.js
+++ b/devtools/shared/gcli/commands/screenshot.js
@@ -368,19 +368,17 @@ function saveToClipboard(context, reply)
     try {
       const channel = NetUtil.newChannel({
         uri: reply.data,
         loadUsingSystemPrincipal: true,
         contentPolicyType: Ci.nsIContentPolicy.TYPE_INTERNAL_IMAGE
       });
       const input = channel.open2();
 
-      const loadContext = context.environment.chromeWindow
-                                 .QueryInterface(Ci.nsIInterfaceRequestor)
-                                 .getInterface(Ci.nsIWebNavigation)
+      const loadContext = context.environment.chromeWindow.docShell
                                  .QueryInterface(Ci.nsILoadContext);
 
       const callback = {
         onImageReady(container, status) {
           if (!container) {
             console.error("imgTools.decodeImageAsync failed");
             reply.destinations.push(l10n.lookup("screenshotErrorCopying"));
             resolve();
--- a/devtools/shared/layout/utils.js
+++ b/devtools/shared/layout/utils.js
@@ -36,19 +36,17 @@ function utilsFor(win) {
 
 /**
  * like win.top, but goes through mozbrowsers and mozapps iframes.
  *
  * @param {DOMWindow} win
  * @return {DOMWindow}
  */
 function getTopWindow(win) {
-  const docShell = win.QueryInterface(Ci.nsIInterfaceRequestor)
-                    .getInterface(Ci.nsIWebNavigation)
-                    .QueryInterface(Ci.nsIDocShell);
+  const docShell = win.docShell;
 
   if (!docShell.isMozBrowser) {
     return win.top;
   }
 
   const topDocShell =
     docShell.getSameTypeRootTreeItemIgnoreBrowserBoundaries();
 
@@ -97,19 +95,17 @@ exports.isWindowIncluded = isWindowInclu
  * @param {DOMWindow} win
  * @return {DOMWindow}
  */
 function getParentWindow(win) {
   if (isTopWindow(win)) {
     return null;
   }
 
-  const docShell = win.QueryInterface(Ci.nsIInterfaceRequestor)
-                 .getInterface(Ci.nsIWebNavigation)
-                 .QueryInterface(Ci.nsIDocShell);
+  const docShell = win.docShell;
 
   if (!docShell.isMozBrowser) {
     return win.parent;
   }
 
   const parentDocShell =
     docShell.getSameTypeParentIgnoreBrowserBoundaries();
 
--- a/devtools/shared/webconsole/network-monitor.js
+++ b/devtools/shared/webconsole/network-monitor.js
@@ -1336,18 +1336,17 @@ NetworkMonitor.prototype = {
         httpActivity.url == this.window.location.href) {
       // If the request URL is the same as the current page URL, then
       // we can try to get the posted text from the page directly.
       // This check is necessary as otherwise the
       //   NetworkHelper.readPostTextFromPageViaWebNav()
       // function is called for image requests as well but these
       // are not web pages and as such don't store the posted text
       // in the cache of the webpage.
-      const webNav = this.window.QueryInterface(Ci.nsIInterfaceRequestor)
-                   .getInterface(Ci.nsIWebNavigation);
+      const webNav = this.window.docShell.QueryInterface(Ci.nsIWebNavigation);
       sentBody = NetworkHelper
                  .readPostTextFromPageViaWebNav(webNav, httpActivity.charset);
     }
 
     if (sentBody !== null) {
       httpActivity.sentBody = sentBody;
     }
   },
@@ -2108,19 +2107,17 @@ ConsoleProgressListener.prototype = {
    * Initialize the ConsoleProgressListener.
    * @private
    */
   _init: function() {
     if (this._initialized) {
       return;
     }
 
-    this._webProgress = this.window.QueryInterface(Ci.nsIInterfaceRequestor)
-                        .getInterface(Ci.nsIWebNavigation)
-                        .QueryInterface(Ci.nsIWebProgress);
+    this._webProgress = this.window.docShell.QueryInterface(Ci.nsIWebProgress);
     this._webProgress.addProgressListener(this,
                                           Ci.nsIWebProgress.NOTIFY_STATE_ALL);
 
     this._initialized = true;
   },
 
   /**
    * Start a monitor/tracker related to the current nsIWebProgressListener