OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2014 The Chromium Authors. All rights reserved. | 2 * Copyright 2014 The Chromium Authors. All rights reserved. |
3 * Use of this source code is governed by a BSD-style license that can be | 3 * Use of this source code is governed by a BSD-style license that can be |
4 * found in the LICENSE file. | 4 * found in the LICENSE file. |
5 */ | 5 */ |
6 | |
7 /** | 6 /** |
8 * @constructor | 7 * @unrestricted |
9 * @extends {WebInspector.Object} | |
10 */ | 8 */ |
11 WebInspector.TargetManager = function() | 9 WebInspector.TargetManager = class extends WebInspector.Object { |
12 { | 10 constructor() { |
13 WebInspector.Object.call(this); | 11 super(); |
14 /** @type {!Array.<!WebInspector.Target>} */ | 12 /** @type {!Array.<!WebInspector.Target>} */ |
15 this._targets = []; | 13 this._targets = []; |
16 /** @type {!Array.<!WebInspector.TargetManager.Observer>} */ | 14 /** @type {!Array.<!WebInspector.TargetManager.Observer>} */ |
17 this._observers = []; | 15 this._observers = []; |
18 this._observerCapabiliesMaskSymbol = Symbol("observerCapabilitiesMask"); | 16 this._observerCapabiliesMaskSymbol = Symbol('observerCapabilitiesMask'); |
19 /** @type {!Map<symbol, !Array<{modelClass: !Function, thisObject: (!Object|
undefined), listener: function(!WebInspector.Event)}>>} */ | 17 /** @type {!Map<symbol, !Array<{modelClass: !Function, thisObject: (!Object|
undefined), listener: function(!WebInspector.Event)}>>} */ |
20 this._modelListeners = new Map(); | 18 this._modelListeners = new Map(); |
21 this._isSuspended = false; | 19 this._isSuspended = false; |
| 20 } |
| 21 |
| 22 suspendAllTargets() { |
| 23 if (this._isSuspended) |
| 24 return; |
| 25 this._isSuspended = true; |
| 26 this.dispatchEventToListeners(WebInspector.TargetManager.Events.SuspendState
Changed); |
| 27 |
| 28 for (var i = 0; i < this._targets.length; ++i) { |
| 29 for (var model of this._targets[i].models()) |
| 30 model.suspendModel(); |
| 31 } |
| 32 } |
| 33 |
| 34 /** |
| 35 * @return {!Promise} |
| 36 */ |
| 37 resumeAllTargets() { |
| 38 if (!this._isSuspended) |
| 39 throw new Error('Not suspended'); |
| 40 this._isSuspended = false; |
| 41 this.dispatchEventToListeners(WebInspector.TargetManager.Events.SuspendState
Changed); |
| 42 |
| 43 var promises = []; |
| 44 for (var i = 0; i < this._targets.length; ++i) { |
| 45 for (var model of this._targets[i].models()) |
| 46 promises.push(model.resumeModel()); |
| 47 } |
| 48 return Promise.all(promises); |
| 49 } |
| 50 |
| 51 suspendAndResumeAllTargets() { |
| 52 this.suspendAllTargets(); |
| 53 this.resumeAllTargets(); |
| 54 } |
| 55 |
| 56 /** |
| 57 * @return {boolean} |
| 58 */ |
| 59 allTargetsSuspended() { |
| 60 return this._isSuspended; |
| 61 } |
| 62 |
| 63 /** |
| 64 * @return {string} |
| 65 */ |
| 66 inspectedURL() { |
| 67 return this._targets[0] ? this._targets[0].inspectedURL() : ''; |
| 68 } |
| 69 |
| 70 /** |
| 71 * @param {!WebInspector.TargetManager.Events} eventName |
| 72 * @param {!WebInspector.Event} event |
| 73 */ |
| 74 _redispatchEvent(eventName, event) { |
| 75 this.dispatchEventToListeners(eventName, event.data); |
| 76 } |
| 77 |
| 78 /** |
| 79 * @param {boolean=} bypassCache |
| 80 * @param {string=} injectedScript |
| 81 */ |
| 82 reloadPage(bypassCache, injectedScript) { |
| 83 if (!this._targets.length) |
| 84 return; |
| 85 |
| 86 var resourceTreeModel = WebInspector.ResourceTreeModel.fromTarget(this._targ
ets[0]); |
| 87 if (!resourceTreeModel) |
| 88 return; |
| 89 |
| 90 resourceTreeModel.reloadPage(bypassCache, injectedScript); |
| 91 } |
| 92 |
| 93 /** |
| 94 * @param {!Function} modelClass |
| 95 * @param {symbol} eventType |
| 96 * @param {function(!WebInspector.Event)} listener |
| 97 * @param {!Object=} thisObject |
| 98 */ |
| 99 addModelListener(modelClass, eventType, listener, thisObject) { |
| 100 for (var i = 0; i < this._targets.length; ++i) { |
| 101 var model = this._targets[i].model(modelClass); |
| 102 if (model) |
| 103 model.addEventListener(eventType, listener, thisObject); |
| 104 } |
| 105 if (!this._modelListeners.has(eventType)) |
| 106 this._modelListeners.set(eventType, []); |
| 107 this._modelListeners.get(eventType).push({modelClass: modelClass, thisObject
: thisObject, listener: listener}); |
| 108 } |
| 109 |
| 110 /** |
| 111 * @param {!Function} modelClass |
| 112 * @param {symbol} eventType |
| 113 * @param {function(!WebInspector.Event)} listener |
| 114 * @param {!Object=} thisObject |
| 115 */ |
| 116 removeModelListener(modelClass, eventType, listener, thisObject) { |
| 117 if (!this._modelListeners.has(eventType)) |
| 118 return; |
| 119 |
| 120 for (var i = 0; i < this._targets.length; ++i) { |
| 121 var model = this._targets[i].model(modelClass); |
| 122 if (model) |
| 123 model.removeEventListener(eventType, listener, thisObject); |
| 124 } |
| 125 |
| 126 var listeners = this._modelListeners.get(eventType); |
| 127 for (var i = 0; i < listeners.length; ++i) { |
| 128 if (listeners[i].modelClass === modelClass && listeners[i].listener === li
stener && |
| 129 listeners[i].thisObject === thisObject) |
| 130 listeners.splice(i--, 1); |
| 131 } |
| 132 if (!listeners.length) |
| 133 this._modelListeners.delete(eventType); |
| 134 } |
| 135 |
| 136 /** |
| 137 * @param {!WebInspector.TargetManager.Observer} targetObserver |
| 138 * @param {number=} capabilitiesMask |
| 139 */ |
| 140 observeTargets(targetObserver, capabilitiesMask) { |
| 141 if (this._observerCapabiliesMaskSymbol in targetObserver) |
| 142 throw new Error('Observer can only be registered once'); |
| 143 targetObserver[this._observerCapabiliesMaskSymbol] = capabilitiesMask || 0; |
| 144 this.targets(capabilitiesMask).forEach(targetObserver.targetAdded.bind(targe
tObserver)); |
| 145 this._observers.push(targetObserver); |
| 146 } |
| 147 |
| 148 /** |
| 149 * @param {!WebInspector.TargetManager.Observer} targetObserver |
| 150 */ |
| 151 unobserveTargets(targetObserver) { |
| 152 delete targetObserver[this._observerCapabiliesMaskSymbol]; |
| 153 this._observers.remove(targetObserver); |
| 154 } |
| 155 |
| 156 /** |
| 157 * @param {string} name |
| 158 * @param {number} capabilitiesMask |
| 159 * @param {!InspectorBackendClass.Connection.Factory} connectionFactory |
| 160 * @param {?WebInspector.Target} parentTarget |
| 161 * @return {!WebInspector.Target} |
| 162 */ |
| 163 createTarget(name, capabilitiesMask, connectionFactory, parentTarget) { |
| 164 var target = new WebInspector.Target(this, name, capabilitiesMask, connectio
nFactory, parentTarget); |
| 165 |
| 166 var logAgent = target.hasLogCapability() ? target.logAgent() : null; |
| 167 |
| 168 /** @type {!WebInspector.ConsoleModel} */ |
| 169 target.consoleModel = new WebInspector.ConsoleModel(target, logAgent); |
| 170 |
| 171 var networkManager = null; |
| 172 var resourceTreeModel = null; |
| 173 if (target.hasNetworkCapability()) |
| 174 networkManager = new WebInspector.NetworkManager(target); |
| 175 if (networkManager && target.hasDOMCapability()) { |
| 176 resourceTreeModel = new WebInspector.ResourceTreeModel( |
| 177 target, networkManager, WebInspector.SecurityOriginManager.fromTarget(
target)); |
| 178 new WebInspector.NetworkLog(target, resourceTreeModel, networkManager); |
| 179 } |
| 180 |
| 181 /** @type {!WebInspector.RuntimeModel} */ |
| 182 target.runtimeModel = new WebInspector.RuntimeModel(target); |
| 183 |
| 184 if (target.hasJSCapability()) |
| 185 new WebInspector.DebuggerModel(target); |
| 186 |
| 187 if (resourceTreeModel) { |
| 188 var domModel = new WebInspector.DOMModel(target); |
| 189 // TODO(eostroukhov) CSSModel should not depend on RTM |
| 190 new WebInspector.CSSModel(target, domModel); |
| 191 } |
| 192 |
| 193 /** @type {?WebInspector.SubTargetsManager} */ |
| 194 target.subTargetsManager = target.hasTargetCapability() ? new WebInspector.S
ubTargetsManager(target) : null; |
| 195 /** @type {!WebInspector.CPUProfilerModel} */ |
| 196 target.cpuProfilerModel = new WebInspector.CPUProfilerModel(target); |
| 197 /** @type {!WebInspector.HeapProfilerModel} */ |
| 198 target.heapProfilerModel = new WebInspector.HeapProfilerModel(target); |
| 199 |
| 200 target.tracingManager = new WebInspector.TracingManager(target); |
| 201 |
| 202 if (target.subTargetsManager && target.hasBrowserCapability()) |
| 203 target.serviceWorkerManager = new WebInspector.ServiceWorkerManager(target
, target.subTargetsManager); |
| 204 |
| 205 this.addTarget(target); |
| 206 return target; |
| 207 } |
| 208 |
| 209 /** |
| 210 * @param {!WebInspector.Target} target |
| 211 * @return {!Array<!WebInspector.TargetManager.Observer>} |
| 212 */ |
| 213 _observersForTarget(target) { |
| 214 return this._observers.filter( |
| 215 (observer) => target.hasAllCapabilities(observer[this._observerCapabilie
sMaskSymbol] || 0)); |
| 216 } |
| 217 |
| 218 /** |
| 219 * @param {!WebInspector.Target} target |
| 220 */ |
| 221 addTarget(target) { |
| 222 this._targets.push(target); |
| 223 var resourceTreeModel = WebInspector.ResourceTreeModel.fromTarget(target); |
| 224 if (this._targets.length === 1 && resourceTreeModel) { |
| 225 resourceTreeModel[WebInspector.TargetManager._listenersSymbol] = [ |
| 226 setupRedispatch.call( |
| 227 this, WebInspector.ResourceTreeModel.Events.MainFrameNavigated, |
| 228 WebInspector.TargetManager.Events.MainFrameNavigated), |
| 229 setupRedispatch.call(this, WebInspector.ResourceTreeModel.Events.Load, W
ebInspector.TargetManager.Events.Load), |
| 230 setupRedispatch.call( |
| 231 this, WebInspector.ResourceTreeModel.Events.PageReloadRequested, |
| 232 WebInspector.TargetManager.Events.PageReloadRequested), |
| 233 setupRedispatch.call( |
| 234 this, WebInspector.ResourceTreeModel.Events.WillReloadPage, |
| 235 WebInspector.TargetManager.Events.WillReloadPage) |
| 236 ]; |
| 237 } |
| 238 var copy = this._observersForTarget(target); |
| 239 for (var i = 0; i < copy.length; ++i) |
| 240 copy[i].targetAdded(target); |
| 241 |
| 242 for (var pair of this._modelListeners) { |
| 243 var listeners = pair[1]; |
| 244 for (var i = 0; i < listeners.length; ++i) { |
| 245 var model = target.model(listeners[i].modelClass); |
| 246 if (model) |
| 247 model.addEventListener(/** @type {symbol} */ (pair[0]), listeners[i].l
istener, listeners[i].thisObject); |
| 248 } |
| 249 } |
| 250 |
| 251 /** |
| 252 * @param {!WebInspector.ResourceTreeModel.Events} sourceEvent |
| 253 * @param {!WebInspector.TargetManager.Events} targetEvent |
| 254 * @return {!WebInspector.EventTarget.EventDescriptor} |
| 255 * @this {WebInspector.TargetManager} |
| 256 */ |
| 257 function setupRedispatch(sourceEvent, targetEvent) { |
| 258 return resourceTreeModel.addEventListener(sourceEvent, this._redispatchEve
nt.bind(this, targetEvent)); |
| 259 } |
| 260 } |
| 261 |
| 262 /** |
| 263 * @param {!WebInspector.Target} target |
| 264 */ |
| 265 removeTarget(target) { |
| 266 if (!this._targets.includes(target)) |
| 267 return; |
| 268 this._targets.remove(target); |
| 269 var resourceTreeModel = WebInspector.ResourceTreeModel.fromTarget(target); |
| 270 var treeModelListeners = resourceTreeModel && resourceTreeModel[WebInspector
.TargetManager._listenersSymbol]; |
| 271 if (treeModelListeners) |
| 272 WebInspector.EventTarget.removeEventListeners(treeModelListeners); |
| 273 |
| 274 var copy = this._observersForTarget(target); |
| 275 for (var i = 0; i < copy.length; ++i) |
| 276 copy[i].targetRemoved(target); |
| 277 |
| 278 for (var pair of this._modelListeners) { |
| 279 var listeners = pair[1]; |
| 280 for (var i = 0; i < listeners.length; ++i) { |
| 281 var model = target.model(listeners[i].modelClass); |
| 282 if (model) |
| 283 model.removeEventListener(/** @type {symbol} */ (pair[0]), listeners[i
].listener, listeners[i].thisObject); |
| 284 } |
| 285 } |
| 286 } |
| 287 |
| 288 /** |
| 289 * @param {number=} capabilitiesMask |
| 290 * @return {!Array.<!WebInspector.Target>} |
| 291 */ |
| 292 targets(capabilitiesMask) { |
| 293 if (!capabilitiesMask) |
| 294 return this._targets.slice(); |
| 295 else |
| 296 return this._targets.filter((target) => target.hasAllCapabilities(capabili
tiesMask || 0)); |
| 297 } |
| 298 |
| 299 /** |
| 300 * |
| 301 * @param {number} id |
| 302 * @return {?WebInspector.Target} |
| 303 */ |
| 304 targetById(id) { |
| 305 for (var i = 0; i < this._targets.length; ++i) { |
| 306 if (this._targets[i].id() === id) |
| 307 return this._targets[i]; |
| 308 } |
| 309 return null; |
| 310 } |
| 311 |
| 312 /** |
| 313 * @return {?WebInspector.Target} |
| 314 */ |
| 315 mainTarget() { |
| 316 return this._targets[0] || null; |
| 317 } |
| 318 |
| 319 /** |
| 320 * @param {!WebInspector.Target} target |
| 321 */ |
| 322 suspendReload(target) { |
| 323 var resourceTreeModel = WebInspector.ResourceTreeModel.fromTarget(target); |
| 324 if (resourceTreeModel) |
| 325 resourceTreeModel.suspendReload(); |
| 326 } |
| 327 |
| 328 /** |
| 329 * @param {!WebInspector.Target} target |
| 330 */ |
| 331 resumeReload(target) { |
| 332 var resourceTreeModel = WebInspector.ResourceTreeModel.fromTarget(target); |
| 333 if (resourceTreeModel) |
| 334 setImmediate(resourceTreeModel.resumeReload.bind(resourceTreeModel)); |
| 335 } |
| 336 |
| 337 /** |
| 338 * @param {function()} webSocketConnectionLostCallback |
| 339 */ |
| 340 connectToMainTarget(webSocketConnectionLostCallback) { |
| 341 this._webSocketConnectionLostCallback = webSocketConnectionLostCallback; |
| 342 this._connectAndCreateMainTarget(); |
| 343 } |
| 344 |
| 345 _connectAndCreateMainTarget() { |
| 346 var capabilities = WebInspector.Target.Capability.Browser | WebInspector.Tar
get.Capability.DOM | |
| 347 WebInspector.Target.Capability.JS | WebInspector.Target.Capability.Log | |
| 348 WebInspector.Target.Capability.Network | WebInspector.Target.Capability.
Target; |
| 349 if (Runtime.queryParam('isSharedWorker')) { |
| 350 capabilities = WebInspector.Target.Capability.Browser | WebInspector.Targe
t.Capability.Log | |
| 351 WebInspector.Target.Capability.Network | WebInspector.Target.Capabilit
y.Target; |
| 352 } else if (Runtime.queryParam('v8only')) { |
| 353 capabilities = WebInspector.Target.Capability.JS; |
| 354 } |
| 355 |
| 356 var target = |
| 357 this.createTarget(WebInspector.UIString('Main'), capabilities, this._cre
ateMainConnection.bind(this), null); |
| 358 target.runtimeAgent().runIfWaitingForDebugger(); |
| 359 } |
| 360 |
| 361 /** |
| 362 * @param {!InspectorBackendClass.Connection.Params} params |
| 363 * @return {!InspectorBackendClass.Connection} |
| 364 */ |
| 365 _createMainConnection(params) { |
| 366 if (Runtime.queryParam('ws')) { |
| 367 var ws = 'ws://' + Runtime.queryParam('ws'); |
| 368 this._mainConnection = new WebInspector.WebSocketConnection(ws, this._webS
ocketConnectionLostCallback, params); |
| 369 } else if (InspectorFrontendHost.isHostedMode()) { |
| 370 this._mainConnection = new WebInspector.StubConnection(params); |
| 371 } else { |
| 372 this._mainConnection = new WebInspector.MainConnection(params); |
| 373 } |
| 374 return this._mainConnection; |
| 375 } |
| 376 |
| 377 /** |
| 378 * @param {function(string)} onMessage |
| 379 * @return {!Promise<!InspectorBackendClass.Connection>} |
| 380 */ |
| 381 interceptMainConnection(onMessage) { |
| 382 var params = {onMessage: onMessage, onDisconnect: this._connectAndCreateMain
Target.bind(this)}; |
| 383 return this._mainConnection.disconnect().then(this._createMainConnection.bin
d(this, params)); |
| 384 } |
22 }; | 385 }; |
23 | 386 |
24 /** @enum {symbol} */ | 387 /** @enum {symbol} */ |
25 WebInspector.TargetManager.Events = { | 388 WebInspector.TargetManager.Events = { |
26 InspectedURLChanged: Symbol("InspectedURLChanged"), | 389 InspectedURLChanged: Symbol('InspectedURLChanged'), |
27 Load: Symbol("Load"), | 390 Load: Symbol('Load'), |
28 MainFrameNavigated: Symbol("MainFrameNavigated"), | 391 MainFrameNavigated: Symbol('MainFrameNavigated'), |
29 NameChanged: Symbol("NameChanged"), | 392 NameChanged: Symbol('NameChanged'), |
30 PageReloadRequested: Symbol("PageReloadRequested"), | 393 PageReloadRequested: Symbol('PageReloadRequested'), |
31 WillReloadPage: Symbol("WillReloadPage"), | 394 WillReloadPage: Symbol('WillReloadPage'), |
32 TargetDisposed: Symbol("TargetDisposed"), | 395 TargetDisposed: Symbol('TargetDisposed'), |
33 SuspendStateChanged: Symbol("SuspendStateChanged") | 396 SuspendStateChanged: Symbol('SuspendStateChanged') |
34 }; | 397 }; |
35 | 398 |
36 WebInspector.TargetManager._listenersSymbol = Symbol("WebInspector.TargetManager
.Listeners"); | 399 WebInspector.TargetManager._listenersSymbol = Symbol('WebInspector.TargetManager
.Listeners'); |
37 | |
38 WebInspector.TargetManager.prototype = { | |
39 suspendAllTargets: function() | |
40 { | |
41 if (this._isSuspended) | |
42 return; | |
43 this._isSuspended = true; | |
44 this.dispatchEventToListeners(WebInspector.TargetManager.Events.SuspendS
tateChanged); | |
45 | |
46 for (var i = 0; i < this._targets.length; ++i) { | |
47 for (var model of this._targets[i].models()) | |
48 model.suspendModel(); | |
49 } | |
50 }, | |
51 | |
52 /** | |
53 * @return {!Promise} | |
54 */ | |
55 resumeAllTargets: function() | |
56 { | |
57 if (!this._isSuspended) | |
58 throw new Error("Not suspended"); | |
59 this._isSuspended = false; | |
60 this.dispatchEventToListeners(WebInspector.TargetManager.Events.SuspendS
tateChanged); | |
61 | |
62 var promises = []; | |
63 for (var i = 0; i < this._targets.length; ++i) { | |
64 for (var model of this._targets[i].models()) | |
65 promises.push(model.resumeModel()); | |
66 } | |
67 return Promise.all(promises); | |
68 }, | |
69 | |
70 suspendAndResumeAllTargets: function() | |
71 { | |
72 this.suspendAllTargets(); | |
73 this.resumeAllTargets(); | |
74 }, | |
75 | |
76 /** | |
77 * @return {boolean} | |
78 */ | |
79 allTargetsSuspended: function() | |
80 { | |
81 return this._isSuspended; | |
82 }, | |
83 | |
84 /** | |
85 * @return {string} | |
86 */ | |
87 inspectedURL: function() | |
88 { | |
89 return this._targets[0] ? this._targets[0].inspectedURL() : ""; | |
90 }, | |
91 | |
92 /** | |
93 * @param {!WebInspector.TargetManager.Events} eventName | |
94 * @param {!WebInspector.Event} event | |
95 */ | |
96 _redispatchEvent: function(eventName, event) | |
97 { | |
98 this.dispatchEventToListeners(eventName, event.data); | |
99 }, | |
100 | |
101 /** | |
102 * @param {boolean=} bypassCache | |
103 * @param {string=} injectedScript | |
104 */ | |
105 reloadPage: function(bypassCache, injectedScript) | |
106 { | |
107 if (!this._targets.length) | |
108 return; | |
109 | |
110 var resourceTreeModel = WebInspector.ResourceTreeModel.fromTarget(this._
targets[0]); | |
111 if (!resourceTreeModel) | |
112 return; | |
113 | |
114 resourceTreeModel.reloadPage(bypassCache, injectedScript); | |
115 }, | |
116 | |
117 /** | |
118 * @param {!Function} modelClass | |
119 * @param {symbol} eventType | |
120 * @param {function(!WebInspector.Event)} listener | |
121 * @param {!Object=} thisObject | |
122 */ | |
123 addModelListener: function(modelClass, eventType, listener, thisObject) | |
124 { | |
125 for (var i = 0; i < this._targets.length; ++i) { | |
126 var model = this._targets[i].model(modelClass); | |
127 if (model) | |
128 model.addEventListener(eventType, listener, thisObject); | |
129 } | |
130 if (!this._modelListeners.has(eventType)) | |
131 this._modelListeners.set(eventType, []); | |
132 this._modelListeners.get(eventType).push({ modelClass: modelClass, thisO
bject: thisObject, listener: listener }); | |
133 }, | |
134 | |
135 /** | |
136 * @param {!Function} modelClass | |
137 * @param {symbol} eventType | |
138 * @param {function(!WebInspector.Event)} listener | |
139 * @param {!Object=} thisObject | |
140 */ | |
141 removeModelListener: function(modelClass, eventType, listener, thisObject) | |
142 { | |
143 if (!this._modelListeners.has(eventType)) | |
144 return; | |
145 | |
146 for (var i = 0; i < this._targets.length; ++i) { | |
147 var model = this._targets[i].model(modelClass); | |
148 if (model) | |
149 model.removeEventListener(eventType, listener, thisObject); | |
150 } | |
151 | |
152 var listeners = this._modelListeners.get(eventType); | |
153 for (var i = 0; i < listeners.length; ++i) { | |
154 if (listeners[i].modelClass === modelClass && listeners[i].listener
=== listener && listeners[i].thisObject === thisObject) | |
155 listeners.splice(i--, 1); | |
156 } | |
157 if (!listeners.length) | |
158 this._modelListeners.delete(eventType); | |
159 }, | |
160 | |
161 /** | |
162 * @param {!WebInspector.TargetManager.Observer} targetObserver | |
163 * @param {number=} capabilitiesMask | |
164 */ | |
165 observeTargets: function(targetObserver, capabilitiesMask) | |
166 { | |
167 if (this._observerCapabiliesMaskSymbol in targetObserver) | |
168 throw new Error("Observer can only be registered once"); | |
169 targetObserver[this._observerCapabiliesMaskSymbol] = capabilitiesMask ||
0; | |
170 this.targets(capabilitiesMask).forEach(targetObserver.targetAdded.bind(t
argetObserver)); | |
171 this._observers.push(targetObserver); | |
172 }, | |
173 | |
174 /** | |
175 * @param {!WebInspector.TargetManager.Observer} targetObserver | |
176 */ | |
177 unobserveTargets: function(targetObserver) | |
178 { | |
179 delete targetObserver[this._observerCapabiliesMaskSymbol]; | |
180 this._observers.remove(targetObserver); | |
181 }, | |
182 | |
183 /** | |
184 * @param {string} name | |
185 * @param {number} capabilitiesMask | |
186 * @param {!InspectorBackendClass.Connection.Factory} connectionFactory | |
187 * @param {?WebInspector.Target} parentTarget | |
188 * @return {!WebInspector.Target} | |
189 */ | |
190 createTarget: function(name, capabilitiesMask, connectionFactory, parentTarg
et) | |
191 { | |
192 var target = new WebInspector.Target(this, name, capabilitiesMask, conne
ctionFactory, parentTarget); | |
193 | |
194 var logAgent = target.hasLogCapability() ? target.logAgent() : null; | |
195 | |
196 /** @type {!WebInspector.ConsoleModel} */ | |
197 target.consoleModel = new WebInspector.ConsoleModel(target, logAgent); | |
198 | |
199 var networkManager = null; | |
200 var resourceTreeModel = null; | |
201 if (target.hasNetworkCapability()) | |
202 networkManager = new WebInspector.NetworkManager(target); | |
203 if (networkManager && target.hasDOMCapability()) { | |
204 resourceTreeModel = new WebInspector.ResourceTreeModel(target, netwo
rkManager, WebInspector.SecurityOriginManager.fromTarget(target)); | |
205 new WebInspector.NetworkLog(target, resourceTreeModel, networkManage
r); | |
206 } | |
207 | |
208 /** @type {!WebInspector.RuntimeModel} */ | |
209 target.runtimeModel = new WebInspector.RuntimeModel(target); | |
210 | |
211 if (target.hasJSCapability()) | |
212 new WebInspector.DebuggerModel(target); | |
213 | |
214 if (resourceTreeModel) { | |
215 var domModel = new WebInspector.DOMModel(target); | |
216 // TODO(eostroukhov) CSSModel should not depend on RTM | |
217 new WebInspector.CSSModel(target, domModel); | |
218 } | |
219 | |
220 /** @type {?WebInspector.SubTargetsManager} */ | |
221 target.subTargetsManager = target.hasTargetCapability() ? new WebInspect
or.SubTargetsManager(target) : null; | |
222 /** @type {!WebInspector.CPUProfilerModel} */ | |
223 target.cpuProfilerModel = new WebInspector.CPUProfilerModel(target); | |
224 /** @type {!WebInspector.HeapProfilerModel} */ | |
225 target.heapProfilerModel = new WebInspector.HeapProfilerModel(target); | |
226 | |
227 target.tracingManager = new WebInspector.TracingManager(target); | |
228 | |
229 if (target.subTargetsManager && target.hasBrowserCapability()) | |
230 target.serviceWorkerManager = new WebInspector.ServiceWorkerManager(
target, target.subTargetsManager); | |
231 | |
232 this.addTarget(target); | |
233 return target; | |
234 }, | |
235 | |
236 /** | |
237 * @param {!WebInspector.Target} target | |
238 * @return {!Array<!WebInspector.TargetManager.Observer>} | |
239 */ | |
240 _observersForTarget: function(target) | |
241 { | |
242 return this._observers.filter((observer) => target.hasAllCapabilities(ob
server[this._observerCapabiliesMaskSymbol] || 0)); | |
243 }, | |
244 | |
245 /** | |
246 * @param {!WebInspector.Target} target | |
247 */ | |
248 addTarget: function(target) | |
249 { | |
250 this._targets.push(target); | |
251 var resourceTreeModel = WebInspector.ResourceTreeModel.fromTarget(target
); | |
252 if (this._targets.length === 1 && resourceTreeModel) { | |
253 resourceTreeModel[WebInspector.TargetManager._listenersSymbol] = [ | |
254 setupRedispatch.call(this, WebInspector.ResourceTreeModel.Events
.MainFrameNavigated, WebInspector.TargetManager.Events.MainFrameNavigated), | |
255 setupRedispatch.call(this, WebInspector.ResourceTreeModel.Events
.Load, WebInspector.TargetManager.Events.Load), | |
256 setupRedispatch.call(this, WebInspector.ResourceTreeModel.Events
.PageReloadRequested, WebInspector.TargetManager.Events.PageReloadRequested), | |
257 setupRedispatch.call(this, WebInspector.ResourceTreeModel.Events
.WillReloadPage, WebInspector.TargetManager.Events.WillReloadPage) | |
258 ]; | |
259 } | |
260 var copy = this._observersForTarget(target); | |
261 for (var i = 0; i < copy.length; ++i) | |
262 copy[i].targetAdded(target); | |
263 | |
264 for (var pair of this._modelListeners) { | |
265 var listeners = pair[1]; | |
266 for (var i = 0; i < listeners.length; ++i) { | |
267 var model = target.model(listeners[i].modelClass); | |
268 if (model) | |
269 model.addEventListener(/** @type {symbol} */ (pair[0]), list
eners[i].listener, listeners[i].thisObject); | |
270 } | |
271 } | |
272 | |
273 /** | |
274 * @param {!WebInspector.ResourceTreeModel.Events} sourceEvent | |
275 * @param {!WebInspector.TargetManager.Events} targetEvent | |
276 * @return {!WebInspector.EventTarget.EventDescriptor} | |
277 * @this {WebInspector.TargetManager} | |
278 */ | |
279 function setupRedispatch(sourceEvent, targetEvent) | |
280 { | |
281 return resourceTreeModel.addEventListener(sourceEvent, this._redispa
tchEvent.bind(this, targetEvent)); | |
282 } | |
283 }, | |
284 | |
285 /** | |
286 * @param {!WebInspector.Target} target | |
287 */ | |
288 removeTarget: function(target) | |
289 { | |
290 if (!this._targets.includes(target)) | |
291 return; | |
292 this._targets.remove(target); | |
293 var resourceTreeModel = WebInspector.ResourceTreeModel.fromTarget(target
); | |
294 var treeModelListeners = resourceTreeModel && resourceTreeModel[WebInspe
ctor.TargetManager._listenersSymbol]; | |
295 if (treeModelListeners) | |
296 WebInspector.EventTarget.removeEventListeners(treeModelListeners); | |
297 | |
298 var copy = this._observersForTarget(target); | |
299 for (var i = 0; i < copy.length; ++i) | |
300 copy[i].targetRemoved(target); | |
301 | |
302 for (var pair of this._modelListeners) { | |
303 var listeners = pair[1]; | |
304 for (var i = 0; i < listeners.length; ++i) { | |
305 var model = target.model(listeners[i].modelClass); | |
306 if (model) | |
307 model.removeEventListener(/** @type {symbol} */ (pair[0]), l
isteners[i].listener, listeners[i].thisObject); | |
308 } | |
309 } | |
310 }, | |
311 | |
312 /** | |
313 * @param {number=} capabilitiesMask | |
314 * @return {!Array.<!WebInspector.Target>} | |
315 */ | |
316 targets: function(capabilitiesMask) | |
317 { | |
318 if (!capabilitiesMask) | |
319 return this._targets.slice(); | |
320 else | |
321 return this._targets.filter((target) => target.hasAllCapabilities(ca
pabilitiesMask || 0)); | |
322 }, | |
323 | |
324 /** | |
325 * | |
326 * @param {number} id | |
327 * @return {?WebInspector.Target} | |
328 */ | |
329 targetById: function(id) | |
330 { | |
331 for (var i = 0; i < this._targets.length; ++i) { | |
332 if (this._targets[i].id() === id) | |
333 return this._targets[i]; | |
334 } | |
335 return null; | |
336 }, | |
337 | |
338 /** | |
339 * @return {?WebInspector.Target} | |
340 */ | |
341 mainTarget: function() | |
342 { | |
343 return this._targets[0] || null; | |
344 }, | |
345 | |
346 /** | |
347 * @param {!WebInspector.Target} target | |
348 */ | |
349 suspendReload: function(target) | |
350 { | |
351 var resourceTreeModel = WebInspector.ResourceTreeModel.fromTarget(target
); | |
352 if (resourceTreeModel) | |
353 resourceTreeModel.suspendReload(); | |
354 }, | |
355 | |
356 /** | |
357 * @param {!WebInspector.Target} target | |
358 */ | |
359 resumeReload: function(target) | |
360 { | |
361 var resourceTreeModel = WebInspector.ResourceTreeModel.fromTarget(target
); | |
362 if (resourceTreeModel) | |
363 setImmediate(resourceTreeModel.resumeReload.bind(resourceTreeModel))
; | |
364 }, | |
365 | |
366 /** | |
367 * @param {function()} webSocketConnectionLostCallback | |
368 */ | |
369 connectToMainTarget: function(webSocketConnectionLostCallback) | |
370 { | |
371 this._webSocketConnectionLostCallback = webSocketConnectionLostCallback; | |
372 this._connectAndCreateMainTarget(); | |
373 }, | |
374 | |
375 _connectAndCreateMainTarget: function() | |
376 { | |
377 var capabilities = | |
378 WebInspector.Target.Capability.Browser | WebInspector.Target.Capabil
ity.DOM | | |
379 WebInspector.Target.Capability.JS | WebInspector.Target.Capability.L
og | | |
380 WebInspector.Target.Capability.Network | WebInspector.Target.Capabil
ity.Target; | |
381 if (Runtime.queryParam("isSharedWorker")) { | |
382 capabilities = | |
383 WebInspector.Target.Capability.Browser | WebInspector.Target.Cap
ability.Log | | |
384 WebInspector.Target.Capability.Network | WebInspector.Target.Cap
ability.Target; | |
385 } else if (Runtime.queryParam("v8only")) { | |
386 capabilities = WebInspector.Target.Capability.JS; | |
387 } | |
388 | |
389 var target = this.createTarget(WebInspector.UIString("Main"), capabiliti
es, this._createMainConnection.bind(this), null); | |
390 target.runtimeAgent().runIfWaitingForDebugger(); | |
391 }, | |
392 | |
393 /** | |
394 * @param {!InspectorBackendClass.Connection.Params} params | |
395 * @return {!InspectorBackendClass.Connection} | |
396 */ | |
397 _createMainConnection: function(params) | |
398 { | |
399 if (Runtime.queryParam("ws")) { | |
400 var ws = "ws://" + Runtime.queryParam("ws"); | |
401 this._mainConnection = new WebInspector.WebSocketConnection(ws, this
._webSocketConnectionLostCallback, params); | |
402 } else if (InspectorFrontendHost.isHostedMode()) { | |
403 this._mainConnection = new WebInspector.StubConnection(params); | |
404 } else { | |
405 this._mainConnection = new WebInspector.MainConnection(params); | |
406 } | |
407 return this._mainConnection; | |
408 }, | |
409 | |
410 /** | |
411 * @param {function(string)} onMessage | |
412 * @return {!Promise<!InspectorBackendClass.Connection>} | |
413 */ | |
414 interceptMainConnection: function(onMessage) | |
415 { | |
416 var params = { | |
417 onMessage: onMessage, | |
418 onDisconnect: this._connectAndCreateMainTarget.bind(this) | |
419 }; | |
420 return this._mainConnection.disconnect().then(this._createMainConnection
.bind(this, params)); | |
421 }, | |
422 | |
423 __proto__: WebInspector.Object.prototype | |
424 }; | |
425 | 400 |
426 /** | 401 /** |
427 * @interface | 402 * @interface |
428 */ | 403 */ |
429 WebInspector.TargetManager.Observer = function() | 404 WebInspector.TargetManager.Observer = function() {}; |
430 { | 405 |
| 406 WebInspector.TargetManager.Observer.prototype = { |
| 407 /** |
| 408 * @param {!WebInspector.Target} target |
| 409 */ |
| 410 targetAdded: function(target) {}, |
| 411 |
| 412 /** |
| 413 * @param {!WebInspector.Target} target |
| 414 */ |
| 415 targetRemoved: function(target) {}, |
431 }; | 416 }; |
432 | 417 |
433 WebInspector.TargetManager.Observer.prototype = { | |
434 /** | |
435 * @param {!WebInspector.Target} target | |
436 */ | |
437 targetAdded: function(target) { }, | |
438 | |
439 /** | |
440 * @param {!WebInspector.Target} target | |
441 */ | |
442 targetRemoved: function(target) { }, | |
443 }; | |
444 | |
445 /** | 418 /** |
446 * @type {!WebInspector.TargetManager} | 419 * @type {!WebInspector.TargetManager} |
447 */ | 420 */ |
448 WebInspector.targetManager = new WebInspector.TargetManager(); | 421 WebInspector.targetManager = new WebInspector.TargetManager(); |
OLD | NEW |