Bug 1274638 - Store weak refs to windows outside of element store; r?automatedtester draft
authorAndreas Tolfsen <ato@mozilla.com>
Mon, 23 May 2016 10:21:15 +0100
changeset 369794 47e593b35c9b40e2aa17bc171e953eb049911dd5
parent 369317 16663eb3dcfa759f25b5e27b101bc79270c156f2
child 521608 7625d637cdc614da54b644a278db9582e19ad117
push id18905
push userbmo:ato@mozilla.com
push dateMon, 23 May 2016 14:43:25 +0000
reviewersautomatedtester
bugs1274638
milestone49.0a1
Bug 1274638 - Store weak refs to windows outside of element store; r?automatedtester Windows do not naturally belong in the seen element store, and it is not naturally related to the scope as that of a browser. MozReview-Commit-ID: JbQh5kDLDw
testing/marionette/browser.js
testing/marionette/driver.js
--- a/testing/marionette/browser.js
+++ b/testing/marionette/browser.js
@@ -254,8 +254,60 @@ browser.Context = class {
     if (this.hasRemotenessChange()) {
       this.pendingCommands.push(cb);
     } else {
       cb();
     }
   }
 
 };
+
+/**
+ * The window storage is used to save outer window IDs mapped to weak
+ * references of Window objects.
+ *
+ * Usage:
+ *
+ *     let wins = new browser.Windows();
+ *     wins.set(browser.outerWindowID, window);
+ *
+ *     ...
+ *
+ *     let win = wins.get(browser.outerWindowID);
+ *
+ */
+browser.Windows = class extends Map {
+
+  /**
+   * Save a weak reference to the Window object.
+   *
+   * @param {string} id
+   *     Outer window ID.
+   * @param {Window} win
+   *     Window object to save.
+   *
+   * @return {browser.Windows}
+   *     Instance of self.
+   */
+  set(id, win) {
+    let wref = Cu.getWeakReference(win);
+    super.set(id, wref);
+    return this;
+  }
+
+  /**
+   * Get the window object stored by provided |id|.
+   *
+   * @param {string} id
+   *     Outer window ID.
+   *
+   * @return {Window}
+   *     Saved window object, or |undefined| if no window is stored by
+   *     provided |id|.
+   */
+  get(id) {
+    let wref = super.get(id);
+    if (wref) {
+      return wref.get();
+    }
+  }
+
+};
--- a/testing/marionette/driver.js
+++ b/testing/marionette/driver.js
@@ -93,17 +93,17 @@ this.Context.fromString = function(s) {
 this.GeckoDriver = function(appName, device, stopSignal, emulator) {
   this.appName = appName;
   this.stopSignal_ = stopSignal;
   this.emulator = emulator;
   // TODO(ato): hack
   this.emulator.sendToListener = this.sendAsync.bind(this);
 
   this.sessionId = null;
-  // holds list of browser.Context's
+  this.wins = new browser.Windows();
   this.browsers = {};
   // points to current browser
   this.curBrowser = null;
   this.context = Context.CONTENT;
   this.scriptTimeout = null;
   this.searchTimeout = null;
   this.pageTimeout = null;
   this.timer = null;
@@ -282,20 +282,20 @@ GeckoDriver.prototype.addFrameCloseListe
  */
 GeckoDriver.prototype.addBrowser = function(win) {
   let bc = new browser.Context(win, this);
   let winId = win.QueryInterface(Ci.nsIInterfaceRequestor)
       .getInterface(Ci.nsIDOMWindowUtils).outerWindowID;
   winId = winId + ((this.appName == "B2G") ? "-b2g" : "");
   this.browsers[winId] = bc;
   this.curBrowser = this.browsers[winId];
-  if (typeof this.curBrowser.elementManager.seenItems[winId] == "undefined") {
+  if (!this.wins.has(winId)) {
     // add this to seenItems so we can guarantee
     // the user will get winId as this window's id
-    this.curBrowser.elementManager.seenItems[winId] = Cu.getWeakReference(win);
+    this.wins.set(winId, win);
   }
 };
 
 /**
  * Registers a new browser, win, with Marionette.
  *
  * If we have not seen the browser content window before, the listener
  * frame script will be loaded into it.  If isNewSession is true, we will
@@ -411,18 +411,17 @@ GeckoDriver.prototype.registerBrowser = 
   }
 
   // set to true if we updated mainContentId
   mainContent = mainContent && this.curBrowser.mainContentId !== null;
   if (mainContent) {
     this.mainContentFrameId = this.curBrowser.curFrameId;
   }
 
-  this.curBrowser.elementManager.seenItems[reg.id] =
-      Cu.getWeakReference(listenerWindow);
+  this.wins.set(reg.id, listenerWindow);
   if (nullPrevious && (this.curBrowser.curFrameId !== null)) {
     this.sendAsync("newSession", this.sessionCapabilities, this.newSessionCommandId);
     if (this.curBrowser.isNewSession) {
       this.newSessionCommandId = null;
     }
   }
 
   return [reg, mainContent, this.sessionCapabilities];