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

Side by Side Diff: third_party/WebKit/Source/devtools/front_end/sources/ThreadsSidebarPane.js

Issue 2431223003: [DevTools]: Require explicit connection (Closed)
Patch Set: Tests pass now. 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 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 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 * @implements {WebInspector.TargetManager.Observer} 5 * @implements {WebInspector.TargetManager.Observer}
6 * @unrestricted 6 * @unrestricted
7 */ 7 */
8 WebInspector.ThreadsSidebarPane = class extends WebInspector.VBox { 8 WebInspector.ThreadsSidebarPane = class extends WebInspector.VBox {
9 constructor() { 9 constructor() {
10 super(); 10 super();
11 11
12 /** @type {!Map.<!WebInspector.DebuggerModel, !WebInspector.UIList.Item>} */
13 this._debuggerModelToListItems = new Map();
14 /** @type {!Map.<!WebInspector.UIList.Item, !WebInspector.Target>} */
15 this._listItemsToTargets = new Map();
16 /** @type {?WebInspector.UIList.Item} */ 12 /** @type {?WebInspector.UIList.Item} */
17 this._selectedListItem = null; 13 this._selectedListItem = null;
14 /** @type {!Map<!WebInspector.PendingSubTarget, !WebInspector.UIList.Item>} */
15 this._subtargetToListItem = new Map();
dgozman 2016/11/02 23:20:40 pendingToListItem
eostroukhov 2016/11/03 17:25:52 Done.
16 /** @type {!Map<!WebInspector.Target, !WebInspector.PendingSubTarget>} */
17 this._targetToSubtarget = new Map();
dgozman 2016/11/02 23:20:40 targetToPending
eostroukhov 2016/11/03 17:25:52 Done.
18 /** @type {?WebInspector.PendingSubTarget} */
19 this._mainTargetConnection = null;
dgozman 2016/11/02 23:20:40 _mainPendingTarget
eostroukhov 2016/11/03 17:25:52 "_mainTargetPending"? Still atrocious - but I don'
18 this.threadList = new WebInspector.UIList(); 20 this.threadList = new WebInspector.UIList();
19 this.threadList.show(this.element); 21 this.threadList.show(this.element);
20 WebInspector.targetManager.addModelListener( 22 WebInspector.targetManager.addModelListener(
21 WebInspector.DebuggerModel, WebInspector.DebuggerModel.Events.DebuggerPa used, this._onDebuggerStateChanged, 23 WebInspector.DebuggerModel, WebInspector.DebuggerModel.Events.DebuggerPa used, this._onDebuggerStateChanged,
22 this); 24 this);
23 WebInspector.targetManager.addModelListener( 25 WebInspector.targetManager.addModelListener(
24 WebInspector.DebuggerModel, WebInspector.DebuggerModel.Events.DebuggerRe sumed, this._onDebuggerStateChanged, 26 WebInspector.DebuggerModel, WebInspector.DebuggerModel.Events.DebuggerRe sumed, this._onDebuggerStateChanged,
25 this); 27 this);
26 WebInspector.targetManager.addModelListener( 28 WebInspector.targetManager.addModelListener(
27 WebInspector.RuntimeModel, WebInspector.RuntimeModel.Events.ExecutionCon textChanged, 29 WebInspector.RuntimeModel, WebInspector.RuntimeModel.Events.ExecutionCon textChanged,
28 this._onExecutionContextChanged, this); 30 this._onExecutionContextChanged, this);
29 WebInspector.context.addFlavorChangeListener(WebInspector.Target, this._targ etChanged, this); 31 WebInspector.context.addFlavorChangeListener(WebInspector.Target, this._targ etChanged, this);
30 WebInspector.targetManager.addEventListener( 32 WebInspector.targetManager.addEventListener(
31 WebInspector.TargetManager.Events.NameChanged, this._targetNameChanged, this); 33 WebInspector.TargetManager.Events.NameChanged, this._targetNameChanged, this);
34 WebInspector.targetManager.addModelListener(WebInspector.SubTargetsManager, WebInspector.SubTargetsManager.Events.SubTargetAdded, this._subTargetAdded, this );
35 WebInspector.targetManager.addModelListener(WebInspector.SubTargetsManager, WebInspector.SubTargetsManager.Events.SubTargetRemoved, this._subTargetRemoved, this);
36 WebInspector.targetManager.addModelListener(WebInspector.SubTargetsManager, WebInspector.SubTargetsManager.Events.SubTargetAttached, this._subTargetAdded, t his);
37 WebInspector.targetManager.addModelListener(WebInspector.SubTargetsManager, WebInspector.SubTargetsManager.Events.SubTargetDetached, this._targetDetached, t his);
32 WebInspector.targetManager.observeTargets(this); 38 WebInspector.targetManager.observeTargets(this);
39
40 var subtargets = [];
41 for (var target of WebInspector.targetManager.targets(WebInspector.Target.Ca pability.Target))
42 subtargets = subtargets.concat(WebInspector.SubTargetsManager.fromTarget(t arget).subTargets());
43
44 subtargets
45 .sort(WebInspector.ThreadsSidebarPane._subTargetsComparator)
46 .forEach(subtarget => this._addListItem(subtarget));
47 }
48
49 /**
50 * @return {boolean}
51 */
52 static isShown() {
dgozman 2016/11/02 23:20:40 nit: shouldBeShown is correct, while isShown is no
eostroukhov 2016/11/03 17:25:51 Done.
53 if (WebInspector.targetManager.targets(WebInspector.Target.Capability.JS).le ngth > 1)
54 return true;
55 for (var target of WebInspector.targetManager.targets(WebInspector.Target.Ca pability.Target)) {
56 if (WebInspector.SubTargetsManager.fromTarget(target).subTargets().some(su btarget => subtarget.canConnect()))
57 return true;
58 }
59 return false;
60 }
61
62 /**
63 * Sorts show tha connected targets appear first, followed by pending subtarge ts.
64 *
65 * @param {!WebInspector.PendingSubTarget} c1
66 * @param {!WebInspector.PendingSubTarget} c2
67 * @return {number}
68 */
69 static _subTargetsComparator(c1, c2)
70 {
71 var t1 = c1.target();
72 var t2 = c2.target();
73 var name1 = t1 ? t1.name() : c1.name();
74 var name2 = t2 ? t2.name() : c2.name();
75 if (!!t1 === !!t2) { // Either both are connected or disconnected
76 return name1.toLowerCase().localeCompare(name2.toLowerCase());
77 } else if (t1) {
78 return -1;
79 }
80 return 1;
81 }
82
83 /**
84 * @param {!WebInspector.Event} event
85 */
86 _subTargetAdded(event) {
87 this._addListItem(/** @type {!WebInspector.PendingSubTarget} */ (event.data) );
88 }
89
90 /**
91 * @param {!WebInspector.Event} event
92 */
93 _subTargetRemoved(event) {
94 this._removeListItem(/** @type {!WebInspector.PendingSubTarget} */ (event.da ta));
95 }
96
97 /**
98 * @param {!WebInspector.Event} event
99 */
100 _targetDetached(event) {
101 this._targetRemoved(/** @type {!WebInspector.PendingSubTarget} */ (event.dat a));
102 }
103
104 /**
105 * @param {!WebInspector.PendingSubTarget} subtarget
106 */
107 _addListItem(subtarget) {
108 var target = subtarget.target();
109 if (!subtarget.canConnect() && !(target && target.hasJSCapability()))
110 return;
111
112 var listItem = this._subtargetToListItem.get(subtarget);
113 if (!listItem) {
114 listItem = new WebInspector.UIList.Item('', '', false);
115 listItem[WebInspector.ThreadsSidebarPane._subtargetSymbol] = subtarget;
116 listItem[WebInspector.ThreadsSidebarPane._targetSymbol] = target;
117 this._subtargetToListItem.set(subtarget, listItem);
118 this.threadList.addItem(listItem);
119 listItem.element.addEventListener('click', this._onListItemClick.bind(this , listItem), false);
120 }
121 this._setupConnectionItem(listItem, subtarget);
122 this._updateDebuggerState(subtarget);
123 var currentTarget = WebInspector.context.flavor(WebInspector.Target);
124 if (currentTarget === target)
125 this._selectListItem(listItem);
126 if (target)
127 this._targetToSubtarget.set(target, subtarget);
33 } 128 }
34 129
35 /** 130 /**
36 * @override 131 * @override
37 * @param {!WebInspector.Target} target 132 * @param {!WebInspector.Target} target
38 */ 133 */
39 targetAdded(target) { 134 targetAdded(target) {
40 var debuggerModel = WebInspector.DebuggerModel.fromTarget(target); 135 if (target !== WebInspector.targetManager.mainTarget())
41 if (!debuggerModel)
42 return; 136 return;
43 137 if (this._mainTargetConnection)
dgozman 2016/11/02 23:20:40 Should not ever be a case, if you null-out mainTar
eostroukhov 2016/11/03 17:25:51 Done.
44 var listItem = new WebInspector.UIList.Item(this._titleForTarget(target), '' ); 138 this._targetRemoved(this._mainTargetConnection);
45 listItem.element.addEventListener('click', this._onListItemClick.bind(this, listItem), false); 139 this._mainTargetConnection = new WebInspector.ThreadsSidebarPane.MainTargetC onnection(target);
46 var currentTarget = WebInspector.context.flavor(WebInspector.Target); 140 this._addListItem(this._mainTargetConnection);
47 if (currentTarget === target)
48 this._selectListItem(listItem);
49
50 this._debuggerModelToListItems.set(debuggerModel, listItem);
51 this._listItemsToTargets.set(listItem, target);
52 this.threadList.addItem(listItem);
53 this._updateDebuggerState(debuggerModel);
54 } 141 }
55 142
56 /** 143 /**
57 * @override 144 * @override
58 * @param {!WebInspector.Target} target 145 * @param {!WebInspector.Target} target
59 */ 146 */
60 targetRemoved(target) { 147 targetRemoved(target) {
61 var debuggerModel = WebInspector.DebuggerModel.fromTarget(target); 148 var subtargetManager = WebInspector.SubTargetsManager.fromTarget(target);
62 if (!debuggerModel) 149 var subtargets = subtargetManager ? subtargetManager.subTargets() : [];
63 return; 150 for (var subtarget of subtargets) {
64 var listItem = this._debuggerModelToListItems.remove(debuggerModel); 151 if (subtarget.target())
65 if (listItem) { 152 this._targetRemoved(subtarget);
66 this._listItemsToTargets.remove(listItem);
67 this.threadList.removeItem(listItem);
68 } 153 }
154 if (target === WebInspector.targetManager.mainTarget() && this._mainTargetCo nnection)
155 this._targetRemoved(this._mainTargetConnection);
69 } 156 }
70 157
71 /** 158 /**
72 * @param {!WebInspector.Event} event 159 * @param {!WebInspector.Event} event
73 */ 160 */
74 _targetNameChanged(event) { 161 _targetNameChanged(event) {
75 var target = /** @type {!WebInspector.Target} */ (event.data); 162 var target = /** @type {!WebInspector.Target} */ (event.data);
76 var listItem = this._listItemForTarget(target); 163 var listItem = this._listItemForTarget(target);
77 if (listItem) 164 if (listItem)
78 listItem.setTitle(this._titleForTarget(target)); 165 listItem.setTitle(this._titleForSubtarget(this._targetToSubtarget.get(targ et)));
79 } 166 }
80 167
81 /** 168 /**
82 * @param {!WebInspector.Event} event 169 * @param {!WebInspector.Event} event
83 */ 170 */
84 _targetChanged(event) { 171 _targetChanged(event) {
85 var listItem = this._listItemForTarget(/** @type {!WebInspector.Target} */ ( event.data)); 172 var listItem = this._listItemForTarget(/** @type {!WebInspector.Target} */ ( event.data));
86 if (listItem) 173 if (listItem)
87 this._selectListItem(listItem); 174 this._selectListItem(listItem);
88 } 175 }
89 176
90 /** 177 /**
91 * @param {!WebInspector.Target} target 178 * @param {!WebInspector.Target} target
92 * @return {?WebInspector.UIList.Item} 179 * @return {?WebInspector.UIList.Item}
93 */ 180 */
94 _listItemForTarget(target) { 181 _listItemForTarget(target) {
95 var debuggerModel = WebInspector.DebuggerModel.fromTarget(target); 182 var subtarget = this._targetToSubtarget.get(target);
96 if (!debuggerModel) 183 return this._subtargetToListItem.get(subtarget) || null;
97 return null;
98 return this._debuggerModelToListItems.get(debuggerModel) || null;
99 } 184 }
100 185
101 /** 186 /**
102 * @param {!WebInspector.Target} target 187 * @param {!WebInspector.PendingSubTarget} subtarget
103 * @return {string} 188 * @return {string}
104 */ 189 */
105 _titleForTarget(target) { 190 _titleForSubtarget(subtarget) {
191 var target = subtarget.target();
192 if (!target)
193 return subtarget.name();
106 var executionContext = target.runtimeModel.defaultExecutionContext(); 194 var executionContext = target.runtimeModel.defaultExecutionContext();
107 return executionContext && executionContext.label() ? executionContext.label () : target.name(); 195 return executionContext && executionContext.label() ? executionContext.label () : target.name();
108 } 196 }
109 197
110 /** 198 /**
111 * @param {!WebInspector.Event} event 199 * @param {!WebInspector.Event} event
112 */ 200 */
113 _onDebuggerStateChanged(event) { 201 _onDebuggerStateChanged(event) {
114 var debuggerModel = /** @type {!WebInspector.DebuggerModel} */ (event.target ); 202 var debuggerModel = /** @type {!WebInspector.DebuggerModel} */ (event.target );
115 this._updateDebuggerState(debuggerModel); 203 var subtarget = this._targetToSubtarget.get(debuggerModel.target());
204 this._updateDebuggerState(subtarget);
116 } 205 }
117 206
118 /** 207 /**
119 * @param {!WebInspector.Event} event 208 * @param {!WebInspector.Event} event
120 */ 209 */
121 _onExecutionContextChanged(event) { 210 _onExecutionContextChanged(event) {
122 var executionContext = /** @type {!WebInspector.ExecutionContext} */ (event. data); 211 var executionContext = /** @type {!WebInspector.ExecutionContext} */ (event. data);
123 if (!executionContext.isDefault) 212 if (!executionContext.isDefault)
124 return; 213 return;
125 var debuggerModel = 214 var subtarget = this._targetToSubtarget.get(executionContext.target());
126 /** @type {!WebInspector.DebuggerModel} */ (WebInspector.DebuggerModel.f romTarget(executionContext.target())); 215 var listItem = this._subtargetToListItem.get(subtarget);
127 var listItem = this._debuggerModelToListItems.get(debuggerModel);
128 if (listItem && executionContext.label()) 216 if (listItem && executionContext.label())
129 listItem.setTitle(executionContext.label()); 217 listItem.setTitle(executionContext.label());
130 } 218 }
131 219
132 /** 220 /**
133 * @param {!WebInspector.DebuggerModel} debuggerModel 221 * @param {!WebInspector.PendingSubTarget} subtarget
134 */ 222 */
135 _updateDebuggerState(debuggerModel) { 223 _updateDebuggerState(subtarget) {
136 var listItem = this._debuggerModelToListItems.get(debuggerModel); 224 var listItem = this._subtargetToListItem.get(subtarget);
137 listItem.setSubtitle(WebInspector.UIString(debuggerModel.isPaused() ? 'pause d' : '')); 225 var target = subtarget.target();
226 var debuggerModel = target && WebInspector.DebuggerModel.fromTarget(target);
227 var isPaused = !!debuggerModel && debuggerModel.isPaused();
228 listItem.setSubtitle(WebInspector.UIString(isPaused ? 'paused' : ''));
138 } 229 }
139 230
140 /** 231 /**
141 * @param {!WebInspector.UIList.Item} listItem 232 * @param {!WebInspector.UIList.Item} listItem
142 */ 233 */
143 _selectListItem(listItem) { 234 _selectListItem(listItem) {
144 if (listItem === this._selectedListItem) 235 if (listItem === this._selectedListItem)
145 return; 236 return;
146 237
147 if (this._selectedListItem) 238 if (this._selectedListItem)
148 this._selectedListItem.setSelected(false); 239 this._selectedListItem.setSelected(false);
149 240
150 this._selectedListItem = listItem; 241 this._selectedListItem = listItem;
151 listItem.setSelected(true); 242 listItem.setSelected(true);
152 } 243 }
153 244
154 /** 245 /**
155 * @param {!WebInspector.UIList.Item} listItem 246 * @param {!WebInspector.UIList.Item} listItem
156 */ 247 */
157 _onListItemClick(listItem) { 248 _onListItemClick(listItem) {
158 WebInspector.context.setFlavor(WebInspector.Target, this._listItemsToTargets .get(listItem)); 249 var subtarget = listItem[WebInspector.ThreadsSidebarPane._subtargetSymbol];
250 var target = subtarget.target();
251 if (!target)
252 return;
253 WebInspector.context.setFlavor(WebInspector.Target, target);
159 listItem.element.scrollIntoViewIfNeeded(); 254 listItem.element.scrollIntoViewIfNeeded();
160 } 255 }
256
257 /**
258 * @param {!WebInspector.UIList.Item} item
259 * @param {!WebInspector.PendingSubTarget} subtarget
260 */
261 _setupConnectionItem(item, subtarget) {
dgozman 2016/11/02 23:20:40 nit: no connection anymore
eostroukhov 2016/11/03 17:25:51 Done.
262 item.setTitle(this._titleForSubtarget(subtarget));
263 item.setSubtitle('');
264 var target = subtarget.target();
265 var action = null;
266 var actionLabel = null;
267 if (subtarget.canConnect()) {
268 actionLabel = target ? 'Disconnect' : 'Connect';
269 action = this._toggleConnection.bind(this, subtarget);
270 }
271 item.setAction(actionLabel, action);
272 item.setDimmed(!target);
273 }
274
275 /**
276 * @param {!WebInspector.Target} target
277 */
278 _selectNewlyAddedTarget(target) {
279 setTimeout(() => WebInspector.context.setFlavor(WebInspector.Target, target) );
280 }
281
282 /**
283 * @param {!WebInspector.PendingSubTarget} subtarget
284 */
285 _toggleConnection(subtarget) {
286 var target = subtarget.target();
287 if (target)
288 subtarget.disconnect();
289 else
290 subtarget.connect().then(target => this._selectNewlyAddedTarget(target));
291 }
292
293 /**
294 * @param {!WebInspector.PendingSubTarget} subtarget
295 */
296 _targetRemoved(subtarget) {
297 var item = this._subtargetToListItem.get(subtarget);
298 if (!item) // Not all targets are represented in the UI.
299 return;
300 var target = item[WebInspector.ThreadsSidebarPane._targetSymbol];
301 item[WebInspector.ThreadsSidebarPane._targetSymbol] = null;
302 this._targetToSubtarget.remove(target);
303 if (subtarget.canConnect())
304 this._setupConnectionItem(item, subtarget);
305 else
306 this._removeListItem(subtarget);
307 }
308
309 /**
310 * @param {!WebInspector.PendingSubTarget} subtarget
311 */
312 _removeListItem(subtarget) {
313 var item = this._subtargetToListItem.get(subtarget);
314 if (!item)
315 return;
316 this.threadList.removeItem(item);
317 this._subtargetToListItem.delete(subtarget);
318 }
161 }; 319 };
320
321 WebInspector.ThreadsSidebarPane._subtargetSymbol = Symbol('_subtargetSymbol');
322 WebInspector.ThreadsSidebarPane._targetSymbol = Symbol('_targetSymbol');
323
324 /**
325 * @unrestricted
326 */
327 WebInspector.ThreadsSidebarPane.MainTargetConnection = class extends WebInspecto r.PendingSubTarget {
328 /**
329 * @param {!WebInspector.Target} target
330 */
331 constructor(target) {
332 super('main-target-list-node-' + target.id(), target.title, false, null);
333 this._target = target;
334 }
335
336 /**
337 * @override
338 * @return {!WebInspector.Target}
339 */
340 target() {
341 return this._target;
dgozman 2016/11/02 23:20:40 2 spaces
eostroukhov 2016/11/03 17:25:51 Done.
342 }
343
344 /**
345 * @override
346 * @return {string}
347 */
348 name() {
349 return this._target.name();
dgozman 2016/11/02 23:20:40 ditto
eostroukhov 2016/11/03 17:25:51 Done.
350 }
351 };
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698