/* 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";
// Map with tool Id and its width size. This lifecycle is out of React's // lifecycle. If a tool is registered, ToolboxTabs will add target tool id // to this map. ToolboxTabs will never remove tool id from this cache. this._cachedToolTabsWidthMap = new Map();
// FIXME: https://bugzilla.mozilla.org/show_bug.cgi?id=1774507
UNSAFE_componentWillUpdate(nextProps, nextState) { if (this.shouldUpdateToolboxTabs(this.props, nextProps)) { // Force recalculate and render in this cycle if panel definition has // changed or selected tool has changed.
nextState.overflowedTabIds = [];
}
}
/** * Check if two array of ids are the same or not.
*/
equalToolIdArray(prevPanels, nextPanels) { if (prevPanels.length !== nextPanels.length) { returnfalse;
}
// Check panel definitions even if both of array size is same. // For example, the case of changing the tab's order. return prevPanels.join("-") === nextPanels.join("-");
}
/** * Return true if we should update the overflowed tabs.
*/
shouldUpdateToolboxTabs(prevProps, nextProps) { if (
prevProps.currentToolId !== nextProps.currentToolId ||
prevProps.visibleToolboxButtonCount !==
nextProps.visibleToolboxButtonCount
) { returntrue;
}
/** * Update the Map of tool id and tool tab width.
*/
updateCachedToolTabsWidthMap() { const utils = window.windowUtils; // Force a reflow before calling getBoundingWithoutFlushing on each tab. this.wrapperEl.current.clientWidth;
for (const tab of this.wrapperEl.current.querySelectorAll( ".devtools-tab"
)) { const tabId = tab.id.replace("toolbox-tab-", ""); if (!this._cachedToolTabsWidthMap.has(tabId)) { const rect = utils.getBoundsWithoutFlushing(tab); this._cachedToolTabsWidthMap.set(tabId, rect.width);
}
}
}
/** * Update the overflowed tab array from currently displayed tool tab. * If calculated result is the same as the current overflowed tab array, this * function will not update state.
*/
updateOverflowedTabs() { const toolboxWidth = parseInt(
getComputedStyle(this.wrapperEl.current).width,
10
); const { currentToolId } = this.props; const enabledTabs = this.props.panelDefinitions.map(def => def.id);
let sumWidth = 0; const visibleTabs = [];
for (const id of enabledTabs) { const width = this._cachedToolTabsWidthMap.get(id);
sumWidth += width; if (sumWidth <= toolboxWidth) {
visibleTabs.push(id);
} else {
sumWidth = sumWidth - width + CHEVRON_BUTTON_WIDTH;
// If toolbox can't display the Chevron, remove the last tool tab. if (sumWidth > toolboxWidth) { const removeTabId = visibleTabs.pop();
sumWidth -= this._cachedToolTabsWidthMap.get(removeTabId);
} break;
}
}
// If the selected tab is in overflowed tabs, insert it into a visible // toolbox. if (
!visibleTabs.includes(currentToolId) &&
enabledTabs.includes(currentToolId)
) { const selectedToolWidth = this._cachedToolTabsWidthMap.get(currentToolId); while (
sumWidth + selectedToolWidth > toolboxWidth &&
visibleTabs.length
) { const removingToolId = visibleTabs.pop(); const removingToolWidth = this._cachedToolTabsWidthMap.get(removingToolId);
sumWidth -= removingToolWidth;
}
// If toolbox width is narrow, toolbox display only chevron menu. // i.e. All tool tabs will overflow. if (sumWidth + selectedToolWidth <= toolboxWidth) {
visibleTabs.push(currentToolId);
}
}
const willOverflowTabs = enabledTabs.filter(
id => !visibleTabs.includes(id)
); if (!this.equalToolIdArray(this.state.overflowedTabIds, willOverflowTabs)) { this.setState({ overflowedTabIds: willOverflowTabs });
}
}
/** * Render a button to access overflowed tools, displayed only when the toolbar * presents an overflow.
*/
renderToolsChevronButton() { const { toolbox } = this.props;
/** * Render all of the tabs, based on the panel definitions and builds out * a toolbox tab for each of them. Will render the chevron button if the * container has an overflow.
*/
render() { const {
currentToolId,
focusButton,
focusedButton,
highlightedTools,
panelDefinitions,
selectTool,
} = this.props;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung ist noch experimentell.