diff options
Diffstat (limited to 'dom/base/DOMRequestHelper.sys.mjs')
-rw-r--r-- | dom/base/DOMRequestHelper.sys.mjs | 335 |
1 files changed, 0 insertions, 335 deletions
diff --git a/dom/base/DOMRequestHelper.sys.mjs b/dom/base/DOMRequestHelper.sys.mjs deleted file mode 100644 index 832c06c4de..0000000000 --- a/dom/base/DOMRequestHelper.sys.mjs +++ /dev/null @@ -1,335 +0,0 @@ -/* 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/. */ - -/** - * Helper object for APIs that deal with DOMRequests and Promises. - * It allows objects inheriting from it to create and keep track of DOMRequests - * and Promises objects in the common scenario where requests are created in - * the child, handed out to content and delivered to the parent within an async - * message (containing the identifiers of these requests). The parent may send - * messages back as answers to different requests and the child will use this - * helper to get the right request object. This helper also takes care of - * releasing the requests objects when the window goes out of scope. - * - * DOMRequestIPCHelper also deals with message listeners, allowing to add them - * to the child side of frame and process message manager and removing them - * when needed. - */ -export function DOMRequestIpcHelper() { - // _listeners keeps a list of messages for which we added a listener and the - // kind of listener that we added (strong or weak). It's an object of this - // form: - // { - // "message1": true, - // "messagen": false - // } - // - // where each property is the name of the message and its value is a boolean - // that indicates if the listener is weak or not. - this._listeners = null; - this._requests = null; - this._window = null; -} - -DOMRequestIpcHelper.prototype = { - /** - * An object which "inherits" from DOMRequestIpcHelper and declares its own - * queryInterface method MUST implement Ci.nsISupportsWeakReference. - */ - QueryInterface: ChromeUtils.generateQI([ - "nsISupportsWeakReference", - "nsIObserver", - ]), - - /** - * 'aMessages' is expected to be an array of either: - * - objects of this form: - * { - * name: "messageName", - * weakRef: false - * } - * where 'name' is the message identifier and 'weakRef' a boolean - * indicating if the listener should be a weak referred one or not. - * - * - or only strings containing the message name, in which case the listener - * will be added as a strong reference by default. - */ - addMessageListeners(aMessages) { - if (!aMessages) { - return; - } - - if (!this._listeners) { - this._listeners = {}; - } - - if (!Array.isArray(aMessages)) { - aMessages = [aMessages]; - } - - aMessages.forEach(aMsg => { - let name = aMsg.name || aMsg; - // If the listener is already set and it is of the same type we just - // increase the count and bail out. If it is not of the same type, - // we throw an exception. - if (this._listeners[name] != undefined) { - if (!!aMsg.weakRef == this._listeners[name].weakRef) { - this._listeners[name].count++; - return; - } - throw Components.Exception("", Cr.NS_ERROR_FAILURE); - } - - aMsg.weakRef - ? Services.cpmm.addWeakMessageListener(name, this) - : Services.cpmm.addMessageListener(name, this); - this._listeners[name] = { - weakRef: !!aMsg.weakRef, - count: 1, - }; - }); - }, - - /** - * 'aMessages' is expected to be a string or an array of strings containing - * the message names of the listeners to be removed. - */ - removeMessageListeners(aMessages) { - if (!this._listeners || !aMessages) { - return; - } - - if (!Array.isArray(aMessages)) { - aMessages = [aMessages]; - } - - aMessages.forEach(aName => { - if (this._listeners[aName] == undefined) { - return; - } - - // Only remove the listener really when we don't have anybody that could - // be waiting on a message. - if (!--this._listeners[aName].count) { - this._listeners[aName].weakRef - ? Services.cpmm.removeWeakMessageListener(aName, this) - : Services.cpmm.removeMessageListener(aName, this); - delete this._listeners[aName]; - } - }); - }, - - /** - * Initialize the helper adding the corresponding listeners to the messages - * provided as the second parameter. - * - * 'aMessages' is expected to be an array of either: - * - * - objects of this form: - * { - * name: 'messageName', - * weakRef: false - * } - * where 'name' is the message identifier and 'weakRef' a boolean - * indicating if the listener should be a weak referred one or not. - * - * - or only strings containing the message name, in which case the listener - * will be added as a strong referred one by default. - */ - initDOMRequestHelper(aWindow, aMessages) { - // Query our required interfaces to force a fast fail if they are not - // provided. These calls will throw if the interface is not available. - this.QueryInterface(Ci.nsISupportsWeakReference); - this.QueryInterface(Ci.nsIObserver); - - if (aMessages) { - this.addMessageListeners(aMessages); - } - - this._id = this._getRandomId(); - - this._window = aWindow; - if (this._window) { - // We don't use this.innerWindowID, but other classes rely on it. - this.innerWindowID = this._window.windowGlobalChild.innerWindowId; - } - - this._destroyed = false; - - Services.obs.addObserver( - this, - "inner-window-destroyed", - /* weak-ref */ true - ); - }, - - destroyDOMRequestHelper() { - if (this._destroyed) { - return; - } - - this._destroyed = true; - - Services.obs.removeObserver(this, "inner-window-destroyed"); - - if (this._listeners) { - Object.keys(this._listeners).forEach(aName => { - this._listeners[aName].weakRef - ? Services.cpmm.removeWeakMessageListener(aName, this) - : Services.cpmm.removeMessageListener(aName, this); - }); - } - - this._listeners = null; - this._requests = null; - - // Objects inheriting from DOMRequestIPCHelper may have an uninit function. - if (this.uninit) { - this.uninit(); - } - - this._window = null; - }, - - observe(aSubject, aTopic, aData) { - if (aTopic !== "inner-window-destroyed") { - return; - } - - let wId = aSubject.QueryInterface(Ci.nsISupportsPRUint64).data; - if (wId != this.innerWindowID) { - return; - } - - this.destroyDOMRequestHelper(); - }, - - getRequestId(aRequest) { - if (!this._requests) { - this._requests = {}; - } - - let id = "id" + this._getRandomId(); - this._requests[id] = aRequest; - return id; - }, - - getPromiseResolverId(aPromiseResolver) { - // Delegates to getRequest() since the lookup table is agnostic about - // storage. - return this.getRequestId(aPromiseResolver); - }, - - getRequest(aId) { - if (this._requests && this._requests[aId]) { - return this._requests[aId]; - } - return undefined; - }, - - getPromiseResolver(aId) { - // Delegates to getRequest() since the lookup table is agnostic about - // storage. - return this.getRequest(aId); - }, - - removeRequest(aId) { - if (this._requests && this._requests[aId]) { - delete this._requests[aId]; - } - }, - - removePromiseResolver(aId) { - // Delegates to getRequest() since the lookup table is agnostic about - // storage. - this.removeRequest(aId); - }, - - takeRequest(aId) { - if (!this._requests || !this._requests[aId]) { - return null; - } - let request = this._requests[aId]; - delete this._requests[aId]; - return request; - }, - - takePromiseResolver(aId) { - // Delegates to getRequest() since the lookup table is agnostic about - // storage. - return this.takeRequest(aId); - }, - - _getRandomId() { - return Services.uuid.generateUUID().toString(); - }, - - createRequest() { - // If we don't have a valid window object, throw. - if (!this._window) { - console.error( - "DOMRequestHelper trying to create a DOMRequest without a valid window, failing." - ); - throw Components.Exception("", Cr.NS_ERROR_FAILURE); - } - return Services.DOMRequest.createRequest(this._window); - }, - - /** - * createPromise() creates a new Promise, with `aPromiseInit` as the - * PromiseInit callback. The promise constructor is obtained from the - * reference to window owned by this DOMRequestIPCHelper. - */ - createPromise(aPromiseInit) { - // If we don't have a valid window object, throw. - if (!this._window) { - console.error( - "DOMRequestHelper trying to create a Promise without a valid window, failing." - ); - throw Components.Exception("", Cr.NS_ERROR_FAILURE); - } - return new this._window.Promise(aPromiseInit); - }, - - /** - * createPromiseWithId() creates a new Promise, accepting a callback - * which is immediately called with the generated resolverId. - */ - createPromiseWithId(aCallback) { - return this.createPromise((aResolve, aReject) => { - let resolverId = this.getPromiseResolverId({ - resolve: aResolve, - reject: aReject, - }); - aCallback(resolverId); - }); - }, - - forEachRequest(aCallback) { - if (!this._requests) { - return; - } - - Object.keys(this._requests).forEach(aKey => { - if (this._window.DOMRequest.isInstance(this.getRequest(aKey))) { - aCallback(aKey); - } - }); - }, - - forEachPromiseResolver(aCallback) { - if (!this._requests) { - return; - } - - Object.keys(this._requests).forEach(aKey => { - if ( - "resolve" in this.getPromiseResolver(aKey) && - "reject" in this.getPromiseResolver(aKey) - ) { - aCallback(aKey); - } - }); - }, -}; |