diff --git a/remote/webdriver-bidi/modules/root/script.jsm b/remote/webdriver-bidi/modules/root/script.jsm index 6c0a0ef3002a..39dfe87ed171 100644 --- a/remote/webdriver-bidi/modules/root/script.jsm +++ b/remote/webdriver-bidi/modules/root/script.jsm @@ -169,6 +169,52 @@ class ScriptModule extends Module { return this.#buildReturnValue(evaluationResult); } + /** + * The script.disown command disowns the given handles. This does not + * guarantee the handled object will be garbage collected, as there can be + * other handles or strong ECMAScript references. + * + * @param {Object=} options + * @param {Array} handles + * Array of handle ids to disown. + * @param {Object} target + * The target owning the handles, which either matches the definition for + * a RealmTarget or for ContextTarget. + */ + async disown(options = {}) { + // TODO: Bug 1778976. Remove once command is fully supported. + this.assertExperimentalCommandsEnabled("script.disown"); + + const { handles, target = {} } = options; + + lazy.assert.array( + handles, + `Expected "handles" to be an array, got ${handles}` + ); + handles.forEach(handle => { + lazy.assert.string( + handle, + `Expected "handles" to be an array of strings, got ${handle}` + ); + }); + + const { contextId, realmId, sandbox } = this.#assertTarget(target); + const context = this.#getContextFromTarget({ contextId, realmId, sandbox }); + await this.messageHandler.forwardCommand({ + moduleName: "script", + commandName: "disownHandles", + destination: { + type: lazy.WindowGlobalMessageHandler.type, + id: context.id, + }, + params: { + handles, + realmId, + sandbox, + }, + }); + } + /** * Evaluate a provided expression in the provided target, which is either a * realm or a browsing context. diff --git a/remote/webdriver-bidi/modules/windowglobal/script.jsm b/remote/webdriver-bidi/modules/windowglobal/script.jsm index 1f41b6512f31..81eb3b471d66 100644 --- a/remote/webdriver-bidi/modules/windowglobal/script.jsm +++ b/remote/webdriver-bidi/modules/windowglobal/script.jsm @@ -209,6 +209,8 @@ class ScriptModule extends Module { * The arguments to pass to the function call. * @param {string} functionDeclaration * The body of the function to call. + * @param {string=} realmId [not supported] + * The id of the realm. * @param {OwnershipModel} resultOwnership * The ownership model to use for the results of this evaluation. * @param {string=} sandbox @@ -252,6 +254,26 @@ class ScriptModule extends Module { return this.#buildReturnValue(rv, realm, awaitPromise, resultOwnership); } + /** + * Delete the provided handles from the realm corresponding to the provided + * sandbox name. + * + * @param {Object=} options + * @param {Array} handles + * Array of handle ids to disown. + * @param {string=} realmId [not supported] + * The id of the realm. + * @param {string=} sandbox + * The name of the sandbox. + */ + disownHandles(options) { + const { handles, sandbox: sandboxName = null } = options; + const realm = this.#getRealmFromSandboxName(sandboxName); + for (const handle of handles) { + realm.removeObjectHandle(handle); + } + } + /** * Evaluate a provided expression in the current window global. * @@ -261,6 +283,8 @@ class ScriptModule extends Module { * expression to resolve, if this return value is a Promise. * @param {string} expression * The expression to evaluate. + * @param {string=} realmId [not supported] + * The id of the realm. * @param {OwnershipModel} resultOwnership * The ownership model to use for the results of this evaluation. * @param {string=} sandbox