diff options
Diffstat (limited to 'devtools/client/memory/components/Toolbar.js')
-rw-r--r-- | devtools/client/memory/components/Toolbar.js | 309 |
1 files changed, 309 insertions, 0 deletions
diff --git a/devtools/client/memory/components/Toolbar.js b/devtools/client/memory/components/Toolbar.js new file mode 100644 index 0000000000..712a04abfe --- /dev/null +++ b/devtools/client/memory/components/Toolbar.js @@ -0,0 +1,309 @@ +/* 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, +} = require("resource://devtools/client/shared/vendor/react.js"); +const PropTypes = require("resource://devtools/client/shared/vendor/react-prop-types.js"); +const dom = require("resource://devtools/client/shared/vendor/react-dom-factories.js"); +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; |