Bug 1477597 - Part 2: Show tabs. r?jdescottes,r?ladybenko draft
authorDaisuke Akatsuka <dakatsuka@mozilla.com>
Wed, 25 Jul 2018 18:39:27 +0900
changeset 822434 16c2c7fabe174774a8b170823c2c917a64c71c2b
parent 822433 94dbf516e811a7cd13816f42bfbb3d2eb4ab3cf4
child 822435 bbf5b5448a01bfe843d8cffdf3ab625272614235
push id117371
push userbmo:dakatsuka@mozilla.com
push dateWed, 25 Jul 2018 09:46:37 +0000
reviewersjdescottes, ladybenko
bugs1477597
milestone63.0a1
Bug 1477597 - Part 2: Show tabs. r?jdescottes,r?ladybenko MozReview-Commit-ID: 5jVWQ18sCUg
devtools/client/aboutdebugging-new/aboutdebugging.css
devtools/client/aboutdebugging-new/src/components/App.css
devtools/client/aboutdebugging-new/src/components/DebugTargetsPane.css
devtools/client/aboutdebugging-new/src/components/DebugTargetsPane.js
devtools/client/aboutdebugging-new/src/components/debugtarget/DebugTargetItem.css
devtools/client/aboutdebugging-new/src/components/debugtarget/DebugTargetItem.js
devtools/client/aboutdebugging-new/src/components/debugtarget/DebugTargetList.css
devtools/client/aboutdebugging-new/src/components/debugtarget/DebugTargetList.js
devtools/client/aboutdebugging-new/src/components/debugtarget/TabView.js
devtools/client/aboutdebugging-new/src/components/debugtarget/moz.build
devtools/client/aboutdebugging-new/src/components/moz.build
devtools/client/aboutdebugging-new/src/debugtargets/debug-target.js
devtools/client/aboutdebugging-new/src/debugtargets/tab.js
--- a/devtools/client/aboutdebugging-new/aboutdebugging.css
+++ b/devtools/client/aboutdebugging-new/aboutdebugging.css
@@ -1,14 +1,17 @@
 /* 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/. */
 
 @import "resource://devtools/client/themes/variables.css";
 @import "resource://devtools/client/aboutdebugging-new/src/components/App.css";
+@import "resource://devtools/client/aboutdebugging-new/src/components/DebugTargetsPane.css";
 @import "resource://devtools/client/aboutdebugging-new/src/components/RuntimeInfo.css";
 @import "resource://devtools/client/aboutdebugging-new/src/components/RuntimesPane.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/runtime/RuntimeItem.css";
 
 html, body {
   margin: 0;
   padding: 0;
 }
