summaryrefslogtreecommitdiffstats
path: root/devtools/server/actors/watcher/target-helpers/worker-helper.js
blob: 6fda83e6bbb5a4cf2eb8de963bc3ebf4958ff2c6 (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
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
/* 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 DEVTOOLS_WORKER_JS_WINDOW_ACTOR_NAME = "DevToolsWorker";

/**
 * Force creating targets for all existing workers for a given Watcher Actor.
 *
 * @param WatcherActor watcher
 *        The Watcher Actor requesting to watch for new targets.
 */
async function createTargets(watcher) {
  // Go over all existing BrowsingContext in order to:
  // - Force the instantiation of a DevToolsWorkerChild
  // - Have the DevToolsWorkerChild to spawn the WorkerTargetActors
  const browsingContexts = watcher.getAllBrowsingContexts({
    acceptSameProcessIframes: true,
    forceAcceptTopLevelTarget: true,
  });
  const promises = [];
  for (const browsingContext of browsingContexts) {
    const promise = browsingContext.currentWindowGlobal
      .getActor(DEVTOOLS_WORKER_JS_WINDOW_ACTOR_NAME)
      .instantiateWorkerTargets({
        watcherActorID: watcher.actorID,
        connectionPrefix: watcher.conn.prefix,
        sessionContext: watcher.sessionContext,
        sessionData: watcher.sessionData,
      });
    promises.push(promise);
  }

  // Await for the different queries in order to try to resolve only *after* we received
  // the already available worker targets.
  return Promise.all(promises);
}

/**
 * Force destroying all worker targets which were related to a given watcher.
 *
 * @param WatcherActor watcher
 *        The Watcher Actor requesting to stop watching for new targets.
 */
async function destroyTargets(watcher) {
  // Go over all existing BrowsingContext in order to destroy all targets
  const browsingContexts = watcher.getAllBrowsingContexts({
    acceptSameProcessIframes: true,
    forceAcceptTopLevelTarget: true,
  });
  for (const browsingContext of browsingContexts) {
    let windowActor;
    try {
      windowActor = browsingContext.currentWindowGlobal.getActor(
        DEVTOOLS_WORKER_JS_WINDOW_ACTOR_NAME
      );
    } catch (e) {
      continue;
    }

    windowActor.destroyWorkerTargets({
      watcherActorID: watcher.actorID,
      sessionContext: watcher.sessionContext,
    });
  }
}

/**
 * Go over all existing BrowsingContext in order to communicate about new data entries
 *
 * @param WatcherActor watcher
 *        The Watcher Actor requesting to stop watching for new targets.
 * @param string type
 *        The type of data to be added
 * @param Array<Object> entries
 *        The values to be added to this type of data
 */
async function addSessionDataEntry({ watcher, type, entries }) {
  const browsingContexts = watcher.getAllBrowsingContexts({
    acceptSameProcessIframes: true,
    forceAcceptTopLevelTarget: true,
  });
  const promises = [];
  for (const browsingContext of browsingContexts) {
    const promise = browsingContext.currentWindowGlobal
      .getActor(DEVTOOLS_WORKER_JS_WINDOW_ACTOR_NAME)
      .addSessionDataEntry({
        watcherActorID: watcher.actorID,
        sessionContext: watcher.sessionContext,
        type,
        entries,
      });
    promises.push(promise);
  }
  // Await for the queries in order to try to resolve only *after* the remote code processed the new data
  return Promise.all(promises);
}

/**
 * Notify all existing frame targets that some data entries have been removed
 *
 * See addSessionDataEntry for argument documentation.
 */
function removeSessionDataEntry({ watcher, type, entries }) {
  const browsingContexts = watcher.getAllBrowsingContexts({
    acceptSameProcessIframes: true,
    forceAcceptTopLevelTarget: true,
  });
  for (const browsingContext of browsingContexts) {
    browsingContext.currentWindowGlobal
      .getActor(DEVTOOLS_WORKER_JS_WINDOW_ACTOR_NAME)
      .removeSessionDataEntry({
        watcherActorID: watcher.actorID,
        sessionContext: watcher.sessionContext,
        type,
        entries,
      });
  }
}

module.exports = {
  createTargets,
  destroyTargets,
  addSessionDataEntry,
  removeSessionDataEntry,
};