Bug 1500350: Re-layout for runtime controllers. r=ladybenko,jdescottes
authorDaisuke Akatsuka <dakatsuka@mozilla.com>
Tue, 19 Feb 2019 01:12:19 +0000
changeset 459836 b10932876150bc73be47f0b332028d3b8bcaa6f3
parent 459835 9a1f91d90de19afda7fb9ecd573074451fb7f153
child 459837 ef94872bfd127ed6111236df825af9cb5479aedb
push id35576
push userbtara@mozilla.com
push dateTue, 19 Feb 2019 09:46:27 +0000
treeherdermozilla-central@dd4aa59c6a12 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersladybenko, jdescottes
bugs1500350
milestone67.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 1500350: Re-layout for runtime controllers. r=ladybenko,jdescottes Depends on D18196 Differential Revision: https://phabricator.services.mozilla.com/D18198
devtools/client/aboutdebugging-new/src/components/ConnectionPromptSetting.js
devtools/client/aboutdebugging-new/src/components/ExtensionDebugSetting.js
devtools/client/aboutdebugging-new/src/components/RuntimePage.css
devtools/client/aboutdebugging-new/src/components/RuntimePage.js
devtools/client/aboutdebugging-new/src/components/debugtarget/TemporaryExtensionInstaller.js
--- a/devtools/client/aboutdebugging-new/src/components/ConnectionPromptSetting.js
+++ b/devtools/client/aboutdebugging-new/src/components/ConnectionPromptSetting.js
@@ -11,40 +11,41 @@ const PropTypes = require("devtools/clie
 const FluentReact = require("devtools/client/shared/vendor/fluent-react");
 const Localized = createFactory(FluentReact.Localized);
 
 const Actions = require("../actions/index");
 
 class ConnectionPromptSetting extends PureComponent {
   static get propTypes() {
     return {
+      className: PropTypes.string,
+      connectionPromptEnabled: PropTypes.bool.isRequired,
       dispatch: PropTypes.func.isRequired,
-      connectionPromptEnabled: PropTypes.bool.isRequired,
     };
   }
 
   onToggleClick() {
     const { connectionPromptEnabled, dispatch } = this.props;
     dispatch(Actions.updateConnectionPromptSetting(!connectionPromptEnabled));
   }
 
   render() {
-    const { connectionPromptEnabled } = this.props;
+    const { className, connectionPromptEnabled } = this.props;
 
     const localizedState = connectionPromptEnabled
                              ? "about-debugging-connection-prompt-disable-button"
                              : "about-debugging-connection-prompt-enable-button";
 
     return Localized(
       {
         id: localizedState,
       },
       dom.button(
         {
-          className: "default-button js-connection-prompt-toggle-button",
+          className: `${ className } default-button js-connection-prompt-toggle-button`,
           onClick: () => this.onToggleClick(),
         },
         localizedState
       )
     );
   }
 }
 
--- a/devtools/client/aboutdebugging-new/src/components/ExtensionDebugSetting.js
+++ b/devtools/client/aboutdebugging-new/src/components/ExtensionDebugSetting.js
@@ -14,16 +14,17 @@ const Localized = createFactory(FluentRe
 const Actions = require("../actions/index");
 
 const DOC_URL =
   "https://developer.mozilla.org/docs/Tools/about:debugging#Enabling_add-on_debugging";
 
 class ExtensionDebugSetting extends PureComponent {
   static get propTypes() {
     return {
+      className: PropTypes.string,
       dispatch: PropTypes.func.isRequired,
       extensionDebugEnabled: PropTypes.bool.isRequired,
     };
   }
 
   onToggle() {
     const { extensionDebugEnabled, dispatch } = this.props;
     dispatch(Actions.updateExtensionDebugSetting(!extensionDebugEnabled));
@@ -58,17 +59,19 @@ class ExtensionDebugSetting extends Pure
           htmlFor: "extension-debug-setting-input",
         },
         "Enable extension debugging [Learn more]"
       )
     );
   }
 
   render() {
+    const { className } = this.props;
+
     return dom.aside(
-      {},
+      { className },
       this.renderCheckbox(),
       this.renderLabel(),
     );
   }
 }
 
 module.exports = ExtensionDebugSetting;
