/* 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;