From 068bfeb48bb00771b224f9fda1bfc7cb8d217e12 Mon Sep 17 00:00:00 2001 From: Micah Tigley Date: Thu, 7 May 2020 17:22:16 +0000 Subject: [PATCH] Bug 1617237 - Part 2: Render URL input in DebugTargetInfo for USB debugging. r=jdescottes,daisuke Depends on D70280 Differential Revision: https://phabricator.services.mozilla.com/D70279 --- .../framework/components/DebugTargetInfo.js | 77 +++++++++++++++++-- devtools/client/themes/toolbox.css | 35 ++++++++- 2 files changed, 103 insertions(+), 9 deletions(-) diff --git a/devtools/client/framework/components/DebugTargetInfo.js b/devtools/client/framework/components/DebugTargetInfo.js index 13615b4f5d60..8921acaffe1f 100644 --- a/devtools/client/framework/components/DebugTargetInfo.js +++ b/devtools/client/framework/components/DebugTargetInfo.js @@ -3,6 +3,7 @@ * You can obtain one at http://mozilla.org/MPL/2.0/. */ "use strict"; +const Services = require("Services"); const { PureComponent } = require("devtools/client/shared/vendor/react"); const dom = require("devtools/client/shared/vendor/react-dom-factories"); const PropTypes = require("devtools/client/shared/vendor/react-prop-types"); @@ -35,6 +36,15 @@ class DebugTargetInfo extends PureComponent { }; } + constructor(props) { + super(props); + + this.state = { urlValue: props.toolbox.target.url }; + + this.onChange = this.onChange.bind(this); + this.onSubmit = this.onSubmit.bind(this); + } + componentDidMount() { this.updateTitle(); } @@ -136,6 +146,32 @@ class DebugTargetInfo extends PureComponent { } } + onChange({ target }) { + this.setState({ urlValue: target.value }); + } + + onSubmit(event) { + event.preventDefault(); + let url = this.state.urlValue; + + if (!url || !url.length) { + return; + } + + try { + // Get the URL from the fixup service: + const flags = Services.uriFixup.FIXUP_FLAG_FIX_SCHEME_TYPOS; + const uriInfo = Services.uriFixup.getFixupURIInfo(url, flags); + url = uriInfo.fixedURI.spec; + } catch (ex) { + // The getFixupURIInfo service will throw an error if a malformed URI is + // produced from the input. + console.error(ex); + } + + this.props.toolbox.target.navigateTo({ url }); + } + shallRenderConnection() { const { connectionType } = this.props.debugTargetData; const renderableTypes = [CONNECTION_TYPES.USB, CONNECTION_TYPES.NETWORK]; @@ -176,21 +212,49 @@ class DebugTargetInfo extends PureComponent { ); } - renderTarget() { + renderTargetTitle() { const title = this.props.toolbox.target.name; - const url = this.props.toolbox.target.url; const { image, l10nId } = this.getAssetsForDebugTargetType(); return dom.span( { - className: "iconized-label", + className: "iconized-label debug-target-title", }, dom.img({ src: image, alt: this.props.L10N.getStr(l10nId) }), title ? dom.b({ className: "devtools-ellipsis-text qa-target-title" }, title) - : null, - dom.span({ className: "devtools-ellipsis-text" }, url) + : null + ); + } + + renderTargetURI() { + const url = this.props.toolbox.target.url; + const { targetType } = this.props.debugTargetData; + const isURLEditable = targetType === DEBUG_TARGET_TYPES.TAB; + + return dom.span( + { + key: url, + className: "debug-target-url", + }, + isURLEditable + ? this.renderTargetInput(url) + : dom.span({ className: "devtools-ellipsis-text" }, url) + ); + } + + renderTargetInput(url) { + return dom.form( + { + className: "debug-target-url-form", + onSubmit: this.onSubmit, + }, + dom.input({ + className: "devtools-textinput debug-target-url-input", + onChange: this.onChange, + defaultValue: url, + }) ); } @@ -201,7 +265,8 @@ class DebugTargetInfo extends PureComponent { }, this.shallRenderConnection() ? this.renderConnection() : null, this.renderRuntime(), - this.renderTarget() + this.renderTargetTitle(), + this.renderTargetURI() ); } } diff --git a/devtools/client/themes/toolbox.css b/devtools/client/themes/toolbox.css index 33ed6a5f6ab2..8e57d977c74d 100644 --- a/devtools/client/themes/toolbox.css +++ b/devtools/client/themes/toolbox.css @@ -9,11 +9,13 @@ * +------------+--------------+------------------------+ */ .debug-target-info { + --border-inline-end-width: 1px; + --padding-inline-end-size: 24px; display: flex; background: var(--theme-tab-toolbar-background); border-bottom: 1px solid var(--theme-splitter-color); padding: 4px 0; - font-size: 1.2em; + font-size: 1.35em; color: var(--theme-toolbar-color); } @@ -29,12 +31,12 @@ grid-template-columns: 20px auto auto; grid-column-gap: 8px; align-items: center; - padding: 0 24px; + padding: 0 var(--padding-inline-end-size); white-space: nowrap; } .debug-target-info .iconized-label:not(:last-child) { - border-inline-end: 1px solid var(--theme-splitter-color); + border-inline-end: var(--border-inline-end-width) solid var(--theme-splitter-color); } .debug-target-info .iconized-label img { @@ -47,6 +49,33 @@ fill: var(--theme-toolbar-color); } + +/* DebugTargetInfo's renderTargetTitle() component should look like it's in the same + section as renderTargetURI() */ +.debug-target-info .debug-target-title { + --border-inline-end-width: 0; + padding-inline-end: 0; +} + +.debug-target-info .debug-target-url { + display: flex; + flex-grow: 1; + padding-inline-end: var(--padding-inline-end-size); + align-self: center; +} + +.debug-target-info .debug-target-url-input { + border: 1px solid var(--theme-toolbarbutton-active-background); + border-radius: 2px; + height: 20px; + padding-inline-start: 10px; +} + +.debug-target-info .debug-target-url-input, +.debug-target-info .debug-target-url-form { + width: 100%; +} + /* Toolbox tabbar */ .devtools-tabbar {