commit fcb89ab88f85f6151c6de995dc5d3c552b024b50
parent e98b1b1e869dc828ce6637b58c67a77dd865c67a
Author: Henrik Skupin <mail@hskupin.info>
Date: Tue, 9 Dec 2025 14:06:19 +0000
Bug 1944568 - [remote] Add support for chrome browsing context tree retrieval in "browsingContext.getTree". r=jdescottes
Differential Revision: https://phabricator.services.mozilla.com/D270536
Diffstat:
2 files changed, 81 insertions(+), 11 deletions(-)
diff --git a/remote/webdriver-bidi/modules/RootBiDiModule.sys.mjs b/remote/webdriver-bidi/modules/RootBiDiModule.sys.mjs
@@ -8,6 +8,8 @@ const lazy = {};
ChromeUtils.defineESModuleGetters(lazy, {
error: "chrome://remote/content/shared/webdriver/Errors.sys.mjs",
+ MozContextScope:
+ "chrome://remote/content/webdriver-bidi/modules/root/browsingContext.sys.mjs",
NavigableManager: "chrome://remote/content/shared/NavigableManager.sys.mjs",
WindowGlobalMessageHandler:
"chrome://remote/content/shared/messagehandler/WindowGlobalMessageHandler.sys.mjs",
@@ -44,6 +46,9 @@ export class RootBiDiModule extends Module {
*
* @param {string} navigableId
* Unique id of the browsing context.
+ * @param {object=} options
+ * @param {MozContextScope=} options.scope
+ * Scope of the browsing context. Defaults to "content".
*
* @returns {BrowsingContext|null}
* The browsing context, or null if `navigableId` is null.
@@ -51,14 +56,21 @@ export class RootBiDiModule extends Module {
* @throws {NoSuchFrameError}
* If the browsing context cannot be found.
*/
- _getNavigable(navigableId) {
+ _getNavigable(navigableId, options = {}) {
+ const { scope = lazy.MozContextScope.CONTENT } = options;
+
if (navigableId === null) {
// The WebDriver BiDi specification expects `null` to be
// returned if navigable id is `null`.
return null;
}
- const context = lazy.NavigableManager.getBrowsingContextById(navigableId);
+ let context = lazy.NavigableManager.getBrowsingContextById(navigableId);
+
+ // Only allow to retrieve contexts for chrome windows if explicitly allowed.
+ if (context && !context.isContent && scope != lazy.MozContextScope.CHROME) {
+ context = null;
+ }
if (context === null) {
throw new lazy.error.NoSuchFrameError(
diff --git a/remote/webdriver-bidi/modules/root/browsingContext.sys.mjs b/remote/webdriver-bidi/modules/root/browsingContext.sys.mjs
@@ -32,6 +32,7 @@ ChromeUtils.defineESModuleGetters(lazy, {
ProgressListener: "chrome://remote/content/shared/Navigate.sys.mjs",
PromptListener:
"chrome://remote/content/shared/listeners/PromptListener.sys.mjs",
+ RemoteAgent: "chrome://remote/content/components/RemoteAgent.sys.mjs",
SessionDataMethod:
"chrome://remote/content/shared/messagehandler/sessiondata/SessionData.sys.mjs",
setDefaultAndAssertSerializationOptions:
@@ -176,6 +177,17 @@ const WaitCondition = {
};
/**
+ * An enum that specifies the scope of a browsing context.
+ *
+ * @readonly
+ * @enum {string}
+ */
+export const MozContextScope = {
+ CHROME: "chrome",
+ CONTENT: "content",
+};
+
+/**
* Used as an argument for browsingContext._updateNavigableViewport command
* to represent an object which holds viewport settings which should be applied.
*
@@ -774,6 +786,7 @@ class BrowsingContextModule extends RootBiDiModule {
};
}
+ /* eslint-disable jsdoc/valid-types */
/**
* An object that holds the WebDriver Bidi browsing context information.
*
@@ -793,7 +806,12 @@ class BrowsingContextModule extends RootBiDiModule {
* reached yet.
* @property {string} clientWindow
* The id of the window the browsing context belongs to.
+ * @property {string=} "moz:name"
+ * Name of the browsing context.
+ * @property {MozContextScope=} "moz:scope"
+ * The scope of the browsing context.
*/
+ /* eslint-enable jsdoc/valid-types */
/**
* An object that holds the WebDriver Bidi browsing context tree information.
@@ -805,7 +823,7 @@ class BrowsingContextModule extends RootBiDiModule {
*/
/**
- * Returns a tree of all browsing contexts that are descendents of the
+ * Returns a tree of all browsing contexts that are descendants of the
* given context, or all top-level contexts when no root is provided.
*
* @param {object=} options
@@ -814,6 +832,8 @@ class BrowsingContextModule extends RootBiDiModule {
* the whole tree is returned.
* @param {string=} options.root
* Id of the root browsing context.
+ * @param {MozContextScope=} options."moz:scope"
+ * The scope to retrieve browsing contexts from.
*
* @returns {BrowsingContextGetTreeResult}
* Tree of browsing context information.
@@ -821,7 +841,11 @@ class BrowsingContextModule extends RootBiDiModule {
* If the browsing context cannot be found.
*/
getTree(options = {}) {
- const { maxDepth = null, root: rootId = null } = options;
+ const {
+ maxDepth = null,
+ root: rootId = null,
+ "moz:scope": scope = MozContextScope.CONTENT,
+ } = options;
if (maxDepth !== null) {
lazy.assert.positiveInteger(
@@ -830,6 +854,18 @@ class BrowsingContextModule extends RootBiDiModule {
);
}
+ const contextScopes = Object.values(MozContextScope);
+ lazy.assert.that(
+ _scope => contextScopes.includes(_scope),
+ `Expected "moz:scope" to be one of ${contextScopes}, ` +
+ lazy.pprint`got ${scope}`
+ )(scope);
+
+ if (scope != MozContextScope.CONTENT) {
+ // By default only content browsing contexts are allowed.
+ lazy.assert.hasSystemAccess();
+ }
+
let contexts;
if (rootId !== null) {
// With a root id specified return the context info for itself
@@ -838,12 +874,22 @@ class BrowsingContextModule extends RootBiDiModule {
rootId,
lazy.pprint`Expected "root" to be a string, got ${rootId}`
);
- contexts = [this._getNavigable(rootId)];
+
+ contexts = [this._getNavigable(rootId, { scope })];
} else {
- // Return all top-level browsing contexts.
- contexts = lazy.TabManager.getBrowsers().map(
- browser => browser.browsingContext
- );
+ switch (scope) {
+ case MozContextScope.CHROME: {
+ // Return all browsing contexts related to chrome windows.
+ contexts = lazy.windowManager.windows.map(win => win.browsingContext);
+ break;
+ }
+ default: {
+ // Return all top-level browsing contexts.
+ contexts = lazy.TabManager.getBrowsers().map(
+ browser => browser.browsingContext
+ );
+ }
+ }
}
const contextsInfo = contexts.map(context => {
@@ -2537,8 +2583,10 @@ export const getBrowsingContextInfo = (context, options = {}) => {
let children = null;
if (maxDepth === null || maxDepth > 0) {
- children = context.children.map(context =>
- getBrowsingContextInfo(context, {
+ // Bug 1996311: When executed for chrome browsing contexts as
+ // well include embedded browsers and their browsing context tree.
+ children = context.children.map(childContext =>
+ getBrowsingContextInfo(childContext, {
maxDepth: maxDepth === null ? maxDepth : maxDepth - 1,
includeParentId: false,
})
@@ -2571,6 +2619,16 @@ export const getBrowsingContextInfo = (context, options = {}) => {
contextInfo.parent = parentId;
}
+ if (lazy.RemoteAgent.allowSystemAccess) {
+ contextInfo["moz:scope"] = context.isContent
+ ? MozContextScope.CONTENT
+ : MozContextScope.CHROME;
+
+ if ("name" in context) {
+ contextInfo["moz:name"] = context.name;
+ }
+ }
+
return contextInfo;
};