element-plus
Version:
A Component Library for Vue 3
449 lines (444 loc) • 12.4 kB
JavaScript
'use strict';
Object.defineProperty(exports, '__esModule', { value: true });
var vue = require('vue');
var util = require('./util.js');
var shared = require('@vue/shared');
var types = require('../../../../utils/types.js');
const getChildState = (node) => {
let all = true;
let none = true;
let allWithoutDisable = true;
for (let i = 0, j = node.length; i < j; i++) {
const n = node[i];
if (n.checked !== true || n.indeterminate) {
all = false;
if (!n.disabled) {
allWithoutDisable = false;
}
}
if (n.checked !== false || n.indeterminate) {
none = false;
}
}
return { all, none, allWithoutDisable, half: !all && !none };
};
const reInitChecked = function(node) {
if (node.childNodes.length === 0 || node.loading)
return;
const { all, none, half } = getChildState(node.childNodes);
if (all) {
node.checked = true;
node.indeterminate = false;
} else if (half) {
node.checked = false;
node.indeterminate = true;
} else if (none) {
node.checked = false;
node.indeterminate = false;
}
const parent = node.parent;
if (!parent || parent.level === 0)
return;
if (!node.store.checkStrictly) {
reInitChecked(parent);
}
};
const getPropertyFromData = function(node, prop) {
const props = node.store.props;
const data = node.data || {};
const config = props[prop];
if (shared.isFunction(config)) {
return config(data, node);
} else if (shared.isString(config)) {
return data[config];
} else if (types.isUndefined(config)) {
const dataProp = data[prop];
return types.isUndefined(dataProp) ? "" : dataProp;
}
};
let nodeIdSeed = 0;
class Node {
constructor(options) {
this.id = nodeIdSeed++;
this.text = null;
this.checked = false;
this.indeterminate = false;
this.data = null;
this.expanded = false;
this.parent = null;
this.visible = true;
this.isCurrent = false;
this.canFocus = false;
for (const name in options) {
if (shared.hasOwn(options, name)) {
this[name] = options[name];
}
}
this.level = 0;
this.loaded = false;
this.childNodes = [];
this.loading = false;
if (this.parent) {
this.level = this.parent.level + 1;
}
}
initialize() {
const store = this.store;
if (!store) {
throw new Error("[Node]store is required!");
}
store.registerNode(this);
const props = store.props;
if (props && typeof props.isLeaf !== "undefined") {
const isLeaf = getPropertyFromData(this, "isLeaf");
if (types.isBoolean(isLeaf)) {
this.isLeafByUser = isLeaf;
}
}
if (store.lazy !== true && this.data) {
this.setData(this.data);
if (store.defaultExpandAll) {
this.expanded = true;
this.canFocus = true;
}
} else if (this.level > 0 && store.lazy && store.defaultExpandAll && !this.isLeafByUser) {
this.expand();
}
if (!shared.isArray(this.data)) {
util.markNodeData(this, this.data);
}
if (!this.data)
return;
const defaultExpandedKeys = store.defaultExpandedKeys;
const key = store.key;
if (key && defaultExpandedKeys && defaultExpandedKeys.includes(this.key)) {
this.expand(null, store.autoExpandParent);
}
if (key && store.currentNodeKey !== void 0 && this.key === store.currentNodeKey) {
store.currentNode = this;
store.currentNode.isCurrent = true;
}
if (store.lazy) {
store._initDefaultCheckedNode(this);
}
this.updateLeafState();
if (this.parent && (this.level === 1 || this.parent.expanded === true))
this.canFocus = true;
}
setData(data) {
if (!shared.isArray(data)) {
util.markNodeData(this, data);
}
this.data = data;
this.childNodes = [];
let children;
if (this.level === 0 && shared.isArray(this.data)) {
children = this.data;
} else {
children = getPropertyFromData(this, "children") || [];
}
for (let i = 0, j = children.length; i < j; i++) {
this.insertChild({ data: children[i] });
}
}
get label() {
return getPropertyFromData(this, "label");
}
get key() {
const nodeKey = this.store.key;
if (this.data)
return this.data[nodeKey];
return null;
}
get disabled() {
return getPropertyFromData(this, "disabled");
}
get nextSibling() {
const parent = this.parent;
if (parent) {
const index = parent.childNodes.indexOf(this);
if (index > -1) {
return parent.childNodes[index + 1];
}
}
return null;
}
get previousSibling() {
const parent = this.parent;
if (parent) {
const index = parent.childNodes.indexOf(this);
if (index > -1) {
return index > 0 ? parent.childNodes[index - 1] : null;
}
}
return null;
}
contains(target, deep = true) {
return (this.childNodes || []).some((child) => child === target || deep && child.contains(target));
}
remove() {
const parent = this.parent;
if (parent) {
parent.removeChild(this);
}
}
insertChild(child, index, batch) {
if (!child)
throw new Error("InsertChild error: child is required.");
if (!(child instanceof Node)) {
if (!batch) {
const children = this.getChildren(true);
if (!children.includes(child.data)) {
if (types.isUndefined(index) || index < 0) {
children.push(child.data);
} else {
children.splice(index, 0, child.data);
}
}
}
Object.assign(child, {
parent: this,
store: this.store
});
child = vue.reactive(new Node(child));
if (child instanceof Node) {
child.initialize();
}
}
child.level = this.level + 1;
if (types.isUndefined(index) || index < 0) {
this.childNodes.push(child);
} else {
this.childNodes.splice(index, 0, child);
}
this.updateLeafState();
}
insertBefore(child, ref) {
let index;
if (ref) {
index = this.childNodes.indexOf(ref);
}
this.insertChild(child, index);
}
insertAfter(child, ref) {
let index;
if (ref) {
index = this.childNodes.indexOf(ref);
if (index !== -1)
index += 1;
}
this.insertChild(child, index);
}
removeChild(child) {
const children = this.getChildren() || [];
const dataIndex = children.indexOf(child.data);
if (dataIndex > -1) {
children.splice(dataIndex, 1);
}
const index = this.childNodes.indexOf(child);
if (index > -1) {
this.store && this.store.deregisterNode(child);
child.parent = null;
this.childNodes.splice(index, 1);
}
this.updateLeafState();
}
removeChildByData(data) {
let targetNode = null;
for (let i = 0; i < this.childNodes.length; i++) {
if (this.childNodes[i].data === data) {
targetNode = this.childNodes[i];
break;
}
}
if (targetNode) {
this.removeChild(targetNode);
}
}
expand(callback, expandParent) {
const done = () => {
if (expandParent) {
let parent = this.parent;
while (parent.level > 0) {
parent.expanded = true;
parent = parent.parent;
}
}
this.expanded = true;
if (callback)
callback();
this.childNodes.forEach((item) => {
item.canFocus = true;
});
};
if (this.shouldLoadData()) {
this.loadData((data) => {
if (shared.isArray(data)) {
if (this.checked) {
this.setChecked(true, true);
} else if (!this.store.checkStrictly) {
reInitChecked(this);
}
done();
}
});
} else {
done();
}
}
doCreateChildren(array, defaultProps = {}) {
array.forEach((item) => {
this.insertChild(Object.assign({ data: item }, defaultProps), void 0, true);
});
}
collapse() {
this.expanded = false;
this.childNodes.forEach((item) => {
item.canFocus = false;
});
}
shouldLoadData() {
return this.store.lazy === true && this.store.load && !this.loaded;
}
updateLeafState() {
if (this.store.lazy === true && this.loaded !== true && typeof this.isLeafByUser !== "undefined") {
this.isLeaf = this.isLeafByUser;
return;
}
const childNodes = this.childNodes;
if (!this.store.lazy || this.store.lazy === true && this.loaded === true) {
this.isLeaf = !childNodes || childNodes.length === 0;
return;
}
this.isLeaf = false;
}
setChecked(value, deep, recursion, passValue) {
this.indeterminate = value === "half";
this.checked = value === true;
if (this.store.checkStrictly)
return;
if (!(this.shouldLoadData() && !this.store.checkDescendants)) {
const { all, allWithoutDisable } = getChildState(this.childNodes);
if (!this.isLeaf && !all && allWithoutDisable) {
this.checked = false;
value = false;
}
const handleDescendants = () => {
if (deep) {
const childNodes = this.childNodes;
for (let i = 0, j = childNodes.length; i < j; i++) {
const child = childNodes[i];
passValue = passValue || value !== false;
const isCheck = child.disabled ? child.checked : passValue;
child.setChecked(isCheck, deep, true, passValue);
}
const { half, all: all2 } = getChildState(childNodes);
if (!all2) {
this.checked = all2;
this.indeterminate = half;
}
}
};
if (this.shouldLoadData()) {
this.loadData(() => {
handleDescendants();
reInitChecked(this);
}, {
checked: value !== false
});
return;
} else {
handleDescendants();
}
}
const parent = this.parent;
if (!parent || parent.level === 0)
return;
if (!recursion) {
reInitChecked(parent);
}
}
getChildren(forceInit = false) {
if (this.level === 0)
return this.data;
const data = this.data;
if (!data)
return null;
const props = this.store.props;
let children = "children";
if (props) {
children = props.children || "children";
}
if (types.isUndefined(data[children])) {
data[children] = null;
}
if (forceInit && !data[children]) {
data[children] = [];
}
return data[children];
}
updateChildren() {
const newData = this.getChildren() || [];
const oldData = this.childNodes.map((node) => node.data);
const newDataMap = {};
const newNodes = [];
newData.forEach((item, index) => {
const key = item[util.NODE_KEY];
const isNodeExists = !!key && oldData.findIndex((data) => data[util.NODE_KEY] === key) >= 0;
if (isNodeExists) {
newDataMap[key] = { index, data: item };
} else {
newNodes.push({ index, data: item });
}
});
if (!this.store.lazy) {
oldData.forEach((item) => {
if (!newDataMap[item[util.NODE_KEY]])
this.removeChildByData(item);
});
}
newNodes.forEach(({ index, data }) => {
this.insertChild({ data }, index);
});
this.updateLeafState();
}
loadData(callback, defaultProps = {}) {
if (this.store.lazy === true && this.store.load && !this.loaded && (!this.loading || Object.keys(defaultProps).length)) {
this.loading = true;
const resolve = (children) => {
this.childNodes = [];
this.doCreateChildren(children, defaultProps);
this.loaded = true;
this.loading = false;
this.updateLeafState();
if (callback) {
callback.call(this, children);
}
};
const reject = () => {
this.loading = false;
};
this.store.load(this, resolve, reject);
} else {
if (callback) {
callback.call(this);
}
}
}
eachNode(callback) {
const arr = [this];
while (arr.length) {
const node = arr.shift();
arr.unshift(...node.childNodes);
callback(node);
}
}
reInitChecked() {
if (this.store.checkStrictly)
return;
reInitChecked(this);
}
}
exports["default"] = Node;
exports.getChildState = getChildState;
//# sourceMappingURL=node.js.map