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/. */
9 } = require("resource://devtools/server/actors/resources/index.js");
10 const Targets = require("resource://devtools/server/actors/targets/index.js");
13 STATES: THREAD_STATES,
14 } = require("resource://devtools/server/actors/thread.js");
17 * Start watching for all JS sources related to a given Target Actor.
18 * This will notify about existing sources, but also the ones created in future.
20 * @param TargetActor targetActor
21 * The target actor from which we should observe sources
22 * @param Object options
23 * Dictionary object with following attributes:
24 * - onAvailable: mandatory function
25 * This will be called for each resource.
29 this.onNewSource = this.onNewSource.bind(this);
32 async watch(targetActor, { onAvailable }) {
33 // When debugging the whole browser, we instantiate both content process and browsing context targets.
34 // But sources will only be debugged the content process target, even browsing context sources.
36 targetActor.sessionContext.type == "all" &&
37 targetActor.targetType === Targets.TYPES.FRAME &&
38 targetActor.typeName != "parentProcessTarget"
43 const { threadActor } = targetActor;
44 this.sourcesManager = targetActor.sourcesManager;
45 this.onAvailable = onAvailable;
47 // Disable `ThreadActor.newSource` RDP event in order to avoid unnecessary traffic
48 threadActor.disableNewSourceEvents();
50 threadActor.sourcesManager.on("newSource", this.onNewSource);
52 // If the thread actors isn't bootstraped yet,
53 // (this might be the case when this watcher is created on target creation)
54 // attach the thread actor automatically.
55 // Otherwise it would not notify about future sources.
56 // However, do not attach the thread actor for Workers. They use a codepath
57 // which releases the worker on `attach`. For them, the client will call `attach`. (bug 1691986)
58 // Content process targets don't have attach method or sequence.
59 // Instead their thread actor is instantiated immediately, when generating their
60 // form. Which is called immediately when we notify the target actor to the TargetList.
61 const isTargetCreation = threadActor.state == THREAD_STATES.DETACHED;
62 if (isTargetCreation && !targetActor.targetType.endsWith("worker")) {
63 await threadActor.attach({});
66 // Before fetching all sources, process existing ones.
67 // The ThreadActor is already up and running before this code runs
68 // and have sources already registered and for which newSource event already fired.
70 threadActor.sourcesManager.iter().map(s => {
71 const resource = s.form();
72 resource.resourceType = SOURCE;
77 // Requesting all sources should end up emitting newSource on threadActor.sourcesManager
78 threadActor.addAllSources();
82 * Stop watching for sources
85 if (this.sourcesManager) {
86 this.sourcesManager.off("newSource", this.onNewSource);
91 const resource = source.form();
92 resource.resourceType = SOURCE;
93 this.onAvailable([resource]);
97 module.exports = SourceWatcher;