mirror of
https://github.com/alibaba/lowcode-engine.git
synced 2026-03-05 17:57:13 +00:00
Merge branch 'develop' into release/1.0.15-beta
This commit is contained in:
commit
f346675e15
116
.github/workflows/ci.yml
vendored
Normal file
116
.github/workflows/ci.yml
vendored
Normal file
@ -0,0 +1,116 @@
|
|||||||
|
name: Node CI
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- main
|
||||||
|
pull_request:
|
||||||
|
branches:
|
||||||
|
- main
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
upload-designer-codecov:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
# if: ${{ github.event.pull_request.head.repo.full_name == 'alibaba/lowcode-engine' }}
|
||||||
|
steps:
|
||||||
|
- name: checkout
|
||||||
|
uses: actions/checkout@v2
|
||||||
|
|
||||||
|
- uses: actions/setup-node@v2
|
||||||
|
with:
|
||||||
|
node-version: '14'
|
||||||
|
|
||||||
|
- name: install
|
||||||
|
run: npm i && npm run setup:skip-build
|
||||||
|
|
||||||
|
- name: test designer
|
||||||
|
run: cd packages/designer && npm run test:cov && cd ../..
|
||||||
|
|
||||||
|
- name: Upload designer coverage to Codecov
|
||||||
|
uses: codecov/codecov-action@v3
|
||||||
|
with:
|
||||||
|
# working-directory: packages/designer
|
||||||
|
directory: ./packages/designer/coverage
|
||||||
|
token: ${{ secrets.CODECOV_TOKEN }}
|
||||||
|
name: designer
|
||||||
|
fail_ci_if_error: true
|
||||||
|
verbose: true
|
||||||
|
|
||||||
|
upload-renderer-core:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: checkout
|
||||||
|
uses: actions/checkout@v2
|
||||||
|
|
||||||
|
- uses: actions/setup-node@v2
|
||||||
|
with:
|
||||||
|
node-version: '14'
|
||||||
|
|
||||||
|
- name: install
|
||||||
|
run: npm i && npm run setup:skip-build
|
||||||
|
|
||||||
|
- name: test renderer-core
|
||||||
|
run: cd packages/renderer-core && npm run test:cov && cd ../..
|
||||||
|
|
||||||
|
- name: Upload renderer-core coverage to Codecov
|
||||||
|
uses: codecov/codecov-action@v3
|
||||||
|
with:
|
||||||
|
# working-directory: packages/designer
|
||||||
|
directory: ./packages/renderer-core/coverage
|
||||||
|
token: ${{ secrets.CODECOV_TOKEN }}
|
||||||
|
name: renderer-core
|
||||||
|
fail_ci_if_error: true
|
||||||
|
verbose: true
|
||||||
|
|
||||||
|
upload-react-simulator-renderer:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: checkout
|
||||||
|
uses: actions/checkout@v2
|
||||||
|
|
||||||
|
- uses: actions/setup-node@v2
|
||||||
|
with:
|
||||||
|
node-version: '14'
|
||||||
|
|
||||||
|
- name: install
|
||||||
|
run: npm i && npm run setup:skip-build
|
||||||
|
|
||||||
|
- name: test react-simulator-renderer
|
||||||
|
run: cd packages/react-simulator-renderer && npm run test:cov && cd ../..
|
||||||
|
|
||||||
|
- name: Upload react-simulator-renderer coverage to Codecov
|
||||||
|
uses: codecov/codecov-action@v3
|
||||||
|
with:
|
||||||
|
# working-directory: packages/designer
|
||||||
|
directory: ./packages/react-simulator-renderer/coverage
|
||||||
|
token: ${{ secrets.CODECOV_TOKEN }}
|
||||||
|
name: react-simulator-renderer
|
||||||
|
fail_ci_if_error: true
|
||||||
|
verbose: true
|
||||||
|
|
||||||
|
upload-code-generator:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
# if: ${{ github.event.pull_request.head.repo.full_name == 'alibaba/lowcode-engine' }}
|
||||||
|
steps:
|
||||||
|
- name: checkout
|
||||||
|
uses: actions/checkout@v2
|
||||||
|
|
||||||
|
- uses: actions/setup-node@v2
|
||||||
|
with:
|
||||||
|
node-version: '14'
|
||||||
|
|
||||||
|
- name: install
|
||||||
|
run: npm i && npm run setup:skip-build
|
||||||
|
|
||||||
|
- name: test code-generator
|
||||||
|
run: cd modules/code-generator && npm i && npm run build && npm run test:cov && cd ../..
|
||||||
|
|
||||||
|
- name: Upload code-generator coverage to Codecov
|
||||||
|
uses: codecov/codecov-action@v3
|
||||||
|
with:
|
||||||
|
# working-directory: packages/designer
|
||||||
|
directory: ./modules/code-generator/coverage
|
||||||
|
token: ${{ secrets.CODECOV_TOKEN }}
|
||||||
|
name: code-generator
|
||||||
|
fail_ci_if_error: true
|
||||||
|
verbose: true
|
||||||
@ -123,7 +123,7 @@ export class SchemaParser implements ISchemaParser {
|
|||||||
const schema = this.decodeSchema(schemaSrc);
|
const schema = this.decodeSchema(schemaSrc);
|
||||||
|
|
||||||
// 解析三方组件依赖
|
// 解析三方组件依赖
|
||||||
schema.componentsMap.forEach((info) => {
|
schema.componentsMap.forEach((info: any) => {
|
||||||
if (info.componentName) {
|
if (info.componentName) {
|
||||||
compDeps[info.componentName] = {
|
compDeps[info.componentName] = {
|
||||||
...info,
|
...info,
|
||||||
|
|||||||
@ -181,7 +181,7 @@ export function parseExpressionGetKeywords(expr: string | null | undefined): str
|
|||||||
const fieldValue = node[fieldName as keyof typeof node];
|
const fieldValue = node[fieldName as keyof typeof node];
|
||||||
if (typeof fieldValue === 'object') {
|
if (typeof fieldValue === 'object') {
|
||||||
if (Array.isArray(fieldValue)) {
|
if (Array.isArray(fieldValue)) {
|
||||||
fieldValue.forEach((item) => {
|
fieldValue.forEach((item: any) => {
|
||||||
addIdentifierIfNeeded(item);
|
addIdentifierIfNeeded(item);
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
@ -233,7 +233,7 @@ export function parseExpressionGetGlobalVariables(
|
|||||||
const fieldValue = node[fieldName as keyof typeof node];
|
const fieldValue = node[fieldName as keyof typeof node];
|
||||||
if (typeof fieldValue === 'object') {
|
if (typeof fieldValue === 'object') {
|
||||||
if (Array.isArray(fieldValue)) {
|
if (Array.isArray(fieldValue)) {
|
||||||
fieldValue.forEach((item) => {
|
fieldValue.forEach((item: any) => {
|
||||||
addUndeclaredIdentifierIfNeeded(item, path);
|
addUndeclaredIdentifierIfNeeded(item, path);
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@ -98,7 +98,7 @@ export function createSimulator(
|
|||||||
doc.close();
|
doc.close();
|
||||||
|
|
||||||
return new Promise((resolve) => {
|
return new Promise((resolve) => {
|
||||||
const renderer = win.SimulatorRenderer || host.renderer;
|
const renderer = win.SimulatorRenderer;
|
||||||
if (renderer) {
|
if (renderer) {
|
||||||
return resolve(renderer);
|
return resolve(renderer);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -232,6 +232,10 @@ export class BuiltinSimulatorHost implements ISimulatorHost<BuiltinSimulatorProp
|
|||||||
return engineConfig.get('thisRequiredInJSE') ?? true;
|
return engineConfig.get('thisRequiredInJSE') ?? true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
get enableStrictNotFoundMode(): any {
|
||||||
|
return engineConfig.get('enableStrictNotFoundMode') ?? false;
|
||||||
|
}
|
||||||
|
|
||||||
@computed get componentsAsset(): Asset | undefined {
|
@computed get componentsAsset(): Asset | undefined {
|
||||||
return this.get('componentsAsset');
|
return this.get('componentsAsset');
|
||||||
}
|
}
|
||||||
@ -850,7 +854,7 @@ export class BuiltinSimulatorHost implements ISimulatorHost<BuiltinSimulatorProp
|
|||||||
|
|
||||||
// filter with context
|
// filter with context
|
||||||
return instances.filter((instance) => {
|
return instances.filter((instance) => {
|
||||||
return this.getClosestNodeInstance(instance, context.nodeId)?.instance === context.instance;
|
return this.getClosestNodeInstance(instance, context?.nodeId)?.instance === context.instance;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -176,12 +176,29 @@ export class ComponentMeta {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private parseMetadata(metadata: ComponentMetadata) {
|
private parseMetadata(metadata: ComponentMetadata) {
|
||||||
const { componentName, npm } = metadata;
|
const { componentName, npm, ...others } = metadata;
|
||||||
|
let _metadata = metadata;
|
||||||
|
if (!npm && !Object.keys(others).length) {
|
||||||
|
// 没有注册的组件,只能删除,不支持复制、移动等操作
|
||||||
|
_metadata = {
|
||||||
|
componentName,
|
||||||
|
configure: {
|
||||||
|
component: {
|
||||||
|
disableBehaviors: ['copy', 'move', 'lock', 'unlock'],
|
||||||
|
},
|
||||||
|
advanced: {
|
||||||
|
callbacks: {
|
||||||
|
onMoveHook: () => false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
this._npm = npm || this._npm;
|
this._npm = npm || this._npm;
|
||||||
this._componentName = componentName;
|
this._componentName = componentName;
|
||||||
|
|
||||||
// 额外转换逻辑
|
// 额外转换逻辑
|
||||||
this._transformedMetadata = this.transformMetadata(metadata);
|
this._transformedMetadata = this.transformMetadata(_metadata);
|
||||||
|
|
||||||
const { title } = this._transformedMetadata;
|
const { title } = this._transformedMetadata;
|
||||||
if (title) {
|
if (title) {
|
||||||
|
|||||||
@ -23,6 +23,7 @@ import {
|
|||||||
setShaken,
|
setShaken,
|
||||||
} from '../../src/designer/dragon';
|
} from '../../src/designer/dragon';
|
||||||
import { Project } from '../../src/project/project';
|
import { Project } from '../../src/project/project';
|
||||||
|
import pageMetadata from '../fixtures/component-metadata/page';
|
||||||
import { Node } from '../../src/document/node/node';
|
import { Node } from '../../src/document/node/node';
|
||||||
import { Designer } from '../../src/designer/designer';
|
import { Designer } from '../../src/designer/designer';
|
||||||
import { DocumentModel } from '../../src/document/document-model';
|
import { DocumentModel } from '../../src/document/document-model';
|
||||||
@ -46,6 +47,7 @@ describe('Host 测试', () => {
|
|||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
designer = new Designer({ editor });
|
designer = new Designer({ editor });
|
||||||
project = designer.project;
|
project = designer.project;
|
||||||
|
designer.createComponentMeta(pageMetadata);
|
||||||
doc = project.createDocument(formSchema);
|
doc = project.createDocument(formSchema);
|
||||||
host = new BuiltinSimulatorHost(designer.project);
|
host = new BuiltinSimulatorHost(designer.project);
|
||||||
});
|
});
|
||||||
@ -373,6 +375,14 @@ describe('Host 测试', () => {
|
|||||||
},
|
},
|
||||||
})).toBeNull();
|
})).toBeNull();
|
||||||
});
|
});
|
||||||
|
it('notFoundComponent', () => {
|
||||||
|
expect(host.locate({
|
||||||
|
dragObject: {
|
||||||
|
type: DragObjectType.Node,
|
||||||
|
nodes: [doc.getNode('form')],
|
||||||
|
},
|
||||||
|
})).toBeUndefined();
|
||||||
|
})
|
||||||
it('locate', () => {
|
it('locate', () => {
|
||||||
host.locate({
|
host.locate({
|
||||||
dragObject: {
|
dragObject: {
|
||||||
|
|||||||
@ -137,6 +137,10 @@ const VALID_ENGINE_OPTIONS = {
|
|||||||
type: 'boolean',
|
type: 'boolean',
|
||||||
description: 'JSExpression 是否只支持使用 this 来访问上下文变量',
|
description: 'JSExpression 是否只支持使用 this 来访问上下文变量',
|
||||||
},
|
},
|
||||||
|
enableStrictNotFoundMode: {
|
||||||
|
type: 'boolean',
|
||||||
|
description: '当开启组件未找到严格模式时,渲染模块不会默认给一个容器组件',
|
||||||
|
},
|
||||||
};
|
};
|
||||||
export interface EngineOptions {
|
export interface EngineOptions {
|
||||||
/**
|
/**
|
||||||
@ -258,6 +262,12 @@ export interface EngineOptions {
|
|||||||
* JSExpression 是否只支持使用 this 来访问上下文变量,假如需要兼容原来的 'state.xxx',则设置为 false
|
* JSExpression 是否只支持使用 this 来访问上下文变量,假如需要兼容原来的 'state.xxx',则设置为 false
|
||||||
*/
|
*/
|
||||||
thisRequiredInJSE?: boolean;
|
thisRequiredInJSE?: boolean;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @default false
|
||||||
|
* 当开启组件未找到严格模式时,渲染模块不会默认给一个容器组件
|
||||||
|
*/
|
||||||
|
enableStrictNotFoundMode?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
const getStrictModeValue = (engineOptions: EngineOptions, defaultValue: boolean): boolean => {
|
const getStrictModeValue = (engineOptions: EngineOptions, defaultValue: boolean): boolean => {
|
||||||
|
|||||||
@ -12,7 +12,9 @@
|
|||||||
|
|
||||||
[![NPM version][npm-image]][npm-url] [![NPM downloads][download-image]][download-url]
|
[![NPM version][npm-image]][npm-url] [![NPM downloads][download-image]][download-url]
|
||||||
|
|
||||||
[![][issues-helper-image]][issues-helper-url] [![Issues need help][help-wanted-image]][help-wanted-url]
|
[![][issues-helper-image]][issues-helper-url] [![Issues need help][help-wanted-image]][help-wanted-url]
|
||||||
|
|
||||||
|
[![codecov][codecov-image-url]][codecov-url]
|
||||||
|
|
||||||
[npm-image]: https://img.shields.io/npm/v/@alilc/lowcode-engine.svg?style=flat-square
|
[npm-image]: https://img.shields.io/npm/v/@alilc/lowcode-engine.svg?style=flat-square
|
||||||
[npm-url]: http://npmjs.org/package/@alilc/lowcode-engine
|
[npm-url]: http://npmjs.org/package/@alilc/lowcode-engine
|
||||||
@ -25,6 +27,9 @@
|
|||||||
[issues-helper-image]: https://img.shields.io/badge/using-issues--helper-orange?style=flat-square
|
[issues-helper-image]: https://img.shields.io/badge/using-issues--helper-orange?style=flat-square
|
||||||
[issues-helper-url]: https://github.com/actions-cool/issues-helper
|
[issues-helper-url]: https://github.com/actions-cool/issues-helper
|
||||||
|
|
||||||
|
[codecov-image-url]: https://codecov.io/gh/alibaba/lowcode-engine/branch/main/graph/badge.svg
|
||||||
|
[codecov-url]: https://codecov.io/gh/alibaba/lowcode-engine
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
[](https://lowcode-engine.cn)
|
[](https://lowcode-engine.cn)
|
||||||
|
|||||||
@ -14,6 +14,8 @@ An enterprise-class low-code technology stack with scale-out design
|
|||||||
|
|
||||||
[![][issues-helper-image]][issues-helper-url] [![Issues need help][help-wanted-image]][help-wanted-url]
|
[![][issues-helper-image]][issues-helper-url] [![Issues need help][help-wanted-image]][help-wanted-url]
|
||||||
|
|
||||||
|
[![codecov][codecov-image-url]][codecov-url]
|
||||||
|
|
||||||
[npm-image]: https://img.shields.io/npm/v/@alilc/lowcode-engine.svg?style=flat-square
|
[npm-image]: https://img.shields.io/npm/v/@alilc/lowcode-engine.svg?style=flat-square
|
||||||
[npm-url]: http://npmjs.org/package/@alilc/lowcode-engine
|
[npm-url]: http://npmjs.org/package/@alilc/lowcode-engine
|
||||||
|
|
||||||
@ -25,6 +27,9 @@ An enterprise-class low-code technology stack with scale-out design
|
|||||||
[issues-helper-image]: https://img.shields.io/badge/using-issues--helper-orange?style=flat-square
|
[issues-helper-image]: https://img.shields.io/badge/using-issues--helper-orange?style=flat-square
|
||||||
[issues-helper-url]: https://github.com/actions-cool/issues-helper
|
[issues-helper-url]: https://github.com/actions-cool/issues-helper
|
||||||
|
|
||||||
|
[codecov-image-url]: https://codecov.io/gh/alibaba/lowcode-engine/branch/main/graph/badge.svg
|
||||||
|
[codecov-url]: https://codecov.io/gh/alibaba/lowcode-engine
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
[](http://lowcode-engine.cn)
|
[](http://lowcode-engine.cn)
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
import { createElement } from 'react';
|
import { createElement } from 'react';
|
||||||
import { render } from 'react-dom';
|
import { render, unmountComponentAtNode } from 'react-dom';
|
||||||
import { globalContext, Editor, engineConfig, EngineOptions } from '@alilc/lowcode-editor-core';
|
import { globalContext, Editor, engineConfig, EngineOptions } from '@alilc/lowcode-editor-core';
|
||||||
import {
|
import {
|
||||||
Designer,
|
Designer,
|
||||||
@ -16,7 +16,7 @@ import {
|
|||||||
|
|
||||||
import Outline, { OutlineBackupPane, getTreeMaster } from '@alilc/lowcode-plugin-outline-pane';
|
import Outline, { OutlineBackupPane, getTreeMaster } from '@alilc/lowcode-plugin-outline-pane';
|
||||||
import DesignerPlugin from '@alilc/lowcode-plugin-designer';
|
import DesignerPlugin from '@alilc/lowcode-plugin-designer';
|
||||||
import { Hotkey, Project, Skeleton, Setters, Material, Event } from '@alilc/lowcode-shell';
|
import { Hotkey, Project, Skeleton, Setters, Material, Event, DocumentModel } from '@alilc/lowcode-shell';
|
||||||
import { getLogger, isPlainObject } from '@alilc/lowcode-utils';
|
import { getLogger, isPlainObject } from '@alilc/lowcode-utils';
|
||||||
import './modules/live-editing';
|
import './modules/live-editing';
|
||||||
import utils from './modules/utils';
|
import utils from './modules/utils';
|
||||||
@ -184,7 +184,8 @@ engineConfig.set('isOpenSource', isOpenSource);
|
|||||||
await plugins.register(defaultPanelRegistry);
|
await plugins.register(defaultPanelRegistry);
|
||||||
})();
|
})();
|
||||||
|
|
||||||
let engineInited = false;
|
// container which will host LowCodeEngine DOM
|
||||||
|
let engineContainer: HTMLElement;
|
||||||
// @ts-ignore webpack Define variable
|
// @ts-ignore webpack Define variable
|
||||||
export const version = VERSION_PLACEHOLDER;
|
export const version = VERSION_PLACEHOLDER;
|
||||||
engineConfig.set('ENGINE_VERSION', version);
|
engineConfig.set('ENGINE_VERSION', version);
|
||||||
@ -193,23 +194,22 @@ export async function init(
|
|||||||
options?: EngineOptions,
|
options?: EngineOptions,
|
||||||
pluginPreference?: PluginPreference,
|
pluginPreference?: PluginPreference,
|
||||||
) {
|
) {
|
||||||
if (engineInited) return;
|
await destroy();
|
||||||
engineInited = true;
|
|
||||||
let engineOptions = null;
|
let engineOptions = null;
|
||||||
let engineContainer = null;
|
|
||||||
if (isPlainObject(container)) {
|
if (isPlainObject(container)) {
|
||||||
engineOptions = container;
|
engineOptions = container;
|
||||||
engineContainer = document.createElement('div');
|
engineContainer = document.createElement('div');
|
||||||
|
engineContainer.id = 'engine';
|
||||||
document.body.appendChild(engineContainer);
|
document.body.appendChild(engineContainer);
|
||||||
} else {
|
} else {
|
||||||
engineOptions = options;
|
engineOptions = options;
|
||||||
engineContainer = container;
|
engineContainer = container;
|
||||||
if (!container) {
|
if (!container) {
|
||||||
engineContainer = document.createElement('div');
|
engineContainer = document.createElement('div');
|
||||||
|
engineContainer.id = 'engine';
|
||||||
document.body.appendChild(engineContainer);
|
document.body.appendChild(engineContainer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
engineContainer.id = 'engine';
|
|
||||||
engineConfig.setEngineOptions(engineOptions as any);
|
engineConfig.setEngineOptions(engineOptions as any);
|
||||||
|
|
||||||
await plugins.init(pluginPreference as any);
|
await plugins.init(pluginPreference as any);
|
||||||
@ -222,3 +222,17 @@ export async function init(
|
|||||||
engineContainer,
|
engineContainer,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export async function destroy() {
|
||||||
|
// remove all documents
|
||||||
|
const { documents } = project;
|
||||||
|
if (Array.isArray(documents) && documents.length > 0) {
|
||||||
|
documents.forEach(((doc: DocumentModel) => project.removeDocument(doc)));
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: delete plugins except for core plugins
|
||||||
|
|
||||||
|
// unmount DOM container, this will trigger React componentWillUnmount lifeCycle,
|
||||||
|
// so necessary cleanups will be done.
|
||||||
|
engineContainer && unmountComponentAtNode(engineContainer);
|
||||||
|
}
|
||||||
|
|||||||
@ -152,7 +152,8 @@ export class OutlineMain implements ISensor, ITreeBoard, IScrollable {
|
|||||||
return canMove;
|
return canMove;
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!operationalNodes || operationalNodes.length === 0) {
|
// 如果拖拽的是 Node 才需要后面的判断,拖拽 data 不需要
|
||||||
|
if (isDragNodeObject(dragObject) && (!operationalNodes || operationalNodes.length === 0)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -17,7 +17,7 @@ export default function compFactory(schema, components = {}, componentsMap = {},
|
|||||||
const AppContext = contextFactory();
|
const AppContext = contextFactory();
|
||||||
|
|
||||||
class LNCompView extends Component {
|
class LNCompView extends Component {
|
||||||
static dislayName = 'lce-comp-factory';
|
static displayName = 'LceCompFactory';
|
||||||
|
|
||||||
static version = config.version || '0.0.0';
|
static version = config.version || '0.0.0';
|
||||||
|
|
||||||
|
|||||||
@ -538,6 +538,7 @@ export class SimulatorRendererContainer implements BuiltinSimulatorRenderer {
|
|||||||
// mock _leaf,减少性能开销
|
// mock _leaf,减少性能开销
|
||||||
const _leaf = {
|
const _leaf = {
|
||||||
isEmpty: () => false,
|
isEmpty: () => false,
|
||||||
|
isMock: true,
|
||||||
};
|
};
|
||||||
viewProps._leaf = _leaf;
|
viewProps._leaf = _leaf;
|
||||||
return createElement(Comp, viewProps, children);
|
return createElement(Comp, viewProps, children);
|
||||||
|
|||||||
@ -13,7 +13,8 @@
|
|||||||
"scripts": {
|
"scripts": {
|
||||||
"test": "build-scripts test --config build.test.json",
|
"test": "build-scripts test --config build.test.json",
|
||||||
"build": "NODE_OPTIONS=--max_old_space_size=8192 build-scripts build --skip-demo",
|
"build": "NODE_OPTIONS=--max_old_space_size=8192 build-scripts build --skip-demo",
|
||||||
"build:umd": "NODE_OPTIONS=--max_old_space_size=8192 build-scripts build --config build.umd.json"
|
"build:umd": "NODE_OPTIONS=--max_old_space_size=8192 build-scripts build --config build.umd.json",
|
||||||
|
"test:cov": "build-scripts test --config build.test.json --jest-coverage"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@alilc/lowcode-designer": "1.0.15-beta.0",
|
"@alilc/lowcode-designer": "1.0.15-beta.0",
|
||||||
|
|||||||
@ -8,7 +8,7 @@ import { getClosestNode, isFromVC, isReactComponent } from '@alilc/lowcode-utils
|
|||||||
import { GlobalEvent } from '@alilc/lowcode-types';
|
import { GlobalEvent } from '@alilc/lowcode-types';
|
||||||
import { SimulatorRendererContainer, DocumentInstance } from './renderer';
|
import { SimulatorRendererContainer, DocumentInstance } from './renderer';
|
||||||
import { host } from './host';
|
import { host } from './host';
|
||||||
|
import { isRendererDetached } from './utils/misc';
|
||||||
import './renderer.less';
|
import './renderer.less';
|
||||||
|
|
||||||
// patch cloneElement avoid lost keyProps
|
// patch cloneElement avoid lost keyProps
|
||||||
@ -170,14 +170,12 @@ class Renderer extends Component<{
|
|||||||
this.startTime = Date.now();
|
this.startTime = Date.now();
|
||||||
this.schemaChangedSymbol = false;
|
this.schemaChangedSymbol = false;
|
||||||
|
|
||||||
if (!container.autoRender) return null;
|
if (!container.autoRender || isRendererDetached()) return null;
|
||||||
return (
|
return (
|
||||||
<LowCodeRenderer
|
<LowCodeRenderer
|
||||||
locale={locale}
|
locale={locale}
|
||||||
messages={messages}
|
messages={messages}
|
||||||
schema={documentInstance.schema}
|
schema={documentInstance.schema}
|
||||||
deltaData={documentInstance.deltaData}
|
|
||||||
deltaMode={documentInstance.deltaMode}
|
|
||||||
components={container.components}
|
components={container.components}
|
||||||
appHelper={container.context}
|
appHelper={container.context}
|
||||||
designMode={designMode}
|
designMode={designMode}
|
||||||
@ -257,6 +255,7 @@ class Renderer extends Component<{
|
|||||||
onCompGetRef={(schema: any, ref: ReactInstance | null) => {
|
onCompGetRef={(schema: any, ref: ReactInstance | null) => {
|
||||||
documentInstance.mountInstance(schema.id, ref);
|
documentInstance.mountInstance(schema.id, ref);
|
||||||
}}
|
}}
|
||||||
|
enableStrictNotFoundMode={host.enableStrictNotFoundMode}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -51,24 +51,6 @@ export class DocumentInstance {
|
|||||||
return this._components;
|
return this._components;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 本次的变更数据
|
|
||||||
*/
|
|
||||||
@obx.ref private _deltaData: any = {};
|
|
||||||
|
|
||||||
@computed get deltaData(): any {
|
|
||||||
return this._deltaData;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 是否使用增量模式
|
|
||||||
*/
|
|
||||||
@obx.ref private _deltaMode: boolean = false;
|
|
||||||
|
|
||||||
@computed get deltaMode(): boolean {
|
|
||||||
return this._deltaMode;
|
|
||||||
}
|
|
||||||
|
|
||||||
// context from: utils、constants、history、location、match
|
// context from: utils、constants、history、location、match
|
||||||
@obx.ref private _appContext = {};
|
@obx.ref private _appContext = {};
|
||||||
|
|
||||||
@ -116,7 +98,7 @@ export class DocumentInstance {
|
|||||||
return this.document.id;
|
return this.document.id;
|
||||||
}
|
}
|
||||||
|
|
||||||
private unmountIntance(id: string, instance: ReactInstance) {
|
private unmountInstance(id: string, instance: ReactInstance) {
|
||||||
const instances = this.instancesMap.get(id);
|
const instances = this.instancesMap.get(id);
|
||||||
if (instances) {
|
if (instances) {
|
||||||
const i = instances.indexOf(instance);
|
const i = instances.indexOf(instance);
|
||||||
@ -144,11 +126,11 @@ export class DocumentInstance {
|
|||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const unmountIntance = this.unmountIntance.bind(this);
|
const unmountInstance = this.unmountInstance.bind(this);
|
||||||
const origId = (instance as any)[SYMBOL_VNID];
|
const origId = (instance as any)[SYMBOL_VNID];
|
||||||
if (origId && origId !== id) {
|
if (origId && origId !== id) {
|
||||||
// 另外一个节点的 instance 在此被复用了,需要从原来地方卸载
|
// 另外一个节点的 instance 在此被复用了,需要从原来地方卸载
|
||||||
unmountIntance(origId, instance);
|
unmountInstance(origId, instance);
|
||||||
}
|
}
|
||||||
if (isElement(instance)) {
|
if (isElement(instance)) {
|
||||||
cacheReactKey(instance);
|
cacheReactKey(instance);
|
||||||
@ -160,7 +142,7 @@ export class DocumentInstance {
|
|||||||
}
|
}
|
||||||
// hack! delete instance from map
|
// hack! delete instance from map
|
||||||
const newUnmount = function (this: any) {
|
const newUnmount = function (this: any) {
|
||||||
unmountIntance(id, instance);
|
unmountInstance(id, instance);
|
||||||
origUnmount && origUnmount.call(this);
|
origUnmount && origUnmount.call(this);
|
||||||
};
|
};
|
||||||
(newUnmount as any).origUnmount = origUnmount;
|
(newUnmount as any).origUnmount = origUnmount;
|
||||||
@ -465,6 +447,7 @@ export class SimulatorRendererContainer implements BuiltinSimulatorRenderer {
|
|||||||
// mock _leaf,减少性能开销
|
// mock _leaf,减少性能开销
|
||||||
const _leaf = {
|
const _leaf = {
|
||||||
isEmpty: () => false,
|
isEmpty: () => false,
|
||||||
|
isMock: true,
|
||||||
};
|
};
|
||||||
viewProps._leaf = _leaf;
|
viewProps._leaf = _leaf;
|
||||||
return createElement(Comp, viewProps, children);
|
return createElement(Comp, viewProps, children);
|
||||||
|
|||||||
@ -24,3 +24,12 @@ export function getProjectUtils(librayMap: LibrayMap, utilsMetadata: UtilsMetada
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* judges if current simulator renderer deteched or not
|
||||||
|
* @returns detached or not
|
||||||
|
*/
|
||||||
|
export function isRendererDetached() {
|
||||||
|
// if current iframe detached from host document, the `window.parent` will be undefined.
|
||||||
|
return !window.parent;
|
||||||
|
}
|
||||||
@ -11,7 +11,7 @@ exports[`Base should be render NotFoundComponent 1`] = `
|
|||||||
<div
|
<div
|
||||||
componentName="Text"
|
componentName="Text"
|
||||||
>
|
>
|
||||||
Component Not Found
|
Text Component Not Found
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -32,7 +32,9 @@
|
|||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@alib/build-scripts": "^0.1.18",
|
"@alib/build-scripts": "^0.1.18",
|
||||||
|
"@alifd/next": "^1.26.0",
|
||||||
"@alilc/lowcode-designer": "1.0.15-beta.0",
|
"@alilc/lowcode-designer": "1.0.15-beta.0",
|
||||||
|
"@alilc/lowcode-designer": "1.0.14",
|
||||||
"@alilc/lowcode-test-mate": "^1.0.1",
|
"@alilc/lowcode-test-mate": "^1.0.1",
|
||||||
"@babel/plugin-transform-typescript": "^7.16.8",
|
"@babel/plugin-transform-typescript": "^7.16.8",
|
||||||
"@testing-library/react": "^11.2.2",
|
"@testing-library/react": "^11.2.2",
|
||||||
|
|||||||
@ -21,21 +21,21 @@ class Adapter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
initRuntime() {
|
initRuntime() {
|
||||||
const Component: IGeneralConstructor = class {
|
const Component: IGeneralConstructor = class <T = any, S = any> {
|
||||||
setState() {}
|
setState() {}
|
||||||
forceUpdate() {}
|
forceUpdate() {}
|
||||||
render() {}
|
render() {}
|
||||||
state: Record<string, unknown>;
|
state: Readonly<S>;
|
||||||
props: Record<string, unknown>;
|
props: Readonly<T> & Readonly<{ children?: any | undefined }>;
|
||||||
refs: Record<string, unknown>;
|
refs: Record<string, unknown>;
|
||||||
context: Record<string, unknown>;
|
context: Record<string, unknown>;
|
||||||
};
|
};
|
||||||
const PureComponent: IGeneralConstructor = class {
|
const PureComponent = class <T = any, S = any> {
|
||||||
setState() {}
|
setState() {}
|
||||||
forceUpdate() {}
|
forceUpdate() {}
|
||||||
render() {}
|
render() {}
|
||||||
state: Record<string, unknown>;
|
state: Readonly<S>;
|
||||||
props: Record<string, unknown>;
|
props: Readonly<T> & Readonly<{ children?: any | undefined }>;
|
||||||
refs: Record<string, unknown>;
|
refs: Record<string, unknown>;
|
||||||
context: Record<string, unknown>;
|
context: Record<string, unknown>;
|
||||||
};
|
};
|
||||||
|
|||||||
@ -5,7 +5,6 @@ import { EngineOptions } from '@alilc/lowcode-editor-core';
|
|||||||
import { debounce } from '../utils/common';
|
import { debounce } from '../utils/common';
|
||||||
import adapter from '../adapter';
|
import adapter from '../adapter';
|
||||||
import * as types from '../types/index';
|
import * as types from '../types/index';
|
||||||
import { parseData } from '../utils';
|
|
||||||
|
|
||||||
export interface IComponentHocInfo {
|
export interface IComponentHocInfo {
|
||||||
schema: any;
|
schema: any;
|
||||||
@ -363,12 +362,12 @@ export function leafWrapper(Comp: types.IBaseRenderComponent, {
|
|||||||
};
|
};
|
||||||
|
|
||||||
componentWillReceiveProps(nextProps: any) {
|
componentWillReceiveProps(nextProps: any) {
|
||||||
let { _leaf, componentId } = nextProps;
|
let { componentId } = nextProps;
|
||||||
if (nextProps.__tag === this.props.__tag) {
|
if (nextProps.__tag === this.props.__tag) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
_leaf = _leaf || getNode?.(componentId);
|
const _leaf = getNode?.(componentId);
|
||||||
if (_leaf && this.curEventLeaf && _leaf !== this.curEventLeaf) {
|
if (_leaf && this.curEventLeaf && _leaf !== this.curEventLeaf) {
|
||||||
this.disposeFunctions.forEach((fn) => fn());
|
this.disposeFunctions.forEach((fn) => fn());
|
||||||
this.disposeFunctions = [];
|
this.disposeFunctions = [];
|
||||||
@ -514,7 +513,12 @@ export function leafWrapper(Comp: types.IBaseRenderComponent, {
|
|||||||
}
|
}
|
||||||
|
|
||||||
get leaf(): Node | undefined {
|
get leaf(): Node | undefined {
|
||||||
return this.props._leaf || getNode?.(componentCacheId);
|
if (this.props._leaf?.isMock) {
|
||||||
|
// 低代码组件作为一个整体更新,其内部的组件不需要监听相关事件
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
return getNode?.(componentCacheId);
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
|
|||||||
@ -6,7 +6,7 @@ import { IRendererAppHelper, IBaseRendererProps, IBaseRenderComponent } from '..
|
|||||||
export default function addonRendererFactory(): IBaseRenderComponent {
|
export default function addonRendererFactory(): IBaseRenderComponent {
|
||||||
const BaseRenderer = baseRendererFactory();
|
const BaseRenderer = baseRendererFactory();
|
||||||
return class AddonRenderer extends BaseRenderer {
|
return class AddonRenderer extends BaseRenderer {
|
||||||
static dislayName = 'addon-renderer';
|
static displayName = 'AddonRenderer';
|
||||||
|
|
||||||
__namespace = 'addon';
|
__namespace = 'addon';
|
||||||
|
|
||||||
@ -69,7 +69,7 @@ export default function addonRendererFactory(): IBaseRenderComponent {
|
|||||||
return '插件 schema 结构异常!';
|
return '插件 schema 结构异常!';
|
||||||
}
|
}
|
||||||
|
|
||||||
this.__debug(`${AddonRenderer.dislayName} render - ${__schema.fileName}`);
|
this.__debug(`${AddonRenderer.displayName} render - ${__schema.fileName}`);
|
||||||
this.__generateCtx({
|
this.__generateCtx({
|
||||||
component: this,
|
component: this,
|
||||||
});
|
});
|
||||||
|
|||||||
@ -104,13 +104,7 @@ export default function baseRendererFactory(): IBaseRenderComponent {
|
|||||||
return customBaseRenderer;
|
return customBaseRenderer;
|
||||||
}
|
}
|
||||||
|
|
||||||
const runtime = adapter.getRuntime();
|
const { Component, createElement } = adapter.getRuntime();
|
||||||
const Component = runtime.Component as IGeneralConstructor<
|
|
||||||
IBaseRendererProps,
|
|
||||||
Record<string, any>,
|
|
||||||
any
|
|
||||||
>;
|
|
||||||
const { createElement } = runtime;
|
|
||||||
const Div = divFactory();
|
const Div = divFactory();
|
||||||
const VisualDom = visualDomFactory();
|
const VisualDom = visualDomFactory();
|
||||||
const AppContext = contextFactory();
|
const AppContext = contextFactory();
|
||||||
@ -125,8 +119,8 @@ export default function baseRendererFactory(): IBaseRenderComponent {
|
|||||||
const DEFAULT_LOOP_ARG_INDEX = 'index';
|
const DEFAULT_LOOP_ARG_INDEX = 'index';
|
||||||
let scopeIdx = 0;
|
let scopeIdx = 0;
|
||||||
|
|
||||||
return class BaseRenderer extends Component {
|
return class BaseRenderer extends Component<IBaseRendererProps, Record<string, any>> {
|
||||||
static displayName = 'base-renderer';
|
static displayName = 'BaseRenderer';
|
||||||
|
|
||||||
static defaultProps = {
|
static defaultProps = {
|
||||||
__schema: {},
|
__schema: {},
|
||||||
@ -533,6 +527,10 @@ export default function baseRendererFactory(): IBaseRenderComponent {
|
|||||||
{
|
{
|
||||||
componentName: schema.componentName,
|
componentName: schema.componentName,
|
||||||
componentId: schema.id,
|
componentId: schema.id,
|
||||||
|
enableStrictNotFoundMode: engine.props.enableStrictNotFoundMode,
|
||||||
|
ref: (ref: any) => {
|
||||||
|
ref && engine.props?.onCompGetRef(schema, ref);
|
||||||
|
},
|
||||||
},
|
},
|
||||||
this.__getSchemaChildrenVirtualDom(schema, scope, Comp),
|
this.__getSchemaChildrenVirtualDom(schema, scope, Comp),
|
||||||
);
|
);
|
||||||
|
|||||||
@ -4,7 +4,7 @@ import { IBaseRendererProps, IBaseRenderComponent } from '../types';
|
|||||||
export default function blockRendererFactory(): IBaseRenderComponent {
|
export default function blockRendererFactory(): IBaseRenderComponent {
|
||||||
const BaseRenderer = baseRendererFactory();
|
const BaseRenderer = baseRendererFactory();
|
||||||
return class BlockRenderer extends BaseRenderer {
|
return class BlockRenderer extends BaseRenderer {
|
||||||
static dislayName = 'block-renderer';
|
static displayName = 'BlockRenderer';
|
||||||
|
|
||||||
__namespace = 'block';
|
__namespace = 'block';
|
||||||
|
|
||||||
@ -23,7 +23,7 @@ export default function blockRendererFactory(): IBaseRenderComponent {
|
|||||||
return '区块 schema 结构异常!';
|
return '区块 schema 结构异常!';
|
||||||
}
|
}
|
||||||
|
|
||||||
this.__debug(`${BlockRenderer.dislayName} render - ${__schema?.fileName}`);
|
this.__debug(`${BlockRenderer.displayName} render - ${__schema?.fileName}`);
|
||||||
this.__generateCtx({});
|
this.__generateCtx({});
|
||||||
this.__render();
|
this.__render();
|
||||||
|
|
||||||
|
|||||||
@ -4,7 +4,7 @@ import { IBaseRendererProps, IBaseRenderComponent } from '../types';
|
|||||||
export default function componentRendererFactory(): IBaseRenderComponent {
|
export default function componentRendererFactory(): IBaseRenderComponent {
|
||||||
const BaseRenderer = baseRendererFactory();
|
const BaseRenderer = baseRendererFactory();
|
||||||
return class CompRenderer extends BaseRenderer {
|
return class CompRenderer extends BaseRenderer {
|
||||||
static dislayName = 'comp-renderer';
|
static displayName = 'CompRenderer';
|
||||||
|
|
||||||
__namespace = 'component';
|
__namespace = 'component';
|
||||||
|
|
||||||
@ -23,7 +23,7 @@ export default function componentRendererFactory(): IBaseRenderComponent {
|
|||||||
if (this.__checkSchema(__schema)) {
|
if (this.__checkSchema(__schema)) {
|
||||||
return '自定义组件 schema 结构异常!';
|
return '自定义组件 schema 结构异常!';
|
||||||
}
|
}
|
||||||
this.__debug(`${CompRenderer.dislayName} render - ${__schema.fileName}`);
|
this.__debug(`${CompRenderer.displayName} render - ${__schema.fileName}`);
|
||||||
|
|
||||||
this.__generateCtx({
|
this.__generateCtx({
|
||||||
component: this,
|
component: this,
|
||||||
|
|||||||
@ -4,7 +4,7 @@ import { IBaseRendererProps, IBaseRenderComponent } from '../types';
|
|||||||
export default function pageRendererFactory(): IBaseRenderComponent {
|
export default function pageRendererFactory(): IBaseRenderComponent {
|
||||||
const BaseRenderer = baseRendererFactory();
|
const BaseRenderer = baseRendererFactory();
|
||||||
return class PageRenderer extends BaseRenderer {
|
return class PageRenderer extends BaseRenderer {
|
||||||
static dislayName = 'page-renderer';
|
static displayName = 'PageRenderer';
|
||||||
|
|
||||||
__namespace = 'page';
|
__namespace = 'page';
|
||||||
|
|
||||||
@ -34,7 +34,7 @@ export default function pageRendererFactory(): IBaseRenderComponent {
|
|||||||
if (this.__checkSchema(__schema)) {
|
if (this.__checkSchema(__schema)) {
|
||||||
return '页面schema结构异常!';
|
return '页面schema结构异常!';
|
||||||
}
|
}
|
||||||
this.__debug(`${PageRenderer.dislayName} render - ${__schema.fileName}`);
|
this.__debug(`${PageRenderer.displayName} render - ${__schema.fileName}`);
|
||||||
|
|
||||||
this.__bindCustomMethods(this.props);
|
this.__bindCustomMethods(this.props);
|
||||||
this.__initDataSource(this.props);
|
this.__initDataSource(this.props);
|
||||||
|
|||||||
@ -4,14 +4,11 @@ import contextFactory from '../context';
|
|||||||
import { isFileSchema, isEmpty } from '../utils';
|
import { isFileSchema, isEmpty } from '../utils';
|
||||||
import baseRendererFactory from './base';
|
import baseRendererFactory from './base';
|
||||||
import divFactory from '../components/Div';
|
import divFactory from '../components/Div';
|
||||||
import { IGeneralConstructor, IRenderComponent, IRendererProps, IRendererState } from '../types';
|
import { IRenderComponent, IRendererProps, IRendererState } from '../types';
|
||||||
import { RootSchema } from '@alilc/lowcode-types';
|
import { NodeSchema, RootSchema } from '@alilc/lowcode-types';
|
||||||
|
|
||||||
export default function rendererFactory(): IRenderComponent {
|
export default function rendererFactory(): IRenderComponent {
|
||||||
const runtime = adapter.getRuntime();
|
const { PureComponent, Component, createElement, findDOMNode } = adapter.getRuntime();
|
||||||
const Component = runtime.Component as IGeneralConstructor<IRendererProps, Record<string, any>>;
|
|
||||||
const PureComponent = runtime.PureComponent as IGeneralConstructor<IRendererProps, Record<string, any>>;
|
|
||||||
const { createElement, findDOMNode } = runtime;
|
|
||||||
const RENDERER_COMPS: any = adapter.getRenderers();
|
const RENDERER_COMPS: any = adapter.getRenderers();
|
||||||
const BaseRenderer = baseRendererFactory();
|
const BaseRenderer = baseRendererFactory();
|
||||||
const AppContext = contextFactory();
|
const AppContext = contextFactory();
|
||||||
@ -21,7 +18,7 @@ export default function rendererFactory(): IRenderComponent {
|
|||||||
|
|
||||||
const debug = Debug('renderer:entry');
|
const debug = Debug('renderer:entry');
|
||||||
|
|
||||||
class FaultComponent extends PureComponent {
|
class FaultComponent extends PureComponent<NodeSchema> {
|
||||||
render() {
|
render() {
|
||||||
// FIXME: errorlog
|
// FIXME: errorlog
|
||||||
console.error('render error', this.props);
|
console.error('render error', this.props);
|
||||||
@ -35,18 +32,23 @@ export default function rendererFactory(): IRenderComponent {
|
|||||||
color: '#ff0000',
|
color: '#ff0000',
|
||||||
border: '2px solid #ff0000',
|
border: '2px solid #ff0000',
|
||||||
},
|
},
|
||||||
}, '组件渲染异常,请查看控制台日志');
|
}, `${this.props.componentName || ''} 组件渲染异常,请查看控制台日志`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class NotFoundComponent extends PureComponent {
|
class NotFoundComponent extends PureComponent<{
|
||||||
|
componentName: string;
|
||||||
|
} & IRendererProps> {
|
||||||
render() {
|
render() {
|
||||||
return createElement(Div, this.props, this.props.children || 'Component Not Found');
|
if (this.props.enableStrictNotFoundMode) {
|
||||||
|
return `${this.props.componentName || ''} Component Not Found`;
|
||||||
|
}
|
||||||
|
return createElement(Div, this.props, this.props.children || `${this.props.componentName || ''} Component Not Found`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return class Renderer extends Component {
|
return class Renderer extends Component<IRendererProps> {
|
||||||
static dislayName = 'renderer';
|
static displayName = 'Renderer';
|
||||||
|
|
||||||
state: Partial<IRendererState> = {};
|
state: Partial<IRendererState> = {};
|
||||||
|
|
||||||
|
|||||||
@ -5,7 +5,7 @@ export default function tempRendererFactory(): IBaseRenderComponent {
|
|||||||
const BaseRenderer = baseRendererFactory();
|
const BaseRenderer = baseRendererFactory();
|
||||||
|
|
||||||
return class TempRenderer extends BaseRenderer {
|
return class TempRenderer extends BaseRenderer {
|
||||||
static dislayName = 'temp-renderer';
|
static displayName = 'TempRenderer';
|
||||||
|
|
||||||
__namespace = 'temp';
|
__namespace = 'temp';
|
||||||
|
|
||||||
@ -51,7 +51,7 @@ export default function tempRendererFactory(): IBaseRenderComponent {
|
|||||||
return '下钻编辑 schema 结构异常!';
|
return '下钻编辑 schema 结构异常!';
|
||||||
}
|
}
|
||||||
|
|
||||||
this.__debug(`${TempRenderer.dislayName} render - ${__schema?.fileName}`);
|
this.__debug(`${TempRenderer.displayName} render - ${__schema?.fileName}`);
|
||||||
|
|
||||||
return this.__renderContent(this.__renderContextProvider({ __ctx }));
|
return this.__renderContent(this.__renderContextProvider({ __ctx }));
|
||||||
}
|
}
|
||||||
|
|||||||
@ -21,12 +21,12 @@ interface IGeneralComponent<P = {}, S = {}, SS = any> extends ComponentLifecycle
|
|||||||
}
|
}
|
||||||
|
|
||||||
export type IGeneralConstructor<
|
export type IGeneralConstructor<
|
||||||
P = {
|
T = {
|
||||||
[key: string]: any;
|
[key: string]: any;
|
||||||
}, S = {
|
}, S = {
|
||||||
[key: string]: any;
|
[key: string]: any;
|
||||||
}, SS = any
|
}, D = any
|
||||||
> = new (props: any, context: any) => IGeneralComponent<P, S, SS>;
|
> = new <TT = T, SS = S, DD = D>(props: TT, context: any) => IGeneralComponent<TT, SS, DD>;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* duck-typed History
|
* duck-typed History
|
||||||
@ -133,6 +133,11 @@ export interface IRendererProps {
|
|||||||
* JSExpression 是否只支持使用 this 来访问上下文变量
|
* JSExpression 是否只支持使用 this 来访问上下文变量
|
||||||
*/
|
*/
|
||||||
thisRequiredInJSE?: boolean;
|
thisRequiredInJSE?: boolean;
|
||||||
|
/**
|
||||||
|
* @default false
|
||||||
|
* 当开启组件未找到严格模式时,渲染模块不会默认给一个容器组件
|
||||||
|
*/
|
||||||
|
enableStrictNotFoundMode?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface IRendererState {
|
export interface IRendererState {
|
||||||
@ -288,7 +293,7 @@ export interface IRenderComponent {
|
|||||||
getNotFoundComponent(): any;
|
getNotFoundComponent(): any;
|
||||||
getFaultComponent(): any;
|
getFaultComponent(): any;
|
||||||
};
|
};
|
||||||
dislayName: string;
|
displayName: string;
|
||||||
defaultProps: IRendererProps;
|
defaultProps: IRendererProps;
|
||||||
findDOMNode: (...args: any) => any;
|
findDOMNode: (...args: any) => any;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -18,7 +18,9 @@ exports[`children this.props.children is array 1`] = `
|
|||||||
exports[`lifecycle leaf change and make componentWillReceiveProps 1`] = `
|
exports[`lifecycle leaf change and make componentWillReceiveProps 1`] = `
|
||||||
<div>
|
<div>
|
||||||
<div
|
<div
|
||||||
|
__id="text6"
|
||||||
__tag="222"
|
__tag="222"
|
||||||
|
componentId="text6"
|
||||||
content="content new leaf"
|
content="content new leaf"
|
||||||
>
|
>
|
||||||
content new leaf
|
content new leaf
|
||||||
|
|||||||
@ -193,9 +193,10 @@ describe('lifecycle', () => {
|
|||||||
|
|
||||||
it('leaf change and make componentWillReceiveProps', () => {
|
it('leaf change and make componentWillReceiveProps', () => {
|
||||||
const newTextNodeLeaf = new Node(textSchema);
|
const newTextNodeLeaf = new Node(textSchema);
|
||||||
|
nodeMap.set(textSchema.id, newTextNodeLeaf);
|
||||||
component.update((
|
component.update((
|
||||||
<Div _leaf={DivNode}>
|
<Div _leaf={DivNode}>
|
||||||
<Text _leaf={newTextNodeLeaf} __tag="222" content="content 123"></Text>
|
<Text componentId={textSchema.id} __tag="222" content="content 123"></Text>
|
||||||
</Div>
|
</Div>
|
||||||
));
|
));
|
||||||
|
|
||||||
@ -232,6 +233,9 @@ describe('mini unit render', () => {
|
|||||||
parent: MiniRenderDivNode,
|
parent: MiniRenderDivNode,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
nodeMap.set(miniRenderSchema.id, MiniRenderDivNode);
|
||||||
|
nodeMap.set(textSchema.id, TextNode);
|
||||||
|
|
||||||
component = renderer.create(
|
component = renderer.create(
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
<MiniRenderDiv _leaf={MiniRenderDivNode}>
|
<MiniRenderDiv _leaf={MiniRenderDivNode}>
|
||||||
@ -277,6 +281,8 @@ describe('mini unit render', () => {
|
|||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
nodeMap.set(textSchema.id, TextNode);
|
||||||
|
|
||||||
renderer.create(
|
renderer.create(
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
<div>
|
<div>
|
||||||
@ -319,6 +325,8 @@ describe('mini unit render', () => {
|
|||||||
isRoot: true,
|
isRoot: true,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
nodeMap.set(textSchema.id, TextNode);
|
||||||
|
|
||||||
const component = renderer.create(
|
const component = renderer.create(
|
||||||
<Text _leaf={TextNode} content="content"></Text>
|
<Text _leaf={TextNode} content="content"></Text>
|
||||||
);
|
);
|
||||||
@ -351,6 +359,8 @@ describe('mini unit render', () => {
|
|||||||
})
|
})
|
||||||
});
|
});
|
||||||
|
|
||||||
|
nodeMap.set(textSchema.id, TextNode);
|
||||||
|
|
||||||
const component = renderer.create(
|
const component = renderer.create(
|
||||||
<Text _leaf={TextNode} content="content"></Text>
|
<Text _leaf={TextNode} content="content"></Text>
|
||||||
);
|
);
|
||||||
@ -370,7 +380,9 @@ describe('mini unit render', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('parent is a mock leaf', () => {
|
it('parent is a mock leaf', () => {
|
||||||
const MiniRenderDivNode = {};
|
const MiniRenderDivNode = {
|
||||||
|
isMock: true,
|
||||||
|
};
|
||||||
|
|
||||||
const component = renderer.create(
|
const component = renderer.create(
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
@ -409,6 +421,9 @@ describe('mini unit render', () => {
|
|||||||
hasLoop: true,
|
hasLoop: true,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
nodeMap.set(textSchema.id, TextNode);
|
||||||
|
nodeMap.set(miniRenderSchema.id, MiniRenderDivNode);
|
||||||
|
|
||||||
component = renderer.create(
|
component = renderer.create(
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
<MiniRenderDiv _leaf={MiniRenderDivNode}>
|
<MiniRenderDiv _leaf={MiniRenderDivNode}>
|
||||||
|
|||||||
@ -1,7 +1,8 @@
|
|||||||
import {
|
import {
|
||||||
BuiltinSimulatorHost,
|
BuiltinSimulatorHost,
|
||||||
} from '@alilc/lowcode-designer';
|
} from '@alilc/lowcode-designer';
|
||||||
import { simulatorHostSymbol } from './symbols';
|
import { simulatorHostSymbol, nodeSymbol } from './symbols';
|
||||||
|
import type Node from './node';
|
||||||
|
|
||||||
export default class SimulatorHost {
|
export default class SimulatorHost {
|
||||||
private readonly [simulatorHostSymbol]: BuiltinSimulatorHost;
|
private readonly [simulatorHostSymbol]: BuiltinSimulatorHost;
|
||||||
@ -51,6 +52,14 @@ export default class SimulatorHost {
|
|||||||
return this[simulatorHostSymbol].get(key);
|
return this[simulatorHostSymbol].get(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* scroll to specific node
|
||||||
|
* @param node
|
||||||
|
*/
|
||||||
|
scrollToNode(node: Node) {
|
||||||
|
this[simulatorHostSymbol].scrollToNode(node[nodeSymbol]);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 刷新渲染画布
|
* 刷新渲染画布
|
||||||
*/
|
*/
|
||||||
|
|||||||
@ -617,8 +617,8 @@ component
|
|||||||
| screenshot | 组件快照 | String | 否 |
|
| screenshot | 组件快照 | String | 否 |
|
||||||
| icon | 组件的小图标 | String (URL) | 是 |
|
| icon | 组件的小图标 | String (URL) | 是 |
|
||||||
| tags | 组件标签 | String | 是 |
|
| tags | 组件标签 | String | 是 |
|
||||||
| keywards | 组件关键词,用于搜索联想 | String | 是 |
|
| keywords | 组件关键词,用于搜索联想 | String | 是 |
|
||||||
| devMode | 组件研发模式 | String (procode,lowcode) | 是 |
|
| devMode | 组件研发模式 | String (proCode,lowCode) | 是 |
|
||||||
| npm | npm 源引入完整描述对象 | Object | 否 |
|
| npm | npm 源引入完整描述对象 | Object | 否 |
|
||||||
| npm.package | 源码组件库名 | String | 否 |
|
| npm.package | 源码组件库名 | String | 否 |
|
||||||
| npm.exportName | 源码组件名称 | String | 否 |
|
| npm.exportName | 源码组件名称 | String | 否 |
|
||||||
@ -857,7 +857,7 @@ props 数组下对象字段描述:
|
|||||||
// 支持条件设置
|
// 支持条件设置
|
||||||
"condition": true,
|
"condition": true,
|
||||||
// 支持样式设置
|
// 支持样式设置
|
||||||
"styles": true,
|
"style": true,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user