Bug 1363428 - Use an iterator for iterating windows, r=ato draft
authorJames Graham <james@hoppipolla.co.uk>
Tue, 09 May 2017 17:49:09 +0100
changeset 600208 5d4eb99c56ec840b17ddde6fcd95c2daaddd927a
parent 600207 dd220667cbf6dd9e2701306502161dc1058c4bd1
child 600209 a12822b629b373cb3e4f505f697beaed31f08254
push id65688
push userbmo:james@hoppipolla.co.uk
push dateSat, 24 Jun 2017 11:04:46 +0000
reviewersato
bugs1363428
milestone56.0a1
Bug 1363428 - Use an iterator for iterating windows, r=ato MozReview-Commit-ID: FKsw9EST2H7
testing/marionette/driver.js
--- a/testing/marionette/driver.js
+++ b/testing/marionette/driver.js
@@ -77,16 +77,28 @@ this.Context.fromString = function (s) {
   s = s.toUpperCase();
   if (s in this) {
     return this[s];
   }
   return null;
 };
 
 /**
+* Helper function for converting an nsISimpleEnumerator to
+* a javascript iterator
+* @param{nsISimpleEnumerator} enumerator
+*    enumerator to convert
+*/
+function* enumeratorIterator (enumerator) {
+  while (enumerator.hasMoreElements()) {
+    yield enumerator.getNext();
+  }
+}
+
+/**
  * Implements (parts of) the W3C WebDriver protocol.  GeckoDriver lives
  * in chrome space and mediates calls to the message listener of the current
  * browsing context's content frame message listener via ListenerProxy.
  *
  * Throughout this prototype, functions with the argument {@code cmd}'s
  * documentation refers to the contents of the {@code cmd.parameters}
  * object.
  *
@@ -180,23 +192,27 @@ Object.defineProperty(GeckoDriver.protot
     return this.capabilities.get("timeouts");
   },
 
   set: function (newTimeouts) {
     this.capabilities.set("timeouts", newTimeouts);
   },
 });
 
+Object.defineProperty(GeckoDriver.prototype, "windows", {
+  get: function () {
+    return enumeratorIterator(Services.wm.getEnumerator(null));
+  }
+});
+
 Object.defineProperty(GeckoDriver.prototype, "windowHandles", {
   get: function () {
     let hs = [];
-    let winEn = Services.wm.getEnumerator(null);
-
-    while (winEn.hasMoreElements()) {
-      let win = winEn.getNext();
+
+    for (let win of this.windows) {
       let tabBrowser = browser.getTabBrowser(win);
 
       // Only return handles for browser windows
       if (tabBrowser) {
         tabBrowser.tabs.forEach(tab => {
           let winId = this.getIdForBrowser(browser.getBrowserForTab(tab));
           if (winId !== null) {
             hs.push(winId);
@@ -207,20 +223,19 @@ Object.defineProperty(GeckoDriver.protot
 
     return hs;
   },
 });
 
 Object.defineProperty(GeckoDriver.prototype, "chromeWindowHandles", {
   get: function () {
     let hs = [];
-    let winEn = Services.wm.getEnumerator(null);
-
-    while (winEn.hasMoreElements()) {
-      hs.push(getOuterWindowId(winEn.getNext()));
+
+    for (let win of this.windows) {
+      hs.push(getOuterWindowId(win));
     }
 
     return hs;
   },
 });
 
 GeckoDriver.prototype.QueryInterface = XPCOMUtils.generateQI([
   Ci.nsIMessageListener,
@@ -2483,19 +2498,18 @@ GeckoDriver.prototype.deleteCookie = fun
  *     A modal dialog is open, blocking this operation.
  */
 GeckoDriver.prototype.close = function (cmd, resp) {
   assert.contentBrowser(this.curBrowser);
   assert.noUserPrompt(this.dialog);
 
   let nwins = 0;
 
-  let winEn = Services.wm.getEnumerator(null);
-  while (winEn.hasMoreElements()) {
-    let win = winEn.getNext();
+  for (let win of this.windows) {
+    // For browser windows count the tabs. Otherwise take the window itself.
     let tabbrowser = browser.getTabBrowser(win);
 
     if (tabbrowser) {
       nwins += tabbrowser.tabs.length;
     }
   }
 
   // If there is only 1 window left, do not close it. Instead return a faked
@@ -2523,20 +2537,18 @@ GeckoDriver.prototype.close = function (
  *     Unique chrome window handles of remaining chrome windows.
  */
 GeckoDriver.prototype.closeChromeWindow = function (cmd, resp) {
   assert.firefox();
   assert.window(this.getCurrentWindow(Context.CHROME));
 
   let nwins = 0;
 
-  let winEn = Services.wm.getEnumerator(null);
-  while (winEn.hasMoreElements()) {
+  for (let _ of this.windows) {
     nwins++;
-    winEn.getNext();
   }
 
   // If there is only 1 window left, do not close it. Instead return a faked
   // empty array of window handles. This will instruct geckodriver to terminate
   // the application.
   if (nwins == 1) {
     return [];
   }
@@ -2561,19 +2573,17 @@ GeckoDriver.prototype.deleteSession = fu
     for (let win in this.browsers) {
       let browser = this.browsers[win];
       for (let i in browser.knownFrames) {
         globalMessageManager.broadcastAsyncMessage(
             "Marionette:deleteSession" + browser.knownFrames[i], {});
       }
     }
 
-    let winEn = Services.wm.getEnumerator(null);
-    while (winEn.hasMoreElements()) {
-      let win = winEn.getNext();
+    for (let win of this.windows) {
       if (win.messageManager) {
         win.messageManager.removeDelayedFrameScript(FRAME_SCRIPT);
       } else {
         logger.error(
             `Could not remove listener from page ${win.location.href}`);
       }
     }