From e3e575b1097ef4cce16fa80c8822dc399222e04b Mon Sep 17 00:00:00 2001 From: "wuji.xwt" Date: Sun, 16 Aug 2020 14:17:16 +0800 Subject: [PATCH] refactor: using the same asset loader --- .../react-simulator-renderer/src/renderer.ts | 5 +- .../src/utils/create-defer.ts | 17 --- .../src/utils/loader.ts | 113 ------------------ .../src/utils/script.ts | 54 --------- .../src/utils/style.ts | 73 ----------- 5 files changed, 3 insertions(+), 259 deletions(-) delete mode 100644 packages/react-simulator-renderer/src/utils/create-defer.ts delete mode 100644 packages/react-simulator-renderer/src/utils/loader.ts delete mode 100644 packages/react-simulator-renderer/src/utils/script.ts delete mode 100644 packages/react-simulator-renderer/src/utils/style.ts diff --git a/packages/react-simulator-renderer/src/renderer.ts b/packages/react-simulator-renderer/src/renderer.ts index 61edf182c..836aa5e29 100644 --- a/packages/react-simulator-renderer/src/renderer.ts +++ b/packages/react-simulator-renderer/src/renderer.ts @@ -5,15 +5,16 @@ import SimulatorRendererView from './renderer-view'; import { computed, obx } from '@recore/obx'; import { Asset } from '@ali/lowcode-utils'; import { getClientRects } from './utils/get-client-rects'; -import loader from './utils/loader'; import { reactFindDOMNodes, FIBER_KEY } from './utils/react-find-dom-nodes'; -import { isElement, cursor, setNativeSelection, buildComponents, getSubComponent } from '@ali/lowcode-utils'; +import { isElement, cursor, setNativeSelection, buildComponents, getSubComponent, AssetLoader } from '@ali/lowcode-utils'; import { RootSchema, ComponentSchema, TransformStage } from '@ali/lowcode-types'; // just use types import { BuiltinSimulatorRenderer, NodeInstance, Component } from '@ali/lowcode-designer'; import Slot from './builtin-components/slot'; import Leaf from './builtin-components/leaf'; +const loader = new AssetLoader(); + export class SimulatorRenderer implements BuiltinSimulatorRenderer { readonly isSimulatorRenderer = true; private dispose?: () => void; diff --git a/packages/react-simulator-renderer/src/utils/create-defer.ts b/packages/react-simulator-renderer/src/utils/create-defer.ts deleted file mode 100644 index e7997365a..000000000 --- a/packages/react-simulator-renderer/src/utils/create-defer.ts +++ /dev/null @@ -1,17 +0,0 @@ -export interface Defer { - resolve(value?: T | PromiseLike): void; - reject(reason?: any): void; - promise(): Promise; -} - -export function createDefer(): Defer { - const r: any = {}; - const promise = new Promise((resolve, reject) => { - r.resolve = resolve; - r.reject = reject; - }); - - r.promise = () => promise; - - return r; -} diff --git a/packages/react-simulator-renderer/src/utils/loader.ts b/packages/react-simulator-renderer/src/utils/loader.ts deleted file mode 100644 index 3bba55ba1..000000000 --- a/packages/react-simulator-renderer/src/utils/loader.ts +++ /dev/null @@ -1,113 +0,0 @@ -import { load, evaluate } from './script'; -import StylePoint from './style'; -import { - Asset, - AssetLevel, - AssetLevels, - AssetType, - AssetList, - isAssetBundle, - isAssetItem, - assetItem, - AssetItem, - isCSSUrl, -} from '@ali/lowcode-utils'; - -function parseAssetList(scripts: any, styles: any, assets: AssetList, level?: AssetLevel) { - for (const asset of assets) { - parseAsset(scripts, styles, asset, level); - } -} - -function parseAsset(scripts: any, styles: any, asset: Asset | undefined | null, level?: AssetLevel) { - if (!asset) { - return; - } - if (Array.isArray(asset)) { - return parseAssetList(scripts, styles, asset, level); - } - - if (isAssetBundle(asset)) { - if (asset.assets) { - if (Array.isArray(asset.assets)) { - parseAssetList(scripts, styles, asset.assets, asset.level || level); - } else { - parseAsset(scripts, styles, asset.assets, asset.level || level); - } - return; - } - return; - } - - if (!isAssetItem(asset)) { - asset = assetItem(isCSSUrl(asset) ? AssetType.CSSUrl : AssetType.JSUrl, asset, level)!; - } - - let lv = asset.level || level; - - if (!lv || AssetLevel[lv] == null) { - lv = AssetLevel.App; - } - - asset.level = lv; - if (asset.type === AssetType.CSSUrl || asset.type == AssetType.CSSText) { - styles[lv].push(asset); - } else { - scripts[lv].push(asset); - } -} - -export class AssetLoader { - async load(asset: Asset) { - const styles: any = {}; - const scripts: any = {}; - AssetLevels.forEach(lv => { - styles[lv] = []; - scripts[lv] = []; - }); - parseAsset(scripts, styles, asset); - const styleQueue: AssetItem[] = styles[AssetLevel.Environment].concat( - styles[AssetLevel.Library], - styles[AssetLevel.Theme], - styles[AssetLevel.Runtime], - styles[AssetLevel.App], - ); - const scriptQueue: AssetItem[] = scripts[AssetLevel.Environment].concat( - scripts[AssetLevel.Library], - scripts[AssetLevel.Theme], - scripts[AssetLevel.Runtime], - scripts[AssetLevel.App], - ); - 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))); - } - - private stylePoints = new Map(); - private loadStyle(content: string | undefined | null, level: AssetLevel, isUrl?: boolean, id?: string) { - if (!content) { - return; - } - let point: StylePoint | undefined; - if (id) { - point = this.stylePoints.get(id); - if (!point) { - point = new StylePoint(level, id); - this.stylePoints.set(id, point); - } - } else { - point = new StylePoint(level); - } - return isUrl ? point.applyUrl(content) : point.applyText(content); - } - - private loadScript(content: string | undefined | null, isUrl?: boolean) { - if (!content) { - return; - } - return isUrl ? load(content) : evaluate(content); - } -} - -export default new AssetLoader(); diff --git a/packages/react-simulator-renderer/src/utils/script.ts b/packages/react-simulator-renderer/src/utils/script.ts deleted file mode 100644 index 81841ff6d..000000000 --- a/packages/react-simulator-renderer/src/utils/script.ts +++ /dev/null @@ -1,54 +0,0 @@ -import { createDefer } from './create-defer'; - -export function evaluate(script: string) { - const scriptEl = document.createElement('script'); - scriptEl.text = script; - document.head.appendChild(scriptEl); - document.head.removeChild(scriptEl); -} - -export function load(url: string) { - const node: any = document.createElement('script'); - - // node.setAttribute('crossorigin', 'anonymous'); - - node.onload = onload; - node.onerror = onload; - - const i = createDefer(); - - function onload(e: any) { - node.onload = null; - node.onerror = null; - if (e.type === 'load') { - i.resolve(); - } else { - i.reject(); - } - // document.head.removeChild(node); - // node = null; - } - - // node.async = true; - node.src = url; - - document.head.appendChild(node); - - return i.promise(); -} - -export function evaluateExpression(expr: string) { - // eslint-disable-next-line no-new-func - const fn = new Function(expr); - return fn(); -} - -export function newFunction(args: string, code: string) { - try { - // eslint-disable-next-line no-new-func - return new Function(args, code); - } catch (e) { - console.warn('Caught error, Cant init func'); - return null; - } -} diff --git a/packages/react-simulator-renderer/src/utils/style.ts b/packages/react-simulator-renderer/src/utils/style.ts deleted file mode 100644 index 74f4eddd4..000000000 --- a/packages/react-simulator-renderer/src/utils/style.ts +++ /dev/null @@ -1,73 +0,0 @@ -import { createDefer } from './create-defer'; - -export default class StylePoint { - private lastContent: string | undefined; - private lastUrl: string | undefined; - private placeholder: Element | Text; - - constructor(readonly level: number, readonly id?: string) { - let placeholder: any; - if (id) { - placeholder = document.head.querySelector(`style[data-id="${id}"]`); - } - if (!placeholder) { - placeholder = document.createTextNode(''); - const meta = document.head.querySelector(`meta[level="${level}"]`); - if (meta) { - document.head.insertBefore(placeholder, meta); - } else { - document.head.appendChild(placeholder); - } - } - this.placeholder = placeholder; - } - - applyText(content: string) { - if (this.lastContent === content) { - return; - } - this.lastContent = content; - this.lastUrl = undefined; - const element = document.createElement('style'); - element.setAttribute('type', 'text/css'); - if (this.id) { - element.setAttribute('data-id', this.id); - } - element.appendChild(document.createTextNode(content)); - document.head.insertBefore(element, this.placeholder.parentNode === document.head ? this.placeholder.nextSibling : null); - document.head.removeChild(this.placeholder); - this.placeholder = element; - } - - applyUrl(url: string) { - if (this.lastUrl === url) { - return; - } - this.lastContent = undefined; - this.lastUrl = url; - const element = document.createElement('link'); - element.onload = onload; - element.onerror = onload; - - const i = createDefer(); - function onload(e: any) { - element.onload = null; - element.onerror = null; - if (e.type === 'load') { - i.resolve(); - } else { - i.reject(); - } - } - - element.href = url; - element.rel = 'stylesheet'; - if (this.id) { - element.setAttribute('data-id', this.id); - } - document.head.insertBefore(element, this.placeholder.parentNode === document.head ? this.placeholder.nextSibling : null); - document.head.removeChild(this.placeholder); - this.placeholder = element; - return i.promise(); - } -}