Bug 1505126: Part 2 - Render the ADB status into a new component, with an icon r=jdescottes,daisuke,Ola
authorBelén Albeza <balbeza@mozilla.com>
Thu, 25 Apr 2019 16:07:41 +0000
changeset 530145 155b510b215d6a95bfe57c36df1c57ca8bdfbeff
parent 530144 def772263e58819da4b777d99625496d2b87d848
child 530146 72ae3513844cdb10886cd351ad7bf7ea5d512248
push id11265
push userffxbld-merge
push dateMon, 13 May 2019 10:53:39 +0000
treeherdermozilla-beta@77e0fe8dbdd3 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjdescottes, daisuke, Ola
bugs1505126
milestone68.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1505126: Part 2 - Render the ADB status into a new component, with an icon r=jdescottes,daisuke,Ola Differential Revision: https://phabricator.services.mozilla.com/D28664
devtools/client/aboutdebugging-new/aboutdebugging.css
devtools/client/aboutdebugging-new/src/base.css
devtools/client/aboutdebugging-new/src/components/shared/IconLabel.css
devtools/client/aboutdebugging-new/src/components/shared/IconLabel.js
devtools/client/aboutdebugging-new/src/components/shared/moz.build
devtools/client/aboutdebugging-new/src/components/sidebar/Sidebar.js
devtools/client/aboutdebugging-new/src/components/sidebar/SidebarItem.css
devtools/client/aboutdebugging-new/src/constants.js
devtools/client/aboutdebugging-new/test/browser/browser_aboutdebugging_message_close.js
--- a/devtools/client/aboutdebugging-new/aboutdebugging.css
+++ b/devtools/client/aboutdebugging-new/aboutdebugging.css
@@ -21,13 +21,14 @@
 @import "resource://devtools/client/aboutdebugging-new/src/components/connect/NetworkLocationsForm.css";
 @import "resource://devtools/client/aboutdebugging-new/src/components/connect/NetworkLocationsList.css";
 @import "resource://devtools/client/aboutdebugging-new/src/components/debugtarget/DebugTargetItem.css";
 @import "resource://devtools/client/aboutdebugging-new/src/components/debugtarget/DebugTargetList.css";
 @import "resource://devtools/client/aboutdebugging-new/src/components/debugtarget/DebugTargetPane.css";
 @import "resource://devtools/client/aboutdebugging-new/src/components/debugtarget/FieldPair.css";
 @import "resource://devtools/client/aboutdebugging-new/src/components/debugtarget/ServiceWorkerAction.css";
 @import "resource://devtools/client/aboutdebugging-new/src/components/debugtarget/TemporaryExtensionInstallSection.css";
+@import "resource://devtools/client/aboutdebugging-new/src/components/shared/IconLabel.css";
 @import "resource://devtools/client/aboutdebugging-new/src/components/shared/Message.css";
 @import "resource://devtools/client/aboutdebugging-new/src/components/sidebar/Sidebar.css";
 @import "resource://devtools/client/aboutdebugging-new/src/components/sidebar/SidebarFixedItem.css";
 @import "resource://devtools/client/aboutdebugging-new/src/components/sidebar/SidebarItem.css";
 @import "resource://devtools/client/aboutdebugging-new/src/components/sidebar/SidebarRuntimeItem.css";
--- a/devtools/client/aboutdebugging-new/src/base.css
+++ b/devtools/client/aboutdebugging-new/src/base.css
@@ -72,17 +72,18 @@
   --page-width: 664px;
   --base-unit: 4px;
 
   /* Global styles */
   --base-font-style: message-box;
   --base-font-size: var(--body-10-font-size);
   --base-font-weight: var(--body-10-font-weight);
   --base-line-height: 1.8;
