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

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

Issue 2431223003: [DevTools]: Require explicit connection (Closed)
Patch Set: Addressed one last comment 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.PendingTarget, !WebInspector.UIList.Item>} */
15 this._pendingToListItem = new Map();
16 /** @type {!Map<!WebInspector.Target, !WebInspector.PendingTarget>} */
17 this._targetToPending = new Map();
18 /** @type {?WebInspector.PendingTarget} */
19 this._mainTargetPending = null;
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.PendingTargetAdded, this._addTargetItem, t his);
35 WebInspector.targetManager.addModelListener(WebInspector.SubTargetsManager, WebInspector.SubTargetsManager.Events.PendingTargetRemoved, this._pendingTargetR emoved, this);
36 WebInspector.targetManager.addModelListener(WebInspector.SubTargetsManager, WebInspector.SubTargetsManager.Events.PendingTargetAttached, this._addTargetItem , this);
37 WebInspector.targetManager.addModelListener(WebInspector.SubTargetsManager, WebInspector.SubTargetsManager.Events.PendingTargetDetached, this._targetDetache d, this);
32 WebInspector.targetManager.observeTargets(this); 38 WebInspector.targetManager.observeTargets(this);
39
40 var pendingTargets = [];
41 for (var target of WebInspector.targetManager.targets(WebInspector.Target.Ca pability.Target))
42 pendingTargets = pendingTargets.concat(WebInspector.SubTargetsManager.from Target(target).pendingTargets());
43
44 pendingTargets
45 .sort(WebInspector.ThreadsSidebarPane._pendingTargetsComparator)
46 .forEach(pendingTarget => this._addListItem(pendingTarget));
47 }
48
49 /**
50 * @return {boolean}
51 */
52 static shouldBeShown() {
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 var pendingTargets = WebInspector.SubTargetsManager.fromTarget(target).pen dingTargets();
57 if (pendingTargets.some(pendingTarget => pendingTarget.canConnect()))
58 return true;
59 }
60 return false;
61 }
62
63 /**
64 * Sorts show tha connected targets appear first, followed by pending subtarge ts.
65 *
66 * @param {!WebInspector.PendingTarget} c1
67 * @param {!WebInspector.PendingTarget} c2
68 * @return {number}
69 */
70 static _pendingTargetsComparator(c1, c2)
71 {
72 var t1 = c1.target();
73 var t2 = c2.target();
74 var name1 = t1 ? t1.name() : c1.name();
75 var name2 = t2 ? t2.name() : c2.name();
76 if (!!t1 === !!t2) { // Either both are connected or disconnected
77 return name1.toLowerCase().localeCompare(name2.toLowerCase());
78 } else if (t1) {
79 return -1;
80 }
81 return 1;
82 }
83
84 /**
85 * @param {!WebInspector.Event} event
86 */
87 _addTargetItem(event) {
88 this._addListItem(/** @type {!WebInspector.PendingTarget} */ (event.data));
89 }
90
91 /**
92 * @param {!WebInspector.Event} event
93 */
94 _pendingTargetRemoved(event) {
95 this._removeListItem(/** @type {!WebInspector.PendingTarget} */ (event.data) );
96 }
97
98 /**
99 * @param {!WebInspector.Event} event
100 */
101 _targetDetached(event) {
102 this._targetRemoved(/** @type {!WebInspector.PendingTarget} */ (event.data)) ;
103 }
104
105 /**
106 * @param {!WebInspector.PendingTarget} pendingTarget
107 */
108 _addListItem(pendingTarget) {
109 var target = pendingTarget.target();
110 if (!pendingTarget.canConnect() && !(target && target.hasJSCapability()))
111 return;
112
113 var listItem = this._pendingToListItem.get(pendingTarget);
114 if (!listItem) {
115 listItem = new WebInspector.UIList.Item('', '', false);
116 listItem[WebInspector.ThreadsSidebarPane._pendingTargetSymbol] = pendingTa rget;
117 listItem[WebInspector.ThreadsSidebarPane._targetSymbol] = target;
118 this._pendingToListItem.set(pendingTarget, listItem);
119 this.threadList.addItem(listItem);
120 listItem.element.addEventListener('click', this._onListItemClick.bind(this , listItem), false);
121 }
122 this._updateListItem(listItem, pendingTarget);
123 this._updateDebuggerState(pendingTarget);
124 var currentTarget = WebInspector.context.flavor(WebInspector.Target);
125 if (currentTarget === target)
126 this._selectListItem(listItem);
127 if (target)
128 this._targetToPending.set(target, pendingTarget);
33 } 129 }
34 130
35 /** 131 /**
36 * @override 132 * @override
37 * @param {!WebInspector.Target} target 133 * @param {!WebInspector.Target} target
38 */ 134 */
39 targetAdded(target) { 135 targetAdded(target) {
40 var debuggerModel = WebInspector.DebuggerModel.fromTarget(target); 136 if (target !== WebInspector.targetManager.mainTarget())
41 if (!debuggerModel)
42 return; 137 return;
43 138 console.assert(!this._mainTargetPending);
44 var listItem = new WebInspector.UIList.Item(this._titleForTarget(target), '' ); 139 this._mainTargetPending = new WebInspector.ThreadsSidebarPane.MainTargetConn ection(target);
45 listItem.element.addEventListener('click', this._onListItemClick.bind(this, listItem), false); 140 this._addListItem(this._mainTargetPending);
46 var currentTarget = WebInspector.context.flavor(WebInspector.Target);
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 pendingTargets = subtargetManager ? subtargetManager.pendingTargets() : [];
63 return; 150 for (var pendingTarget of pendingTargets) {
64 var listItem = this._debuggerModelToListItems.remove(debuggerModel); 151 if (pendingTarget.target())
65 if (listItem) { 152 this._targetRemoved(pendingTarget);
66 this._listItemsToTargets.remove(listItem); 153 }
67 this.threadList.removeItem(listItem); 154 if (target === WebInspector.targetManager.mainTarget() && this._mainTargetPe nding) {
155 this._targetRemoved(this._mainTargetPending);
156 this._mainTargetPending = null;
68 } 157 }
69 } 158 }
70 159
71 /** 160 /**
72 * @param {!WebInspector.Event} event 161 * @param {!WebInspector.Event} event
73 */ 162 */
74 _targetNameChanged(event) { 163 _targetNameChanged(event) {
75 var target = /** @type {!WebInspector.Target} */ (event.data); 164 var target = /** @type {!WebInspector.Target} */ (event.data);
76 var listItem = this._listItemForTarget(target); 165 var listItem = this._listItemForTarget(target);
77 if (listItem) 166 if (listItem)
78 listItem.setTitle(this._titleForTarget(target)); 167 listItem.setTitle(this._titleForPending(this._targetToPending.get(target)) );
79 } 168 }
80 169
81 /** 170 /**
82 * @param {!WebInspector.Event} event 171 * @param {!WebInspector.Event} event
83 */ 172 */
84 _targetChanged(event) { 173 _targetChanged(event) {
85 var listItem = this._listItemForTarget(/** @type {!WebInspector.Target} */ ( event.data)); 174 var listItem = this._listItemForTarget(/** @type {!WebInspector.Target} */ ( event.data));
86 if (listItem) 175 if (listItem)
87 this._selectListItem(listItem); 176 this._selectListItem(listItem);
88 } 177 }
89 178
90 /** 179 /**
91 * @param {!WebInspector.Target} target 180 * @param {!WebInspector.Target} target
92 * @return {?WebInspector.UIList.Item} 181 * @return {?WebInspector.UIList.Item}
93 */ 182 */
94 _listItemForTarget(target) { 183 _listItemForTarget(target) {
95 var debuggerModel = WebInspector.DebuggerModel.fromTarget(target); 184 var pendingTarget = this._targetToPending.get(target);
96 if (!debuggerModel) 185 return this._pendingToListItem.get(pendingTarget) || null;
97 return null;
98 return this._debuggerModelToListItems.get(debuggerModel) || null;
99 } 186 }
100 187
101 /** 188 /**
102 * @param {!WebInspector.Target} target 189 * @param {!WebInspector.PendingTarget} pendingTarget
103 * @return {string} 190 * @return {string}
104 */ 191 */
105 _titleForTarget(target) { 192 _titleForPending(pendingTarget) {
193 var target = pendingTarget.target();
194 if (!target)
195 return pendingTarget.name();
106 var executionContext = target.runtimeModel.defaultExecutionContext(); 196 var executionContext = target.runtimeModel.defaultExecutionContext();
107 return executionContext && executionContext.label() ? executionContext.label () : target.name(); 197 return executionContext && executionContext.label() ? executionContext.label () : target.name();
108 } 198 }
109 199
110 /** 200 /**
111 * @param {!WebInspector.Event} event 201 * @param {!WebInspector.Event} event
112 */ 202 */
113 _onDebuggerStateChanged(event) { 203 _onDebuggerStateChanged(event) {
114 var debuggerModel = /** @type {!WebInspector.DebuggerModel} */ (event.target ); 204 var debuggerModel = /** @type {!WebInspector.DebuggerModel} */ (event.target );
115 this._updateDebuggerState(debuggerModel); 205 var pendingTarget = this._targetToPending.get(debuggerModel.target());
206 this._updateDebuggerState(pendingTarget);
116 } 207 }
117 208
118 /** 209 /**
119 * @param {!WebInspector.Event} event 210 * @param {!WebInspector.Event} event
120 */ 211 */
121 _onExecutionContextChanged(event) { 212 _onExecutionContextChanged(event) {
122 var executionContext = /** @type {!WebInspector.ExecutionContext} */ (event. data); 213 var executionContext = /** @type {!WebInspector.ExecutionContext} */ (event. data);
123 if (!executionContext.isDefault) 214 if (!executionContext.isDefault)
124 return; 215 return;
125 var debuggerModel = 216 var pendingTarget = this._targetToPending.get(executionContext.target());
126 /** @type {!WebInspector.DebuggerModel} */ (WebInspector.DebuggerModel.f romTarget(executionContext.target())); 217 var listItem = this._pendingToListItem.get(pendingTarget);
127 var listItem = this._debuggerModelToListItems.get(debuggerModel);
128 if (listItem && executionContext.label()) 218 if (listItem && executionContext.label())
129 listItem.setTitle(executionContext.label()); 219 listItem.setTitle(executionContext.label());
130 } 220 }
131 221
132 /** 222 /**
133 * @param {!WebInspector.DebuggerModel} debuggerModel 223 * @param {!WebInspector.PendingTarget} pendingTarget
134 */ 224 */
135 _updateDebuggerState(debuggerModel) { 225 _updateDebuggerState(pendingTarget) {
136 var listItem = this._debuggerModelToListItems.get(debuggerModel); 226 var listItem = this._pendingToListItem.get(pendingTarget);
137 listItem.setSubtitle(WebInspector.UIString(debuggerModel.isPaused() ? 'pause d' : '')); 227 var target = pendingTarget.target();
228 var debuggerModel = target && WebInspector.DebuggerModel.fromTarget(target);
229 var isPaused = !!debuggerModel && debuggerModel.isPaused();
230 listItem.setSubtitle(WebInspector.UIString(isPaused ? 'paused' : ''));
138 } 231 }
139 232
140 /** 233 /**
141 * @param {!WebInspector.UIList.Item} listItem 234 * @param {!WebInspector.UIList.Item} listItem
142 */ 235 */
143 _selectListItem(listItem) { 236 _selectListItem(listItem) {
144 if (listItem === this._selectedListItem) 237 if (listItem === this._selectedListItem)
145 return; 238 return;
146 239
147 if (this._selectedListItem) 240 if (this._selectedListItem)
148 this._selectedListItem.setSelected(false); 241 this._selectedListItem.setSelected(false);
149 242
150 this._selectedListItem = listItem; 243 this._selectedListItem = listItem;
151 listItem.setSelected(true); 244 listItem.setSelected(true);
152 } 245 }
153 246
154 /** 247 /**
155 * @param {!WebInspector.UIList.Item} listItem 248 * @param {!WebInspector.UIList.Item} listItem
156 */ 249 */
157 _onListItemClick(listItem) { 250 _onListItemClick(listItem) {
158 WebInspector.context.setFlavor(WebInspector.Target, this._listItemsToTargets .get(listItem)); 251 var pendingTarget = listItem[WebInspector.ThreadsSidebarPane._pendingTargetS ymbol];
252 var target = pendingTarget.target();
253 if (!target)
254 return;
255 WebInspector.context.setFlavor(WebInspector.Target, target);
159 listItem.element.scrollIntoViewIfNeeded(); 256 listItem.element.scrollIntoViewIfNeeded();
160 } 257 }
258
259 /**
260 * @param {!WebInspector.UIList.Item} item
261 * @param {!WebInspector.PendingTarget} pendingTarget
262 */
263 _updateListItem(item, pendingTarget) {
264 item.setTitle(this._titleForPending(pendingTarget));
265 item.setSubtitle('');
266 var target = pendingTarget.target();
267 var action = null;
268 var actionLabel = null;
269 if (pendingTarget.canConnect()) {
270 actionLabel = target ? 'Disconnect' : 'Connect';
271 action = this._toggleConnection.bind(this, pendingTarget);
272 }
273 item.setAction(actionLabel, action);
274 item.setDimmed(!target);
275 }
276
277 /**
278 * @param {!WebInspector.Target} target
279 */
280 _selectNewlyAddedTarget(target) {
281 setTimeout(() => WebInspector.context.setFlavor(WebInspector.Target, target) );
282 }
283
284 /**
285 * @param {!WebInspector.PendingTarget} pendingTarget
286 * @return {!Promise}
287 */
288 _toggleConnection(pendingTarget) {
289 var target = pendingTarget.target();
290 if (target)
291 return pendingTarget.detach();
292 else
293 return pendingTarget.attach().then(target => this._selectNewlyAddedTarget( target));
294 }
295
296 /**
297 * @param {!WebInspector.PendingTarget} pendingTarget
298 */
299 _targetRemoved(pendingTarget) {
300 var item = this._pendingToListItem.get(pendingTarget);
301 if (!item) // Not all targets are represented in the UI.
302 return;
303 var target = item[WebInspector.ThreadsSidebarPane._targetSymbol];
304 item[WebInspector.ThreadsSidebarPane._targetSymbol] = null;
305 this._targetToPending.remove(target);
306 if (pendingTarget.canConnect())
307 this._updateListItem(item, pendingTarget);
308 else
309 this._removeListItem(pendingTarget);
310 }
311
312 /**
313 * @param {!WebInspector.PendingTarget} pendingTarget
314 */
315 _removeListItem(pendingTarget) {
316 var item = this._pendingToListItem.get(pendingTarget);
317 if (!item)
318 return;
319 this.threadList.removeItem(item);
320 this._pendingToListItem.delete(pendingTarget);
321 }
161 }; 322 };
323
324 WebInspector.ThreadsSidebarPane._pendingTargetSymbol = Symbol('_subtargetSymbol' );
325 WebInspector.ThreadsSidebarPane._targetSymbol = Symbol('_targetSymbol');
326
327 /**
328 * @unrestricted
329 */
330 WebInspector.ThreadsSidebarPane.MainTargetConnection = class extends WebInspecto r.PendingTarget {
331 /**
332 * @param {!WebInspector.Target} target
333 */
334 constructor(target) {
335 super('main-target-list-node-' + target.id(), target.title, false, null);
336 this._target = target;
337 }
338
339 /**
340 * @override
341 * @return {!WebInspector.Target}
342 */
343 target() {
344 return this._target;
345 }
346
347 /**
348 * @override
349 * @return {string}
350 */
351 name() {
352 return this._target.name();
353 }
354 };
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698