Bug 1274638 - Store weak refs to windows outside of element store; r=automatedtester a=test-only
authorAndreas Tolfsen <ato@mozilla.com>
Mon, 23 May 2016 10:21:15 +0100
changeset 333249 314e202438dedcf2a65cdbc9e7b3a91e57e28f25
parent 333248 2f2941ed16da8f86e849c7e53b4f715d3e389917
child 333250 06e08681af3a0b0e17ac59ee3df0bf4a4abeb23f
push id6048
push userkmoir@mozilla.com
push dateMon, 06 Jun 2016 19:02:08 +0000
treeherdermozilla-beta@46d72a56c57d [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersautomatedtester, test-only
bugs1274638
milestone48.0a2
Bug 1274638 - Store weak refs to windows outside of element store; r=automatedtester a=test-only 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];