-  --message-font-size: 13px; /* Body 10 in Photon - https://design.firefox.com/photon/visuals/typography.html */
+  --icon-label-font-size: var(--body-10-font-size);
+  --message-font-size: var(--body-10-font-size);
   --button-font-size: var(--base-font-size);
   --micro-font-size: 11px;
   --monospace-font-family: monospace;
 
   --card-separator-color: var(--grey-20);
   --card-shadow-blur-radius: var(--base-unit);
 
   /*
new file mode 100644
--- /dev/null
+++ b/devtools/client/aboutdebugging-new/src/components/shared/IconLabel.css
@@ -0,0 +1,23 @@
+.icon-label {
+  display: flex;
+  column-gap: var(--base-unit);
+  align-items: center;
+  margin: calc(var(--base-unit) * 2) 0;
+  -moz-context-properties: fill;
+
+  font-size: var(--icon-label-font-size);
+}
+
+.icon-label--ok {
+  --icon-color: var(--green-70);
+}
+.icon-label--info {
+  --icon-color: var(--grey-90);
+}
+
+.icon-label__icon {
+  padding: var(--base-unit);
+  fill: var(--icon-color);
+  width: calc(var(--base-unit) * 4);
+  height: calc(var(--base-unit) * 4);
+}
new file mode 100644
--- /dev/null
+++ b/devtools/client/aboutdebugging-new/src/components/shared/IconLabel.js
@@ -0,0 +1,46 @@
+/* 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/. */
+
+"use strict";
+
+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");
+
+const { ICON_LABEL_LEVEL } = require("../../constants");
+
+const ICONS = {
+  [ICON_LABEL_LEVEL.INFO]: "chrome://global/skin/icons/info.svg",
+  [ICON_LABEL_LEVEL.OK]: "chrome://global/skin/icons/check.svg",
+};
+
+/* This component displays an icon accompanied by some content. It's similar
+   to a message, but it's not interactive */
+class IconLabel extends PureComponent {
+  static get propTypes() {
+    return {
+      children: PropTypes.node.isRequired,
+      className: PropTypes.string,
+      level: PropTypes.oneOf(Object.values(ICON_LABEL_LEVEL)).isRequired,
+    };
+  }
+
+  render() {
+    const { children, className, level } = this.props;
+    return dom.span(
+      {
+        className: `icon-label icon-label--${level} ${className || ""}`,
+      },
+      dom.img(
+        {
+          className: "icon-label__icon",
+          src: ICONS[level],
+        }
+      ),
+      children,
+    );
+  }
+}
+
+module.exports = IconLabel;
--- a/devtools/client/aboutdebugging-new/src/components/shared/moz.build
+++ b/devtools/client/aboutdebugging-new/src/components/shared/moz.build
@@ -1,8 +1,10 @@
 # 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/.
 
 DevToolsModules(
+    'IconLabel.css',
+    'IconLabel.js',
     'Message.css',
     'Message.js',
 )
