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
--- 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];