| OLD | NEW |
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 /** | 4 /** |
| 5 * @unrestricted | 5 * @unrestricted |
| 6 */ | 6 */ |
| 7 SDK.SubTargetsManager = class extends SDK.SDKModel { | 7 SDK.SubTargetsManager = class extends SDK.SDKModel { |
| 8 /** | 8 /** |
| 9 * @param {!SDK.Target} target | 9 * @param {!SDK.Target} target |
| 10 */ | 10 */ |
| 11 constructor(target) { | 11 constructor(target) { |
| 12 super(SDK.SubTargetsManager, target); | 12 super(SDK.SubTargetsManager, target); |
| 13 target.registerTargetDispatcher(new SDK.SubTargetsDispatcher(this)); | 13 target.registerTargetDispatcher(new SDK.SubTargetsDispatcher(this)); |
| 14 this._lastAnonymousTargetId = 0; | 14 this._lastAnonymousTargetId = 0; |
| 15 this._agent = target.targetAgent(); | 15 this._agent = target.targetAgent(); |
| 16 | 16 |
| 17 /** @type {!Map<string, !SDK.Target>} */ | 17 /** @type {!Map<string, !SDK.Target>} */ |
| 18 this._attachedTargets = new Map(); | 18 this._attachedTargets = new Map(); |
| 19 /** @type {!Map<string, !SDK.SubTargetConnection>} */ | 19 /** @type {!Map<string, !SDK.SubTargetConnection>} */ |
| 20 this._connections = new Map(); | 20 this._connections = new Map(); |
| 21 /** @type {!Map<string, !SDK.PendingTarget>} */ | 21 |
| 22 this._pendingTargets = new Map(); | 22 /** @type {!Set<string>} */ |
| 23 this._nodeTargetIds = new Set(); |
| 24 |
| 23 this._agent.setAutoAttach(true /* autoAttach */, true /* waitForDebuggerOnSt
art */); | 25 this._agent.setAutoAttach(true /* autoAttach */, true /* waitForDebuggerOnSt
art */); |
| 24 if (Runtime.experiments.isEnabled('autoAttachToCrossProcessSubframes')) | 26 if (Runtime.experiments.isEnabled('autoAttachToCrossProcessSubframes')) |
| 25 this._agent.setAttachToFrames(true); | 27 this._agent.setAttachToFrames(true); |
| 26 | 28 |
| 27 if (Runtime.experiments.isEnabled('nodeDebugging') && !target.parentTarget()
) { | 29 if (!target.parentTarget()) { |
| 28 var defaultLocations = [{host: 'localhost', port: 9229}]; | 30 var defaultLocations = [{host: 'localhost', port: 9229}]; |
| 29 this._agent.setRemoteLocations(defaultLocations); | 31 this._agent.setRemoteLocations(defaultLocations); |
| 30 this._agent.setDiscoverTargets(true); | 32 this._agent.setDiscoverTargets(true); |
| 31 } | 33 } |
| 32 SDK.targetManager.addEventListener(SDK.TargetManager.Events.MainFrameNavigat
ed, this._mainFrameNavigated, this); | 34 SDK.targetManager.addEventListener(SDK.TargetManager.Events.MainFrameNavigat
ed, this._mainFrameNavigated, this); |
| 33 } | 35 } |
| 34 | 36 |
| 35 /** | 37 /** |
| 36 * @param {!SDK.Target} target | 38 * @param {!SDK.Target} target |
| 37 * @return {?SDK.SubTargetsManager} | 39 * @return {?SDK.SubTargetsManager} |
| 38 */ | 40 */ |
| 39 static fromTarget(target) { | 41 static fromTarget(target) { |
| 40 return target.model(SDK.SubTargetsManager); | 42 return target.model(SDK.SubTargetsManager); |
| 41 } | 43 } |
| 42 | 44 |
| 43 /** | 45 /** |
| 46 * @return {number} |
| 47 */ |
| 48 availableNodeTargetsCount() { |
| 49 return this._nodeTargetIds.size; |
| 50 } |
| 51 |
| 52 /** |
| 44 * @override | 53 * @override |
| 45 * @return {!Promise} | 54 * @return {!Promise} |
| 46 */ | 55 */ |
| 47 suspendModel() { | 56 suspendModel() { |
| 48 var fulfill; | 57 var fulfill; |
| 49 var promise = new Promise(f => fulfill = f); | 58 var promise = new Promise(f => fulfill = f); |
| 50 this._agent.setAutoAttach(true /* autoAttach */, false /* waitForDebuggerOnS
tart */, fulfill); | 59 this._agent.setAutoAttach(true /* autoAttach */, false /* waitForDebuggerOnS
tart */, fulfill); |
| 51 return promise; | 60 return promise; |
| 52 } | 61 } |
| 53 | 62 |
| 54 /** | 63 /** |
| 55 * @override | 64 * @override |
| 56 * @return {!Promise} | 65 * @return {!Promise} |
| 57 */ | 66 */ |
| 58 resumeModel() { | 67 resumeModel() { |
| 59 var fulfill; | 68 var fulfill; |
| 60 var promise = new Promise(f => fulfill = f); | 69 var promise = new Promise(f => fulfill = f); |
| 61 this._agent.setAutoAttach(true /* autoAttach */, true /* waitForDebuggerOnSt
art */, fulfill); | 70 this._agent.setAutoAttach(true /* autoAttach */, true /* waitForDebuggerOnSt
art */, fulfill); |
| 62 return promise; | 71 return promise; |
| 63 } | 72 } |
| 64 | 73 |
| 65 /** | 74 /** |
| 66 * @override | 75 * @override |
| 67 */ | 76 */ |
| 68 dispose() { | 77 dispose() { |
| 69 for (var attachedTargetId of this._attachedTargets.keys()) | 78 for (var attachedTargetId of this._attachedTargets.keys()) |
| 70 this._detachedFromTarget(attachedTargetId); | 79 this._detachedFromTarget(attachedTargetId); |
| 71 for (var pendingConnectionId of this._pendingTargets.keys()) | |
| 72 this._targetDestroyed(pendingConnectionId); | |
| 73 } | 80 } |
| 74 | 81 |
| 75 /** | 82 /** |
| 76 * @param {!Protocol.Target.TargetID} targetId | 83 * @param {!Protocol.Target.TargetID} targetId |
| 77 */ | 84 */ |
| 78 activateTarget(targetId) { | 85 activateTarget(targetId) { |
| 79 this._agent.activateTarget(targetId); | 86 this._agent.activateTarget(targetId); |
| 80 } | 87 } |
| 81 | 88 |
| 82 /** | 89 /** |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 153 this.target()); | 160 this.target()); |
| 154 target[SDK.SubTargetsManager._InfoSymbol] = targetInfo; | 161 target[SDK.SubTargetsManager._InfoSymbol] = targetInfo; |
| 155 this._attachedTargets.set(targetInfo.id, target); | 162 this._attachedTargets.set(targetInfo.id, target); |
| 156 | 163 |
| 157 // Only pause new worker if debugging SW - we are going through the pause on
start checkbox. | 164 // Only pause new worker if debugging SW - we are going through the pause on
start checkbox. |
| 158 var mainIsServiceWorker = | 165 var mainIsServiceWorker = |
| 159 !this.target().parentTarget() && this.target().hasTargetCapability() &&
!this.target().hasBrowserCapability(); | 166 !this.target().parentTarget() && this.target().hasTargetCapability() &&
!this.target().hasBrowserCapability(); |
| 160 if (mainIsServiceWorker && waitingForDebugger) | 167 if (mainIsServiceWorker && waitingForDebugger) |
| 161 target.debuggerAgent().pause(); | 168 target.debuggerAgent().pause(); |
| 162 target.runtimeAgent().runIfWaitingForDebugger(); | 169 target.runtimeAgent().runIfWaitingForDebugger(); |
| 163 | |
| 164 var pendingTarget = this._pendingTargets.get(targetInfo.id); | |
| 165 if (!pendingTarget) { | |
| 166 this._targetCreated(targetInfo); | |
| 167 pendingTarget = this._pendingTargets.get(targetInfo.id); | |
| 168 } | |
| 169 pendingTarget.notifyAttached(target); | |
| 170 this.dispatchEventToListeners(SDK.SubTargetsManager.Events.PendingTargetAtta
ched, pendingTarget); | |
| 171 } | 170 } |
| 172 | 171 |
| 173 /** | 172 /** |
| 174 * @param {string} targetId | 173 * @param {string} targetId |
| 175 * @param {!Protocol.InspectorBackend.Connection.Params} params | 174 * @param {!Protocol.InspectorBackend.Connection.Params} params |
| 176 * @return {!Protocol.InspectorBackend.Connection} | 175 * @return {!Protocol.InspectorBackend.Connection} |
| 177 */ | 176 */ |
| 178 _createConnection(targetId, params) { | 177 _createConnection(targetId, params) { |
| 179 var connection = new SDK.SubTargetConnection(this._agent, targetId, params); | 178 var connection = new SDK.SubTargetConnection(this._agent, targetId, params); |
| 180 this._connections.set(targetId, connection); | 179 this._connections.set(targetId, connection); |
| 181 return connection; | 180 return connection; |
| 182 } | 181 } |
| 183 | 182 |
| 184 /** | 183 /** |
| 185 * @param {string} targetId | 184 * @param {string} targetId |
| 186 */ | 185 */ |
| 187 _detachedFromTarget(targetId) { | 186 _detachedFromTarget(targetId) { |
| 188 this._attachedTargets.delete(targetId); | 187 this._attachedTargets.delete(targetId); |
| 189 var connection = this._connections.get(targetId); | 188 var connection = this._connections.get(targetId); |
| 190 connection._onDisconnect.call(null, 'target terminated'); | 189 connection._onDisconnect.call(null, 'target terminated'); |
| 191 this._connections.delete(targetId); | 190 this._connections.delete(targetId); |
| 192 this.dispatchEventToListeners( | |
| 193 SDK.SubTargetsManager.Events.PendingTargetDetached, this._pendingTargets
.get(targetId)); | |
| 194 } | 191 } |
| 195 | 192 |
| 196 /** | 193 /** |
| 197 * @param {string} targetId | 194 * @param {string} targetId |
| 198 * @param {string} message | 195 * @param {string} message |
| 199 */ | 196 */ |
| 200 _receivedMessageFromTarget(targetId, message) { | 197 _receivedMessageFromTarget(targetId, message) { |
| 201 var connection = this._connections.get(targetId); | 198 var connection = this._connections.get(targetId); |
| 202 if (connection) | 199 if (connection) |
| 203 connection._onMessage.call(null, message); | 200 connection._onMessage.call(null, message); |
| 204 } | 201 } |
| 205 | 202 |
| 206 /** | 203 /** |
| 207 * @param {!SDK.TargetInfo} targetInfo | 204 * @param {!SDK.TargetInfo} targetInfo |
| 208 */ | 205 */ |
| 209 _targetCreated(targetInfo) { | 206 _targetCreated(targetInfo) { |
| 210 var pendingTarget = this._pendingTargets.get(targetInfo.id); | 207 if (targetInfo.type !== 'node') |
| 211 if (pendingTarget) | |
| 212 return; | 208 return; |
| 213 pendingTarget = new SDK.PendingTarget(targetInfo.id, targetInfo.title, targe
tInfo.type === 'node', this); | 209 if (Runtime.queryParam('nodeFrontend')) { |
| 214 this._pendingTargets.set(targetInfo.id, pendingTarget); | 210 this._agent.attachToTarget(targetInfo.id); |
| 215 this.dispatchEventToListeners(SDK.SubTargetsManager.Events.PendingTargetAdde
d, pendingTarget); | 211 } else { |
| 212 this._nodeTargetIds.add(targetInfo.id); |
| 213 this.dispatchEventToListeners(SDK.SubTargetsManager.Events.AvailableNodeTa
rgetsChanged); |
| 214 } |
| 216 } | 215 } |
| 217 | 216 |
| 218 /** | 217 /** |
| 219 * @param {string} targetId | 218 * @param {string} targetId |
| 220 */ | 219 */ |
| 221 _targetDestroyed(targetId) { | 220 _targetDestroyed(targetId) { |
| 222 var pendingTarget = this._pendingTargets.get(targetId); | 221 if (Runtime.queryParam('nodeFrontend') || !this._nodeTargetIds.has(targetId)
) |
| 223 if (!pendingTarget) | |
| 224 return; | 222 return; |
| 225 this._pendingTargets.delete(targetId); | 223 this._nodeTargetIds.delete(targetId); |
| 226 this.dispatchEventToListeners(SDK.SubTargetsManager.Events.PendingTargetRemo
ved, pendingTarget); | 224 this.dispatchEventToListeners(SDK.SubTargetsManager.Events.AvailableNodeTarg
etsChanged); |
| 227 } | 225 } |
| 228 | 226 |
| 229 /** | 227 /** |
| 230 * @return {!Array<!SDK.PendingTarget>} | |
| 231 */ | |
| 232 pendingTargets() { | |
| 233 return this._pendingTargets.valuesArray(); | |
| 234 } | |
| 235 | |
| 236 /** | |
| 237 * @param {!Common.Event} event | 228 * @param {!Common.Event} event |
| 238 */ | 229 */ |
| 239 _mainFrameNavigated(event) { | 230 _mainFrameNavigated(event) { |
| 240 if (event.data.target() !== this.target()) | 231 if (event.data.target() !== this.target()) |
| 241 return; | 232 return; |
| 242 | 233 |
| 243 var idsToDetach = []; | 234 var idsToDetach = []; |
| 244 for (var targetId of this._attachedTargets.keys()) { | 235 for (var targetId of this._attachedTargets.keys()) { |
| 245 var target = this._attachedTargets.get(targetId); | 236 var target = this._attachedTargets.get(targetId); |
| 246 var targetInfo = this.targetInfo(target); | 237 var targetInfo = this.targetInfo(target); |
| 247 if (targetInfo.type === 'worker') | 238 if (targetInfo.type === 'worker') |
| 248 idsToDetach.push(targetId); | 239 idsToDetach.push(targetId); |
| 249 } | 240 } |
| 250 idsToDetach.forEach(id => this._detachedFromTarget(id)); | 241 idsToDetach.forEach(id => this._detachedFromTarget(id)); |
| 251 } | 242 } |
| 252 }; | 243 }; |
| 253 | 244 |
| 254 /** @enum {symbol} */ | 245 /** @enum {symbol} */ |
| 255 SDK.SubTargetsManager.Events = { | 246 SDK.SubTargetsManager.Events = { |
| 256 PendingTargetAdded: Symbol('PendingTargetAdded'), | 247 AvailableNodeTargetsChanged: Symbol('AvailableNodeTargetsChanged'), |
| 257 PendingTargetRemoved: Symbol('PendingTargetRemoved'), | |
| 258 PendingTargetAttached: Symbol('PendingTargetAttached'), | |
| 259 PendingTargetDetached: Symbol('PendingTargetDetached'), | |
| 260 }; | 248 }; |
| 261 | 249 |
| 262 SDK.SubTargetsManager._InfoSymbol = Symbol('SubTargetInfo'); | 250 SDK.SubTargetsManager._InfoSymbol = Symbol('SubTargetInfo'); |
| 263 | 251 |
| 264 /** | 252 /** |
| 265 * @implements {Protocol.TargetDispatcher} | 253 * @implements {Protocol.TargetDispatcher} |
| 266 * @unrestricted | 254 * @unrestricted |
| 267 */ | 255 */ |
| 268 SDK.SubTargetsDispatcher = class { | 256 SDK.SubTargetsDispatcher = class { |
| 269 /** | 257 /** |
| (...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 363 this.type = payload.type; | 351 this.type = payload.type; |
| 364 this.canActivate = this.type === 'page' || this.type === 'iframe'; | 352 this.canActivate = this.type === 'page' || this.type === 'iframe'; |
| 365 if (this.type === 'node') | 353 if (this.type === 'node') |
| 366 this.title = Common.UIString('Node: %s', this.url); | 354 this.title = Common.UIString('Node: %s', this.url); |
| 367 else if (this.type === 'page' || this.type === 'iframe') | 355 else if (this.type === 'page' || this.type === 'iframe') |
| 368 this.title = payload.title; | 356 this.title = payload.title; |
| 369 else | 357 else |
| 370 this.title = Common.UIString('Worker: %s', this.url); | 358 this.title = Common.UIString('Worker: %s', this.url); |
| 371 } | 359 } |
| 372 }; | 360 }; |
| 373 | |
| 374 /** | |
| 375 * @unrestricted | |
| 376 */ | |
| 377 SDK.PendingTarget = class { | |
| 378 /** | |
| 379 * @param {string} id | |
| 380 * @param {string} title | |
| 381 * @param {boolean} canConnect | |
| 382 * @param {?SDK.SubTargetsManager} manager | |
| 383 */ | |
| 384 constructor(id, title, canConnect, manager) { | |
| 385 this._id = id; | |
| 386 this._title = title; | |
| 387 this._isRemote = canConnect; | |
| 388 this._manager = manager; | |
| 389 /** @type {?Promise} */ | |
| 390 this._connectPromise = null; | |
| 391 /** @type {?Function} */ | |
| 392 this._attachedCallback = null; | |
| 393 } | |
| 394 | |
| 395 /** | |
| 396 * @return {string} | |
| 397 */ | |
| 398 id() { | |
| 399 return this._id; | |
| 400 } | |
| 401 | |
| 402 /** | |
| 403 * @return {?SDK.Target} | |
| 404 */ | |
| 405 target() { | |
| 406 if (!this._manager) | |
| 407 return null; | |
| 408 return this._manager.targetForId(this.id()); | |
| 409 } | |
| 410 | |
| 411 /** | |
| 412 * @return {string} | |
| 413 */ | |
| 414 name() { | |
| 415 return this._title; | |
| 416 } | |
| 417 | |
| 418 /** | |
| 419 * @return {!Promise} | |
| 420 */ | |
| 421 attach() { | |
| 422 if (!this._manager) | |
| 423 return Promise.reject(); | |
| 424 if (this._connectPromise) | |
| 425 return this._connectPromise; | |
| 426 if (this.target()) | |
| 427 return Promise.resolve(this.target()); | |
| 428 this._connectPromise = new Promise(resolve => { | |
| 429 this._attachedCallback = resolve; | |
| 430 this._manager._agent.attachToTarget(this.id()); | |
| 431 }); | |
| 432 return this._connectPromise; | |
| 433 } | |
| 434 | |
| 435 /** | |
| 436 * @return {!Promise} | |
| 437 */ | |
| 438 detach() { | |
| 439 if (this._manager) | |
| 440 this._manager._agent.detachFromTarget(this.id()); | |
| 441 return Promise.resolve(); | |
| 442 } | |
| 443 | |
| 444 /** | |
| 445 * @param {!SDK.Target} target | |
| 446 */ | |
| 447 notifyAttached(target) { | |
| 448 if (this._attachedCallback) | |
| 449 this._attachedCallback(target); | |
| 450 this._connectPromise = null; | |
| 451 this._attachedCallback = null; | |
| 452 } | |
| 453 | |
| 454 /** | |
| 455 * @return {boolean} | |
| 456 */ | |
| 457 canConnect() { | |
| 458 return this._isRemote; | |
| 459 } | |
| 460 }; | |
| OLD | NEW |