152 lines
4.4 KiB
JavaScript
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));
|
|
}
|
|
});
|