Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(51)

Side by Side Diff: third_party/WebKit/Source/devtools/front_end/sdk/SubTargetsManager.js

Issue 2431223003: [DevTools]: Require explicit connection (Closed)
Patch Set: Reworked - again Created 4 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 /** 5 /**
6 * @constructor 6 * @constructor
7 * @extends {WebInspector.SDKModel} 7 * @extends {WebInspector.SDKModel}
8 * @param {!WebInspector.Target} target 8 * @param {!WebInspector.Target} target
9 */ 9 */
10 WebInspector.SubTargetsManager = function(target) 10 WebInspector.SubTargetsManager = function(target)
11 { 11 {
12 WebInspector.SDKModel.call(this, WebInspector.SubTargetsManager, target); 12 WebInspector.SDKModel.call(this, 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 /** @type {!Map<string, !WebInspector.PendingConnection>} */
22 this._pendingConnections = new Map();
21 23
22 this._agent.setAutoAttach(true /* autoAttach */, true /* waitForDebuggerOnSt art */); 24 this._agent.setAutoAttach(true /* autoAttach */, true /* waitForDebuggerOnSt art */);
23 if (Runtime.experiments.isEnabled("autoAttachToCrossProcessSubframes")) 25 if (Runtime.experiments.isEnabled("autoAttachToCrossProcessSubframes"))
24 this._agent.setAttachToFrames(true); 26 this._agent.setAttachToFrames(true);
25 27
26 if (Runtime.experiments.isEnabled("nodeDebugging") && !target.parentTarget() ) { 28 if (Runtime.experiments.isEnabled("nodeDebugging") && !target.parentTarget() ) {
27 var defaultLocations = [{host: "localhost", port: 9229}]; 29 var defaultLocations = [{host: "localhost", port: 9229}];
28 this._agent.setRemoteLocations(defaultLocations); 30 this._agent.setRemoteLocations(defaultLocations);
29 this._agent.setDiscoverTargets(true); 31 this._agent.setDiscoverTargets(true);
30 } 32 }
31 WebInspector.targetManager.addEventListener(WebInspector.TargetManager.Event s.MainFrameNavigated, this._mainFrameNavigated, this); 33 WebInspector.targetManager.addEventListener(WebInspector.TargetManager.Event s.MainFrameNavigated, this._mainFrameNavigated, this);
32 }; 34 };
33 35
34 /** @enum {symbol} */ 36 /** @enum {symbol} */
35 WebInspector.SubTargetsManager.Events = { 37 WebInspector.SubTargetsManager.Events = {
36 SubTargetAdded: Symbol("SubTargetAdded"), 38 SubTargetConnectionCreated: Symbol("SubTargetCreated"),
dgozman 2016/10/28 18:31:35 PendingConnectionCreated
eostroukhov 2016/11/01 20:28:14 I removed the word "connection" - it is too ambigu
37 SubTargetRemoved: Symbol("SubTargetRemoved"), 39 SubTargetConnectionDestroyed: Symbol("SubTargetDestroyed"),
38 }; 40 };
39 41
40 WebInspector.SubTargetsManager._InfoSymbol = Symbol("SubTargetInfo"); 42 WebInspector.SubTargetsManager._InfoSymbol = Symbol("SubTargetInfo");
41 43
42 WebInspector.SubTargetsManager.prototype = { 44 WebInspector.SubTargetsManager.prototype = {
43 /** 45 /**
44 * @override 46 * @override
45 * @return {!Promise} 47 * @return {!Promise}
46 */ 48 */
47 suspendModel: function() 49 suspendModel: function()
(...skipping 18 matching lines...) Expand all
66 68
67 /** 69 /**
68 * @override 70 * @override
69 */ 71 */
70 dispose: function() 72 dispose: function()
71 { 73 {
72 for (var connection of this._connections.values()) { 74 for (var connection of this._connections.values()) {
73 this._agent.detachFromTarget(connection._targetId); 75 this._agent.detachFromTarget(connection._targetId);
74 connection._onDisconnect.call(null, "disposed"); 76 connection._onDisconnect.call(null, "disposed");
75 } 77 }
78 for (var pending of this._pendingConnections.values())
79 pending.disconnect();
76 this._connections.clear(); 80 this._connections.clear();
77 this._attachedTargets.clear(); 81 this._attachedTargets.clear();
78 }, 82 },
79 83
80 /** 84 /**
81 * @param {!TargetAgent.TargetID} targetId 85 * @param {!TargetAgent.TargetID} targetId
82 */ 86 */
83 activateTarget: function(targetId) 87 activateTarget: function(targetId)
84 { 88 {
85 this._agent.activateTarget(targetId); 89 this._agent.activateTarget(targetId);
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
153 */ 157 */
154 _attachedToTarget: function(targetInfo, waitingForDebugger) 158 _attachedToTarget: function(targetInfo, waitingForDebugger)
155 { 159 {
156 var targetName = ""; 160 var targetName = "";
157 if (targetInfo.type === "node") { 161 if (targetInfo.type === "node") {
158 targetName = targetInfo.title; 162 targetName = targetInfo.title;
159 } else if (targetInfo.type !== "iframe") { 163 } else if (targetInfo.type !== "iframe") {
160 var parsedURL = targetInfo.url.asParsedURL(); 164 var parsedURL = targetInfo.url.asParsedURL();
161 targetName = parsedURL ? parsedURL.lastPathComponentWithFragment() : "#" + (++this._lastAnonymousTargetId); 165 targetName = parsedURL ? parsedURL.lastPathComponentWithFragment() : "#" + (++this._lastAnonymousTargetId);
162 } 166 }
163 var target = WebInspector.targetManager.createTarget(targetName, this._c apabilitiesForType(targetInfo.type), this._createConnection.bind(this, targetInf o.id), this.target()); 167 var target = WebInspector.targetManager.createTarget(targetName, this._c apabilitiesForType(targetInfo.type), this._createConnection.bind(this, targetInf o.id), this.target(), true);
164 target[WebInspector.SubTargetsManager._InfoSymbol] = targetInfo; 168 target[WebInspector.SubTargetsManager._InfoSymbol] = targetInfo;
165 this._attachedTargets.set(targetInfo.id, target); 169 this._attachedTargets.set(targetInfo.id, target);
166 170 WebInspector.targetManager.addTarget(target);
167 // Only pause new worker if debugging SW - we are going through the paus e on start checkbox. 171 // Only pause new worker if debugging SW - we are going through the paus e on start checkbox.
168 var mainIsServiceWorker = !this.target().parentTarget() && this.target() .hasTargetCapability() && !this.target().hasBrowserCapability(); 172 var mainIsServiceWorker = !this.target().parentTarget() && this.target() .hasTargetCapability() && !this.target().hasBrowserCapability();
169 if (mainIsServiceWorker && waitingForDebugger) 173 if (mainIsServiceWorker && waitingForDebugger)
170 target.debuggerAgent().pause(); 174 target.debuggerAgent().pause();
171 target.runtimeAgent().runIfWaitingForDebugger(); 175 target.runtimeAgent().runIfWaitingForDebugger();
172 176 var connection = this._pendingConnections.get(targetInfo.id);
173 this.dispatchEventToListeners(WebInspector.SubTargetsManager.Events.SubT argetAdded, target); 177 if (connection)
178 connection.notifyAttached(target);
174 }, 179 },
175 180
176 /** 181 /**
177 * @param {string} targetId 182 * @param {string} targetId
178 * @param {!InspectorBackendClass.Connection.Params} params 183 * @param {!InspectorBackendClass.Connection.Params} params
179 * @return {!InspectorBackendClass.Connection} 184 * @return {!InspectorBackendClass.Connection}
180 */ 185 */
181 _createConnection: function(targetId, params) 186 _createConnection: function(targetId, params)
182 { 187 {
183 var connection = new WebInspector.SubTargetConnection(this._agent, targe tId, params); 188 var connection = new WebInspector.SubTargetConnection(this._agent, targe tId, params);
184 this._connections.set(targetId, connection); 189 this._connections.set(targetId, connection);
185 return connection; 190 return connection;
186 }, 191 },
187 192
188 /** 193 /**
189 * @param {string} targetId 194 * @param {string} targetId
190 */ 195 */
191 _detachedFromTarget: function(targetId) 196 _detachedFromTarget: function(targetId)
192 { 197 {
193 var target = this._attachedTargets.get(targetId); 198 var target = this._attachedTargets.get(targetId);
194 this._attachedTargets.delete(targetId); 199 this._attachedTargets.delete(targetId);
195 this.dispatchEventToListeners(WebInspector.SubTargetsManager.Events.SubT argetRemoved, target);
196 var connection = this._connections.get(targetId); 200 var connection = this._connections.get(targetId);
197 if (connection) 201 if (connection)
198 connection._onDisconnect.call(null, "target terminated"); 202 connection._onDisconnect.call(null, "target terminated");
199 this._connections.delete(targetId); 203 this._connections.delete(targetId);
200 }, 204 },
201 205
202 /** 206 /**
203 * @param {string} targetId 207 * @param {string} targetId
204 * @param {string} message 208 * @param {string} message
205 */ 209 */
206 _receivedMessageFromTarget: function(targetId, message) 210 _receivedMessageFromTarget: function(targetId, message)
207 { 211 {
208 var connection = this._connections.get(targetId); 212 var connection = this._connections.get(targetId);
209 if (connection) 213 if (connection)
210 connection._onMessage.call(null, message); 214 connection._onMessage.call(null, message);
211 }, 215 },
212 216
213 /** 217 /**
214 * @param {!WebInspector.TargetInfo} targetInfo 218 * @param {!WebInspector.TargetInfo} targetInfo
219 * @return {?WebInspector.PendingConnection}
215 */ 220 */
216 _targetCreated: function(targetInfo) 221 _targetCreated: function(targetInfo)
217 { 222 {
218 if (targetInfo.type !== "node") 223 if (targetInfo.type !== "node")
219 return; 224 return null;
220 this._agent.attachToTarget(targetInfo.id); 225 var connection = this._pendingConnections.get(targetInfo.id);
dgozman 2016/10/28 18:31:35 console.assert(!this._pendingConnections.has(targe
eostroukhov 2016/11/01 20:28:14 Why not "console.assert(!connection)"?
eostroukhov 2016/11/02 21:55:52 I had to rollback the change. As we discussed befo
226 if (connection)
227 return connection;
228 connection = new WebInspector.PendingConnection(targetInfo, this);
229 this._pendingConnections.set(targetInfo.id, connection);
230 this.dispatchEventToListeners(WebInspector.SubTargetsManager.Events.SubT argetConnectionCreated, connection);
231 return connection;
dgozman 2016/10/28 18:31:35 You never use return value, which is good :-)
eostroukhov 2016/11/01 20:28:14 Fixed
221 }, 232 },
222 233
223 /** 234 /**
224 * @param {string} targetId 235 * @param {string} targetId
225 */ 236 */
226 _targetDestroyed: function(targetId) 237 _targetDestroyed: function(targetId)
227 { 238 {
228 // All the work is done in _detachedFromTarget. 239 var connection = this._pendingConnections.get(targetId);
240 if (!connection)
241 return;
242 this._pendingConnections.delete(targetId);
243 this.dispatchEventToListeners(WebInspector.SubTargetsManager.Events.SubT argetConnectionDestroyed, connection);
229 }, 244 },
230 245
231 /** 246 /**
247 * @return {!Array<!WebInspector.PendingConnection>}
248 */
249 targetConnections: function()
dgozman 2016/10/28 18:31:35 pendingConnections
eostroukhov 2016/11/01 20:28:14 subTargets?
250 {
251 return Array.from(this._pendingConnections.values());
dgozman 2016/10/28 18:31:35 .valuesArray()
eostroukhov 2016/11/01 20:28:14 Done.
252 },
253
254 /**
232 * @param {!WebInspector.Event} event 255 * @param {!WebInspector.Event} event
233 */ 256 */
234 _mainFrameNavigated: function(event) 257 _mainFrameNavigated: function(event)
235 { 258 {
236 if (event.data.target() !== this.target()) 259 if (event.data.target() !== this.target())
237 return; 260 return;
238 261
239 var idsToDetach = []; 262 var idsToDetach = [];
240 for (var targetId of this._attachedTargets.keys()) { 263 for (var targetId of this._attachedTargets.keys()) {
241 var target = this._attachedTargets.get(targetId); 264 var target = this._attachedTargets.get(targetId);
242 var targetInfo = this.targetInfo(target); 265 var targetInfo = this.targetInfo(target);
243 if (targetInfo.type === "worker") 266 if (targetInfo.type === "worker")
244 idsToDetach.push(targetId); 267 idsToDetach.push(targetId);
245 } 268 }
246 idsToDetach.forEach(id => this._detachedFromTarget(id)); 269 idsToDetach.forEach(id => this._detachedFromTarget(id));
247 }, 270 },
248 271
249 __proto__: WebInspector.SDKModel.prototype 272 __proto__: WebInspector.SDKModel.prototype
250 }; 273 };
251 274
252 /** 275 /**
276 * @param {!WebInspector.Target} target
277 * @return {?WebInspector.SubTargetsManager}
278 */
279 WebInspector.SubTargetsManager.fromTarget = function(target)
280 {
281 return /** @type {?WebInspector.SubTargetsManager} */ (target.model(WebInspe ctor.SubTargetsManager));
282 };
283
284
285 /**
253 * @constructor 286 * @constructor
254 * @implements {TargetAgent.Dispatcher} 287 * @implements {TargetAgent.Dispatcher}
255 * @param {!WebInspector.SubTargetsManager} manager 288 * @param {!WebInspector.SubTargetsManager} manager
256 */ 289 */
257 WebInspector.SubTargetsDispatcher = function(manager) 290 WebInspector.SubTargetsDispatcher = function(manager)
258 { 291 {
259 this._manager = manager; 292 this._manager = manager;
260 }; 293 };
261 294
262 WebInspector.SubTargetsDispatcher.prototype = { 295 WebInspector.SubTargetsDispatcher.prototype = {
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
334 }, 367 },
335 368
336 /** 369 /**
337 * @override 370 * @override
338 * @return {!Promise} 371 * @return {!Promise}
339 */ 372 */
340 disconnect: function() 373 disconnect: function()
341 { 374 {
342 throw new Error("Not implemented"); 375 throw new Error("Not implemented");
343 }, 376 },
377
378 /**
379 * @return {string}
380 */
381 targetId: function()
382 {
383 return this._targetId;
dgozman 2016/10/28 18:31:35 Just use ._targetId directly in this file.
eostroukhov 2016/11/01 20:28:14 Done.
384 },
344 }; 385 };
345 386
346 /** 387 /**
347 * @constructor 388 * @constructor
348 * @param {!TargetAgent.TargetInfo} payload 389 * @param {!TargetAgent.TargetInfo} payload
349 */ 390 */
350 WebInspector.TargetInfo = function(payload) 391 WebInspector.TargetInfo = function(payload)
351 { 392 {
352 this.id = payload.targetId; 393 this.id = payload.targetId;
353 this.url = payload.url; 394 this.url = payload.url;
354 this.type = payload.type; 395 this.type = payload.type;
355 if (this.type !== "page" && this.type !== "iframe") { 396 if (this.type !== "page" && this.type !== "iframe" && this.type !== "node") {
dgozman 2016/10/28 18:31:35 This has changed recently, please rebase.
eostroukhov 2016/11/01 20:28:15 Done.
356 this.title = WebInspector.UIString("Worker: %s", this.url); 397 this.title = WebInspector.UIString("Worker: %s", this.url);
357 this.canActivate = false; 398 this.canActivate = false;
358 } else { 399 } else {
359 this.title = payload.title; 400 this.title = payload.title;
360 this.canActivate = true; 401 this.canActivate = true;
361 } 402 }
362 }; 403 };
404
405 /**
406 * @constructor
407 * @param {!WebInspector.TargetInfo} info
408 * @param {!WebInspector.SubTargetsManager} manager
409 */
410 WebInspector.PendingConnection = function(info, manager)
411 {
412 this._info = info;
413 this._manager = manager;
414 /** @type {?Promise} */
415 this._connectPromise = null;
416 /** @type {?Function} */
417 this._attachedCallback = null;
418 };
419
420 WebInspector.PendingConnection.prototype = {
421 /**
422 * @return {string}
423 */
424 id: function()
425 {
426 return this._info.id;
427 },
428
429 /**
430 * @return {?WebInspector.Target}
431 */
432 target: function()
433 {
434 return this._manager.targetForId(this.id());
435 },
436
437 /**
438 * @return {string}
439 */
440 name: function()
441 {
442 return this._info.title;
443 },
444
445 /**
446 * @return {!Promise}
447 */
448 connect: function()
449 {
450 if (this._connectPromise)
451 return this._connectPromise;
452 if (this.target())
453 return Promise.resolve(this.target());
454 this._connectPromise = new Promise(resolve => this._attachedCallback = r esolve)
dgozman 2016/10/28 18:31:35 If you don't follow the pattern I described, then
eostroukhov 2016/11/01 20:28:14 Not sure I understood correctly, but I restructure
455 .then(() => {
456 this._connectPromise = null;
457 this._attachedCallback = null;
458 return this.target();
459 });
460 this._manager._agent.attachToTarget(this.id());
461 return this._connectPromise;
462 },
463
464 disconnect: function()
465 {
466 this._manager._agent.detachFromTarget(this.id());
467 },
468
469 notifyAttached: function(target)
dgozman 2016/10/28 18:31:35 JSDoc please.
eostroukhov 2016/11/01 20:28:15 Done.
470 {
471 if (this._attachedCallback)
472 this._attachedCallback(target);
473 },
474 };
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698