mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-16 23:05:42 +00:00
Bug 1747222 - [remote] Move browsing context APIs from browser.js and WindowManager to TabManager r=webdriver-reviewers,whimboo
Depends on D135414 Differential Revision: https://phabricator.services.mozilla.com/D135415
This commit is contained in:
parent
7d8052e4a0
commit
892ae10673
@ -15,6 +15,7 @@ remote.jar:
|
||||
# shared modules (all protocols)
|
||||
content/shared/Format.jsm (shared/Format.jsm)
|
||||
content/shared/Log.jsm (shared/Log.jsm)
|
||||
content/shared/MobileTabBrowser.jsm (shared/MobileTabBrowser.jsm)
|
||||
content/shared/Navigate.jsm (shared/Navigate.jsm)
|
||||
content/shared/RecommendedPreferences.jsm (shared/RecommendedPreferences.jsm)
|
||||
content/shared/Stack.jsm (shared/Stack.jsm)
|
||||
|
@ -14,6 +14,7 @@ XPCOMUtils.defineLazyModuleGetters(this, {
|
||||
AppInfo: "chrome://remote/content/marionette/appinfo.js",
|
||||
error: "chrome://remote/content/shared/webdriver/Errors.jsm",
|
||||
MessageManagerDestroyedPromise: "chrome://remote/content/marionette/sync.js",
|
||||
TabManager: "chrome://remote/content/shared/TabManager.jsm",
|
||||
waitForEvent: "chrome://remote/content/marionette/sync.js",
|
||||
WebElementEventTarget: "chrome://remote/content/marionette/dom.js",
|
||||
windowManager: "chrome://remote/content/shared/WindowManager.jsm",
|
||||
@ -61,91 +62,6 @@ Context.Chrome = "chrome";
|
||||
Context.Content = "content";
|
||||
this.Context = Context;
|
||||
|
||||
// GeckoView shim for Desktop's gBrowser
|
||||
class MobileTabBrowser {
|
||||
constructor(window) {
|
||||
this.window = window;
|
||||
}
|
||||
|
||||
get tabs() {
|
||||
return [this.window.tab];
|
||||
}
|
||||
|
||||
get selectedTab() {
|
||||
return this.window.tab;
|
||||
}
|
||||
|
||||
set selectedTab(tab) {
|
||||
if (tab != this.selectedTab) {
|
||||
throw new Error("GeckoView only supports a single tab");
|
||||
}
|
||||
|
||||
// Synthesize a custom TabSelect event to indicate that a tab has been
|
||||
// selected even when we don't change it.
|
||||
const event = this.window.CustomEvent("TabSelect", {
|
||||
bubbles: true,
|
||||
cancelable: false,
|
||||
detail: {
|
||||
previousTab: this.selectedTab,
|
||||
},
|
||||
});
|
||||
this.window.document.dispatchEvent(event);
|
||||
}
|
||||
|
||||
get selectedBrowser() {
|
||||
return this.selectedTab.linkedBrowser;
|
||||
}
|
||||
|
||||
addEventListener() {
|
||||
this.window.addEventListener(...arguments);
|
||||
}
|
||||
|
||||
removeEventListener() {
|
||||
this.window.removeEventListener(...arguments);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the <code><xul:browser></code> for the specified tab.
|
||||
*
|
||||
* @param {Tab} tab
|
||||
* The tab whose browser needs to be returned.
|
||||
*
|
||||
* @return {Browser}
|
||||
* The linked browser for the tab or null if no browser can be found.
|
||||
*/
|
||||
browser.getBrowserForTab = function(tab) {
|
||||
if (tab && "linkedBrowser" in tab) {
|
||||
return tab.linkedBrowser;
|
||||
}
|
||||
|
||||
return null;
|
||||
};
|
||||
|
||||
/**
|
||||
* Return the tab browser for the specified chrome window.
|
||||
*
|
||||
* @param {ChromeWindow} win
|
||||
* Window whose <code>tabbrowser</code> needs to be accessed.
|
||||
*
|
||||
* @return {Tab}
|
||||
* Tab browser or null if it's not a browser window.
|
||||
*/
|
||||
browser.getTabBrowser = function(window) {
|
||||
// GeckoView
|
||||
if (AppInfo.isAndroid) {
|
||||
return new MobileTabBrowser(window);
|
||||
// Firefox
|
||||
} else if ("gBrowser" in window) {
|
||||
return window.gBrowser;
|
||||
// Thunderbird
|
||||
} else if (window.document.getElementById("tabmail")) {
|
||||
return window.document.getElementById("tabmail");
|
||||
}
|
||||
|
||||
return null;
|
||||
};
|
||||
|
||||
/**
|
||||
* Creates a browsing context wrapper.
|
||||
*
|
||||
@ -165,7 +81,7 @@ browser.Context = class {
|
||||
|
||||
// In Firefox this is <xul:tabbrowser> (not <xul:browser>!)
|
||||
// and MobileTabBrowser in GeckoView.
|
||||
this.tabBrowser = browser.getTabBrowser(this.window);
|
||||
this.tabBrowser = TabManager.getTabBrowser(this.window);
|
||||
|
||||
// Used to set curFrameId upon new session
|
||||
this.newSession = true;
|
||||
@ -186,7 +102,7 @@ browser.Context = class {
|
||||
*/
|
||||
get contentBrowser() {
|
||||
if (this.tab) {
|
||||
return browser.getBrowserForTab(this.tab);
|
||||
return TabManager.getBrowserForTab(this.tab);
|
||||
} else if (
|
||||
this.tabBrowser &&
|
||||
this.driver.isReftestBrowser(this.tabBrowser)
|
||||
@ -374,7 +290,7 @@ browser.Context = class {
|
||||
|
||||
if (window) {
|
||||
this.window = window;
|
||||
this.tabBrowser = browser.getTabBrowser(this.window);
|
||||
this.tabBrowser = TabManager.getTabBrowser(this.window);
|
||||
}
|
||||
|
||||
if (!this.tabBrowser) {
|
||||
|
@ -48,6 +48,7 @@ XPCOMUtils.defineLazyModuleGetters(this, {
|
||||
registerCommandsActor:
|
||||
"chrome://remote/content/marionette/actors/MarionetteCommandsParent.jsm",
|
||||
RemoteAgent: "chrome://remote/content/components/RemoteAgent.jsm",
|
||||
TabManager: "chrome://remote/content/shared/TabManager.jsm",
|
||||
TimedPromise: "chrome://remote/content/marionette/sync.js",
|
||||
Timeouts: "chrome://remote/content/shared/webdriver/Capabilities.jsm",
|
||||
UnhandledPromptBehavior:
|
||||
@ -442,11 +443,11 @@ GeckoDriver.prototype.newSession = async function(cmd) {
|
||||
this.dialogObserver.add(this.handleModalDialog.bind(this));
|
||||
|
||||
for (let win of windowManager.windows) {
|
||||
const tabBrowser = browser.getTabBrowser(win);
|
||||
const tabBrowser = TabManager.getTabBrowser(win);
|
||||
|
||||
if (tabBrowser) {
|
||||
for (const tab of tabBrowser.tabs) {
|
||||
const contentBrowser = browser.getBrowserForTab(tab);
|
||||
const contentBrowser = TabManager.getBrowserForTab(tab);
|
||||
this.registerBrowser(contentBrowser);
|
||||
}
|
||||
}
|
||||
@ -489,7 +490,7 @@ GeckoDriver.prototype.newSession = async function(cmd) {
|
||||
* Chrome window to register event listeners for.
|
||||
*/
|
||||
GeckoDriver.prototype.registerListenersForWindow = function(win) {
|
||||
const tabBrowser = browser.getTabBrowser(win);
|
||||
const tabBrowser = TabManager.getTabBrowser(win);
|
||||
|
||||
// Listen for any kind of top-level process switch
|
||||
tabBrowser?.addEventListener("XULFrameLoaderCreated", this);
|
||||
@ -502,7 +503,7 @@ GeckoDriver.prototype.registerListenersForWindow = function(win) {
|
||||
* Chrome window to unregister event listeners for.
|
||||
*/
|
||||
GeckoDriver.prototype.unregisterListenersForWindow = function(win) {
|
||||
const tabBrowser = browser.getTabBrowser(win);
|
||||
const tabBrowser = TabManager.getTabBrowser(win);
|
||||
|
||||
tabBrowser?.removeEventListener("XULFrameLoaderCreated", this);
|
||||
};
|
||||
@ -984,7 +985,7 @@ GeckoDriver.prototype.getWindowHandle = function() {
|
||||
if (this.context == Context.Chrome) {
|
||||
return windowManager.getIdForWindow(this.curBrowser.window);
|
||||
}
|
||||
return windowManager.getIdForBrowser(this.curBrowser.contentBrowser);
|
||||
return TabManager.getIdForBrowser(this.curBrowser.contentBrowser);
|
||||
};
|
||||
|
||||
/**
|
||||
@ -1005,7 +1006,7 @@ GeckoDriver.prototype.getWindowHandles = function() {
|
||||
if (this.context == Context.Chrome) {
|
||||
return windowManager.chromeWindowHandles.map(String);
|
||||
}
|
||||
return windowManager.windowHandles.map(String);
|
||||
return TabManager.allBrowserUniqueIds.map(String);
|
||||
};
|
||||
|
||||
/**
|
||||
@ -1171,7 +1172,7 @@ GeckoDriver.prototype.setWindowHandle = async function(
|
||||
if (!winProperties.hasTabBrowser) {
|
||||
this.currentSession.contentBrowsingContext = null;
|
||||
} else {
|
||||
const tabBrowser = browser.getTabBrowser(winProperties.win);
|
||||
const tabBrowser = TabManager.getTabBrowser(winProperties.win);
|
||||
|
||||
// For chrome windows such as a reftest window, `getTabBrowser` is not
|
||||
// a tabbrowser, it is the content browser which should be used here.
|
||||
@ -2010,21 +2011,21 @@ GeckoDriver.prototype.newWindow = async function(cmd) {
|
||||
switch (type) {
|
||||
case "window":
|
||||
let win = await this.curBrowser.openBrowserWindow(focus, isPrivate);
|
||||
contentBrowser = browser.getTabBrowser(win).selectedBrowser;
|
||||
contentBrowser = TabManager.getTabBrowser(win).selectedBrowser;
|
||||
break;
|
||||
|
||||
default:
|
||||
// To not fail if a new type gets added in the future, make opening
|
||||
// a new tab the default action.
|
||||
let tab = await this.curBrowser.openTab(focus);
|
||||
contentBrowser = browser.getBrowserForTab(tab);
|
||||
contentBrowser = TabManager.getBrowserForTab(tab);
|
||||
}
|
||||
|
||||
// Actors need the new window to be loaded to safely execute queries.
|
||||
// Wait until the initial page load has been finished.
|
||||
await waitForInitialNavigationCompleted(contentBrowser.browsingContext);
|
||||
|
||||
const id = windowManager.getIdForBrowser(contentBrowser);
|
||||
const id = TabManager.getIdForBrowser(contentBrowser);
|
||||
|
||||
return { handle: id.toString(), type };
|
||||
};
|
||||
@ -2050,29 +2051,17 @@ GeckoDriver.prototype.close = async function() {
|
||||
assert.open(this.getBrowsingContext({ context: Context.Content, top: true }));
|
||||
await this._handleUserPrompts();
|
||||
|
||||
let nwins = 0;
|
||||
|
||||
for (let win of windowManager.windows) {
|
||||
// For browser windows count the tabs. Otherwise take the window itself.
|
||||
let tabbrowser = browser.getTabBrowser(win);
|
||||
if (tabbrowser && tabbrowser.tabs) {
|
||||
nwins += tabbrowser.tabs.length;
|
||||
} else {
|
||||
nwins += 1;
|
||||
}
|
||||
}
|
||||
|
||||
// If there is only one 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) {
|
||||
if (TabManager.getTabCount() === 1) {
|
||||
return [];
|
||||
}
|
||||
|
||||
await this.curBrowser.closeTab();
|
||||
this.currentSession.contentBrowsingContext = null;
|
||||
|
||||
return windowManager.windowHandles.map(String);
|
||||
return TabManager.allBrowserUniqueIds.map(String);
|
||||
};
|
||||
|
||||
/**
|
||||
|
51
remote/shared/MobileTabBrowser.jsm
Normal file
51
remote/shared/MobileTabBrowser.jsm
Normal file
@ -0,0 +1,51 @@
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
"use strict";
|
||||
|
||||
var EXPORTED_SYMBOLS = ["MobileTabBrowser"];
|
||||
|
||||
// GeckoView shim for Desktop's gBrowser
|
||||
class MobileTabBrowser {
|
||||
constructor(window) {
|
||||
this.window = window;
|
||||
}
|
||||
|
||||
get tabs() {
|
||||
return [this.window.tab];
|
||||
}
|
||||
|
||||
get selectedTab() {
|
||||
return this.window.tab;
|
||||
}
|
||||
|
||||
set selectedTab(tab) {
|
||||
if (tab != this.selectedTab) {
|
||||
throw new Error("GeckoView only supports a single tab");
|
||||
}
|
||||
|
||||
// Synthesize a custom TabSelect event to indicate that a tab has been
|
||||
// selected even when we don't change it.
|
||||
const event = this.window.CustomEvent("TabSelect", {
|
||||
bubbles: true,
|
||||
cancelable: false,
|
||||
detail: {
|
||||
previousTab: this.selectedTab,
|
||||
},
|
||||
});
|
||||
this.window.document.dispatchEvent(event);
|
||||
}
|
||||
|
||||
get selectedBrowser() {
|
||||
return this.selectedTab.linkedBrowser;
|
||||
}
|
||||
|
||||
addEventListener() {
|
||||
this.window.addEventListener(...arguments);
|
||||
}
|
||||
|
||||
removeEventListener() {
|
||||
this.window.removeEventListener(...arguments);
|
||||
}
|
||||
}
|
@ -12,12 +12,94 @@ var { XPCOMUtils } = ChromeUtils.import(
|
||||
|
||||
XPCOMUtils.defineLazyModuleGetters(this, {
|
||||
Services: "resource://gre/modules/Services.jsm",
|
||||
|
||||
MobileTabBrowser: "chrome://remote/content/shared/MobileTabBrowser.jsm",
|
||||
});
|
||||
|
||||
// Maps browser's permanentKey to uuid: WeakMap.<Object, string>
|
||||
const browserUniqueIds = new WeakMap();
|
||||
|
||||
var TabManager = {
|
||||
get gBrowser() {
|
||||
const window = Services.wm.getMostRecentWindow("navigator:browser");
|
||||
return window.gBrowser;
|
||||
return this.getTabBrowser(window);
|
||||
},
|
||||
|
||||
get windows() {
|
||||
return Services.wm.getEnumerator(null);
|
||||
},
|
||||
|
||||
/**
|
||||
* Array of unique browser ids (UUIDs) for all content browsers of all
|
||||
* windows.
|
||||
*
|
||||
* TODO: Similarly to getBrowserById, we should improve the performance of
|
||||
* this getter in Bug 1750065.
|
||||
*
|
||||
* @return {Array<String>}
|
||||
* Array of UUIDs for all content browsers.
|
||||
*/
|
||||
get allBrowserUniqueIds() {
|
||||
const browserIds = [];
|
||||
|
||||
for (const win of this.windows) {
|
||||
const tabBrowser = this.getTabBrowser(win);
|
||||
|
||||
// Only return handles for browser windows
|
||||
if (tabBrowser && tabBrowser.tabs) {
|
||||
for (const tab of tabBrowser.tabs) {
|
||||
const contentBrowser = this.getBrowserForTab(tab);
|
||||
const winId = this.getIdForBrowser(contentBrowser);
|
||||
if (winId !== null) {
|
||||
browserIds.push(winId);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return browserIds;
|
||||
},
|
||||
|
||||
/**
|
||||
* Get the <code><xul:browser></code> for the specified tab.
|
||||
*
|
||||
* @param {Tab} tab
|
||||
* The tab whose browser needs to be returned.
|
||||
*
|
||||
* @return {xul:browser}
|
||||
* The linked browser for the tab or null if no browser can be found.
|
||||
*/
|
||||
getBrowserForTab(tab) {
|
||||
if (tab && "linkedBrowser" in tab) {
|
||||
return tab.linkedBrowser;
|
||||
}
|
||||
|
||||
return null;
|
||||
},
|
||||
|
||||
/**
|
||||
* Return the tab browser for the specified chrome window.
|
||||
*
|
||||
* @param {ChromeWindow} win
|
||||
* Window whose <code>tabbrowser</code> needs to be accessed.
|
||||
*
|
||||
* @return {Tab}
|
||||
* Tab browser or null if it's not a browser window.
|
||||
*/
|
||||
getTabBrowser(win) {
|
||||
// GeckoView
|
||||
// TODO: Migrate to AppInfo.isAndroid after AppInfo moves to shared/
|
||||
if (Services.appinfo.OS === "Android") {
|
||||
return new MobileTabBrowser(win);
|
||||
// Firefox
|
||||
} else if ("gBrowser" in win) {
|
||||
return win.gBrowser;
|
||||
// Thunderbird
|
||||
} else if (win.document.getElementById("tabmail")) {
|
||||
return win.document.getElementById("tabmail");
|
||||
}
|
||||
|
||||
return null;
|
||||
},
|
||||
|
||||
addTab({ userContextId }) {
|
||||
@ -30,6 +112,84 @@ var TabManager = {
|
||||
return tab;
|
||||
},
|
||||
|
||||
/**
|
||||
* Retrieve a the browser element corresponding to the provided unique id,
|
||||
* previously generated via getIdForBrowser.
|
||||
*
|
||||
* TODO: To avoid creating strong references on browser elements and
|
||||
* potentially leaking those elements, this method loops over all windows and
|
||||
* all tabs. It should be replaced by a faster implementation in Bug 1750065.
|
||||
*
|
||||
* @param {String} id
|
||||
* A browser unique id created by getIdForBrowser.
|
||||
* @return {xul:browser}
|
||||
* The <xul:browser> corresponding to the provided id. Will return null if
|
||||
* no matching browser element is found.
|
||||
*/
|
||||
getBrowserById(id) {
|
||||
for (const win of this.windows) {
|
||||
const tabBrowser = this.getTabBrowser(win);
|
||||
if (tabBrowser && tabBrowser.tabs) {
|
||||
for (let i = 0; i < tabBrowser.tabs.length; ++i) {
|
||||
const contentBrowser = this.getBrowserForTab(tabBrowser.tabs[i]);
|
||||
if (this.getIdForBrowser(contentBrowser) == id) {
|
||||
return contentBrowser;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
},
|
||||
|
||||
/**
|
||||
* Retrieve the unique id for the given xul browser element. The id is a
|
||||
* dynamically generated uuid associated with the permanentKey property of the
|
||||
* given browser element.
|
||||
*
|
||||
* @param {xul:browser} browserElement
|
||||
* The <xul:browser> for which we want to retrieve the id.
|
||||
* @return {String} The unique id for this browser.
|
||||
*/
|
||||
getIdForBrowser(browserElement) {
|
||||
if (browserElement === null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const key = browserElement.permanentKey;
|
||||
if (!browserUniqueIds.has(key)) {
|
||||
const uuid = Services.uuid.generateUUID().toString();
|
||||
browserUniqueIds.set(key, uuid.substring(1, uuid.length - 1));
|
||||
}
|
||||
return browserUniqueIds.get(key);
|
||||
},
|
||||
|
||||
/**
|
||||
* Retrieve the unique id for the browser element owning the provided browsing
|
||||
* context.
|
||||
*
|
||||
* @param {BrowsingContext} browsingContext
|
||||
* The browsing context for which we want to retrieve the (browser) uuid.
|
||||
* @return {String} The unique id for the browser owning the browsing context.
|
||||
*/
|
||||
getBrowserIdForBrowsingContext(browsingContext) {
|
||||
const contentBrowser = browsingContext.top.embedderElement;
|
||||
return this.getIdForBrowser(contentBrowser);
|
||||
},
|
||||
|
||||
getTabCount() {
|
||||
let count = 0;
|
||||
for (const win of this.windows) {
|
||||
// For browser windows count the tabs. Otherwise take the window itself.
|
||||
const tabbrowser = this.getTabBrowser(win);
|
||||
if (tabbrowser?.tabs) {
|
||||
count += tabbrowser.tabs.length;
|
||||
} else {
|
||||
count += 1;
|
||||
}
|
||||
}
|
||||
return count;
|
||||
},
|
||||
|
||||
removeTab(tab) {
|
||||
this.gBrowser.removeTab(tab);
|
||||
},
|
||||
|
@ -14,8 +14,8 @@ XPCOMUtils.defineLazyModuleGetters(this, {
|
||||
Services: "resource://gre/modules/Services.jsm",
|
||||
|
||||
AppInfo: "chrome://remote/content/marionette/appinfo.js",
|
||||
browser: "chrome://remote/content/marionette/browser.js",
|
||||
error: "chrome://remote/content/shared/webdriver/Errors.jsm",
|
||||
TabManager: "chrome://remote/content/shared/TabManager.jsm",
|
||||
TimedPromise: "chrome://remote/content/marionette/sync.js",
|
||||
waitForEvent: "chrome://remote/content/marionette/sync.js",
|
||||
waitForObserverTopic: "chrome://remote/content/marionette/sync.js",
|
||||
@ -28,32 +28,10 @@ XPCOMUtils.defineLazyModuleGetters(this, {
|
||||
*/
|
||||
class WindowManager {
|
||||
constructor() {
|
||||
// Maps browser's permanentKey to uuid: WeakMap.<Object, string>
|
||||
this._windowHandles = new WeakMap();
|
||||
// Maps ChromeWindow to uuid: WeakMap.<Object, string>
|
||||
this._chromeWindowHandles = new WeakMap();
|
||||
}
|
||||
|
||||
get windowHandles() {
|
||||
const windowHandles = [];
|
||||
|
||||
for (const win of this.windows) {
|
||||
const tabBrowser = browser.getTabBrowser(win);
|
||||
|
||||
// Only return handles for browser windows
|
||||
if (tabBrowser && tabBrowser.tabs) {
|
||||
for (const tab of tabBrowser.tabs) {
|
||||
const winId = this.getIdForBrowser(browser.getBrowserForTab(tab));
|
||||
if (winId !== null) {
|
||||
windowHandles.push(winId);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return windowHandles;
|
||||
}
|
||||
|
||||
get chromeWindowHandles() {
|
||||
const chromeWindowHandles = [];
|
||||
|
||||
@ -88,11 +66,11 @@ class WindowManager {
|
||||
|
||||
// Otherwise check if the chrome window has a tab browser, and that it
|
||||
// contains a tab with the wanted window handle.
|
||||
const tabBrowser = browser.getTabBrowser(win);
|
||||
const tabBrowser = TabManager.getTabBrowser(win);
|
||||
if (tabBrowser && tabBrowser.tabs) {
|
||||
for (let i = 0; i < tabBrowser.tabs.length; ++i) {
|
||||
let contentBrowser = browser.getBrowserForTab(tabBrowser.tabs[i]);
|
||||
let contentWindowId = this.getIdForBrowser(contentBrowser);
|
||||
let contentBrowser = TabManager.getBrowserForTab(tabBrowser.tabs[i]);
|
||||
let contentWindowId = TabManager.getIdForBrowser(contentBrowser);
|
||||
|
||||
if (contentWindowId == handle) {
|
||||
return this.getWindowProperties(win, { tabIndex: i });
|
||||
@ -104,35 +82,6 @@ class WindowManager {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve a the browser element corresponding to the provided unique id,
|
||||
* previously generated via getIdForBrowser.
|
||||
*
|
||||
* TODO: To avoid creating strong references on browser elements and
|
||||
* potentially leaking those elements, this method loops over all windows and
|
||||
* all tabs. It should be replaced by a faster implementation in Bug 1750065.
|
||||
*
|
||||
* @param {String} id
|
||||
* A browser unique id created by getIdForBrowser.
|
||||
* @return {xul:browser}
|
||||
* The <xul:browser> corresponding to the provided id. Will return null if
|
||||
* no matching browser element is found.
|
||||
*/
|
||||
getBrowserById(id) {
|
||||
for (const win of this.windows) {
|
||||
const tabBrowser = browser.getTabBrowser(win);
|
||||
if (tabBrowser && tabBrowser.tabs) {
|
||||
for (let i = 0; i < tabBrowser.tabs.length; ++i) {
|
||||
const contentBrowser = browser.getBrowserForTab(tabBrowser.tabs[i]);
|
||||
if (this.getIdForBrowser(contentBrowser) == id) {
|
||||
return contentBrowser;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* A set of properties describing a window and that should allow to uniquely
|
||||
* identify it. The described window can either be a Chrome Window or a
|
||||
@ -166,46 +115,11 @@ class WindowManager {
|
||||
return {
|
||||
win,
|
||||
id: this.getIdForWindow(win),
|
||||
hasTabBrowser: !!browser.getTabBrowser(win),
|
||||
hasTabBrowser: !!TabManager.getTabBrowser(win),
|
||||
tabIndex: options.tabIndex,
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves an id for the given xul browser element. The id is a dynamically
|
||||
* generated uuid associated with the permanentKey property of the given
|
||||
* browser element.
|
||||
*
|
||||
* @param {xul:browser} browserElement
|
||||
* The <xul:browser> for which we want to retrieve the id.
|
||||
* @return {String} The unique id for this browser.
|
||||
*/
|
||||
getIdForBrowser(browserElement) {
|
||||
if (browserElement === null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const key = browserElement.permanentKey;
|
||||
if (!this._windowHandles.has(key)) {
|
||||
const uuid = Services.uuid.generateUUID().toString();
|
||||
this._windowHandles.set(key, uuid.substring(1, uuid.length - 1));
|
||||
}
|
||||
return this._windowHandles.get(key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve an id for the browser element owning the provided browsing
|
||||
* context.
|
||||
*
|
||||
* @param {BrowsingContext} browsingContext
|
||||
* The browsing context for which we want to retrieve the (browser) uuid.
|
||||
* @return {String} The unique id for the browser owning the browsing context.
|
||||
*/
|
||||
getBrowserIdForBrowsingContext(browsingContext) {
|
||||
const contentBrowser = browsingContext.top.embedderElement;
|
||||
return this.getIdForBrowser(contentBrowser);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves an id for the given chrome window. The id is a dynamically
|
||||
* generated uuid associated with the window object.
|
||||
|
@ -3,8 +3,8 @@
|
||||
|
||||
"use strict";
|
||||
|
||||
const { windowManager } = ChromeUtils.import(
|
||||
"chrome://remote/content/shared/WindowManager.jsm"
|
||||
const { TabManager } = ChromeUtils.import(
|
||||
"chrome://remote/content/shared/TabManager.jsm"
|
||||
);
|
||||
|
||||
const COM_TEST_PAGE = "https://example.com/document-builder.sjs?html=COM";
|
||||
@ -80,7 +80,7 @@ function sendBroadcastForTopBrowsingContext(
|
||||
{},
|
||||
{
|
||||
type: CONTEXT_DESCRIPTOR_TYPES.TOP_BROWSING_CONTEXT,
|
||||
id: windowManager.getBrowserIdForBrowsingContext(topBrowsingContext),
|
||||
id: TabManager.getBrowserIdForBrowsingContext(topBrowsingContext),
|
||||
},
|
||||
rootMessageHandler
|
||||
);
|
||||
|
@ -19,7 +19,7 @@ XPCOMUtils.defineLazyModuleGetters(this, {
|
||||
"chrome://remote/content/shared/messagehandler/transports/FrameContextUtils.jsm",
|
||||
MessageHandlerFrameActor:
|
||||
"chrome://remote/content/shared/messagehandler/transports/js-window-actors/MessageHandlerFrameActor.jsm",
|
||||
windowManager: "chrome://remote/content/shared/WindowManager.jsm",
|
||||
TabManager: "chrome://remote/content/shared/TabManager.jsm",
|
||||
});
|
||||
|
||||
/**
|
||||
@ -119,7 +119,7 @@ class FrameTransport {
|
||||
}
|
||||
|
||||
if (type === CONTEXT_DESCRIPTOR_TYPES.TOP_BROWSING_CONTEXT) {
|
||||
const { browserId } = windowManager.getBrowserById(id);
|
||||
const { browserId } = TabManager.getBrowserById(id);
|
||||
return this._getBrowsingContexts({ browserId });
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user