// NOTE: 仅用作类型标注,切勿作为实体使用 import { SimulatorRenderer } from '../renderer/renderer'; 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 { const win: any = iframe.contentWindow; const doc = iframe.contentDocument!; win.LCSimulatorHost = host; const styles: any = {}; const scripts: any = {}; AssetLevels.forEach(lv => { styles[lv] = []; scripts[lv] = []; }); function parseAssetList(assets: AssetList, level?: AssetLevel) { for (let asset of assets) { if (!asset) { continue; } if (isAssetBundle(asset)) { if (asset.assets) { parseAssetList(Array.isArray(asset.assets) ? asset.assets : [asset.assets], asset.level || level); } continue; } if (Array.isArray(asset)) { parseAssetList(asset, level); continue; } if (!isAssetItem(asset)) { asset = assetItem(isCSSUrl(asset) ? AssetType.CSSUrl : AssetType.JSUrl, asset, level)!; } const id = asset.id ? ` data-id="${asset.id}"` : ''; const lv = asset.level || level || AssetLevel.Environment; if (asset.type === AssetType.JSUrl) { (scripts[lv] || scripts[AssetLevel.App]).push(``); } else if (asset.type === AssetType.JSText) { (scripts[lv] || scripts[AssetLevel.App]).push(`${asset.content}`); } else if (asset.type === AssetType.CSSUrl) { (styles[lv] || styles[AssetLevel.App]).push(``); } else if (asset.type === AssetType.CSSText) { (styles[lv] || styles[AssetLevel.App]).push(``); } } } parseAssetList(vendors); const styleFrags = Object.keys(styles) .map(key => { return styles[key].join('\n') + ``; }) .join(''); const scriptFrags = Object.keys(scripts) .map(key => { return scripts[key].join('\n'); }) .join(''); doc.open(); doc.write(` ${styleFrags} ${scriptFrags}`); doc.close(); return new Promise(resolve => { if (win.SimulatorRenderer || host.renderer) { return resolve(win.SimulatorRenderer || host.renderer); } const loaded = () => { resolve(win.SimulatorRenderer || host.renderer); win.removeEventListener('load', loaded); }; win.addEventListener('load', loaded); }); }