feat(vision-polyfill): support polyfill of vision package

This commit is contained in:
磬楠 2020-04-14 21:04:33 +08:00
parent ef5a72ea3d
commit 204fdfecd4
7 changed files with 530 additions and 3 deletions

View File

@ -0,0 +1,134 @@
import bus from '../bus';
import SchemaManager from './schemaManager';
import VisualDesigner from './visualDesigner';
import VisualManager from './visualManager';
import { findIndex, get, unionBy, uniqueId } from 'lodash';
export type removeEventListener = () => void;
export interface IEventNameMap {
[eventName: string]: string | symbol;
}
export interface ISchemaController {
getSchemaManager(): SchemaManager;
getSchemaManagerById(id?: string): SchemaManager;
getSchemaManagerByName(name?: string): SchemaManager[];
getSchemaManagerList(): SchemaManager[];
connectSchemaManager(manager: SchemaManager): this;
connectSchemaManagerList(managerList: SchemaManager[]): this;
notifyAllSchemaManagers(eventName: string | symbol, eventData: any): boolean;
}
export interface IManagerController {
getManager(): VisualManager;
getManagerById(id?: string): VisualManager;
getManagerByName(name?: string): VisualManager[];
getManagerList(name?: string): VisualManager[];
connectManager(manager: VisualManager): this;
connectManagerList(managerList: VisualManager[]): this;
notifyAllManagers(eventName: string | symbol, eventData: any): boolean;
}
export interface IDesignerController {
getDesigner(): VisualDesigner;
getDesignerById(id?: string): VisualDesigner;
getDesignerByName(name?: string): VisualDesigner[];
getDesignerList(): VisualDesigner[];
connectDesigner(designer: VisualDesigner): this;
connectDesignerList(designerList: VisualDesigner[]): this;
notifyAllDesigners(eventName: string | symbol, eventData: any): boolean;
}
export interface INameable {
getName(): string;
getId(): string;
setName(name?: string): this;
}
export interface IObservable {
getEventMap(): IEventNameMap;
on(eventName: string | symbol, callback: () => any): removeEventListener;
emit(eventName: string | symbol, eventData?: any[]): boolean;
}
export interface IManagerConfigs {
name?: string;
disableEvents?: boolean;
emitter?: IEmitter;
}
export interface IEmitter {
on(eventName: string | symbol, callback: () => any): removeEventListener;
emit(eventName: string | symbol, eventData?: any): boolean;
removeListener(eventName: string | symbol, callback: () => any): any;
}
export function connectGeneralManager(manager: any, managerList: any[]) {
const index = findIndex(managerList, (m) => m.getId() === manager.getId());
if (index > -1) {
managerList.push(manager);
} else {
managerList.splice(index, 1, manager);
}
return managerList;
}
export function connectGeneralManagerList(managerList: any[], sourceManagerList: any[]): any {
return unionBy(sourceManagerList, managerList, (manager) => manager.getId());
}
export class BaseManager implements INameable, IObservable {
static EVENTS: IEventNameMap = {};
static NAME = 'BaseManager';
private name: string;
private id: string;
private emitter: any;
constructor(managerConfigs: IManagerConfigs = {}) {
this.name = managerConfigs.name || get(this, 'constructor', 'NAME');
this.id = uniqueId(this.name);
if (!managerConfigs.disableEvents) {
if (managerConfigs.emitter) {
// 使用自定义的满足 EventEmitter 接口要求的自定义事件对象
this.emitter = managerConfigs.emitter;
} else {
// Bus 为单例模式
this.emitter = bus;
}
}
}
getId(): string {
return this.id;
}
setName(name: string): this {
this.name = name;
return this;
}
getName(): string {
return this.name;
}
getEventMap() {
/**
* Hack for get current constructor
* because if we write this.constructor.EVENTS
* ts compiler will show compiled error
*/
return get(this, 'constructor', BaseManager.EVENTS);
}
on(eventName: string | symbol, callback: () => any): removeEventListener {
this.emitter.on(eventName, callback);
return () => this.emitter.removeListener(eventName, callback);
}
emit(eventName: string | symbol, ...eventData: any[]): boolean {
return this.emitter.emit.call(this.emitter, eventName, ...eventData);
}
}

View File

@ -0,0 +1,44 @@
/**
* Storage the const variables
*/
/**
* Global
*/
export const VERSION = '5.3.0';
/**
* schema version defined in alibaba
*/
export const ALI_SCHEMA_VERSION = '1.0.0';
export const VE_EVENTS = {
/**
* node props to be dynamically replaced
* @event props the new props object been replaced
*/
VE_NODE_CREATED: 've.node.created',
VE_NODE_DESTROY: 've.node.destroyed',
VE_NODE_PROPS_REPLACE: 've.node.props.replaced',
// copy / clone node
VE_OVERLAY_ACTION_CLONE_NODE: 've.overlay.cloneElement',
// remove / delete node
VE_OVERLAY_ACTION_REMOVE_NODE: 've.overlay.removeElement',
// one page successfully mount on the DOM
VE_PAGE_PAGE_READY: 've.page.pageReady',
};
export const VE_HOOKS = {
// a decorator function
VE_NODE_PROPS_DECORATOR: 've.leaf.props.decorator',
// a remove callback function
VE_NODE_REMOVE_HELPER: 've.outline.actions.removeHelper',
/**
* provide customization field
*/
VE_SETTING_FIELD_PROVIDER: 've.settingField.provider',
/**
* VariableSetter for variable mode of a specified prop
*/
VE_SETTING_FIELD_VARIABLE_SETTER: 've.settingField.variableSetter',
};

