1# How actors are organized
2
3To start with, actors are living within devtools/server/actors folder.
4They are organized in a hierarchy for easier lifecycle and memory management:
5once a parent is removed from the pool, its children are removed as well.
6(See actor-registration.md for more information about how to implement one)
7
8The overall hierarchy of actors looks like this:
9
10```
11RootActor: First one, automatically instantiated when we start connecting.
12   |       Mostly meant to instantiate new actors.
13   |
14   |-- Global-scoped actors:
15   |   Actors exposing features related to the main process, that are not
16   |   specific to any particular target (document, tab, add-on, or worker).
17   |   These actors are registered with `global: true` in
18   |   devtools/server/main.js.
19   |   Examples include:
20   |   PreferenceActor (for Firefox prefs)
21   |
22   \-- Target actors:
23       Actors that represent the main "thing" being targeted by a given toolbox,
24       such as a tab, frame, worker, add-on, etc. and track its lifetime.
25       Generally, there is a target actor for each thing you can point a
26       toolbox at.
27       Examples include:
28       FrameTargetActor (for a frame, such as a tab)
29       WorkerTargetActor (for various kind of workers)
30       |
31       \-- Target-scoped actors:
32           Actors exposing one particular feature set. They are children of a
33           given target actor and the data they return is filtered to reflect
34           the target.
35           These actors are registered with `target: true` in
36           devtools/server/main.js.
37           Examples include:
38           WebConsoleActor
39           InspectorActor
40           These actors may extend this hierarchy by having their own children,
41           like LongStringActor, WalkerActor, etc.
42```
43
44## RootActor
45
46The root actor is special. It is automatically created when a client connects.
47It has a special `actorID` which is unique and is "root".
48All other actors have an `actorID` which is computed dynamically,
49so that you need to ask an existing actor to create an Actor
50and returns its `actorID`. That's the main role of RootActor.
51
52```
53RootActor (root.js)
54   |
55   |-- TabDescriptorActor (descriptors/tab.js)
56   |   Targets frames (such as a tab) living in the parent or child process.
57   |   Note that this is just a proxy for FrameTargetActor, which is loaded via
58   |   the frame's message manager as a frame script in the process containing
59   |   the frame content. This proxy via message manager is always used, even
60   |   when the content happens to be in the same process.
61   |   Returned by "listTabs" or "getTab" requests.
62   |   |
63   |   \-- FrameTargetActor (frame.js)
64   |       The "real" target actor for a frame (such as a tab) which runs in
65   |       whichever process holds the content. FrameTargetActorProxy
66   |       communicates with this via the frame's message manager.
67   |       Extends the abstract class BrowsingContextTargetActor.
68   |       Returned by "connect" server method on FrameTargetActorProxy.
69   |
70   |-- WorkerTargetActor (worker.js)
71   |   Targets a worker (applies to various kinds like web worker, service
72   |   worker, etc.).
73   |   Returned by "listWorkers" request to the root actor to get all workers.
74   |   Returned by "listWorkers" request to a FrameTargetActorProxy to get
75   |   workers for a specific frame.
76   |   Returned by "listWorkers" request to a ContentProcessTargetActor to get
77   |   workers for the chrome of the child process.
78   |
79   |-- ChromeWindowTargetActor (chrome-window.js)
80   |   Targets a single window, such as a browser window in Firefox, but it can
81   |   be used to reach any window in the parent process.
82   |   Extends the abstract class BrowsingContextTargetActor.
83   |   Returned by "getWindow" request to the root actor.
84   |
85   |-- ParentProcessTargetActor (parent-process.js)
86   |   Targets all resources in the parent process of Firefox (chrome documents,
87   |   JSMs, JS XPCOM, etc.).
88   |   Extends the abstract class BrowsingContextTargetActor.
89   |   Extended by WebExtensionTargetActor.
90   |   Returned by "getProcess" request without any argument.
91   |
92   |-- ContentProcessTargetActor (content-process.js)
93   |   Targets all resources in a content process of Firefox (chrome sandboxes,
94   |   frame scripts, documents, etc.)
95   |   Returned by "getProcess" request with a id argument, matching the
96   |   targeted process.
97   |
98   \-- WebExtensionActor (addon/webextension.js)
99       Represents a WebExtension add-on in the parent process. This gives some
100       metadata about the add-on and watches for uninstall events. This uses a
101       proxy to access the actual WebExtension in the WebExtension process via
102       the message manager.
103       Returned by "listAddons" request.
104       |
105       \-- WebExtensionTargetActor (targets/webextension.js)
106           Targets a WebExtension add-on. This runs in the WebExtension process.
107           The client issues an additional "connect" request to
108           WebExtensionActor to get this actor, which is different from the
109           approach used for frame target actors.
110           Extends ParentProcessTargetActor.
111           Returned by "connect" request to WebExtensionActor.
112```
113
114## Target Actors
115
116Those are the actors exposed by the root actors which are meant to track the
117lifetime of a given target: tab, process, add-on, or worker. It also allows to
118fetch the target-scoped actors connected to this target, which are actors like
119console, inspector, thread (for debugger), style inspector, etc.
120
121Some target actors inherit from BrowsingContextTargetActor (defined in
122browsing-context.js) which is meant for "browsing contexts" which present
123documents to the user. It automatically tracks the lifetime of the targeted
124browsing context, but it also tracks its iframes and allows switching the
125target to one of its iframes.
126
127For historical reasons, target actors also handle creating the ThreadActor, used
128to manage breakpoints in the debugger. Actors inheriting from
129BrowsingContextTargetActor expose `attach`/`detach` requests, that allows to
130start/stop the ThreadActor.
131
132Target-scoped actors are accessed via the target actor's RDP form which contains
133the `actorID` for each target-scoped actor.
134
135The target-scoped actors expect to find the following properties on the target
136actor:
137 - threadActor:
138   ThreadActor instance for the given target,
139   only defined once `attach` request is called, or on construction.
140 - isRootActor: (historical name)
141   Always false, except on ParentProcessTargetActor.
142   Despite the attribute name, it is being used to accept all resources
143   (like chrome one) instead of limiting only to content resources.
144 - makeDebugger:
145   Helper function used to create Debugger object for the target.
146   (See actors/utils/make-debugger.js for more info)
147
148In addition to this, the actors inheriting from BrowsingContextTargetActor,
149expose many other attributes and events:
150 - window:
151   Reference to the window global object currently targeted.
152   It can change over time if we switch target to an iframe, so it
153   shouldn't be stored in a variable, but always retrieved from the actor.
154 - windows:
155   List of all document globals including the main window object and all
156   iframes.
157 - docShell:
158   Primary docShell reference for the targeted document.
159 - docShells:
160   List of all docShells for the targeted document and all its iframes.
161 - chromeEventHandler:
162   The chrome event handler for the current target. Allows to listen to events
163   that can be missing/cancelled on this document itself.
164
165See BrowsingContextTargetActor documentation for more details.
166
167## Target-scoped actors
168
169Each of these actors focuses on providing one particular feature set. They are
170children of a given target actor.
171
172The data they return is filtered to reflect the target. For example, the
173InspectorActor that you fetch from a FrameTargetActor gives you information
174about the markup and styles for only that frame.
175
176These actors may extend this hierarchy by having their own children, like
177LongStringActor, WalkerActor, etc.
178
179To improve performance, target-scoped actors are created lazily. The target
180actor lists the actor ID for each one, but the actor modules aren't actually
181loaded and instantiated at that point. Once the first request for a given
182target-scoped actor is received by the server, that specific actor is
183instantiated just in time to service the request.
184