summaryrefslogtreecommitdiffstats
path: root/devtools/client/netmonitor/src/connector/har-metadata-collector.js
blob: c0227065a5a835502a922348a662b6e244acbaea (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
/* 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 {
  TYPES,
} = require("resource://devtools/shared/commands/resource/resource-command.js");

/**
 * This collector class is dedicated to recording additional metadata necessary
 * to build HAR files. The actual request data will be provided by the
 * netmonitor which is already monitoring for requests.
 *
 * The only purpose of this class is to record additional document and network
 * events, which will help to assign requests to individual pages.
 *
 * It should be created and destroyed by the main netmonitor data collector.
 */
class HarMetadataCollector {
  #commands;
  #initialTargetTitle;
  #navigationRequests;
  #targetTitlesPerURL;

  constructor(commands) {
    this.#commands = commands;
  }

  /**
   * Stop recording and clear the state.
   */
  destroy() {
    this.clear();

    this.#commands.resourceCommand.unwatchResources(
      [TYPES.DOCUMENT_EVENT, TYPES.NETWORK_EVENT],
      {
        onAvailable: this.#onResourceAvailable,
      }
    );
  }

  /**
   * Reset the current state.
   */
  clear() {
    this.#navigationRequests = [];
    this.#targetTitlesPerURL = new Map();
    this.#initialTargetTitle = this.#commands.targetCommand.targetFront.title;
  }

  /**
   * Start recording additional events for HAR files building.
   */
  async connect() {
    this.clear();

    await this.#commands.resourceCommand.watchResources(
      [TYPES.DOCUMENT_EVENT, TYPES.NETWORK_EVENT],
      {
        onAvailable: this.#onResourceAvailable,
      }
    );
  }

  getHarData() {
    return {
      initialTargetTitle: this.#initialTargetTitle,
      navigationRequests: this.#navigationRequests,
      targetTitlesPerURL: this.#targetTitlesPerURL,
    };
  }

  #onResourceAvailable = resources => {
    for (const resource of resources) {
      if (resource.resourceType === TYPES.DOCUMENT_EVENT) {
        if (
          resource.name === "dom-complete" &&
          resource.targetFront.isTopLevel
        ) {
          this.#targetTitlesPerURL.set(
            resource.targetFront.url,
            resource.targetFront.title
          );
        }
      } else if (resource.resourceType === TYPES.NETWORK_EVENT) {
        if (resource.isNavigationRequest) {
          this.#navigationRequests.push(resource);
        }
      }
    }
  };
}

exports.HarMetadataCollector = HarMetadataCollector;