import { INode as InnerNode, INodeChildren } from '@alilc/lowcode-designer'; import { IPublicTypeNodeData, IPublicEnumTransformStage, IPublicModelNodeChildren, IPublicModelNode } from '@alilc/lowcode-types'; import { Node as ShellNode } from './node'; import { nodeSymbol, nodeChildrenSymbol } from '../symbols'; export class NodeChildren implements IPublicModelNodeChildren { private readonly [nodeChildrenSymbol]: INodeChildren; constructor(nodeChildren: INodeChildren) { this[nodeChildrenSymbol] = nodeChildren; } static create(nodeChildren: INodeChildren | null): IPublicModelNodeChildren | null { if (!nodeChildren) { return null; } return new NodeChildren(nodeChildren); } /** * 返回当前 children 实例所属的节点实例 */ get owner(): IPublicModelNode | null { return ShellNode.create(this[nodeChildrenSymbol].owner); } /** * children 内的节点实例数 */ get size(): number { return this[nodeChildrenSymbol].size; } /** * @deprecated * 是否为空 * @returns */ get isEmpty(): boolean { return this[nodeChildrenSymbol].isEmptyNode; } /** * 是否为空 * @returns */ get isEmptyNode(): boolean { return this[nodeChildrenSymbol].isEmptyNode; } /** * @deprecated * judge if it is not empty */ get notEmpty(): boolean { return this[nodeChildrenSymbol].notEmptyNode; } /** * judge if it is not empty */ get notEmptyNode(): boolean { return this[nodeChildrenSymbol].notEmptyNode; } /** * 删除指定节点 * delete the node * @param node */ delete(node: IPublicModelNode): boolean { return this[nodeChildrenSymbol].delete((node as any)?.[nodeSymbol]); } /** * 插入一个节点 * @param node 待插入节点 * @param at 插入下标 * @returns */ insert(node: IPublicModelNode, at?: number | null): void { return this[nodeChildrenSymbol].insert((node as any)?.[nodeSymbol], at); } /** * 返回指定节点的下标 * @param node * @returns */ indexOf(node: IPublicModelNode): number { return this[nodeChildrenSymbol].indexOf((node as any)?.[nodeSymbol]); } /** * 类似数组 splice 操作 * @param start * @param deleteCount * @param node */ splice(start: number, deleteCount: number, node?: IPublicModelNode): any { this[nodeChildrenSymbol].splice(start, deleteCount, (node as any)?.[nodeSymbol]); } /** * 返回指定下标的节点 * @param index * @returns */ get(index: number): IPublicModelNode | null { return ShellNode.create(this[nodeChildrenSymbol].get(index)); } /** * 是否包含指定节点 * @param node * @returns */ has(node: IPublicModelNode): boolean { return this[nodeChildrenSymbol].has((node as any)?.[nodeSymbol]); } /** * 类似数组的 forEach * @param fn */ forEach(fn: (node: IPublicModelNode, index: number) => void): void { this[nodeChildrenSymbol].forEach((item: InnerNode, index: number) => { fn(ShellNode.create(item)!, index); }); } /** * 类似数组的 reverse */ reverse(): IPublicModelNode[] { return this[nodeChildrenSymbol].reverse().map(d => { return ShellNode.create(d)!; }); } /** * 类似数组的 map * @param fn */ map(fn: (node: IPublicModelNode, index: number) => T): T[] | null { return this[nodeChildrenSymbol].map((item: InnerNode, index: number): T => { return fn(ShellNode.create(item)!, index); }); } /** * 类似数组的 every * @param fn */ every(fn: (node: IPublicModelNode, index: number) => boolean): boolean { return this[nodeChildrenSymbol].every((item: InnerNode, index: number) => { return fn(ShellNode.create(item)!, index); }); } /** * 类似数组的 some * @param fn */ some(fn: (node: IPublicModelNode, index: number) => boolean): boolean { return this[nodeChildrenSymbol].some((item: InnerNode, index: number) => { return fn(ShellNode.create(item)!, index); }); } /** * 类似数组的 filter * @param fn */ filter(fn: (node: IPublicModelNode, index: number) => boolean): any { return this[nodeChildrenSymbol] .filter((item: InnerNode, index: number) => { return fn(ShellNode.create(item)!, index); }) .map((item: InnerNode) => ShellNode.create(item)!); } /** * 类似数组的 find * @param fn */ find(fn: (node: IPublicModelNode, index: number) => boolean): IPublicModelNode | null { return ShellNode.create( this[nodeChildrenSymbol].find((item: InnerNode, index: number) => { return fn(ShellNode.create(item)!, index); }), ); } /** * 类似数组的 reduce * @param fn */ reduce(fn: (acc: any, cur: IPublicModelNode) => any, initialValue: any): void { return this[nodeChildrenSymbol].reduce((acc: any, cur: InnerNode) => { return fn(acc, ShellNode.create(cur)!); }, initialValue); } /** * 导入 schema * @param data */ importSchema(data?: IPublicTypeNodeData | IPublicTypeNodeData[]): void { this[nodeChildrenSymbol].import(data); } /** * 导出 schema * @param stage * @returns */ exportSchema(stage: IPublicEnumTransformStage = IPublicEnumTransformStage.Render): any { return this[nodeChildrenSymbol].export(stage); } /** * 执行新增、删除、排序等操作 * @param remover * @param adder * @param sorter */ mergeChildren( remover: (node: IPublicModelNode, idx: number) => boolean, adder: (children: IPublicModelNode[]) => any, originalSorter: (firstNode: IPublicModelNode, secondNode: IPublicModelNode) => number, ) { let sorter = originalSorter; if (!sorter) { sorter = () => 0; } this[nodeChildrenSymbol].mergeChildren( (node: InnerNode, idx: number) => remover(ShellNode.create(node)!, idx), (children: InnerNode[]) => adder(children.map((node) => ShellNode.create(node)!)), (firstNode: InnerNode, secondNode: InnerNode) => { return sorter(ShellNode.create(firstNode)!, ShellNode.create(secondNode)!); }, ); } }