mirror of
https://github.com/alibaba/lowcode-engine.git
synced 2026-03-06 10:27:22 +00:00
chore: 临时提交
This commit is contained in:
parent
3ef5b7ff41
commit
344c0113a2
@ -39,7 +39,7 @@ export class Detecting {
|
||||
}
|
||||
}
|
||||
|
||||
release(node: Node) {
|
||||
release(node: Node | null) {
|
||||
if (this._current === node) {
|
||||
this._current = null;
|
||||
this.emitter.emit(DETECTING_CHANGE_EVENT, this.current);
|
||||
@ -52,7 +52,7 @@ export class Detecting {
|
||||
}
|
||||
}
|
||||
|
||||
onDetectingChange(fn: () => void) {
|
||||
onDetectingChange(fn: (node: Node) => void) {
|
||||
this.emitter.on(DETECTING_CHANGE_EVENT, fn);
|
||||
return () => {
|
||||
this.emitter.off(DETECTING_CHANGE_EVENT, fn);
|
||||
|
||||
@ -161,7 +161,7 @@ export class Selection {
|
||||
return nodes;
|
||||
}
|
||||
|
||||
onSelectionChange(fn: () => void): () => void {
|
||||
onSelectionChange(fn: (ids: string[]) => void): () => void {
|
||||
this.emitter.on('selectionchange', fn);
|
||||
return () => {
|
||||
this.emitter.removeListener('selectionchange', fn);
|
||||
|
||||
@ -1,53 +1,50 @@
|
||||
import { Editor, Hotkey, hotkey, getSetter, registerSetter, getSettersMap, engineConfig, EngineConfig } from '@ali/lowcode-editor-core';
|
||||
import { Skeleton } from '@ali/lowcode-editor-skeleton';
|
||||
import { ILowCodePluginConfig, ILowCodePluginManager, ILowCodePluginContext, IDesignerCabin } from './plugin-types';
|
||||
import { getLogger, Logger } from '../utils';
|
||||
import { Editor, engineConfig } from '@ali/lowcode-editor-core';
|
||||
import { Designer } from '@ali/lowcode-designer';
|
||||
import { Skeleton as InnerSkeleton } from '@ali/lowcode-editor-skeleton';
|
||||
import {
|
||||
registerMetadataTransducer,
|
||||
addBuiltinComponentAction,
|
||||
removeBuiltinComponentAction,
|
||||
} from '../component-meta';
|
||||
import { Designer } from '../designer';
|
||||
import { Setters, Utils, utils } from '../types';
|
||||
Hotkey,
|
||||
Project,
|
||||
Skeleton,
|
||||
Setters,
|
||||
Material,
|
||||
editorSymbol,
|
||||
designerSymbol,
|
||||
skeletonSymbol,
|
||||
} from '@ali/lowcode-shell';
|
||||
import { getLogger, Logger } from '../utils/logger';
|
||||
import { ILowCodePluginContext } from './plugin-types';
|
||||
|
||||
/**
|
||||
* 一些 API 设计约定:
|
||||
* 1. 事件的命名格式为:on[Will|Did]VerbNoun?,参考 https://code.visualstudio.com/api/references/vscode-api#events
|
||||
* 2. 基于 Disposable 模式,对于事件的绑定、快捷键的绑定函数,返回值则是解绑函数
|
||||
*/
|
||||
export default class PluginContext implements ILowCodePluginContext {
|
||||
editor: Editor;
|
||||
skeleton: Skeleton;
|
||||
designer: Designer;
|
||||
hotkey: Hotkey;
|
||||
logger: Logger;
|
||||
plugins: ILowCodePluginManager;
|
||||
designerCabin: IDesignerCabin;
|
||||
setters: Setters;
|
||||
utils: Utils;
|
||||
engineConfig: EngineConfig;
|
||||
private readonly [editorSymbol]: Editor;
|
||||
private readonly [designerSymbol]: Designer;
|
||||
private readonly [skeletonSymbol]: InnerSkeleton;
|
||||
public hotkey: Hotkey;
|
||||
public project: Project;
|
||||
public skeleton: Skeleton;
|
||||
public logger: Logger;
|
||||
public setters: Setters;
|
||||
public material: Material;
|
||||
|
||||
constructor(editor: Editor, plugins: ILowCodePluginManager) {
|
||||
this.editor = editor;
|
||||
this.designer = editor.get('designer')!;
|
||||
this.skeleton = editor.get('skeleton')!;
|
||||
this.hotkey = hotkey;
|
||||
this.plugins = plugins;
|
||||
this.designerCabin = this.createDesignerCabin();
|
||||
this.setters = {
|
||||
getSetter,
|
||||
registerSetter,
|
||||
getSettersMap,
|
||||
};
|
||||
this.engineConfig = engineConfig;
|
||||
this.utils = utils;
|
||||
}
|
||||
constructor(editor: Editor) {
|
||||
this[editorSymbol] = editor;
|
||||
const designer = this[designerSymbol] = editor.get('designer')!;
|
||||
const skeleton = this[skeletonSymbol] = editor.get('skeleton')!;
|
||||
|
||||
private createDesignerCabin(): IDesignerCabin {
|
||||
return {
|
||||
registerMetadataTransducer,
|
||||
addBuiltinComponentAction,
|
||||
removeBuiltinComponentAction,
|
||||
};
|
||||
}
|
||||
|
||||
setLogger(config: ILowCodePluginConfig): void {
|
||||
this.logger = getLogger({ level: 'log', bizName: `designer:plugin:${config.name}` });
|
||||
// TODO: to be deleted
|
||||
// this.editor = editor;
|
||||
const project = designer.project;
|
||||
this.hotkey = new Hotkey();
|
||||
this.project = new Project(project);
|
||||
this.skeleton = new Skeleton(skeleton);
|
||||
this.setters = new Setters();
|
||||
this.material = new Material(editor);
|
||||
this.config = engineConfig;
|
||||
// TODO: pluginName
|
||||
this.logger = getLogger({ level: 'warn', bizName: 'designer:plugin:' });
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -18,19 +18,24 @@ export class LowCodePluginManager implements ILowCodePluginManager {
|
||||
this.editor = editor;
|
||||
}
|
||||
|
||||
private _getLowCodePluginContext() {
|
||||
return new LowCodePluginContext(this.editor, this);
|
||||
private _getLowCodePluginContext(config: any) {
|
||||
return new LowCodePluginContext(this.editor, config);
|
||||
}
|
||||
|
||||
// private getNewContext(config: any) {
|
||||
// return new LowCodePluginContext2(this.editor, config);
|
||||
// }
|
||||
|
||||
async register(
|
||||
pluginConfigCreator: (ctx: ILowCodePluginContext, pluginOptions?: any) => ILowCodePluginConfig,
|
||||
pluginOptions?: any,
|
||||
options?: LowCodeRegisterOptions,
|
||||
): Promise<void> {
|
||||
const ctx = this._getLowCodePluginContext();
|
||||
const ctx = this._getLowCodePluginContext({ name: pluginConfigCreator.pluginName });
|
||||
// ctx.newCtx = this.getNewContext();
|
||||
const config = pluginConfigCreator(ctx, pluginOptions);
|
||||
invariant(config.name, `${config.name} required`, config);
|
||||
ctx.setLogger(config);
|
||||
// ctx.setLogger(config);
|
||||
const allowOverride = options?.override === true;
|
||||
if (this.pluginsMap.has(config.name)) {
|
||||
if (!allowOverride) {
|
||||
|
||||
@ -46,15 +46,16 @@ export interface IDesignerCabin {
|
||||
|
||||
export interface ILowCodePluginContext {
|
||||
skeleton: Skeleton;
|
||||
designer: Designer;
|
||||
editor: Editor;
|
||||
// designer: Designer;
|
||||
// editor: Editor;
|
||||
hotkey: Hotkey;
|
||||
logger: Logger;
|
||||
plugins: ILowCodePluginManager;
|
||||
designerCabin: IDesignerCabin;
|
||||
// plugins: ILowCodePluginManager;
|
||||
// designerCabin: IDesignerCabin;
|
||||
setters: Setters;
|
||||
utils: Utils;
|
||||
// utils: Utils;
|
||||
engineConfig: EngineConfig;
|
||||
material: any;
|
||||
}
|
||||
|
||||
interface ILowCodePluginManagerPluginAccessor {
|
||||
|
||||
@ -192,6 +192,10 @@ export class Project {
|
||||
return this.documents.find(doc => doc.id === id) || null;
|
||||
}
|
||||
|
||||
getDocumentByFileName(fileName: string): DocumentModel | null {
|
||||
return this.documents.find(doc => doc.fileName === fileName) || null;
|
||||
}
|
||||
|
||||
@action
|
||||
createDocument(data?: RootSchema): DocumentModel {
|
||||
const doc = new DocumentModel(this, data || this?.data?.componentsTree?.[0]);
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
import { isEqual } from 'lodash';
|
||||
import { globalContext } from './di';
|
||||
import { Editor } from './editor';
|
||||
|
||||
@ -385,6 +386,21 @@ export class Hotkey {
|
||||
return this;
|
||||
}
|
||||
|
||||
unbind(combos: string[] | string, callback: HotkeyCallback, action?: string) {
|
||||
const combinations = Array.isArray(combos) ? combos : [combos];
|
||||
|
||||
combinations.forEach(combination => {
|
||||
const info: KeyInfo = getKeyInfo(combination, action);
|
||||
const { key, modifiers } = info;
|
||||
const idx = this.callBacks[key].findIndex(info => {
|
||||
return isEqual(info.modifiers, modifiers) && info.callback === callback;
|
||||
});
|
||||
if (idx !== -1) {
|
||||
this.callBacks[key].splice(idx, 1);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* resets all sequence counters except for the ones passed in
|
||||
*/
|
||||
|
||||
@ -51,14 +51,14 @@ const setters: Setters = {
|
||||
export {
|
||||
editor,
|
||||
editorCabin,
|
||||
skeleton,
|
||||
// skeleton,
|
||||
skeletonCabin,
|
||||
designer,
|
||||
designerCabin,
|
||||
plugins,
|
||||
setters,
|
||||
// setters,
|
||||
project,
|
||||
selection,
|
||||
// selection,
|
||||
/**
|
||||
* 注册一些全局的切面
|
||||
*/
|
||||
@ -67,10 +67,10 @@ export {
|
||||
* 全局的一些数据存储
|
||||
*/
|
||||
// store,
|
||||
hotkey,
|
||||
// hotkey,
|
||||
monitor,
|
||||
utils,
|
||||
engineConfig,
|
||||
// engineConfig,
|
||||
};
|
||||
|
||||
const getSelection = () => designer.currentDocument?.selection;
|
||||
@ -78,16 +78,16 @@ const getSelection = () => designer.currentDocument?.selection;
|
||||
(window as any).AliLowCodeEngine = {
|
||||
editor,
|
||||
editorCabin,
|
||||
skeleton,
|
||||
// skeleton,
|
||||
skeletonCabin,
|
||||
designer,
|
||||
designerCabin,
|
||||
plugins,
|
||||
setters,
|
||||
// setters,
|
||||
project,
|
||||
get selection() {
|
||||
return getSelection();
|
||||
},
|
||||
// get selection() {
|
||||
// return getSelection();
|
||||
// },
|
||||
/**
|
||||
* 注册一些全局的切面
|
||||
*/
|
||||
@ -96,11 +96,11 @@ const getSelection = () => designer.currentDocument?.selection;
|
||||
* 全局的一些数据存储
|
||||
*/
|
||||
// store,
|
||||
hotkey,
|
||||
// hotkey,
|
||||
monitor,
|
||||
init,
|
||||
utils,
|
||||
engineConfig,
|
||||
// engineConfig,
|
||||
};
|
||||
|
||||
// 处理 editor.set('assets'),将组件元数据创建好
|
||||
|
||||
@ -11,7 +11,7 @@ export default class TreeNode {
|
||||
/**
|
||||
* 是否可以展开
|
||||
*/
|
||||
@computed get expandable(): boolean {
|
||||
get expandable(): boolean {
|
||||
if (this.locked) return false;
|
||||
return this.hasChildren() || this.hasSlots() || this.dropDetail?.index != null;
|
||||
}
|
||||
|
||||
5
packages/shell/build.json
Normal file
5
packages/shell/build.json
Normal file
@ -0,0 +1,5 @@
|
||||
{
|
||||
"plugins": [
|
||||
"build-plugin-component"
|
||||
]
|
||||
}
|
||||
6
packages/shell/build.test.json
Normal file
6
packages/shell/build.test.json
Normal file
@ -0,0 +1,6 @@
|
||||
{
|
||||
"plugins": [
|
||||
"build-plugin-component",
|
||||
"@ali/lowcode-test-mate/plugin/index.ts"
|
||||
]
|
||||
}
|
||||
55
packages/shell/package.json
Normal file
55
packages/shell/package.json
Normal file
@ -0,0 +1,55 @@
|
||||
{
|
||||
"name": "@ali/lowcode-shell",
|
||||
"version": "1.0.74",
|
||||
"description": "Shell Layer for AliLowCodeEngine",
|
||||
"main": "lib/index.js",
|
||||
"module": "es/index.js",
|
||||
"files": [
|
||||
"lib",
|
||||
"es"
|
||||
],
|
||||
"scripts": {
|
||||
"build": "build-scripts build --skip-demo",
|
||||
"test": "build-scripts test --config build.test.json",
|
||||
"test:cov": "build-scripts test --config build.test.json --jest-coverage"
|
||||
},
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@ali/lowcode-editor-core": "1.0.74",
|
||||
"@ali/lowcode-editor-skeleton": "1.0.74",
|
||||
"@ali/lowcode-types": "1.0.74",
|
||||
"@ali/lowcode-utils": "1.0.74",
|
||||
"classnames": "^2.2.6",
|
||||
"enzyme": "^3.11.0",
|
||||
"enzyme-adapter-react-16": "^1.15.5",
|
||||
"react": "^16",
|
||||
"react-dom": "^16.7.0",
|
||||
"zen-logger": "^1.1.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@ali/lowcode-test-mate": "^1.0.1",
|
||||
"@alib/build-scripts": "^0.1.29",
|
||||
"@testing-library/react": "^11.2.2",
|
||||
"@types/classnames": "^2.2.7",
|
||||
"@types/jest": "^26.0.16",
|
||||
"@types/lodash": "^4.14.165",
|
||||
"@types/medium-editor": "^5.0.3",
|
||||
"@types/node": "^13.7.1",
|
||||
"@types/react": "^16",
|
||||
"@types/react-dom": "^16",
|
||||
"babel-jest": "^26.5.2",
|
||||
"build-plugin-component": "^0.2.10",
|
||||
"build-scripts-config": "^0.1.8",
|
||||
"jest": "^26.6.3",
|
||||
"lodash": "^4.17.20",
|
||||
"moment": "^2.29.1",
|
||||
"typescript": "^4.0.3"
|
||||
},
|
||||
"publishConfig": {
|
||||
"registry": "https://registry.antfin-inc.com"
|
||||
},
|
||||
"resolutions": {
|
||||
"@builder/babel-preset-ice": "1.0.1"
|
||||
},
|
||||
"gitHead": "19b2119b9f95f8a3da0851b3943774a770975991"
|
||||
}
|
||||
27
packages/shell/src/detecting.ts
Normal file
27
packages/shell/src/detecting.ts
Normal file
@ -0,0 +1,27 @@
|
||||
import {
|
||||
Detecting as InnerDetecting,
|
||||
DocumentModel as InnerDocumentModel,
|
||||
} from '@ali/lowcode-designer';
|
||||
import { documentSymbol, detectingSymbol } from './symbols';
|
||||
|
||||
export default class Detecting {
|
||||
private readonly [documentSymbol]: InnerDocumentModel;
|
||||
private readonly [detectingSymbol]: InnerDetecting;
|
||||
|
||||
constructor(document: InnerDocumentModel) {
|
||||
this[documentSymbol] = document;
|
||||
this[detectingSymbol] = document.designer.detecting;
|
||||
}
|
||||
|
||||
capture(id: string) {
|
||||
this[detectingSymbol].capture(this[documentSymbol].getNode(id));
|
||||
}
|
||||
|
||||
release(id: string) {
|
||||
this[detectingSymbol].release(this[documentSymbol].getNode(id));
|
||||
}
|
||||
|
||||
leave() {
|
||||
this[detectingSymbol].leave(this[documentSymbol]);
|
||||
}
|
||||
}
|
||||
164
packages/shell/src/document-model.ts
Normal file
164
packages/shell/src/document-model.ts
Normal file
@ -0,0 +1,164 @@
|
||||
import { Editor } from '@ali/lowcode-editor-core';
|
||||
import {
|
||||
DocumentModel as InnerDocumentModel,
|
||||
Node as InnerNode,
|
||||
ParentalNode,
|
||||
IOnChangeOptions as InnerIOnChangeOptions,
|
||||
PropChangeOptions as InnerPropChangeOptions,
|
||||
} from '@ali/lowcode-designer';
|
||||
import { TransformStage, RootSchema, NodeSchema, NodeData, GlobalEvent } from '@ali/lowcode-types';
|
||||
import Node from './node';
|
||||
import Selection from './selection';
|
||||
import Detecting from './detecting';
|
||||
import History from './history';
|
||||
import Project from './project';
|
||||
import Prop from './prop';
|
||||
import { documentSymbol, editorSymbol } from './symbols';
|
||||
|
||||
type IOnChangeOptions = {
|
||||
type: string;
|
||||
node: Node;
|
||||
};
|
||||
|
||||
type PropChangeOptions = {
|
||||
key?: string | number;
|
||||
prop?: Prop;
|
||||
node: Node;
|
||||
newValue: any;
|
||||
oldValue: any;
|
||||
};
|
||||
|
||||
export default class DocumentModel {
|
||||
private readonly [documentSymbol]: InnerDocumentModel;
|
||||
private readonly [editorSymbol]: Editor;
|
||||
public selection: Selection;
|
||||
public detecting: Detecting;
|
||||
public history: History;
|
||||
|
||||
constructor(document: InnerDocumentModel) {
|
||||
this[documentSymbol] = document;
|
||||
this[editorSymbol] = document.designer.editor as Editor;
|
||||
this.selection = new Selection(document);
|
||||
this.detecting = new Detecting(document);
|
||||
this.history = new History(document);
|
||||
}
|
||||
|
||||
static create(document: InnerDocumentModel | undefined | null) {
|
||||
if (document == undefined) return null;
|
||||
return new DocumentModel(document);
|
||||
}
|
||||
|
||||
getProject() {
|
||||
return Project.create(this[documentSymbol].project);
|
||||
}
|
||||
|
||||
getRoot() {
|
||||
return Node.create(this[documentSymbol].getRoot());
|
||||
}
|
||||
|
||||
getNodesMap() {
|
||||
const map = new Map<string, Node>();
|
||||
for (let id in this[documentSymbol].nodesMap.keys()) {
|
||||
map.set(id, this.getNodeById(id)!);
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
||||
getNodeById(nodeId: string) {
|
||||
return Node.create(this[documentSymbol].getNode(nodeId));
|
||||
}
|
||||
|
||||
importSchema(schema: RootSchema) {
|
||||
this[documentSymbol].import(schema);
|
||||
}
|
||||
|
||||
exportSchema(stage?: TransformStage) {
|
||||
return this[documentSymbol].export(stage);
|
||||
}
|
||||
|
||||
insertNode(
|
||||
parent: ParentalNode<NodeSchema>,
|
||||
thing: InnerNode<NodeSchema> | NodeData,
|
||||
at?: number | null | undefined,
|
||||
copy?: boolean | undefined,
|
||||
) {
|
||||
const node = this[documentSymbol].insertNode(parent, thing, at, copy);
|
||||
return Node.create(node);
|
||||
}
|
||||
|
||||
removeNode(idOrNode: string | InnerNode<NodeSchema>) {
|
||||
this[documentSymbol].removeNode(idOrNode);
|
||||
}
|
||||
|
||||
/**
|
||||
* 当前 document 新增节点事件
|
||||
*/
|
||||
onAddNode(fn: (node: Node) => void) {
|
||||
this[documentSymbol].onNodeCreate((node: InnerNode) => {
|
||||
fn(Node.create(node)!);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 当前 document 删除节点事件
|
||||
*/
|
||||
onRemoveNode(fn: (node: Node) => void) {
|
||||
this[documentSymbol].onNodeDestroy((node: InnerNode) => {
|
||||
fn(Node.create(node)!);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 当前 document 的 hover 变更事件
|
||||
*/
|
||||
onChangeDetecting(fn: (node: Node) => void) {
|
||||
this[documentSymbol].designer.detecting.onDetectingChange((node: InnerNode) => {
|
||||
fn(Node.create(node)!);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 当前 document 的选中变更事件
|
||||
*/
|
||||
onChangeSelection(fn: (ids: string[]) => void) {
|
||||
this[documentSymbol].selection.onSelectionChange((ids: string[]) => {
|
||||
fn(ids);
|
||||
});
|
||||
}
|
||||
|
||||
onChangeNodeVisible(fn: (node: Node, visible: boolean) => void) {
|
||||
// TODO: history 变化时需要重新绑定
|
||||
this[documentSymbol].nodesMap.forEach((node) => {
|
||||
node.onVisibleChange((flag: boolean) => {
|
||||
fn(Node.create(node)!, flag);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
onChangeNodeChildren(fn: (info?: IOnChangeOptions) => void) {
|
||||
// TODO: history 变化时需要重新绑定
|
||||
this[documentSymbol].nodesMap.forEach((node) => {
|
||||
node.onChildrenChange((info?: InnerIOnChangeOptions) => {
|
||||
return info ? fn({
|
||||
type: info.type,
|
||||
node: Node.create(node)!,
|
||||
}) : fn();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 当前 document 节点属性修改事件
|
||||
*/
|
||||
onChangeNodeProp(fn: (info: PropChangeOptions) => void) {
|
||||
this[editorSymbol].on(GlobalEvent.Node.Prop.InnerChange, (info: GlobalEvent.Node.Prop.ChangeOptions) => {
|
||||
fn({
|
||||
key: info.key,
|
||||
oldValue: info.oldValue,
|
||||
newValue: info.newValue,
|
||||
prop: Prop.create(info.prop)!,
|
||||
node: Node.create(info.node as any)!,
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
3
packages/shell/src/dragon.ts
Normal file
3
packages/shell/src/dragon.ts
Normal file
@ -0,0 +1,3 @@
|
||||
export default class Dragon {
|
||||
|
||||
}
|
||||
3
packages/shell/src/event.ts
Normal file
3
packages/shell/src/event.ts
Normal file
@ -0,0 +1,3 @@
|
||||
export default class Event {
|
||||
|
||||
}
|
||||
44
packages/shell/src/history.ts
Normal file
44
packages/shell/src/history.ts
Normal file
@ -0,0 +1,44 @@
|
||||
import { History as InnerHistory, DocumentModel as InnerDocumentModel } from '@ali/lowcode-designer';
|
||||
import { documentSymbol, historySymbol } from './symbols';
|
||||
|
||||
export default class History {
|
||||
private readonly [documentSymbol]: InnerDocumentModel;
|
||||
private readonly [historySymbol]: InnerHistory;
|
||||
|
||||
constructor(document: InnerDocumentModel) {
|
||||
this[documentSymbol] = document;
|
||||
this[historySymbol] = this[documentSymbol].getHistory();
|
||||
}
|
||||
|
||||
go(cursor: number) {
|
||||
this[historySymbol].go(cursor);
|
||||
}
|
||||
|
||||
back() {
|
||||
this[historySymbol].back();
|
||||
}
|
||||
|
||||
forward() {
|
||||
this[historySymbol].forward();
|
||||
}
|
||||
|
||||
savePoint() {
|
||||
this[historySymbol].savePoint();
|
||||
}
|
||||
|
||||
isSavePoint() {
|
||||
return this[historySymbol].isSavePoint();
|
||||
}
|
||||
|
||||
getState() {
|
||||
return this[historySymbol].getState();
|
||||
}
|
||||
|
||||
onChangeState(func: () => any) {
|
||||
return this[historySymbol].onStateChange(func);
|
||||
}
|
||||
|
||||
onChangeCursor(func: () => any) {
|
||||
return this[historySymbol].onCursor(func);
|
||||
}
|
||||
}
|
||||
11
packages/shell/src/hotkey.ts
Normal file
11
packages/shell/src/hotkey.ts
Normal file
@ -0,0 +1,11 @@
|
||||
import { hotkey, HotkeyCallback } from '@ali/lowcode-editor-core';
|
||||
import { Disposable } from '@ali/lowcode-types';
|
||||
|
||||
export default class Hotkey {
|
||||
bind(combos: string[] | string, callback: HotkeyCallback, action?: string): Disposable {
|
||||
hotkey.bind(combos, callback, action);
|
||||
return () => {
|
||||
hotkey.unbind(combos, callback, action);
|
||||
};
|
||||
}
|
||||
}
|
||||
30
packages/shell/src/index.ts
Normal file
30
packages/shell/src/index.ts
Normal file
@ -0,0 +1,30 @@
|
||||
import Detecting from './detecting';
|
||||
// import Dragon from './dragon';
|
||||
import DocumentModel from './document-model';
|
||||
import Event from './event';
|
||||
import History from './history';
|
||||
import Material from './material';
|
||||
import Node from './node';
|
||||
import Project from './project';
|
||||
import Prop from './prop';
|
||||
import Selection from './selection';
|
||||
import Setters from './setters';
|
||||
import Hotkey from './hotkey';
|
||||
import Skeleton from './skeleton';
|
||||
export * from './symbols';
|
||||
|
||||
export {
|
||||
DocumentModel,
|
||||
Detecting,
|
||||
// Dragon,
|
||||
Event,
|
||||
History,
|
||||
Material,
|
||||
Node,
|
||||
Project,
|
||||
Prop,
|
||||
Selection,
|
||||
Setters,
|
||||
Hotkey,
|
||||
Skeleton,
|
||||
};
|
||||
67
packages/shell/src/material.ts
Normal file
67
packages/shell/src/material.ts
Normal file
@ -0,0 +1,67 @@
|
||||
import { Editor } from '@ali/lowcode-editor-core';
|
||||
import {
|
||||
Designer,
|
||||
registerMetadataTransducer,
|
||||
MetadataTransducer,
|
||||
getRegisteredMetadataTransducers,
|
||||
addBuiltinComponentAction,
|
||||
removeBuiltinComponentAction,
|
||||
modifyBuiltinComponentAction,
|
||||
} from '@ali/lowcode-designer';
|
||||
import { AssetsJson } from '@ali/lowcode-utils';
|
||||
import { ComponentAction } from '@ali/lowcode-types';
|
||||
import { editorSymbol, designerSymbol } from './symbols';
|
||||
|
||||
export default class Material {
|
||||
private readonly [editorSymbol]: Editor;
|
||||
private readonly [designerSymbol]: Designer;
|
||||
|
||||
constructor(editor: Editor) {
|
||||
this[editorSymbol] = editor;
|
||||
this[designerSymbol] = editor.get('designer')!;
|
||||
}
|
||||
|
||||
setAssets(assets: AssetsJson) {
|
||||
return this[editorSymbol].setAssets(assets);
|
||||
}
|
||||
|
||||
getAssets() {
|
||||
return this[editorSymbol].get('assets');
|
||||
}
|
||||
|
||||
loadIncrementalAssets(incrementalAssets: AssetsJson) {
|
||||
return this[designerSymbol].loadIncrementalAssets(incrementalAssets);
|
||||
}
|
||||
|
||||
registerMetadataTransducer(
|
||||
transducer: MetadataTransducer,
|
||||
level?: number,
|
||||
id?: string | undefined,
|
||||
) {
|
||||
registerMetadataTransducer(transducer, level, id);
|
||||
}
|
||||
|
||||
getRegisteredMetadataTransducers() {
|
||||
return getRegisteredMetadataTransducers();
|
||||
}
|
||||
|
||||
getComponentMeta(componentName: string) {
|
||||
return this[designerSymbol].getComponentMeta(componentName);
|
||||
}
|
||||
|
||||
getComponentsMap() {
|
||||
return this[designerSymbol].componentsMap;
|
||||
}
|
||||
|
||||
addBuiltinComponentAction(action: ComponentAction) {
|
||||
addBuiltinComponentAction(action);
|
||||
}
|
||||
|
||||
removeBuiltinComponentAction(name: string) {
|
||||
removeBuiltinComponentAction(name);
|
||||
}
|
||||
|
||||
modifyBuiltinComponentAction(actionName: string, handle: (action: ComponentAction) => void) {
|
||||
modifyBuiltinComponentAction(actionName, handle);
|
||||
}
|
||||
}
|
||||
91
packages/shell/src/node.ts
Normal file
91
packages/shell/src/node.ts
Normal file
@ -0,0 +1,91 @@
|
||||
import {
|
||||
DocumentModel as InnerDocumentModel,
|
||||
Node as InnerNode,
|
||||
getConvertedExtraKey,
|
||||
} from '@ali/lowcode-designer';
|
||||
import { CompositeValue, NodeSchema, TransformStage } from '@ali/lowcode-types';
|
||||
import Prop from './prop';
|
||||
import DocumentModel from './document-model';
|
||||
import { documentSymbol, nodeSymbol } from './symbols';
|
||||
|
||||
export default class Node {
|
||||
private readonly [documentSymbol]: InnerDocumentModel;
|
||||
private readonly [nodeSymbol]: InnerNode;
|
||||
|
||||
constructor(node: InnerNode) {
|
||||
this[nodeSymbol] = node;
|
||||
this[documentSymbol] = node.document;
|
||||
}
|
||||
|
||||
static create(node: InnerNode | null) {
|
||||
if (!node) return null;
|
||||
return new Node(node);
|
||||
}
|
||||
|
||||
getDocumentModel() {
|
||||
return DocumentModel.create(this[documentSymbol]);
|
||||
}
|
||||
|
||||
getProp(path: string): Prop | null {
|
||||
return Prop.create(this[nodeSymbol].getProp(path));
|
||||
}
|
||||
|
||||
getPropValue(path: string) {
|
||||
return this.getProp(path)?.getValue();
|
||||
}
|
||||
|
||||
getExtraProp(path: string): Prop | null {
|
||||
return Prop.create(this[nodeSymbol].getProp(getConvertedExtraKey(path)));
|
||||
}
|
||||
|
||||
getExtraPropValue(path: string) {
|
||||
return this.getExtraProp(path)?.getValue();
|
||||
}
|
||||
|
||||
setPropValue(path: string, value: CompositeValue) {
|
||||
return this.getProp(path)?.setValue(value);
|
||||
}
|
||||
|
||||
setExtraPropValue(path: string, value: CompositeValue) {
|
||||
return this.getExtraProp(path)?.setValue(value);
|
||||
}
|
||||
|
||||
getPrevSibling() {
|
||||
return this[nodeSymbol].prevSibling;
|
||||
}
|
||||
getNextSibling() {
|
||||
return this[nodeSymbol].nextSibling;
|
||||
}
|
||||
|
||||
getParent() {
|
||||
return this[nodeSymbol].parent;
|
||||
}
|
||||
|
||||
getChildren() {
|
||||
return this[nodeSymbol].children;
|
||||
}
|
||||
|
||||
importSchema(data: NodeSchema) {
|
||||
this[nodeSymbol].import(data);
|
||||
}
|
||||
|
||||
exportSchema(stage?: TransformStage, options?: any) {
|
||||
return this[nodeSymbol].export(stage, options);
|
||||
}
|
||||
|
||||
insertBefore(node: InnerNode<NodeSchema>, ref?: InnerNode<NodeSchema> | undefined, useMutator?: boolean) {
|
||||
this[nodeSymbol].insertBefore(node, ref, useMutator);
|
||||
}
|
||||
|
||||
insertAfter(node: InnerNode<NodeSchema>, ref?: InnerNode<NodeSchema> | undefined, useMutator?: boolean) {
|
||||
this[nodeSymbol].insertAfter(node, ref, useMutator);
|
||||
}
|
||||
|
||||
replaceChild(node: InnerNode<NodeSchema>, data: any) {
|
||||
return Node.create(this[nodeSymbol].replaceChild(node, data));
|
||||
}
|
||||
|
||||
replaceWith(schema: NodeSchema) {
|
||||
this[nodeSymbol].replaceWith(schema);
|
||||
}
|
||||
}
|
||||
92
packages/shell/src/project.ts
Normal file
92
packages/shell/src/project.ts
Normal file
@ -0,0 +1,92 @@
|
||||
import { Project as InnerProject, PropsReducer, TransformStage } from '@ali/lowcode-designer';
|
||||
import { RootSchema, ProjectSchema } from '@ali/lowcode-types';
|
||||
import DocumentModel from './document-model';
|
||||
import { projectSymbol } from './symbols';
|
||||
|
||||
export default class Project {
|
||||
private readonly [projectSymbol]: InnerProject;
|
||||
|
||||
constructor(project: InnerProject) {
|
||||
this[projectSymbol] = project;
|
||||
}
|
||||
|
||||
static create(project: InnerProject) {
|
||||
return new Project(project);
|
||||
}
|
||||
|
||||
/**
|
||||
* 打开一个 document
|
||||
* @param doc
|
||||
* @returns
|
||||
*/
|
||||
openDocument(doc?: string | RootSchema | undefined) {
|
||||
const documentModel = this[projectSymbol].open(doc);
|
||||
if (!documentModel) return null;
|
||||
return DocumentModel.create(documentModel);
|
||||
}
|
||||
|
||||
createDocument(data?: RootSchema): DocumentModel | null {
|
||||
const doc = this[projectSymbol].createDocument(data);
|
||||
return DocumentModel.create(doc);
|
||||
}
|
||||
|
||||
getDocumentByFileName(fileName: string): DocumentModel | null {
|
||||
return DocumentModel.create(this[projectSymbol].getDocumentByFileName(fileName));
|
||||
}
|
||||
|
||||
getDocumentById(id: string): DocumentModel | null {
|
||||
return DocumentModel.create(this[projectSymbol].getDocument(id));
|
||||
}
|
||||
|
||||
getDocuments(): DocumentModel[] {
|
||||
return this[projectSymbol].documents.map((doc) => DocumentModel.create(doc)!);
|
||||
}
|
||||
|
||||
exportSchema() {
|
||||
return this[projectSymbol].getSchema();
|
||||
}
|
||||
|
||||
importSchema(schema?: ProjectSchema) {
|
||||
this[projectSymbol].load(schema, true);
|
||||
}
|
||||
|
||||
getCurrentDocument(): DocumentModel | null {
|
||||
return DocumentModel.create(this[projectSymbol].currentDocument);
|
||||
}
|
||||
|
||||
addPropsTransducer(reducer: PropsReducer, stage: TransformStage) {
|
||||
this[projectSymbol].designer.addPropsReducer(reducer, stage);
|
||||
}
|
||||
|
||||
/**
|
||||
* 当前 project 内的 document 变更事件
|
||||
*/
|
||||
onChangeDocument(fn: (doc: DocumentModel) => void) {
|
||||
// TODO: 思考一下是否要实现补偿触发能力
|
||||
return this[projectSymbol].onCurrentDocumentChange((originalDoc) => {
|
||||
fn(DocumentModel.create(originalDoc)!);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 当前 project 的模拟器 ready 事件
|
||||
*/
|
||||
onSimulatorReady(fn: () => void) {
|
||||
// TODO: 补充 simulator 实例
|
||||
// TODO: 思考一下是否要实现补偿触发能力
|
||||
return this[projectSymbol].onSimulatorReady(() => {
|
||||
fn();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 当前 project 的渲染器 ready 事件
|
||||
*/
|
||||
onRendererReady(fn: () => void) {
|
||||
// TODO: 补充 renderer 实例
|
||||
// TODO: 思考一下是否要实现补偿触发能力
|
||||
return this[projectSymbol].onRendererReady(() => {
|
||||
fn();
|
||||
});
|
||||
}
|
||||
}
|
||||
31
packages/shell/src/prop.ts
Normal file
31
packages/shell/src/prop.ts
Normal file
@ -0,0 +1,31 @@
|
||||
import { Prop as InnerProp } from '@ali/lowcode-designer';
|
||||
import { CompositeValue } from '@ali/lowcode-types';
|
||||
import { propSymbol } from './symbols';
|
||||
import Node from './node';
|
||||
|
||||
export default class Prop {
|
||||
private readonly [propSymbol]: InnerProp;
|
||||
|
||||
constructor(prop: InnerProp) {
|
||||
this[propSymbol] = prop;
|
||||
}
|
||||
|
||||
static create(prop: InnerProp | undefined | null) {
|
||||
if (!prop) return null;
|
||||
return new Prop(prop);
|
||||
}
|
||||
|
||||
getNode() {
|
||||
return Node.create(this[propSymbol].getNode());
|
||||
}
|
||||
|
||||
setValue(val: CompositeValue) {
|
||||
this[propSymbol].setValue(val);
|
||||
}
|
||||
|
||||
getValue() {
|
||||
return this[propSymbol].getValue();
|
||||
}
|
||||
|
||||
exportSchema() {}
|
||||
}
|
||||
49
packages/shell/src/selection.ts
Normal file
49
packages/shell/src/selection.ts
Normal file
@ -0,0 +1,49 @@
|
||||
import {
|
||||
DocumentModel as InnerDocumentModel,
|
||||
Node as InnerNode,
|
||||
Selection as InnerSelection,
|
||||
} from '@ali/lowcode-designer';
|
||||
import Node from './node';
|
||||
import { documentSymbol, selectionSymbol } from './symbols';
|
||||
|
||||
export default class Selection {
|
||||
private readonly [documentSymbol]: InnerDocumentModel;
|
||||
private readonly [selectionSymbol]: InnerSelection;
|
||||
|
||||
constructor(document: InnerDocumentModel) {
|
||||
this[documentSymbol] = document;
|
||||
this[selectionSymbol] = document.selection;
|
||||
}
|
||||
|
||||
select(id: string) {
|
||||
this[selectionSymbol].select(id);
|
||||
}
|
||||
|
||||
selectAll(ids: string[]) {
|
||||
this[selectionSymbol].selectAll(ids);
|
||||
}
|
||||
|
||||
getSelected() {
|
||||
return this[selectionSymbol].selected;
|
||||
}
|
||||
|
||||
remove(id: string) {
|
||||
this[selectionSymbol].remove(id);
|
||||
}
|
||||
|
||||
clear() {
|
||||
this[selectionSymbol].clear();
|
||||
}
|
||||
|
||||
has(id: string) {
|
||||
return this[selectionSymbol].has(id);
|
||||
}
|
||||
|
||||
add(id: string) {
|
||||
this[selectionSymbol].add(id);
|
||||
}
|
||||
|
||||
getNodes() {
|
||||
return this[selectionSymbol].getNodes().map((node: InnerNode) => Node.create(node));
|
||||
}
|
||||
}
|
||||
19
packages/shell/src/setters.ts
Normal file
19
packages/shell/src/setters.ts
Normal file
@ -0,0 +1,19 @@
|
||||
import { getSetter, registerSetter, getSettersMap, RegisteredSetter } from '@ali/lowcode-editor-core';
|
||||
import { CustomView } from '@ali/lowcode-types';
|
||||
|
||||
export default class Setters {
|
||||
getSetter(type: string) {
|
||||
return getSetter(type);
|
||||
}
|
||||
|
||||
getSettersMap() {
|
||||
return getSettersMap();
|
||||
}
|
||||
|
||||
registerSetter(
|
||||
typeOrMaps: string | { [key: string]: CustomView | RegisteredSetter },
|
||||
setter?: CustomView | RegisteredSetter | undefined,
|
||||
) {
|
||||
return registerSetter(typeOrMaps, setter);
|
||||
}
|
||||
}
|
||||
55
packages/shell/src/skeleton.ts
Normal file
55
packages/shell/src/skeleton.ts
Normal file
@ -0,0 +1,55 @@
|
||||
import {
|
||||
Skeleton as InnerSkeleton,
|
||||
IWidgetBaseConfig,
|
||||
IWidgetConfigArea,
|
||||
} from '@ali/lowcode-editor-skeleton';
|
||||
import { skeletonSymbol } from './symbols';
|
||||
|
||||
export default class Skeleton {
|
||||
private readonly [skeletonSymbol]: InnerSkeleton;
|
||||
|
||||
constructor(skeleton: InnerSkeleton) {
|
||||
this[skeletonSymbol] = skeleton;
|
||||
}
|
||||
|
||||
add(config: IWidgetBaseConfig, extraConfig?: Record<string, any>) {
|
||||
return this[skeletonSymbol].add(config, extraConfig);
|
||||
}
|
||||
|
||||
remove(config: IWidgetBaseConfig) {
|
||||
const { area, name } = config;
|
||||
const skeleton = this[skeletonSymbol];
|
||||
if (!normalizeArea(area)) return;
|
||||
skeleton[normalizeArea(area)!].container.remove(name);
|
||||
}
|
||||
}
|
||||
|
||||
function normalizeArea(area: IWidgetConfigArea | undefined) {
|
||||
switch (area) {
|
||||
case 'leftArea':
|
||||
case 'left':
|
||||
return 'leftArea';
|
||||
case 'rightArea':
|
||||
case 'right':
|
||||
return 'rightArea';
|
||||
case 'topArea':
|
||||
case 'top':
|
||||
return 'topArea';
|
||||
case 'toolbar':
|
||||
return 'toolbar';
|
||||
case 'mainArea':
|
||||
case 'main':
|
||||
case 'center':
|
||||
case 'centerArea':
|
||||
return 'mainArea';
|
||||
case 'bottomArea':
|
||||
case 'bottom':
|
||||
return 'bottomArea';
|
||||
case 'leftFixedArea':
|
||||
return 'leftFixedArea';
|
||||
case 'leftFloatArea':
|
||||
return 'leftFloatArea';
|
||||
case 'stages':
|
||||
return 'stages';
|
||||
}
|
||||
}
|
||||
14
packages/shell/src/symbols.ts
Normal file
14
packages/shell/src/symbols.ts
Normal file
@ -0,0 +1,14 @@
|
||||
/**
|
||||
* 以下 symbol 均用于在 plugin context 对外暴露的模型中存储相应内部模型的 key
|
||||
*/
|
||||
export const projectSymbol = Symbol('project');
|
||||
export const designerSymbol = Symbol('designer');
|
||||
export const skeletonSymbol = Symbol('skeleton');
|
||||
export const documentSymbol = Symbol('document');
|
||||
export const editorSymbol = Symbol('editor');
|
||||
export const nodeSymbol = Symbol('node');
|
||||
export const propsSymbol = Symbol('props');
|
||||
export const propSymbol = Symbol('prop');
|
||||
export const detectingSymbol = Symbol('detecting');
|
||||
export const selectionSymbol = Symbol('selection');
|
||||
export const historySymbol = Symbol('history');
|
||||
3
packages/types/src/disposable.ts
Normal file
3
packages/types/src/disposable.ts
Normal file
@ -0,0 +1,3 @@
|
||||
export interface Disposable {
|
||||
(): void;
|
||||
}
|
||||
@ -20,3 +20,4 @@ export * from './code-intermediate';
|
||||
export * from './code-result';
|
||||
export * from './assets';
|
||||
export * as GlobalEvent from './event';
|
||||
export * from './disposable';
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user