tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

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;