mirror of
https://github.com/alibaba/lowcode-engine.git
synced 2025-12-12 03:01:16 +00:00
feat: add getDOMNode api definition in node module
This commit is contained in:
parent
9228a2baa7
commit
964833128b
@ -645,3 +645,14 @@ setConditionalVisible(): void;
|
|||||||
```
|
```
|
||||||
|
|
||||||
**@since v1.1.0**
|
**@since v1.1.0**
|
||||||
|
|
||||||
|
### getDOMNode
|
||||||
|
获取节点实例对应的 dom 节点
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
/**
|
||||||
|
* 获取节点实例对应的 dom 节点
|
||||||
|
*/
|
||||||
|
getDOMNode(): HTMLElement;
|
||||||
|
|
||||||
|
```
|
||||||
@ -15,6 +15,7 @@ const jestConfig = {
|
|||||||
// testMatch: ['**/document-model.test.ts'],
|
// testMatch: ['**/document-model.test.ts'],
|
||||||
// testMatch: ['**/prop.test.ts'],
|
// testMatch: ['**/prop.test.ts'],
|
||||||
// testMatch: ['(/tests?/.*(test))\\.[jt]s$'],
|
// testMatch: ['(/tests?/.*(test))\\.[jt]s$'],
|
||||||
|
// testMatch: ['**/document/node/node.add.test.ts'],
|
||||||
transformIgnorePatterns: [
|
transformIgnorePatterns: [
|
||||||
`/node_modules/(?!${esModules})/`,
|
`/node_modules/(?!${esModules})/`,
|
||||||
],
|
],
|
||||||
|
|||||||
@ -71,6 +71,8 @@ export interface IDesigner {
|
|||||||
|
|
||||||
get editor(): IPublicModelEditor;
|
get editor(): IPublicModelEditor;
|
||||||
|
|
||||||
|
get detecting(): Detecting;
|
||||||
|
|
||||||
createScroller(scrollable: IPublicTypeScrollable): IPublicModelScroller;
|
createScroller(scrollable: IPublicTypeScrollable): IPublicModelScroller;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@ -17,6 +17,7 @@ function generateSessionId(nodes: INode[]) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export interface ISettingTopEntry extends ISettingEntry {
|
export interface ISettingTopEntry extends ISettingEntry {
|
||||||
|
purge(): void;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class SettingTopEntry implements ISettingTopEntry {
|
export class SettingTopEntry implements ISettingTopEntry {
|
||||||
|
|||||||
@ -87,6 +87,8 @@ export interface IDocumentModel extends Omit< IPublicModelDocumentModel<
|
|||||||
|
|
||||||
get active(): boolean;
|
get active(): boolean;
|
||||||
|
|
||||||
|
get nodesMap(): Map<string, INode>;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 根据 id 获取节点
|
* 根据 id 获取节点
|
||||||
*/
|
*/
|
||||||
@ -114,6 +116,12 @@ export interface IDocumentModel extends Omit< IPublicModelDocumentModel<
|
|||||||
onChangeNodeVisible(fn: (node: INode, visible: boolean) => void): IPublicTypeDisposable;
|
onChangeNodeVisible(fn: (node: INode, visible: boolean) => void): IPublicTypeDisposable;
|
||||||
|
|
||||||
addWillPurge(node: INode): void;
|
addWillPurge(node: INode): void;
|
||||||
|
|
||||||
|
removeWillPurge(node: INode): void;
|
||||||
|
|
||||||
|
getComponentMeta(componentName: string): IComponentMeta;
|
||||||
|
|
||||||
|
insertNodes(parent: INode, thing: INode[] | IPublicTypeNodeData[], at?: number | null, copy?: boolean): INode[];
|
||||||
}
|
}
|
||||||
|
|
||||||
export class DocumentModel implements IDocumentModel {
|
export class DocumentModel implements IDocumentModel {
|
||||||
@ -379,7 +387,7 @@ export class DocumentModel implements IDocumentModel {
|
|||||||
* 根据 schema 创建一个节点
|
* 根据 schema 创建一个节点
|
||||||
*/
|
*/
|
||||||
@action
|
@action
|
||||||
createNode<T extends INode = INode, C = undefined>(data: GetDataType<C, T>, checkId: boolean = true): T {
|
createNode<T extends INode = INode, C = undefined>(data: GetDataType<C, T>): T {
|
||||||
let schema: any;
|
let schema: any;
|
||||||
if (isDOMText(data) || isJSExpression(data)) {
|
if (isDOMText(data) || isJSExpression(data)) {
|
||||||
schema = {
|
schema = {
|
||||||
@ -410,7 +418,7 @@ export class DocumentModel implements IDocumentModel {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!node) {
|
if (!node) {
|
||||||
node = new Node(this, schema, { checkId });
|
node = new Node(this, schema);
|
||||||
// will add
|
// will add
|
||||||
// todo: this.activeNodes?.push(node);
|
// todo: this.activeNodes?.push(node);
|
||||||
}
|
}
|
||||||
@ -429,7 +437,7 @@ export class DocumentModel implements IDocumentModel {
|
|||||||
/**
|
/**
|
||||||
* 插入一个节点
|
* 插入一个节点
|
||||||
*/
|
*/
|
||||||
insertNode(parent: INode, thing: INode | IPublicTypeNodeData, at?: number | null, copy?: boolean): INode {
|
insertNode(parent: INode, thing: INode | IPublicTypeNodeData, at?: number | null, copy?: boolean): INode | null {
|
||||||
return insertChild(parent, thing, at, copy);
|
return insertChild(parent, thing, at, copy);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -445,7 +453,7 @@ export class DocumentModel implements IDocumentModel {
|
|||||||
*/
|
*/
|
||||||
removeNode(idOrNode: string | INode) {
|
removeNode(idOrNode: string | INode) {
|
||||||
let id: string;
|
let id: string;
|
||||||
let node: INode | null;
|
let node: INode | null = null;
|
||||||
if (typeof idOrNode === 'string') {
|
if (typeof idOrNode === 'string') {
|
||||||
id = idOrNode;
|
id = idOrNode;
|
||||||
node = this.getNode(id);
|
node = this.getNode(id);
|
||||||
@ -859,7 +867,7 @@ export class DocumentModel implements IDocumentModel {
|
|||||||
onReady(fn: Function) {
|
onReady(fn: Function) {
|
||||||
this.designer.editor.eventBus.on('document-open', fn);
|
this.designer.editor.eventBus.on('document-open', fn);
|
||||||
return () => {
|
return () => {
|
||||||
this.designer.editor.removeListener('document-open', fn);
|
this.designer.editor.eventBus.off('document-open', fn);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,18 +1,30 @@
|
|||||||
import { obx, computed, makeObservable } from '@alilc/lowcode-editor-core';
|
import { obx, computed, makeObservable } from '@alilc/lowcode-editor-core';
|
||||||
import { uniqueId } from '@alilc/lowcode-utils';
|
import { uniqueId } from '@alilc/lowcode-utils';
|
||||||
import { IPublicTypeTitleContent, IPublicModelExclusiveGroup } from '@alilc/lowcode-types';
|
import { IPublicTypeTitleContent, IPublicModelExclusiveGroup } from '@alilc/lowcode-types';
|
||||||
import { Node } from './node';
|
import { INode } from './node';
|
||||||
import { intl } from '../../locale';
|
import { intl } from '../../locale';
|
||||||
|
|
||||||
|
export interface IExclusiveGroup extends IPublicModelExclusiveGroup<INode> {
|
||||||
|
readonly name: string;
|
||||||
|
|
||||||
|
remove(node: INode): void;
|
||||||
|
|
||||||
|
add(node: INode): void;
|
||||||
|
|
||||||
|
isVisible(node: INode): boolean;
|
||||||
|
}
|
||||||
|
|
||||||
// modals assoc x-hide value, initial: check is Modal, yes will put it in modals, cross levels
|
// modals assoc x-hide value, initial: check is Modal, yes will put it in modals, cross levels
|
||||||
// if-else-if assoc conditionGroup value, should be the same level,
|
// if-else-if assoc conditionGroup value, should be the same level,
|
||||||
// and siblings, need renderEngine support
|
// and siblings, need renderEngine support
|
||||||
export class ExclusiveGroup implements IPublicModelExclusiveGroup {
|
export class ExclusiveGroup implements IExclusiveGroup {
|
||||||
readonly isExclusiveGroup = true;
|
readonly isExclusiveGroup = true;
|
||||||
|
|
||||||
readonly id = uniqueId('exclusive');
|
readonly id = uniqueId('exclusive');
|
||||||
|
|
||||||
@obx.shallow readonly children: Node[] = [];
|
readonly title: IPublicTypeTitleContent;
|
||||||
|
|
||||||
|
@obx.shallow readonly children: INode[] = [];
|
||||||
|
|
||||||
@obx private visibleIndex = 0;
|
@obx private visibleIndex = 0;
|
||||||
|
|
||||||
@ -28,11 +40,11 @@ export class ExclusiveGroup implements IPublicModelExclusiveGroup {
|
|||||||
return this.children.length;
|
return this.children.length;
|
||||||
}
|
}
|
||||||
|
|
||||||
@computed get visibleNode(): Node {
|
@computed get visibleNode(): INode {
|
||||||
return this.children[this.visibleIndex];
|
return this.children[this.visibleIndex];
|
||||||
}
|
}
|
||||||
|
|
||||||
@computed get firstNode(): Node {
|
@computed get firstNode(): INode {
|
||||||
return this.children[0]!;
|
return this.children[0]!;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -40,8 +52,16 @@ export class ExclusiveGroup implements IPublicModelExclusiveGroup {
|
|||||||
return this.firstNode.index;
|
return this.firstNode.index;
|
||||||
}
|
}
|
||||||
|
|
||||||
add(node: Node) {
|
constructor(readonly name: string, title?: IPublicTypeTitleContent) {
|
||||||
if (node.nextSibling && node.nextSibling.conditionGroup === this) {
|
makeObservable(this);
|
||||||
|
this.title = title || {
|
||||||
|
type: 'i18n',
|
||||||
|
intl: intl('Condition Group'),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
add(node: INode) {
|
||||||
|
if (node.nextSibling && node.nextSibling.conditionGroup?.id === this.id) {
|
||||||
const i = this.children.indexOf(node.nextSibling);
|
const i = this.children.indexOf(node.nextSibling);
|
||||||
this.children.splice(i, 0, node);
|
this.children.splice(i, 0, node);
|
||||||
} else {
|
} else {
|
||||||
@ -49,7 +69,7 @@ export class ExclusiveGroup implements IPublicModelExclusiveGroup {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
remove(node: Node) {
|
remove(node: INode) {
|
||||||
const i = this.children.indexOf(node);
|
const i = this.children.indexOf(node);
|
||||||
if (i > -1) {
|
if (i > -1) {
|
||||||
this.children.splice(i, 1);
|
this.children.splice(i, 1);
|
||||||
@ -61,27 +81,17 @@ export class ExclusiveGroup implements IPublicModelExclusiveGroup {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
setVisible(node: Node) {
|
setVisible(node: INode) {
|
||||||
const i = this.children.indexOf(node);
|
const i = this.children.indexOf(node);
|
||||||
if (i > -1) {
|
if (i > -1) {
|
||||||
this.visibleIndex = i;
|
this.visibleIndex = i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
isVisible(node: Node) {
|
isVisible(node: INode) {
|
||||||
const i = this.children.indexOf(node);
|
const i = this.children.indexOf(node);
|
||||||
return i === this.visibleIndex;
|
return i === this.visibleIndex;
|
||||||
}
|
}
|
||||||
|
|
||||||
readonly title: IPublicTypeTitleContent;
|
|
||||||
|
|
||||||
constructor(readonly name: string, title?: IPublicTypeTitleContent) {
|
|
||||||
makeObservable(this);
|
|
||||||
this.title = title || {
|
|
||||||
type: 'i18n',
|
|
||||||
intl: intl('Condition Group'),
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export function isExclusiveGroup(obj: any): obj is ExclusiveGroup {
|
export function isExclusiveGroup(obj: any): obj is ExclusiveGroup {
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
import { obx, computed, globalContext, makeObservable, IEventBus, createModuleEventBus } from '@alilc/lowcode-editor-core';
|
import { obx, computed, globalContext, makeObservable, IEventBus, createModuleEventBus } from '@alilc/lowcode-editor-core';
|
||||||
import { Node, INode } from './node';
|
import { Node, INode } from './node';
|
||||||
import { IPublicTypeNodeData, IPublicModelNodeChildren, IPublicEnumTransformStage } from '@alilc/lowcode-types';
|
import { IPublicTypeNodeData, IPublicModelNodeChildren, IPublicEnumTransformStage, IPublicTypeDisposable } from '@alilc/lowcode-types';
|
||||||
import { shallowEqual, compatStage, isNodeSchema } from '@alilc/lowcode-utils';
|
import { shallowEqual, compatStage, isNodeSchema } from '@alilc/lowcode-utils';
|
||||||
import { foreachReverse } from '../../utils/tree';
|
import { foreachReverse } from '../../utils/tree';
|
||||||
import { NodeRemoveOptions } from '../../types';
|
import { NodeRemoveOptions } from '../../types';
|
||||||
@ -18,6 +18,8 @@ export interface INodeChildren extends Omit<IPublicModelNodeChildren<INode>,
|
|||||||
> {
|
> {
|
||||||
get owner(): INode;
|
get owner(): INode;
|
||||||
|
|
||||||
|
get length(): number;
|
||||||
|
|
||||||
unlinkChild(node: INode): void;
|
unlinkChild(node: INode): void;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -58,6 +60,8 @@ export interface INodeChildren extends Omit<IPublicModelNodeChildren<INode>,
|
|||||||
|
|
||||||
internalInitParent(): void;
|
internalInitParent(): void;
|
||||||
|
|
||||||
|
onChange(fn: (info?: IOnChangeOptions) => void): IPublicTypeDisposable;
|
||||||
|
|
||||||
/** overriding methods end */
|
/** overriding methods end */
|
||||||
}
|
}
|
||||||
export class NodeChildren implements INodeChildren {
|
export class NodeChildren implements INodeChildren {
|
||||||
@ -478,7 +482,7 @@ export class NodeChildren implements INodeChildren {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
onChange(fn: (info?: IOnChangeOptions) => void): () => void {
|
onChange(fn: (info?: IOnChangeOptions) => void): IPublicTypeDisposable {
|
||||||
this.emitter.on('change', fn);
|
this.emitter.on('change', fn);
|
||||||
return () => {
|
return () => {
|
||||||
this.emitter.removeListener('change', fn);
|
this.emitter.removeListener('change', fn);
|
||||||
|
|||||||
@ -18,14 +18,14 @@ import {
|
|||||||
IPublicTypeDisposable,
|
IPublicTypeDisposable,
|
||||||
IBaseModelNode,
|
IBaseModelNode,
|
||||||
} from '@alilc/lowcode-types';
|
} from '@alilc/lowcode-types';
|
||||||
import { compatStage, isDOMText, isJSExpression, isNode } from '@alilc/lowcode-utils';
|
import { compatStage, isDOMText, isJSExpression, isNode, isNodeSchema } from '@alilc/lowcode-utils';
|
||||||
import { ISettingTopEntry, SettingTopEntry } from '@alilc/lowcode-designer';
|
import { ISettingTopEntry } from '@alilc/lowcode-designer';
|
||||||
import { Props, getConvertedExtraKey, IProps } from './props/props';
|
import { Props, getConvertedExtraKey, IProps } from './props/props';
|
||||||
import { DocumentModel, IDocumentModel } from '../document-model';
|
import { IDocumentModel } from '../document-model';
|
||||||
import { NodeChildren, INodeChildren } from './node-children';
|
import { NodeChildren, INodeChildren } from './node-children';
|
||||||
import { IProp, Prop } from './props/prop';
|
import { IProp, Prop } from './props/prop';
|
||||||
import { ComponentMeta, IComponentMeta } from '../../component-meta';
|
import { IComponentMeta } from '../../component-meta';
|
||||||
import { ExclusiveGroup, isExclusiveGroup } from './exclusive-group';
|
import { ExclusiveGroup, IExclusiveGroup, isExclusiveGroup } from './exclusive-group';
|
||||||
import { includeSlot, removeSlot } from '../../utils/slot';
|
import { includeSlot, removeSlot } from '../../utils/slot';
|
||||||
import { foreachReverse } from '../../utils/tree';
|
import { foreachReverse } from '../../utils/tree';
|
||||||
import { NodeRemoveOptions, EDITOR_EVENT } from '../../types';
|
import { NodeRemoveOptions, EDITOR_EVENT } from '../../types';
|
||||||
@ -42,14 +42,11 @@ export interface INode extends Omit<IBaseModelNode<
|
|||||||
INode,
|
INode,
|
||||||
INodeChildren,
|
INodeChildren,
|
||||||
IComponentMeta,
|
IComponentMeta,
|
||||||
ISettingTopEntry
|
ISettingTopEntry,
|
||||||
|
IProps,
|
||||||
|
IProp,
|
||||||
|
IExclusiveGroup
|
||||||
>,
|
>,
|
||||||
'slots' |
|
|
||||||
'slotFor' |
|
|
||||||
'props' |
|
|
||||||
'getProp' |
|
|
||||||
'getExtraProp' |
|
|
||||||
'replaceChild' |
|
|
||||||
'isRoot' |
|
'isRoot' |
|
||||||
'isPage' |
|
'isPage' |
|
||||||
'isComponent' |
|
'isComponent' |
|
||||||
@ -64,29 +61,21 @@ export interface INode extends Omit<IBaseModelNode<
|
|||||||
'exportSchema' |
|
'exportSchema' |
|
||||||
'visible' |
|
'visible' |
|
||||||
'importSchema' |
|
'importSchema' |
|
||||||
'isEmptyNode' |
|
|
||||||
// 内外实现有差异
|
// 内外实现有差异
|
||||||
'isContainer' |
|
'isContainer' |
|
||||||
'isEmpty'
|
'isEmpty'
|
||||||
> {
|
> {
|
||||||
get slots(): INode[];
|
isNode: boolean;
|
||||||
|
|
||||||
/**
|
|
||||||
* 关联属性
|
|
||||||
*/
|
|
||||||
get slotFor(): IProp | null;
|
|
||||||
|
|
||||||
get props(): IProps;
|
|
||||||
|
|
||||||
get componentMeta(): IComponentMeta;
|
get componentMeta(): IComponentMeta;
|
||||||
|
|
||||||
get settingEntry(): SettingTopEntry;
|
get settingEntry(): ISettingTopEntry;
|
||||||
|
|
||||||
get isPurged(): boolean;
|
get isPurged(): boolean;
|
||||||
|
|
||||||
setVisible(flag: boolean): void;
|
get index(): number | undefined;
|
||||||
|
|
||||||
getVisible(): boolean;
|
get isPurging(): boolean;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 内部方法,请勿使用
|
* 内部方法,请勿使用
|
||||||
@ -100,7 +89,7 @@ export interface INode extends Omit<IBaseModelNode<
|
|||||||
|
|
||||||
internalPurgeStart(): void;
|
internalPurgeStart(): void;
|
||||||
|
|
||||||
unlinkSlot(slotNode: Node): void;
|
unlinkSlot(slotNode: INode): void;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 导出 schema
|
* 导出 schema
|
||||||
@ -117,15 +106,9 @@ export interface INode extends Omit<IBaseModelNode<
|
|||||||
|
|
||||||
onVisibleChange(func: (flag: boolean) => any): () => void;
|
onVisibleChange(func: (flag: boolean) => any): () => void;
|
||||||
|
|
||||||
getProp(path: string, createIfNone?: boolean): IProp | null;
|
|
||||||
|
|
||||||
getExtraProp(key: string, createIfNone?: boolean): IProp | null;
|
|
||||||
|
|
||||||
replaceChild(node: INode, data: any): INode;
|
|
||||||
|
|
||||||
getSuitablePlace(node: INode, ref: any): any;
|
getSuitablePlace(node: INode, ref: any): any;
|
||||||
|
|
||||||
onChildrenChange(fn: (param?: { type: string; node: INode }) => void): IPublicTypeDisposable;
|
onChildrenChange(fn: (param?: { type: string; node: INode }) => void): IPublicTypeDisposable | undefined;
|
||||||
|
|
||||||
onPropChange(func: (info: IPublicTypePropChangeOptions) => void): IPublicTypeDisposable;
|
onPropChange(func: (info: IPublicTypePropChangeOptions) => void): IPublicTypeDisposable;
|
||||||
|
|
||||||
@ -153,13 +136,17 @@ export interface INode extends Omit<IBaseModelNode<
|
|||||||
options?: NodeRemoveOptions,
|
options?: NodeRemoveOptions,
|
||||||
): void;
|
): void;
|
||||||
|
|
||||||
didDropIn(dragment: Node): void;
|
didDropIn(dragment: INode): void;
|
||||||
|
|
||||||
didDropOut(dragment: Node): void;
|
didDropOut(dragment: INode): void;
|
||||||
|
|
||||||
get isPurging(): boolean;
|
|
||||||
|
|
||||||
purge(): void;
|
purge(): void;
|
||||||
|
|
||||||
|
removeSlot(slotNode: INode): boolean;
|
||||||
|
|
||||||
|
setVisible(flag: boolean): void;
|
||||||
|
|
||||||
|
getVisible(): boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -322,7 +309,11 @@ export class Node<Schema extends IPublicTypeNodeSchema = IPublicTypeNodeSchema>
|
|||||||
return !!this._isRGLContainer;
|
return !!this._isRGLContainer;
|
||||||
}
|
}
|
||||||
|
|
||||||
private _slotFor?: IProp | null = null;
|
get isEmptyNode() {
|
||||||
|
return this.isEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
|
private _slotFor?: IProp | null | undefined = null;
|
||||||
|
|
||||||
@obx.shallow _slots: INode[] = [];
|
@obx.shallow _slots: INode[] = [];
|
||||||
|
|
||||||
@ -331,10 +322,10 @@ export class Node<Schema extends IPublicTypeNodeSchema = IPublicTypeNodeSchema>
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* istanbul ignore next */
|
/* istanbul ignore next */
|
||||||
@obx.ref private _conditionGroup: IPublicModelExclusiveGroup | null = null;
|
@obx.ref private _conditionGroup: IExclusiveGroup | null = null;
|
||||||
|
|
||||||
/* istanbul ignore next */
|
/* istanbul ignore next */
|
||||||
get conditionGroup(): IPublicModelExclusiveGroup | null {
|
get conditionGroup(): IExclusiveGroup | null {
|
||||||
return this._conditionGroup;
|
return this._conditionGroup;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -518,7 +509,7 @@ export class Node<Schema extends IPublicTypeNodeSchema = IPublicTypeNodeSchema>
|
|||||||
this.document.addWillPurge(this);
|
this.document.addWillPurge(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
didDropIn(dragment: Node) {
|
didDropIn(dragment: INode) {
|
||||||
const { callbacks } = this.componentMeta.advanced;
|
const { callbacks } = this.componentMeta.advanced;
|
||||||
if (callbacks?.onNodeAdd) {
|
if (callbacks?.onNodeAdd) {
|
||||||
const cbThis = this.internalToShellNode();
|
const cbThis = this.internalToShellNode();
|
||||||
@ -529,7 +520,7 @@ export class Node<Schema extends IPublicTypeNodeSchema = IPublicTypeNodeSchema>
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
didDropOut(dragment: Node) {
|
didDropOut(dragment: INode) {
|
||||||
const { callbacks } = this.componentMeta.advanced;
|
const { callbacks } = this.componentMeta.advanced;
|
||||||
if (callbacks?.onNodeRemove) {
|
if (callbacks?.onNodeRemove) {
|
||||||
const cbThis = this.internalToShellNode();
|
const cbThis = this.internalToShellNode();
|
||||||
@ -590,7 +581,7 @@ export class Node<Schema extends IPublicTypeNodeSchema = IPublicTypeNodeSchema>
|
|||||||
/**
|
/**
|
||||||
* 关联属性
|
* 关联属性
|
||||||
*/
|
*/
|
||||||
get slotFor(): IProp | null {
|
get slotFor(): IProp | null | undefined {
|
||||||
return this._slotFor;
|
return this._slotFor;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -610,10 +601,10 @@ export class Node<Schema extends IPublicTypeNodeSchema = IPublicTypeNodeSchema>
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
if (this.isSlot()) {
|
if (this.isSlot()) {
|
||||||
this.parent.removeSlot(this, purge);
|
this.parent.removeSlot(this);
|
||||||
this.parent.children.internalDelete(this, purge, useMutator, { suppressRemoveEvent: true });
|
this.parent.children?.internalDelete(this, purge, useMutator, { suppressRemoveEvent: true });
|
||||||
} else {
|
} else {
|
||||||
this.parent.children.internalDelete(this, purge, useMutator, { suppressRemoveEvent: true });
|
this.parent.children?.internalDelete(this, purge, useMutator, { suppressRemoveEvent: true });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -653,7 +644,7 @@ export class Node<Schema extends IPublicTypeNodeSchema = IPublicTypeNodeSchema>
|
|||||||
/**
|
/**
|
||||||
* 节点组件描述
|
* 节点组件描述
|
||||||
*/
|
*/
|
||||||
@computed get componentMeta(): ComponentMeta {
|
@computed get componentMeta(): IComponentMeta {
|
||||||
return this.document.getComponentMeta(this.componentName);
|
return this.document.getComponentMeta(this.componentName);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -670,6 +661,7 @@ export class Node<Schema extends IPublicTypeNodeSchema = IPublicTypeNodeSchema>
|
|||||||
|
|
||||||
/* istanbul ignore next */
|
/* istanbul ignore next */
|
||||||
setConditionGroup(grp: IPublicModelExclusiveGroup | string | null) {
|
setConditionGroup(grp: IPublicModelExclusiveGroup | string | null) {
|
||||||
|
let _grp: IExclusiveGroup | null = null;
|
||||||
if (!grp) {
|
if (!grp) {
|
||||||
this.getExtraProp('conditionGroup', false)?.remove();
|
this.getExtraProp('conditionGroup', false)?.remove();
|
||||||
if (this._conditionGroup) {
|
if (this._conditionGroup) {
|
||||||
@ -680,20 +672,20 @@ export class Node<Schema extends IPublicTypeNodeSchema = IPublicTypeNodeSchema>
|
|||||||
}
|
}
|
||||||
if (!isExclusiveGroup(grp)) {
|
if (!isExclusiveGroup(grp)) {
|
||||||
if (this.prevSibling?.conditionGroup?.name === grp) {
|
if (this.prevSibling?.conditionGroup?.name === grp) {
|
||||||
grp = this.prevSibling.conditionGroup;
|
_grp = this.prevSibling.conditionGroup;
|
||||||
} else if (this.nextSibling?.conditionGroup?.name === grp) {
|
} else if (this.nextSibling?.conditionGroup?.name === grp) {
|
||||||
grp = this.nextSibling.conditionGroup;
|
_grp = this.nextSibling.conditionGroup;
|
||||||
} else {
|
} else if (typeof grp === 'string') {
|
||||||
grp = new ExclusiveGroup(grp);
|
_grp = new ExclusiveGroup(grp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (this._conditionGroup !== grp) {
|
if (_grp && this._conditionGroup !== _grp) {
|
||||||
this.getExtraProp('conditionGroup', true)?.setValue(grp.name);
|
this.getExtraProp('conditionGroup', true)?.setValue(_grp.name);
|
||||||
if (this._conditionGroup) {
|
if (this._conditionGroup) {
|
||||||
this._conditionGroup.remove(this);
|
this._conditionGroup.remove(this);
|
||||||
}
|
}
|
||||||
this._conditionGroup = grp;
|
this._conditionGroup = _grp;
|
||||||
grp.add(this);
|
_grp?.add(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -749,13 +741,17 @@ export class Node<Schema extends IPublicTypeNodeSchema = IPublicTypeNodeSchema>
|
|||||||
* @param {INode} node
|
* @param {INode} node
|
||||||
* @param {object} data
|
* @param {object} data
|
||||||
*/
|
*/
|
||||||
replaceChild(node: INode, data: any): INode {
|
replaceChild(node: INode, data: any): INode | null {
|
||||||
if (this.children?.has(node)) {
|
if (this.children?.has(node)) {
|
||||||
const selected = this.document.selection.has(node.id);
|
const selected = this.document.selection.has(node.id);
|
||||||
|
|
||||||
delete data.id;
|
delete data.id;
|
||||||
const newNode = this.document.createNode(data);
|
const newNode = this.document.createNode(data);
|
||||||
|
|
||||||
|
if (!isNode(newNode)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
this.insertBefore(newNode, node, false);
|
this.insertBefore(newNode, node, false);
|
||||||
node.remove(false);
|
node.remove(false);
|
||||||
|
|
||||||
@ -838,39 +834,45 @@ export class Node<Schema extends IPublicTypeNodeSchema = IPublicTypeNodeSchema>
|
|||||||
/**
|
/**
|
||||||
* 获取节点在父容器中的索引
|
* 获取节点在父容器中的索引
|
||||||
*/
|
*/
|
||||||
@computed get index(): number {
|
@computed get index(): number | undefined {
|
||||||
if (!this.parent) {
|
if (!this.parent) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
return this.parent.children.indexOf(this);
|
return this.parent.children?.indexOf(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取下一个兄弟节点
|
* 获取下一个兄弟节点
|
||||||
*/
|
*/
|
||||||
get nextSibling(): INode | null {
|
get nextSibling(): INode | null | undefined {
|
||||||
if (!this.parent) {
|
if (!this.parent) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
const { index } = this;
|
const { index } = this;
|
||||||
|
if (typeof index !== 'number') {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
if (index < 0) {
|
if (index < 0) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
return this.parent.children.get(index + 1);
|
return this.parent.children?.get(index + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取上一个兄弟节点
|
* 获取上一个兄弟节点
|
||||||
*/
|
*/
|
||||||
get prevSibling(): INode | null {
|
get prevSibling(): INode | null | undefined {
|
||||||
if (!this.parent) {
|
if (!this.parent) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
const { index } = this;
|
const { index } = this;
|
||||||
|
if (typeof index !== 'number') {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
if (index < 1) {
|
if (index < 1) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
return this.parent.children.get(index - 1);
|
return this.parent.children?.get(index - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -889,7 +891,7 @@ export class Node<Schema extends IPublicTypeNodeSchema = IPublicTypeNodeSchema>
|
|||||||
if (this.isSlot()) {
|
if (this.isSlot()) {
|
||||||
foreachReverse(
|
foreachReverse(
|
||||||
this.children!,
|
this.children!,
|
||||||
(subNode: Node) => {
|
(subNode: INode) => {
|
||||||
subNode.remove(true, true);
|
subNode.remove(true, true);
|
||||||
},
|
},
|
||||||
(iterable, idx) => (iterable as NodeChildren).get(idx),
|
(iterable, idx) => (iterable as NodeChildren).get(idx),
|
||||||
@ -954,7 +956,7 @@ export class Node<Schema extends IPublicTypeNodeSchema = IPublicTypeNodeSchema>
|
|||||||
...this.document.designer.transformProps(_extras_, this, stage),
|
...this.document.designer.transformProps(_extras_, this, stage),
|
||||||
};
|
};
|
||||||
|
|
||||||
if (this.isParental() && this.children.size > 0 && !options.bypassChildren) {
|
if (this.isParental() && this.children && this.children.size > 0 && !options.bypassChildren) {
|
||||||
schema.children = this.children.export(stage);
|
schema.children = this.children.export(stage);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -971,7 +973,7 @@ export class Node<Schema extends IPublicTypeNodeSchema = IPublicTypeNodeSchema>
|
|||||||
/**
|
/**
|
||||||
* 获取特定深度的父亲节点
|
* 获取特定深度的父亲节点
|
||||||
*/
|
*/
|
||||||
getZLevelTop(zLevel: number): Node | null {
|
getZLevelTop(zLevel: number): INode | null {
|
||||||
return getZLevelTop(this, zLevel);
|
return getZLevelTop(this, zLevel);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -983,11 +985,11 @@ export class Node<Schema extends IPublicTypeNodeSchema = IPublicTypeNodeSchema>
|
|||||||
* 2 thisNode before or after otherNode
|
* 2 thisNode before or after otherNode
|
||||||
* 0 thisNode same as otherNode
|
* 0 thisNode same as otherNode
|
||||||
*/
|
*/
|
||||||
comparePosition(otherNode: Node): PositionNO {
|
comparePosition(otherNode: INode): PositionNO {
|
||||||
return comparePosition(this, otherNode);
|
return comparePosition(this, otherNode);
|
||||||
}
|
}
|
||||||
|
|
||||||
unlinkSlot(slotNode: Node) {
|
unlinkSlot(slotNode: INode) {
|
||||||
const i = this._slots.indexOf(slotNode);
|
const i = this._slots.indexOf(slotNode);
|
||||||
if (i < 0) {
|
if (i < 0) {
|
||||||
return false;
|
return false;
|
||||||
@ -998,7 +1000,7 @@ export class Node<Schema extends IPublicTypeNodeSchema = IPublicTypeNodeSchema>
|
|||||||
/**
|
/**
|
||||||
* 删除一个Slot节点
|
* 删除一个Slot节点
|
||||||
*/
|
*/
|
||||||
removeSlot(slotNode: Node): boolean {
|
removeSlot(slotNode: INode): boolean {
|
||||||
// if (purge) {
|
// if (purge) {
|
||||||
// // should set parent null
|
// // should set parent null
|
||||||
// slotNode?.internalSetParent(null, false);
|
// slotNode?.internalSetParent(null, false);
|
||||||
@ -1039,7 +1041,7 @@ export class Node<Schema extends IPublicTypeNodeSchema = IPublicTypeNodeSchema>
|
|||||||
* 删除一个节点
|
* 删除一个节点
|
||||||
* @param node
|
* @param node
|
||||||
*/
|
*/
|
||||||
removeChild(node: Node) {
|
removeChild(node: INode) {
|
||||||
this.children?.delete(node);
|
this.children?.delete(node);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1090,7 +1092,7 @@ export class Node<Schema extends IPublicTypeNodeSchema = IPublicTypeNodeSchema>
|
|||||||
return this.componentName;
|
return this.componentName;
|
||||||
}
|
}
|
||||||
|
|
||||||
insert(node: Node, ref?: INode, useMutator = true) {
|
insert(node: INode, ref?: INode, useMutator = true) {
|
||||||
this.insertAfter(node, ref, useMutator);
|
this.insertAfter(node, ref, useMutator);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1101,7 +1103,7 @@ export class Node<Schema extends IPublicTypeNodeSchema = IPublicTypeNodeSchema>
|
|||||||
|
|
||||||
insertAfter(node: any, ref?: INode, useMutator = true) {
|
insertAfter(node: any, ref?: INode, useMutator = true) {
|
||||||
const nodeInstance = ensureNode(node, this.document);
|
const nodeInstance = ensureNode(node, this.document);
|
||||||
this.children?.internalInsert(nodeInstance, ref ? ref.index + 1 : null, useMutator);
|
this.children?.internalInsert(nodeInstance, ref ? (ref.index || 0) + 1 : null, useMutator);
|
||||||
}
|
}
|
||||||
|
|
||||||
getParent() {
|
getParent() {
|
||||||
@ -1128,7 +1130,7 @@ export class Node<Schema extends IPublicTypeNodeSchema = IPublicTypeNodeSchema>
|
|||||||
return this.props;
|
return this.props;
|
||||||
}
|
}
|
||||||
|
|
||||||
onChildrenChange(fn: (param?: { type: string; node: INode }) => void): IPublicTypeDisposable {
|
onChildrenChange(fn: (param?: { type: string; node: INode }) => void): IPublicTypeDisposable | undefined {
|
||||||
const wrappedFunc = wrapWithEventSwitch(fn);
|
const wrappedFunc = wrapWithEventSwitch(fn);
|
||||||
return this.children?.onChange(wrappedFunc);
|
return this.children?.onChange(wrappedFunc);
|
||||||
}
|
}
|
||||||
@ -1330,7 +1332,7 @@ export class Node<Schema extends IPublicTypeNodeSchema = IPublicTypeNodeSchema>
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function ensureNode(node: any, document: DocumentModel): Node {
|
function ensureNode(node: any, document: IDocumentModel): INode {
|
||||||
let nodeInstance = node;
|
let nodeInstance = node;
|
||||||
if (!isNode(node)) {
|
if (!isNode(node)) {
|
||||||
if (node.getComponentName) {
|
if (node.getComponentName) {
|
||||||
@ -1443,20 +1445,24 @@ export function insertChild(
|
|||||||
thing: INode | IPublicTypeNodeData,
|
thing: INode | IPublicTypeNodeData,
|
||||||
at?: number | null,
|
at?: number | null,
|
||||||
copy?: boolean,
|
copy?: boolean,
|
||||||
): INode {
|
): INode | null {
|
||||||
let node: INode;
|
let node: INode | null | RootNode | undefined;
|
||||||
if (isNode(thing) && (copy || thing.isSlot())) {
|
let nodeSchema: IPublicTypeNodeSchema;
|
||||||
thing = thing.export(IPublicEnumTransformStage.Clone);
|
if (isNode<INode>(thing) && (copy || thing.isSlot())) {
|
||||||
}
|
nodeSchema = thing.export(IPublicEnumTransformStage.Clone);
|
||||||
if (isNode(thing)) {
|
node = container.document?.createNode(nodeSchema);
|
||||||
|
} else if (isNode<INode>(thing)) {
|
||||||
node = thing;
|
node = thing;
|
||||||
} else {
|
} else if (isNodeSchema(thing)) {
|
||||||
node = container.document.createNode(thing);
|
node = container.document?.createNode(thing);
|
||||||
}
|
}
|
||||||
|
|
||||||
container.children.insert(node, at);
|
if (isNode<INode>(node)) {
|
||||||
|
container.children?.insert(node, at);
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
|
||||||
return node;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function insertChildren(
|
export function insertChildren(
|
||||||
|
|||||||
@ -11,14 +11,14 @@ export const UNSET = Symbol.for('unset');
|
|||||||
// eslint-disable-next-line no-redeclare
|
// eslint-disable-next-line no-redeclare
|
||||||
export type UNSET = typeof UNSET;
|
export type UNSET = typeof UNSET;
|
||||||
|
|
||||||
export interface IProp extends Omit<IPublicModelProp, 'exportSchema' | 'node' | 'slotNode' > {
|
export interface IProp extends Omit<IPublicModelProp<
|
||||||
|
INode
|
||||||
|
>, 'exportSchema' | 'node' > {
|
||||||
|
|
||||||
readonly props: IProps;
|
readonly props: IProps;
|
||||||
|
|
||||||
readonly owner: INode;
|
readonly owner: INode;
|
||||||
|
|
||||||
get slotNode(): INode | null;
|
|
||||||
|
|
||||||
delete(prop: Prop): void;
|
delete(prop: Prop): void;
|
||||||
|
|
||||||
export(stage: IPublicEnumTransformStage): IPublicTypeCompositeValue;
|
export(stage: IPublicEnumTransformStage): IPublicTypeCompositeValue;
|
||||||
@ -26,6 +26,10 @@ export interface IProp extends Omit<IPublicModelProp, 'exportSchema' | 'node' |
|
|||||||
getNode(): INode;
|
getNode(): INode;
|
||||||
|
|
||||||
getAsString(): string;
|
getAsString(): string;
|
||||||
|
|
||||||
|
unset(): void;
|
||||||
|
|
||||||
|
get value(): IPublicTypeCompositeValue | UNSET;
|
||||||
}
|
}
|
||||||
|
|
||||||
export type ValueTypes = 'unset' | 'literal' | 'map' | 'list' | 'expression' | 'slot';
|
export type ValueTypes = 'unset' | 'literal' | 'map' | 'list' | 'expression' | 'slot';
|
||||||
|
|||||||
@ -33,8 +33,6 @@ export interface IPropParent {
|
|||||||
get path(): string[];
|
get path(): string[];
|
||||||
|
|
||||||
delete(prop: Prop): void;
|
delete(prop: Prop): void;
|
||||||
|
|
||||||
query(path: string, createIfNone: boolean): Prop | null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface IProps extends Omit<IBaseModelProps<IProp>, | 'getExtraProp' | 'getExtraPropValue' | 'setExtraPropValue' | 'node'> {
|
export interface IProps extends Omit<IBaseModelProps<IProp>, | 'getExtraProp' | 'getExtraPropValue' | 'setExtraPropValue' | 'node'> {
|
||||||
@ -52,6 +50,12 @@ export interface IProps extends Omit<IBaseModelProps<IProp>, | 'getExtraProp' |
|
|||||||
};
|
};
|
||||||
|
|
||||||
merge(value: IPublicTypePropsMap, extras?: IPublicTypePropsMap): void;
|
merge(value: IPublicTypePropsMap, extras?: IPublicTypePropsMap): void;
|
||||||
|
|
||||||
|
purge(): void;
|
||||||
|
|
||||||
|
query(path: string, createIfNone: boolean): Prop | null;
|
||||||
|
|
||||||
|
import(value?: IPublicTypePropsMap | IPublicTypePropsList | null, extras?: ExtrasObject): void;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class Props implements IProps, IPropParent {
|
export class Props implements IProps, IPropParent {
|
||||||
|
|||||||
@ -23,7 +23,7 @@ describe('document-model 测试', () => {
|
|||||||
|
|
||||||
it('empty schema', () => {
|
it('empty schema', () => {
|
||||||
const doc = new DocumentModel(project);
|
const doc = new DocumentModel(project);
|
||||||
expect(doc.rootNode.id).toBe('root');
|
expect(doc.rootNode?.id).toBe('root');
|
||||||
expect(doc.currentRoot).toBe(doc.rootNode);
|
expect(doc.currentRoot).toBe(doc.rootNode);
|
||||||
expect(doc.root).toBe(doc.rootNode);
|
expect(doc.root).toBe(doc.rootNode);
|
||||||
expect(doc.modalNode).toBeUndefined();
|
expect(doc.modalNode).toBeUndefined();
|
||||||
|
|||||||
@ -1,8 +1,8 @@
|
|||||||
import set from 'lodash/set';
|
import set from 'lodash/set';
|
||||||
import cloneDeep from 'lodash/cloneDeep';
|
import cloneDeep from 'lodash/cloneDeep';
|
||||||
import '../../fixtures/window';
|
import '../../fixtures/window';
|
||||||
import { Project } from '../../../src/project/project';
|
import { Project, IProject } from '../../../src/project/project';
|
||||||
import { Node } from '../../../src/document/node/node';
|
import { Node, INode } from '../../../src/document/node/node';
|
||||||
import { Designer } from '../../../src/designer/designer';
|
import { Designer } from '../../../src/designer/designer';
|
||||||
import formSchema from '../../fixtures/schema/form';
|
import formSchema from '../../fixtures/schema/form';
|
||||||
import { getIdsFromSchema, getNodeFromSchemaById } from '../../utils';
|
import { getIdsFromSchema, getNodeFromSchemaById } from '../../utils';
|
||||||
@ -37,7 +37,7 @@ beforeAll(() => {
|
|||||||
|
|
||||||
describe('schema 生成节点模型测试', () => {
|
describe('schema 生成节点模型测试', () => {
|
||||||
describe('block ❌ | component ❌ | slot ❌', () => {
|
describe('block ❌ | component ❌ | slot ❌', () => {
|
||||||
let project: Project;
|
let project: IProject;
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
project = new Project(designer, {
|
project = new Project(designer, {
|
||||||
componentsTree: [
|
componentsTree: [
|
||||||
@ -52,12 +52,12 @@ describe('schema 生成节点模型测试', () => {
|
|||||||
it('基本的节点模型初始化,模型导出', () => {
|
it('基本的节点模型初始化,模型导出', () => {
|
||||||
expect(project).toBeTruthy();
|
expect(project).toBeTruthy();
|
||||||
const { currentDocument } = project;
|
const { currentDocument } = project;
|
||||||
const { nodesMap } = currentDocument;
|
const nodesMap = currentDocument?.nodesMap;
|
||||||
const ids = getIdsFromSchema(formSchema);
|
const ids = getIdsFromSchema(formSchema);
|
||||||
const expectedNodeCnt = ids.length;
|
const expectedNodeCnt = ids.length;
|
||||||
expect(nodesMap.size).toBe(expectedNodeCnt);
|
expect(nodesMap?.size).toBe(expectedNodeCnt);
|
||||||
ids.forEach(id => {
|
ids.forEach(id => {
|
||||||
expect(nodesMap.get(id).componentName).toBe(getNodeFromSchemaById(formSchema, id).componentName);
|
expect(nodesMap?.get(id)?.componentName).toBe(getNodeFromSchemaById(formSchema, id).componentName);
|
||||||
});
|
});
|
||||||
|
|
||||||
const pageNode = currentDocument?.getNode('page');
|
const pageNode = currentDocument?.getNode('page');
|
||||||
@ -76,18 +76,18 @@ describe('schema 生成节点模型测试', () => {
|
|||||||
it('基本的节点模型初始化,节点深度', () => {
|
it('基本的节点模型初始化,节点深度', () => {
|
||||||
expect(project).toBeTruthy();
|
expect(project).toBeTruthy();
|
||||||
const { currentDocument } = project;
|
const { currentDocument } = project;
|
||||||
const getNode = currentDocument.getNode.bind(currentDocument);
|
const getNode = currentDocument?.getNode.bind(currentDocument);
|
||||||
|
|
||||||
const pageNode = getNode('page');
|
const pageNode = getNode?.('page');
|
||||||
const rootHeaderNode = getNode('node_k1ow3cba');
|
const rootHeaderNode = getNode?.('node_k1ow3cba');
|
||||||
const rootContentNode = getNode('node_k1ow3cbb');
|
const rootContentNode = getNode?.('node_k1ow3cbb');
|
||||||
const rootFooterNode = getNode('node_k1ow3cbc');
|
const rootFooterNode = getNode?.('node_k1ow3cbc');
|
||||||
const formNode = getNode('form');
|
const formNode = getNode?.('form');
|
||||||
const cardNode = getNode('node_k1ow3cbj');
|
const cardNode = getNode?.('node_k1ow3cbj');
|
||||||
const cardContentNode = getNode('node_k1ow3cbk');
|
const cardContentNode = getNode?.('node_k1ow3cbk');
|
||||||
const columnsLayoutNode = getNode('node_k1ow3cbw');
|
const columnsLayoutNode = getNode?.('node_k1ow3cbw');
|
||||||
const columnNode = getNode('node_k1ow3cbx');
|
const columnNode = getNode?.('node_k1ow3cbx');
|
||||||
const textFieldNode = getNode('node_k1ow3cbz');
|
const textFieldNode = getNode?.('node_k1ow3cbz');
|
||||||
|
|
||||||
expect(pageNode?.zLevel).toBe(0);
|
expect(pageNode?.zLevel).toBe(0);
|
||||||
expect(rootHeaderNode?.zLevel).toBe(1);
|
expect(rootHeaderNode?.zLevel).toBe(1);
|
||||||
@ -131,7 +131,7 @@ describe('schema 生成节点模型测试', () => {
|
|||||||
const textFieldNode = getNode('node_k1ow3cbz');
|
const textFieldNode = getNode('node_k1ow3cbz');
|
||||||
|
|
||||||
expect(pageNode?.index).toBe(-1);
|
expect(pageNode?.index).toBe(-1);
|
||||||
expect(pageNode?.children.toString()).toBe('[object Array]');
|
expect(pageNode?.children?.toString()).toBe('[object Array]');
|
||||||
expect(pageNode?.children?.get(1)).toBe(rootContentNode);
|
expect(pageNode?.children?.get(1)).toBe(rootContentNode);
|
||||||
expect(pageNode?.getChildren()?.get(1)).toBe(rootContentNode);
|
expect(pageNode?.getChildren()?.get(1)).toBe(rootContentNode);
|
||||||
expect(pageNode?.getNode()).toBe(pageNode);
|
expect(pageNode?.getNode()).toBe(pageNode);
|
||||||
@ -162,20 +162,20 @@ describe('schema 生成节点模型测试', () => {
|
|||||||
it('基本的节点模型初始化,节点新建、删除等事件', () => {
|
it('基本的节点模型初始化,节点新建、删除等事件', () => {
|
||||||
expect(project).toBeTruthy();
|
expect(project).toBeTruthy();
|
||||||
const { currentDocument } = project;
|
const { currentDocument } = project;
|
||||||
const getNode = currentDocument.getNode.bind(currentDocument);
|
const getNode = currentDocument?.getNode.bind(currentDocument);
|
||||||
const createNode = currentDocument.createNode.bind(currentDocument);
|
const createNode = currentDocument?.createNode.bind(currentDocument);
|
||||||
|
|
||||||
const pageNode = getNode('page');
|
const pageNode = getNode?.('page');
|
||||||
const nodeCreateHandler = jest.fn();
|
const nodeCreateHandler = jest.fn();
|
||||||
const offCreate = currentDocument?.onNodeCreate(nodeCreateHandler);
|
const offCreate = currentDocument?.onNodeCreate(nodeCreateHandler);
|
||||||
|
|
||||||
const node = createNode({
|
const node = createNode?.({
|
||||||
componentName: 'TextInput',
|
componentName: 'TextInput',
|
||||||
props: {
|
props: {
|
||||||
propA: 'haha',
|
propA: 'haha',
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
currentDocument?.insertNode(pageNode, node);
|
pageNode && node && currentDocument?.insertNode(pageNode, node);
|
||||||
|
|
||||||
expect(nodeCreateHandler).toHaveBeenCalledTimes(1);
|
expect(nodeCreateHandler).toHaveBeenCalledTimes(1);
|
||||||
expect(nodeCreateHandler.mock.calls[0][0]).toBe(node);
|
expect(nodeCreateHandler.mock.calls[0][0]).toBe(node);
|
||||||
@ -184,7 +184,7 @@ describe('schema 生成节点模型测试', () => {
|
|||||||
|
|
||||||
const nodeDestroyHandler = jest.fn();
|
const nodeDestroyHandler = jest.fn();
|
||||||
const offDestroy = currentDocument?.onNodeDestroy(nodeDestroyHandler);
|
const offDestroy = currentDocument?.onNodeDestroy(nodeDestroyHandler);
|
||||||
node.remove();
|
node?.remove();
|
||||||
expect(nodeDestroyHandler).toHaveBeenCalledTimes(1);
|
expect(nodeDestroyHandler).toHaveBeenCalledTimes(1);
|
||||||
expect(nodeDestroyHandler.mock.calls[0][0]).toBe(node);
|
expect(nodeDestroyHandler.mock.calls[0][0]).toBe(node);
|
||||||
expect(nodeDestroyHandler.mock.calls[0][0].componentName).toBe('TextInput');
|
expect(nodeDestroyHandler.mock.calls[0][0].componentName).toBe('TextInput');
|
||||||
@ -290,9 +290,9 @@ describe('schema 生成节点模型测试', () => {
|
|||||||
expect(project).toBeTruthy();
|
expect(project).toBeTruthy();
|
||||||
const ids = getIdsFromSchema(formSchema);
|
const ids = getIdsFromSchema(formSchema);
|
||||||
const { currentDocument } = project;
|
const { currentDocument } = project;
|
||||||
const { nodesMap } = currentDocument;
|
const nodesMap = currentDocument?.nodesMap;
|
||||||
const formNode = nodesMap.get('form');
|
const formNode = nodesMap?.get('form');
|
||||||
currentDocument?.insertNode(formNode, {
|
formNode && currentDocument?.insertNode(formNode, {
|
||||||
componentName: 'TextInput',
|
componentName: 'TextInput',
|
||||||
id: 'nodeschema-id1',
|
id: 'nodeschema-id1',
|
||||||
props: {
|
props: {
|
||||||
@ -300,11 +300,11 @@ describe('schema 生成节点模型测试', () => {
|
|||||||
propB: 3,
|
propB: 3,
|
||||||
},
|
},
|
||||||
}, 0);
|
}, 0);
|
||||||
expect(nodesMap.size).toBe(ids.length + 1);
|
expect(nodesMap?.size).toBe(ids.length + 1);
|
||||||
expect(formNode.children.length).toBe(4);
|
expect(formNode?.children?.length).toBe(4);
|
||||||
const insertedNode = formNode.children.get(0);
|
const insertedNode = formNode?.children?.get(0);
|
||||||
expect(insertedNode.componentName).toBe('TextInput');
|
expect(insertedNode?.componentName).toBe('TextInput');
|
||||||
expect(insertedNode.propsData).toEqual({
|
expect(insertedNode?.propsData).toEqual({
|
||||||
propA: 'haha',
|
propA: 'haha',
|
||||||
propB: 3,
|
propB: 3,
|
||||||
});
|
});
|
||||||
@ -316,9 +316,9 @@ describe('schema 生成节点模型测试', () => {
|
|||||||
expect(project).toBeTruthy();
|
expect(project).toBeTruthy();
|
||||||
const ids = getIdsFromSchema(formSchema);
|
const ids = getIdsFromSchema(formSchema);
|
||||||
const { currentDocument } = project;
|
const { currentDocument } = project;
|
||||||
const { nodesMap } = currentDocument;
|
const nodesMap = currentDocument?.nodesMap;
|
||||||
const formNode = nodesMap.get('form');
|
const formNode = nodesMap?.get('form');
|
||||||
currentDocument?.insertNode(formNode, {
|
formNode && currentDocument?.insertNode(formNode, {
|
||||||
componentName: 'TextInput',
|
componentName: 'TextInput',
|
||||||
id: 'nodeschema-id1',
|
id: 'nodeschema-id1',
|
||||||
props: {
|
props: {
|
||||||
@ -326,11 +326,11 @@ describe('schema 生成节点模型测试', () => {
|
|||||||
propB: 3,
|
propB: 3,
|
||||||
},
|
},
|
||||||
}, 1);
|
}, 1);
|
||||||
expect(nodesMap.size).toBe(ids.length + 1);
|
expect(nodesMap?.size).toBe(ids.length + 1);
|
||||||
expect(formNode.children.length).toBe(4);
|
expect(formNode?.children?.length).toBe(4);
|
||||||
const insertedNode = formNode.children.get(1);
|
const insertedNode = formNode?.children?.get(1);
|
||||||
expect(insertedNode.componentName).toBe('TextInput');
|
expect(insertedNode?.componentName).toBe('TextInput');
|
||||||
expect(insertedNode.propsData).toEqual({
|
expect(insertedNode?.propsData).toEqual({
|
||||||
propA: 'haha',
|
propA: 'haha',
|
||||||
propB: 3,
|
propB: 3,
|
||||||
});
|
});
|
||||||
@ -342,8 +342,8 @@ describe('schema 生成节点模型测试', () => {
|
|||||||
expect(project).toBeTruthy();
|
expect(project).toBeTruthy();
|
||||||
const ids = getIdsFromSchema(formSchema);
|
const ids = getIdsFromSchema(formSchema);
|
||||||
const { currentDocument } = project;
|
const { currentDocument } = project;
|
||||||
const { nodesMap } = currentDocument;
|
const nodesMap = currentDocument?.nodesMap;
|
||||||
const formNode = nodesMap.get('form') as Node;
|
const formNode = nodesMap?.get('form') as INode;
|
||||||
currentDocument?.insertNode(formNode, {
|
currentDocument?.insertNode(formNode, {
|
||||||
componentName: 'ParentNode',
|
componentName: 'ParentNode',
|
||||||
props: {
|
props: {
|
||||||
@ -367,8 +367,8 @@ describe('schema 生成节点模型测试', () => {
|
|||||||
},
|
},
|
||||||
],
|
],
|
||||||
});
|
});
|
||||||
expect(nodesMap.size).toBe(ids.length + 3);
|
expect(nodesMap?.size).toBe(ids.length + 3);
|
||||||
expect(formNode.children.length).toBe(4);
|
expect(formNode.children?.length).toBe(4);
|
||||||
expect(formNode.children?.get(3)?.componentName).toBe('ParentNode');
|
expect(formNode.children?.get(3)?.componentName).toBe('ParentNode');
|
||||||
expect(formNode.children?.get(3)?.children?.get(0)?.componentName).toBe('SubNode');
|
expect(formNode.children?.get(3)?.children?.get(0)?.componentName).toBe('SubNode');
|
||||||
expect(formNode.children?.get(3)?.children?.get(1)?.componentName).toBe('SubNode2');
|
expect(formNode.children?.get(3)?.children?.get(1)?.componentName).toBe('SubNode2');
|
||||||
@ -378,9 +378,9 @@ describe('schema 生成节点模型测试', () => {
|
|||||||
expect(project).toBeTruthy();
|
expect(project).toBeTruthy();
|
||||||
const ids = getIdsFromSchema(formSchema);
|
const ids = getIdsFromSchema(formSchema);
|
||||||
const { currentDocument } = project;
|
const { currentDocument } = project;
|
||||||
const { nodesMap } = currentDocument;
|
const nodesMap = currentDocument?.nodesMap;
|
||||||
const formNode = nodesMap.get('form');
|
const formNode = nodesMap?.get('form');
|
||||||
currentDocument?.insertNode(formNode, {
|
formNode && currentDocument?.insertNode(formNode, {
|
||||||
componentName: 'TextInput',
|
componentName: 'TextInput',
|
||||||
id: 'nodeschema-id1',
|
id: 'nodeschema-id1',
|
||||||
props: {
|
props: {
|
||||||
@ -388,17 +388,17 @@ describe('schema 生成节点模型测试', () => {
|
|||||||
propB: 3,
|
propB: 3,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
expect(nodesMap.get('nodeschema-id1').componentName).toBe('TextInput');
|
expect(nodesMap?.get('nodeschema-id1')?.componentName).toBe('TextInput');
|
||||||
expect(nodesMap.size).toBe(ids.length + 1);
|
expect(nodesMap?.size).toBe(ids.length + 1);
|
||||||
});
|
});
|
||||||
|
|
||||||
it.skip('场景一:插入 NodeSchema,id 与现有 schema 里的 id 重复,但关闭了 id 检测器', () => {
|
it.skip('场景一:插入 NodeSchema,id 与现有 schema 里的 id 重复,但关闭了 id 检测器', () => {
|
||||||
expect(project).toBeTruthy();
|
expect(project).toBeTruthy();
|
||||||
const ids = getIdsFromSchema(formSchema);
|
const ids = getIdsFromSchema(formSchema);
|
||||||
const { currentDocument } = project;
|
const { currentDocument } = project;
|
||||||
const { nodesMap } = currentDocument;
|
const nodesMap = currentDocument?.nodesMap;
|
||||||
const formNode = nodesMap.get('form');
|
const formNode = nodesMap?.get('form');
|
||||||
currentDocument?.insertNode(formNode, {
|
formNode && currentDocument?.insertNode(formNode, {
|
||||||
componentName: 'TextInput',
|
componentName: 'TextInput',
|
||||||
id: 'nodeschema-id1',
|
id: 'nodeschema-id1',
|
||||||
props: {
|
props: {
|
||||||
@ -406,16 +406,16 @@ describe('schema 生成节点模型测试', () => {
|
|||||||
propB: 3,
|
propB: 3,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
expect(nodesMap.get('nodeschema-id1').componentName).toBe('TextInput');
|
expect(nodesMap?.get('nodeschema-id1')?.componentName).toBe('TextInput');
|
||||||
expect(nodesMap.size).toBe(ids.length + 1);
|
expect(nodesMap?.size).toBe(ids.length + 1);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('场景二:插入 Node 实例', () => {
|
it('场景二:插入 Node 实例', () => {
|
||||||
expect(project).toBeTruthy();
|
expect(project).toBeTruthy();
|
||||||
const ids = getIdsFromSchema(formSchema);
|
const ids = getIdsFromSchema(formSchema);
|
||||||
const { currentDocument } = project;
|
const { currentDocument } = project;
|
||||||
const { nodesMap } = currentDocument;
|
const nodesMap = currentDocument?.nodesMap;
|
||||||
const formNode = nodesMap.get('form');
|
const formNode = nodesMap?.get('form');
|
||||||
const inputNode = currentDocument?.createNode({
|
const inputNode = currentDocument?.createNode({
|
||||||
componentName: 'TextInput',
|
componentName: 'TextInput',
|
||||||
id: 'nodeschema-id2',
|
id: 'nodeschema-id2',
|
||||||
@ -424,22 +424,22 @@ describe('schema 生成节点模型测试', () => {
|
|||||||
propB: 3,
|
propB: 3,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
currentDocument?.insertNode(formNode, inputNode);
|
formNode && currentDocument?.insertNode(formNode, inputNode);
|
||||||
expect(formNode.children?.get(3)?.componentName).toBe('TextInput');
|
expect(formNode?.children?.get(3)?.componentName).toBe('TextInput');
|
||||||
expect(nodesMap.size).toBe(ids.length + 1);
|
expect(nodesMap?.size).toBe(ids.length + 1);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('场景三:插入 JSExpression', () => {
|
it('场景三:插入 JSExpression', () => {
|
||||||
expect(project).toBeTruthy();
|
expect(project).toBeTruthy();
|
||||||
const ids = getIdsFromSchema(formSchema);
|
const ids = getIdsFromSchema(formSchema);
|
||||||
const { currentDocument } = project;
|
const { currentDocument } = project;
|
||||||
const { nodesMap } = currentDocument;
|
const nodesMap = currentDocument?.nodesMap;
|
||||||
const formNode = nodesMap.get('form') as Node;
|
const formNode = nodesMap?.get('form') as Node;
|
||||||
currentDocument?.insertNode(formNode, {
|
currentDocument?.insertNode(formNode, {
|
||||||
type: 'JSExpression',
|
type: 'JSExpression',
|
||||||
value: 'just a expression',
|
value: 'just a expression',
|
||||||
});
|
});
|
||||||
expect(nodesMap.size).toBe(ids.length + 1);
|
expect(nodesMap?.size).toBe(ids.length + 1);
|
||||||
expect(formNode.children?.get(3)?.componentName).toBe('Leaf');
|
expect(formNode.children?.get(3)?.componentName).toBe('Leaf');
|
||||||
// expect(formNode.children?.get(3)?.children).toEqual({
|
// expect(formNode.children?.get(3)?.children).toEqual({
|
||||||
// type: 'JSExpression',
|
// type: 'JSExpression',
|
||||||
@ -450,10 +450,10 @@ describe('schema 生成节点模型测试', () => {
|
|||||||
expect(project).toBeTruthy();
|
expect(project).toBeTruthy();
|
||||||
const ids = getIdsFromSchema(formSchema);
|
const ids = getIdsFromSchema(formSchema);
|
||||||
const { currentDocument } = project;
|
const { currentDocument } = project;
|
||||||
const { nodesMap } = currentDocument;
|
const nodesMap = currentDocument?.nodesMap;
|
||||||
const formNode = nodesMap.get('form') as Node;
|
const formNode = nodesMap?.get('form') as Node;
|
||||||
currentDocument?.insertNode(formNode, 'just a string');
|
currentDocument?.insertNode(formNode, 'just a string');
|
||||||
expect(nodesMap.size).toBe(ids.length + 1);
|
expect(nodesMap?.size).toBe(ids.length + 1);
|
||||||
expect(formNode.children?.get(3)?.componentName).toBe('Leaf');
|
expect(formNode.children?.get(3)?.componentName).toBe('Leaf');
|
||||||
// expect(formNode.children?.get(3)?.children).toBe('just a string');
|
// expect(formNode.children?.get(3)?.children).toBe('just a string');
|
||||||
});
|
});
|
||||||
@ -473,8 +473,8 @@ describe('schema 生成节点模型测试', () => {
|
|||||||
expect(project).toBeTruthy();
|
expect(project).toBeTruthy();
|
||||||
const ids = getIdsFromSchema(formSchema);
|
const ids = getIdsFromSchema(formSchema);
|
||||||
const { currentDocument } = project;
|
const { currentDocument } = project;
|
||||||
const { nodesMap } = currentDocument;
|
const nodesMap = currentDocument?.nodesMap;
|
||||||
const formNode = nodesMap.get('form') as Node;
|
const formNode = nodesMap?.get('form') as Node;
|
||||||
const formNode2 = currentDocument?.getNode('form');
|
const formNode2 = currentDocument?.getNode('form');
|
||||||
expect(formNode).toEqual(formNode2);
|
expect(formNode).toEqual(formNode2);
|
||||||
currentDocument?.insertNodes(formNode, [
|
currentDocument?.insertNodes(formNode, [
|
||||||
@ -493,17 +493,17 @@ describe('schema 生成节点模型测试', () => {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
], 1);
|
], 1);
|
||||||
expect(nodesMap.size).toBe(ids.length + 2);
|
expect(nodesMap?.size).toBe(ids.length + 2);
|
||||||
expect(formNode.children?.length).toBe(5);
|
expect(formNode.children?.length).toBe(5);
|
||||||
const insertedNode1 = formNode.children.get(1);
|
const insertedNode1 = formNode.children?.get(1);
|
||||||
const insertedNode2 = formNode.children.get(2);
|
const insertedNode2 = formNode.children?.get(2);
|
||||||
expect(insertedNode1.componentName).toBe('TextInput');
|
expect(insertedNode1?.componentName).toBe('TextInput');
|
||||||
expect(insertedNode1.propsData).toEqual({
|
expect(insertedNode1?.propsData).toEqual({
|
||||||
propA: 'haha2',
|
propA: 'haha2',
|
||||||
propB: 3,
|
propB: 3,
|
||||||
});
|
});
|
||||||
expect(insertedNode2.componentName).toBe('TextInput2');
|
expect(insertedNode2?.componentName).toBe('TextInput2');
|
||||||
expect(insertedNode2.propsData).toEqual({
|
expect(insertedNode2?.propsData).toEqual({
|
||||||
propA: 'haha',
|
propA: 'haha',
|
||||||
propB: 3,
|
propB: 3,
|
||||||
});
|
});
|
||||||
@ -513,8 +513,8 @@ describe('schema 生成节点模型测试', () => {
|
|||||||
expect(project).toBeTruthy();
|
expect(project).toBeTruthy();
|
||||||
const ids = getIdsFromSchema(formSchema);
|
const ids = getIdsFromSchema(formSchema);
|
||||||
const { currentDocument } = project;
|
const { currentDocument } = project;
|
||||||
const { nodesMap } = currentDocument;
|
const nodesMap = currentDocument?.nodesMap;
|
||||||
const formNode = nodesMap.get('form') as Node;
|
const formNode = nodesMap?.get('form') as INode;
|
||||||
const formNode2 = currentDocument?.getNode('form');
|
const formNode2 = currentDocument?.getNode('form');
|
||||||
expect(formNode).toEqual(formNode2);
|
expect(formNode).toEqual(formNode2);
|
||||||
const createdNode1 = currentDocument?.createNode({
|
const createdNode1 = currentDocument?.createNode({
|
||||||
@ -532,17 +532,17 @@ describe('schema 生成节点模型测试', () => {
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
currentDocument?.insertNodes(formNode, [createdNode1, createdNode2], 1);
|
currentDocument?.insertNodes(formNode, [createdNode1, createdNode2], 1);
|
||||||
expect(nodesMap.size).toBe(ids.length + 2);
|
expect(nodesMap?.size).toBe(ids.length + 2);
|
||||||
expect(formNode.children?.length).toBe(5);
|
expect(formNode.children?.length).toBe(5);
|
||||||
const insertedNode1 = formNode.children.get(1);
|
const insertedNode1 = formNode.children?.get(1);
|
||||||
const insertedNode2 = formNode.children.get(2);
|
const insertedNode2 = formNode.children?.get(2);
|
||||||
expect(insertedNode1.componentName).toBe('TextInput');
|
expect(insertedNode1?.componentName).toBe('TextInput');
|
||||||
expect(insertedNode1.propsData).toEqual({
|
expect(insertedNode1?.propsData).toEqual({
|
||||||
propA: 'haha2',
|
propA: 'haha2',
|
||||||
propB: 3,
|
propB: 3,
|
||||||
});
|
});
|
||||||
expect(insertedNode2.componentName).toBe('TextInput2');
|
expect(insertedNode2?.componentName).toBe('TextInput2');
|
||||||
expect(insertedNode2.propsData).toEqual({
|
expect(insertedNode2?.propsData).toEqual({
|
||||||
propA: 'haha',
|
propA: 'haha',
|
||||||
propB: 3,
|
propB: 3,
|
||||||
});
|
});
|
||||||
@ -561,13 +561,13 @@ describe('schema 生成节点模型测试', () => {
|
|||||||
project.open();
|
project.open();
|
||||||
expect(project).toBeTruthy();
|
expect(project).toBeTruthy();
|
||||||
const { currentDocument } = project;
|
const { currentDocument } = project;
|
||||||
const { nodesMap } = currentDocument;
|
const nodesMap = currentDocument?.nodesMap;
|
||||||
const ids = getIdsFromSchema(formSchema);
|
const ids = getIdsFromSchema(formSchema);
|
||||||
// 目前每个 slot 会新增(1 + children.length)个节点
|
// 目前每个 slot 会新增(1 + children.length)个节点
|
||||||
const expectedNodeCnt = ids.length + 2;
|
const expectedNodeCnt = ids.length + 2;
|
||||||
expect(nodesMap.size).toBe(expectedNodeCnt);
|
expect(nodesMap?.size).toBe(expectedNodeCnt);
|
||||||
// PageHeader
|
// PageHeader
|
||||||
expect(nodesMap.get('node_k1ow3cbd').slots).toHaveLength(1);
|
expect(nodesMap?.get('node_k1ow3cbd')?.slots).toHaveLength(1);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
42
packages/shell/src/model/condition-group.ts
Normal file
42
packages/shell/src/model/condition-group.ts
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
import { IExclusiveGroup } from '@alilc/lowcode-designer';
|
||||||
|
import { IPublicModelExclusiveGroup, IPublicModelNode } from '@alilc/lowcode-types';
|
||||||
|
import { conditionGroupSymbol, nodeSymbol } from '../symbols';
|
||||||
|
import { Node } from './node';
|
||||||
|
|
||||||
|
export class ConditionGroup implements IPublicModelExclusiveGroup {
|
||||||
|
private [conditionGroupSymbol]: IExclusiveGroup | null;
|
||||||
|
|
||||||
|
constructor(conditionGroup: IExclusiveGroup | null) {
|
||||||
|
this[conditionGroupSymbol] = conditionGroup;
|
||||||
|
}
|
||||||
|
|
||||||
|
get id() {
|
||||||
|
return this[conditionGroupSymbol]?.id;
|
||||||
|
}
|
||||||
|
|
||||||
|
get title() {
|
||||||
|
return this[conditionGroupSymbol]?.title;
|
||||||
|
}
|
||||||
|
|
||||||
|
get firstNode() {
|
||||||
|
return Node.create(this[conditionGroupSymbol]?.firstNode);
|
||||||
|
}
|
||||||
|
|
||||||
|
setVisible(node: IPublicModelNode) {
|
||||||
|
this[conditionGroupSymbol]?.setVisible((node as any)[nodeSymbol] ? (node as any)[nodeSymbol] : node);
|
||||||
|
}
|
||||||
|
|
||||||
|
static create(conditionGroup: IExclusiveGroup | null) {
|
||||||
|
if (!conditionGroup) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
// @ts-ignore
|
||||||
|
if (conditionGroup[conditionGroupSymbol]) {
|
||||||
|
return (conditionGroup as any)[conditionGroupSymbol];
|
||||||
|
}
|
||||||
|
const shellConditionGroup = new ConditionGroup(conditionGroup);
|
||||||
|
// @ts-ignore
|
||||||
|
shellConditionGroup[conditionGroupSymbol] = shellConditionGroup;
|
||||||
|
return shellConditionGroup;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -27,6 +27,7 @@ import { ComponentMeta as ShellComponentMeta } from './component-meta';
|
|||||||
import { SettingTopEntry as ShellSettingTopEntry } from './setting-top-entry';
|
import { SettingTopEntry as ShellSettingTopEntry } from './setting-top-entry';
|
||||||
import { documentSymbol, nodeSymbol } from '../symbols';
|
import { documentSymbol, nodeSymbol } from '../symbols';
|
||||||
import { ReactElement } from 'react';
|
import { ReactElement } from 'react';
|
||||||
|
import { ConditionGroup } from './condition-group';
|
||||||
|
|
||||||
const shellNodeSymbol = Symbol('shellNodeSymbol');
|
const shellNodeSymbol = Symbol('shellNodeSymbol');
|
||||||
|
|
||||||
@ -289,7 +290,7 @@ export class Node implements IPublicModelNode {
|
|||||||
/**
|
/**
|
||||||
* 当前节点为插槽节点时,返回节点对应的属性实例
|
* 当前节点为插槽节点时,返回节点对应的属性实例
|
||||||
*/
|
*/
|
||||||
get slotFor(): IPublicModelProp | null {
|
get slotFor(): IPublicModelProp | null | undefined {
|
||||||
return ShellProp.create(this[nodeSymbol].slotFor);
|
return ShellProp.create(this[nodeSymbol].slotFor);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -349,7 +350,6 @@ export class Node implements IPublicModelNode {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取节点实例对应的 dom 节点
|
* 获取节点实例对应的 dom 节点
|
||||||
* @deprecated
|
|
||||||
*/
|
*/
|
||||||
getDOMNode() {
|
getDOMNode() {
|
||||||
return (this[nodeSymbol] as any).getDOMNode();
|
return (this[nodeSymbol] as any).getDOMNode();
|
||||||
@ -362,9 +362,9 @@ export class Node implements IPublicModelNode {
|
|||||||
* @param sorter
|
* @param sorter
|
||||||
*/
|
*/
|
||||||
mergeChildren(
|
mergeChildren(
|
||||||
remover: (node: Node, idx: number) => boolean,
|
remover: (node: IPublicModelNode, idx: number) => boolean,
|
||||||
adder: (children: Node[]) => any,
|
adder: (children: IPublicModelNode[]) => any,
|
||||||
sorter: (firstNode: Node, secondNode: Node) => number,
|
sorter: (firstNode: IPublicModelNode, secondNode: IPublicModelNode) => number,
|
||||||
): any {
|
): any {
|
||||||
return this.children?.mergeChildren(remover, adder, sorter);
|
return this.children?.mergeChildren(remover, adder, sorter);
|
||||||
}
|
}
|
||||||
@ -641,7 +641,7 @@ export class Node implements IPublicModelNode {
|
|||||||
* @since v1.1.0
|
* @since v1.1.0
|
||||||
*/
|
*/
|
||||||
get conditionGroup(): IPublicModelExclusiveGroup | null {
|
get conditionGroup(): IPublicModelExclusiveGroup | null {
|
||||||
return this[nodeSymbol].conditionGroup;
|
return ConditionGroup.create(this[nodeSymbol].conditionGroup);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@ -33,3 +33,4 @@ export const resourceTypeSymbol = Symbol('resourceType');
|
|||||||
export const resourceSymbol = Symbol('resource');
|
export const resourceSymbol = Symbol('resource');
|
||||||
export const clipboardSymbol = Symbol('clipboard');
|
export const clipboardSymbol = Symbol('clipboard');
|
||||||
export const configSymbol = Symbol('configSymbol');
|
export const configSymbol = Symbol('configSymbol');
|
||||||
|
export const conditionGroupSymbol = Symbol('conditionGroup');
|
||||||
|
|||||||
@ -1,8 +1,10 @@
|
|||||||
import { IPublicModelNode } from '..';
|
import { IPublicModelNode, IPublicTypeTitleContent } from '..';
|
||||||
|
|
||||||
export interface IPublicModelExclusiveGroup {
|
export interface IPublicModelExclusiveGroup<
|
||||||
readonly id: string;
|
Node = IPublicModelNode,
|
||||||
readonly title: string;
|
> {
|
||||||
get firstNode(): IPublicModelNode;
|
readonly id: string | undefined;
|
||||||
|
readonly title: IPublicTypeTitleContent | undefined;
|
||||||
|
get firstNode(): Node | null;
|
||||||
setVisible(node: Node): void;
|
setVisible(node: Node): void;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -8,7 +8,10 @@ export interface IBaseModelNode<
|
|||||||
Node = IPublicModelNode,
|
Node = IPublicModelNode,
|
||||||
NodeChildren = IPublicModelNodeChildren,
|
NodeChildren = IPublicModelNodeChildren,
|
||||||
ComponentMeta = IPublicModelComponentMeta,
|
ComponentMeta = IPublicModelComponentMeta,
|
||||||
SettingTopEntry = IPublicModelSettingTopEntry
|
SettingTopEntry = IPublicModelSettingTopEntry,
|
||||||
|
Props = IPublicModelProps,
|
||||||
|
Prop = IPublicModelProp,
|
||||||
|
ExclusiveGroup = IPublicModelExclusiveGroup
|
||||||
> {
|
> {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -167,7 +170,7 @@ export interface IBaseModelNode<
|
|||||||
* 下标
|
* 下标
|
||||||
* index
|
* index
|
||||||
*/
|
*/
|
||||||
get index(): number;
|
get index(): number | undefined;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 图标
|
* 图标
|
||||||
@ -203,13 +206,13 @@ export interface IBaseModelNode<
|
|||||||
* 获取当前节点的前一个兄弟节点
|
* 获取当前节点的前一个兄弟节点
|
||||||
* get previous sibling of this node
|
* get previous sibling of this node
|
||||||
*/
|
*/
|
||||||
get prevSibling(): Node | null;
|
get prevSibling(): Node | null | undefined;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取当前节点的后一个兄弟节点
|
* 获取当前节点的后一个兄弟节点
|
||||||
* get next sibling of this node
|
* get next sibling of this node
|
||||||
*/
|
*/
|
||||||
get nextSibling(): Node | null;
|
get nextSibling(): Node | null | undefined;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取当前节点的父亲节点
|
* 获取当前节点的父亲节点
|
||||||
@ -233,13 +236,13 @@ export interface IBaseModelNode<
|
|||||||
* 当前节点为插槽节点时,返回节点对应的属性实例
|
* 当前节点为插槽节点时,返回节点对应的属性实例
|
||||||
* return coresponding prop when this node is a slot node
|
* return coresponding prop when this node is a slot node
|
||||||
*/
|
*/
|
||||||
get slotFor(): IPublicModelProp | null;
|
get slotFor(): Prop | null | undefined;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 返回节点的属性集
|
* 返回节点的属性集
|
||||||
* get props
|
* get props
|
||||||
*/
|
*/
|
||||||
get props(): IPublicModelProps | null;
|
get props(): Props | null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 返回节点的属性集
|
* 返回节点的属性集
|
||||||
@ -250,7 +253,7 @@ export interface IBaseModelNode<
|
|||||||
/**
|
/**
|
||||||
* get conditionGroup
|
* get conditionGroup
|
||||||
*/
|
*/
|
||||||
get conditionGroup(): IPublicModelExclusiveGroup | null;
|
get conditionGroup(): ExclusiveGroup | null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取符合搭建协议 - 节点 schema 结构
|
* 获取符合搭建协议 - 节点 schema 结构
|
||||||
@ -295,7 +298,7 @@ export interface IBaseModelNode<
|
|||||||
* get prop by path
|
* get prop by path
|
||||||
* @param path 属性路径,支持 a / a.b / a.0 等格式
|
* @param path 属性路径,支持 a / a.b / a.0 等格式
|
||||||
*/
|
*/
|
||||||
getProp(path: string, createIfNone: boolean): IPublicModelProp | null;
|
getProp(path: string, createIfNone: boolean): Prop | null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取指定 path 的属性模型实例值
|
* 获取指定 path 的属性模型实例值
|
||||||
@ -313,7 +316,7 @@ export interface IBaseModelNode<
|
|||||||
* @param path 属性路径,支持 a / a.b / a.0 等格式
|
* @param path 属性路径,支持 a / a.b / a.0 等格式
|
||||||
* @param createIfNone 当没有属性的时候,是否创建一个属性
|
* @param createIfNone 当没有属性的时候,是否创建一个属性
|
||||||
*/
|
*/
|
||||||
getExtraProp(path: string, createIfNone?: boolean): IPublicModelProp | null;
|
getExtraProp(path: string, createIfNone?: boolean): Prop | null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取指定 path 的属性模型实例,
|
* 获取指定 path 的属性模型实例,
|
||||||
@ -481,6 +484,11 @@ export interface IBaseModelNode<
|
|||||||
* @since v1.1.0
|
* @since v1.1.0
|
||||||
*/
|
*/
|
||||||
setConditionalVisible(): void;
|
setConditionalVisible(): void;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取节点实例对应的 dom 节点
|
||||||
|
*/
|
||||||
|
getDOMNode(): HTMLElement;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface IPublicModelNode extends IBaseModelNode<IPublicModelDocumentModel, IPublicModelNode> {}
|
export interface IPublicModelNode extends IBaseModelNode<IPublicModelDocumentModel, IPublicModelNode> {}
|
||||||
@ -2,7 +2,9 @@ import { IPublicEnumTransformStage } from '../enum';
|
|||||||
import { IPublicTypeCompositeValue } from '../type';
|
import { IPublicTypeCompositeValue } from '../type';
|
||||||
import { IPublicModelNode } from './';
|
import { IPublicModelNode } from './';
|
||||||
|
|
||||||
export interface IPublicModelProp {
|
export interface IPublicModelProp<
|
||||||
|
Node = IPublicModelNode
|
||||||
|
> {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* id
|
* id
|
||||||
@ -25,14 +27,14 @@ export interface IPublicModelProp {
|
|||||||
* 返回所属的节点实例
|
* 返回所属的节点实例
|
||||||
* get node instance, which this prop belongs to
|
* get node instance, which this prop belongs to
|
||||||
*/
|
*/
|
||||||
get node(): IPublicModelNode | null;
|
get node(): Node | null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 当本 prop 代表一个 Slot 时,返回对应的 slotNode
|
* 当本 prop 代表一个 Slot 时,返回对应的 slotNode
|
||||||
* return the slot node (only if the current prop represents a slot)
|
* return the slot node (only if the current prop represents a slot)
|
||||||
* @since v1.1.0
|
* @since v1.1.0
|
||||||
*/
|
*/
|
||||||
get slotNode(): IPublicModelNode | undefined | null;
|
get slotNode(): Node | undefined | null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 是否是 Prop , 固定返回 true
|
* 是否是 Prop , 固定返回 true
|
||||||
|
|||||||
@ -195,8 +195,8 @@ export interface IPublicTypeCallbacks {
|
|||||||
onChildMoveHook?: (childNode: IPublicModelNode, currentNode: IPublicModelNode) => boolean;
|
onChildMoveHook?: (childNode: IPublicModelNode, currentNode: IPublicModelNode) => boolean;
|
||||||
|
|
||||||
// events
|
// events
|
||||||
onNodeRemove?: (removedNode: IPublicModelNode, currentNode: IPublicModelNode) => void;
|
onNodeRemove?: (removedNode: IPublicModelNode | null, currentNode: IPublicModelNode | null) => void;
|
||||||
onNodeAdd?: (addedNode: IPublicModelNode, currentNode: IPublicModelNode) => void;
|
onNodeAdd?: (addedNode: IPublicModelNode | null, currentNode: IPublicModelNode | null) => void;
|
||||||
onSubtreeModified?: (currentNode: IPublicModelNode, options: any) => void;
|
onSubtreeModified?: (currentNode: IPublicModelNode, options: any) => void;
|
||||||
onResize?: (
|
onResize?: (
|
||||||
e: MouseEvent & {
|
e: MouseEvent & {
|
||||||
|
|||||||
@ -1,3 +1,3 @@
|
|||||||
export function isDOMText(data: any): boolean {
|
export function isDOMText(data: any): data is string {
|
||||||
return typeof data === 'string';
|
return typeof data === 'string';
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
import { IPublicTypeNodeSchema } from '@alilc/lowcode-types';
|
import { IPublicTypeNodeSchema } from '@alilc/lowcode-types';
|
||||||
|
|
||||||
export function isNodeSchema(data: any): data is IPublicTypeNodeSchema {
|
export function isNodeSchema(data: any): data is IPublicTypeNodeSchema {
|
||||||
return data && data.componentName;
|
return data && data.componentName && !data.isNode;
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user