Source code

Revision control

Copy as Markdown

Other Tools

/* 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";
const webTransportEventService = Cc[
"@mozilla.org/webtransportevent/service;1"
].getService(Ci.nsIWebTransportEventService);
class WebTransportWatcher {
constructor() {
this.windowIds = new Map();
this.abortController = new AbortController();
this.onWindowReady = this.onWindowReady.bind(this);
this.onWindowDestroy = this.onWindowDestroy.bind(this);
}
static createResource(wtMessageType, eventParams) {
return {
wtMessageType,
...eventParams,
};
}
watch(targetActor, { onAvailable }) {
this.targetActor = targetActor;
this.onAvailable = onAvailable;
for (const window of this.targetActor.windows) {
const { innerWindowId } = window.windowGlobalChild;
this.startListening(innerWindowId);
}
// On navigate/reload we should re-start listening with the new `innerWindowID`
if (!this.targetActor.followWindowGlobalLifeCycle) {
this.targetActor.on("window-ready", this.onWindowReady, {
signal: this.abortController.signal,
});
this.targetActor.on("window-destroyed", this.onWindowDestroy, {
signal: this.abortController.signal,
});
}
}
onWindowReady({ window }) {
const { innerWindowId } = window.windowGlobalChild;
this.startListening(innerWindowId);
}
onWindowDestroy({ id }) {
this.stopListening(id);
}
startListening(innerWindowId) {
if (!this.windowIds.has(innerWindowId)) {
const listener = {
// methods for the webTransportEventService
webTransportSessionCreated: () => {},
webTransportSessionClosed: () => {},
};
this.windowIds.set(innerWindowId, listener);
webTransportEventService.addListener(innerWindowId, listener);
}
}
stopListening(innerWindowId) {
if (this.windowIds.has(innerWindowId)) {
if (!webTransportEventService.hasListenerFor(innerWindowId)) {
// The listener might have already been cleaned up on `window-destroy`.
console.warn(
"Already stopped listening to webtransport events for this window."
);
return;
}
webTransportEventService.removeListener(
innerWindowId,
this.windowIds.get(innerWindowId)
);
this.windowIds.delete(innerWindowId);
}
}
destroy() {
this.abortController.abort();
for (const id of this.windowIds) {
this.stopListening(id);
}
}
}
module.exports = WebTransportWatcher;