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

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

Issue 2625223002: [DevTools] Dedicated frontend for debugging Node. (Closed)
Patch Set: test fix Created 3 years, 11 months 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 {SDK.TargetManager.Observer} 5 * @implements {SDK.TargetManager.Observer}
6 * @unrestricted 6 * @unrestricted
7 */ 7 */
8 Sources.ThreadsSidebarPane = class extends UI.VBox { 8 Sources.ThreadsSidebarPane = class extends UI.VBox {
9 constructor() { 9 constructor() {
10 super(); 10 super();
11 11
12 /** @type {?Sources.UIList.Item} */ 12 /** @type {?Sources.UIList.Item} */
13 this._selectedListItem = null; 13 this._selectedListItem = null;
14 /** @type {!Map<!SDK.PendingTarget, !Sources.UIList.Item>} */ 14 /** @type {!Map<!SDK.Target, !Sources.UIList.Item>} */
15 this._pendingToListItem = new Map(); 15 this._targetToListItem = new Map();
16 /** @type {!Map<!SDK.Target, !SDK.PendingTarget>} */ 16
17 this._targetToPending = new Map();
18 /** @type {?SDK.PendingTarget} */
19 this._mainTargetPending = null;
20 this.threadList = new Sources.UIList(); 17 this.threadList = new Sources.UIList();
21 this.threadList.show(this.element); 18 this.threadList.show(this.element);
19
20 this._availableNodeTargetsElement = this.element.createChild('div', 'hidden available-node-targets');
21
22 SDK.targetManager.addModelListener( 22 SDK.targetManager.addModelListener(
23 SDK.DebuggerModel, SDK.DebuggerModel.Events.DebuggerPaused, this._onDebu ggerStateChanged, this); 23 SDK.DebuggerModel, SDK.DebuggerModel.Events.DebuggerPaused, this._onDebu ggerStateChanged, this);
24 SDK.targetManager.addModelListener( 24 SDK.targetManager.addModelListener(
25 SDK.DebuggerModel, SDK.DebuggerModel.Events.DebuggerResumed, this._onDeb uggerStateChanged, this); 25 SDK.DebuggerModel, SDK.DebuggerModel.Events.DebuggerResumed, this._onDeb uggerStateChanged, this);
26 SDK.targetManager.addModelListener( 26 SDK.targetManager.addModelListener(
27 SDK.RuntimeModel, SDK.RuntimeModel.Events.ExecutionContextChanged, this. _onExecutionContextChanged, this); 27 SDK.RuntimeModel, SDK.RuntimeModel.Events.ExecutionContextChanged, this. _onExecutionContextChanged, this);
28 UI.context.addFlavorChangeListener(SDK.Target, this._targetChanged, this); 28 UI.context.addFlavorChangeListener(SDK.Target, this._targetChanged, this);
29 SDK.targetManager.addEventListener(SDK.TargetManager.Events.NameChanged, thi s._targetNameChanged, this); 29 SDK.targetManager.addEventListener(SDK.TargetManager.Events.NameChanged, thi s._targetNameChanged, this);
30 SDK.targetManager.addModelListener( 30 SDK.targetManager.addModelListener(
31 SDK.SubTargetsManager, SDK.SubTargetsManager.Events.PendingTargetAdded, this._addTargetItem, this); 31 SDK.SubTargetsManager, SDK.SubTargetsManager.Events.AvailableNodeTargets Changed,
32 SDK.targetManager.addModelListener( 32 this._availableNodeTargetsChanged, this);
33 SDK.SubTargetsManager, SDK.SubTargetsManager.Events.PendingTargetRemoved , this._pendingTargetRemoved, this); 33 SDK.targetManager.observeTargets(this, SDK.Target.Capability.JS);
34 SDK.targetManager.addModelListener( 34 this._availableNodeTargetsChanged();
35 SDK.SubTargetsManager, SDK.SubTargetsManager.Events.PendingTargetAttache d, this._addTargetItem, this);
36 SDK.targetManager.addModelListener(
37 SDK.SubTargetsManager, SDK.SubTargetsManager.Events.PendingTargetDetache d, this._targetDetached, this);
38 SDK.targetManager.observeTargets(this);
39
40 var pendingTargets = [];
41 for (var target of SDK.targetManager.targets(SDK.Target.Capability.Target))
42 pendingTargets = pendingTargets.concat(SDK.SubTargetsManager.fromTarget(ta rget).pendingTargets());
43
44 pendingTargets.sort(Sources.ThreadsSidebarPane._pendingTargetsComparator)
45 .forEach(pendingTarget => this._addListItem(pendingTarget));
46 } 35 }
47 36
48 /** 37 /**
49 * @return {boolean} 38 * @return {boolean}
50 */ 39 */
51 static shouldBeShown() { 40 static shouldBeShown() {
52 if (SDK.targetManager.targets(SDK.Target.Capability.JS).length > 1) 41 var minJSTargets = Runtime.queryParam('nodeFrontend') ? 1 : 2;
42 if (SDK.targetManager.targets(SDK.Target.Capability.JS).length >= minJSTarge ts)
53 return true; 43 return true;
54 for (var target of SDK.targetManager.targets(SDK.Target.Capability.Target)) { 44 if (Sources.ThreadsSidebarPane.availableNodeTargetsCount())
55 var pendingTargets = SDK.SubTargetsManager.fromTarget(target).pendingTarge ts(); 45 return true;
56 if (pendingTargets.some(pendingTarget => pendingTarget.canConnect()))
57 return true;
58 }
59 return false; 46 return false;
60 } 47 }
61 48
62 /** 49 /**
63 * Sorts show tha connected targets appear first, followed by pending subtarge ts.
64 *
65 * @param {!SDK.PendingTarget} c1
66 * @param {!SDK.PendingTarget} c2
67 * @return {number} 50 * @return {number}
68 */ 51 */
69 static _pendingTargetsComparator(c1, c2) { 52 static availableNodeTargetsCount() {
70 var t1 = c1.target(); 53 var count = 0;
71 var t2 = c2.target(); 54 for (var target of SDK.targetManager.targets(SDK.Target.Capability.Target))
72 var name1 = t1 ? t1.name() : c1.name(); 55 count += SDK.SubTargetsManager.fromTarget(target).availableNodeTargetsCoun t();
73 var name2 = t2 ? t2.name() : c2.name(); 56
74 if (!!t1 === !!t2) { // Either both are connected or disconnected 57 return count;
75 return name1.toLowerCase().localeCompare(name2.toLowerCase()); 58 }
76 } else if (t1) { 59
77 return -1; 60 _availableNodeTargetsChanged() {
61 var count = Sources.ThreadsSidebarPane.availableNodeTargetsCount();
62 if (!count) {
63 this._availableNodeTargetsElement.classList.add('hidden');
64 return;
78 } 65 }
79 return 1; 66 this._availableNodeTargetsElement.removeChildren();
67 this._availableNodeTargetsElement.createTextChild(
68 count === 1 ? Common.UIString('Node instance available.') :
69 Common.UIString('%d Node instances available.', count));
70 var link = this._availableNodeTargetsElement.createChild('span', 'link');
71 link.textContent = Common.UIString('Connect');
72 link.addEventListener('click', () => {
73 InspectorFrontendHost.openNodeFrontend();
74 }, false);
75 this._availableNodeTargetsElement.classList.remove('hidden');
80 } 76 }
81 77
82 /** 78 /**
83 * @param {!Common.Event} event
84 */
85 _addTargetItem(event) {
86 this._addListItem(/** @type {!SDK.PendingTarget} */ (event.data));
87 }
88
89 /**
90 * @param {!Common.Event} event
91 */
92 _pendingTargetRemoved(event) {
93 this._removeListItem(/** @type {!SDK.PendingTarget} */ (event.data));
94 }
95
96 /**
97 * @param {!Common.Event} event
98 */
99 _targetDetached(event) {
100 this._targetRemoved(/** @type {!SDK.PendingTarget} */ (event.data));
101 }
102
103 /**
104 * @param {!SDK.PendingTarget} pendingTarget
105 */
106 _addListItem(pendingTarget) {
107 var target = pendingTarget.target();
108 if (!pendingTarget.canConnect() && !(target && target.hasJSCapability()))
109 return;
110
111 var listItem = this._pendingToListItem.get(pendingTarget);
112 if (!listItem) {
113 listItem = new Sources.UIList.Item('', '', false);
114 listItem[Sources.ThreadsSidebarPane._pendingTargetSymbol] = pendingTarget;
115 listItem[Sources.ThreadsSidebarPane._targetSymbol] = target;
116 this._pendingToListItem.set(pendingTarget, listItem);
117 this.threadList.addItem(listItem);
118 listItem.element.addEventListener('click', this._onListItemClick.bind(this , listItem), false);
119 }
120 this._updateListItem(listItem, pendingTarget);
121 this._updateDebuggerState(pendingTarget);
122 var currentTarget = UI.context.flavor(SDK.Target);
123 if (currentTarget === target)
124 this._selectListItem(listItem);
125 if (target)
126 this._targetToPending.set(target, pendingTarget);
127 }
128
129 /**
130 * @override 79 * @override
131 * @param {!SDK.Target} target 80 * @param {!SDK.Target} target
132 */ 81 */
133 targetAdded(target) { 82 targetAdded(target) {
134 if (target !== SDK.targetManager.mainTarget()) 83 var listItem = new Sources.UIList.Item('', '', false);
135 return; 84 listItem.element.addEventListener('click', this._onListItemClick.bind(this, listItem, target), false);
136 console.assert(!this._mainTargetPending); 85 this._targetToListItem.set(target, listItem);
137 this._mainTargetPending = new Sources.ThreadsSidebarPane.MainTargetConnectio n(target); 86 this.threadList.addItem(listItem);
138 this._addListItem(this._mainTargetPending); 87 listItem.setTitle(this._titleForTarget(target));
88 this._updateDebuggerState(target);
89
90 var currentTarget = UI.context.flavor(SDK.Target);
91 if (currentTarget === target)
92 this._selectListItem(listItem);
139 } 93 }
140 94
141 /** 95 /**
142 * @override 96 * @override
143 * @param {!SDK.Target} target 97 * @param {!SDK.Target} target
144 */ 98 */
145 targetRemoved(target) { 99 targetRemoved(target) {
146 var subtargetManager = SDK.SubTargetsManager.fromTarget(target); 100 var item = this._targetToListItem.get(target);
147 var pendingTargets = subtargetManager ? subtargetManager.pendingTargets() : []; 101 if (!item)
148 for (var pendingTarget of pendingTargets) { 102 return;
149 if (pendingTarget.target()) 103 this.threadList.removeItem(item);
150 this._targetRemoved(pendingTarget); 104 this._targetToListItem.delete(target);
151 }
152 if (target === SDK.targetManager.mainTarget() && this._mainTargetPending) {
153 this._targetRemoved(this._mainTargetPending);
154 this._mainTargetPending = null;
155 }
156 } 105 }
157 106
158 /** 107 /**
159 * @param {!Common.Event} event 108 * @param {!Common.Event} event
160 */ 109 */
161 _targetNameChanged(event) { 110 _targetNameChanged(event) {
162 var target = /** @type {!SDK.Target} */ (event.data); 111 var target = /** @type {!SDK.Target} */ (event.data);
163 var listItem = this._listItemForTarget(target); 112 var listItem = this._targetToListItem.get(target);
164 if (listItem) 113 if (listItem)
165 listItem.setTitle(this._titleForPending(this._targetToPending.get(target)) ); 114 listItem.setTitle(this._titleForTarget(target));
166 } 115 }
167 116
168 /** 117 /**
169 * @param {!Common.Event} event 118 * @param {!Common.Event} event
170 */ 119 */
171 _targetChanged(event) { 120 _targetChanged(event) {
172 var listItem = this._listItemForTarget(/** @type {!SDK.Target} */ (event.dat a)); 121 var listItem = this._targetToListItem.get(/** @type {!SDK.Target} */ (event. data));
173 if (listItem) 122 if (listItem)
174 this._selectListItem(listItem); 123 this._selectListItem(listItem);
175 } 124 }
176 125
177 /** 126 /**
178 * @param {!SDK.Target} target 127 * @param {!SDK.Target} target
179 * @return {?Sources.UIList.Item}
180 */
181 _listItemForTarget(target) {
182 var pendingTarget = this._targetToPending.get(target);
183 return this._pendingToListItem.get(pendingTarget) || null;
184 }
185
186 /**
187 * @param {!SDK.PendingTarget} pendingTarget
188 * @return {string} 128 * @return {string}
189 */ 129 */
190 _titleForPending(pendingTarget) { 130 _titleForTarget(target) {
191 var target = pendingTarget.target();
192 if (!target)
193 return pendingTarget.name();
194 var executionContext = target.runtimeModel.defaultExecutionContext(); 131 var executionContext = target.runtimeModel.defaultExecutionContext();
195 return executionContext && executionContext.label() ? executionContext.label () : target.name(); 132 return executionContext && executionContext.label() ? executionContext.label () : target.name();
196 } 133 }
197 134
198 /** 135 /**
199 * @param {!Common.Event} event 136 * @param {!Common.Event} event
200 */ 137 */
201 _onDebuggerStateChanged(event) { 138 _onDebuggerStateChanged(event) {
202 var debuggerModel = /** @type {!SDK.DebuggerModel} */ (event.data); 139 var debuggerModel = /** @type {!SDK.DebuggerModel} */ (event.data);
203 var pendingTarget = this._targetToPending.get(debuggerModel.target()); 140 this._updateDebuggerState(debuggerModel.target());
204 this._updateDebuggerState(pendingTarget);
205 } 141 }
206 142
207 /** 143 /**
208 * @param {!Common.Event} event 144 * @param {!Common.Event} event
209 */ 145 */
210 _onExecutionContextChanged(event) { 146 _onExecutionContextChanged(event) {
211 var executionContext = /** @type {!SDK.ExecutionContext} */ (event.data); 147 var executionContext = /** @type {!SDK.ExecutionContext} */ (event.data);
212 if (!executionContext.isDefault) 148 var target = executionContext.target();
213 return; 149 var listItem = this._targetToListItem.get(target);
214 var pendingTarget = this._targetToPending.get(executionContext.target()); 150 if (listItem)
215 var listItem = this._pendingToListItem.get(pendingTarget); 151 listItem.setTitle(this._titleForTarget(target));
216 if (listItem && executionContext.label())
217 listItem.setTitle(executionContext.label());
218 } 152 }
219 153
220 /** 154 /**
221 * @param {!SDK.PendingTarget} pendingTarget 155 * @param {!SDK.Target} target
222 */ 156 */
223 _updateDebuggerState(pendingTarget) { 157 _updateDebuggerState(target) {
224 var listItem = this._pendingToListItem.get(pendingTarget); 158 var listItem = this._targetToListItem.get(target);
225 var target = pendingTarget.target(); 159 var debuggerModel = SDK.DebuggerModel.fromTarget(target);
226 var debuggerModel = target && SDK.DebuggerModel.fromTarget(target); 160 console.assert(debuggerModel);
227 var isPaused = !!debuggerModel && debuggerModel.isPaused(); 161 listItem.setSubtitle(Common.UIString(debuggerModel.isPaused() ? 'paused' : ' '));
228 listItem.setSubtitle(Common.UIString(isPaused ? 'paused' : ''));
229 } 162 }
230 163
231 /** 164 /**
232 * @param {!Sources.UIList.Item} listItem 165 * @param {!Sources.UIList.Item} listItem
233 */ 166 */
234 _selectListItem(listItem) { 167 _selectListItem(listItem) {
235 if (listItem === this._selectedListItem) 168 if (listItem === this._selectedListItem)
236 return; 169 return;
237 170
238 if (this._selectedListItem) 171 if (this._selectedListItem)
239 this._selectedListItem.setSelected(false); 172 this._selectedListItem.setSelected(false);
240 173
241 this._selectedListItem = listItem; 174 this._selectedListItem = listItem;
242 listItem.setSelected(true); 175 listItem.setSelected(true);
243 } 176 }
244 177
245 /** 178 /**
246 * @param {!Sources.UIList.Item} listItem 179 * @param {!Sources.UIList.Item} listItem
180 * @param {!SDK.Target} target
247 */ 181 */
248 _onListItemClick(listItem) { 182 _onListItemClick(listItem, target) {
249 var pendingTarget = listItem[Sources.ThreadsSidebarPane._pendingTargetSymbol ];
250 var target = pendingTarget.target();
251 if (!target)
252 return;
253 UI.context.setFlavor(SDK.Target, target); 183 UI.context.setFlavor(SDK.Target, target);
254 listItem.element.scrollIntoViewIfNeeded(); 184 listItem.element.scrollIntoViewIfNeeded();
255 } 185 }
256
257 /**
258 * @param {!Sources.UIList.Item} item
259 * @param {!SDK.PendingTarget} pendingTarget
260 */
261 _updateListItem(item, pendingTarget) {
262 item.setTitle(this._titleForPending(pendingTarget));
263 item.setSubtitle('');
264 var target = pendingTarget.target();
265 var action = null;
266 var actionLabel = null;
267 if (pendingTarget.canConnect()) {
268 actionLabel = target ? 'Disconnect' : 'Connect';
269 action = this._toggleConnection.bind(this, pendingTarget);
270 }
271 item.setAction(actionLabel, action);
272 item.setDimmed(!target);
273 }
274
275 /**
276 * @param {!SDK.Target} target
277 */
278 _selectNewlyAddedTarget(target) {
279 setTimeout(() => UI.context.setFlavor(SDK.Target, target));
280 }
281
282 /**
283 * @param {!SDK.PendingTarget} pendingTarget
284 * @return {!Promise}
285 */
286 _toggleConnection(pendingTarget) {
287 var target = pendingTarget.target();
288 if (target)
289 return pendingTarget.detach();
290 else
291 return pendingTarget.attach().then(target => this._selectNewlyAddedTarget( target));
292 }
293
294 /**
295 * @param {!SDK.PendingTarget} pendingTarget
296 */
297 _targetRemoved(pendingTarget) {
298 var item = this._pendingToListItem.get(pendingTarget);
299 if (!item) // Not all targets are represented in the UI.
300 return;
301 var target = item[Sources.ThreadsSidebarPane._targetSymbol];
302 item[Sources.ThreadsSidebarPane._targetSymbol] = null;
303 this._targetToPending.remove(target);
304 if (pendingTarget.canConnect())
305 this._updateListItem(item, pendingTarget);
306 else
307 this._removeListItem(pendingTarget);
308 }
309
310 /**
311 * @param {!SDK.PendingTarget} pendingTarget
312 */
313 _removeListItem(pendingTarget) {
314 var item = this._pendingToListItem.get(pendingTarget);
315 if (!item)
316 return;
317 this.threadList.removeItem(item);
318 this._pendingToListItem.delete(pendingTarget);
319 }
320 }; 186 };
321 187
322 Sources.ThreadsSidebarPane._pendingTargetSymbol = Symbol('_subtargetSymbol');
323 Sources.ThreadsSidebarPane._targetSymbol = Symbol('_targetSymbol'); 188 Sources.ThreadsSidebarPane._targetSymbol = Symbol('_targetSymbol');
324
325 /**
326 * @unrestricted
327 */
328 Sources.ThreadsSidebarPane.MainTargetConnection = class extends SDK.PendingTarge t {
329 /**
330 * @param {!SDK.Target} target
331 */
332 constructor(target) {
333 super('main-target-list-node-' + target.id(), target.title, false, null);
334 this._target = target;
335 }
336
337 /**
338 * @override
339 * @return {!SDK.Target}
340 */
341 target() {
342 return this._target;
343 }
344
345 /**
346 * @override
347 * @return {string}
348 */
349 name() {
350 return this._target.name();
351 }
352 };
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698