ven DOM element. * * @param {Element} element The DOM element to generate the identifier for. * @return {ElementIdentifier} The identifier for the DOM element that can be passed between * processes as a message. */ get(element) { if (!element) { throw new Error( "Can't create a ContentDOMReference identifier for " + "non-existant nodes." ); } let browsingContext = BrowsingContext.getFromWindow(element.ownerGlobal); let mappings = gRegistry.get(browsingContext); if (!mappings) { mappings = { IDToElement: new Map(), elementToID: new WeakMap(), }; gRegistry.set(browsingContext, mappings); } let id = mappings.elementToID.get(element); if (id) { // We already had this element registered, so return the pre-existing ID. return { browsingContextId: browsingContext.id, id }; } // We must be registering a new element at this point. id = Math.random(); mappings.elementToID.set(element, id); mappings.IDToElement.set(id, Cu.getWeakReference(element)); let identifier = { browsingContextId: browsingContext.id, id }; finalizerRoots.set( element, lazy.finalizationService.make( FINALIZATION_TOPIC, JSON.stringify(identifier) ) ); return identifier; }, /** * Resolves an identifier back into the DOM Element that it was generated from. * * @param {ElementIdentifier} The identifier generated via ContentDOMReference.get for a * DOM element. * @return {Element} The DOM element that the identifier was generated for, or * null if the element does not still exist. */ resolve(identifier) { let browsingContext = BrowsingContext.get(identifier.browsingContextId); let { id } = identifier; return this._resolveIDToElement(browsingContext, id); }, /** * Removes an identifier from the registry so that subsequent attempts * to resolve it will result in null. This is done automatically when the * target node is GCed. * * @param {ElementIdentifier} The identifier to revoke, issued by ContentDOMReference.get for * a DOM element. */ _revoke(identifier) { let browsingContext = BrowsingContext.get(identifier.browsingContextId); let { id } = identifier; let mappings = gRegistry.get(browsingContext); if (!mappings) { return; } mappings.IDToElement.delete(id); }, /** * Private helper function that resolves a BrowsingContext and ID (the * pair that makes up an identifier) to a DOM element. * * @param {BrowsingContext} browsingContext The BrowsingContext that was hosting * the DOM element at the time that the identifier was generated. * @param {ElementID} id The ID generated for the DOM element. * * @return {Element} The DOM element that the identifier was generated for, or * null if the element does not still exist. */ _resolveIDToElement(browsingContext, id) { let mappings = gRegistry.get(browsingContext); if (!mappings) { return null; } let weakReference = mappings.IDToElement.get(id); if (!weakReference) { return null; } return weakReference.get(); }, }; ContentDOMReference._init(); PK