Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 }; | |
| OLD | NEW |