--- a/devtools/client/aboutdebugging-new/src/components/RuntimePage.css
+++ b/devtools/client/aboutdebugging-new/src/components/RuntimePage.css
@@ -1,8 +1,18 @@
 /* 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/. */
 
-.connection-prompt-setting {
-  margin-block-end: var(--base-unit);
-  text-align: right;
+.runtime-actions {
+  column-gap: var(--base-unit);
+  display: grid;
+  grid-template-areas: "start center end";
+  grid-template-columns: max-content 1fr max-content;
 }
+
+.runtime-actions__end {
+  grid-area: end;
+}
+
+.runtime-actions__start {
+  grid-area: start;
+}
--- a/devtools/client/aboutdebugging-new/src/components/RuntimePage.js
+++ b/devtools/client/aboutdebugging-new/src/components/RuntimePage.js
@@ -13,29 +13,30 @@ const FluentReact = require("devtools/cl
 const Localized = createFactory(FluentReact.Localized);
 
 const CompatibilityWarning = createFactory(require("./CompatibilityWarning"));
 const ConnectionPromptSetting = createFactory(require("./ConnectionPromptSetting"));
 const DebugTargetPane = createFactory(require("./debugtarget/DebugTargetPane"));
 const ExtensionDebugSetting = createFactory(require("./ExtensionDebugSetting"));
 const ExtensionDetail = createFactory(require("./debugtarget/ExtensionDetail"));
 const InspectAction = createFactory(require("./debugtarget/InspectAction"));
+const Message = createFactory(require("./shared/Message"));
 const ProfilerDialog = createFactory(require("./ProfilerDialog"));
 const RuntimeInfo = createFactory(require("./RuntimeInfo"));
 const ServiceWorkerAction = createFactory(require("./debugtarget/ServiceWorkerAction"));
 const ServiceWorkersWarning = createFactory(require("./ServiceWorkersWarning"));
 const TabDetail = createFactory(require("./debugtarget/TabDetail"));
 const TemporaryExtensionAction = createFactory(require("./debugtarget/TemporaryExtensionAction"));
 const TemporaryExtensionDetail = createFactory(require("./debugtarget/TemporaryExtensionDetail"));
 const TemporaryExtensionInstaller =
   createFactory(require("./debugtarget/TemporaryExtensionInstaller"));
 const WorkerDetail = createFactory(require("./debugtarget/WorkerDetail"));
 
 const Actions = require("../actions/index");
-const { DEBUG_TARGET_PANE, PAGE_TYPES, RUNTIMES } = require("../constants");
+const { DEBUG_TARGET_PANE, MESSAGE_LEVEL, PAGE_TYPES, RUNTIMES } = require("../constants");
 const Types = require("../types/index");
 
 const { getCurrentRuntimeDetails } = require("../modules/runtimes-state-helper");
 const {
   isExtensionDebugSettingNeeded,
   isSupportedDebugTargetPane,
 } = require("../modules/debug-target-support");
 
@@ -63,50 +64,27 @@ class RuntimePage extends PureComponent 
     const { dispatch, runtimeId } = this.props;
     dispatch(Actions.selectPage(PAGE_TYPES.RUNTIME, runtimeId));
   }
 
   onProfilerButtonClick() {
     this.props.dispatch(Actions.showProfilerDialog());
   }
 
-  renderRemoteRuntimeActions() {
-    const { runtimeDetails, runtimeId, dispatch } = this.props;
+  renderConnectionPromptSetting() {
+    const { dispatch, runtimeDetails, runtimeId } = this.props;
     const { connectionPromptEnabled } = runtimeDetails;
-
-    if (runtimeId === RUNTIMES.THIS_FIREFOX) {
-      // Connection prompt and Profiling are only available on remote runtimes.
-      return null;
-    }
-
-    return [
-      dom.div(
-        {
-          className: "connection-prompt-setting",
-          key: "connection-prompt-setting",
-        },
-        ConnectionPromptSetting({ connectionPromptEnabled, dispatch }),
-      ),
-      dom.p(
-        {},
-        Localized(
-          {
-            id: "about-debugging-runtime-profile-button",
-            key: "profile-runtime-button",
-          },
-          dom.button(
-            {
-              className: "default-button js-profile-runtime-button",
-              onClick: () => this.onProfilerButtonClick(),
-            },
-            "Profile Runtime"
-          ),
-        ),
-      ),
-    ];
+    // do not show the connection prompt setting in 'This Firefox'
+    return runtimeId !== RUNTIMES.THIS_FIREFOX
+             ? ConnectionPromptSetting({
+               className: "runtime-actions__end",
+               connectionPromptEnabled,
+               dispatch,
+             })
+             : null;
   }
 
   renderDebugTargetPane(name, targets, actionComponent,
                         detailComponent, paneKey, localizationId) {
     const { collapsibilities, dispatch, runtimeDetails } = this.props;
 
     if (!isSupportedDebugTargetPane(runtimeDetails.info.type, paneKey)) {
       return null;
@@ -125,60 +103,132 @@ class RuntimePage extends PureComponent 
         isCollapsed: collapsibilities.get(paneKey),
         name,
         targets,
       })
     );
   }
 
   renderExtensionDebugSetting() {
-    const { runtimeDetails, dispatch } = this.props;
-    const { extensionDebugEnabled } = runtimeDetails;
-    return ExtensionDebugSetting({ extensionDebugEnabled, dispatch });
+    const { dispatch, runtimeDetails } = this.props;
+    const { extensionDebugEnabled, info } = runtimeDetails;
+    return isExtensionDebugSettingNeeded(info.type)
+             ? ExtensionDebugSetting({
+                 className: "runtime-actions__start",
+                 dispatch,
+                 extensionDebugEnabled,
+             })
+             : null;
+  }
+
+  renderProfileButton() {
+    const { runtimeId } = this.props;
+
+    return runtimeId !== RUNTIMES.THIS_FIREFOX
+         ? Localized(
+           {
+             id: "about-debugging-runtime-profile-button",
+           },
+           dom.button(
+             {
+               className: "default-button runtime-actions__start " +
+                          "js-profile-runtime-button",
+               onClick: () => this.onProfilerButtonClick(),
+             },
+             "Profile Runtime"
+           ),
+         )
+         : null;
+  }
+
+  renderRuntimeActions() {
+    return dom.div(
+      {
+        className: "runtime-actions",
+      },
+      this.renderConnectionPromptSetting(),
+      this.renderProfileButton(),
+      this.renderExtensionDebugSetting(),
+      this.renderTemporaryExtensionInstaller(),
+    );
+  }
+
+  renderTemporaryExtensionInstaller() {
+    const { dispatch, runtimeDetails, temporaryInstallError } = this.props;
+    const { type } = runtimeDetails.info;
+    return isSupportedDebugTargetPane(type, DEBUG_TARGET_PANE.TEMPORARY_EXTENSION)
+             ? TemporaryExtensionInstaller({
+                 className: "runtime-actions__end",
+                 dispatch,
+                 temporaryInstallError,
+             })
+             : null;
+  }
+
+  renderTemporaryExtensionInstallError() {
+    const { runtimeDetails, temporaryInstallError } = this.props;
+    const { type } = runtimeDetails.info;
+
+    if (!temporaryInstallError ||
+        !isSupportedDebugTargetPane(type, DEBUG_TARGET_PANE.TEMPORARY_EXTENSION)) {
+      return null;
+    }
+
+    return Message(
+      {
+        level: MESSAGE_LEVEL.ERROR,
+      },
+      dom.div(
+        {},
+        Localized(
+          {
+            id: "about-debugging-tmp-extension-install-error",
+          },
+          dom.span({}, "There was an error during the temporary add-on installation")
+        ),
+        dom.div(
+          {
+            className: "technical-text",
+          },
+          temporaryInstallError
+        )
+      )
+    );
   }
 
   render() {
     const {
       dispatch,
       installedExtensions,
       otherWorkers,
       runtimeDetails,
       serviceWorkers,
       sharedWorkers,
       showProfilerDialog,
       tabs,
       temporaryExtensions,
-      temporaryInstallError,
     } = this.props;
 
     if (!runtimeDetails) {
       // runtimeInfo can be null when the selectPage action navigates from a runtime A
       // to a runtime B (between unwatchRuntime and watchRuntime).
       return null;
     }
 
-    const { type } = runtimeDetails.info;
     const { compatibilityReport } = runtimeDetails;
+
     return dom.article(
       {
         className: "page js-runtime-page",
       },
       RuntimeInfo(runtimeDetails.info),
-      this.renderRemoteRuntimeActions(),
+      this.renderRuntimeActions(),
       runtimeDetails.serviceWorkersAvailable ? null : ServiceWorkersWarning(),
       CompatibilityWarning({ compatibilityReport }),
-      // show component to enable/disable extension debugging.
-      isExtensionDebugSettingNeeded(type)
-        ? this.renderExtensionDebugSetting()
-        : null,
-      isSupportedDebugTargetPane(type, DEBUG_TARGET_PANE.TEMPORARY_EXTENSION)
-        ? TemporaryExtensionInstaller({
-            dispatch,
-            temporaryInstallError,
-        }) : null,
+      this.renderTemporaryExtensionInstallError(),
       this.renderDebugTargetPane("Temporary Extensions",
                                  temporaryExtensions,
                                  TemporaryExtensionAction,
                                  TemporaryExtensionDetail,
                                  DEBUG_TARGET_PANE.TEMPORARY_EXTENSION,
                                  "about-debugging-runtime-temporary-extensions"),
       this.renderDebugTargetPane("Extensions",
                                  installedExtensions,
--- a/devtools/client/aboutdebugging-new/src/components/debugtarget/TemporaryExtensionInstaller.js
+++ b/devtools/client/aboutdebugging-new/src/components/debugtarget/TemporaryExtensionInstaller.js
@@ -6,69 +6,45 @@
 
 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 = createFactory(require("../shared/Message"));
-
 const Actions = require("../../actions/index");
-const { MESSAGE_LEVEL } = require("../../constants");
 
 /**
  * This component provides an installer for temporary extension.
  */
 class TemporaryExtensionInstaller extends PureComponent {
   static get propTypes() {
     return {
+      className: PropTypes.string,
       dispatch: PropTypes.func.isRequired,
-      temporaryInstallError: PropTypes.string,
     };
   }
 
   install() {
     this.props.dispatch(Actions.installTemporaryExtension());
   }
 
   render() {
-    const { temporaryInstallError } = this.props;
-    return dom.div(
-      {},
-      Localized(
-        {
-          id: "about-debugging-tmp-extension-install-button",
-        },
-        dom.button(
-          {
-            className: "default-button js-temporary-extension-install-button",
-            onClick: e => this.install(),
-          },
-          "Load Temporary Add-on…"
-        )
-      ),
-      temporaryInstallError ? Message(
+    const { className } = this.props;
+
+    return Localized(
+      {
+        id: "about-debugging-tmp-extension-install-button",
+      },
+      dom.button(
         {
-          level: MESSAGE_LEVEL.ERROR,
+          className:
+            `${ className } default-button js-temporary-extension-install-button`,
+          onClick: e => this.install(),
         },
-        dom.div(
-          {},
-          Localized(
-            {
-              id: "about-debugging-tmp-extension-install-error",
-            },
-            dom.span({}, "There was an error during the temporary add-on installation")
-          ),
-          dom.div(
-            {
-              className: "technical-text",
-            },
-            temporaryInstallError
-          )
-        )
-      ) : null
+        "Load Temporary Add-on…"
+      )
     );
   }
 }
 
 module.exports = TemporaryExtensionInstaller;