Bug 1391110: Part 4 - Remove unnecessary nsIFrameLoaderOwner QIs. r=smaug
authorKris Maglione <maglione.k@gmail.com>
Sat, 19 Aug 2017 13:32:58 -0700
changeset 376555 4b9198e1725289baac765a7b0398ff97db87da38
parent 376554 5a801710d5f2daa3cc19f1b13c37900b5a594b7c
child 376556 c9164c497b328c6324f097869539fbc65df134cd
push id32385
push userarchaeopteryx@coole-files.de
push dateThu, 24 Aug 2017 11:29:15 +0000
treeherdermozilla-central@32674de9af80 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssmaug
bugs1391110
milestone57.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 1391110: Part 4 - Remove unnecessary nsIFrameLoaderOwner QIs. r=smaug The FrameLoaderOwner interface has been implemented in WebIDL for several years now, so these QIs are simply unnecessary overhead. MozReview-Commit-ID: LAzvfm5Qhy0
accessible/jsat/Utils.jsm
browser/base/content/aboutaccounts/aboutaccounts.js
browser/base/content/browser.js
browser/base/content/tabbrowser.xml
browser/components/sessionstore/SessionStore.jsm
browser/modules/ProcessHangMonitor.jsm
devtools/client/framework/toolbox-init.js
devtools/shim/devtools-startup.js
layout/tools/reftest/reftest.jsm
mobile/android/chrome/content/aboutAccounts.js
mobile/android/chrome/content/browser.js
mobile/android/modules/geckoview/GeckoViewNavigation.jsm
testing/marionette/frame.js
testing/specialpowers/content/SpecialPowersObserver.jsm
testing/specialpowers/content/SpecialPowersObserverAPI.js
testing/specialpowers/content/specialpowers.js
testing/specialpowers/content/specialpowersAPI.js
toolkit/components/contextualidentity/ContextualIdentityService.jsm
toolkit/components/extensions/ExtensionUtils.jsm
toolkit/content/contentAreaUtils.js
toolkit/content/widgets/browser.xml
toolkit/content/widgets/editor.xml
toolkit/content/widgets/general.xml
toolkit/content/widgets/remote-browser.xml
--- a/accessible/jsat/Utils.jsm
+++ b/accessible/jsat/Utils.jsm
@@ -247,18 +247,17 @@ this.Utils = { // jshint ignore:line
         }
       }
     };
     return this.stringBundle;
   },
 
   getMessageManager: function getMessageManager(aBrowser) {
     try {
-      return aBrowser.QueryInterface(Ci.nsIFrameLoaderOwner).
-         frameLoader.messageManager;
+      return aBrowser.frameLoader.messageManager;
     } catch (x) {
       return null;
     }
   },
 
   getState: function getState(aAccessibleOrEvent) {
     if (aAccessibleOrEvent instanceof Ci.nsIAccessibleStateChangeEvent) {
       return new State(
--- a/browser/base/content/aboutaccounts/aboutaccounts.js
+++ b/browser/base/content/aboutaccounts/aboutaccounts.js
@@ -102,17 +102,16 @@ var wrapper = {
     // If a master-password is enabled, we want to encourage the user to
     // unlock it.  Things still work if not, but the user will probably need
     // to re-auth next startup (in which case we will get here again and
     // re-prompt)
     Utils.ensureMPUnlocked();
 
     let iframe = document.getElementById("remote");
     this.iframe = iframe;
-    this.iframe.QueryInterface(Ci.nsIFrameLoaderOwner);
     let docShell = this.iframe.frameLoader.docShell;
     docShell.QueryInterface(Ci.nsIWebProgress);
     docShell.addProgressListener(this.iframeListener,
                                  Ci.nsIWebProgress.NOTIFY_STATE_DOCUMENT |
                                  Ci.nsIWebProgress.NOTIFY_LOCATION);
     iframe.addEventListener("load", this);
 
     // Ideally we'd just merge urlParams with new URL(url).searchParams, but our
--- a/browser/base/content/browser.js
+++ b/browser/base/content/browser.js
@@ -5356,27 +5356,23 @@ nsBrowserAccess.prototype = {
     var isExternal = !!(aFlags & Ci.nsIBrowserDOMWindow.OPEN_EXTERNAL);
 
     var userContextId = aParams.openerOriginAttributes &&
                         ("userContextId" in aParams.openerOriginAttributes)
                           ? aParams.openerOriginAttributes.userContextId
                           : Ci.nsIScriptSecurityManager.DEFAULT_USER_CONTEXT_ID
 
     let referrer = aParams.referrer ? makeURI(aParams.referrer) : null;
-    let browser = this._openURIInNewTab(aURI, referrer,
-                                        aParams.referrerPolicy,
-                                        aParams.isPrivate,
-                                        isExternal, false,
-                                        userContextId, null, aParams.openerBrowser,
-                                        aParams.triggeringPrincipal,
-                                        aNextTabParentId, aName);
-    if (browser)
-      return browser.QueryInterface(Ci.nsIFrameLoaderOwner);
-
-    return null;
+    return this._openURIInNewTab(aURI, referrer,
+                                 aParams.referrerPolicy,
+                                 aParams.isPrivate,
+                                 isExternal, false,
+                                 userContextId, null, aParams.openerBrowser,
+                                 aParams.triggeringPrincipal,
+                                 aNextTabParentId, aName);
   },
 
   isTabContentWindow(aWindow) {
     return gBrowser.browsers.some(browser => browser.contentWindow == aWindow);
   },
 
   canClose() {
     return CanCloseWindow();
--- a/browser/base/content/tabbrowser.xml
+++ b/browser/base/content/tabbrowser.xml
@@ -2110,17 +2110,17 @@
               b.setAttribute("remoteType", aParams.remoteType);
               b.setAttribute("remote", "true");
             }
 
             if (aParams.openerWindow) {
               if (aParams.remoteType) {
                 throw new Error("Cannot set opener window on a remote browser!");
               }
-              b.QueryInterface(Ci.nsIFrameLoaderOwner).presetOpenerWindow(aParams.openerWindow);
+              b.presetOpenerWindow(aParams.openerWindow);
             }
 
             if (!aParams.isPreloadBrowser && this.hasAttribute("autocompletepopup")) {
               b.setAttribute("autocompletepopup", this.getAttribute("autocompletepopup"));
             }
 
             if (aParams.isPreloadBrowser) {
               b.setAttribute("isPreloadBrowser", "true");
@@ -4127,17 +4127,17 @@
                 this.tabState.set(tab, state);
               }
             },
 
             setTabState(tab, state) {
               this.setTabStateNoAction(tab, state);
 
               let browser = tab.linkedBrowser;
-              let {tabParent} = browser.QueryInterface(Ci.nsIFrameLoaderOwner).frameLoader;
+              let {tabParent} = browser.frameLoader;
               if (state == this.STATE_LOADING) {
                 this.assert(!this.minimizedOrFullyOccluded);
                 browser.docShellIsActive = true;
                 if (!tabParent) {
                   this.onLayersReady(browser);
                 }
               } else if (state == this.STATE_UNLOADING) {
                 browser.docShellIsActive = false;
@@ -4714,17 +4714,17 @@
 
               this._requestingTab = true;
               this.logState("requestTab " + this.tinfo(tab));
               this.startTabSwitch();
 
               this.requestedTab = tab;
 
               let browser = this.requestedTab.linkedBrowser;
-              let fl = browser.QueryInterface(Ci.nsIFrameLoaderOwner).frameLoader;
+              let fl = browser.frameLoader;
 
               if (fl && fl.tabParent && !this.activeSuppressDisplayport.has(fl.tabParent)) {
                 fl.tabParent.suppressDisplayport(true);
                 this.activeSuppressDisplayport.add(fl.tabParent);
               }
 
               this.preActions();
 
--- a/browser/components/sessionstore/SessionStore.jsm
+++ b/browser/components/sessionstore/SessionStore.jsm
@@ -4751,17 +4751,17 @@ var SessionStoreInternal = {
    */
   _sendRestoreHistory(browser, options) {
     // If the tabData which we're sending down has any sessionStorage associated
     // with it, we need to send down permissions for the domains, as this
     // information will be needed to correctly restore the session.
     if (options.tabData.storage) {
       for (let origin of Object.getOwnPropertyNames(options.tabData.storage)) {
         try {
-          let {frameLoader} = browser.QueryInterface(Components.interfaces.nsIFrameLoaderOwner);
+          let {frameLoader} = browser;
           if (frameLoader.tabParent) {
             let attrs = browser.contentPrincipal.originAttributes;
             let dataPrincipal = Services.scriptSecurityManager.createCodebasePrincipalFromOrigin(origin);
             let principal = Services.scriptSecurityManager.createCodebasePrincipal(dataPrincipal.URI, attrs);
             frameLoader.tabParent.transmitPermissionsForPrincipal(principal);
           }
         } catch (e) {
           console.error(e);
--- a/browser/modules/ProcessHangMonitor.jsm
+++ b/browser/modules/ProcessHangMonitor.jsm
@@ -219,30 +219,30 @@ var ProcessHangMonitor = {
         break;
     }
   },
 
   /**
    * Find a active hang report for the given <browser> element.
    */
   findActiveReport(browser) {
-    let frameLoader = browser.QueryInterface(Ci.nsIFrameLoaderOwner).frameLoader;
+    let frameLoader = browser.frameLoader;
     for (let report of this._activeReports) {
       if (report.isReportForBrowser(frameLoader)) {
         return report;
       }
     }
     return null;
   },
 
   /**
    * Find a paused hang report for the given <browser> element.
    */
   findPausedReport(browser) {
-    let frameLoader = browser.QueryInterface(Ci.nsIFrameLoaderOwner).frameLoader;
+    let frameLoader = browser.frameLoader;
     for (let [report, ] of this._pausedReports) {
       if (report.isReportForBrowser(frameLoader)) {
         return report;
       }
     }
     return null;
   },
 
--- a/devtools/client/framework/toolbox-init.js
+++ b/devtools/client/framework/toolbox-init.js
@@ -57,20 +57,19 @@ if (url.search.length > 1) {
 
       // `iframe` is the targeted document to debug
       let iframe = host.wrappedJSObject ? host.wrappedJSObject.target
                                         : host.target;
       if (!iframe) {
         throw new Error("Unable to find the targeted iframe to debug");
       }
 
-      // Need to use a xray and query some interfaces to have
-      // attributes and behavior expected by devtools codebase
+      // Need to use a xray to have attributes and behavior expected by
+      // devtools codebase
       iframe = XPCNativeWrapper(iframe);
-      iframe.QueryInterface(Ci.nsIFrameLoaderOwner);
 
       // Fake a xul:tab object as we don't have one.
       // linkedBrowser is the only one attribute being queried by client.getTab
       let tab = { linkedBrowser: iframe };
 
       if (!DebuggerServer.initialized) {
         DebuggerServer.init();
         DebuggerServer.addBrowserActors();
--- a/devtools/shim/devtools-startup.js
+++ b/devtools/shim/devtools-startup.js
@@ -622,18 +622,17 @@ const JsonView = {
     let browser = chrome.gBrowser.selectedBrowser;
     if (message.data.url === null) {
       // Save original contents
       chrome.saveBrowser(browser, false, message.data.windowID);
     } else {
       // The following code emulates saveBrowser, but:
       // - Uses the given blob URL containing the custom contents to save.
       // - Obtains the file name from the URL of the document, not the blob.
-      let persistable = browser.QueryInterface(Ci.nsIFrameLoaderOwner)
-        .frameLoader.QueryInterface(Ci.nsIWebBrowserPersistable);
+      let persistable = browser.frameLoader;
       persistable.startPersistence(message.data.windowID, {
         onDocumentReady(doc) {
           let uri = chrome.makeURI(doc.documentURI, doc.characterSet);
           let filename = chrome.getDefaultFileName(undefined, uri, doc, null);
           chrome.internalSave(message.data.url, doc, filename, null, doc.contentType,
             false, null, null, null, doc, false, null, undefined);
         },
         onError(status) {
--- a/layout/tools/reftest/reftest.jsm
+++ b/layout/tools/reftest/reftest.jsm
@@ -331,18 +331,17 @@ this.OnRefTestLoad = function OnRefTestL
     if (plugin1 && plugin2) {
       gTestPluginEnabledStates = [plugin1.enabledState, plugin2.enabledState];
       plugin1.enabledState = CI.nsIPluginTag.STATE_ENABLED;
       plugin2.enabledState = CI.nsIPluginTag.STATE_ENABLED;
     } else {
       logger.warning("Could not get test plugin tags.");
     }
 
-    gBrowserMessageManager = gBrowser.QueryInterface(CI.nsIFrameLoaderOwner)
-                                     .frameLoader.messageManager;
+    gBrowserMessageManager = gBrowser.frameLoader.messageManager;
     // The content script waits for the initial onload, then notifies
     // us.
     RegisterMessageListenersAndLoadContentScript();
 }
 
 function InitAndStartRefTests()
 {
     /* These prefs are optional, so we don't need to spit an error to the log */
--- a/mobile/android/chrome/content/aboutAccounts.js
+++ b/mobile/android/chrome/content/aboutAccounts.js
@@ -89,17 +89,16 @@ var wrapper = {
   url: null,
 
   init: function(url) {
     this.url = url;
     deferTransitionToRemoteAfterLoaded();
 
     let iframe = document.getElementById("remote");
     this.iframe = iframe;
-    this.iframe.QueryInterface(Ci.nsIFrameLoaderOwner);
     let docShell = this.iframe.frameLoader.docShell;
     docShell.QueryInterface(Ci.nsIWebProgress);
     docShell.addProgressListener(this.iframeListener,
                                  Ci.nsIWebProgress.NOTIFY_STATE_DOCUMENT |
                                  Ci.nsIWebProgress.NOTIFY_LOCATION);
 
     // Set the iframe's location with loadURI/LOAD_FLAGS_BYPASS_HISTORY to
     // avoid having a new history entry being added.
--- a/mobile/android/chrome/content/browser.js
+++ b/mobile/android/chrome/content/browser.js
@@ -3421,20 +3421,17 @@ nsBrowserAccess.prototype = {
   openURIInFrame: function browser_openURIInFrame(aURI, aParams, aWhere, aFlags,
                                                   aNextTabParentId, aName) {
     // We currently ignore aNextTabParentId on mobile.  This needs to change
     // when Fennec starts to support e10s.  Assertions will fire if this code
     // isn't fixed by then.
     //
     // We also ignore aName if it is set, as it is currently only used on the
     // e10s codepath.
-    let browser = this._getBrowser(aURI, null, aWhere, aFlags, null);
-    if (browser)
-      return browser.QueryInterface(Ci.nsIFrameLoaderOwner);
-    return null;
+    return this._getBrowser(aURI, null, aWhere, aFlags, null);
   },
 
   isTabContentWindow: function(aWindow) {
     return BrowserApp.getBrowserForWindow(aWindow) != null;
   },
 
   canClose() {
     return BrowserUtils.canCloseWindow(window);
--- a/mobile/android/modules/geckoview/GeckoViewNavigation.jsm
+++ b/mobile/android/modules/geckoview/GeckoViewNavigation.jsm
@@ -118,17 +118,17 @@ class GeckoViewNavigation extends GeckoV
           " aParams=" + aParams +
           " aWhere=" + aWhere +
           " aFlags=" + aFlags +
           " aNextTabParentId=" + aNextTabParentId +
           " aName=" + aName);
 
     if (aWhere === Ci.nsIBrowserDOMWindow.OPEN_DEFAULTWINDOW ||
         aWhere === Ci.nsIBrowserDOMWindow.OPEN_CURRENTWINDOW) {
-      return this.browser.QueryInterface(Ci.nsIFrameLoaderOwner);
+      return this.browser;
     }
 
     throw Cr.NS_ERROR_ABORT;
   }
 
   isTabContentWindow(aWindow) {
     debug("isTabContentWindow " + this.browser.contentWindow === aWindow);
     return this.browser.contentWindow === aWindow;
--- a/testing/marionette/frame.js
+++ b/testing/marionette/frame.js
@@ -132,18 +132,17 @@ frame.Manager = class {
     let outerWin = Services.wm.getOuterWindowWithId(winId);
     // find the OOP frame
     let f = outerWin.document.getElementsByTagName("iframe")[frameId];
     return f;
   }
 
   getFrameMM(winId, frameId) {
     let oopFrame = this.getOopFrame(winId, frameId);
-    let mm = oopFrame.QueryInterface(Ci.nsIFrameLoaderOwner)
-        .frameLoader.messageManager;
+    let mm = oopFrame.frameLoader.messageManager;
     return mm;
   }
 
   /**
    * Switch to OOP frame.  We're handling this here so we can maintain
    * a list of remote frames.
    */
   switchToFrame(winId, frameId) {
--- a/testing/specialpowers/content/SpecialPowersObserver.jsm
+++ b/testing/specialpowers/content/SpecialPowersObserver.jsm
@@ -228,19 +228,17 @@ SpecialPowersObserver.prototype._registe
 /**
  * messageManager callback function
  * This will get requests from our API in the window and process them in chrome for it
  **/
 SpecialPowersObserver.prototype.receiveMessage = function(aMessage) {
   switch (aMessage.name) {
     case "SPPingService":
       if (aMessage.json.op == "ping") {
-        aMessage.target
-                .QueryInterface(Ci.nsIFrameLoaderOwner)
-                .frameLoader
+        aMessage.target.frameLoader
                 .messageManager
                 .sendAsyncMessage("SPPingService", { op: "pong" });
       }
       break;
     case "SpecialPowers.Quit":
       let appStartup = Cc["@mozilla.org/toolkit/app-startup;1"].getService(Ci.nsIAppStartup);
       appStartup.quit(Ci.nsIAppStartup.eForceQuit);
       break;
@@ -272,32 +270,26 @@ SpecialPowersObserver.prototype.receiveM
           outStream.close();
           promises.push(File.createFromFileName(testFile.path, request.options).then(function(file) {
             filePaths.push(file);
           }));
           createdFiles.push(testFile);
         });
 
         Promise.all(promises).then(function() {
-          aMessage.target
-                  .QueryInterface(Ci.nsIFrameLoaderOwner)
-                  .frameLoader
+          aMessage.target.frameLoader
                   .messageManager
                   .sendAsyncMessage("SpecialPowers.FilesCreated", filePaths);
         }, function(e) {
-          aMessage.target
-                  .QueryInterface(Ci.nsIFrameLoaderOwner)
-                  .frameLoader
+          aMessage.target.frameLoader
                   .messageManager
                   .sendAsyncMessage("SpecialPowers.FilesError", e.toString());
         });
       } catch (e) {
-          aMessage.target
-                  .QueryInterface(Ci.nsIFrameLoaderOwner)
-                  .frameLoader
+          aMessage.target.frameLoader
                   .messageManager
                   .sendAsyncMessage("SpecialPowers.FilesError", e.toString());
       }
 
       break;
     case "SpecialPowers.RemoveFiles":
       if (this._createdFiles) {
         this._createdFiles.forEach(function(testFile) {
--- a/testing/specialpowers/content/SpecialPowersObserverAPI.js
+++ b/testing/specialpowers/content/SpecialPowersObserverAPI.js
@@ -243,19 +243,17 @@ SpecialPowersObserverAPI.prototype = {
         "The script doesn't exists. Ensure you have registered it in " +
         "'support-files' in your mochitest.ini.");
     }
 
     return output;
   },
 
   _sendReply(aMessage, aReplyName, aReplyMsg) {
-    let mm = aMessage.target
-                     .QueryInterface(Ci.nsIFrameLoaderOwner)
-                     .frameLoader
+    let mm = aMessage.target.frameLoader
                      .messageManager;
     mm.sendAsyncMessage(aReplyName, aReplyMsg);
   },
 
   _notifyCategoryAndObservers(subject, topic, data) {
     const serviceMarker = "service,";
 
     // First create observers from the category manager.
@@ -466,19 +464,17 @@ SpecialPowersObserverAPI.prototype = {
         // and addMessageListener in order to communicate with
         // the mochitest.
         let systemPrincipal = Services.scriptSecurityManager.getSystemPrincipal();
         let sandboxOptions = aMessage.json.sandboxOptions;
         if (!sandboxOptions) {
           sandboxOptions = {}
         }
         let sb = Components.utils.Sandbox(systemPrincipal, sandboxOptions);
-        let mm = aMessage.target
-                         .QueryInterface(Ci.nsIFrameLoaderOwner)
-                         .frameLoader
+        let mm = aMessage.target.frameLoader
                          .messageManager;
         sb.sendAsyncMessage = (name, message) => {
           mm.sendAsyncMessage("SPChromeScriptMessage",
                               { id, name, message });
         };
         sb.addMessageListener = (name, listener) => {
           this._chromeScriptListeners.push({ id, name, listener });
         };
--- a/testing/specialpowers/content/specialpowers.js
+++ b/testing/specialpowers/content/specialpowers.js
@@ -197,17 +197,17 @@ SpecialPowers.prototype.nestedFrameSetup
     let frameLoader = subject;
     // get a ref to the app <iframe>
     frameLoader.QueryInterface(Components.interfaces.nsIFrameLoader);
     let frame = frameLoader.ownerElement;
     let frameId = frame.getAttribute("id");
     if (frameId === "nested-parent-frame") {
       Services.obs.removeObserver(onRemoteBrowserShown, "remote-browser-shown");
 
-      let mm = frame.QueryInterface(Components.interfaces.nsIFrameLoaderOwner).frameLoader.messageManager;
+      let mm = frame.frameLoader.messageManager;
       self._grandChildFrameMM = mm;
 
       self.SP_SYNC_MESSAGES.forEach(function(msgname) {
         mm.addMessageListener(msgname, function(msg) {
           return self._sendSyncMessage(msgname, msg.data)[0];
         });
       });
       self.SP_ASYNC_MESSAGES.forEach(function(msgname) {
--- a/testing/specialpowers/content/specialpowersAPI.js
+++ b/testing/specialpowers/content/specialpowersAPI.js
@@ -1799,19 +1799,17 @@ SpecialPowersAPI.prototype = {
     var debugsvc = Cc["@mozilla.org/xpcom/debug;1"].getService(Ci.nsIDebug2);
     return debugsvc.assertionCount;
   },
 
   /**
    * Get the message manager associated with an <iframe mozbrowser>.
    */
   getBrowserFrameMessageManager(aFrameElement) {
-    return this.wrap(aFrameElement.QueryInterface(Ci.nsIFrameLoaderOwner)
-                                  .frameLoader
-                                  .messageManager);
+    return this.wrap(aFrameElement.frameLoader.messageManager);
   },
 
   _getPrincipalFromArg(arg) {
     let principal;
     let secMan = Services.scriptSecurityManager;
 
     if (typeof(arg) == "string") {
       // It's an URL.
--- a/toolkit/components/contextualidentity/ContextualIdentityService.jsm
+++ b/toolkit/components/contextualidentity/ContextualIdentityService.jsm
@@ -365,17 +365,17 @@ function _ContextualIdentityService(path
     }, userContextId);
     return count;
   },
 
   closeContainerTabs(userContextId = 0) {
     return new Promise(resolve => {
       let tabParentIds = new Set();
       this._forEachContainerTab((tab, tabbrowser) => {
-        let frameLoader = tab.linkedBrowser.QueryInterface(Ci.nsIFrameLoaderOwner).frameLoader;
+        let frameLoader = tab.linkedBrowser.frameLoader;
 
         // We don't have tabParent in non-e10s mode.
         if (frameLoader.tabParent) {
           tabParentIds.add(frameLoader.tabParent.tabId);
         }
 
         tabbrowser.removeTab(tab);
       }, userContextId);
--- a/toolkit/components/extensions/ExtensionUtils.jsm
+++ b/toolkit/components/extensions/ExtensionUtils.jsm
@@ -401,18 +401,18 @@ function promiseObserved(topic, test = (
         resolve({subject, data});
       }
     };
     Services.obs.addObserver(observer, topic);
   });
 }
 
 function getMessageManager(target) {
-  if (target instanceof Ci.nsIFrameLoaderOwner) {
-    return target.QueryInterface(Ci.nsIFrameLoaderOwner).frameLoader.messageManager;
+  if (target.frameLoader) {
+    return target.frameLoader.messageManager;
   }
   return target.QueryInterface(Ci.nsIMessageSender);
 }
 
 function flushJarCache(jarPath) {
   Services.obs.notifyObservers(null, "flush-cache-entry", jarPath);
 }
 
--- a/toolkit/content/contentAreaUtils.js
+++ b/toolkit/content/contentAreaUtils.js
@@ -164,25 +164,23 @@ function saveImageURL(aURL, aFileName, a
   }
 
   internalSave(aURL, null, aFileName, aContentDisp, aContentType,
                aShouldBypassCache, aFilePickerTitleKey, null, aReferrer,
                null, aSkipPrompt, null, aIsContentWindowPrivate);
 }
 
 // This is like saveDocument, but takes any browser/frame-like element
-// (nsIFrameLoaderOwner) and saves the current document inside it,
+// and saves the current document inside it,
 // whether in-process or out-of-process.
 function saveBrowser(aBrowser, aSkipPrompt, aOuterWindowID = 0) {
   if (!aBrowser) {
     throw "Must have a browser when calling saveBrowser";
   }
-  let persistable = aBrowser.QueryInterface(Ci.nsIFrameLoaderOwner)
-                    .frameLoader
-                    .QueryInterface(Ci.nsIWebBrowserPersistable);
+  let persistable = aBrowser.frameLoader;
   let stack = Components.stack.caller;
   persistable.startPersistence(aOuterWindowID, {
     onDocumentReady(document) {
       saveDocument(document, aSkipPrompt);
     },
     onError(status) {
       throw new Components.Exception("saveBrowser failed asynchronously in startPersistence",
                                      status, stack);
--- a/toolkit/content/widgets/browser.xml
+++ b/toolkit/content/widgets/browser.xml
@@ -246,32 +246,32 @@
 
       <field name="_docShell">null</field>
 
       <property name="docShell" readonly="true">
         <getter><![CDATA[
           if (this._docShell)
             return this._docShell;
 
-          let frameLoader = this.QueryInterface(Components.interfaces.nsIFrameLoaderOwner).frameLoader;
+          let {frameLoader} = this;
           if (!frameLoader)
             return null;
           this._docShell = frameLoader.docShell;
           return this._docShell;
         ]]></getter>
       </property>
 
       <field name="_loadContext">null</field>
 
       <property name="loadContext" readonly="true">
         <getter><![CDATA[
           if (this._loadContext)
             return this._loadContext;
 
-          let frameLoader = this.QueryInterface(Components.interfaces.nsIFrameLoaderOwner).frameLoader;
+          let {frameLoader} = this;
           if (!frameLoader)
             return null;
           this._loadContext = frameLoader.loadContext;
           return this._loadContext;
         ]]></getter>
       </property>
 
       <property name="autoCompletePopup"
@@ -342,21 +342,20 @@
           ]]>
         </getter>
       </property>
 
       <property name="messageManager"
                 readonly="true">
         <getter>
           <![CDATA[
-            var owner = this.QueryInterface(Components.interfaces.nsIFrameLoaderOwner);
-            if (!owner.frameLoader) {
-              return null;
+            if (this.frameLoader) {
+              return this.frameLoader.messageManager;
             }
-            return owner.frameLoader.messageManager;
+            return null;
           ]]>
         </getter>
 
       </property>
 
       <field name="_webNavigation">null</field>
 
       <property name="webNavigation"
@@ -1564,24 +1563,23 @@
       </method>
 
       <method name="print">
         <parameter name="aOuterWindowID"/>
         <parameter name="aPrintSettings"/>
         <parameter name="aPrintProgressListener"/>
         <body>
           <![CDATA[
-            var owner = this.QueryInterface(Components.interfaces.nsIFrameLoaderOwner);
-            if (!owner.frameLoader) {
+            if (!this.frameLoader) {
               throw Components.Exception("No frame loader.",
                                          Components.results.NS_ERROR_FAILURE);
             }
 
-            owner.frameLoader.print(aOuterWindowID, aPrintSettings,
-                                    aPrintProgressListener);
+            this.frameLoader.print(aOuterWindowID, aPrintSettings,
+                                   aPrintProgressListener);
           ]]>
         </body>
       </method>
 
       <method name="dropLinks">
         <parameter name="aLinksCount"/>
         <parameter name="aLinks"/>
         <parameter name="aTriggeringPrincipal"/>
--- a/toolkit/content/widgets/editor.xml
+++ b/toolkit/content/widgets/editor.xml
@@ -125,17 +125,17 @@
                 onset="this.setAttribute('editortype', val); return val;"/>
       <property name="webNavigation"
                 onget="return this.docShell.QueryInterface(Components.interfaces.nsIWebNavigation);"
                 readonly="true"/>
       <property name="contentDocument" readonly="true"
                 onget="return this.webNavigation.document;"/>
       <property name="docShell" readonly="true">
         <getter><![CDATA[
-          let frameLoader = this.QueryInterface(Components.interfaces.nsIFrameLoaderOwner).frameLoader;
+          let {frameLoader} = this;
           return frameLoader ? frameLoader.docShell : null;
         ]]></getter>
       </property>
       <property name="currentURI"
                 readonly="true"
                 onget="return this.webNavigation.currentURI;"/>
       <property name="contentWindow"
                 readonly="true"
@@ -163,21 +163,20 @@
                 onset="this.markupDocumentViewer.textZoom = val;"/>
       <property name="isSyntheticDocument"
                 onget="return this.contentDocument.isSyntheticDocument;"
                 readonly="true"/>
       <property name="messageManager"
                 readonly="true">
         <getter>
           <![CDATA[
-            var owner = this.QueryInterface(Components.interfaces.nsIFrameLoaderOwner);
-            if (!owner.frameLoader) {
-              return null;
+            if (this.frameLoader) {
+              return this.frameLoader.messageManager;
             }
-            return owner.frameLoader.messageManager;
+            return null;
           ]]>
         </getter>
       </property>
       <property name="outerWindowID" readonly="true">
         <getter><![CDATA[
           return this.contentWindow
                      .QueryInterface(Components.interfaces.nsIInterfaceRequestor)
                      .getInterface(Components.interfaces.nsIDOMWindowUtils)
--- a/toolkit/content/widgets/general.xml
+++ b/toolkit/content/widgets/general.xml
@@ -82,17 +82,17 @@
       ]]></destructor>
     </implementation>
   </binding>
 
   <binding id="iframe" role="outerdoc">
     <implementation>
       <property name="docShell" readonly="true">
         <getter><![CDATA[
-          let frameLoader = this.QueryInterface(Components.interfaces.nsIFrameLoaderOwner).frameLoader;
+          let {frameLoader} = this;
           return frameLoader ? frameLoader.docShell : null;
         ]]></getter>
       </property>
       <property name="contentWindow"
                 readonly="true"
                 onget="return this.docShell.QueryInterface(Components.interfaces.nsIInterfaceRequestor).getInterface(Components.interfaces.nsIDOMWindow);"/>
       <property name="webNavigation"
                 onget="return this.docShell.QueryInterface(Components.interfaces.nsIWebNavigation);"
--- a/toolkit/content/widgets/remote-browser.xml
+++ b/toolkit/content/widgets/remote-browser.xml
@@ -207,18 +207,17 @@
       <property name="isSyntheticDocument">
         <getter><![CDATA[
           return this._isSyntheticDocument;
         ]]></getter>
       </property>
 
       <property name="hasContentOpener">
         <getter><![CDATA[
-          let {frameLoader} = this.QueryInterface(Components.interfaces.nsIFrameLoaderOwner);
-          return frameLoader.tabParent.hasContentOpener;
+          return this.frameLoader.tabParent.hasContentOpener;
         ]]></getter>
       </property>
 
       <field name="_outerWindowID">null</field>
       <property name="outerWindowID"
                 onget="return this._outerWindowID"
                 readonly="true"/>
 
@@ -227,33 +226,31 @@
         <getter><![CDATA[
           return this._innerWindowID;
         ]]></getter>
       </property>
 
       <property name="docShellIsActive">
         <getter>
           <![CDATA[
-            let {frameLoader} = this.QueryInterface(Components.interfaces.nsIFrameLoaderOwner);
-            return frameLoader.tabParent.docShellIsActive;
+            return this.frameLoader.tabParent.docShellIsActive;
           ]]>
         </getter>
         <setter>
           <![CDATA[
-            let {frameLoader} = this.QueryInterface(Components.interfaces.nsIFrameLoaderOwner);
-            frameLoader.tabParent.docShellIsActive = val;
+            this.frameLoader.tabParent.docShellIsActive = val;
             return val;
           ]]>
         </setter>
       </property>
 
       <method name="preserveLayers">
         <parameter name="preserve"/>
         <body><![CDATA[
-          let {frameLoader} = this.QueryInterface(Components.interfaces.nsIFrameLoaderOwner);
+          let {frameLoader} = this;
           if (frameLoader.tabParent) {
             frameLoader.tabParent.preserveLayers(preserve);
           }
         ]]></body>
       </method>
 
       <field name="_manifestURI"/>
       <property name="manifestURI"
@@ -279,18 +276,17 @@
           });
         ]]>
         </body>
       </method>
 
       <method name="permitUnload">
         <body>
         <![CDATA[
-          let { frameLoader } = this.QueryInterface(Components.interfaces.nsIFrameLoaderOwner);
-          let tabParent = frameLoader.tabParent;
+          let {tabParent} = this.frameLoader;
 
           if (!tabParent.hasBeforeUnload) {
             return { permitUnload: true, timedOut: false };
           }
 
           const kTimeout = 1000;
 
           let finished = false;
@@ -556,18 +552,17 @@
       <method name="createAboutBlankContentViewer">
         <parameter name="aPrincipal"/>
         <body>
           <![CDATA[
             // Ensure that the content process has the permissions which are
             // needed to create a document with the given principal.
             let permissionPrincipal =
               BrowserUtils.principalWithMatchingOA(aPrincipal, this.contentPrincipal);
-            let {frameLoader} = this.QueryInterface(Components.interfaces.nsIFrameLoaderOwner);
-            frameLoader.tabParent.transmitPermissionsForPrincipal(permissionPrincipal);
+            this.frameLoader.tabParent.transmitPermissionsForPrincipal(permissionPrincipal);
 
             // Create the about blank content viewer in the content process
             this.messageManager.sendAsyncMessage("Browser:CreateAboutBlank", aPrincipal);
           ]]>
         </body>
       </method>
     </implementation>
     <handlers>