--- a/devtools/client/aboutdebugging-new/src/components/App.css
+++ b/devtools/client/aboutdebugging-new/src/components/App.css
@@ -11,8 +11,14 @@ ul {
 .app {
   display: grid;
   font-size: 15px;
   grid-template-columns: 240px auto;
   height: 100vh;
   overflow: hidden;
   width: 100vw;
 }
+
+.ellipsis-text {
+  overflow: hidden;
+  text-overflow: ellipsis;
+  white-space: nowrap;
+}
new file mode 100644
--- /dev/null
+++ b/devtools/client/aboutdebugging-new/src/components/DebugTargetsPane.css
@@ -0,0 +1,14 @@
+/* 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/. */
+
+.debug-targets-pane {
+  height: 100%;
+  overflow-y: auto;
+  overflow-x: hidden;
+  padding-inline-end: 28px;
+}
+
+.debug-targets-pane__contents {
+  max-width: 800px;
+}
--- a/devtools/client/aboutdebugging-new/src/components/DebugTargetsPane.js
+++ b/devtools/client/aboutdebugging-new/src/components/DebugTargetsPane.js
@@ -4,34 +4,52 @@
 
 "use strict";
 
 const { connect } = require("devtools/client/shared/vendor/react-redux");
 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 Tab = require("../debugtargets/tab");
+
+const DebugTargetList = createFactory(require("./debugtarget/DebugTargetList"));
 const RuntimeInfo = createFactory(require("./RuntimeInfo"));
+const TabView = createFactory(require("./debugtarget/TabView"));
 
 class DebugTargetsPane extends PureComponent {
   static get propTypes() {
     return {
       runtimeInfo: PropTypes.object.isRequired,
+      tabs: PropTypes.arrayOf(PropTypes.instanceOf(Tab)).isRequired,
     };
   }
 
   render() {
-    const { runtimeInfo } = this.props;
+    const { runtimeInfo, tabs } = this.props;
 
     return dom.section(
-      {},
-      RuntimeInfo({ runtimeInfo })
+      {
+        className: "debug-targets-pane",
+      },
+      dom.div(
+        {
+          className: "debug-targets-pane__contents",
+        },
+        RuntimeInfo({ runtimeInfo }),
+        DebugTargetList({
+          debugTargets: tabs,
+          debugTargetViewComponent: TabView,
+          title: "Tabs",
+        }),
+      )
     );
   }
 }
 
 const mapStateToProps = state => {
   return {
     runtimeInfo: state.debugtargets.runtimeInfo,
+    tabs: state.debugtargets.tabs,
   };
 };
 
 module.exports = connect(mapStateToProps)(DebugTargetsPane);
new file mode 100644
--- /dev/null
+++ b/devtools/client/aboutdebugging-new/src/components/debugtarget/DebugTargetItem.css
@@ -0,0 +1,23 @@
+/* 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/. */
+
+.debug-target-item {
+  display: grid;
+  grid-template-columns: 54px auto;
+  margin-block-end: 20px;
+}
+
+.debug-target-item__icon {
+  height: 36px;
+  width: 36px;
+}
+
+.debug-target-item__info {
+  min-width: 0;
+}
+
+.debug-target-item__info__name {
+  font-size: 20px;
+  margin-block-end: 2px;
+}
new file mode 100644
--- /dev/null
+++ b/devtools/client/aboutdebugging-new/src/components/debugtarget/DebugTargetItem.js
@@ -0,0 +1,67 @@
+/* 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 DebutTarget = require("../../debugtargets/debug-target");
+
+/**
+ * This component shows the debug target as item in DebugTargetsPane.
+ */
+class DebugTargetItem extends PureComponent {
+  static get propTypes() {
+    return {
+      debugTarget: PropTypes.instanceOf(DebutTarget).isRequired,
+      debugTargetViewComponent: PropTypes.any.isRequired,
+    };
+  }
+
+  renderIcon() {
+    const { debugTarget } = this.props;
+
+    return dom.img({
+      className: "debug-target-item__icon",
+      src: debugTarget.getIcon(),
+    });
+  }
+
+  renderInfo() {
+    const { debugTarget, debugTargetViewComponent } = this.props;
+
+    return dom.div(
+      {
+        className: "debug-target-item__info",
+      },
+      dom.div(
+        {
+          className: "debug-target-item__info__name ellipsis-text",
+          title: debugTarget.getName(),
+        },
+        debugTarget.getName()
+      ),
+      dom.div(
+        {
+          className: "debug-target-item__info__detail",
+        },
+        debugTargetViewComponent({ debugTarget })
+      ),
+    );
+  }
+
+  render() {
+    return dom.li(
+      {
+        className: "debug-target-item",
+      },
+      this.renderIcon(),
+      this.renderInfo(),
+    );
+  }
+}
+
+module.exports = DebugTargetItem;
new file mode 100644
--- /dev/null
+++ b/devtools/client/aboutdebugging-new/src/components/debugtarget/DebugTargetList.css
@@ -0,0 +1,16 @@
+/* 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/. */
+
+.debug-target-list {
+  margin-block-end: 30px;
+}
+
+.debug-target-list__title {
+  margin-block-start: 10px;
+  margin-block-end: 10px;
+}
+
+.debug-target-list__ul {
+  margin-inline-start: 60px;
+}
new file mode 100644
--- /dev/null
+++ b/devtools/client/aboutdebugging-new/src/components/debugtarget/DebugTargetList.js
@@ -0,0 +1,55 @@
+/* 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 { 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 DebutTarget = require("../../debugtargets/debug-target");
+
+const DebutTargetItem = createFactory(require("./DebugTargetItem"));
+
+/**
+ * This component shows the debug target as list in DebugTargetsPane.
+ */
+class DebugTargetList extends PureComponent {
+  static get propTypes() {
+    return {
+      debugTargetViewComponent: PropTypes.any.isRequired,
+      debugTargets: PropTypes.arrayOf(PropTypes.instanceOf(DebutTarget)).isRequired,
+      title: PropTypes.string.isRequired,
+    };
+  }
+
+  render() {
+    const { debugTargetViewComponent, debugTargets, title } = this.props;
+
+    return dom.section(
+      {
+        className: "debug-target-list",
+      },
+      dom.h2(
+        {
+          className: "debug-target-list__title",
+        },
+        title
+      ),
+      dom.ul(
+        {
+          className: "debug-target-list__ul",
+        },
+        debugTargets.map(
+          debugTarget => DebutTargetItem({
+            debugTarget,
+            debugTargetViewComponent,
+          })
+        )
+      )
+    );
+  }
+}
+
+module.exports = DebugTargetList;
new file mode 100644
--- /dev/null
+++ b/devtools/client/aboutdebugging-new/src/components/debugtarget/TabView.js
@@ -0,0 +1,35 @@
+/* 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 Tab = require("../../debugtargets/tab");
+
+/**
+ * This component shows detail tab information.
+ */
+class TabView extends PureComponent {
+  static get propTypes() {
+    return {
+      debugTarget: PropTypes.instanceOf(Tab).isRequired,
+    };
+  }
+
+  render() {
+    const { debugTarget } = this.props;
+
+    return dom.div(
+      {
+        className: "tab-view ellipsis-text",
+      },
+      debugTarget.getURL()
+    );
+  }
+}
+
+module.exports = TabView;
new file mode 100644
--- /dev/null
+++ b/devtools/client/aboutdebugging-new/src/components/debugtarget/moz.build
@@ -0,0 +1,11 @@
+# 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(
+    'DebugTargetItem.css',
+    'DebugTargetItem.js',
+    'DebugTargetList.css',
+    'DebugTargetList.js',
+    'TabView.js',
+)
--- a/devtools/client/aboutdebugging-new/src/components/moz.build
+++ b/devtools/client/aboutdebugging-new/src/components/moz.build
@@ -1,17 +1,19 @@
 # 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/.
 
 DIRS += [
+    'debugtarget',
     'runtime',
 ]
 
 DevToolsModules(
     'App.css',
     'App.js',
+    'DebugTargetsPane.css',
     'DebugTargetsPane.js',
     'RuntimeInfo.css',
     'RuntimeInfo.js',
     'RuntimesPane.css',
     'RuntimesPane.js'
 )
