Bug 1484496: Part 5d - Convert devtools/ nsISimpleEnumerator users to use JS iteration. r=bgrins
authorKris Maglione <maglione.k@gmail.com>
Sat, 18 Aug 2018 19:28:37 -0700
changeset 488335 719523b165252de73b82dda809015d3582fca6af
parent 488334 3f1617759de56e327eb0b4edf1c4689a95ad8023
child 488336 7b496ebb5bbf0c42c3dd64a90022fbadd4005239
push id9719
push userffxbld-merge
push dateFri, 24 Aug 2018 17:49:46 +0000
treeherdermozilla-beta@719ec98fba77 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbgrins
bugs1484496
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 1484496: Part 5d - Convert devtools/ nsISimpleEnumerator users to use JS iteration. r=bgrins Differential Revision: https://phabricator.services.mozilla.com/D3732
devtools/client/framework/devtools-browser.js
devtools/client/framework/test/browser_toolbox_dynamic_registration.js
devtools/client/framework/test/browser_toolbox_tools_per_toolbox_registration.js
devtools/client/scratchpad/scratchpad-manager.jsm
devtools/client/shared/view-source.js
devtools/server/actors/accessibility.js
devtools/server/actors/inspector/walker.js
devtools/server/actors/replay/graphics.js
devtools/server/actors/storage.js
devtools/server/actors/targets/addon.js
devtools/server/actors/targets/browsing-context.js
devtools/server/actors/targets/content-process.js
devtools/server/actors/targets/parent-process.js
devtools/server/actors/targets/webextension.js
devtools/server/actors/webbrowser.js
devtools/server/actors/worker/worker-list.js
devtools/server/performance/timeline.js
devtools/shared/system.js
devtools/startup/devtools-startup.js
--- a/devtools/client/framework/devtools-browser.js
+++ b/devtools/client/framework/devtools-browser.js
@@ -738,15 +738,13 @@ gDevTools.on("toolbox-destroyed", gDevTo
 
 Services.obs.addObserver(gDevToolsBrowser, "quit-application");
 Services.obs.addObserver(gDevToolsBrowser, "browser-delayed-startup-finished");
 // Watch for module loader unload. Fires when the tools are reloaded.
 Services.obs.addObserver(gDevToolsBrowser, "devtools:loader:destroy");
 
 // Fake end of browser window load event for all already opened windows
 // that is already fully loaded.
-const enumerator = Services.wm.getEnumerator(gDevTools.chromeWindowType);
-while (enumerator.hasMoreElements()) {
-  const win = enumerator.getNext();
+for (const win of Services.wm.getEnumerator(gDevTools.chromeWindowType)) {
   if (win.gBrowserInit && win.gBrowserInit.delayedStartupFinished) {
     gDevToolsBrowser._registerBrowserWindow(win);
   }
 }
--- a/devtools/client/framework/test/browser_toolbox_dynamic_registration.js
+++ b/devtools/client/framework/test/browser_toolbox_dynamic_registration.js
@@ -45,22 +45,17 @@ function toolRegistered(toolId) {
     ok(menuitem, "menu item of new tool added to every browser window");
   }
 
   // then unregister it
   testUnregister();
 }
 
 function getAllBrowserWindows() {
-  const wins = [];
-  const enumerator = Services.wm.getEnumerator("navigator:browser");
-  while (enumerator.hasMoreElements()) {
-    wins.push(enumerator.getNext());
-  }
-  return wins;
+  return Array.from(Services.wm.getEnumerator("navigator:browser"));
 }
 
 function testUnregister() {
   gDevTools.once("tool-unregistered", toolUnregistered);
 
   gDevTools.unregisterTool("testTool");
 }
 
--- a/devtools/client/framework/test/browser_toolbox_tools_per_toolbox_registration.js
+++ b/devtools/client/framework/test/browser_toolbox_tools_per_toolbox_registration.js
@@ -92,22 +92,17 @@ function testToolRegistered() {
   // Test that the tool is built once selected and then test its unregistering.
   info("select per-toolbox tool in the opened toolbox.");
   gDevTools.showToolbox(target, TOOL_ID)
            .then(waitForToolInstanceBuild)
            .then(testUnregister);
 }
 
 function getAllBrowserWindows() {
-  const wins = [];
-  const enumerator = Services.wm.getEnumerator("navigator:browser");
-  while (enumerator.hasMoreElements()) {
-    wins.push(enumerator.getNext());
-  }
-  return wins;
+  return Array.from(Services.wm.getEnumerator("navigator:browser"));
 }
 
 function testUnregister() {
   info("remove per-toolbox tool in the opened toolbox.");
   toolbox.removeAdditionalTool(TOOL_ID);
 
   Promise.all([
     waitForToolInstanceDestroyed
--- a/devtools/client/scratchpad/scratchpad-manager.jsm
+++ b/devtools/client/scratchpad/scratchpad-manager.jsm
@@ -82,19 +82,17 @@ this.ScratchpadManager = {
     }
 
     // We need to clone objects we get from Scratchpad instances
     // because such (cross-window) objects have a property 'parent'
     // that holds on to a ChromeWindow instance. This means that
     // such objects are not primitive-values-only anymore so they
     // can leak.
 
-    const enumerator = Services.wm.getEnumerator("devtools:scratchpad");
-    while (enumerator.hasMoreElements()) {
-      const win = enumerator.getNext();
+    for (const win of Services.wm.getEnumerator("devtools:scratchpad")) {
       if (!win.closed && win.Scratchpad.initialized) {
         this._scratchpads.push(clone(win.Scratchpad.getState()));
       }
     }
   },
 
   /**
    * Open a new scratchpad window with an optional initial state.
--- a/devtools/client/shared/view-source.js
+++ b/devtools/client/shared/view-source.js
@@ -127,21 +127,17 @@ exports.viewSourceInDebugger = async fun
  *
  * @param {string} sourceURL
  * @param {number} sourceLine
  *
  * @return {Promise}
  */
 exports.viewSourceInScratchpad = async function(sourceURL, sourceLine) {
   // Check for matching top level scratchpad window.
-  const wins = Services.wm.getEnumerator("devtools:scratchpad");
-
-  while (wins.hasMoreElements()) {
-    const win = wins.getNext();
-
+  for (const win of Services.wm.getEnumerator("devtools:scratchpad")) {
     if (!win.closed && win.Scratchpad.uniqueName === sourceURL) {
       win.focus();
       win.Scratchpad.editor.setCursor({ line: sourceLine, ch: 0 });
       return;
     }
   }
 
   // For scratchpads within toolbox
--- a/devtools/server/actors/accessibility.js
+++ b/devtools/server/actors/accessibility.js
@@ -20,17 +20,16 @@ const {
 const { isXUL } = require("devtools/server/actors/highlighters/utils/markup");
 const { isWindowIncluded } = require("devtools/shared/layout/utils");
 const { CustomHighlighterActor, register } =
   require("devtools/server/actors/highlighters");
 const PREF_ACCESSIBILITY_FORCE_DISABLED = "accessibility.force_disabled";
 
 const nsIAccessibleEvent = Ci.nsIAccessibleEvent;
 const nsIAccessibleStateChangeEvent = Ci.nsIAccessibleStateChangeEvent;
-const nsIPropertyElement = Ci.nsIPropertyElement;
 const nsIAccessibleRole = Ci.nsIAccessibleRole;
 
 const {
   EVENT_TEXT_CHANGED,
   EVENT_TEXT_INSERTED,
   EVENT_TEXT_REMOVED,
   EVENT_ACCELERATOR_CHANGE,
   EVENT_ACTION_CHANGE,
@@ -317,20 +316,17 @@ const AccessibleActor = ActorClassWithSp
   },
 
   get attributes() {
     if (this.isDefunct || !this.rawAccessible.attributes) {
       return {};
     }
 
     const attributes = {};
-    const attrsEnum = this.rawAccessible.attributes.enumerate();
-    while (attrsEnum.hasMoreElements()) {
-      const { key, value } = attrsEnum.getNext().QueryInterface(
-        nsIPropertyElement);
+    for (const { key, value } of this.rawAccessible.attributes.enumerate()) {
       attributes[key] = value;
     }
 
     return attributes;
   },
 
   get bounds() {
     if (this.isDefunct) {
--- a/devtools/server/actors/inspector/walker.js
+++ b/devtools/server/actors/inspector/walker.js
@@ -181,19 +181,17 @@ var WalkerActor = protocol.ActorClassWit
   },
 
   /**
    * Callback for eventListenerService.addListenerChangeListener
    * @param nsISimpleEnumerator changesEnum
    *    enumerator of nsIEventListenerChange
    */
   _onEventListenerChange: function(changesEnum) {
-    const changes = changesEnum.enumerate();
-    while (changes.hasMoreElements()) {
-      const current = changes.getNext().QueryInterface(Ci.nsIEventListenerChange);
+    for (const current of changesEnum.enumerate(Ci.nsIEventListenerChange)) {
       const target = current.target;
 
       if (this._refMap.has(target)) {
         const actor = this.getNode(target);
         const mutation = {
           type: "events",
           target: actor.actorID,
           hasEventListeners: actor._hasEventListeners
--- a/devtools/server/actors/replay/graphics.js
+++ b/devtools/server/actors/replay/graphics.js
@@ -46,19 +46,17 @@ function updateWindow(window, buffer, wi
 }
 
 // Entry point for when we have some new graphics data from the child process
 // to draw.
 // eslint-disable-next-line no-unused-vars
 function Update(buffer, width, height) {
   try {
     // Paint to all windows we can find. Hopefully there is only one.
-    const windowEnumerator = Services.ww.getWindowEnumerator();
-    while (windowEnumerator.hasMoreElements()) {
-      const window = windowEnumerator.getNext().QueryInterface(Ci.nsIDOMWindow);
+    for (const window of Services.ww.getWindowEnumerator()) {
       updateWindow(window, buffer, width, height);
     }
   } catch (e) {
     dump("Middleman Graphics Update Exception: " + e + "\n");
   }
 }
 
 // eslint-disable-next-line no-unused-vars
--- a/devtools/server/actors/storage.js
+++ b/devtools/server/actors/storage.js
@@ -805,26 +805,18 @@ var cookieHelpers = {
   getCookiesFromHost(host, originAttributes) {
     // Local files have no host.
     if (host.startsWith("file:///")) {
       host = "";
     }
 
     host = trimHttpHttpsPort(host);
 
-    const cookies = Services.cookies.getCookiesFromHost(host, originAttributes);
-    const store = [];
-
-    while (cookies.hasMoreElements()) {
-      const cookie = cookies.getNext().QueryInterface(Ci.nsICookie2);
-
-      store.push(cookie);
-    }
-
-    return store;
+    return Array.from(
+      Services.cookies.getCookiesFromHost(host, originAttributes));
   },
 
   /**
    * Apply the results of a cookie edit.
    *
    * @param {Object} data
    *        An object in the following format:
    *        {
@@ -849,21 +841,19 @@ var cookieHelpers = {
    */
   editCookie(data) {
     let {field, oldValue, newValue} = data;
     const origName = field === "name" ? oldValue : data.items.name;
     const origHost = field === "host" ? oldValue : data.items.host;
     const origPath = field === "path" ? oldValue : data.items.path;
     let cookie = null;
 
-    const enumerator =
-      Services.cookies.getCookiesFromHost(origHost, data.originAttributes || {});
-
-    while (enumerator.hasMoreElements()) {
-      const nsiCookie = enumerator.getNext().QueryInterface(Ci.nsICookie2);
+    const cookies = Services.cookies.getCookiesFromHost(origHost,
+                                                        data.originAttributes || {});
+    for (const nsiCookie of cookies) {
       if (nsiCookie.name === origName &&
           nsiCookie.host === origHost &&
           nsiCookie.path === origPath) {
         cookie = {
           host: nsiCookie.host,
           path: nsiCookie.path,
           name: nsiCookie.name,
           value: nsiCookie.value,
@@ -951,21 +941,19 @@ var cookieHelpers = {
         return matchHost == null;
       }
       if (cookieHost.startsWith(".")) {
         return ("." + matchHost).endsWith(cookieHost);
       }
       return cookieHost == host;
     }
 
-    const enumerator =
-      Services.cookies.getCookiesFromHost(host, opts.originAttributes || {});
-
-    while (enumerator.hasMoreElements()) {
-      const cookie = enumerator.getNext().QueryInterface(Ci.nsICookie2);
+    const cookies = Services.cookies.getCookiesFromHost(host,
+                                                        opts.originAttributes || {});
+    for (const cookie of cookies) {
       if (hostMatches(cookie.host, host) &&
           (!opts.name || cookie.name === opts.name) &&
           (!opts.domain || cookie.host === opts.domain) &&
           (!opts.path || cookie.path === opts.path) &&
           (!opts.session || (!cookie.expires && !cookie.maxAge))) {
         Services.cookies.remove(
           cookie.host,
           cookie.name,
--- a/devtools/server/actors/targets/addon.js
+++ b/devtools/server/actors/targets/addon.js
@@ -180,30 +180,24 @@ AddonTargetActor.prototype = {
     return this._addon.reload()
       .then(() => {
         // send an empty response
         return {};
       });
   },
 
   preNest: function() {
-    const e = Services.wm.getEnumerator(null);
-    while (e.hasMoreElements()) {
-      const win = e.getNext();
-      const windowUtils = win.windowUtils;
+    for (const {windowUtils} of Services.wm.getEnumerator(null)) {
       windowUtils.suppressEventHandling(true);
       windowUtils.suspendTimeouts();
     }
   },
 
   postNest: function() {
-    const e = Services.wm.getEnumerator(null);
-    while (e.hasMoreElements()) {
-      const win = e.getNext();
-      const windowUtils = win.windowUtils;
+    for (const {windowUtils} of Services.wm.getEnumerator(null)) {
       windowUtils.resumeTimeouts();
       windowUtils.suppressEventHandling(false);
     }
   },
 
   /**
    * Return true if the given global is associated with this addon and should be
    * added as a debuggee, false otherwise.
--- a/devtools/server/actors/targets/browsing-context.js
+++ b/devtools/server/actors/targets/browsing-context.js
@@ -72,19 +72,17 @@ function getDocShellChromeEventHandler(d
 
 function getChildDocShells(parentDocShell) {
   const docShellsEnum = parentDocShell.getDocShellEnumerator(
     Ci.nsIDocShellTreeItem.typeAll,
     Ci.nsIDocShell.ENUMERATE_FORWARDS
   );
 
   const docShells = [];
-  while (docShellsEnum.hasMoreElements()) {
-    const docShell = docShellsEnum.getNext();
-    docShell.QueryInterface(Ci.nsIDocShell);
+  for (const docShell of docShellsEnum) {
     docShell.QueryInterface(Ci.nsIInterfaceRequestor)
             .getInterface(Ci.nsIWebProgress);
     docShells.push(docShell);
   }
   return docShells;
 }
 
 exports.getChildDocShells = getChildDocShells;
--- a/devtools/server/actors/targets/content-process.js
+++ b/devtools/server/actors/targets/content-process.js
@@ -33,24 +33,18 @@ function ContentProcessTargetActor(conne
   // Use a see-everything debugger
   this.makeDebugger = makeDebugger.bind(null, {
     findDebuggees: dbg => dbg.findAllGlobals(),
     shouldAddNewGlobalAsDebuggee: global => true
   });
 
   const sandboxPrototype = {
     get tabs() {
-      const tabs = [];
-      const windowEnumerator = Services.ww.getWindowEnumerator();
-      while (windowEnumerator.hasMoreElements()) {
-        const window = windowEnumerator.getNext().QueryInterface(Ci.nsIDOMWindow);
-        const tabChildGlobal = window.docShell.messageManager;
-        tabs.push(tabChildGlobal);
-      }
-      return tabs;
+      return Array.from(Services.ww.getWindowEnumerator(),
+                        win => win.docShell.messageManager);
     },
   };
 
   // Scope into which the webconsole executes:
   // A sandbox with chrome privileges with a `tabs` getter.
   const systemPrincipal = Cc["@mozilla.org/systemprincipal;1"]
     .createInstance(Ci.nsIPrincipal);
   const sandbox = Cu.Sandbox(systemPrincipal, {
--- a/devtools/server/actors/targets/parent-process.js
+++ b/devtools/server/actors/targets/parent-process.js
@@ -88,20 +88,17 @@ parentProcessTargetPrototype.isRootActor
 /**
  * Getter for the list of all docshells in this targetActor
  * @return {Array}
  */
 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.docShell;
+    for (const {docShell} of Services.ww.getWindowEnumerator()) {
       docShells = docShells.concat(getChildDocShells(docShell));
     }
 
     return docShells;
   }
 });
 
 parentProcessTargetPrototype.observe = function(subject, topic, data) {
@@ -126,20 +123,17 @@ parentProcessTargetPrototype._attach = f
 
   BrowsingContextTargetActor.prototype._attach.call(this);
 
   // 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.docShell;
+  for (const {docShell} of Services.ww.getWindowEnumerator()) {
     if (docShell == this.docShell) {
       continue;
     }
     this._progressListener.watch(docShell);
   }
   return undefined;
 };
 
@@ -147,20 +141,17 @@ parentProcessTargetPrototype._detach = f
   if (!this.attached) {
     return false;
   }
 
   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.docShell;
+  for (const {docShell} of Services.ww.getWindowEnumerator()) {
     if (docShell == this.docShell) {
       continue;
     }
     this._progressListener.unwatch(docShell);
   }
 
   BrowsingContextTargetActor.prototype._detach.call(this);
   return undefined;
@@ -168,34 +159,28 @@ parentProcessTargetPrototype._detach = f
 
 /* ThreadActor hooks. */
 
 /**
  * Prepare to enter a nested event loop by disabling debuggee events.
  */
 parentProcessTargetPrototype.preNest = function() {
   // Disable events in all open windows.
-  const e = Services.wm.getEnumerator(null);
-  while (e.hasMoreElements()) {
-    const win = e.getNext();
-    const windowUtils = win.windowUtils;
+  for (const {windowUtils} of Services.wm.getEnumerator(null)) {
     windowUtils.suppressEventHandling(true);
     windowUtils.suspendTimeouts();
   }
 };
 
 /**
  * Prepare to exit a nested event loop by enabling debuggee events.
  */
 parentProcessTargetPrototype.postNest = function(nestData) {
   // Enable events in all open windows.
-  const e = Services.wm.getEnumerator(null);
-  while (e.hasMoreElements()) {
-    const win = e.getNext();
-    const windowUtils = win.windowUtils;
+  for (const {windowUtils} of Services.wm.getEnumerator(null)) {
     windowUtils.resumeTimeouts();
     windowUtils.suppressEventHandling(false);
   }
 };
 
 exports.parentProcessTargetPrototype = parentProcessTargetPrototype;
 exports.ParentProcessTargetActor =
   ActorClassWithSpec(parentProcessTargetSpec, parentProcessTargetPrototype);
--- a/devtools/server/actors/targets/webextension.js
+++ b/devtools/server/actors/targets/webextension.js
@@ -183,20 +183,17 @@ webExtensionTargetPrototype._destroyFall
   }
 };
 
 // Discovery an extension page to use as a default target window.
 // NOTE: This currently fail to discovery an extension page running in a
 // windowless browser when running in non-oop mode, and the background page
 // is set later using _onNewExtensionWindow.
 webExtensionTargetPrototype._searchForExtensionWindow = function() {
-  const e = Services.ww.getWindowEnumerator(null);
-  while (e.hasMoreElements()) {
-    const window = e.getNext();
-
+  for (const window of Services.ww.getWindowEnumerator(null)) {
     if (window.document.nodePrincipal.addonId == this.id) {
       return window;
     }
   }
 
   return undefined;
 };
 
--- a/devtools/server/actors/webbrowser.js
+++ b/devtools/server/actors/webbrowser.js
@@ -20,42 +20,28 @@ loader.lazyRequireGetter(this, "ServiceW
 loader.lazyRequireGetter(this, "ProcessActorList", "devtools/server/actors/process", true);
 loader.lazyImporter(this, "AddonManager", "resource://gre/modules/AddonManager.jsm");
 
 /**
  * Browser-specific actors.
  */
 
 /**
- * Yield all windows of type |windowType|, from the oldest window to the
- * youngest, using nsIWindowMediator::getEnumerator. We're usually
- * interested in "navigator:browser" windows.
- */
-function* allAppShellDOMWindows(windowType) {
-  const e = Services.wm.getEnumerator(windowType);
-  while (e.hasMoreElements()) {
-    yield e.getNext();
-  }
-}
-
-exports.allAppShellDOMWindows = allAppShellDOMWindows;
-
-/**
  * Retrieve the window type of the top-level window |window|.
  */
 function appShellDOMWindowType(window) {
   /* This is what nsIWindowMediator's enumerator checks. */
   return window.document.documentElement.getAttribute("windowtype");
 }
 
 /**
  * Send Debugger:Shutdown events to all "navigator:browser" windows.
  */
 function sendShutdownEvent() {
-  for (const win of allAppShellDOMWindows(DebuggerServer.chromeWindowType)) {
+  for (const win of Services.wm.getEnumerator(DebuggerServer.chromeWindowType)) {
     const evt = win.document.createEvent("Event");
     evt.initEvent("Debugger:Shutdown", true, false);
     win.document.documentElement.dispatchEvent(evt);
   }
 }
 
 exports.sendShutdownEvent = sendShutdownEvent;
 
@@ -223,17 +209,17 @@ BrowserTabList.prototype._getSelectedBro
 };
 
 /**
  * Produces an iterable (in this case a generator) to enumerate all available
  * browser tabs.
  */
 BrowserTabList.prototype._getBrowsers = function* () {
   // Iterate over all navigator:browser XUL windows.
-  for (const win of allAppShellDOMWindows(DebuggerServer.chromeWindowType)) {
+  for (const win of Services.wm.getEnumerator(DebuggerServer.chromeWindowType)) {
     // For each tab in this XUL window, ensure that we have an actor for
     // it, reusing existing actors where possible.
     for (const browser of this._getChildren(win)) {
       yield browser;
     }
   }
 };
 
@@ -483,17 +469,17 @@ BrowserTabList.prototype._checkListening
  *    already listening for those events.
  * @param eventNames array of strings
  *    An array of event names.
  */
 BrowserTabList.prototype._listenForEventsIf =
   function(shouldListen, guard, eventNames) {
     if (!shouldListen !== !this[guard]) {
       const op = shouldListen ? "addEventListener" : "removeEventListener";
-      for (const win of allAppShellDOMWindows(DebuggerServer.chromeWindowType)) {
+      for (const win of Services.wm.getEnumerator(DebuggerServer.chromeWindowType)) {
         for (const name of eventNames) {
           win[op](name, this, false);
         }
       }
       this[guard] = shouldListen;
     }
   };
 
@@ -507,17 +493,17 @@ BrowserTabList.prototype._listenForEvent
  *    already listening for those messages.
  * @param aMessageNames array of strings
  *    An array of message names.
  */
 BrowserTabList.prototype._listenForMessagesIf =
   function(shouldListen, guard, messageNames) {
     if (!shouldListen !== !this[guard]) {
       const op = shouldListen ? "addMessageListener" : "removeMessageListener";
-      for (const win of allAppShellDOMWindows(DebuggerServer.chromeWindowType)) {
+      for (const win of Services.wm.getEnumerator(DebuggerServer.chromeWindowType)) {
         for (const name of messageNames) {
           win.messageManager[op](name, this);
         }
       }
       this[guard] = shouldListen;
     }
   };
 
--- a/devtools/server/actors/worker/worker-list.js
+++ b/devtools/server/actors/worker/worker-list.js
@@ -48,19 +48,17 @@ function WorkerTargetActorList(conn, opt
   this.onRegister = this.onRegister.bind(this);
   this.onUnregister = this.onUnregister.bind(this);
 }
 
 WorkerTargetActorList.prototype = {
   getList() {
     // Create a set of debuggers.
     const dbgs = new Set();
-    const e = wdm.getWorkerDebuggerEnumerator();
-    while (e.hasMoreElements()) {
-      const dbg = e.getNext().QueryInterface(Ci.nsIWorkerDebugger);
+    for (const dbg of wdm.getWorkerDebuggerEnumerator()) {
       if (matchWorkerDebugger(dbg, this._options)) {
         dbgs.add(dbg);
       }
     }
 
     // Delete each actor for which we don't have a debugger.
     for (const [dbg, ] of this._actors) {
       if (!dbgs.has(dbg)) {
--- a/devtools/server/performance/timeline.js
+++ b/devtools/server/performance/timeline.js
@@ -70,39 +70,33 @@ Timeline.prototype = {
    * the targetActor was switched to a child frame. This is because for now,
    * paint markers are only recorded at parent frame level so switching the
    * timeline to a child frame would hide all paint markers.
    * See https://bugzilla.mozilla.org/show_bug.cgi?id=1050773#c14
    * @return {Array}
    */
   get docShells() {
     let originalDocShell;
-    const docShells = [];
 
     if (this.targetActor.isRootActor) {
       originalDocShell = this.targetActor.docShell;
     } else {
       originalDocShell = this.targetActor.originalDocShell;
     }
 
     if (!originalDocShell) {
-      return docShells;
+      return [];
     }
 
     const docShellsEnum = originalDocShell.getDocShellEnumerator(
       Ci.nsIDocShellTreeItem.typeAll,
       Ci.nsIDocShell.ENUMERATE_FORWARDS
     );
 
-    while (docShellsEnum.hasMoreElements()) {
-      const docShell = docShellsEnum.getNext();
-      docShells.push(docShell.QueryInterface(Ci.nsIDocShell));
-    }
-
-    return docShells;
+    return Array.from(docShellsEnum);
   },
 
   /**
    * At regular intervals, pop the markers from the docshell, and forward
    * markers, memory, tick and frames events, if any.
    */
   _pullTimelineData: function() {
     const docShells = this.docShells;
--- a/devtools/shared/system.js
+++ b/devtools/shared/system.js
@@ -170,19 +170,17 @@ async function getSystemInfo() {
 }
 
 function getProfileLocation() {
   // In child processes, we cannot access the profile location.
   try {
     const profd = Services.dirsvc.get("ProfD", Ci.nsIFile);
     const profservice = Cc["@mozilla.org/toolkit/profile-service;1"]
                         .getService(Ci.nsIToolkitProfileService);
-    const profiles = profservice.profiles;
-    while (profiles.hasMoreElements()) {
-      const profile = profiles.getNext().QueryInterface(Ci.nsIToolkitProfile);
+    for (const profile of profservice.profiles) {
       if (profile.rootDir.path == profd.path) {
         return profile.name;
       }
     }
 
     return profd.leafName;
   } catch (e) {
     return "";
--- a/devtools/startup/devtools-startup.js
+++ b/devtools/startup/devtools-startup.js
@@ -495,19 +495,17 @@ DevToolsStartup.prototype = {
     item.hidden = Services.prefs.getBoolPref(DEVTOOLS_ENABLED_PREF);
   },
 
   /**
    * Loop on all windows and update the hidden attribute of the "enable DevTools" menu
    * item.
    */
   onEnabledPrefChanged() {
-    const enumerator = Services.wm.getEnumerator("navigator:browser");
-    while (enumerator.hasMoreElements()) {
-      const window = enumerator.getNext();
+    for (const window of Services.wm.getEnumerator("navigator:browser")) {
       if (window.gBrowserInit && window.gBrowserInit.delayedStartupFinished) {
         this.updateDevToolsMenuItems(window);
       }
     }
   },
 
   /**
    * Check if the user is a DevTools user by looking at our selfxss pref.