--- a/devtools/client/aboutdebugging-new/src/components/sidebar/Sidebar.js
+++ b/devtools/client/aboutdebugging-new/src/components/sidebar/Sidebar.js
@@ -6,21 +6,21 @@
 
 const { createFactory, 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");
 
 const FluentReact = require("devtools/client/shared/vendor/fluent-react");
 const Localized = createFactory(FluentReact.Localized);
 
-const { MESSAGE_LEVEL, PAGE_TYPES, RUNTIMES } = require("../../constants");
+const { ICON_LABEL_LEVEL, PAGE_TYPES, RUNTIMES } = require("../../constants");
 const Types = require("../../types/index");
 loader.lazyRequireGetter(this, "ADB_ADDON_STATES", "devtools/shared/adb/adb-addon", true);
 
-const Message = createFactory(require("../shared/Message"));
+const IconLabel = createFactory(require("../shared/IconLabel"));
 const SidebarItem = createFactory(require("./SidebarItem"));
 const SidebarFixedItem = createFactory(require("./SidebarFixedItem"));
 const SidebarRuntimeItem = createFactory(require("./SidebarRuntimeItem"));
 const RefreshDevicesButton = createFactory(require("./RefreshDevicesButton"));
 const FIREFOX_ICON = "chrome://devtools/skin/images/aboutdebugging-firefox-logo.svg";
 const CONNECT_ICON = "chrome://devtools/skin/images/settings.svg";
 const GLOBE_ICON = "chrome://devtools/skin/images/aboutdebugging-globe-icon.svg";
 const USB_ICON = "chrome://devtools/skin/images/aboutdebugging-connect-icon.svg";
@@ -40,31 +40,30 @@ class Sidebar extends PureComponent {
     };
   }
 
   renderAdbStatus() {
     const isUsbEnabled = this.props.isAdbReady &&
       this.props.adbAddonStatus === ADB_ADDON_STATES.INSTALLED;
     const localizationId = isUsbEnabled ? "about-debugging-sidebar-usb-enabled" :
                                           "about-debugging-sidebar-usb-disabled";
-    return Message(
+    return IconLabel(
       {
-          level: MESSAGE_LEVEL.INFO,
-          isCloseable: true,
+          level: isUsbEnabled ? ICON_LABEL_LEVEL.OK : ICON_LABEL_LEVEL.INFO,
       },
-        Localized(
+      Localized(
+        {
+          id: localizationId,
+        },
+        dom.span(
           {
-            id: localizationId,
+            className: "js-sidebar-usb-status",
           },
-          dom.div(
-            {
-              className: "js-sidebar-usb-status",
-            },
-            localizationId
-          )
+          localizationId
+        )
       )
     );
   }
 
   renderDevicesEmpty() {
     return SidebarItem(
       {},
       Localized(
@@ -202,17 +201,17 @@ class Sidebar extends PureComponent {
               selectedRuntimeId === RUNTIMES.THIS_FIREFOX,
             key: RUNTIMES.THIS_FIREFOX,
             name: "This Firefox",
             to: `/runtime/${RUNTIMES.THIS_FIREFOX}`,
           })
         ),
         SidebarItem(
           {
-            className: "sidebar__adb-status sidebar-item--full-width",
+            className: "sidebar__adb-status",
           },
           dom.hr({ className: "separator separator--breathe" }),
           this.renderAdbStatus(),
         ),
         this.renderDevices(),
         SidebarItem(
           {
             className: "sidebar-item--breathe sidebar__refresh-usb",
--- a/devtools/client/aboutdebugging-new/src/components/sidebar/SidebarItem.css
+++ b/devtools/client/aboutdebugging-new/src/components/sidebar/SidebarItem.css
@@ -20,21 +20,16 @@
 .sidebar-item--tall {
   height: var(--category-height);
 }
 
 .sidebar-item--condensed {
   height: calc(var(--base-unit) * 9);
 }
 
-.sidebar-item--full-width {
-  padding-inline-start: 0;
-  padding-inline-end: 0;
-}
-
 .sidebar-item__link {
   display: block;
   height: 100%;
 }
 
 .sidebar-item__link,
 .sidebar-item__link:hover {
   color: inherit; /* do not apply usual link colors, but grab this element parent's */
--- a/devtools/client/aboutdebugging-new/src/constants.js
+++ b/devtools/client/aboutdebugging-new/src/constants.js
@@ -79,16 +79,21 @@ const DEBUG_TARGET_PANE = {
   PROCESSES: "processes",
   OTHER_WORKER: "otherWorker",
   SERVICE_WORKER: "serviceWorker",
   SHARED_WORKER: "sharedWorker",
   TAB: "tab",
   TEMPORARY_EXTENSION: "temporaryExtension",
 };
 
+const ICON_LABEL_LEVEL = {
+  INFO: "info",
+  OK: "ok",
+};
+
 const MESSAGE_LEVEL = {
   ERROR: "error",
   INFO: "info",
   WARNING: "warning",
 };
 
 const PAGE_TYPES = {
   RUNTIME: "runtime",
@@ -134,16 +139,17 @@ const USB_STATES = {
   ENABLED_USB: "ENABLED_USB",
   UPDATING_USB: "UPDATING_USB",
 };
 
 // flatten constants
 module.exports = Object.assign({}, {
   DEBUG_TARGETS,
   DEBUG_TARGET_PANE,
+  ICON_LABEL_LEVEL,
   MESSAGE_LEVEL,
   PAGE_TYPES,
   PREFERENCES,
   RUNTIME_PREFERENCE,
   RUNTIMES,
   SERVICE_WORKER_FETCH_STATES,
   SERVICE_WORKER_STATUSES,
   USB_STATES,
--- a/devtools/client/aboutdebugging-new/test/browser/browser_aboutdebugging_message_close.js
+++ b/devtools/client/aboutdebugging-new/test/browser/browser_aboutdebugging_message_close.js
@@ -1,26 +1,44 @@
 /* Any copyright is dedicated to the Public Domain.
    http://creativecommons.org/publicdomain/zero/1.0/ */
 
 "use strict";
 
-/**
- * This test asserts that the sidebar shows a message with a closing button describing
- * the status of the USB devices debugging.
- */
+/* import-globals-from helper-addons.js */
+Services.scriptloader.loadSubScript(CHROME_URL_ROOT + "helper-addons.js", this);
+
+// Test that Message component can be closed with the X button
 add_task(async function() {
-  const { document, tab } = await openAboutDebugging();
+  const EXTENSION_NAME = "Temporary web extension";
+  const EXTENSION_ID = "test-devtools@mozilla.org";
+
+  const { document, tab, window } = await openAboutDebugging();
+  await selectThisFirefoxPage(document, window.AboutDebugging.store);
 
-  const usbStatusElement = document.querySelector(".js-sidebar-usb-status");
-  ok(usbStatusElement, "Sidebar shows the USB status element");
-  ok(usbStatusElement.textContent.includes("USB disabled"),
-    "USB status element has the expected content");
+  await installTemporaryExtensionFromXPI({
+    id: EXTENSION_ID,
+    name: EXTENSION_NAME,
+    extraProperties: {
+      // This property is not expected in the manifest and should trigger a warning!
+      "wrongProperty": {},
+    },
+  }, document);
+
+  info("Wait until a debug target item appears");
+  await waitUntil(() => findDebugTargetByText(EXTENSION_NAME, document));
+  const target = findDebugTargetByText(EXTENSION_NAME, document);
 
-  const button = document.querySelector(".js-sidebar-item .qa-message-button-close");
-  button.click();
+  const warningMessage = target.querySelector(".js-message");
+  ok(!!warningMessage, "A warning message is displayed for the installed addon");
+
+  const button = warningMessage.querySelector(".qa-message-button-close");
+  ok(!!button, "The warning message has a close button");
 
-  // new search for element
-  ok(document.querySelector(".js-sidebar-usb-status") === null,
-    "USB status element is no longer displayed");
+  info("Closing the message and waiting for it to disappear");
+  button.click();
+  await waitUntil(() => {
+    return target.querySelector(".js-message") === null;
+  });
 
+  await removeTemporaryExtension(EXTENSION_NAME, document);
   await removeTab(tab);
 });