Source code

Revision control

Copy as Markdown

Other Tools

/* 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("resource://devtools/shared/DevToolsUtils.js");
const {
Component,
const { L10N } = require("resource://devtools/client/memory/utils.js");
const models = require("resource://devtools/client/memory/models.js");
const { viewState } = require("resource://devtools/client/memory/constants.js");
class Toolbar extends Component {
static get propTypes() {
return {
censusDisplays: PropTypes.arrayOf(models.censusDisplay).isRequired,
censusDisplay: models.censusDisplay.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(models.labelDisplay).isRequired,
labelDisplay: models.labelDisplay.isRequired,
onLabelDisplayChange: PropTypes.func.isRequired,
treeMapDisplays: PropTypes.arrayOf(models.treeMapDisplay).isRequired,
onTreeMapDisplayChange: PropTypes.func.isRequired,
snapshots: PropTypes.arrayOf(models.snapshot).isRequired,
};
}
render() {
const {
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: "devtools-toolbar-select 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.span({ className: "devtools-separator" }),
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",
className: "devtools-toolbar-select 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",
className: "devtools-toolbar-select select-view",
onChange: e => onViewChange(e.target.value),
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: "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
);
}
}
module.exports = Toolbar;