UNPKG

office-ui-fabric-react

Version:

Reusable React components for building experiences for Office 365.

244 lines • 10.5 kB
import { find, values } from '../../Utilities'; import { mergeOverflows, sequencesToID } from '../../utilities/keytips/KeytipUtils'; import { KTP_LAYER_ID } from '../../utilities/keytips/KeytipConstants'; /** * This class is responsible for handling the parent/child relationships between keytips */ var KeytipTree = /** @class */ (function () { /** * KeytipTree constructor */ function KeytipTree() { this.nodeMap = {}; // Root has no keytipSequence this.root = { id: KTP_LAYER_ID, children: [], parent: '', keySequences: [] }; this.nodeMap[this.root.id] = this.root; } /** * Add a keytip node to this KeytipTree * * @param keytipProps - Keytip to add to the Tree * @param uniqueID - Unique ID for this keytip * @param persisted - T/F if this keytip should be marked as persisted */ KeytipTree.prototype.addNode = function (keytipProps, uniqueID, persisted) { var fullSequence = this._getFullSequence(keytipProps); var nodeID = sequencesToID(fullSequence); // Take off the last item to calculate the parent sequence fullSequence.pop(); // Parent ID is the root if there aren't any more sequences var parentID = this._getParentID(fullSequence); // Create node and add to map var node = this._createNode(nodeID, parentID, [], keytipProps, persisted); this.nodeMap[uniqueID] = node; // Try to add self to parents children, if they exist var parent = this.getNode(parentID); if (parent) { parent.children.push(nodeID); } }; /** * Updates a node in the tree * * @param keytipProps - Keytip props to update * @param uniqueID - Unique ID for this keytip */ KeytipTree.prototype.updateNode = function (keytipProps, uniqueID) { var fullSequence = this._getFullSequence(keytipProps); var nodeID = sequencesToID(fullSequence); // Take off the last item to calculate the parent sequence fullSequence.pop(); // Parent ID is the root if there aren't any more sequences var parentID = this._getParentID(fullSequence); var node = this.nodeMap[uniqueID]; if (node) { // Update values node.id = nodeID; node.keySequences = keytipProps.keySequences; node.overflowSetSequence = keytipProps.overflowSetSequence; node.onExecute = keytipProps.onExecute; node.onReturn = keytipProps.onReturn; node.hasDynamicChildren = keytipProps.hasDynamicChildren; node.hasMenu = keytipProps.hasMenu; node.parent = parentID; node.disabled = keytipProps.disabled; } }; /** * Removes a node from the KeytipTree * * @param sequence - full string of the node to remove */ KeytipTree.prototype.removeNode = function (keytipProps, uniqueID) { var fullSequence = this._getFullSequence(keytipProps); var nodeID = sequencesToID(fullSequence); // Take off the last sequence to calculate the parent ID fullSequence.pop(); // Parent ID is the root if there aren't any more sequences var parentID = this._getParentID(fullSequence); var parent = this.getNode(parentID); if (parent) { // Remove node from its parent's children parent.children.splice(parent.children.indexOf(nodeID), 1); } if (this.nodeMap[uniqueID]) { // Remove the node from the nodeMap delete this.nodeMap[uniqueID]; } }; /** * Searches the currentKeytip's children to exactly match a sequence. Will not match disabled nodes but * will match persisted nodes * * @param keySequence - string to match * @param currentKeytip - The keytip who's children will try to match * @returns {IKeytipTreeNode | undefined} The node that exactly matched the keySequence, or undefined if none matched */ KeytipTree.prototype.getExactMatchedNode = function (keySequence, currentKeytip) { var _this = this; var possibleNodes = this.getNodes(currentKeytip.children); return find(possibleNodes, function (node) { return _this._getNodeSequence(node) === keySequence && !node.disabled; }); }; /** * Searches the currentKeytip's children to find nodes that start with the given sequence. Will not match * disabled nodes but will match persisted nodes * * @param keySequence - string to partially match * @param currentKeytip - The keytip who's children will try to partially match * @returns {IKeytipTreeNode[]} List of tree nodes that partially match the given sequence */ KeytipTree.prototype.getPartiallyMatchedNodes = function (keySequence, currentKeytip) { var _this = this; // Get children that are persisted var possibleNodes = this.getNodes(currentKeytip.children); return possibleNodes.filter(function (node) { return _this._getNodeSequence(node).indexOf(keySequence) === 0 && !node.disabled; }); }; /** * Get the non-persisted children of the give node * If no node is given, will use the 'currentKeytip' * * @param node - Node to get the children for * @returns {string[]} List of node IDs that are the children of the node */ KeytipTree.prototype.getChildren = function (node) { var _this = this; if (!node) { node = this.currentKeytip; if (!node) { return []; } } var children = node.children; return Object.keys(this.nodeMap).reduce(function (nodes, key) { if (children.indexOf(_this.nodeMap[key].id) >= 0 && !_this.nodeMap[key].persisted) { nodes.push(_this.nodeMap[key].id); } return nodes; }, []); }; /** * Gets all nodes from their IDs * * @param ids List of keytip IDs * @returns {IKeytipTreeNode[]} Array of nodes that match the given IDs, can be empty */ KeytipTree.prototype.getNodes = function (ids) { var _this = this; return Object.keys(this.nodeMap).reduce(function (nodes, key) { if (ids.indexOf(_this.nodeMap[key].id) >= 0) { nodes.push(_this.nodeMap[key]); } return nodes; }, []); }; /** * Gets a single node from its ID * * @param id - ID of the node to get * @returns {IKeytipTreeNode | undefined} Node with the given ID, if found */ KeytipTree.prototype.getNode = function (id) { var nodeMapValues = values(this.nodeMap); return find(nodeMapValues, function (node) { return node.id === id; }); }; /** * Tests if the currentKeytip in this.keytipTree is the parent of 'keytipProps' * * @param keytipProps - Keytip to test the parent for * @returns {boolean} T/F if the currentKeytip is this keytipProps' parent */ KeytipTree.prototype.isCurrentKeytipParent = function (keytipProps) { if (this.currentKeytip) { var fullSequence = keytipProps.keySequences.slice(); if (keytipProps.overflowSetSequence) { fullSequence = mergeOverflows(fullSequence, keytipProps.overflowSetSequence); } // Take off the last sequence to calculate the parent ID fullSequence.pop(); // Parent ID is the root if there aren't any more sequences var parentID = fullSequence.length === 0 ? this.root.id : sequencesToID(fullSequence); var matchesCurrWithoutOverflow = false; if (this.currentKeytip.overflowSetSequence) { var currKeytipIdWithoutOverflow = sequencesToID(this.currentKeytip.keySequences); matchesCurrWithoutOverflow = currKeytipIdWithoutOverflow === parentID; } return matchesCurrWithoutOverflow || this.currentKeytip.id === parentID; } return false; }; KeytipTree.prototype._getParentID = function (fullSequence) { return fullSequence.length === 0 ? this.root.id : sequencesToID(fullSequence); }; KeytipTree.prototype._getFullSequence = function (keytipProps) { var fullSequence = keytipProps.keySequences.slice(); if (keytipProps.overflowSetSequence) { fullSequence = mergeOverflows(fullSequence, keytipProps.overflowSetSequence); } return fullSequence; }; KeytipTree.prototype._getNodeSequence = function (node) { var fullSequence = node.keySequences.slice(); if (node.overflowSetSequence) { fullSequence = mergeOverflows(fullSequence, node.overflowSetSequence); } return fullSequence[fullSequence.length - 1]; }; KeytipTree.prototype._createNode = function (id, parentId, children, keytipProps, persisted) { var _this = this; var keySequences = keytipProps.keySequences, hasDynamicChildren = keytipProps.hasDynamicChildren, overflowSetSequence = keytipProps.overflowSetSequence, hasMenu = keytipProps.hasMenu, onExecute = keytipProps.onExecute, onReturn = keytipProps.onReturn, disabled = keytipProps.disabled; var node = { id: id, keySequences: keySequences, overflowSetSequence: overflowSetSequence, parent: parentId, children: children, onExecute: onExecute, onReturn: onReturn, hasDynamicChildren: hasDynamicChildren, hasMenu: hasMenu, disabled: disabled, persisted: persisted }; node.children = Object.keys(this.nodeMap).reduce(function (array, nodeMapKey) { if (_this.nodeMap[nodeMapKey].parent === id) { array.push(_this.nodeMap[nodeMapKey].id); } return array; }, []); return node; }; return KeytipTree; }()); export { KeytipTree }; //# sourceMappingURL=KeytipTree.js.map