Files
tubestation/devtools/client/framework/components/toolbox-tabs.js
2017-03-01 17:32:55 +01:00

155 lines
3.7 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 {DOM, createClass, createFactory, PropTypes} = require("devtools/client/shared/vendor/react");
const {findDOMNode} = require("devtools/client/shared/vendor/react-dom");
const {button, div} = DOM;
const Menu = require("devtools/client/framework/menu");
const MenuItem = require("devtools/client/framework/menu-item");
const ToolboxTab = createFactory(require("devtools/client/framework/components/toolbox-tab"));
module.exports = createClass({
displayName: "ToolboxTabs",
// See toolbox-toolbar propTypes for details on the props used here.
propTypes: {
currentToolId: PropTypes.string,
focusButton: PropTypes.func,
focusedButton: PropTypes.string,
highlightedTool: PropTypes.string,
panelDefinitions: PropTypes.array,
selectTool: PropTypes.func,
toolbox: PropTypes.object,
L10N: PropTypes.object,
},
getInitialState() {
return {
overflow: false,
};
},
componentDidUpdate() {
this.addFlowEvents();
},
componentWillUnmount() {
this.removeFlowEvents();
},
addFlowEvents() {
this.removeFlowEvents();
let node = findDOMNode(this);
if (node) {
node.addEventListener("overflow", this.onOverflow);
node.addEventListener("underflow", this.onUnderflow);
}
},
removeFlowEvents() {
let node = findDOMNode(this);
if (node) {
node.removeEventListener("overflow", this.onOverflow);
node.removeEventListener("underflow", this.onUnderflow);
}
},
onOverflow() {
this.setState({
overflow: true
});
},
onUnderflow() {
this.setState({
overflow: false
});
},
/**
* Render all of the tabs, based on the panel definitions and builds out
* a toolbox tab for each of them. Will render an all-tabs button if the
* container has an overflow.
*/
render() {
let {
currentToolId,
focusButton,
focusedButton,
highlightedTool,
panelDefinitions,
selectTool,
} = this.props;
let tabs = panelDefinitions.map(panelDefinition => ToolboxTab({
currentToolId,
focusButton,
focusedButton,
highlightedTool,
panelDefinition,
selectTool,
}));
// A wrapper is needed to get flex sizing correct in XUL.
return div(
{
className: "toolbox-tabs-wrapper"
},
div(
{
className: "toolbox-tabs"
},
tabs
),
this.state.overflow ? renderAllToolsButton(this.props) : null
);
},
});
/**
* Render a button to access all tools, displayed only when the toolbar presents an
* overflow.
*/
function renderAllToolsButton(props) {
let {
currentToolId,
panelDefinitions,
selectTool,
toolbox,
L10N,
} = props;
return button({
className: "all-tools-menu all-tabs-menu",
tabIndex: -1,
title: L10N.getStr("toolbox.allToolsButton.tooltip"),
onClick: ({ target }) => {
let menu = new Menu({
id: "all-tools-menupopup"
});
panelDefinitions.forEach(({id, label}) => {
menu.append(new MenuItem({
checked: currentToolId === id,
click: () => {
selectTool(id);
},
id: "all-tools-menupopup-" + id,
label,
}));
});
let rect = target.getBoundingClientRect();
let screenX = target.ownerDocument.defaultView.mozInnerScreenX;
let screenY = target.ownerDocument.defaultView.mozInnerScreenY;
// Display the popup below the button.
menu.popup(rect.left + screenX, rect.bottom + screenY, toolbox);
return menu;
},
});
}