--- a/devtools/client/aboutdebugging-new/src/debugtargets/debug-target.js
+++ b/devtools/client/aboutdebugging-new/src/debugtargets/debug-target.js
@@ -6,11 +6,29 @@
 
 /**
  * This class represents a debug target, such as a tab, an extension or a worker.
  */
 class DebugTarget {
   constructor(target) {
     this.target = target;
   }
+
+  /**
+   * Return the icon of this debug target.
+   * Subclass should override this method.
+   * @return {String}
+   */
+  getIcon() {
+    throw new Error("Subclass of DebugTarget should override getIcon()");
+  }
+
+  /**
+   * Return the name of this debug target.
+   * Subclass should override this method.
+   * @return {String}
+   */
+  getName() {
+    throw new Error("Subclass of DebugTarget should override getName()");
+  }
 }
 
 module.exports = DebugTarget;
--- a/devtools/client/aboutdebugging-new/src/debugtargets/tab.js
+++ b/devtools/client/aboutdebugging-new/src/debugtargets/tab.js
@@ -8,11 +8,32 @@ const DebugTarget = require("./debug-tar
 
 /**
  * This class represents a tab as debug target.
  */
 class Tab extends DebugTarget {
   constructor(target) {
     super(target);
   }
+
+  getIcon() {
+    if (this.target.favicon) {
+      const base64Favicon = btoa(String.fromCharCode.apply(String, this.target.favicon));
+      return `data:image/png;base64,${ base64Favicon }`;
+    }
+
+    return "chrome://devtools/skin/images/globe.svg";
+  }
+
+  getName() {
+    // If the title is empty, display the url instead.
+    return this.target.title || this.target.url;
+  }
+
+  /**
+   * Return the url of this tab.
+   */
+  getURL() {
+    return this.target.url;
+  }
 }
 
 module.exports = Tab;