mirror of
https://github.com/alibaba/lowcode-engine.git
synced 2025-12-15 05:36:39 +00:00
debug start
This commit is contained in:
parent
a127fc8d5f
commit
5f0ac69595
@ -1,7 +1,7 @@
|
||||
// NOTE: 仅用作类型标注,切勿作为实体使用
|
||||
import { SimulatorRenderer } from '../renderer/renderer';
|
||||
import { SimulatorHost } from './host';
|
||||
import { AssetLevel, AssetList, isAssetBundle, isAssetItem, isCSSUrl, AssetType, assetItem } from '../utils/asset';
|
||||
import { AssetLevel, AssetLevels, AssetList, isAssetBundle, isAssetItem, isCSSUrl, AssetType, assetItem } from '../utils/asset';
|
||||
|
||||
export function createSimulator(host: SimulatorHost, iframe: HTMLIFrameElement, vendors: AssetList = []): Promise<SimulatorRenderer> {
|
||||
const win: any = iframe.contentWindow;
|
||||
@ -11,10 +11,9 @@ export function createSimulator(host: SimulatorHost, iframe: HTMLIFrameElement,
|
||||
|
||||
const styles: any = {};
|
||||
const scripts: any = {};
|
||||
Object.keys(AssetLevel).forEach((key) => {
|
||||
const v = (AssetLevel as any)[key];
|
||||
styles[v] = [];
|
||||
scripts[v] = [];
|
||||
AssetLevels.forEach((lv) => {
|
||||
styles[lv] = [];
|
||||
scripts[lv] = [];
|
||||
});
|
||||
|
||||
function parseAssetList(assets: AssetList, level?: AssetLevel) {
|
||||
@ -37,13 +36,13 @@ export function createSimulator(host: SimulatorHost, iframe: HTMLIFrameElement,
|
||||
}
|
||||
const id = asset.id ? ` data-id="${asset.id}"` : '';
|
||||
const lv = asset.level || level || AssetLevel.BaseDepends;
|
||||
if (asset.type === 'jsUrl') {
|
||||
if (asset.type === AssetType.JSUrl) {
|
||||
(scripts[lv] || scripts[AssetLevel.App]).push(`<script src="${asset.content}"${id}></script>`)
|
||||
} else if (asset.type === 'jsText') {
|
||||
} else if (asset.type === AssetType.JSText) {
|
||||
(scripts[lv] || scripts[AssetLevel.App]).push(`<script${id}>${asset.content}</script>`);
|
||||
} else if (asset.type === 'cssUrl') {
|
||||
} else if (asset.type === AssetType.CSSUrl) {
|
||||
(styles[lv] || styles[AssetLevel.App]).push(`<link rel="stylesheet" href="${asset.content}"${id} />`);
|
||||
} else if (asset.type === 'cssText') {
|
||||
} else if (asset.type === AssetType.CSSText) {
|
||||
(styles[lv] || styles[AssetLevel.App]).push(`<style type="text/css"${id}>${asset.content}</style>`);
|
||||
}
|
||||
}
|
||||
@ -53,10 +52,10 @@ export function createSimulator(host: SimulatorHost, iframe: HTMLIFrameElement,
|
||||
|
||||
const styleFrags = Object.keys(styles).map(key => {
|
||||
return styles[key].join('\n') + `<meta level="${key}" />`;
|
||||
});
|
||||
}).join('');
|
||||
const scriptFrags = Object.keys(scripts).map(key => {
|
||||
return styles[key].join('\n') + `<meta level="${key}" />`;
|
||||
});
|
||||
return scripts[key].join('\n');
|
||||
}).join('');
|
||||
|
||||
doc.open();
|
||||
doc.write(`<!doctype html><html><head><meta charset="utf-8"/>
|
||||
|
||||
@ -25,6 +25,7 @@ export class SimulatorHostView extends Component<SimulatorProps & {
|
||||
super(props);
|
||||
const { documentContext } = this.props;
|
||||
this.host = (documentContext.simulator as SimulatorHost) || new SimulatorHost(documentContext);
|
||||
this.host.setProps(this.props);
|
||||
}
|
||||
shouldComponentUpdate(nextProps: SimulatorProps) {
|
||||
this.host.setProps(nextProps);
|
||||
|
||||
@ -6,7 +6,7 @@ import { SimulatorRenderer } from '../renderer/renderer';
|
||||
import Node, { NodeParent } from '../../../designer/document/node/node';
|
||||
import DocumentModel from '../../../designer/document/document-model';
|
||||
import ResourceConsumer from './resource-consumer';
|
||||
import { AssetLevel, Asset, assetBundle } from '../utils/asset';
|
||||
import { AssetLevel, Asset, assetBundle, assetItem, AssetType } from '../utils/asset';
|
||||
import { DragObjectType, isShaken, LocateEvent, DragNodeObject, DragNodeDataObject } from '../../../designer/dragon';
|
||||
import { LocationData } from '../../../designer/location';
|
||||
import { NodeData } from '../../../designer/schema';
|
||||
@ -32,23 +32,19 @@ const defaultSimulatorUrl = (() => {
|
||||
if (process.env.NODE_ENV === 'production') {
|
||||
urls = [`${publicPath}simulator-renderer.min.css`, `${publicPath}simulator-renderer.min.js`];
|
||||
} else {
|
||||
urls = [`${publicPath}simulator-renderer.js`];
|
||||
urls = [`${publicPath}simulator-renderer.css`, `${publicPath}simulator-renderer.js`];
|
||||
}
|
||||
return urls;
|
||||
})();
|
||||
|
||||
const defaultDepends = [
|
||||
{
|
||||
type: 'jsUrl',
|
||||
content:
|
||||
'https://g.alicdn.com/mylib/??react/16.11.0/umd/react.production.min.js,react-dom/16.8.6/umd/react-dom.production.min.js,prop-types/15.7.2/prop-types.min.js',
|
||||
id: 'rect',
|
||||
},
|
||||
{
|
||||
type: 'jsText',
|
||||
content:
|
||||
'React.PropTypes=window.PropTypes;window.__REACT_DEVTOOLS_GLOBAL_HOOK__ = window.parent.__REACT_DEVTOOLS_GLOBAL_HOOK__;',
|
||||
},
|
||||
// https://g.alicdn.com/mylib/??react/16.11.0/umd/react.production.min.js,react-dom/16.8.6/umd/react-dom.production.min.js,prop-types/15.7.2/prop-types.min.js
|
||||
assetItem(AssetType.JSText, 'window.React=parent.React;window.ReactDOM=parent.ReactDOM;', undefined, 'react'),
|
||||
assetItem(
|
||||
AssetType.JSText,
|
||||
'window.PropTypes=parent.PropTypes;React.PropTypes=parent.PropTypes; window.__REACT_DEVTOOLS_GLOBAL_HOOK__ = window.parent.__REACT_DEVTOOLS_GLOBAL_HOOK__;',
|
||||
),
|
||||
assetItem(AssetType.JSUrl, 'http://localhost:4444/js/index.js'),
|
||||
];
|
||||
|
||||
export class SimulatorHost implements ISimulator<SimulatorProps> {
|
||||
@ -138,15 +134,7 @@ export class SimulatorHost implements ISimulator<SimulatorProps> {
|
||||
return this._renderer;
|
||||
}
|
||||
|
||||
readonly componentsConsumer = new ResourceConsumer<{
|
||||
componentsAsset?: Asset;
|
||||
componentsMap: object;
|
||||
}>(() => {
|
||||
return {
|
||||
componentsAsset: this.componentsAsset,
|
||||
componentsMap: this.componentsMap,
|
||||
};
|
||||
});
|
||||
readonly componentsConsumer = new ResourceConsumer<Asset | undefined>(() => this.componentsAsset);
|
||||
|
||||
readonly injectionConsumer = new ResourceConsumer(() => {
|
||||
return {};
|
||||
@ -350,8 +338,8 @@ export class SimulatorHost implements ISimulator<SimulatorProps> {
|
||||
throw new Error('Method not implemented.');
|
||||
}
|
||||
|
||||
getClosestNodeId(elem: Element): string {
|
||||
throw new Error('Method not implemented.');
|
||||
getClosestNodeId(elem: Element): string | null {
|
||||
return this.renderer?.getClosestNodeId(elem) || null;
|
||||
}
|
||||
|
||||
findDOMNodes(instance: ComponentInstance): (Element | Text)[] | null {
|
||||
|
||||
@ -58,7 +58,11 @@ export default class ResourceConsumer<T = any> {
|
||||
}
|
||||
await consumer(this._data);
|
||||
// TODO: catch error and report
|
||||
this.emitter.emit('consume');
|
||||
if (this.resovleFirst) {
|
||||
this.resovleFirst();
|
||||
} else {
|
||||
this._firstConsumed = true;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@ -72,9 +76,15 @@ export default class ResourceConsumer<T = any> {
|
||||
this.emitter.removeAllListeners();
|
||||
}
|
||||
|
||||
private _firstConsumed: boolean = false;
|
||||
private resovleFirst?: () => void;
|
||||
|
||||
waitFirstConsume(): Promise<any> {
|
||||
if (this._firstConsumed) {
|
||||
return Promise.resolve();
|
||||
}
|
||||
return new Promise((resolve) => {
|
||||
this.emitter.once('consume', resolve);
|
||||
this.resovleFirst = resolve;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
// import { Engine as LowCodeRenderer } from '@ali/iceluna-sdk';
|
||||
import LowCodeRenderer from '@ali/iceluna-sdk';
|
||||
import { ReactInstance, Fragment, Component } from 'react';
|
||||
import { observer } from '@recore/core-obx';
|
||||
import { SimulatorRenderer } from './renderer';
|
||||
@ -50,20 +50,21 @@ class Renderer extends Component<{ renderer: SimulatorRenderer }> {
|
||||
componentsMap={renderer.componentsMap}
|
||||
suspended={renderer.suspended}
|
||||
self={renderer.scope}
|
||||
onComponentGetRef={(schema: any, ref: ReactInstance | null) => {
|
||||
onCompGetRef={(schema: any, ref: ReactInstance | null) => {
|
||||
renderer.mountInstance(schema.id, ref);
|
||||
}}
|
||||
onComponentGetCtx={(schema: any, ctx: object) => {
|
||||
renderer.mountContext(schema.id, ctx);
|
||||
}}
|
||||
//onCompGetCtx={(schema: any, ctx: object) => {
|
||||
// renderer.mountContext(schema.id, ctx);
|
||||
//}}
|
||||
/>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
class LowCodeRenderer extends Component<any> {
|
||||
render() {
|
||||
const { schema } = this.props;
|
||||
return <div>{JSON.stringify(this.props.schema)}</div>
|
||||
}
|
||||
}
|
||||
}*/
|
||||
|
||||
@ -67,6 +67,9 @@ export class SimulatorRenderer {
|
||||
// sync schema
|
||||
this._schema = host.document.schema;
|
||||
|
||||
this._componentsMap = host.designer.componentsMap;
|
||||
this.buildComponents();
|
||||
|
||||
// sync designMode
|
||||
|
||||
// sync suspended
|
||||
@ -75,13 +78,11 @@ export class SimulatorRenderer {
|
||||
|
||||
// sync device
|
||||
});
|
||||
host.componentsConsumer.consume(async (data) => {
|
||||
if (data.componentsAsset) {
|
||||
await this.load(data.componentsAsset);
|
||||
host.componentsConsumer.consume(async (componentsAsset) => {
|
||||
if (componentsAsset) {
|
||||
await this.load(componentsAsset);
|
||||
this.buildComponents();
|
||||
}
|
||||
|
||||
// sync componetsMap
|
||||
this._componentsMap = data.componentsMap;
|
||||
});
|
||||
host.injectionConsumer.consume((data) => {
|
||||
// sync utils, i18n, contants,... config
|
||||
@ -103,11 +104,14 @@ export class SimulatorRenderer {
|
||||
@computed get schema(): any {
|
||||
return this._schema;
|
||||
}
|
||||
@obx.ref private _componentsMap = {};
|
||||
private buildComponents() {
|
||||
this._components = buildComponents(this._componentsMap);
|
||||
}
|
||||
@obx.ref private _components = {};
|
||||
@computed get components(): object {
|
||||
// 根据 device 选择不同组件,进行响应式
|
||||
// 更好的做法是,根据 device 选择加载不同的组件资源,甚至是 simulatorUrl
|
||||
return buildComponents(this._componentsMap);
|
||||
return this._components;
|
||||
}
|
||||
// context from: utils、constants、history、location、match
|
||||
@obx.ref private _appContext = {};
|
||||
@ -118,6 +122,7 @@ export class SimulatorRenderer {
|
||||
@computed get designMode(): any {
|
||||
return 'border';
|
||||
}
|
||||
@obx.ref private _componentsMap = {};
|
||||
@computed get componentsMap(): any {
|
||||
return this._componentsMap;
|
||||
}
|
||||
|
||||
@ -20,6 +20,15 @@ export enum AssetLevel {
|
||||
App = 6,
|
||||
}
|
||||
|
||||
export const AssetLevels = [
|
||||
AssetLevel.BaseDepends,
|
||||
AssetLevel.BaseComponents,
|
||||
AssetLevel.Theme,
|
||||
AssetLevel.Runtime,
|
||||
AssetLevel.Components,
|
||||
AssetLevel.App,
|
||||
];
|
||||
|
||||
export type URL = string;
|
||||
|
||||
export enum AssetType {
|
||||
@ -27,7 +36,7 @@ export enum AssetType {
|
||||
CSSUrl = 'cssUrl',
|
||||
CSSText = 'cssText',
|
||||
JSText = 'jsText',
|
||||
Bundle = 'bundel',
|
||||
Bundle = 'bundle',
|
||||
}
|
||||
|
||||
export interface AssetBundle {
|
||||
@ -64,7 +73,7 @@ export function assetBundle(assets?: Asset | AssetList | null, level?: AssetLeve
|
||||
}
|
||||
|
||||
export function assetItem(type: AssetType, content?: string | null, level?: AssetLevel, id?: string): AssetItem | null {
|
||||
if (content) {
|
||||
if (!content) {
|
||||
return null;
|
||||
}
|
||||
return {
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
import { load, evaluate } from './script';
|
||||
import StylePoint from './style';
|
||||
import { Asset, AssetLevel, AssetType, AssetList, isAssetBundle, isAssetItem, assetItem, isCSSUrl, AssetItem } from './asset';
|
||||
import { Asset, AssetLevel, AssetLevels, AssetType, AssetList, isAssetBundle, isAssetItem, assetItem, isCSSUrl, AssetItem } from './asset';
|
||||
|
||||
function parseAssetList(scripts: any, styles: any, assets: AssetList, level?: AssetLevel) {
|
||||
for (let asset of assets) {
|
||||
@ -50,10 +50,9 @@ export class AssetLoader {
|
||||
async load(asset: Asset) {
|
||||
const styles: any = {};
|
||||
const scripts: any = {};
|
||||
Object.keys(AssetLevel).forEach((key) => {
|
||||
const v = (AssetLevel as any)[key];
|
||||
styles[v] = [];
|
||||
scripts[v] = [];
|
||||
AssetLevels.forEach((lv) => {
|
||||
styles[lv] = [];
|
||||
scripts[lv] = [];
|
||||
});
|
||||
parseAsset(scripts, styles, asset);
|
||||
const styleQueue: AssetItem[] = styles[AssetLevel.BaseDepends].concat(
|
||||
|
||||
@ -0,0 +1,28 @@
|
||||
.lc-designer {
|
||||
position: relative;
|
||||
min-width: 500px;
|
||||
min-height: 500px;
|
||||
.lc-project {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
.lc-document {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
&&-hidden {
|
||||
// todo:
|
||||
display: none;
|
||||
}
|
||||
|
||||
.lc-simulator-shell {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -93,7 +93,7 @@ export default class Node {
|
||||
this._directives = new Props(this, {});
|
||||
Object.keys(extras).forEach(key => {
|
||||
if (DIRECTIVES.indexOf(key) > -1) {
|
||||
this.directives!.add((extras as any)[key], key);
|
||||
this._directives!.add((extras as any)[key], key);
|
||||
delete (extras as any)[key];
|
||||
}
|
||||
});
|
||||
@ -295,9 +295,9 @@ export default class Node {
|
||||
// TODO...
|
||||
const schema: any = {
|
||||
componentName: this.componentName,
|
||||
...this.extras,
|
||||
props: this.props,
|
||||
...this.directives,
|
||||
...this.extras?.value,
|
||||
props: this.props?.value || {},
|
||||
...this.directives?.value,
|
||||
};
|
||||
if (serialize) {
|
||||
schema.id = this.id;
|
||||
|
||||
@ -65,9 +65,10 @@ export default class Props<O = any> implements IPropParent {
|
||||
constructor(readonly owner: O, value?: PropsMap | PropsList | null) {
|
||||
if (Array.isArray(value)) {
|
||||
this.type = 'list';
|
||||
value.forEach(item => {});
|
||||
this.items = value.map(item => new Prop(this, item.value, item.name, item.spread));
|
||||
} else if (value != null) {
|
||||
this.type = 'map';
|
||||
this.items = Object.keys(value).map(key => new Prop(this, value[key], key));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -35,12 +35,24 @@ import Props from './props/props';
|
||||
*/
|
||||
export default class RootNode extends Node implements NodeParent {
|
||||
readonly isRootNode = true;
|
||||
readonly isNodeParent = true;
|
||||
readonly index = 0;
|
||||
readonly nextSibling = null;
|
||||
readonly prevSibling = null;
|
||||
readonly zLevel = 0;
|
||||
readonly parent = null;
|
||||
get isNodeParent() {
|
||||
return true;
|
||||
}
|
||||
get index() {
|
||||
return 0;
|
||||
}
|
||||
get nextSibling() {
|
||||
return null
|
||||
}
|
||||
get prevSibling() {
|
||||
return null
|
||||
}
|
||||
get zLevel() {
|
||||
return 0;
|
||||
}
|
||||
get parent() {
|
||||
return null
|
||||
}
|
||||
get children(): NodeChildren {
|
||||
return this._children as NodeChildren;
|
||||
}
|
||||
@ -51,7 +63,7 @@ export default class RootNode extends Node implements NodeParent {
|
||||
return this._extras as any;
|
||||
}
|
||||
get directives(): Props<RootNode> {
|
||||
return this._props as any;
|
||||
return this._directives as any;
|
||||
}
|
||||
internalSetParent(parent: null) {}
|
||||
|
||||
|
||||
@ -132,9 +132,9 @@ export interface ISimulator<P = object> extends ISensor {
|
||||
/**
|
||||
* 根据节点获取节点的组件运行上下文
|
||||
*/
|
||||
getComponentContext(node: Node): object;
|
||||
getComponentContext(node: Node): object | null;
|
||||
|
||||
getClosestNodeId(elem: Element): string;
|
||||
getClosestNodeId(elem: Element): string | null;
|
||||
|
||||
findDOMNodes(instance: ComponentInstance): Array<Element | Text> | null;
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user