Files
tubestation/devtools/client/framework/components/toolbox-controller.js
2016-11-18 15:02:21 -06:00

152 lines
4.4 KiB
JavaScript

/* 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 {createClass, createFactory} = require("devtools/client/shared/vendor/react");
const ToolboxToolbar = createFactory(require("devtools/client/framework/components/toolbox-toolbar"));
const ELEMENT_PICKER_ID = "command-button-pick";
/**
* This component serves as a state controller for the toolbox React component. It's a
* thin layer for translating events and state of the outside world into the React update
* cycle. This solution was used to keep the amount of code changes to a minimimum while
* adapting the existing codebase to start using React.
*/
module.exports = createClass({
displayName: "ToolboxController",
getInitialState() {
// See the ToolboxToolbar propTypes for documentation on each of these items in state,
// and for the defintions of the props that are expected to be passed in.
return {
focusedButton: ELEMENT_PICKER_ID,
currentToolId: null,
canRender: false,
highlightedTool: "",
areDockButtonsEnabled: true,
panelDefinitions: [],
hostTypes: [],
canCloseToolbox: true,
toolboxButtons: [],
buttonIds: [],
checkedButtonsUpdated: () => {
this.forceUpdate();
}
};
},
componentWillUnmount() {
this.state.toolboxButtons.forEach(button => {
button.off("updatechecked", this.state.checkedButtonsUpdated);
});
},
/**
* The button and tab ids must be known in order to be able to focus left and right
* using the arrow keys.
*/
updateButtonIds() {
const {panelDefinitions, toolboxButtons, optionsPanel, hostTypes,
canCloseToolbox} = this.state;
// This is a little gnarly, but go through all of the state and extract the IDs.
this.setState({
buttonIds: [
...toolboxButtons.filter(btn => btn.isInStartContainer).map(({id}) => id),
...panelDefinitions.map(({id}) => id),
...toolboxButtons.filter(btn => !btn.isInStartContainer).map(({id}) => id),
optionsPanel ? optionsPanel.id : null,
...hostTypes.map(({position}) => "toolbox-dock-" + position),
canCloseToolbox ? "toolbox-close" : null
].filter(id => id)
});
this.updateFocusedButton();
},
updateFocusedButton() {
this.setFocusedButton(this.state.focusedButton);
},
setFocusedButton(focusedButton) {
const {buttonIds} = this.state;
this.setState({
focusedButton: focusedButton && buttonIds.includes(focusedButton)
? focusedButton
: buttonIds[0]
});
},
setCurrentToolId(currentToolId) {
this.setState({currentToolId});
// Also set the currently focused button to this tool.
this.setFocusedButton(currentToolId);
},
setCanRender() {
this.setState({ canRender: true });
this.updateButtonIds();
},
setOptionsPanel(optionsPanel) {
this.setState({ optionsPanel });
this.updateButtonIds();
},
highlightTool(highlightedTool) {
this.setState({ highlightedTool });
},
unhighlightTool(id) {
if (this.state.highlightedTool === id) {
this.setState({ highlightedTool: "" });
}
},
setDockButtonsEnabled(areDockButtonsEnabled) {
this.setState({ areDockButtonsEnabled });
this.updateButtonIds();
},
setHostTypes(hostTypes) {
this.setState({ hostTypes });
this.updateButtonIds();
},
setCanCloseToolbox(canCloseToolbox) {
this.setState({ canCloseToolbox });
this.updateButtonIds();
},
setPanelDefinitions(panelDefinitions) {
this.setState({ panelDefinitions });
this.updateButtonIds();
},
setToolboxButtons(toolboxButtons) {
// Listen for updates of the checked attribute.
this.state.toolboxButtons.forEach(button => {
button.off("updatechecked", this.state.checkedButtonsUpdated);
});
toolboxButtons.forEach(button => {
button.on("updatechecked", this.state.checkedButtonsUpdated);
});
this.setState({ toolboxButtons });
this.updateButtonIds();
},
setCanMinimize(canMinimize) {
/* Bug 1177463 - The minimize button is currently hidden until we agree on
the UI for it, and until bug 1173849 is fixed too. */
// this.setState({ canMinimize });
},
render() {
return ToolboxToolbar(Object.assign({}, this.props, this.state));
}
});