Chromium Code Reviews| 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 WebInspector.SubTargetsManager = class extends WebInspector.SDKModel { | 7 WebInspector.SubTargetsManager = class extends WebInspector.SDKModel { |
| 8 /** | 8 /** |
| 9 * @param {!WebInspector.Target} target | 9 * @param {!WebInspector.Target} target |
| 10 */ | 10 */ |
| 11 constructor(target) { | 11 constructor(target) { |
| 12 super(WebInspector.SubTargetsManager, target); | 12 super(WebInspector.SubTargetsManager, target); |
| 13 target.registerTargetDispatcher(new WebInspector.SubTargetsDispatcher(this)) ; | 13 target.registerTargetDispatcher(new WebInspector.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, !WebInspector.Target>} */ | 17 /** @type {!Map<string, !WebInspector.Target>} */ |
| 18 this._attachedTargets = new Map(); | 18 this._attachedTargets = new Map(); |
| 19 /** @type {!Map<string, !WebInspector.SubTargetConnection>} */ | 19 /** @type {!Map<string, !WebInspector.SubTargetConnection>} */ |
| 20 this._connections = new Map(); | 20 this._connections = new Map(); |
| 21 | 21 /** @type {!Map<string, !WebInspector.PendingTarget>} */ |
| 22 this._pendingTargets = new Map(); | |
| 22 this._agent.setAutoAttach(true /* autoAttach */, true /* waitForDebuggerOnSt art */); | 23 this._agent.setAutoAttach(true /* autoAttach */, true /* waitForDebuggerOnSt art */); |
| 23 if (Runtime.experiments.isEnabled('autoAttachToCrossProcessSubframes')) | 24 if (Runtime.experiments.isEnabled('autoAttachToCrossProcessSubframes')) |
| 24 this._agent.setAttachToFrames(true); | 25 this._agent.setAttachToFrames(true); |
| 25 | 26 |
| 26 if (Runtime.experiments.isEnabled('nodeDebugging') && !target.parentTarget() ) { | 27 if (Runtime.experiments.isEnabled('nodeDebugging') && !target.parentTarget() ) { |
| 27 var defaultLocations = [{host: 'localhost', port: 9229}]; | 28 var defaultLocations = [{host: 'localhost', port: 9229}]; |
| 28 this._agent.setRemoteLocations(defaultLocations); | 29 this._agent.setRemoteLocations(defaultLocations); |
| 29 this._agent.setDiscoverTargets(true); | 30 this._agent.setDiscoverTargets(true); |
| 30 } | 31 } |
| 31 WebInspector.targetManager.addEventListener( | 32 WebInspector.targetManager.addEventListener( |
| 32 WebInspector.TargetManager.Events.MainFrameNavigated, this._mainFrameNav igated, this); | 33 WebInspector.TargetManager.Events.MainFrameNavigated, this._mainFrameNav igated, this); |
| 33 } | 34 } |
| 34 | 35 |
| 35 /** | 36 /** |
| 37 * @param {!WebInspector.Target} target | |
| 38 * @return {?WebInspector.SubTargetsManager} | |
| 39 */ | |
| 40 static fromTarget(target) | |
| 41 { | |
| 42 return /** @type {?WebInspector.SubTargetsManager} */ (target.model(WebInspe ctor.SubTargetsManager)); | |
| 43 } | |
| 44 | |
| 45 /** | |
| 36 * @override | 46 * @override |
| 37 * @return {!Promise} | 47 * @return {!Promise} |
| 38 */ | 48 */ |
| 39 suspendModel() { | 49 suspendModel() { |
| 40 var fulfill; | 50 var fulfill; |
| 41 var promise = new Promise(f => fulfill = f); | 51 var promise = new Promise(f => fulfill = f); |
| 42 this._agent.setAutoAttach(true /* autoAttach */, false /* waitForDebuggerOnS tart */, fulfill); | 52 this._agent.setAutoAttach(true /* autoAttach */, false /* waitForDebuggerOnS tart */, fulfill); |
| 43 return promise; | 53 return promise; |
| 44 } | 54 } |
| 45 | 55 |
| 46 /** | 56 /** |
| 47 * @override | 57 * @override |
| 48 * @return {!Promise} | 58 * @return {!Promise} |
| 49 */ | 59 */ |
| 50 resumeModel() { | 60 resumeModel() { |
| 51 var fulfill; | 61 var fulfill; |
| 52 var promise = new Promise(f => fulfill = f); | 62 var promise = new Promise(f => fulfill = f); |
| 53 this._agent.setAutoAttach(true /* autoAttach */, true /* waitForDebuggerOnSt art */, fulfill); | 63 this._agent.setAutoAttach(true /* autoAttach */, true /* waitForDebuggerOnSt art */, fulfill); |
| 54 return promise; | 64 return promise; |
| 55 } | 65 } |
| 56 | 66 |
| 57 /** | 67 /** |
| 58 * @override | 68 * @override |
| 59 */ | 69 */ |
| 60 dispose() { | 70 dispose() { |
| 61 for (var connection of this._connections.values()) { | 71 for (var attachedTargetId of this._attachedTargets.keys()) |
| 62 this._agent.detachFromTarget(connection._targetId); | 72 this._detachedFromTarget(attachedTargetId); |
| 63 connection._onDisconnect.call(null, 'disposed'); | 73 for (var pendingConnectionId of this._pendingTargets.keys()) |
| 64 } | 74 this._targetDestroyed(pendingConnectionId); |
| 65 this._connections.clear(); | |
| 66 this._attachedTargets.clear(); | |
| 67 } | 75 } |
| 68 | 76 |
| 69 /** | 77 /** |
| 70 * @param {!Protocol.Target.TargetID} targetId | 78 * @param {!Protocol.Target.TargetID} targetId |
| 71 */ | 79 */ |
| 72 activateTarget(targetId) { | 80 activateTarget(targetId) { |
| 73 this._agent.activateTarget(targetId); | 81 this._agent.activateTarget(targetId); |
| 74 } | 82 } |
| 75 | 83 |
| 76 /** | 84 /** |
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 149 target[WebInspector.SubTargetsManager._InfoSymbol] = targetInfo; | 157 target[WebInspector.SubTargetsManager._InfoSymbol] = targetInfo; |
| 150 this._attachedTargets.set(targetInfo.id, target); | 158 this._attachedTargets.set(targetInfo.id, target); |
| 151 | 159 |
| 152 // Only pause new worker if debugging SW - we are going through the pause on start checkbox. | 160 // Only pause new worker if debugging SW - we are going through the pause on start checkbox. |
| 153 var mainIsServiceWorker = | 161 var mainIsServiceWorker = |
| 154 !this.target().parentTarget() && this.target().hasTargetCapability() && !this.target().hasBrowserCapability(); | 162 !this.target().parentTarget() && this.target().hasTargetCapability() && !this.target().hasBrowserCapability(); |
| 155 if (mainIsServiceWorker && waitingForDebugger) | 163 if (mainIsServiceWorker && waitingForDebugger) |
| 156 target.debuggerAgent().pause(); | 164 target.debuggerAgent().pause(); |
| 157 target.runtimeAgent().runIfWaitingForDebugger(); | 165 target.runtimeAgent().runIfWaitingForDebugger(); |
| 158 | 166 |
| 159 this.dispatchEventToListeners(WebInspector.SubTargetsManager.Events.SubTarge tAdded, target); | 167 var pendingTarget = this._pendingTargets.get(targetInfo.id); |
| 168 if (!pendingTarget) { | |
| 169 this._targetCreated(targetInfo); | |
| 170 pendingTarget = this._pendingTargets.get(targetInfo.id); | |
| 171 } | |
| 172 pendingTarget.notifyAttached(target); | |
| 173 this.dispatchEventToListeners(WebInspector.SubTargetsManager.Events.SubTarge tAttached, pendingTarget); | |
| 160 } | 174 } |
| 161 | 175 |
| 162 /** | 176 /** |
| 163 * @param {string} targetId | 177 * @param {string} targetId |
| 164 * @param {!InspectorBackendClass.Connection.Params} params | 178 * @param {!InspectorBackendClass.Connection.Params} params |
| 165 * @return {!InspectorBackendClass.Connection} | 179 * @return {!InspectorBackendClass.Connection} |
| 166 */ | 180 */ |
| 167 _createConnection(targetId, params) { | 181 _createConnection(targetId, params) { |
| 168 var connection = new WebInspector.SubTargetConnection(this._agent, targetId, params); | 182 var connection = new WebInspector.SubTargetConnection(this._agent, targetId, params); |
| 169 this._connections.set(targetId, connection); | 183 this._connections.set(targetId, connection); |
| 170 return connection; | 184 return connection; |
| 171 } | 185 } |
| 172 | 186 |
| 173 /** | 187 /** |
| 174 * @param {string} targetId | 188 * @param {string} targetId |
| 175 */ | 189 */ |
| 176 _detachedFromTarget(targetId) { | 190 _detachedFromTarget(targetId) { |
| 177 var target = this._attachedTargets.get(targetId); | 191 var target = this._attachedTargets.get(targetId); |
| 178 this._attachedTargets.delete(targetId); | 192 this._attachedTargets.delete(targetId); |
| 179 this.dispatchEventToListeners(WebInspector.SubTargetsManager.Events.SubTarge tRemoved, target); | |
| 180 var connection = this._connections.get(targetId); | 193 var connection = this._connections.get(targetId); |
| 181 if (connection) | 194 connection._onDisconnect.call(null, 'target terminated'); |
| 182 connection._onDisconnect.call(null, 'target terminated'); | |
| 183 this._connections.delete(targetId); | 195 this._connections.delete(targetId); |
| 196 this.dispatchEventToListeners(WebInspector.SubTargetsManager.Events.SubTarge tDetached, this._pendingTargets.get(targetId)); | |
| 184 } | 197 } |
| 185 | 198 |
| 186 /** | 199 /** |
| 187 * @param {string} targetId | 200 * @param {string} targetId |
| 188 * @param {string} message | 201 * @param {string} message |
| 189 */ | 202 */ |
| 190 _receivedMessageFromTarget(targetId, message) { | 203 _receivedMessageFromTarget(targetId, message) { |
| 191 var connection = this._connections.get(targetId); | 204 var connection = this._connections.get(targetId); |
| 192 if (connection) | 205 if (connection) |
| 193 connection._onMessage.call(null, message); | 206 connection._onMessage.call(null, message); |
| 194 } | 207 } |
| 195 | 208 |
| 196 /** | 209 /** |
| 197 * @param {!WebInspector.TargetInfo} targetInfo | 210 * @param {!WebInspector.TargetInfo} targetInfo |
| 198 */ | 211 */ |
| 199 _targetCreated(targetInfo) { | 212 _targetCreated(targetInfo) { |
| 200 if (targetInfo.type !== 'node') | 213 var pendingTarget = this._pendingTargets.get(targetInfo.id); |
| 214 if (pendingTarget) | |
| 201 return; | 215 return; |
| 202 this._agent.attachToTarget(targetInfo.id); | 216 pendingTarget = new WebInspector.PendingTarget(targetInfo.id, targetInfo.tit le, targetInfo.type === 'node', this); |
| 217 this._pendingTargets.set(targetInfo.id, pendingTarget); | |
| 218 this.dispatchEventToListeners(WebInspector.SubTargetsManager.Events.SubTarge tAdded, pendingTarget); | |
| 203 } | 219 } |
| 204 | 220 |
| 205 /** | 221 /** |
| 206 * @param {string} targetId | 222 * @param {string} targetId |
| 207 */ | 223 */ |
| 208 _targetDestroyed(targetId) { | 224 _targetDestroyed(targetId) { |
| 209 // All the work is done in _detachedFromTarget. | 225 var pendingTarget = this._pendingTargets.get(targetId); |
| 226 if (!pendingTarget) | |
| 227 return; | |
| 228 this._pendingTargets.delete(targetId); | |
| 229 this.dispatchEventToListeners(WebInspector.SubTargetsManager.Events.SubTarge tRemoved, pendingTarget); | |
| 210 } | 230 } |
| 211 | 231 |
| 212 /** | 232 /** |
| 233 * @return {!Array<!WebInspector.PendingTarget>} | |
| 234 */ | |
| 235 pendingTargets() { | |
| 236 return this._pendingTargets.valuesArray(); | |
| 237 } | |
| 238 | |
| 239 /** | |
| 213 * @param {!WebInspector.Event} event | 240 * @param {!WebInspector.Event} event |
| 214 */ | 241 */ |
| 215 _mainFrameNavigated(event) { | 242 _mainFrameNavigated(event) { |
| 216 if (event.data.target() !== this.target()) | 243 if (event.data.target() !== this.target()) |
| 217 return; | 244 return; |
| 218 | 245 |
| 219 var idsToDetach = []; | 246 var idsToDetach = []; |
| 220 for (var targetId of this._attachedTargets.keys()) { | 247 for (var targetId of this._attachedTargets.keys()) { |
| 221 var target = this._attachedTargets.get(targetId); | 248 var target = this._attachedTargets.get(targetId); |
| 222 var targetInfo = this.targetInfo(target); | 249 var targetInfo = this.targetInfo(target); |
| 223 if (targetInfo.type === 'worker') | 250 if (targetInfo.type === 'worker') |
| 224 idsToDetach.push(targetId); | 251 idsToDetach.push(targetId); |
| 225 } | 252 } |
| 226 idsToDetach.forEach(id => this._detachedFromTarget(id)); | 253 idsToDetach.forEach(id => this._detachedFromTarget(id)); |
| 227 } | 254 } |
| 228 }; | 255 }; |
| 229 | 256 |
| 230 /** @enum {symbol} */ | 257 /** @enum {symbol} */ |
| 231 WebInspector.SubTargetsManager.Events = { | 258 WebInspector.SubTargetsManager.Events = { |
| 232 SubTargetAdded: Symbol('SubTargetAdded'), | 259 SubTargetAdded: Symbol('SubTargetAdded'), |
|
dgozman
2016/11/03 21:21:30
PendingTarget{Added,Removed,Attached,Detached}
eostroukhov
2016/11/03 22:44:50
Done.
| |
| 233 SubTargetRemoved: Symbol('SubTargetRemoved'), | 260 SubTargetRemoved: Symbol('SubTargetRemoved'), |
| 261 SubTargetAttached: Symbol('SubTargetAttached'), | |
| 262 SubTargetDetached: Symbol('SubTargetDetached'), | |
| 234 }; | 263 }; |
| 235 | 264 |
| 236 WebInspector.SubTargetsManager._InfoSymbol = Symbol('SubTargetInfo'); | 265 WebInspector.SubTargetsManager._InfoSymbol = Symbol('SubTargetInfo'); |
| 237 | 266 |
| 238 /** | 267 /** |
| 239 * @implements {Protocol.TargetDispatcher} | 268 * @implements {Protocol.TargetDispatcher} |
| 240 * @unrestricted | 269 * @unrestricted |
| 241 */ | 270 */ |
| 242 WebInspector.SubTargetsDispatcher = class { | 271 WebInspector.SubTargetsDispatcher = class { |
| 243 /** | 272 /** |
| (...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 337 this.type = payload.type; | 366 this.type = payload.type; |
| 338 this.canActivate = this.type === 'page' || this.type === 'iframe'; | 367 this.canActivate = this.type === 'page' || this.type === 'iframe'; |
| 339 if (this.type === 'node') | 368 if (this.type === 'node') |
| 340 this.title = WebInspector.UIString('Node: %s', this.url); | 369 this.title = WebInspector.UIString('Node: %s', this.url); |
| 341 else if (this.type === 'page' || this.type === 'iframe') | 370 else if (this.type === 'page' || this.type === 'iframe') |
| 342 this.title = payload.title; | 371 this.title = payload.title; |
| 343 else | 372 else |
| 344 this.title = WebInspector.UIString('Worker: %s', this.url); | 373 this.title = WebInspector.UIString('Worker: %s', this.url); |
| 345 } | 374 } |
| 346 }; | 375 }; |
| 376 | |
| 377 /** | |
| 378 * @unrestricted | |
| 379 */ | |
| 380 WebInspector.PendingTarget = class { | |
| 381 /** | |
| 382 * @param {string} id | |
| 383 * @param {string} title | |
| 384 * @param {boolean} canConnect | |
| 385 * @param {?WebInspector.SubTargetsManager} manager | |
| 386 */ | |
| 387 constructor(id, title, canConnect, manager) { | |
| 388 this._id = id; | |
| 389 this._title = title; | |
| 390 this._isRemote = canConnect; | |
| 391 this._manager = manager; | |
| 392 /** @type {?Promise} */ | |
| 393 this._connectPromise = null; | |
| 394 /** @type {?Function} */ | |
| 395 this._attachedCallback = null; | |
| 396 } | |
| 397 | |
| 398 /** | |
| 399 * @return {string} | |
| 400 */ | |
| 401 id() { | |
| 402 return this._id; | |
| 403 } | |
| 404 | |
| 405 /** | |
| 406 * @return {?WebInspector.Target} | |
| 407 */ | |
| 408 target() { | |
| 409 if (!this._manager) | |
| 410 return null; | |
| 411 return this._manager.targetForId(this.id()); | |
| 412 } | |
| 413 | |
| 414 /** | |
| 415 * @return {string} | |
| 416 */ | |
| 417 name() | |
| 418 { | |
|
dgozman
2016/11/03 21:21:30
{ on the same line everywhere please.
eostroukhov
2016/11/03 22:44:50
Done.
| |
| 419 return this._title; | |
| 420 } | |
| 421 | |
| 422 /** | |
| 423 * @return {!Promise} | |
| 424 */ | |
| 425 connect() | |
|
dgozman
2016/11/03 21:21:30
Let's call these attach/detach to be consistent.
eostroukhov
2016/11/03 22:44:50
Done.
| |
| 426 { | |
| 427 if (!this._manager) | |
| 428 return Promise.reject(); | |
| 429 if (this._connectPromise) | |
| 430 return this._connectPromise; | |
| 431 if (this.target()) | |
| 432 return Promise.resolve(this.target()); | |
| 433 this._connectPromise = new Promise(resolve => { | |
| 434 this._attachedCallback = resolve; | |
| 435 this._manager._agent.attachToTarget(this.id()); | |
| 436 }); | |
| 437 return this._connectPromise; | |
| 438 } | |
| 439 | |
| 440 disconnect() | |
| 441 { | |
| 442 if (!this._manager) | |
| 443 return; | |
| 444 this._manager._agent.detachFromTarget(this.id()); | |
| 445 } | |
| 446 | |
| 447 /** | |
| 448 * @param {!WebInspector.Target} target | |
| 449 */ | |
| 450 notifyAttached(target) | |
| 451 { | |
| 452 if (this._attachedCallback) | |
| 453 this._attachedCallback(target); | |
| 454 this._connectPromise = null; | |
| 455 this._attachedCallback = null; | |
| 456 } | |
| 457 | |
| 458 /** | |
| 459 * @return {boolean} | |
| 460 */ | |
| 461 canConnect() | |
| 462 { | |
| 463 return this._isRemote; | |
| 464 } | |
| 465 }; | |
| OLD | NEW |