diff --git a/BUILD.gn b/BUILD.gn index 731a4d5e21..8ed7791564 100644 --- a/BUILD.gn +++ b/BUILD.gn @@ -305,6 +305,7 @@ all_devtools_files = [ "front_end/main/GCActionDelegate.js", "front_end/main/Main.js", "front_end/main/module.json", + "front_end/main/nodeIcon.css", "front_end/main/remoteDebuggingTerminatedScreen.css", "front_end/main/renderingOptions.css", "front_end/main/RenderingOptions.js", @@ -823,6 +824,7 @@ devtools_image_files = [ "front_end/Images/ic_warning_black_18dp.svg", "front_end/Images/navigationControls.png", "front_end/Images/navigationControls_2x.png", + "front_end/Images/nodeIcon.png", "front_end/Images/popoverArrows.png", "front_end/Images/profileGroupIcon.png", "front_end/Images/profileIcon.png", diff --git a/front_end/Images/nodeIcon.png b/front_end/Images/nodeIcon.png new file mode 100644 index 0000000000..a7929a98eb Binary files /dev/null and b/front_end/Images/nodeIcon.png differ diff --git a/front_end/main/Main.js b/front_end/main/Main.js index f89d2f43be..949c844490 100644 --- a/front_end/main/Main.js +++ b/front_end/main/Main.js @@ -729,6 +729,37 @@ Main.Main.MainMenuItem = class { } }; +/** + * @implements {UI.ToolbarItem.Provider} + */ +Main.Main.NodeIndicator = class { + constructor() { + var element = createElement('div'); + var shadowRoot = UI.createShadowRootWithCoreStyles(element, 'main/nodeIcon.css'); + this._element = shadowRoot.createChild('div', 'node-icon'); + element.addEventListener('click', () => InspectorFrontendHost.openNodeFrontend(), false); + this._button = new UI.ToolbarItem(element); + this._button.setTitle(Common.UIString('Open dedicated DevTools for Node.js')); + SDK.targetManager.addEventListener(SDK.TargetManager.Events.AvailableNodeTargetsChanged, this._update, this); + this._button.setVisible(false); + this._update(); + } + + _update() { + this._element.classList.toggle('inactive', !SDK.targetManager.availableNodeTargetsCount()); + if (SDK.targetManager.availableNodeTargetsCount()) + this._button.setVisible(true); + } + + /** + * @override + * @return {?UI.ToolbarItem} + */ + item() { + return this._button; + } +}; + Main.NetworkPanelIndicator = class { constructor() { // TODO: we should not access network from other modules. diff --git a/front_end/main/module.json b/front_end/main/module.json index 591621bfbf..538e46319b 100644 --- a/front_end/main/module.json +++ b/front_end/main/module.json @@ -202,6 +202,13 @@ "location": "main-toolbar-left", "order": 100 }, + { + "type": "@UI.ToolbarItem.Provider", + "className": "Main.Main.NodeIndicator", + "order": 2, + "location": "main-toolbar-left", + "condition": "!nodeFrontend" + }, { "type": "@UI.ToolbarItem.Provider", "className": "Main.Main.WarningErrorCounter", @@ -441,6 +448,7 @@ ], "resources": [ "errorWarningCounter.css", + "nodeIcon.css", "remoteDebuggingTerminatedScreen.css", "renderingOptions.css", "targetCrashedScreen.css" diff --git a/front_end/main/nodeIcon.css b/front_end/main/nodeIcon.css new file mode 100644 index 0000000000..326247d333 --- /dev/null +++ b/front_end/main/nodeIcon.css @@ -0,0 +1,23 @@ +/* + * Copyright 2017 The Chromium Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +.node-icon { + width: 28px; + height: 26px; + background-image: url(Images/nodeIcon.png); + background-size: 17px 17px; + background-repeat: no-repeat; + background-position: center; + opacity: 0.8; +} + +.node-icon:hover { + opacity: 1.0; +} + +.node-icon.inactive { + filter: grayscale(100%); +} diff --git a/front_end/sdk/TargetManager.js b/front_end/sdk/TargetManager.js index f7105c3895..2275b75102 100644 --- a/front_end/sdk/TargetManager.js +++ b/front_end/sdk/TargetManager.js @@ -328,9 +328,9 @@ SDK.TargetManager = class extends Common.Object { _connectAndCreateMainTarget() { if (Runtime.queryParam('nodeFrontend')) { var target = new SDK.Target( - this, 'main', Common.UIString('Node'), SDK.Target.Capability.Target, this._createMainConnection.bind(this), + this, 'main', Common.UIString('Node.js'), SDK.Target.Capability.Target, this._createMainConnection.bind(this), null); - target.setInspectedURL('Node'); + target.setInspectedURL('Node.js'); this._childTargetManagers.set(target, new SDK.ChildTargetManager(this, target)); Host.userMetrics.actionTaken(Host.UserMetrics.Action.ConnectToNodeJSFromFrontend); return; @@ -410,13 +410,15 @@ SDK.ChildTargetManager = class { if (Runtime.experiments.isEnabled('autoAttachToCrossProcessSubframes')) this._targetAgent.setAttachToFrames(true); - if (!parentTarget.parentTarget()) + if (!parentTarget.parentTarget()) { this._targetAgent.setDiscoverTargets(true); - - if (Runtime.queryParam('nodeFrontend') && !this._parentTarget.parentTarget()) { - InspectorFrontendHost.setDevicesUpdatesEnabled(true); - InspectorFrontendHost.events.addEventListener( - InspectorFrontendHostAPI.Events.DevicesDiscoveryConfigChanged, this._devicesDiscoveryConfigChanged, this); + if (Runtime.queryParam('nodeFrontend')) { + InspectorFrontendHost.setDevicesUpdatesEnabled(true); + InspectorFrontendHost.events.addEventListener( + InspectorFrontendHostAPI.Events.DevicesDiscoveryConfigChanged, this._devicesDiscoveryConfigChanged, this); + } else { + this._targetAgent.setRemoteLocations([{host: 'localhost', port: 9229}]); + } } } @@ -429,7 +431,8 @@ SDK.ChildTargetManager = class { for (var address of config.networkDiscoveryConfig) { var parts = address.split(':'); var port = parseInt(parts[1], 10); - locations.push({host: parts[0] || 'localhost', port: port || 9229}); + if (parts[0] && port) + locations.push({host: parts[0], port: port}); } this._targetAgent.setRemoteLocations(locations); } @@ -513,7 +516,7 @@ SDK.ChildTargetManager = class { attachedToTarget(targetInfo, waitingForDebugger) { var targetName = ''; if (targetInfo.type === 'node') { - targetName = Common.UIString('Node: %s', targetInfo.url); + targetName = Common.UIString('Node.js: %s', targetInfo.url); } else if (targetInfo.type !== 'iframe') { var parsedURL = targetInfo.url.asParsedURL(); targetName = diff --git a/front_end/sources/ThreadsSidebarPane.js b/front_end/sources/ThreadsSidebarPane.js index 7ce72ce12b..0abf5a482d 100644 --- a/front_end/sources/ThreadsSidebarPane.js +++ b/front_end/sources/ThreadsSidebarPane.js @@ -16,14 +16,7 @@ Sources.ThreadsSidebarPane = class extends UI.VBox { this._list = new UI.ListControl(this._items, this, UI.ListMode.NonViewport); this.contentElement.appendChild(this._list.element); - this._availableNodeTargetsElement = this.contentElement.createChild('div', 'hidden available-node-targets'); - UI.context.addFlavorChangeListener(SDK.Target, this._targetFlavorChanged, this); - - SDK.targetManager.addEventListener( - SDK.TargetManager.Events.AvailableNodeTargetsChanged, this._availableNodeTargetsChanged, this); - this._availableNodeTargetsChanged(); - SDK.targetManager.observeModels(SDK.DebuggerModel, this); } @@ -32,27 +25,7 @@ Sources.ThreadsSidebarPane = class extends UI.VBox { */ static shouldBeShown() { var minJSTargets = Runtime.queryParam('nodeFrontend') ? 1 : 2; - if (SDK.targetManager.models(SDK.DebuggerModel).length >= minJSTargets) - return true; - return !!SDK.targetManager.availableNodeTargetsCount(); - } - - _availableNodeTargetsChanged() { - var count = SDK.targetManager.availableNodeTargetsCount(); - if (!count) { - this._availableNodeTargetsElement.classList.add('hidden'); - return; - } - this._availableNodeTargetsElement.removeChildren(); - this._availableNodeTargetsElement.createTextChild( - count === 1 ? Common.UIString('Node instance available.') : - Common.UIString('%d Node instances available.', count)); - var link = this._availableNodeTargetsElement.createChild('span', 'link'); - link.textContent = Common.UIString('Connect'); - link.addEventListener('click', () => { - InspectorFrontendHost.openNodeFrontend(); - }, false); - this._availableNodeTargetsElement.classList.remove('hidden'); + return SDK.targetManager.models(SDK.DebuggerModel).length >= minJSTargets; } /** diff --git a/front_end/sources/threadsSidebarPane.css b/front_end/sources/threadsSidebarPane.css index f4a8d8fde5..6863de6d1e 100644 --- a/front_end/sources/threadsSidebarPane.css +++ b/front_end/sources/threadsSidebarPane.css @@ -4,20 +4,6 @@ * found in the LICENSE file. */ -.available-node-targets { - height: 22px; - display: flex; - align-items: center; - justify-content: flex-start; - padding-left: 20px; - border-top: 1px solid #eee; - font-style: italic; -} - -.available-node-targets > span { - margin-left: 5px; -} - .thread-item { padding: 3px 8px 3px 20px; position: relative;