tor-browser

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

document-event.js (3885B)


      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 {
      8  DocumentEventsListener,
      9 } = require("resource://devtools/server/actors/webconsole/listeners/document-events.js");
     10 
     11 class DocumentEventWatcher {
     12  #abortController = new AbortController();
     13  /**
     14   * Start watching for all document event related to a given Target Actor.
     15   *
     16   * @param TargetActor targetActor
     17   *        The target actor from which we should observe document event
     18   * @param Object options
     19   *        Dictionary object with following attributes:
     20   *        - onAvailable: mandatory function
     21   *          This will be called for each resource.
     22   */
     23  async watch(targetActor, { onAvailable }) {
     24    if (isWorker) {
     25      return;
     26    }
     27    // Bug 1975277: ignore iframes which are destroying.
     28    // The inner-window-destroyed event isn't yet fired and the actor is still
     29    // registered, but it no longer has a valid window reference.
     30    if (!targetActor.window) {
     31      return;
     32    }
     33 
     34    const onDocumentEvent = (
     35      name,
     36      {
     37        time,
     38        // This will be `true` when the user selected a document in the frame picker tool,
     39        // in the toolbox toolbar.
     40        isFrameSwitching,
     41        // This is only passed for dom-complete event
     42        hasNativeConsoleAPI,
     43        // This is only passed for will-navigate event
     44        newURI,
     45      } = {}
     46    ) => {
     47      // Ignore will-navigate as that's managed by parent-process-document-event.js.
     48      // Except frame switching, when selecting an iframe document via the dropdown menu,
     49      // this is handled by the target actor in the content process and the parent process
     50      // doesn't know about it.
     51      if (name == "will-navigate" && !isFrameSwitching) {
     52        return;
     53      }
     54      onAvailable([
     55        {
     56          name,
     57          time,
     58          isFrameSwitching,
     59          // only send `title` on dom interactive (once the HTML was parsed) so we don't
     60          // make the payload bigger for events where we either don't have a title yet,
     61          // or where we already had a chance to get the title.
     62          title: name === "dom-interactive" ? targetActor.title : undefined,
     63          // only send `url` on dom loading and dom-interactive so we don't make the
     64          // payload bigger for other events
     65          url:
     66            name === "dom-loading" || name === "dom-interactive"
     67              ? targetActor.url
     68              : undefined,
     69          // only send `newURI` on will navigate so we don't make the payload bigger for
     70          // other events
     71          newURI: name === "will-navigate" ? newURI : null,
     72          // only send `hasNativeConsoleAPI` on dom complete so we don't make the payload bigger for
     73          // other events
     74          hasNativeConsoleAPI:
     75            name == "dom-complete" ? hasNativeConsoleAPI : null,
     76        },
     77      ]);
     78    };
     79 
     80    this.listener = new DocumentEventsListener(targetActor);
     81 
     82    this.listener.on(
     83      "will-navigate",
     84      data => onDocumentEvent("will-navigate", data),
     85      { signal: this.#abortController.signal }
     86    );
     87    this.listener.on(
     88      "dom-loading",
     89      data => onDocumentEvent("dom-loading", data),
     90      { signal: this.#abortController.signal }
     91    );
     92    this.listener.on(
     93      "dom-interactive",
     94      data => onDocumentEvent("dom-interactive", data),
     95      { signal: this.#abortController.signal }
     96    );
     97    this.listener.on(
     98      "dom-complete",
     99      data => onDocumentEvent("dom-complete", data),
    100      { signal: this.#abortController.signal }
    101    );
    102 
    103    this.listener.listen();
    104  }
    105 
    106  destroy() {
    107    this.#abortController.abort();
    108    if (this.listener) {
    109      this.listener.destroy();
    110    }
    111  }
    112 }
    113 
    114 module.exports = DocumentEventWatcher;