Bug 1506784 - UX implementation: show debug target info in about:devtools-toolbox r=jdescottes,daisuke

Differential Revision: https://phabricator.services.mozilla.com/D16553

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Belén Albeza 2019-01-18 02:22:43 +00:00
Родитель 2604235be7
Коммит 2ae8206bc8
8 изменённых файлов: 202 добавлений и 40 удалений

Просмотреть файл

@ -6,6 +6,8 @@
const { PureComponent } = require("devtools/client/shared/vendor/react"); const { PureComponent } = require("devtools/client/shared/vendor/react");
const dom = require("devtools/client/shared/vendor/react-dom-factories"); const dom = require("devtools/client/shared/vendor/react-dom-factories");
const PropTypes = require("devtools/client/shared/vendor/react-prop-types"); const PropTypes = require("devtools/client/shared/vendor/react-prop-types");
const { CONNECTION_TYPES } =
require("devtools/client/shared/remote-debugging/remote-client-manager");
/** /**
* This is header that should be displayed on top of the toolbox when using * This is header that should be displayed on top of the toolbox when using
@ -15,6 +17,8 @@ class DebugTargetInfo extends PureComponent {
static get propTypes() { static get propTypes() {
return { return {
deviceDescription: PropTypes.shape({ deviceDescription: PropTypes.shape({
channel: PropTypes.string.isRequired,
connectionType: PropTypes.string,
deviceName: PropTypes.string, deviceName: PropTypes.string,
name: PropTypes.string.isRequired, name: PropTypes.string.isRequired,
version: PropTypes.string.isRequired, version: PropTypes.string.isRequired,
@ -24,37 +28,100 @@ class DebugTargetInfo extends PureComponent {
}; };
} }
getTargetText() {
const { L10N, toolbox } = this.props;
const name = toolbox.target.name;
const type = L10N.getStr("toolbox.debugTargetInfo.type.tab");
return L10N.getFormatStr("toolbox.debugTargetInfo.targetLabel", name, type);
}
getRuntimeText() { getRuntimeText() {
const { deviceDescription, L10N } = this.props; const { deviceDescription, L10N } = this.props;
const { name, deviceName, version } = deviceDescription; const { name, version, connectionType } = deviceDescription;
const localizationType =
deviceName ? "toolbox.debugTargetInfo.runtimeLabelWithDeviceName" return (connectionType === CONNECTION_TYPES.THIS_FIREFOX)
: "toolbox.debugTargetInfo.runtimeLabel"; ? L10N.getFormatStr("toolbox.debugTargetInfo.runtimeLabel.thisFirefox", version)
return L10N.getFormatStr(localizationType, name, version, deviceName); : L10N.getFormatStr("toolbox.debugTargetInfo.runtimeLabel", name, version);
}
getAssetsForConnectionType() {
const { connectionType } = this.props.deviceDescription;
const BASE_IMG_URL = "chrome://devtools/skin/images/";
switch (connectionType) {
case CONNECTION_TYPES.USB:
return {
image: `${BASE_IMG_URL}aboutdebugging-usb-icon.svg`,
l10nId: "toolbox.debugTargetInfo.connection.usb",
};
case CONNECTION_TYPES.NETWORK:
return {
image: `${BASE_IMG_URL}aboutdebugging-globe-icon.svg`,
l10nId: "toolbox.debugTargetInfo.connection.network",
};
}
}
shallRenderConnection() {
const { connectionType } = this.props.deviceDescription;
const renderableTypes = [
CONNECTION_TYPES.USB,
CONNECTION_TYPES.NETWORK,
];
return renderableTypes.includes(connectionType);
}
renderConnection() {
const { connectionType } = this.props.deviceDescription;
const { image, l10nId } = this.getAssetsForConnectionType();
return dom.span(
{
className: "iconized-label",
},
dom.img({ src: image, alt: `${connectionType} icon`}),
this.props.L10N.getStr(l10nId),
);
}
renderRuntime() {
const { channel, deviceName } = this.props.deviceDescription;
const channelIcon =
(channel === "release" || channel === "beta" || channel === "aurora") ?
`chrome://devtools/skin/images/aboutdebugging-firefox-${ channel }.svg` :
"chrome://devtools/skin/images/aboutdebugging-firefox-nightly.svg";
return dom.span(
{
className: "iconized-label",
},
dom.img({ src: channelIcon, className: "channel-icon" }),
dom.b({ className: "ellipsis-text" }, this.getRuntimeText()),
dom.span({ className: "ellipsis-text" }, deviceName),
);
}
renderTarget() {
const title = this.props.toolbox.target.name;
const url = this.props.toolbox.target.url;
// TODO: https://bugzilla.mozilla.org/show_bug.cgi?id=1520723
// Show actual favicon (currently toolbox.target.activeTab.favicon
// is unpopulated)
const favicon = "chrome://devtools/skin/images/aboutdebugging-globe-icon.svg";
return dom.span(
{
className: "iconized-label",
},
dom.img({ src: favicon, alt: "favicon"}),
title ? dom.b({ className: "ellipsis-text"}, title) : null,
dom.span({ className: "ellipsis-text" }, url),
);
} }
render() { render() {
const { deviceDescription } = this.props;
const { channel } = deviceDescription;
const icon =
(channel === "release" || channel === "beta" || channel === "aurora")
? `chrome://devtools/skin/images/aboutdebugging-firefox-${ channel }.svg`
: "chrome://devtools/skin/images/aboutdebugging-firefox-nightly.svg";
return dom.header( return dom.header(
{ {
className: "debug-target-info", className: "debug-target-info",
}, },
dom.img({ src: icon }), this.shallRenderConnection() ? this.renderConnection() : null,
dom.span({}, this.getRuntimeText()), this.renderRuntime(),
dom.span({ className: "target" }, this.getTargetText()), this.renderTarget(),
); );
} }
} }

Просмотреть файл

@ -76,6 +76,10 @@ loader.lazyGetter(this, "reloadAndRecordTab",
loader.lazyGetter(this, "reloadAndStopRecordingTab", loader.lazyGetter(this, "reloadAndStopRecordingTab",
() => require("devtools/client/webreplay/menu.js").reloadAndStopRecordingTab); () => require("devtools/client/webreplay/menu.js").reloadAndStopRecordingTab);
loader.lazyGetter(this, "remoteClientManager", () =>
require("devtools/client/shared/remote-debugging/remote-client-manager.js")
.remoteClientManager);
/** /**
* A "Toolbox" is the component that holds all the tools for one specific * A "Toolbox" is the component that holds all the tools for one specific
* target. Visually, it's a document that includes the tools tabs and all * target. Visually, it's a document that includes the tools tabs and all
@ -454,7 +458,10 @@ Toolbox.prototype = {
this._showDebugTargetInfo = true; this._showDebugTargetInfo = true;
const deviceFront = await this.target.client.mainRoot.getFront("device"); const deviceFront = await this.target.client.mainRoot.getFront("device");
// DebugTargetInfo requires the device description to be rendered. // DebugTargetInfo requires the device description to be rendered.
this._deviceDescription = await deviceFront.getDescription(); const description = await deviceFront.getDescription();
const remoteId = new this.win.URLSearchParams(this.win.location.href).get("remoteId");
const connectionType = remoteClientManager.getConnectionTypeByRemoteId(remoteId);
this._deviceDescription = Object.assign({}, description, { connectionType });
} }
// Start tracking network activity on toolbox open for targets such as tabs. // Start tracking network activity on toolbox open for targets such as tabs.

Просмотреть файл

@ -109,6 +109,8 @@ devtools.jar:
skin/images/aboutdebugging-firefox-nightly.svg (themes/images/aboutdebugging-firefox-nightly.svg) skin/images/aboutdebugging-firefox-nightly.svg (themes/images/aboutdebugging-firefox-nightly.svg)
skin/images/aboutdebugging-firefox-release.svg (themes/images/aboutdebugging-firefox-release.svg) skin/images/aboutdebugging-firefox-release.svg (themes/images/aboutdebugging-firefox-release.svg)
skin/images/aboutdebugging-globe-icon.svg (themes/images/aboutdebugging-globe-icon.svg) skin/images/aboutdebugging-globe-icon.svg (themes/images/aboutdebugging-globe-icon.svg)
skin/images/aboutdebugging-wifi-icon.svg (themes/images/aboutdebugging-wifi-icon.svg)
skin/images/aboutdebugging-usb-icon.svg (themes/images/aboutdebugging-usb-icon.svg)
skin/images/fox-smiling.svg (themes/images/fox-smiling.svg) skin/images/fox-smiling.svg (themes/images/fox-smiling.svg)
skin/images/grid.svg (themes/images/grid.svg) skin/images/grid.svg (themes/images/grid.svg)
skin/images/angle-swatch.svg (themes/images/angle-swatch.svg) skin/images/angle-swatch.svg (themes/images/angle-swatch.svg)

Просмотреть файл

@ -200,6 +200,13 @@ toolbox.options.enableNewDebugger.label=Enable new debugger frontend
# The version of runtime: %2$S # The version of runtime: %2$S
toolbox.debugTargetInfo.runtimeLabel=%1$S (%2$S) toolbox.debugTargetInfo.runtimeLabel=%1$S (%2$S)
# LOCALIZATION NOTE (toolbox.debugTargetInfo.runtimeLabel.thisFirefox): this is displayed
# as a toolbox header in about:devtools-toolbox, when inspecting the current Firefox runtime
# (for instance, when inspecting one of its tabs in about:debugging)
# e.g. This Firefox (65.0a1)
# The version of runtime: %S
toolbox.debugTargetInfo.runtimeLabel.thisFirefox=This Firefox (%S)
# LOCALIZATION NOTE (toolbox.debugTargetInfo.runtimeLabelWithDeviceName): This is displayed # LOCALIZATION NOTE (toolbox.debugTargetInfo.runtimeLabelWithDeviceName): This is displayed
# as a toolbox header in about:devtools-toolbox. about:devtools-toolbox is used for # as a toolbox header in about:devtools-toolbox. about:devtools-toolbox is used for
# instance when inspecting tabs in about:debugging. # instance when inspecting tabs in about:debugging.
@ -223,6 +230,12 @@ toolbox.debugTargetInfo.targetLabel=%1$S (%2$S)
# Currently, we support only this type. # Currently, we support only this type.
toolbox.debugTargetInfo.type.tab=tab toolbox.debugTargetInfo.type.tab=tab
# LOCALIZATION NOTE (toolbox.debugTargetInfo.connection.*): This is displayed in the
# toolbox header in about:devtools-toolbox, to indicate how the connection to the
# runtime being inspected was made.
toolbox.debugTargetInfo.connection.usb=USB
toolbox.debugTargetInfo.connection.network=Network
# LOCALIZATION NOTE (browserToolbox.statusMessage): This is the label # LOCALIZATION NOTE (browserToolbox.statusMessage): This is the label
# shown next to status details when the Browser Toolbox fails to connect or # shown next to status details when the Browser Toolbox fails to connect or
# appears to be taking a while to do so. # appears to be taking a while to do so.

Просмотреть файл

@ -4,6 +4,14 @@
"use strict"; "use strict";
/* connection types for remote clients */
const CONNECTION_TYPES = {
THIS_FIREFOX: "this-firefox",
USB: "usb",
NETWORK: "network",
UNKNOWN: "unknown",
};
/** /**
* This class is designed to be a singleton shared by all DevTools to get access to * This class is designed to be a singleton shared by all DevTools to get access to
* existing clients created for remote debugging. * existing clients created for remote debugging.
@ -68,10 +76,31 @@ class RemoteClientManager {
return this._clients.get(key); return this._clients.get(key);
} }
/**
* Retrieve a managed client for a remote id. The remote id should have been generated
* using getRemoteId.
*/
getConnectionTypeByRemoteId(remoteId) {
if (!remoteId) {
return CONNECTION_TYPES.THIS_FIREFOX;
}
const key = decodeURIComponent(remoteId);
const type = this._getType(key);
return Object.values(CONNECTION_TYPES).includes(type)
? type
: CONNECTION_TYPES.UNKNOWN;
}
_getKey(id, type) { _getKey(id, type) {
return id + "-" + type; return id + "-" + type;
} }
_getType(key) {
const chunks = key.split("-");
return chunks[chunks.length - 1];
}
_removeClientByKey(key) { _removeClientByKey(key) {
const client = this._clients.get(key); const client = this._clients.get(key);
if (client) { if (client) {
@ -95,4 +124,7 @@ class RemoteClientManager {
} }
// Expose a singleton of RemoteClientManager. // Expose a singleton of RemoteClientManager.
exports.remoteClientManager = new RemoteClientManager(); module.exports = {
remoteClientManager: new RemoteClientManager(),
CONNECTION_TYPES,
};

Просмотреть файл

@ -0,0 +1,6 @@
<!-- This Source Code Form is subject to the terms of the Mozilla Public
- License, v. 2.0. If a copy of the MPL was not distributed with this
- file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
<svg data-name="usb" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16">
<path fill="context-fill" d="M13.5 4h-2a.5.5 0 0 0-.5.5v2a.5.5 0 0 0 .5.5h.44c-.17.63-.69.8-1.56 1A4.76 4.76 0 0 0 9 8.53V4h1.07a.46.46 0 0 0 .37-.74L8.37.5a.46.46 0 0 0-.74 0L5.56 3.26a.46.46 0 0 0 .37.74H7v6.53A4.76 4.76 0 0 0 5.62 10C4.71 9.79 4.17 9.61 4 8.9a1.5 1.5 0 1 0-2-1.4 1.49 1.49 0 0 0 1 1.42c.2 1.51 1.42 1.84 2.34 2.07s1.53.43 1.6 1.3a2 2 0 1 0 2 0V10.5C9 9.44 9.56 9.25 10.62 9s2.1-.54 2.33-2h.55a.5.5 0 0 0 .5-.5v-2a.5.5 0 0 0-.5-.5z" />
</svg>

После

Ширина:  |  Высота:  |  Размер: 753 B

Просмотреть файл

@ -0,0 +1,9 @@
<!-- This Source Code Form is subject to the terms of the Mozilla Public
- License, v. 2.0. If a copy of the MPL was not distributed with this
- file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
<svg data-name="wifi" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16">
<path fill="context-fill" d="M15 6.24a1 1 0 0 1-.58-.18 10.94 10.94 0 0 0-12.78 0A1 1 0 0 1 .45 4.43a12.94 12.94 0 0 1 15.1 0 1 1 0 0 1 .23 1.4 1 1 0 0 1-.78.41z"/>
<path fill="context-fill" d="M9.74 13.56a1 1 0 0 1-.58-.18 2 2 0 0 0-2.32 0 1 1 0 0 1-1.16-1.63 4 4 0 0 1 4.64 0 1 1 0 0 1 .23 1.4 1 1 0 0 1-.81.41z"/>
<path fill="context-fill" d="M11.48 11.12a1 1 0 0 1-.58-.19 5.05 5.05 0 0 0-5.8 0 1 1 0 1 1-1.17-1.62 7.1 7.1 0 0 1 8.14 0 1 1 0 0 1 .23 1.4 1 1 0 0 1-.82.41z"/>
<path fill="context-fill" d="M13.23 8.68a1 1 0 0 1-.59-.18 8.06 8.06 0 0 0-9.28 0A1 1 0 0 1 2 8.26a1 1 0 0 1 .23-1.39 10 10 0 0 1 11.62 0A1 1 0 0 1 14 8.26a1 1 0 0 1-.77.42z"/>
</svg>

После

Ширина:  |  Высота:  |  Размер: 961 B

Просмотреть файл

@ -3,29 +3,55 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this * License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
/*
* Utils
*/
/* text that needs to be cut with … */
.ellipsis-text {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
/* /*
* Debug Target Info layout * Debug Target Info layout
* +------+-------------------+------------------+ * +------------+--------------+------------------------+
* | icon | runtime info text | target info text | * | connection | runtime info | target info icon + text |
* | 32px | auto | 1fr | * +------------+--------------+------------------------+
* +------+-------------------+------------------+
*/ */
.debug-target-info { .debug-target-info {
display: grid; display: flex;
grid-template-columns: 32px auto 1fr;
grid-column-gap: 8px;
align-items: center;
background: var(--theme-tab-toolbar-background); background: var(--theme-tab-toolbar-background);
border-bottom: 1px solid var(--theme-splitter-color); border-bottom: 1px solid var(--theme-splitter-color);
padding-bottom: 4px; padding: 4px 0;
padding-left: 12px; font-size: 1.2em;
padding-top: 4px;
font-size: 1.46em;
color: var(--theme-toolbar-color); color: var(--theme-toolbar-color);
} }
.debug-target-info .target { /*
font-weight: lighter; * Debug Target labels with icon layout
* +------+------------------------+---------------+
* | icon | label text (bold) | optional text |
* | 20px | max-content | max-content |
* +------+------------------------+---------------+
*/
.debug-target-info .iconized-label {
display: grid;
grid-template-columns: 20px auto auto;
grid-column-gap: 8px;
align-items: center;
padding: 0 24px;
white-space: nowrap;
}
.debug-target-info .iconized-label:not(:last-child) {
border-right: 1px solid var(--theme-splitter-color);
}
.debug-target-info img {
-moz-context-properties: fill, stroke;
fill: var(--theme-toolbar-icon-color);
} }
/* Toolbox tabbar */ /* Toolbox tabbar */
@ -615,5 +641,5 @@
} }
.webreplay-player #overlay .tick:hover ~ .tick { .webreplay-player #overlay .tick:hover ~ .tick {
opacity: 0.5; opacity: 0.5;
} }