Bug 1477597 - Part 2: Show tabs. r?jdescottes,r?ladybenko
MozReview-Commit-ID: 5jVWQ18sCUg
--- 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;