mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-21 01:05:45 +00:00
Backed out 4 changesets (bug 1519335) for causing a spike in bug 1641788, per whimboo's request CLOSED TREE
Backed out changeset 80a0c09b0211 (bug 1519335) Backed out changeset 315a7ffd643b (bug 1519335) Backed out changeset 7c82cbd6f034 (bug 1519335) Backed out changeset f84fa4157d90 (bug 1519335)
This commit is contained in:
parent
49600f0317
commit
6b3e9fd483
@ -287,25 +287,6 @@ assert.callable = function(obj, msg = "") {
|
||||
return assert.that(o => typeof o == "function", msg)(obj);
|
||||
};
|
||||
|
||||
/**
|
||||
* Asserts that <var>obj</var> is an unsigned short number.
|
||||
*
|
||||
* @param {?} obj
|
||||
* Value to test.
|
||||
* @param {string=} msg
|
||||
* Custom error message.
|
||||
*
|
||||
* @return {number}
|
||||
* <var>obj</var> is returned unaltered.
|
||||
*
|
||||
* @throws {InvalidArgumentError}
|
||||
* If <var>obj</var> is not an unsigned short.
|
||||
*/
|
||||
assert.unsignedShort = function(obj, msg = "") {
|
||||
msg = msg || pprint`Expected ${obj} to be >= 0 and < 65536`;
|
||||
return assert.that(n => n >= 0 && n < 65536, msg)(obj);
|
||||
};
|
||||
|
||||
/**
|
||||
* Asserts that <var>obj</var> is an integer.
|
||||
*
|
||||
|
@ -567,17 +567,17 @@ browser.Context = class {
|
||||
};
|
||||
|
||||
/**
|
||||
* The window storage is used to save browsing context ids mapped to weak
|
||||
* 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.browsingContext.id, window);
|
||||
* wins.set(browser.outerWindowID, window);
|
||||
*
|
||||
* ...
|
||||
*
|
||||
* let win = wins.get(browser.browsingContext.id);
|
||||
* let win = wins.get(browser.outerWindowID);
|
||||
*
|
||||
*/
|
||||
browser.Windows = class extends Map {
|
||||
@ -585,7 +585,7 @@ browser.Windows = class extends Map {
|
||||
* Save a weak reference to the Window object.
|
||||
*
|
||||
* @param {string} id
|
||||
* Browsing context id.
|
||||
* Outer window ID.
|
||||
* @param {Window} win
|
||||
* Window object to save.
|
||||
*
|
||||
@ -602,7 +602,7 @@ browser.Windows = class extends Map {
|
||||
* Get the window object stored by provided |id|.
|
||||
*
|
||||
* @param {string} id
|
||||
* Browsing context id.
|
||||
* Outer window ID.
|
||||
*
|
||||
* @return {Window}
|
||||
* Saved window object.
|
||||
|
@ -288,7 +288,7 @@ Object.defineProperty(GeckoDriver.prototype, "chromeWindowHandles", {
|
||||
let hs = [];
|
||||
|
||||
for (let win of this.windows) {
|
||||
hs.push(getWindowId(win));
|
||||
hs.push(getOuterWindowId(win));
|
||||
}
|
||||
|
||||
return hs;
|
||||
@ -474,16 +474,16 @@ GeckoDriver.prototype.addFrameCloseListener = function(action) {
|
||||
* @return {string}
|
||||
* Returns the unique server-assigned ID of the window.
|
||||
*/
|
||||
GeckoDriver.prototype.addBrowser = function(win) {
|
||||
let context = new browser.Context(win, this);
|
||||
let winId = getWindowId(win);
|
||||
GeckoDriver.prototype.addBrowser = function(window) {
|
||||
let bc = new browser.Context(window, this);
|
||||
let winId = getOuterWindowId(window);
|
||||
|
||||
this.browsers[winId] = context;
|
||||
this.browsers[winId] = bc;
|
||||
this.curBrowser = this.browsers[winId];
|
||||
if (!this.wins.has(winId)) {
|
||||
// add this to seenItems so we can guarantee
|
||||
// the user will get winId as this window's id
|
||||
this.wins.set(winId, win);
|
||||
this.wins.set(winId, window);
|
||||
}
|
||||
};
|
||||
|
||||
@ -579,6 +579,8 @@ GeckoDriver.prototype.getVisibleText = function(el, lines) {
|
||||
* their type they are either accepted or ignored.
|
||||
*/
|
||||
GeckoDriver.prototype.registerBrowser = function(id, be) {
|
||||
let listenerWindow = Services.wm.getOuterWindowWithId(id);
|
||||
|
||||
// We want to ignore frames that are XUL browsers that aren't in the "main"
|
||||
// tabbrowser, but accept things on Fennec (which doesn't have a
|
||||
// xul:tabbrowser), and accept HTML iframes (because tests depend on it),
|
||||
@ -594,9 +596,7 @@ GeckoDriver.prototype.registerBrowser = function(id, be) {
|
||||
this.curBrowser.register(id, be);
|
||||
}
|
||||
|
||||
const context = BrowsingContext.get(id);
|
||||
this.wins.set(id, context.currentWindowGlobal);
|
||||
|
||||
this.wins.set(id, listenerWindow);
|
||||
return id;
|
||||
};
|
||||
|
||||
@ -605,8 +605,8 @@ GeckoDriver.prototype.registerPromise = function() {
|
||||
|
||||
return new Promise(resolve => {
|
||||
let cb = ({ json, target }) => {
|
||||
let { frameId } = json;
|
||||
this.registerBrowser(frameId, target);
|
||||
let { outerWindowID } = json;
|
||||
this.registerBrowser(outerWindowID, target);
|
||||
|
||||
if (this.curBrowser.frameRegsPending > 0) {
|
||||
this.curBrowser.frameRegsPending--;
|
||||
@ -617,7 +617,7 @@ GeckoDriver.prototype.registerPromise = function() {
|
||||
resolve();
|
||||
}
|
||||
|
||||
return { frameId };
|
||||
return { outerWindowID };
|
||||
};
|
||||
this.mm.addMessageListener(li, cb);
|
||||
});
|
||||
@ -628,7 +628,7 @@ GeckoDriver.prototype.listeningPromise = function() {
|
||||
|
||||
return new Promise(resolve => {
|
||||
let cb = msg => {
|
||||
if (msg.json.frameId === this.curBrowser.curFrameId) {
|
||||
if (msg.json.outerWindowID === this.curBrowser.curFrameId) {
|
||||
this.mm.removeMessageListener(li, cb);
|
||||
resolve();
|
||||
}
|
||||
@ -1390,7 +1390,7 @@ GeckoDriver.prototype.getIdForBrowser = function(browser) {
|
||||
return this._browserIds.get(permKey);
|
||||
}
|
||||
|
||||
let winId = browser.browsingContext.id;
|
||||
let winId = browser.outerWindowID;
|
||||
if (winId) {
|
||||
this._browserIds.set(permKey, winId);
|
||||
return winId;
|
||||
@ -1618,13 +1618,13 @@ GeckoDriver.prototype.switchToWindow = async function(cmd) {
|
||||
* associated metadata.
|
||||
*/
|
||||
GeckoDriver.prototype.findWindow = function(winIterable, filter) {
|
||||
for (const win of winIterable) {
|
||||
const bc = win.docShell.browsingContext;
|
||||
const tabBrowser = browser.getTabBrowser(win);
|
||||
for (let win of winIterable) {
|
||||
let outerId = getOuterWindowId(win);
|
||||
let tabBrowser = browser.getTabBrowser(win);
|
||||
|
||||
// In case the wanted window is a chrome window, we are done.
|
||||
if (filter(win, bc.id)) {
|
||||
return { win, id: bc.id, hasTabBrowser: !!tabBrowser };
|
||||
if (filter(win, outerId)) {
|
||||
return { win, outerId, hasTabBrowser: !!tabBrowser };
|
||||
|
||||
// Otherwise check if the chrome window has a tab browser, and that it
|
||||
// contains a tab with the wanted window handle.
|
||||
@ -1636,7 +1636,7 @@ GeckoDriver.prototype.findWindow = function(winIterable, filter) {
|
||||
if (filter(win, contentWindowId)) {
|
||||
return {
|
||||
win,
|
||||
id: bc.id,
|
||||
outerId,
|
||||
hasTabBrowser: true,
|
||||
tabIndex: i,
|
||||
};
|
||||
@ -1665,7 +1665,7 @@ GeckoDriver.prototype.setWindowHandle = async function(
|
||||
winProperties,
|
||||
focus = true
|
||||
) {
|
||||
if (!(winProperties.id in this.browsers)) {
|
||||
if (!(winProperties.outerId in this.browsers)) {
|
||||
// Initialise Marionette if the current chrome window has not been seen
|
||||
// before. Also register the initial tab, if one exists.
|
||||
let registerBrowsers, browserListening;
|
||||
@ -1683,7 +1683,7 @@ GeckoDriver.prototype.setWindowHandle = async function(
|
||||
}
|
||||
} else {
|
||||
// Otherwise switch to the known chrome window
|
||||
this.curBrowser = this.browsers[winProperties.id];
|
||||
this.curBrowser = this.browsers[winProperties.outerId];
|
||||
this.mainFrame = this.curBrowser.window;
|
||||
this.curFrame = null;
|
||||
|
||||
@ -1758,10 +1758,6 @@ GeckoDriver.prototype.switchToFrame = async function(cmd) {
|
||||
|
||||
let { id, focus } = cmd.parameters;
|
||||
|
||||
if (typeof id == "number") {
|
||||
assert.unsignedShort(id, `Expected id to be unsigned short, got ${id}`);
|
||||
}
|
||||
|
||||
// TODO(ato): element can be either string (deprecated) or a web
|
||||
// element JSON Object. Can be removed with Firefox 60.
|
||||
let byFrame;
|
||||
@ -3572,12 +3568,12 @@ GeckoDriver.prototype.receiveMessage = function(message) {
|
||||
break;
|
||||
|
||||
case "Marionette:Register":
|
||||
let { frameId } = message.json;
|
||||
this.registerBrowser(frameId, message.target);
|
||||
return { frameId };
|
||||
let { outerWindowID } = message.json;
|
||||
this.registerBrowser(outerWindowID, message.target);
|
||||
return { outerWindowID };
|
||||
|
||||
case "Marionette:ListenersAttached":
|
||||
if (message.json.frameId === this.curBrowser.curFrameId) {
|
||||
if (message.json.outerWindowID === this.curBrowser.curFrameId) {
|
||||
this.curBrowser.flushPendingCommands();
|
||||
}
|
||||
break;
|
||||
@ -3899,8 +3895,8 @@ GeckoDriver.prototype.commands = {
|
||||
"WebDriver:TakeScreenshot": GeckoDriver.prototype.takeScreenshot,
|
||||
};
|
||||
|
||||
function getWindowId(win) {
|
||||
return win.docShell.browsingContext.id;
|
||||
function getOuterWindowId(win) {
|
||||
return win.windowUtils.outerWindowID;
|
||||
}
|
||||
|
||||
async function exitFullscreen(win) {
|
||||
|
@ -92,7 +92,7 @@ class WindowManagerMixin(object):
|
||||
return self.marionette.execute_script("""
|
||||
Components.utils.import("resource://gre/modules/Services.jsm");
|
||||
|
||||
const win = BrowsingContext.get(Number(arguments[0])).window;
|
||||
let win = Services.wm.getOuterWindowWithId(Number(arguments[0]));
|
||||
return win.document.readyState == "complete";
|
||||
""", script_args=[handle])
|
||||
|
||||
@ -174,7 +174,7 @@ class WindowManagerMixin(object):
|
||||
await focused;
|
||||
}
|
||||
|
||||
resolve(win.docShell.browsingContext.id);
|
||||
resolve(win.windowUtils.outerWindowID);
|
||||
})();
|
||||
""", script_args=(url, focus))
|
||||
|
||||
|
@ -6,7 +6,6 @@ from __future__ import absolute_import
|
||||
|
||||
from marionette_driver.by import By
|
||||
from marionette_driver.errors import (
|
||||
InvalidArgumentException,
|
||||
JavascriptException,
|
||||
NoSuchFrameException,
|
||||
)
|
||||
@ -123,13 +122,11 @@ class TestSwitchFrame(MarionetteTestCase):
|
||||
def test_switch_to_frame_with_out_of_bounds_index(self):
|
||||
self.marionette.navigate(self.marionette.absolute_url("test_iframe.html"))
|
||||
count = self.marionette.execute_script("return window.frames.length;")
|
||||
for index in [count, 65535]:
|
||||
self.assertRaises(NoSuchFrameException, self.marionette.switch_to_frame, index)
|
||||
self.assertRaises(NoSuchFrameException, self.marionette.switch_to_frame, count)
|
||||
|
||||
def test_switch_to_frame_with_invalid_index(self):
|
||||
def test_switch_to_frame_with_negative_index(self):
|
||||
self.marionette.navigate(self.marionette.absolute_url("test_iframe.html"))
|
||||
for index in [-1, 65536]:
|
||||
self.assertRaises(InvalidArgumentException, self.marionette.switch_to_frame, index)
|
||||
self.assertRaises(NoSuchFrameException, self.marionette.switch_to_frame, -1)
|
||||
|
||||
def test_switch_to_parent_frame(self):
|
||||
frame_html = self.marionette.absolute_url("frameset.html")
|
||||
|
@ -58,26 +58,13 @@ const { navigate } = ChromeUtils.import(
|
||||
);
|
||||
const { proxy } = ChromeUtils.import("chrome://marionette/content/proxy.js");
|
||||
|
||||
XPCOMUtils.defineLazyGetter(this, "logger", () => Log.getWithPrefix(contentId));
|
||||
XPCOMUtils.defineLazyGetter(this, "logger", () =>
|
||||
Log.getWithPrefix(outerWindowID)
|
||||
);
|
||||
XPCOMUtils.defineLazyGlobalGetters(this, ["URL"]);
|
||||
|
||||
const contentId = content.docShell.browsingContext.id;
|
||||
|
||||
const curContainer = {
|
||||
_frame: null,
|
||||
shadowRoot: null,
|
||||
|
||||
get frame() {
|
||||
return this._frame;
|
||||
},
|
||||
|
||||
set frame(frame) {
|
||||
this._frame = frame;
|
||||
|
||||
this.id = this._frame.docShell.browsingContext.id;
|
||||
this.shadowRoot = null;
|
||||
},
|
||||
};
|
||||
let { outerWindowID } = winUtil;
|
||||
let curContainer = { frame: content, shadowRoot: null };
|
||||
|
||||
// Listen for click event to indicate one click has happened, so actions
|
||||
// code can send dblclick event
|
||||
@ -386,16 +373,17 @@ const loadListener = {
|
||||
},
|
||||
|
||||
observe(subject, topic) {
|
||||
logger.trace(`Received observer notification ${topic}`);
|
||||
const win = curContainer.frame;
|
||||
const winID = subject.QueryInterface(Ci.nsISupportsPRUint64).data;
|
||||
const curWinID = win.windowUtils.outerWindowID;
|
||||
|
||||
const winId = subject.QueryInterface(Ci.nsISupportsPRUint64).data;
|
||||
const bc = BrowsingContext.get(curContainer.id);
|
||||
logger.trace(`Received observer notification ${topic}`);
|
||||
|
||||
switch (topic) {
|
||||
// In the case when the currently selected frame is closed,
|
||||
// there will be no further load events. Stop listening immediately.
|
||||
case "outer-window-destroyed":
|
||||
if (bc.window.windowUtils.outerWindowID == winId) {
|
||||
if (curWinID === winID) {
|
||||
this.stop();
|
||||
sendOk(this.commandID);
|
||||
}
|
||||
@ -493,27 +481,25 @@ const loadListener = {
|
||||
function registerSelf() {
|
||||
logger.trace("Frame script loaded");
|
||||
|
||||
curContainer.frame = content;
|
||||
|
||||
sandboxes.clear();
|
||||
curContainer = {
|
||||
frame: content,
|
||||
shadowRoot: null,
|
||||
};
|
||||
legacyactions.mouseEventsOnly = false;
|
||||
action.inputStateMap = new Map();
|
||||
action.inputsToCancel = [];
|
||||
|
||||
let reply = sendSyncMessage("Marionette:Register", {
|
||||
frameId: contentId,
|
||||
});
|
||||
let reply = sendSyncMessage("Marionette:Register", { outerWindowID });
|
||||
if (reply.length == 0) {
|
||||
logger.error("No reply from Marionette:Register");
|
||||
return;
|
||||
}
|
||||
|
||||
if (reply[0].frameId === contentId) {
|
||||
if (reply[0].outerWindowID === outerWindowID) {
|
||||
logger.trace("Frame script registered");
|
||||
startListeners();
|
||||
sendAsyncMessage("Marionette:ListenersAttached", {
|
||||
frameId: contentId,
|
||||
});
|
||||
sendAsyncMessage("Marionette:ListenersAttached", { outerWindowID });
|
||||
}
|
||||
}
|
||||
|
||||
@ -680,11 +666,9 @@ function deregister() {
|
||||
|
||||
function deleteSession() {
|
||||
seenEls.clear();
|
||||
|
||||
// reset container frame to the top-most frame
|
||||
curContainer.frame = content;
|
||||
curContainer = { frame: content, shadowRoot: null };
|
||||
curContainer.frame.focus();
|
||||
|
||||
legacyactions.touchIds = {};
|
||||
if (action.inputStateMap !== undefined) {
|
||||
action.inputStateMap.clear();
|
||||
@ -765,7 +749,8 @@ function emitTouchEvent(type, touch) {
|
||||
);
|
||||
|
||||
const win = curContainer.frame;
|
||||
if (win.docShell.asyncPanZoomEnabled && legacyactions.scrolling) {
|
||||
let docShell = win.docShell;
|
||||
if (docShell.asyncPanZoomEnabled && legacyactions.scrolling) {
|
||||
let ev = {
|
||||
index: 0,
|
||||
type,
|
||||
@ -1530,9 +1515,7 @@ function switchToParentFrame(msg) {
|
||||
*/
|
||||
function switchToFrame(msg) {
|
||||
let commandID = msg.json.commandID;
|
||||
|
||||
let foundFrame;
|
||||
let frameWebEl;
|
||||
let foundFrame = null;
|
||||
|
||||
// check if curContainer.frame reference is dead
|
||||
let frames = [];
|
||||
@ -1552,7 +1535,6 @@ function switchToFrame(msg) {
|
||||
sendSyncMessage("Marionette:switchedToFrame", { frameValue: null });
|
||||
|
||||
curContainer.frame = content;
|
||||
|
||||
if (msg.json.focus) {
|
||||
curContainer.frame.focus();
|
||||
}
|
||||
@ -1588,12 +1570,13 @@ function switchToFrame(msg) {
|
||||
let wrappedItem = new XPCNativeWrapper(frameEl);
|
||||
let wrappedWanted = new XPCNativeWrapper(wantedFrame);
|
||||
if (wrappedItem == wrappedWanted) {
|
||||
foundFrame = frameEl;
|
||||
curContainer.frame = frameEl;
|
||||
foundFrame = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!foundFrame) {
|
||||
if (foundFrame === null) {
|
||||
// Either the frame has been removed or we have a OOP frame
|
||||
// so lets just get all the iframes and do a quick loop before
|
||||
// throwing in the towel
|
||||
@ -1604,19 +1587,20 @@ function switchToFrame(msg) {
|
||||
let wrappedEl = new XPCNativeWrapper(frameEl);
|
||||
let wrappedWanted = new XPCNativeWrapper(wantedFrame);
|
||||
if (wrappedEl == wrappedWanted) {
|
||||
foundFrame = iframes[i];
|
||||
curContainer.frame = iframes[i];
|
||||
foundFrame = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!foundFrame) {
|
||||
if (foundFrame === null) {
|
||||
if (typeof msg.json.id === "number") {
|
||||
try {
|
||||
if (msg.json.id >= 0 && msg.json.id < frames.length) {
|
||||
foundFrame = frames[msg.json.id].frameElement;
|
||||
if (foundFrame !== null) {
|
||||
frameWebEl = seenEls.add(foundFrame.wrappedJSObject);
|
||||
curContainer.frame = foundFrame;
|
||||
foundFrame = seenEls.add(curContainer.frame);
|
||||
} else {
|
||||
// If foundFrame is null at this point then we have the top
|
||||
// level browsing context so should treat it accordingly.
|
||||
@ -1630,21 +1614,21 @@ function switchToFrame(msg) {
|
||||
sendOk(commandID);
|
||||
return;
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
// Since window.frames does not return OOP frames it will throw
|
||||
// and we land up here. Let's not give up and check if there are
|
||||
// iframes and switch to the indexed frame there
|
||||
let doc = foundFrame.document;
|
||||
let doc = curContainer.frame.document;
|
||||
let iframes = doc.getElementsByTagName("iframe");
|
||||
if (msg.json.id >= 0 && msg.json.id < iframes.length) {
|
||||
foundFrame = iframes[msg.json.id];
|
||||
curContainer.frame = iframes[msg.json.id];
|
||||
foundFrame = msg.json.id;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!foundFrame) {
|
||||
if (foundFrame === null) {
|
||||
let failedFrame = msg.json.id || msg.json.element;
|
||||
let err = new NoSuchFrameError(`Unable to locate frame: ${failedFrame}`);
|
||||
sendError(err, commandID);
|
||||
@ -1653,14 +1637,12 @@ function switchToFrame(msg) {
|
||||
|
||||
// send a synchronous message to let the server update the currently active
|
||||
// frame element (for getActiveFrame)
|
||||
if (!frameWebEl) {
|
||||
frameWebEl = seenEls.add(foundFrame.wrappedJSObject);
|
||||
}
|
||||
let frameWebEl = seenEls.add(curContainer.frame.wrappedJSObject);
|
||||
sendSyncMessage("Marionette:switchedToFrame", {
|
||||
frameValue: frameWebEl.uuid,
|
||||
});
|
||||
|
||||
curContainer.frame = foundFrame.contentWindow;
|
||||
curContainer.frame = curContainer.frame.contentWindow;
|
||||
if (msg.json.focus) {
|
||||
curContainer.frame.focus();
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user