Bug 1383059 - Remove instanceof for supplemental interfaces. Part 1: add Window.isChromeWindow and switch |instanceof [nsIDOM]ChromeWindow| to use it instead. r=bz.
authorPeter Van der Beken <peterv@propagandism.org>
Fri, 06 Oct 2017 13:47:27 +0200
changeset 385480 f6b5bbc888413b87292a34fcfb4a039dc1712fe4
parent 385479 55161cebaca079886f2d7e5f323928392d299f0b
child 385481 a3d4cd8f538db7e3e61998d547579cc5fd26f2b2
push id32656
push userarchaeopteryx@coole-files.de
push dateWed, 11 Oct 2017 09:50:40 +0000
treeherdermozilla-central@20d9ad08dd36 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbz
bugs1383059
milestone58.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 1383059 - Remove instanceof for supplemental interfaces. Part 1: add Window.isChromeWindow and switch |instanceof [nsIDOM]ChromeWindow| to use it instead. r=bz.
accessible/jsat/EventManager.jsm
accessible/jsat/PointerAdapter.jsm
browser/base/content/tabbrowser.xml
browser/components/places/content/controller.js
browser/components/sessionstore/test/browser_394759_basic.js
devtools/server/actors/webbrowser.js
docshell/test/navigation/NavigationUtils.js
dom/base/test/test_bug1016960.html
dom/webidl/Window.webidl
js/src/tests/browser.js
toolkit/components/passwordmgr/nsLoginManagerPrompter.js
toolkit/content/widgets/text.xml
toolkit/content/widgets/textbox.xml
toolkit/modules/PrivateBrowsingUtils.jsm
--- a/accessible/jsat/EventManager.jsm
+++ b/accessible/jsat/EventManager.jsm
@@ -689,18 +689,17 @@ const AccessibilityEventObserver = {
         Logger.eventToString(event), "accessible:",
         Logger.accessibleToString(event.accessible));
       return;
     }
     let content = event.accessibleDocument.window;
     // Match the content window to its EventManager.
     let eventManager = this.getListener(content);
     if (!eventManager || !eventManager._started) {
-      if (Utils.MozBuildApp === "browser" &&
-          !(content instanceof Ci.nsIDOMChromeWindow)) {
+      if (Utils.MozBuildApp === "browser" && !content.isChromeWindow) {
         Logger.warning(
           "AccessibilityEventObserver.observe: ignored event:",
           Logger.eventToString(event), "accessible:",
           Logger.accessibleToString(event.accessible), "document:",
           Logger.accessibleToString(event.accessibleDocument));
       }
       return;
     }
--- a/accessible/jsat/PointerAdapter.jsm
+++ b/accessible/jsat/PointerAdapter.jsm
@@ -86,18 +86,17 @@ var PointerRelay = { // jshint ignore:li
     delete this.onPointerEvent;
     for (let eventType in this._eventsOfInterest) {
       Utils.win.removeEventListener(eventType, this, true, true);
     }
   },
 
   handleEvent: function PointerRelay_handleEvent(aEvent) {
     // Don't bother with chrome mouse events.
-    if (Utils.MozBuildApp === "browser" &&
-      aEvent.view.top instanceof Ci.nsIDOMChromeWindow) {
+    if (Utils.MozBuildApp === "browser" && aEvent.view.top.isChromeWindow) {
       return;
     }
     if (aEvent.mozInputSource === Ci.nsIDOMMouseEvent.MOZ_SOURCE_UNKNOWN ||
         aEvent.isSynthesized) {
       // Ignore events that are scripted or clicks from the a11y API.
       return;
     }
 
--- a/browser/base/content/tabbrowser.xml
+++ b/browser/base/content/tabbrowser.xml
@@ -7069,17 +7069,17 @@
           var dt = event.dataTransfer;
           if (dt.mozItemCount == 1) {
             var types = dt.mozTypesAt(0);
             // tabs are always added as the first type
             if (types[0] == TAB_DROP_TYPE) {
               let sourceNode = dt.mozGetDataAt(TAB_DROP_TYPE, 0);
               if (sourceNode instanceof XULElement &&
                   sourceNode.localName == "tab" &&
-                  sourceNode.ownerGlobal instanceof ChromeWindow &&
+                  sourceNode.ownerGlobal.isChromeWindow &&
                   sourceNode.ownerDocument.documentElement.getAttribute("windowtype") == "navigator:browser" &&
                   sourceNode.ownerGlobal.gBrowser.tabContainer == sourceNode.parentNode) {
                 // Do not allow transfering a private tab to a non-private window
                 // and vice versa.
                 if (PrivateBrowsingUtils.isWindowPrivate(window) !=
                     PrivateBrowsingUtils.isWindowPrivate(sourceNode.ownerGlobal))
                   return "none";
 
--- a/browser/components/places/content/controller.js
+++ b/browser/components/places/content/controller.js
@@ -1635,17 +1635,17 @@ var PlacesControllerDragHelper = {
       dtItems.push({flavor, data});
     }
 
     for (let {flavor, data} of dtItems) {
       let nodes;
       if (flavor != TAB_DROP_TYPE) {
         nodes = PlacesUtils.unwrapNodes(data, flavor);
       } else if (data instanceof XULElement && data.localName == "tab" &&
-               data.ownerGlobal instanceof ChromeWindow) {
+               data.ownerGlobal.isChromeWindow) {
         let uri = data.linkedBrowser.currentURI;
         let spec = uri ? uri.spec : "about:blank";
         nodes = [{ uri: spec,
                    title: data.label,
                    type: PlacesUtils.TYPE_X_MOZ_URL}];
       } else
         throw new Error("bogus data was passed as a tab");
 
--- a/browser/components/sessionstore/test/browser_394759_basic.js
+++ b/browser/components/sessionstore/test/browser_394759_basic.js
@@ -45,17 +45,17 @@ function test() {
            "Non-serialized data is the same as serialized data")
 
         ok(data[0].title == TEST_URL && JSON.stringify(data[0]).indexOf(uniqueText) > -1,
            "The closed window data was stored correctly");
 
         // Reopen the closed window and ensure its integrity.
         let newWin2 = ss.undoCloseWindow(0);
 
-        ok(newWin2 instanceof ChromeWindow,
+        ok(newWin2.isChromeWindow,
            "undoCloseWindow actually returned a window");
         is(ss.getClosedWindowCount(), 0,
            "The reopened window was removed from Recently Closed Windows");
 
         // SSTabRestored will fire more than once, so we need to make sure we count them.
         let restoredTabs = 0;
         let expectedTabs = data[0].tabs.length;
         newWin2.addEventListener("SSTabRestored", function sstabrestoredListener(aEvent) {
--- a/devtools/server/actors/webbrowser.js
+++ b/devtools/server/actors/webbrowser.js
@@ -323,17 +323,17 @@ BrowserTabList.prototype._getActorForBro
   return actor.connect();
 };
 
 BrowserTabList.prototype.getTab = function ({ outerWindowID, tabId }) {
   if (typeof outerWindowID == "number") {
     // First look for in-process frames with this ID
     let window = Services.wm.getOuterWindowWithId(outerWindowID);
     // Safety check to prevent debugging top level window via getTab
-    if (window instanceof Ci.nsIDOMChromeWindow) {
+    if (window && window.isChromeWindow) {
       return promise.reject({
         error: "forbidden",
         message: "Window with outerWindowID '" + outerWindowID + "' is chrome"
       });
     }
     if (window) {
       let iframe = window.QueryInterface(Ci.nsIInterfaceRequestor)
                          .getInterface(Ci.nsIDOMWindowUtils)
--- a/docshell/test/navigation/NavigationUtils.js
+++ b/docshell/test/navigation/NavigationUtils.js
@@ -103,17 +103,17 @@ function xpcEnumerateContentWindows(call
   var ww = SpecialPowers.Cc["@mozilla.org/embedcomp/window-watcher;1"]
                         .getService(Ci.nsIWindowWatcher);
   var enumerator = ww.getWindowEnumerator();
 
   var contentWindows = [];
 
   while (enumerator.hasMoreElements()) {
     var win = enumerator.getNext();
-    if (/ChromeWindow/.exec(win)) {
+    if (win.isChromeWindow) {
       var docshellTreeNode = win.QueryInterface(Ci.nsIInterfaceRequestor)
                                 .getInterface(Ci.nsIWebNavigation)
                                 .QueryInterface(Ci.nsIDocShellTreeItem);
       var childCount = docshellTreeNode.childCount;
       for (var i = 0; i < childCount; ++i) {
         var childTreeNode = docshellTreeNode.getChildAt(i);
 
         // we're only interested in content docshells
--- a/dom/base/test/test_bug1016960.html
+++ b/dom/base/test/test_bug1016960.html
@@ -9,16 +9,17 @@ https://bugzilla.mozilla.org/show_bug.cg
   <script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
   <link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"/>
   <script type="application/javascript">
 
   /** Test for Bug 1016960 **/
 
   var chromeWindow = window.open("chrome://mochitests/content/chrome/dom/base/test/file_empty.html", "1016960", "chrome");
   ok(chromeWindow instanceof ChromeWindow, "A chrome window should return true for |instanceof ChromeWindow|.");
+  ok(chromeWindow.isChromeWindow, "A chrome window should return true for |instanceof ChromeWindow|.");
   chromeWindow.close();
 
   </script>
 </head>
 <body>
 <a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1016960">Mozilla Bug 1016960</a>
 <p id="display"></p>
 <div id="content" style="display: none">
--- a/dom/webidl/Window.webidl
+++ b/dom/webidl/Window.webidl
@@ -441,16 +441,22 @@ interface ChromeWindow {
    * The optional panel argument should be set when moving a panel.
    *
    * Throws NS_ERROR_NOT_IMPLEMENTED if the OS doesn't support this.
    */
   [Throws, Func="nsGlobalWindow::IsPrivilegedChromeWindow"]
   void beginWindowMove(Event mouseDownEvent, optional Element? panel = null);
 };
 
+// Mozilla extensions for Chrome windows.
+partial interface Window {
+  [Func="IsChromeOrXBL"]
+  readonly attribute boolean isChromeWindow;
+};
+
 partial interface Window {
   [Pref="dom.vr.enabled"]
   attribute EventHandler onvrdisplayconnect;
   [Pref="dom.vr.enabled"]
   attribute EventHandler onvrdisplaydisconnect;
   [Pref="dom.vr.enabled"]
   attribute EventHandler onvrdisplayactivate;
   [Pref="dom.vr.enabled"]
--- a/js/src/tests/browser.js
+++ b/js/src/tests/browser.js
@@ -725,17 +725,17 @@ function unregisterDialogCloser()
 }
 
 // use an array to handle the case where multiple dialogs
 // appear at one time
 var gDialogCloserSubjects = [];
 
 function dialogCloser_observe(subject, topic, data)
 {
-  if (subject instanceof ChromeWindow && topic == 'domwindowopened' )
+  if (topic == 'domwindowopened' && subject.isChromeWindow)
   {
     gDialogCloserSubjects.push(subject);
     // timeout of 0 needed when running under reftest framework.
     subject.setTimeout(closeDialog, 0);
   }
 }
 
 function closeDialog()
--- a/toolkit/components/passwordmgr/nsLoginManagerPrompter.js
+++ b/toolkit/components/passwordmgr/nsLoginManagerPrompter.js
@@ -731,17 +731,17 @@ LoginManagerPrompter.prototype = {
   /* ---------- nsILoginManagerPrompter prompts ---------- */
 
 
   init(aWindow = null, aFactory = null) {
     if (!aWindow) {
       // There may be no applicable window e.g. in a Sandbox or JSM.
       this._chromeWindow = null;
       this._browser = null;
-    } else if (aWindow instanceof Ci.nsIDOMChromeWindow) {
+    } else if (aWindow.isChromeWindow) {
       this._chromeWindow = aWindow;
       // needs to be set explicitly using setBrowser
       this._browser = null;
     } else {
       let {win, browser} = this._getChromeWindow(aWindow);
       this._chromeWindow = win;
       this._browser = browser;
     }
--- a/toolkit/content/widgets/text.xml
+++ b/toolkit/content/widgets/text.xml
@@ -357,17 +357,17 @@
           Components.classes["@mozilla.org/observer-service;1"]
                     .getService(Components.interfaces.nsIObserverService)
                     .notifyObservers(linkHandled, "handle-xul-text-link", JSON.stringify(data));
           if (linkHandled.data)
             return;
 
           // otherwise, fall back to opening the anchor directly
           var win = window;
-          if (window instanceof Components.interfaces.nsIDOMChromeWindow) {
+          if (window.isChromeWindow) {
             while (win.opener && !win.opener.closed)
               win = win.opener;
           }
           win.open(href);
         ]]>
         </body>
       </method>
     </implementation>
--- a/toolkit/content/widgets/textbox.xml
+++ b/toolkit/content/widgets/textbox.xml
@@ -212,17 +212,17 @@
       </handler>
 
       <handler event="blur" phase="capturing">
         <![CDATA[
           this.removeAttribute("focused");
 
           // don't trigger clickSelectsAll when switching application windows
           if (window == window.top &&
-              window.constructor == ChromeWindow &&
+              window.isChromeWindow &&
               document.activeElement == this.inputField)
             this.mIgnoreFocus = true;
         ]]>
       </handler>
 
       <handler event="mousedown">
         <![CDATA[
           this.mIgnoreClick = this.hasAttribute("focused");
--- a/toolkit/modules/PrivateBrowsingUtils.jsm
+++ b/toolkit/modules/PrivateBrowsingUtils.jsm
@@ -14,17 +14,17 @@ var gTemporaryAutoStartMode = false;
 
 const Cc = Components.classes;
 const Ci = Components.interfaces;
 
 this.PrivateBrowsingUtils = {
   // Rather than passing content windows to this function, please use
   // isBrowserPrivate since it works with e10s.
   isWindowPrivate: function pbu_isWindowPrivate(aWindow) {
-    if (!(aWindow instanceof Components.interfaces.nsIDOMChromeWindow)) {
+    if (!aWindow.isChromeWindow) {
       dump("WARNING: content window passed to PrivateBrowsingUtils.isWindowPrivate. " +
            "Use isContentWindowPrivate instead (but only for frame scripts).\n"
            + new Error().stack);
     }
 
     return this.privacyContextFromWindow(aWindow).usePrivateBrowsing;
   },