зеркало из https://github.com/mozilla/gecko-dev.git
202 строки
5.9 KiB
JavaScript
202 строки
5.9 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 {
|
|
Component,
|
|
createFactory,
|
|
} = require("devtools/client/shared/vendor/react");
|
|
const ToolboxToolbar = createFactory(
|
|
require("devtools/client/framework/components/ToolboxToolbar")
|
|
);
|
|
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.
|
|
*/
|
|
class ToolboxController extends Component {
|
|
constructor(props, context) {
|
|
super(props, context);
|
|
|
|
// See the ToolboxToolbar propTypes for documentation on each of these items in
|
|
// state, and for the definitions of the props that are expected to be passed in.
|
|
this.state = {
|
|
focusedButton: ELEMENT_PICKER_ID,
|
|
toolboxButtons: [],
|
|
visibleToolboxButtonCount: 0,
|
|
currentToolId: null,
|
|
highlightedTools: new Set(),
|
|
panelDefinitions: [],
|
|
hostTypes: [],
|
|
currentHostType: undefined,
|
|
areDockOptionsEnabled: true,
|
|
canCloseToolbox: true,
|
|
isSplitConsoleActive: false,
|
|
disableAutohide: undefined,
|
|
canRender: false,
|
|
buttonIds: [],
|
|
checkedButtonsUpdated: () => {
|
|
this.forceUpdate();
|
|
},
|
|
};
|
|
|
|
this.setFocusedButton = this.setFocusedButton.bind(this);
|
|
this.setToolboxButtons = this.setToolboxButtons.bind(this);
|
|
this.setCurrentToolId = this.setCurrentToolId.bind(this);
|
|
this.highlightTool = this.highlightTool.bind(this);
|
|
this.unhighlightTool = this.unhighlightTool.bind(this);
|
|
this.setHostTypes = this.setHostTypes.bind(this);
|
|
this.setCurrentHostType = this.setCurrentHostType.bind(this);
|
|
this.setDockOptionsEnabled = this.setDockOptionsEnabled.bind(this);
|
|
this.setCanCloseToolbox = this.setCanCloseToolbox.bind(this);
|
|
this.setIsSplitConsoleActive = this.setIsSplitConsoleActive.bind(this);
|
|
this.setDisableAutohide = this.setDisableAutohide.bind(this);
|
|
this.setCanRender = this.setCanRender.bind(this);
|
|
this.setPanelDefinitions = this.setPanelDefinitions.bind(this);
|
|
this.updateButtonIds = this.updateButtonIds.bind(this);
|
|
this.updateFocusedButton = this.updateFocusedButton.bind(this);
|
|
}
|
|
|
|
shouldComponentUpdate() {
|
|
return this.state.canRender;
|
|
}
|
|
|
|
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 { toolboxButtons, panelDefinitions, 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),
|
|
canCloseToolbox ? "toolbox-close" : null,
|
|
].filter(id => id),
|
|
});
|
|
|
|
this.updateFocusedButton();
|
|
}
|
|
|
|
updateFocusedButton() {
|
|
this.setFocusedButton(this.state.focusedButton);
|
|
}
|
|
|
|
setFocusedButton(focusedButton) {
|
|
const { buttonIds } = this.state;
|
|
|
|
focusedButton =
|
|
focusedButton && buttonIds.includes(focusedButton)
|
|
? focusedButton
|
|
: buttonIds[0];
|
|
if (this.state.focusedButton !== focusedButton) {
|
|
this.setState({
|
|
focusedButton,
|
|
});
|
|
}
|
|
}
|
|
|
|
setCurrentToolId(currentToolId) {
|
|
this.setState({ currentToolId }, () => {
|
|
// Also set the currently focused button to this tool.
|
|
this.setFocusedButton(currentToolId);
|
|
});
|
|
}
|
|
|
|
setCanRender() {
|
|
this.setState({ canRender: true }, this.updateButtonIds);
|
|
}
|
|
|
|
isToolHighlighted(toolID) {
|
|
return this.state.highlightedTools.has(toolID);
|
|
}
|
|
|
|
highlightTool(highlightedTool) {
|
|
const { highlightedTools } = this.state;
|
|
highlightedTools.add(highlightedTool);
|
|
this.setState({ highlightedTools });
|
|
}
|
|
|
|
unhighlightTool(id) {
|
|
const { highlightedTools } = this.state;
|
|
if (highlightedTools.has(id)) {
|
|
highlightedTools.delete(id);
|
|
this.setState({ highlightedTools });
|
|
}
|
|
}
|
|
|
|
setDockOptionsEnabled(areDockOptionsEnabled) {
|
|
this.setState({ areDockOptionsEnabled });
|
|
}
|
|
|
|
setHostTypes(hostTypes) {
|
|
this.setState({ hostTypes });
|
|
}
|
|
|
|
setCurrentHostType(currentHostType) {
|
|
this.setState({ currentHostType });
|
|
}
|
|
|
|
setCanCloseToolbox(canCloseToolbox) {
|
|
this.setState({ canCloseToolbox }, this.updateButtonIds);
|
|
}
|
|
|
|
setIsSplitConsoleActive(isSplitConsoleActive) {
|
|
this.setState({ isSplitConsoleActive });
|
|
}
|
|
|
|
setDisableAutohide(disableAutohide) {
|
|
this.setState({ disableAutohide });
|
|
}
|
|
|
|
setPanelDefinitions(panelDefinitions) {
|
|
this.setState({ panelDefinitions }, this.updateButtonIds);
|
|
}
|
|
|
|
get panelDefinitions() {
|
|
return this.state.panelDefinitions;
|
|
}
|
|
|
|
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);
|
|
});
|
|
|
|
const visibleToolboxButtonCount = toolboxButtons.filter(
|
|
button => button.isVisible
|
|
).length;
|
|
|
|
this.setState(
|
|
{ toolboxButtons, visibleToolboxButtonCount },
|
|
this.updateButtonIds
|
|
);
|
|
}
|
|
|
|
render() {
|
|
return ToolboxToolbar(Object.assign({}, this.props, this.state));
|
|
}
|
|
}
|
|
|
|
module.exports = ToolboxController;
|