mirror of
https://github.com/alibaba/lowcode-engine.git
synced 2025-12-14 21:12:53 +00:00
add some assets
This commit is contained in:
parent
b9272d6bab
commit
a44120df48
@ -4,7 +4,11 @@ import { SimulatorHost } from './host';
|
||||
import { AssetLevel, AssetLevels, AssetList, isAssetBundle, isAssetItem, AssetType, assetItem } from '../utils/asset';
|
||||
import { isCSSUrl } from '../../../utils/is-css-url';
|
||||
|
||||
export function createSimulator(host: SimulatorHost, iframe: HTMLIFrameElement, vendors: AssetList = []): Promise<SimulatorRenderer> {
|
||||
export function createSimulator(
|
||||
host: SimulatorHost,
|
||||
iframe: HTMLIFrameElement,
|
||||
vendors: AssetList = [],
|
||||
): Promise<SimulatorRenderer> {
|
||||
const win: any = iframe.contentWindow;
|
||||
const doc = iframe.contentDocument!;
|
||||
|
||||
@ -12,7 +16,7 @@ export function createSimulator(host: SimulatorHost, iframe: HTMLIFrameElement,
|
||||
|
||||
const styles: any = {};
|
||||
const scripts: any = {};
|
||||
AssetLevels.forEach((lv) => {
|
||||
AssetLevels.forEach(lv => {
|
||||
styles[lv] = [];
|
||||
scripts[lv] = [];
|
||||
});
|
||||
@ -36,9 +40,9 @@ export function createSimulator(host: SimulatorHost, iframe: HTMLIFrameElement,
|
||||
asset = assetItem(isCSSUrl(asset) ? AssetType.CSSUrl : AssetType.JSUrl, asset, level)!;
|
||||
}
|
||||
const id = asset.id ? ` data-id="${asset.id}"` : '';
|
||||
const lv = asset.level || level || AssetLevel.BaseDepends;
|
||||
const lv = asset.level || level || AssetLevel.Environment;
|
||||
if (asset.type === AssetType.JSUrl) {
|
||||
(scripts[lv] || scripts[AssetLevel.App]).push(`<script src="${asset.content}"${id}></script>`)
|
||||
(scripts[lv] || scripts[AssetLevel.App]).push(`<script src="${asset.content}"${id}></script>`);
|
||||
} else if (asset.type === AssetType.JSText) {
|
||||
(scripts[lv] || scripts[AssetLevel.App]).push(`<script${id}>${asset.content}</script>`);
|
||||
} else if (asset.type === AssetType.CSSUrl) {
|
||||
@ -51,12 +55,16 @@ export function createSimulator(host: SimulatorHost, iframe: HTMLIFrameElement,
|
||||
|
||||
parseAssetList(vendors);
|
||||
|
||||
const styleFrags = Object.keys(styles).map(key => {
|
||||
return styles[key].join('\n') + `<meta level="${key}" />`;
|
||||
}).join('');
|
||||
const scriptFrags = Object.keys(scripts).map(key => {
|
||||
return scripts[key].join('\n');
|
||||
}).join('');
|
||||
const styleFrags = Object.keys(styles)
|
||||
.map(key => {
|
||||
return styles[key].join('\n') + `<meta level="${key}" />`;
|
||||
})
|
||||
.join('');
|
||||
const scriptFrags = Object.keys(scripts)
|
||||
.map(key => {
|
||||
return scripts[key].join('\n');
|
||||
})
|
||||
.join('');
|
||||
|
||||
doc.open();
|
||||
doc.write(`<!doctype html><html><head><meta charset="utf-8"/>
|
||||
|
||||
@ -6,7 +6,7 @@ import { SimulatorRenderer } from '../renderer/renderer';
|
||||
import Node, { NodeParent, isNodeParent, isNode, contains } from '../../../designer/document/node/node';
|
||||
import DocumentModel from '../../../designer/document/document-model';
|
||||
import ResourceConsumer from './resource-consumer';
|
||||
import { AssetLevel, Asset, assetBundle, assetItem, AssetType } from '../utils/asset';
|
||||
import { AssetLevel, Asset, AssetList, assetBundle, assetItem, AssetType } from '../utils/asset';
|
||||
import {
|
||||
DragObjectType,
|
||||
isShaken,
|
||||
@ -34,6 +34,12 @@ import { ReactInstance } from 'react';
|
||||
import { isRootNode } from '../../../designer/document/node/root-node';
|
||||
import { parseProps } from '../utils/parse-props';
|
||||
|
||||
export interface LibraryItem {
|
||||
package: string;
|
||||
library: string;
|
||||
urls: Asset;
|
||||
}
|
||||
|
||||
export interface SimulatorProps {
|
||||
// 从 documentModel 上获取
|
||||
// suspended?: boolean;
|
||||
@ -41,8 +47,9 @@ export interface SimulatorProps {
|
||||
device?: 'mobile' | 'iphone' | string;
|
||||
deviceClassName?: string;
|
||||
simulatorUrl?: Asset;
|
||||
dependsAsset?: Asset;
|
||||
themesAsset?: Asset;
|
||||
environment?: Asset;
|
||||
library?: LibraryItem[];
|
||||
theme?: Asset;
|
||||
componentsAsset?: Asset;
|
||||
[key: string]: any;
|
||||
}
|
||||
@ -59,14 +66,13 @@ const defaultSimulatorUrl = (() => {
|
||||
return urls;
|
||||
})();
|
||||
|
||||
const defaultDepends = [
|
||||
const defaultEnvironment = [
|
||||
// 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, 'https://g.alicdn.com/mylib/@ali/recore/1.5.7/umd/recore.min.js'),
|
||||
assetItem(AssetType.JSUrl, '/statics/lowcode-renderer.js'),
|
||||
];
|
||||
|
||||
@ -97,8 +103,8 @@ export class SimulatorHost implements ISimulator<SimulatorProps> {
|
||||
return this.get('componentsAsset');
|
||||
}
|
||||
|
||||
@computed get themesAsset(): Asset | undefined {
|
||||
return this.get('themesAsset');
|
||||
@computed get theme(): Asset | undefined {
|
||||
return this.get('theme');
|
||||
}
|
||||
|
||||
@computed get componentsMap() {
|
||||
@ -166,6 +172,8 @@ export class SimulatorHost implements ISimulator<SimulatorProps> {
|
||||
return {};
|
||||
});
|
||||
|
||||
readonly libraryMap: { [key: string]: string } = {};
|
||||
|
||||
async mountContentFrame(iframe: HTMLIFrameElement | null) {
|
||||
if (!iframe) {
|
||||
return;
|
||||
@ -173,11 +181,22 @@ export class SimulatorHost implements ISimulator<SimulatorProps> {
|
||||
|
||||
this._contentWindow = iframe.contentWindow!;
|
||||
|
||||
const library = this.get('library') as LibraryItem[];
|
||||
const libraryAsset: AssetList = [];
|
||||
if (library) {
|
||||
library.forEach(item => {
|
||||
this.libraryMap[item.package] = item.library;
|
||||
libraryAsset.push(item.urls);
|
||||
});
|
||||
}
|
||||
|
||||
const vendors = [
|
||||
// required & use once
|
||||
assetBundle(this.get('dependsAsset') || defaultDepends, AssetLevel.BaseDepends),
|
||||
assetBundle(this.get('environment') || defaultEnvironment, AssetLevel.Environment),
|
||||
// required & use once
|
||||
assetBundle(libraryAsset, AssetLevel.Library),
|
||||
// required & TODO: think of update
|
||||
assetBundle(this.themesAsset, AssetLevel.Theme),
|
||||
assetBundle(this.theme, AssetLevel.Theme),
|
||||
// required & use once
|
||||
assetBundle(this.get('simulatorUrl') || defaultSimulatorUrl, AssetLevel.Runtime),
|
||||
];
|
||||
|
||||
@ -40,11 +40,11 @@ class Renderer extends Component<{ renderer: SimulatorRenderer }> {
|
||||
}
|
||||
render() {
|
||||
const { renderer } = this.props;
|
||||
const { components, schemas } = LowCodeRenderer.others;
|
||||
// const { components, schemas } = LowCodeRenderer.others;
|
||||
return (
|
||||
<LowCodeRenderer
|
||||
schema={renderer.schema}
|
||||
components={components /*renderer.components*/}
|
||||
components={renderer.components}
|
||||
appHelper={renderer.context}
|
||||
// context={renderer.context}
|
||||
designMode={renderer.designMode}
|
||||
|
||||
@ -27,8 +27,12 @@ export class SimulatorRenderer {
|
||||
// sync schema
|
||||
this._schema = host.document.schema;
|
||||
|
||||
this._componentsMap = host.designer.componentsMap;
|
||||
this.buildComponents();
|
||||
// todo: split with others, not all should recompute
|
||||
if (this._libraryMap !== host.libraryMap || this._componentsMap !== host.designer.componentsMap) {
|
||||
this._libraryMap = host.libraryMap || {};
|
||||
this._componentsMap = host.designer.componentsMap;
|
||||
this.buildComponents();
|
||||
}
|
||||
|
||||
// sync designMode
|
||||
|
||||
@ -64,8 +68,9 @@ export class SimulatorRenderer {
|
||||
@computed get schema(): any {
|
||||
return this._schema;
|
||||
}
|
||||
private _libraryMap: { [key: string]: string } = {};
|
||||
private buildComponents() {
|
||||
this._components = buildComponents(this._componentsMap);
|
||||
this._components = buildComponents(this._libraryMap, this._componentsMap);
|
||||
}
|
||||
@obx.ref private _components: any = {};
|
||||
@computed get components(): object {
|
||||
@ -280,7 +285,7 @@ function getSubComponent(library: any, paths: string[]) {
|
||||
return component;
|
||||
}
|
||||
|
||||
function findComponent(componentName: string, npm?: NpmInfo) {
|
||||
function findComponent(libraryMap: LibraryMap, componentName: string, npm?: NpmInfo) {
|
||||
if (!npm) {
|
||||
return accessLibrary(componentName);
|
||||
}
|
||||
@ -290,21 +295,26 @@ function findComponent(componentName: string, npm?: NpmInfo) {
|
||||
// export { exportName as componentName } from package
|
||||
// if exportName == null exportName === componentName;
|
||||
// const componentName = exportName.subName, if exportName empty subName donot use
|
||||
const libraryName = npm.exportName || npm.componentName || componentName;
|
||||
const exportName = npm.exportName || npm.componentName || componentName;
|
||||
const libraryName = libraryMap[npm.package] || exportName;
|
||||
const library = accessLibrary(libraryName);
|
||||
const paths = npm.exportName && npm.subName ? npm.subName.split('.') : [];
|
||||
if (npm.destructuring) {
|
||||
paths.unshift(libraryName);
|
||||
paths.unshift(exportName);
|
||||
} else if (isESModule(library)) {
|
||||
paths.unshift('default');
|
||||
}
|
||||
return getSubComponent(library, paths);
|
||||
}
|
||||
|
||||
function buildComponents(componentsMap: { [componentName: string]: NpmInfo }) {
|
||||
export interface LibraryMap {
|
||||
[key: string]: string;
|
||||
}
|
||||
|
||||
function buildComponents(libraryMap: LibraryMap, componentsMap: { [componentName: string]: NpmInfo }) {
|
||||
const components: any = {};
|
||||
Object.keys(componentsMap).forEach(componentName => {
|
||||
components[componentName] = findComponent(componentName, componentsMap[componentName]);
|
||||
components[componentName] = findComponent(libraryMap, componentName, componentsMap[componentName]);
|
||||
});
|
||||
return components;
|
||||
}
|
||||
|
||||
@ -6,11 +6,11 @@ export interface AssetItem {
|
||||
}
|
||||
|
||||
export enum AssetLevel {
|
||||
// 基础依赖库
|
||||
BaseDepends = 1,
|
||||
// 基础组件库
|
||||
BaseComponents = 2,
|
||||
// 主题包
|
||||
// 环境依赖库 比如 react, react-dom
|
||||
Environment = 1,
|
||||
// 基础类库,比如 lodash deep fusion antd
|
||||
Library = 2,
|
||||
// 主题
|
||||
Theme = 3,
|
||||
// 运行时
|
||||
Runtime = 4,
|
||||
@ -21,8 +21,8 @@ export enum AssetLevel {
|
||||
}
|
||||
|
||||
export const AssetLevels = [
|
||||
AssetLevel.BaseDepends,
|
||||
AssetLevel.BaseComponents,
|
||||
AssetLevel.Environment,
|
||||
AssetLevel.Library,
|
||||
AssetLevel.Theme,
|
||||
AssetLevel.Runtime,
|
||||
AssetLevel.Components,
|
||||
|
||||
@ -1,10 +1,20 @@
|
||||
import { load, evaluate } from './script';
|
||||
import StylePoint from './style';
|
||||
import { Asset, AssetLevel, AssetLevels, AssetType, AssetList, isAssetBundle, isAssetItem, assetItem, AssetItem } from './asset';
|
||||
import {
|
||||
Asset,
|
||||
AssetLevel,
|
||||
AssetLevels,
|
||||
AssetType,
|
||||
AssetList,
|
||||
isAssetBundle,
|
||||
isAssetItem,
|
||||
assetItem,
|
||||
AssetItem,
|
||||
} from './asset';
|
||||
import { isCSSUrl } from '../../../utils/is-css-url';
|
||||
|
||||
function parseAssetList(scripts: any, styles: any, assets: AssetList, level?: AssetLevel) {
|
||||
for (let asset of assets) {
|
||||
for (const asset of assets) {
|
||||
parseAsset(scripts, styles, asset, level);
|
||||
}
|
||||
}
|
||||
@ -36,7 +46,7 @@ function parseAsset(scripts: any, styles: any, asset: Asset | undefined | null,
|
||||
let lv = asset.level || level;
|
||||
|
||||
if (!lv || AssetLevel[lv] == null) {
|
||||
lv = AssetLevel.App
|
||||
lv = AssetLevel.App;
|
||||
}
|
||||
|
||||
asset.level = lv;
|
||||
@ -51,19 +61,19 @@ export class AssetLoader {
|
||||
async load(asset: Asset) {
|
||||
const styles: any = {};
|
||||
const scripts: any = {};
|
||||
AssetLevels.forEach((lv) => {
|
||||
AssetLevels.forEach(lv => {
|
||||
styles[lv] = [];
|
||||
scripts[lv] = [];
|
||||
});
|
||||
parseAsset(scripts, styles, asset);
|
||||
const styleQueue: AssetItem[] = styles[AssetLevel.BaseDepends].concat(
|
||||
styles[AssetLevel.BaseComponents],
|
||||
const styleQueue: AssetItem[] = styles[AssetLevel.Environment].concat(
|
||||
styles[AssetLevel.Library],
|
||||
styles[AssetLevel.Theme],
|
||||
styles[AssetLevel.Runtime],
|
||||
styles[AssetLevel.App],
|
||||
);
|
||||
const scriptQueue: AssetItem[] = scripts[AssetLevel.BaseDepends].concat(
|
||||
scripts[AssetLevel.BaseComponents],
|
||||
const scriptQueue: AssetItem[] = scripts[AssetLevel.Environment].concat(
|
||||
scripts[AssetLevel.Library],
|
||||
scripts[AssetLevel.Theme],
|
||||
scripts[AssetLevel.Runtime],
|
||||
scripts[AssetLevel.App],
|
||||
@ -71,9 +81,7 @@ export class AssetLoader {
|
||||
await Promise.all(
|
||||
styleQueue.map(({ content, level, type, id }) => this.loadStyle(content, level!, type === AssetType.CSSUrl, id)),
|
||||
);
|
||||
await Promise.all(
|
||||
scriptQueue.map(({ content, type }) => this.loadScript(content, type === AssetType.JSUrl)),
|
||||
);
|
||||
await Promise.all(scriptQueue.map(({ content, type }) => this.loadScript(content, type === AssetType.JSUrl)));
|
||||
}
|
||||
|
||||
private stylePoints = new Map<string, StylePoint>();
|
||||
|
||||
@ -330,7 +330,7 @@ export default class Designer {
|
||||
return meta;
|
||||
}
|
||||
|
||||
get componentsMap(): { [key: string]: NpmInfo } {
|
||||
@computed get componentsMap(): { [key: string]: NpmInfo } {
|
||||
const maps: any = {};
|
||||
this._componentMetasMap.forEach((config, key) => {
|
||||
maps[key] = config.metadata.npm;
|
||||
|
||||
@ -325,7 +325,7 @@ export default class Node {
|
||||
*/
|
||||
export(serialize = false): NodeSchema {
|
||||
const baseSchema: any = {
|
||||
componentName: this.componentName,
|
||||
componentName: this.componentName === 'Leaf' ? 'Fragment' : this.componentName,
|
||||
};
|
||||
|
||||
if (serialize) {
|
||||
@ -334,10 +334,11 @@ export default class Node {
|
||||
|
||||
if (!isNodeParent(this)) {
|
||||
baseSchema.children = this.props.get('children')?.export(serialize);
|
||||
return baseSchema;
|
||||
// FIXME!
|
||||
return baseSchema.children;
|
||||
}
|
||||
|
||||
const { props, extras } = this.props.export(serialize) || {};
|
||||
const { props = {}, extras } = this.props.export(serialize) || {};
|
||||
const schema: any = {
|
||||
...baseSchema,
|
||||
props,
|
||||
|
||||
@ -33,22 +33,24 @@ export default {
|
||||
propType: 'string'
|
||||
}
|
||||
],
|
||||
configure: {
|
||||
props: [
|
||||
{
|
||||
name: 'type',
|
||||
setter: {
|
||||
componentName: 'Input'
|
||||
}
|
||||
},
|
||||
{
|
||||
name: 'children',
|
||||
setter: {
|
||||
componentName: 'Input'
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
'Button.Group': {
|
||||
componentName: 'Button.Group',
|
||||
title: '按钮组',
|
||||
devMode: 'proCode',
|
||||
npm: {
|
||||
package: '@alifd/next',
|
||||
version: '1.19.18',
|
||||
destructuring: true,
|
||||
exportName: 'Button',
|
||||
subName: 'Group'
|
||||
},
|
||||
props: [
|
||||
{
|
||||
name: 'size',
|
||||
propType: 'string'
|
||||
}
|
||||
],
|
||||
},
|
||||
Input: {
|
||||
componentName: 'Input',
|
||||
@ -66,16 +68,91 @@ export default {
|
||||
propType: 'string'
|
||||
}
|
||||
],
|
||||
configure: {
|
||||
props: [
|
||||
{
|
||||
name: 'placeholder',
|
||||
setter: {
|
||||
componentName: 'Input'
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
Form: {
|
||||
componentName: 'Form',
|
||||
title: '表单容器',
|
||||
devMode: 'proCode',
|
||||
npm: {
|
||||
package: '@alifd/next',
|
||||
version: '1.19.18',
|
||||
destructuring: true,
|
||||
exportName: 'Form'
|
||||
},
|
||||
props: [
|
||||
{
|
||||
name: 'device',
|
||||
propType: 'string'
|
||||
}
|
||||
],
|
||||
},
|
||||
'Form.Item': {
|
||||
componentName: 'Form.Item',
|
||||
title: '表单项',
|
||||
devMode: 'proCode',
|
||||
npm: {
|
||||
package: '@alifd/next',
|
||||
version: '1.19.18',
|
||||
destructuring: true,
|
||||
exportName: 'Form',
|
||||
subName: 'Item'
|
||||
},
|
||||
props: [
|
||||
{
|
||||
name: 'label',
|
||||
propType: 'string',
|
||||
},
|
||||
{
|
||||
name: 'device',
|
||||
propType: 'string'
|
||||
}
|
||||
],
|
||||
},
|
||||
NumberPicker: {
|
||||
componentName: 'NumberPicker',
|
||||
title: '数字输入',
|
||||
devMode: 'proCode',
|
||||
npm: {
|
||||
package: '@alifd/next',
|
||||
version: '1.19.18',
|
||||
destructuring: true,
|
||||
exportName: 'NumberPicker',
|
||||
},
|
||||
props: [
|
||||
{
|
||||
name: 'size',
|
||||
propType: 'string',
|
||||
},
|
||||
{
|
||||
name: 'defaultValue',
|
||||
propType: 'number'
|
||||
}
|
||||
],
|
||||
},
|
||||
Select: {
|
||||
componentName: 'Select',
|
||||
title: '下拉',
|
||||
devMode: 'proCode',
|
||||
npm: {
|
||||
package: '@alifd/next',
|
||||
version: '1.19.18',
|
||||
destructuring: true,
|
||||
exportName: 'Select',
|
||||
},
|
||||
props: [
|
||||
{
|
||||
name: 'size',
|
||||
propType: 'string',
|
||||
},
|
||||
{
|
||||
name: 'defaultValue',
|
||||
propType: 'number'
|
||||
},
|
||||
{
|
||||
name: 'placeholder',
|
||||
propType: 'string'
|
||||
}
|
||||
],
|
||||
}
|
||||
},
|
||||
componentList: [
|
||||
|
||||
@ -6,6 +6,8 @@ import { PluginConfig } from '../../framework/definitions';
|
||||
// @ts-ignore
|
||||
import Designer from '../../../../designer';
|
||||
|
||||
import assets from '../../config/assets';
|
||||
|
||||
import './index.scss';
|
||||
|
||||
export interface PluginProps {
|
||||
@ -53,7 +55,7 @@ const SCHEMA = {
|
||||
},
|
||||
children: [
|
||||
{
|
||||
componentName: 'FormItem',
|
||||
componentName: 'Form.Item',
|
||||
props: {
|
||||
label: '姓名:',
|
||||
name: 'name',
|
||||
@ -73,7 +75,7 @@ const SCHEMA = {
|
||||
]
|
||||
},
|
||||
{
|
||||
componentName: 'FormItem',
|
||||
componentName: 'Form.Item',
|
||||
props: {
|
||||
label: '年龄:',
|
||||
name: 'age',
|
||||
@ -90,7 +92,7 @@ const SCHEMA = {
|
||||
]
|
||||
},
|
||||
{
|
||||
componentName: 'FormItem',
|
||||
componentName: 'Form.Item',
|
||||
props: {
|
||||
label: '职业:',
|
||||
name: 'profession'
|
||||
@ -126,7 +128,7 @@ const SCHEMA = {
|
||||
},
|
||||
children: [
|
||||
{
|
||||
componentName: 'ButtonGroup',
|
||||
componentName: 'Button.Group',
|
||||
props: {},
|
||||
children: [
|
||||
{
|
||||
@ -179,21 +181,9 @@ export default class DesignerPlugin extends PureComponent<PluginProps> {
|
||||
className="lowcode-plugin-designer"
|
||||
defaultSchema={SCHEMA as any}
|
||||
eventPipe={editor as any}
|
||||
componentsDescription={Object.values(assets.components) as any}
|
||||
simulatorProps={{
|
||||
componentsAsset: [
|
||||
{
|
||||
type: 'jsUrl',
|
||||
content: 'https://unpkg.alibaba-inc.com/@alifd/next@1.18.17/dist/next.min.js',
|
||||
id: 'next',
|
||||
level: 2
|
||||
},
|
||||
{
|
||||
type: 'cssUrl',
|
||||
content: 'https://unpkg.alibaba-inc.com/@alifd/next@1.18.17/dist/next.min.css',
|
||||
id: 'next',
|
||||
level: 2
|
||||
}
|
||||
]
|
||||
library: Object.values(assets.packages),
|
||||
}}
|
||||
/>
|
||||
);
|
||||
|
||||
1082
packages/editor/statics/assets.json
Normal file
1082
packages/editor/statics/assets.json
Normal file
File diff suppressed because it is too large
Load Diff
Loading…
x
Reference in New Issue
Block a user