chore: 将删除节点的 parent 保留,subtreeModified 时能拿到一些父子关系信息

refactor: 不再在 document 初始化完成后新建的节点都默认重置 id
chore(test): 补充 prototype 部分的单测
This commit is contained in:
力皓 2020-11-10 14:03:11 +08:00
parent bfa0f36334
commit 537258d9e6
7 changed files with 144 additions and 16 deletions

View File

@ -179,7 +179,7 @@ export class BoxResizingInstance extends Component<{
typeof metaData.experimental.callbacks.onResizeEnd === 'function'
) {
(e as any).trigger = direction;
metaData.experimental.callbacks.onResizeStart(e, node);
metaData.experimental.callbacks.onResizeEnd(e, node);
}
const editor = globalContext.get(Editor);

View File

@ -205,7 +205,7 @@ export class DocumentModel {
}
let node: Node | null = null;
if (this.inited) {
if (this.hasNode(schema?.id)) {
schema.id = null;
}
if (schema.id) {

View File

@ -295,9 +295,9 @@ export class Node<Schema extends NodeSchema = NodeSchema> {
if (useMutator) {
this._parent?.didDropOut(this);
}
// 建立新的父子关系
this._parent = parent;
if (parent) {
// 建立新的父子关系,尤其注意:对于 parent 为 null 的场景,不会赋值,因为 subtreeModified 等事件可能需要知道该 node 被删除前的父子关系
this._parent = parent;
this.document.removeWillPurge(this);
if (!this.conditionGroup) {
// initial conditionGroup

View File

@ -1,9 +1,5 @@
import { IocContext } from 'power-di';
// 原本的 canBeKey 里判断函数的方法是 instanceof Function在某些 babel 编译 class 后的场景不满足该判断条件,此处暴力破解
IocContext.prototype.canBeKey = (obj: any) =>
typeof obj === 'function' || ['string', 'symbol'].includes(typeof obj);
export * from 'power-di';
export const globalContext = IocContext.DefaultInstance;

View File

@ -1,3 +1,4 @@
import { Component } from 'react';
import set from 'lodash/set';
import cloneDeep from 'lodash/clonedeep';
import '../fixtures/window';
@ -8,18 +9,20 @@ import divPrototypeConfig from '../fixtures/prototype/div-vision';
import divPrototypeMeta from '../fixtures/prototype/div-meta';
// import VisualEngine from '../../src';
import { designer } from '../../src/editor';
import Prototype from '../../src/bundle/prototype';
import Prototype, { isPrototype } from '../../src/bundle/prototype';
import { Editor } from '@ali/lowcode-editor-core';
// import { getIdsFromSchema, getNodeFromSchemaById } from '../utils';
describe('Prototype', () => {
it('构造函数 - OldPrototypeConfig', () => {
const proto = new Prototype(divPrototypeConfig);
expect(isPrototype(proto)).toBeTruthy;
expect(proto.getComponentName()).toBe('Div');
expect(proto.getId()).toBe('Div');
expect(proto.getCategory()).toBe('布局');
expect(proto.getDocUrl()).toBe('http://gitlab.alibaba-inc.com/vision-components/vc-block/blob/master/README.md');
expect(proto.getDocUrl()).toBe(
'http://gitlab.alibaba-inc.com/vision-components/vc-block/blob/master/README.md',
);
expect(proto.getIcon()).toBeUndefined;
expect(proto.getTitle()).toBe('Div');
expect(proto.isPrototype).toBeTruthy;
@ -31,7 +34,9 @@ describe('Prototype', () => {
expect(proto.getComponentName()).toBe('Div');
expect(proto.getId()).toBe('Div');
expect(proto.getCategory()).toBe('布局');
expect(proto.getDocUrl()).toBe('http://gitlab.alibaba-inc.com/vision-components/vc-block/blob/master/README.md');
expect(proto.getDocUrl()).toBe(
'http://gitlab.alibaba-inc.com/vision-components/vc-block/blob/master/README.md',
);
expect(proto.getIcon()).toBeUndefined;
expect(proto.getTitle()).toBe('Div');
expect(proto.isPrototype).toBeTruthy;
@ -44,7 +49,9 @@ describe('Prototype', () => {
expect(proto.getComponentName()).toBe('Div');
expect(proto.getId()).toBe('Div');
expect(proto.getCategory()).toBe('布局');
expect(proto.getDocUrl()).toBe('http://gitlab.alibaba-inc.com/vision-components/vc-block/blob/master/README.md');
expect(proto.getDocUrl()).toBe(
'http://gitlab.alibaba-inc.com/vision-components/vc-block/blob/master/README.md',
);
expect(proto.getIcon()).toBeUndefined;
expect(proto.getTitle()).toBe('Div');
expect(proto.isPrototype).toBeTruthy;
@ -56,7 +63,9 @@ describe('Prototype', () => {
expect(proto.getComponentName()).toBe('Div');
expect(proto.getId()).toBe('Div');
expect(proto.getCategory()).toBe('布局');
expect(proto.getDocUrl()).toBe('http://gitlab.alibaba-inc.com/vision-components/vc-block/blob/master/README.md');
expect(proto.getDocUrl()).toBe(
'http://gitlab.alibaba-inc.com/vision-components/vc-block/blob/master/README.md',
);
expect(proto.getIcon()).toBeUndefined;
expect(proto.getTitle()).toBe('Div');
expect(proto.isPrototype).toBeTruthy;
@ -68,4 +77,127 @@ describe('Prototype', () => {
const proto2 = Prototype.create(divPrototypeConfig, {}, true);
expect(proto).toBe(proto2);
});
describe('类成员函数', () => {
let proto: Prototype = null;
beforeEach(() => {
proto = new Prototype(divPrototypeConfig);
});
afterEach(() => {
proto = null;
});
it('各种函数', () => {
expect(proto.componentName).toBe('Div');
expect(proto.getComponentName()).toBe('Div');
expect(proto.getId()).toBe('Div');
expect(proto.getContextInfo('anything')).toBeUndefined;
expect(proto.getPropConfigs()).toBe(divPrototypeConfig);
expect(proto.getConfig()).toBe(divPrototypeConfig);
expect(proto.getConfig('componentName')).toBe('Div');
expect(proto.getConfig('configure')).toBe(divPrototypeConfig.configure);
expect(proto.getConfig('docUrl')).toBe(
'http://gitlab.alibaba-inc.com/vision-components/vc-block/blob/master/README.md',
);
expect(proto.getConfig('title')).toBe('容器');
expect(proto.getConfig('isContainer')).toBeTruthy;
class MockView extends Component {}
expect(proto.getView()).toBeUndefined;
proto.setView(MockView);
expect(proto.getView()).toBe(MockView);
expect(proto.meta.getMetadata().experimental?.view).toBe(MockView);
expect(proto.getPackageName()).toBeUndefined;
proto.setPackageName('@ali/vc-div');
expect(proto.getPackageName()).toBe('@ali/vc-div');
expect(proto.getConfig('category')).toBe('布局');
proto.setCategory('布局 new');
expect(proto.getConfig('category')).toBe('布局 new');
expect(proto.getConfigure()).toHaveLength(3);
expect(proto.getConfigure()[0].name).toBe('#props');
expect(proto.getConfigure()[1].name).toBe('#styles');
expect(proto.getConfigure()[2].name).toBe('#advanced');
expect(proto.getRectSelector()).toBeUndefined;
expect(proto.isAutoGenerated()).toBeFalsy;
});
});
describe('类成员函数', () => {
it('addGlobalPropsConfigure', () => {
Prototype.addGlobalPropsConfigure({
name: 'globalInsertProp1',
});
const proto1 = new Prototype(divPrototypeConfig);
expect(proto1.getConfigure()[2].items).toHaveLength(4);
expect(proto1.getConfigure()[2].items[3].name).toBe('globalInsertProp1');
Prototype.addGlobalPropsConfigure({
name: 'globalInsertProp2',
});
const proto2 = new Prototype(divPrototypeConfig);
expect(proto2.getConfigure()[2].items).toHaveLength(5);
expect(proto1.getConfigure()[2].items[4].name).toBe('globalInsertProp2');
Prototype.addGlobalPropsConfigure({
name: 'globalInsertProp3',
position: 'top',
});
const proto3 = new Prototype(divPrototypeConfig);
expect(proto3.getConfigure()[0].items).toHaveLength(3);
expect(proto1.getConfigure()[0].items[0].name).toBe('globalInsertProp3');
});
it('removeGlobalPropsConfigure', () => {
Prototype.removeGlobalPropsConfigure('globalInsertProp1');
Prototype.removeGlobalPropsConfigure('globalInsertProp2');
Prototype.removeGlobalPropsConfigure('globalInsertProp3');
const proto2 = new Prototype(divPrototypeConfig);
expect(proto2.getConfigure()[0].items).toHaveLength(2);
expect(proto2.getConfigure()[2].items).toHaveLength(3);
});
it('overridePropsConfigure', () => {
Prototype.addGlobalPropsConfigure({
name: 'globalInsertProp1',
title: 'globalInsertPropTitle',
position: 'top',
});
const proto1 = new Prototype(divPrototypeConfig);
expect(proto1.getConfigure()[0].items).toHaveLength(3);
expect(proto1.getConfigure()[0].items[0].name).toBe('globalInsertProp1');
expect(proto1.getConfigure()[0].items[0].title).toBe('globalInsertPropTitle');
Prototype.overridePropsConfigure('Div', [
{
name: 'globalInsertProp1',
title: 'globalInsertPropTitleChanged',
},
]);
const proto2 = new Prototype(divPrototypeConfig);
expect(proto2.getConfigure()[0].name).toBe('globalInsertProp1');
expect(proto2.getConfigure()[0].title).toBe('globalInsertPropTitleChanged');
Prototype.overridePropsConfigure('Div', {
globalInsertProp1: {
name: 'globalInsertProp1',
title: 'globalInsertPropTitleChanged new',
position: 'top',
},
});
const proto3 = new Prototype(divPrototypeConfig);
expect(proto3.getConfigure()[0].items[0].name).toBe('globalInsertProp1');
expect(proto3.getConfigure()[0].items[0].title).toBe('globalInsertPropTitleChanged new');
});
it('addGlobalExtraActions', () => {
function haha() { return 'heihei'; }
Prototype.addGlobalExtraActions(haha);
const proto1 = new Prototype(divPrototypeConfig);
expect(proto1.meta.availableActions).toHaveLength(4);
expect(proto1.meta.availableActions[3].name).toBe('haha');
});
});
});

View File

@ -329,7 +329,7 @@ export default function (metadata: TransformedComponentMetadata): TransformedCom
if (advanceGroup.length > 0) {
combined.push({
name: '#advanced',
title: { type: 'i18n', 'zh-CN': '高级', 'en-US': 'Advance' },
title: { type: 'i18n', 'zh-CN': '高级', 'en-US': 'Advanced' },
items: advanceGroup,
});
}

View File

@ -57,5 +57,5 @@
"publishConfig": {
"registry": "https://registry.npm.alibaba-inc.com"
},
"homepage": "https://unpkg.alibaba-inc.com/@ali/lowcode-rax-simulator-renderer@0.13.1-10/build/index.html"
"homepage": "https://unpkg.alibaba-inc.com/@ali/lowcode-rax-simulator-renderer@0.13.1-11/build/index.html"
}