webtransport.js (2676B)
1 /* This Source Code Form is subject to the terms of the Mozilla Public 2 * License, v. 2.0. If a copy of the MPL was not distributed with this 3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 5 "use strict"; 6 7 const webTransportEventService = Cc[ 8 "@mozilla.org/webtransportevent/service;1" 9 ].getService(Ci.nsIWebTransportEventService); 10 11 class WebTransportWatcher { 12 constructor() { 13 this.windowIds = new Map(); 14 this.abortController = new AbortController(); 15 this.onWindowReady = this.onWindowReady.bind(this); 16 this.onWindowDestroy = this.onWindowDestroy.bind(this); 17 } 18 19 static createResource(wtMessageType, eventParams) { 20 return { 21 wtMessageType, 22 ...eventParams, 23 }; 24 } 25 26 watch(targetActor, { onAvailable }) { 27 this.targetActor = targetActor; 28 this.onAvailable = onAvailable; 29 30 for (const window of this.targetActor.windows) { 31 const { innerWindowId } = window.windowGlobalChild; 32 this.startListening(innerWindowId); 33 } 34 35 // On navigate/reload we should re-start listening with the new `innerWindowID` 36 if (!this.targetActor.followWindowGlobalLifeCycle) { 37 this.targetActor.on("window-ready", this.onWindowReady, { 38 signal: this.abortController.signal, 39 }); 40 this.targetActor.on("window-destroyed", this.onWindowDestroy, { 41 signal: this.abortController.signal, 42 }); 43 } 44 } 45 46 onWindowReady({ window }) { 47 const { innerWindowId } = window.windowGlobalChild; 48 this.startListening(innerWindowId); 49 } 50 51 onWindowDestroy({ id }) { 52 this.stopListening(id); 53 } 54 55 startListening(innerWindowId) { 56 if (!this.windowIds.has(innerWindowId)) { 57 const listener = { 58 // methods for the webTransportEventService 59 webTransportSessionCreated: () => {}, 60 webTransportSessionClosed: () => {}, 61 }; 62 this.windowIds.set(innerWindowId, listener); 63 webTransportEventService.addListener(innerWindowId, listener); 64 } 65 } 66 67 stopListening(innerWindowId) { 68 if (this.windowIds.has(innerWindowId)) { 69 if (!webTransportEventService.hasListenerFor(innerWindowId)) { 70 // The listener might have already been cleaned up on `window-destroy`. 71 console.warn( 72 "Already stopped listening to webtransport events for this window." 73 ); 74 return; 75 } 76 webTransportEventService.removeListener( 77 innerWindowId, 78 this.windowIds.get(innerWindowId) 79 ); 80 this.windowIds.delete(innerWindowId); 81 } 82 } 83 84 destroy() { 85 this.abortController.abort(); 86 for (const id of this.windowIds) { 87 this.stopListening(id); 88 } 89 } 90 } 91 92 module.exports = WebTransportWatcher;