fix: editor

This commit is contained in:
kangwei 2020-04-16 01:27:44 +08:00
parent c0c8760936
commit ccd916287f
3 changed files with 105 additions and 40 deletions

View File

@ -68,7 +68,7 @@ export type HooksConfig = HookConfig[];
export interface HookConfig {
message: string;
type: 'on' | 'once';
handler: (editor: Editor, ...args: []) => void;
handler: (editor: Editor, ...args: any[]) => void;
}
export type ShortCutsConfig = ShortCutConfig[];

View File

@ -70,39 +70,41 @@ export interface HooksFuncs {
}
export default class Editor extends EventEmitter {
public static getInstance = (config: EditorConfig, components: PluginClassSet, utils?: Utils): Editor => {
static getInstance = (config: EditorConfig, components: PluginClassSet, utils?: Utils): Editor => {
if (!instance) {
instance = new Editor(config, components, utils);
}
return instance;
};
public config: EditorConfig;
private _components?: PluginClassSet;
get components(): PluginClassSet {
if (!this._components) {
this._components = {};
Object.keys(this.componentsMap).forEach((key) => {
(this._components as any)[key] = pluginFactory(this.componentsMap[key]);
});
}
return this._components;
}
public components: PluginClassSet;
readonly utils: Utils;
public utils: Utils;
pluginStatus?: PluginStatusSet;
public pluginStatus: PluginStatusSet;
plugins?: PluginSet;
public plugins: PluginSet;
locale?: LocaleType;
public locale: LocaleType;
hooksFuncs?: HooksFuncs;
private hooksFuncs: HooksFuncs;
constructor(config: EditorConfig = {}, components: PluginClassSet = {}, utils?: Utils) {
constructor(readonly config: EditorConfig = {}, readonly componentsMap: PluginClassSet = {}, utils?: Utils) {
super();
this.config = config;
this.components = {};
Object.entries(components).forEach(([key, value]): void => {
this.components[key] = pluginFactory(value);
});
this.utils = { ...editorUtils, ...utils };
this.utils = ({ ...editorUtils, ...utils } as any);
instance = this;
}
public init(): Promise<any> {
init(): Promise<any> {
const { hooks, shortCuts = [], lifeCycles } = this.config || {};
this.locale = store.get('lowcode-editor-locale') || 'zh-CN';
// this.messages = this.messagesSet[this.locale];
@ -125,7 +127,7 @@ export default class Editor extends EventEmitter {
});
}
public destroy(): void {
destroy(): void {
debug('destroy');
try {
const { hooks = [], shortCuts = [], lifeCycles = {} } = this.config;
@ -139,25 +141,26 @@ export default class Editor extends EventEmitter {
}
}
public get(key: string): any {
return this[key];
get(key: string): any {
return (this as any)[key];
}
public set(key: string | object, val: any): void {
set(key: string | object, val: any): void {
if (typeof key === 'string') {
if (['init', 'destroy', 'get', 'set', 'batchOn', 'batchOff', 'batchOnce'].includes(key)) {
console.error('init, destroy, get, set, batchOn, batchOff, batchOnce is private attribute');
return;
}
this[key] = val;
// FIXME! set to plugins, not to this
(this as any)[key] = val;
} else if (typeof key === 'object') {
Object.keys(key).forEach((item): void => {
this[item] = key[item];
(this as any)[item] = (key as any)[item];
});
}
}
public batchOn(events: string[], lisenter: (...args) => void): void {
batchOn(events: string[], lisenter: (...args: any[]) => void): void {
if (!Array.isArray(events)) {
return;
}
@ -166,7 +169,7 @@ export default class Editor extends EventEmitter {
});
}
public batchOnce(events: string[], lisenter: (...args) => void): void {
batchOnce(events: string[], lisenter: (...args: any[]) => void): void {
if (!Array.isArray(events)) {
return;
}
@ -175,7 +178,7 @@ export default class Editor extends EventEmitter {
});
}
public batchOff(events: string[], lisenter: (...args) => void): void {
batchOff(events: string[], lisenter: (...args: any[]) => void): void {
if (!Array.isArray(events)) {
return;
}
@ -187,7 +190,7 @@ export default class Editor extends EventEmitter {
// 销毁hooks中的消息监听
private destroyHooks(hooks: HooksConfig = []): void {
hooks.forEach((item, idx): void => {
if (typeof this.hooksFuncs[idx] === 'function') {
if (typeof this.hooksFuncs?.[idx] === 'function') {
this.off(item.message, this.hooksFuncs[idx]);
}
});
@ -196,8 +199,8 @@ export default class Editor extends EventEmitter {
// 初始化hooks中的消息监听
private initHooks(hooks: HooksConfig = []): void {
this.hooksFuncs = hooks.map((item): ((...arg) => void) => {
const func = (...args): void => {
this.hooksFuncs = hooks.map((item): ((...arg: any[]) => void) => {
const func = (...args: any[]): void => {
item.handler(this, ...args);
};
this[item.type](item.message, func);

View File

@ -17,6 +17,7 @@ import Widget, { isWidget, IWidget } from './widget';
import PanelDock from './panel-dock';
import Dock from './dock';
import { Stage, StageConfig } from './stage';
import { isValidElement } from 'react';
export class Skeleton {
private panels = new Map<string, Panel>();
@ -127,6 +128,50 @@ export class Skeleton {
}
return new Stage(this, config);
});
this.setupPlugins();
}
private setupPlugins() {
const { config, componentsMap } = this.editor;
const { plugins } = config;
if (!plugins) {
return;
}
Object.keys(plugins).forEach((area) => {
plugins[area].forEach(item => {
const { pluginKey, type, props = {}, pluginProps } = item;
const config: any = {
area,
type: "Widget",
name: pluginKey,
contentProps: pluginProps,
};
const { dialogProps, balloonProps, panelProps, linkProps, ...restProps } = props;
config.props = restProps;
if (dialogProps) {
config.dialogProps = dialogProps;
}
if (balloonProps) {
config.balloonProps = balloonProps;
}
if (panelProps) {
config.panelProps = panelProps;
}
if (linkProps) {
config.linkProps = linkProps;
}
if (type === 'TabPanel') {
config.type = 'Panel';
} else if (/Icon$/.test(type)) {
config.type = type.replace('Icon', 'Dock');
}
if (pluginKey in componentsMap) {
config.content = componentsMap[pluginKey];
}
this.add(config);
});
})
}
createWidget(config: IWidgetBaseConfig | IWidget) {
@ -169,26 +214,43 @@ export class Skeleton {
}
add(config: IWidgetBaseConfig & { area: string }) {
const { area } = config;
const { content, ...restConfig } = config;
if (content) {
if (typeof content === 'object' && !isValidElement(content)) {
Object.keys(content).forEach(key => {
if (/props$/i.test(key) && restConfig[key]) {
restConfig[key] = {
...restConfig[key],
...content[key],
};
} else {
restConfig[key] = content[key];
}
});
} else {
restConfig.content = content;
}
}
const { area } = restConfig;
switch (area) {
case 'leftArea': case 'left':
return this.leftArea.add(config as any);
return this.leftArea.add(restConfig as any);
case 'rightArea': case 'right':
return this.rightArea.add(config as any);
return this.rightArea.add(restConfig as any);
case 'topArea': case 'top':
return this.topArea.add(config as any);
return this.topArea.add(restConfig as any);
case 'toolbar':
return this.toolbar.add(config as any);
return this.toolbar.add(restConfig as any);
case 'mainArea': case 'main': case 'center': case 'centerArea':
return this.mainArea.add(config as any);
return this.mainArea.add(restConfig as any);
case 'bottomArea': case 'bottom':
return this.bottomArea.add(config as any);
return this.bottomArea.add(restConfig as any);
case 'leftFixedArea':
return this.leftFixedArea.add(config as any);
return this.leftFixedArea.add(restConfig as any);
case 'leftFloatArea':
return this.leftFloatArea.add(config as any);
return this.leftFloatArea.add(restConfig as any);
case 'stages':
return this.stages.add(config as any);
return this.stages.add(restConfig as any);
}
}
}