summaryrefslogtreecommitdiffstats
path: root/devtools/client/memory/components/toolbar.js
diff options
context:
space:
mode:
Diffstat (limited to 'devtools/client/memory/components/toolbar.js')
-rw-r--r--devtools/client/memory/components/toolbar.js300
1 files changed, 300 insertions, 0 deletions
diff --git a/devtools/client/memory/components/toolbar.js b/devtools/client/memory/components/toolbar.js
new file mode 100644
index 000000000..de60b2af9
--- /dev/null
+++ b/devtools/client/memory/components/toolbar.js
@@ -0,0 +1,300 @@
+/* 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 { assert } = require("devtools/shared/DevToolsUtils");
+const { DOM: dom, createClass, PropTypes } = require("devtools/client/shared/vendor/react");
+const { L10N } = require("../utils");
+const models = require("../models");
+const { viewState } = require("../constants");
+
+module.exports = createClass({
+ displayName: "Toolbar",
+
+ propTypes: {
+ censusDisplays: PropTypes.arrayOf(PropTypes.shape({
+ displayName: PropTypes.string.isRequired,
+ })).isRequired,
+ censusDisplay: PropTypes.shape({
+ displayName: PropTypes.string.isRequired,
+ }).isRequired,
+ onTakeSnapshotClick: PropTypes.func.isRequired,
+ onImportClick: PropTypes.func.isRequired,
+ onClearSnapshotsClick: PropTypes.func.isRequired,
+ onCensusDisplayChange: PropTypes.func.isRequired,
+ onToggleRecordAllocationStacks: PropTypes.func.isRequired,
+ allocations: models.allocations,
+ filterString: PropTypes.string,
+ setFilterString: PropTypes.func.isRequired,
+ diffing: models.diffingModel,
+ onToggleDiffing: PropTypes.func.isRequired,
+ view: models.view.isRequired,
+ onViewChange: PropTypes.func.isRequired,
+ labelDisplays: PropTypes.arrayOf(PropTypes.shape({
+ displayName: PropTypes.string.isRequired,
+ })).isRequired,
+ labelDisplay: PropTypes.shape({
+ displayName: PropTypes.string.isRequired,
+ }).isRequired,
+ onLabelDisplayChange: PropTypes.func.isRequired,
+ treeMapDisplays: PropTypes.arrayOf(PropTypes.shape({
+ displayName: PropTypes.string.isRequired,
+ })).isRequired,
+ onTreeMapDisplayChange: PropTypes.func.isRequired,
+ snapshots: PropTypes.arrayOf(models.snapshot).isRequired,
+ },
+
+ render() {
+ let {
+ onTakeSnapshotClick,
+ onImportClick,
+ onClearSnapshotsClick,
+ onCensusDisplayChange,
+ censusDisplays,
+ censusDisplay,
+ labelDisplays,
+ labelDisplay,
+ onLabelDisplayChange,
+ treeMapDisplays,
+ onTreeMapDisplayChange,
+ onToggleRecordAllocationStacks,
+ allocations,
+ filterString,
+ setFilterString,
+ snapshots,
+ diffing,
+ onToggleDiffing,
+ view,
+ onViewChange,
+ } = this.props;
+
+ let viewToolbarOptions;
+ if (view.state == viewState.CENSUS || view.state === viewState.DIFFING) {
+ viewToolbarOptions = dom.div(
+ {
+ className: "toolbar-group"
+ },
+
+ dom.label(
+ {
+ className: "display-by",
+ title: L10N.getStr("toolbar.displayBy.tooltip"),
+ },
+ L10N.getStr("toolbar.displayBy"),
+ dom.select(
+ {
+ id: "select-display",
+ className: "select-display",
+ onChange: e => {
+ const newDisplay =
+ censusDisplays.find(b => b.displayName === e.target.value);
+ onCensusDisplayChange(newDisplay);
+ },
+ value: censusDisplay.displayName,
+ },
+ censusDisplays.map(({ tooltip, displayName }) => dom.option(
+ {
+ key: `display-${displayName}`,
+ value: displayName,
+ title: tooltip,
+ },
+ displayName
+ ))
+ )
+ ),
+
+ dom.div({ id: "toolbar-spacer", className: "spacer" }),
+
+ dom.input({
+ id: "filter",
+ type: "search",
+ className: "devtools-filterinput",
+ placeholder: L10N.getStr("filter.placeholder"),
+ title: L10N.getStr("filter.tooltip"),
+ onChange: event => setFilterString(event.target.value),
+ value: filterString || undefined,
+ })
+ );
+ } else if (view.state == viewState.TREE_MAP) {
+ assert(treeMapDisplays.length >= 1,
+ "Should always have at least one tree map display");
+
+ // Only show the dropdown if there are multiple display options
+ viewToolbarOptions = treeMapDisplays.length > 1
+ ? dom.div(
+ {
+ className: "toolbar-group"
+ },
+
+ dom.label(
+ {
+ className: "display-by",
+ title: L10N.getStr("toolbar.displayBy.tooltip"),
+ },
+ L10N.getStr("toolbar.displayBy"),
+ dom.select(
+ {
+ id: "select-tree-map-display",
+ onChange: e => {
+ const newDisplay =
+ treeMapDisplays.find(b => b.displayName === e.target.value);
+ onTreeMapDisplayChange(newDisplay);
+ },
+ },
+ treeMapDisplays.map(({ tooltip, displayName }) => dom.option(
+ {
+ key: `tree-map-display-${displayName}`,
+ value: displayName,
+ title: tooltip,
+ },
+ displayName
+ ))
+ )
+ )
+ )
+ : null;
+ } else {
+ assert(view.state === viewState.DOMINATOR_TREE ||
+ view.state === viewState.INDIVIDUALS);
+
+ viewToolbarOptions = dom.div(
+ {
+ className: "toolbar-group"
+ },
+
+ dom.label(
+ {
+ className: "label-by",
+ title: L10N.getStr("toolbar.labelBy.tooltip"),
+ },
+ L10N.getStr("toolbar.labelBy"),
+ dom.select(
+ {
+ id: "select-label-display",
+ onChange: e => {
+ const newDisplay =
+ labelDisplays.find(b => b.displayName === e.target.value);
+ onLabelDisplayChange(newDisplay);
+ },
+ value: labelDisplay.displayName,
+ },
+ labelDisplays.map(({ tooltip, displayName }) => dom.option(
+ {
+ key: `label-display-${displayName}`,
+ value: displayName,
+ title: tooltip,
+ },
+ displayName
+ ))
+ )
+ )
+ );
+ }
+
+ let viewSelect;
+ if (view.state !== viewState.DIFFING && view.state !== viewState.INDIVIDUALS) {
+ viewSelect = dom.label(
+ {
+ title: L10N.getStr("toolbar.view.tooltip"),
+ },
+ L10N.getStr("toolbar.view"),
+ dom.select(
+ {
+ id: "select-view",
+ onChange: e => onViewChange(e.target.value),
+ defaultValue: view,
+ value: view.state,
+ },
+ dom.option(
+ {
+ value: viewState.TREE_MAP,
+ title: L10N.getStr("toolbar.view.treemap.tooltip"),
+ },
+ L10N.getStr("toolbar.view.treemap")
+ ),
+ dom.option(
+ {
+ value: viewState.CENSUS,
+ title: L10N.getStr("toolbar.view.census.tooltip"),
+ },
+ L10N.getStr("toolbar.view.census")
+ ),
+ dom.option(
+ {
+ value: viewState.DOMINATOR_TREE,
+ title: L10N.getStr("toolbar.view.dominators.tooltip"),
+ },
+ L10N.getStr("toolbar.view.dominators")
+ )
+ )
+ );
+ }
+
+ return (
+ dom.div(
+ {
+ className: "devtools-toolbar"
+ },
+
+ dom.div(
+ {
+ className: "toolbar-group"
+ },
+
+ dom.button({
+ id: "clear-snapshots",
+ className: "clear-snapshots devtools-button",
+ disabled: !snapshots.length,
+ onClick: onClearSnapshotsClick,
+ title: L10N.getStr("clear-snapshots.tooltip")
+ }),
+
+ dom.button({
+ id: "take-snapshot",
+ className: "take-snapshot devtools-button",
+ onClick: onTakeSnapshotClick,
+ title: L10N.getStr("take-snapshot")
+ }),
+
+ dom.button(
+ {
+ id: "diff-snapshots",
+ className: "devtools-button devtools-monospace" + (!!diffing ? " checked" : ""),
+ disabled: snapshots.length < 2,
+ onClick: onToggleDiffing,
+ title: L10N.getStr("diff-snapshots.tooltip"),
+ }
+ ),
+
+ dom.button(
+ {
+ id: "import-snapshot",
+ className: "devtools-toolbarbutton import-snapshot devtools-button",
+ onClick: onImportClick,
+ title: L10N.getStr("import-snapshot"),
+ }
+ )
+ ),
+
+ dom.label(
+ {
+ id: "record-allocation-stacks-label",
+ title: L10N.getStr("checkbox.recordAllocationStacks.tooltip"),
+ },
+ dom.input({
+ id: "record-allocation-stacks-checkbox",
+ type: "checkbox",
+ checked: allocations.recording,
+ disabled: allocations.togglingInProgress,
+ onChange: onToggleRecordAllocationStacks,
+ }),
+ L10N.getStr("checkbox.recordAllocationStacks")
+ ),
+
+ viewSelect,
+ viewToolbarOptions
+ )
+ );
+ }
+});