View File

@ -0,0 +1,102 @@
import { cloneDeep, find } from 'lodash';
import {
BaseManager,
connectGeneralManager,
connectGeneralManagerList,
IManagerController,
ISchemaController,
} from './base';
import VisualManager from './visualManager';
export default class SchemaManager extends BaseManager implements IManagerController, ISchemaController {
private schemaData: object = {};
private visualManagerList: VisualManager[] = [];
private schemaManagerList: SchemaManager[] = [];
getManager(): VisualManager {
return this.visualManagerList[0];
}
getManagerByName(name?: string): VisualManager[] {
return this.visualManagerList.filter((m) => m.getName() === name);
}
getManagerById(id?: string): VisualManager {
return find(this.visualManagerList, (m) => m.getId() === id) as VisualManager;
}
getManagerList(): VisualManager[] {
return this.visualManagerList;
}
getSchemaManager(): SchemaManager {
return this.schemaManagerList[0];
}
getSchemaManagerById(id?: string): SchemaManager {
return find(this.schemaManagerList, (m) => m.getId() === id) as SchemaManager;
}
getSchemaManagerByName(name?: string): SchemaManager[] {
return this.schemaManagerList.filter((m) => m.getName() === name);
}
getSchemaManagerList() {
return this.schemaManagerList;
}
connectManager(manager: any) {
connectGeneralManager.call(this, manager, this.visualManagerList as any);
return this;
}
connectSchemaManager(manager: SchemaManager): this {
connectGeneralManager.call(this, manager, this.schemaManagerList);
return this;
}
connectManagerList(managerList: VisualManager[]): this {
this.visualManagerList = connectGeneralManagerList.call(this, managerList as any, this.visualManagerList as any);
return this;
}
connectSchemaManagerList(managerList: SchemaManager[]): this {
this.schemaManagerList = connectGeneralManagerList.call(this, managerList, this.schemaManagerList);
return this;
}
notifyAllManagers(eventName: string | symbol, ...eventData: any[]): boolean {
return this.visualManagerList.map((m) => m.emit(eventName, eventData)).every((r) => r);
}
notifyAllSchemaManagers(eventName: string | symbol, ...eventData: any[]): boolean {
return this.schemaManagerList.map((m) => m.emit(eventName, eventData)).every((r) => r);
}
exportSchema(): string {
try {
return JSON.stringify(this.schemaData);
} catch (e) {
throw new Error(e.message);
}
}
exportSchemaObject(): object {
return cloneDeep(this.schemaData);
}
importSchema(schemaString: string): this {
try {
this.schemaData = JSON.parse(schemaString);
return this;
} catch (e) {
throw new Error(e.message);
}
}
importSchemaObject(schema: object): this {
this.schemaData = schema;
return this;
}
}

View File

@ -0,0 +1,110 @@
import { assign, find, get } from 'lodash';
import { Component } from 'react';
import bus from '../bus';
import {
BaseManager,
connectGeneralManager,
connectGeneralManagerList,
IEmitter,
IEventNameMap,
IManagerController,
INameable,
IObservable,
} from './base';
import VisualManager from './visualManager';
interface IDesignerProps {
name?: string;
visualManagers?: VisualManager[];
emitter?: IEmitter;
}
export default class VisualDesigner extends Component implements IManagerController, IObservable, INameable {
static NAME = 'VisualDesigner';
static EVENTS: IEventNameMap = {};
props: IDesignerProps = {};
defaultProps: IDesignerProps = {
name: 'defaultDesigner',
visualManagers: [],
};
private visualManagerList: VisualManager[] = [];
private name = '';
private id = '';
private emitter: IEmitter;
constructor(props: IDesignerProps) {
super(props);
this.setName(props.name || get(this, 'constructor', 'NAME'));
this.connectManagerList(this.props.visualManagers as any);
if (props.emitter) {
// 使用自定义的满足 EventEmitter 接口要求的自定义事件对象
this.emitter = props.emitter;
} else {
this.emitter = bus;
}
}
getId(): string {
return this.id;
}
setName(name: string): this {
this.name = name;
return this;
}
getName() {
return this.name;
}
getManager(): VisualManager {
return this.visualManagerList[0];
}
getManagerByName(name?: string): VisualManager[] {
return this.visualManagerList.filter((m) => m.getName() === name);
}
getManagerById(id: string): VisualManager {
return find(this.visualManagerList, (m) => m.getId() === id) as VisualManager;
}
getManagerList(): VisualManager[] {
return this.visualManagerList;
}
connectManager(manager: VisualManager) {
connectGeneralManager.call(this, manager, this.visualManagerList);
return this;
}
connectManagerList(managerList: VisualManager[]): this {
this.visualManagerList = connectGeneralManagerList.call(this, managerList, this.visualManagerList);
return this;
}
getEventMap() {
/**
* Hack for get current constructor
* because if we write this.constructor.EVENTS
* ts compiler will show compiled error
*/
return get(this, 'constructor', BaseManager.EVENTS);
}
notifyAllManagers(eventName: string | symbol, ...eventData: any[]): boolean {
return this.visualManagerList.map((m) => m.emit(eventName, eventData)).every((r) => r);
}
on(eventName: string | symbol, callback: () => any) {
this.emitter.on(eventName, callback);
return () => this.emitter.removeListener(eventName, callback);
}
emit(eventName: string | symbol, ...eventData: any[]): boolean {
return this.emitter.emit.call(this.emitter, eventName, ...eventData);
}
}

