Chromium Code Reviews| Index: third_party/WebKit/Source/devtools/front_end/sources/ThreadsSidebarPane.js |
| diff --git a/third_party/WebKit/Source/devtools/front_end/sources/ThreadsSidebarPane.js b/third_party/WebKit/Source/devtools/front_end/sources/ThreadsSidebarPane.js |
| index 2cfed689bcb276bd3ed0b734ab604dd455bf2104..6726e6f4be214ff98e3d6f69c6f36b68317c113a 100644 |
| --- a/third_party/WebKit/Source/devtools/front_end/sources/ThreadsSidebarPane.js |
| +++ b/third_party/WebKit/Source/devtools/front_end/sources/ThreadsSidebarPane.js |
| @@ -9,12 +9,14 @@ WebInspector.ThreadsSidebarPane = class extends WebInspector.VBox { |
| constructor() { |
| super(); |
| - /** @type {!Map.<!WebInspector.DebuggerModel, !WebInspector.UIList.Item>} */ |
| - this._debuggerModelToListItems = new Map(); |
| - /** @type {!Map.<!WebInspector.UIList.Item, !WebInspector.Target>} */ |
| - this._listItemsToTargets = new Map(); |
| /** @type {?WebInspector.UIList.Item} */ |
| this._selectedListItem = null; |
| + /** @type {!Map<!WebInspector.PendingSubTarget, !WebInspector.UIList.Item>} */ |
| + this._subtargetToListItem = new Map(); |
|
dgozman
2016/11/02 23:20:40
pendingToListItem
eostroukhov
2016/11/03 17:25:52
Done.
|
| + /** @type {!Map<!WebInspector.Target, !WebInspector.PendingSubTarget>} */ |
| + this._targetToSubtarget = new Map(); |
|
dgozman
2016/11/02 23:20:40
targetToPending
eostroukhov
2016/11/03 17:25:52
Done.
|
| + /** @type {?WebInspector.PendingSubTarget} */ |
| + this._mainTargetConnection = null; |
|
dgozman
2016/11/02 23:20:40
_mainPendingTarget
eostroukhov
2016/11/03 17:25:52
"_mainTargetPending"? Still atrocious - but I don'
|
| this.threadList = new WebInspector.UIList(); |
| this.threadList.show(this.element); |
| WebInspector.targetManager.addModelListener( |
| @@ -29,28 +31,113 @@ WebInspector.ThreadsSidebarPane = class extends WebInspector.VBox { |
| WebInspector.context.addFlavorChangeListener(WebInspector.Target, this._targetChanged, this); |
| WebInspector.targetManager.addEventListener( |
| WebInspector.TargetManager.Events.NameChanged, this._targetNameChanged, this); |
| + WebInspector.targetManager.addModelListener(WebInspector.SubTargetsManager, WebInspector.SubTargetsManager.Events.SubTargetAdded, this._subTargetAdded, this); |
| + WebInspector.targetManager.addModelListener(WebInspector.SubTargetsManager, WebInspector.SubTargetsManager.Events.SubTargetRemoved, this._subTargetRemoved, this); |
| + WebInspector.targetManager.addModelListener(WebInspector.SubTargetsManager, WebInspector.SubTargetsManager.Events.SubTargetAttached, this._subTargetAdded, this); |
| + WebInspector.targetManager.addModelListener(WebInspector.SubTargetsManager, WebInspector.SubTargetsManager.Events.SubTargetDetached, this._targetDetached, this); |
| WebInspector.targetManager.observeTargets(this); |
| + |
| + var subtargets = []; |
| + for (var target of WebInspector.targetManager.targets(WebInspector.Target.Capability.Target)) |
| + subtargets = subtargets.concat(WebInspector.SubTargetsManager.fromTarget(target).subTargets()); |
| + |
| + subtargets |
| + .sort(WebInspector.ThreadsSidebarPane._subTargetsComparator) |
| + .forEach(subtarget => this._addListItem(subtarget)); |
| } |
| /** |
| - * @override |
| - * @param {!WebInspector.Target} target |
| + * @return {boolean} |
| */ |
| - targetAdded(target) { |
| - var debuggerModel = WebInspector.DebuggerModel.fromTarget(target); |
| - if (!debuggerModel) |
| + 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.
|
| + if (WebInspector.targetManager.targets(WebInspector.Target.Capability.JS).length > 1) |
| + return true; |
| + for (var target of WebInspector.targetManager.targets(WebInspector.Target.Capability.Target)) { |
| + if (WebInspector.SubTargetsManager.fromTarget(target).subTargets().some(subtarget => subtarget.canConnect())) |
| + return true; |
| + } |
| + return false; |
| + } |
| + |
| + /** |
| + * Sorts show tha connected targets appear first, followed by pending subtargets. |
| + * |
| + * @param {!WebInspector.PendingSubTarget} c1 |
| + * @param {!WebInspector.PendingSubTarget} c2 |
| + * @return {number} |
| + */ |
| + static _subTargetsComparator(c1, c2) |
| + { |
| + var t1 = c1.target(); |
| + var t2 = c2.target(); |
| + var name1 = t1 ? t1.name() : c1.name(); |
| + var name2 = t2 ? t2.name() : c2.name(); |
| + if (!!t1 === !!t2) { // Either both are connected or disconnected |
| + return name1.toLowerCase().localeCompare(name2.toLowerCase()); |
| + } else if (t1) { |
| + return -1; |
| + } |
| + return 1; |
| + } |
| + |
| + /** |
| + * @param {!WebInspector.Event} event |
| + */ |
| + _subTargetAdded(event) { |
| + this._addListItem(/** @type {!WebInspector.PendingSubTarget} */ (event.data)); |
| + } |
| + |
| + /** |
| + * @param {!WebInspector.Event} event |
| + */ |
| + _subTargetRemoved(event) { |
| + this._removeListItem(/** @type {!WebInspector.PendingSubTarget} */ (event.data)); |
| + } |
| + |
| + /** |
| + * @param {!WebInspector.Event} event |
| + */ |
| + _targetDetached(event) { |
| + this._targetRemoved(/** @type {!WebInspector.PendingSubTarget} */ (event.data)); |
| + } |
| + |
| + /** |
| + * @param {!WebInspector.PendingSubTarget} subtarget |
| + */ |
| + _addListItem(subtarget) { |
| + var target = subtarget.target(); |
| + if (!subtarget.canConnect() && !(target && target.hasJSCapability())) |
| return; |
| - var listItem = new WebInspector.UIList.Item(this._titleForTarget(target), ''); |
| - listItem.element.addEventListener('click', this._onListItemClick.bind(this, listItem), false); |
| + var listItem = this._subtargetToListItem.get(subtarget); |
| + if (!listItem) { |
| + listItem = new WebInspector.UIList.Item('', '', false); |
| + listItem[WebInspector.ThreadsSidebarPane._subtargetSymbol] = subtarget; |
| + listItem[WebInspector.ThreadsSidebarPane._targetSymbol] = target; |
| + this._subtargetToListItem.set(subtarget, listItem); |
| + this.threadList.addItem(listItem); |
| + listItem.element.addEventListener('click', this._onListItemClick.bind(this, listItem), false); |
| + } |
| + this._setupConnectionItem(listItem, subtarget); |
| + this._updateDebuggerState(subtarget); |
| var currentTarget = WebInspector.context.flavor(WebInspector.Target); |
| if (currentTarget === target) |
| this._selectListItem(listItem); |
| + if (target) |
| + this._targetToSubtarget.set(target, subtarget); |
| + } |
| - this._debuggerModelToListItems.set(debuggerModel, listItem); |
| - this._listItemsToTargets.set(listItem, target); |
| - this.threadList.addItem(listItem); |
| - this._updateDebuggerState(debuggerModel); |
| + /** |
| + * @override |
| + * @param {!WebInspector.Target} target |
| + */ |
| + targetAdded(target) { |
| + if (target !== WebInspector.targetManager.mainTarget()) |
| + return; |
| + 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.
|
| + this._targetRemoved(this._mainTargetConnection); |
| + this._mainTargetConnection = new WebInspector.ThreadsSidebarPane.MainTargetConnection(target); |
| + this._addListItem(this._mainTargetConnection); |
| } |
| /** |
| @@ -58,14 +145,14 @@ WebInspector.ThreadsSidebarPane = class extends WebInspector.VBox { |
| * @param {!WebInspector.Target} target |
| */ |
| targetRemoved(target) { |
| - var debuggerModel = WebInspector.DebuggerModel.fromTarget(target); |
| - if (!debuggerModel) |
| - return; |
| - var listItem = this._debuggerModelToListItems.remove(debuggerModel); |
| - if (listItem) { |
| - this._listItemsToTargets.remove(listItem); |
| - this.threadList.removeItem(listItem); |
| + var subtargetManager = WebInspector.SubTargetsManager.fromTarget(target); |
| + var subtargets = subtargetManager ? subtargetManager.subTargets() : []; |
| + for (var subtarget of subtargets) { |
| + if (subtarget.target()) |
| + this._targetRemoved(subtarget); |
| } |
| + if (target === WebInspector.targetManager.mainTarget() && this._mainTargetConnection) |
| + this._targetRemoved(this._mainTargetConnection); |
| } |
| /** |
| @@ -75,7 +162,7 @@ WebInspector.ThreadsSidebarPane = class extends WebInspector.VBox { |
| var target = /** @type {!WebInspector.Target} */ (event.data); |
| var listItem = this._listItemForTarget(target); |
| if (listItem) |
| - listItem.setTitle(this._titleForTarget(target)); |
| + listItem.setTitle(this._titleForSubtarget(this._targetToSubtarget.get(target))); |
| } |
| /** |
| @@ -92,17 +179,18 @@ WebInspector.ThreadsSidebarPane = class extends WebInspector.VBox { |
| * @return {?WebInspector.UIList.Item} |
| */ |
| _listItemForTarget(target) { |
| - var debuggerModel = WebInspector.DebuggerModel.fromTarget(target); |
| - if (!debuggerModel) |
| - return null; |
| - return this._debuggerModelToListItems.get(debuggerModel) || null; |
| + var subtarget = this._targetToSubtarget.get(target); |
| + return this._subtargetToListItem.get(subtarget) || null; |
| } |
| /** |
| - * @param {!WebInspector.Target} target |
| + * @param {!WebInspector.PendingSubTarget} subtarget |
| * @return {string} |
| */ |
| - _titleForTarget(target) { |
| + _titleForSubtarget(subtarget) { |
| + var target = subtarget.target(); |
| + if (!target) |
| + return subtarget.name(); |
| var executionContext = target.runtimeModel.defaultExecutionContext(); |
| return executionContext && executionContext.label() ? executionContext.label() : target.name(); |
| } |
| @@ -112,7 +200,8 @@ WebInspector.ThreadsSidebarPane = class extends WebInspector.VBox { |
| */ |
| _onDebuggerStateChanged(event) { |
| var debuggerModel = /** @type {!WebInspector.DebuggerModel} */ (event.target); |
| - this._updateDebuggerState(debuggerModel); |
| + var subtarget = this._targetToSubtarget.get(debuggerModel.target()); |
| + this._updateDebuggerState(subtarget); |
| } |
| /** |
| @@ -122,19 +211,21 @@ WebInspector.ThreadsSidebarPane = class extends WebInspector.VBox { |
| var executionContext = /** @type {!WebInspector.ExecutionContext} */ (event.data); |
| if (!executionContext.isDefault) |
| return; |
| - var debuggerModel = |
| - /** @type {!WebInspector.DebuggerModel} */ (WebInspector.DebuggerModel.fromTarget(executionContext.target())); |
| - var listItem = this._debuggerModelToListItems.get(debuggerModel); |
| + var subtarget = this._targetToSubtarget.get(executionContext.target()); |
| + var listItem = this._subtargetToListItem.get(subtarget); |
| if (listItem && executionContext.label()) |
| listItem.setTitle(executionContext.label()); |
| } |
| /** |
| - * @param {!WebInspector.DebuggerModel} debuggerModel |
| + * @param {!WebInspector.PendingSubTarget} subtarget |
| */ |
| - _updateDebuggerState(debuggerModel) { |
| - var listItem = this._debuggerModelToListItems.get(debuggerModel); |
| - listItem.setSubtitle(WebInspector.UIString(debuggerModel.isPaused() ? 'paused' : '')); |
| + _updateDebuggerState(subtarget) { |
| + var listItem = this._subtargetToListItem.get(subtarget); |
| + var target = subtarget.target(); |
| + var debuggerModel = target && WebInspector.DebuggerModel.fromTarget(target); |
| + var isPaused = !!debuggerModel && debuggerModel.isPaused(); |
| + listItem.setSubtitle(WebInspector.UIString(isPaused ? 'paused' : '')); |
| } |
| /** |
| @@ -155,7 +246,106 @@ WebInspector.ThreadsSidebarPane = class extends WebInspector.VBox { |
| * @param {!WebInspector.UIList.Item} listItem |
| */ |
| _onListItemClick(listItem) { |
| - WebInspector.context.setFlavor(WebInspector.Target, this._listItemsToTargets.get(listItem)); |
| + var subtarget = listItem[WebInspector.ThreadsSidebarPane._subtargetSymbol]; |
| + var target = subtarget.target(); |
| + if (!target) |
| + return; |
| + WebInspector.context.setFlavor(WebInspector.Target, target); |
| listItem.element.scrollIntoViewIfNeeded(); |
| } |
| + |
| + /** |
| + * @param {!WebInspector.UIList.Item} item |
| + * @param {!WebInspector.PendingSubTarget} subtarget |
| + */ |
| + _setupConnectionItem(item, subtarget) { |
|
dgozman
2016/11/02 23:20:40
nit: no connection anymore
eostroukhov
2016/11/03 17:25:51
Done.
|
| + item.setTitle(this._titleForSubtarget(subtarget)); |
| + item.setSubtitle(''); |
| + var target = subtarget.target(); |
| + var action = null; |
| + var actionLabel = null; |
| + if (subtarget.canConnect()) { |
| + actionLabel = target ? 'Disconnect' : 'Connect'; |
| + action = this._toggleConnection.bind(this, subtarget); |
| + } |
| + item.setAction(actionLabel, action); |
| + item.setDimmed(!target); |
| + } |
| + |
| + /** |
| + * @param {!WebInspector.Target} target |
| + */ |
| + _selectNewlyAddedTarget(target) { |
| + setTimeout(() => WebInspector.context.setFlavor(WebInspector.Target, target)); |
| + } |
| + |
| + /** |
| + * @param {!WebInspector.PendingSubTarget} subtarget |
| + */ |
| + _toggleConnection(subtarget) { |
| + var target = subtarget.target(); |
| + if (target) |
| + subtarget.disconnect(); |
| + else |
| + subtarget.connect().then(target => this._selectNewlyAddedTarget(target)); |
| + } |
| + |
| + /** |
| + * @param {!WebInspector.PendingSubTarget} subtarget |
| + */ |
| + _targetRemoved(subtarget) { |
| + var item = this._subtargetToListItem.get(subtarget); |
| + if (!item) // Not all targets are represented in the UI. |
| + return; |
| + var target = item[WebInspector.ThreadsSidebarPane._targetSymbol]; |
| + item[WebInspector.ThreadsSidebarPane._targetSymbol] = null; |
| + this._targetToSubtarget.remove(target); |
| + if (subtarget.canConnect()) |
| + this._setupConnectionItem(item, subtarget); |
| + else |
| + this._removeListItem(subtarget); |
| + } |
| + |
| + /** |
| + * @param {!WebInspector.PendingSubTarget} subtarget |
| + */ |
| + _removeListItem(subtarget) { |
| + var item = this._subtargetToListItem.get(subtarget); |
| + if (!item) |
| + return; |
| + this.threadList.removeItem(item); |
| + this._subtargetToListItem.delete(subtarget); |
| + } |
| +}; |
| + |
| +WebInspector.ThreadsSidebarPane._subtargetSymbol = Symbol('_subtargetSymbol'); |
| +WebInspector.ThreadsSidebarPane._targetSymbol = Symbol('_targetSymbol'); |
| + |
| +/** |
| + * @unrestricted |
| + */ |
| +WebInspector.ThreadsSidebarPane.MainTargetConnection = class extends WebInspector.PendingSubTarget { |
| + /** |
| + * @param {!WebInspector.Target} target |
| + */ |
| + constructor(target) { |
| + super('main-target-list-node-' + target.id(), target.title, false, null); |
| + this._target = target; |
| + } |
| + |
| + /** |
| + * @override |
| + * @return {!WebInspector.Target} |
| + */ |
| + target() { |
| + return this._target; |
|
dgozman
2016/11/02 23:20:40
2 spaces
eostroukhov
2016/11/03 17:25:51
Done.
|
| + } |
| + |
| + /** |
| + * @override |
| + * @return {string} |
| + */ |
| + name() { |
| + return this._target.name(); |
|
dgozman
2016/11/02 23:20:40
ditto
eostroukhov
2016/11/03 17:25:51
Done.
|
| + } |
| }; |