"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.warnOnlyTreeNode = warnOnlyTreeNode; exports.arrDel = arrDel; exports.arrAdd = arrAdd; exports.posToArr = posToArr; exports.getPosition = getPosition; exports.isTreeNode = isTreeNode; exports.getNodeChildren = getNodeChildren; exports.isCheckDisabled = isCheckDisabled; exports.traverseTreeNodes = traverseTreeNodes; exports.mapChildren = mapChildren; exports.getDragNodesKeys = getDragNodesKeys; exports.calcDropPosition = calcDropPosition; exports.calcSelectedKeys = calcSelectedKeys; exports.convertDataToTree = convertDataToTree; exports.convertTreeToEntities = convertTreeToEntities; exports.parseCheckedKeys = parseCheckedKeys; exports.conductCheck = conductCheck; exports.conductExpandParent = conductExpandParent; exports.getDataAndAria = getDataAndAria; var _react = _interopRequireWildcard(require("react")); var _toArray = _interopRequireDefault(require("rc-util/lib/Children/toArray")); var _warning = _interopRequireDefault(require("warning")); var _TreeNode = _interopRequireDefault(require("./TreeNode")); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function _getRequireWildcardCache() { return cache; }; return cache; } function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || _typeof(obj) !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; } function _typeof(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); } function _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; } function _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; } var DRAG_SIDE_RANGE = 0.25; var DRAG_MIN_GAP = 2; var onlyTreeNodeWarned = false; function warnOnlyTreeNode() { if (onlyTreeNodeWarned) return; onlyTreeNodeWarned = true; (0, _warning.default)(false, 'Tree only accept TreeNode as children.'); } function arrDel(list, value) { var clone = list.slice(); var index = clone.indexOf(value); if (index >= 0) { clone.splice(index, 1); } return clone; } function arrAdd(list, value) { var clone = list.slice(); if (clone.indexOf(value) === -1) { clone.push(value); } return clone; } function posToArr(pos) { return pos.split('-'); } function getPosition(level, index) { return "".concat(level, "-").concat(index); } function isTreeNode(node) { return node && node.type && node.type.isTreeNode; } function getNodeChildren(children) { return (0, _toArray.default)(children).filter(isTreeNode); } function isCheckDisabled(node) { var _ref = node.props || {}, disabled = _ref.disabled, disableCheckbox = _ref.disableCheckbox, checkable = _ref.checkable; return !!(disabled || disableCheckbox) || checkable === false; } function traverseTreeNodes(treeNodes, callback) { function processNode(node, index, parent) { var children = node ? node.props.children : treeNodes; var pos = node ? getPosition(parent.pos, index) : 0; // Filter children var childList = getNodeChildren(children); // Process node if is not root if (node) { var data = { node: node, index: index, pos: pos, key: node.key || pos, parentPos: parent.node ? parent.pos : null }; callback(data); } // Process children node _react.Children.forEach(childList, function (subNode, subIndex) { processNode(subNode, subIndex, { node: node, pos: pos }); }); } processNode(null); } /** * Use `rc-util` `toArray` to get the children list which keeps the key. * And return single node if children is only one(This can avoid `key` missing check). */ function mapChildren(children, func) { var list = (0, _toArray.default)(children).map(func); if (list.length === 1) { return list[0]; } return list; } function getDragNodesKeys(treeNodes, node) { var _node$props = node.props, eventKey = _node$props.eventKey, pos = _node$props.pos; var dragNodesKeys = []; traverseTreeNodes(treeNodes, function (_ref2) { var key = _ref2.key; dragNodesKeys.push(key); }); dragNodesKeys.push(eventKey || pos); return dragNodesKeys; } // Only used when drag, not affect SSR. function calcDropPosition(event, treeNode) { var clientY = event.clientY; var _treeNode$selectHandl = treeNode.selectHandle.getBoundingClientRect(), top = _treeNode$selectHandl.top, bottom = _treeNode$selectHandl.bottom, height = _treeNode$selectHandl.height; var des = Math.max(height * DRAG_SIDE_RANGE, DRAG_MIN_GAP); if (clientY <= top + des) { return -1; } if (clientY >= bottom - des) { return 1; } return 0; } /** * Return selectedKeys according with multiple prop * @param selectedKeys * @param props * @returns [string] */ function calcSelectedKeys(selectedKeys, props) { if (!selectedKeys) return undefined; var multiple = props.multiple; if (multiple) { return selectedKeys.slice(); } if (selectedKeys.length) { return [selectedKeys[0]]; } return selectedKeys; } /** * Since React internal will convert key to string, * we need do this to avoid `checkStrictly` use number match */ function keyListToString(keyList) { if (!keyList) return keyList; return keyList.map(function (key) { return String(key); }); } var internalProcessProps = function internalProcessProps(props) { return props; }; function convertDataToTree(treeData, processor) { if (!treeData) return []; var _ref3 = processor || {}, _ref3$processProps = _ref3.processProps, processProps = _ref3$processProps === void 0 ? internalProcessProps : _ref3$processProps; var list = Array.isArray(treeData) ? treeData : [treeData]; return list.map(function (_ref4) { var children = _ref4.children, props = _objectWithoutProperties(_ref4, ["children"]); var childrenNodes = convertDataToTree(children, processor); return _react.default.createElement(_TreeNode.default, Object.assign({}, processProps(props)), childrenNodes); }); } /** * Calculate treeNodes entities. `processTreeEntity` is used for `rc-tree-select` * @param treeNodes * @param processTreeEntity User can customize the entity */ function convertTreeToEntities(treeNodes) { var _ref5 = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}, initWrapper = _ref5.initWrapper, processEntity = _ref5.processEntity, onProcessFinished = _ref5.onProcessFinished; var posEntities = {}; var keyEntities = {}; var wrapper = { posEntities: posEntities, keyEntities: keyEntities }; if (initWrapper) { wrapper = initWrapper(wrapper) || wrapper; } traverseTreeNodes(treeNodes, function (item) { var node = item.node, index = item.index, pos = item.pos, key = item.key, parentPos = item.parentPos; var entity = { node: node, index: index, key: key, pos: pos }; posEntities[pos] = entity; keyEntities[key] = entity; // Fill children entity.parent = posEntities[parentPos]; if (entity.parent) { entity.parent.children = entity.parent.children || []; entity.parent.children.push(entity); } if (processEntity) { processEntity(entity, wrapper); } }); if (onProcessFinished) { onProcessFinished(wrapper); } return wrapper; } /** * Parse `checkedKeys` to { checkedKeys, halfCheckedKeys } style */ function parseCheckedKeys(keys) { if (!keys) { return null; } // Convert keys to object format var keyProps; if (Array.isArray(keys)) { // [Legacy] Follow the api doc keyProps = { checkedKeys: keys, halfCheckedKeys: undefined }; } else if (_typeof(keys) === 'object') { keyProps = { checkedKeys: keys.checked || undefined, halfCheckedKeys: keys.halfChecked || undefined }; } else { (0, _warning.default)(false, '`checkedKeys` is not an array or an object'); return null; } keyProps.checkedKeys = keyListToString(keyProps.checkedKeys); keyProps.halfCheckedKeys = keyListToString(keyProps.halfCheckedKeys); return keyProps; } /** * Conduct check state by the keyList. It will conduct up & from the provided key. * If the conduct path reach the disabled or already checked / unchecked node will stop conduct. */ function conductCheck( /** list of keys */ keyList, /** is check the node or not */ isCheck, /** parsed by `convertTreeToEntities` function in Tree */ keyEntities) { var checkStatus = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {}; var checkedKeys = {}; var halfCheckedKeys = {}; // Record the key has some child checked (include child half checked) (checkStatus.checkedKeys || []).forEach(function (key) { checkedKeys[key] = true; }); (checkStatus.halfCheckedKeys || []).forEach(function (key) { halfCheckedKeys[key] = true; }); // Conduct up function conductUp(key) { if (checkedKeys[key] === isCheck) return; var entity = keyEntities[key]; if (!entity) return; var children = entity.children, parent = entity.parent, node = entity.node; if (isCheckDisabled(node)) return; // Check child node checked status var everyChildChecked = true; var someChildChecked = false; // Child checked or half checked (children || []).filter(function (child) { return !isCheckDisabled(child.node); }).forEach(function (_ref6) { var childKey = _ref6.key; var childChecked = checkedKeys[childKey]; var childHalfChecked = halfCheckedKeys[childKey]; if (childChecked || childHalfChecked) someChildChecked = true; if (!childChecked) everyChildChecked = false; }); // Update checked status if (isCheck) { checkedKeys[key] = everyChildChecked; } else { checkedKeys[key] = false; } halfCheckedKeys[key] = someChildChecked; if (parent) { conductUp(parent.key); } } // Conduct down function conductDown(key) { if (checkedKeys[key] === isCheck) return; var entity = keyEntities[key]; if (!entity) return; var children = entity.children, node = entity.node; if (isCheckDisabled(node)) return; checkedKeys[key] = isCheck; (children || []).forEach(function (child) { conductDown(child.key); }); } function conduct(key) { var entity = keyEntities[key]; if (!entity) { (0, _warning.default)(false, "'".concat(key, "' does not exist in the tree.")); return; } var children = entity.children, parent = entity.parent, node = entity.node; checkedKeys[key] = isCheck; if (isCheckDisabled(node)) return; // Conduct down (children || []).filter(function (child) { return !isCheckDisabled(child.node); }).forEach(function (child) { conductDown(child.key); }); // Conduct up if (parent) { conductUp(parent.key); } } (keyList || []).forEach(function (key) { conduct(key); }); var checkedKeyList = []; var halfCheckedKeyList = []; // Fill checked list Object.keys(checkedKeys).forEach(function (key) { if (checkedKeys[key]) { checkedKeyList.push(key); } }); // Fill half checked list Object.keys(halfCheckedKeys).forEach(function (key) { if (!checkedKeys[key] && halfCheckedKeys[key]) { halfCheckedKeyList.push(key); } }); return { checkedKeys: checkedKeyList, halfCheckedKeys: halfCheckedKeyList }; } /** * If user use `autoExpandParent` we should get the list of parent node * @param keyList * @param keyEntities */ function conductExpandParent(keyList, keyEntities) { var expandedKeys = {}; function conductUp(key) { if (expandedKeys[key]) return; var entity = keyEntities[key]; if (!entity) return; expandedKeys[key] = true; var parent = entity.parent, node = entity.node; if (node.props && node.props.disabled) return; if (parent) { conductUp(parent.key); } } (keyList || []).forEach(function (key) { conductUp(key); }); return Object.keys(expandedKeys); } /** * Returns only the data- and aria- key/value pairs */ function getDataAndAria(props) { return Object.keys(props).reduce(function (prev, key) { if (key.substr(0, 5) === 'data-' || key.substr(0, 5) === 'aria-') { prev[key] = props[key]; } return prev; }, {}); }