View File

@ -0,0 +1,79 @@
import { find } from 'lodash';
import {
BaseManager,
connectGeneralManager,
connectGeneralManagerList,
IDesignerController,
IManagerController,
} from './base';
import VisualDesigner from './visualDesigner';
export default class VisualManager extends BaseManager implements IManagerController, IDesignerController {
private visualManagerList: VisualManager[] = [];
private visualDesignerList: VisualDesigner[] = [];
getManager(): VisualManager {
return this.visualManagerList[0];
}
getManagerByName(name?: string): VisualManager[] {
return this.visualManagerList.filter((m) => m.getName() === name);
}
getManagerById(id?: string): VisualManager {
return find(this.visualManagerList, (m) => m.getId() === id) as VisualManager;
}
getManagerList(): VisualManager[] {
return this.visualManagerList;
}
getDesigner(): VisualDesigner {
return this.visualDesignerList[0];
}
getDesignerByName(name?: string): VisualDesigner[] {
return this.visualDesignerList.filter((m) => m.getName() === name);
}
getDesignerById(id?: string): VisualDesigner {
return find(this.visualDesignerList, (m) => m.getId() === id) as VisualDesigner;
}
getDesignerList() {
return this.visualDesignerList;
}
connectManager(manager: VisualManager) {
connectGeneralManager.call(this, manager, this.visualManagerList);
return this;
}
connectDesigner(manager: VisualDesigner): this {
connectGeneralManager.call(this, manager, this.visualDesignerList);
return this;
}
connectManagerList(managerList: VisualManager[]): this {
this.visualManagerList = connectGeneralManagerList.call(this, managerList, this.visualManagerList);
return this;
}
connectDesignerList(managerList: VisualDesigner[]): this {
this.visualDesignerList = connectGeneralManagerList.call(this, managerList, this.visualDesignerList);
return this;
}
notifyAllManagers(eventName: string | symbol, ...eventData: any[]): boolean {
return this.getManagerList()
.map((m) => m.emit(eventName, eventData))
.every((r) => r);
}
notifyAllDesigners(eventName: string | symbol, ...eventData: any[]): boolean {
return this.getDesignerList()
.map((m) => m.emit(eventName, eventData))
.every((r) => r);
}
}

View File

@ -0,0 +1,48 @@
import { find } from 'lodash';
import { BaseManager, connectGeneralManager, connectGeneralManagerList, IManagerController } from './base';
import VisualManager from './visualManager';
export default class VisualRender extends BaseManager implements IManagerController {
private visualManagerList: VisualManager[] = [];
getManager(): VisualManager {
return this.visualManagerList[0];
}
getManagerByName(name?: string): VisualManager[] {
return this.visualManagerList.filter((m) => m.getName() === name);
}
getManagerById(id?: string): VisualManager {
return find(this.visualManagerList, (m) => m.getId() === id) as VisualManager;
}
getManagerList(): VisualManager[] {
return this.visualManagerList;
}
connectManager(manager: VisualManager) {
connectGeneralManager.call(this, manager, this.visualManagerList);
return this;
}
connectManagerList(managerList: VisualManager[]): this {
this.visualManagerList = connectGeneralManagerList.call(this, managerList, this.visualManagerList);
return this;
}
notifyAllManagers(eventName: string | symbol, ...eventData: any[]): boolean {
return this.visualManagerList.map((m) => m.emit(eventName, eventData)).every((r) => r);
}
/**
* Render function
* @override
*
* @memberof VisualRender
*/
render(): any {
return '';
}
}

View File

@ -10,6 +10,8 @@ import Skeleton from '@ali/lowcode-editor-skeleton';
import editor from './editor';
import Exchange from './exchange';
import VisualManager from './base/visualManager';
function init(container?: Element) {
if (!container) {
container = document.createElement('div');
@ -17,9 +19,12 @@ function init(container?: Element) {
}
container.id = 'engine';
render(createElement(Skeleton, {
editor,
}), container);
render(
createElement(Skeleton, {
editor,
}),
container,
);
}
const ui = {
@ -28,6 +33,10 @@ const ui = {
Popup,
};
const modules = {
VisualManager,
};
export {
/**
* VE.Popup
@ -53,4 +62,5 @@ export {
*/
init,
ui,
modules,
};