xpe 0.0.0-alpha.1 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +627 -71
- package/dist/child/app-client.d.ts +44 -0
- package/dist/child/app-client.js +151 -0
- package/dist/child/index.d.ts +3 -0
- package/dist/child/index.js +3 -0
- package/dist/child/lifecycle.d.ts +12 -0
- package/dist/child/lifecycle.js +47 -0
- package/dist/child/mock-host.d.ts +8 -0
- package/dist/child/mock-host.js +41 -0
- package/dist/core/bridge.d.ts +28 -0
- package/dist/core/bridge.js +19 -0
- package/dist/core/events.d.ts +13 -0
- package/dist/core/events.js +56 -0
- package/dist/core/index.d.ts +3 -0
- package/dist/core/index.js +3 -0
- package/dist/core/types.d.ts +102 -0
- package/dist/core/types.js +20 -0
- package/dist/dev-shell/index.d.ts +26 -0
- package/dist/dev-shell/index.js +56 -0
- package/dist/host/app-path-router.d.ts +33 -0
- package/dist/host/app-path-router.js +183 -0
- package/dist/host/host-runtime.d.ts +29 -0
- package/dist/host/host-runtime.js +176 -0
- package/dist/host/index.d.ts +1 -0
- package/dist/host/index.js +1 -0
- package/dist/host/xpe-host.d.ts +41 -0
- package/dist/host/xpe-host.js +61 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.js +4 -0
- package/dist/kernel/common.d.ts +62 -0
- package/dist/kernel/common.js +207 -0
- package/dist/kernel/constant.d.ts +26 -0
- package/dist/kernel/constant.js +42 -0
- package/dist/kernel/effect.d.ts +32 -0
- package/dist/kernel/effect.js +529 -0
- package/dist/kernel/entry.d.ts +43 -0
- package/dist/kernel/entry.js +224 -0
- package/dist/kernel/event.d.ts +22 -0
- package/dist/kernel/event.js +120 -0
- package/dist/kernel/iframe.d.ts +141 -0
- package/dist/kernel/iframe.js +1104 -0
- package/dist/kernel/index.d.ts +25 -0
- package/dist/kernel/index.js +86 -0
- package/dist/kernel/plugin.d.ts +36 -0
- package/dist/kernel/plugin.js +68 -0
- package/dist/kernel/proxy.d.ts +17 -0
- package/dist/kernel/proxy.js +440 -0
- package/dist/kernel/runtime-engine.d.ts +154 -0
- package/dist/kernel/runtime-engine.js +209 -0
- package/dist/kernel/sandbox.d.ts +235 -0
- package/dist/kernel/sandbox.js +879 -0
- package/dist/kernel/shadow.d.ts +64 -0
- package/dist/kernel/shadow.js +385 -0
- package/dist/kernel/sync.d.ts +21 -0
- package/dist/kernel/sync.js +185 -0
- package/dist/kernel/template.d.ts +67 -0
- package/dist/kernel/template.js +226 -0
- package/dist/kernel/tracker.d.ts +44 -0
- package/dist/kernel/tracker.js +92 -0
- package/dist/kernel/utils.d.ts +100 -0
- package/dist/kernel/utils.js +325 -0
- package/dist/kernel/xpe-bridge.d.ts +27 -0
- package/dist/kernel/xpe-bridge.js +205 -0
- package/dist/shared/index.d.ts +1 -0
- package/dist/shared/index.js +3 -0
- package/package.json +79 -57
- package/LICENSE +0 -21
- package/framework/es/core/Application.d.ts +0 -126
- package/framework/es/core/Command/Command.d.ts +0 -7
- package/framework/es/core/Container/Container.d.ts +0 -80
- package/framework/es/core/Contracts/AxiosAdapter.d.ts +0 -12
- package/framework/es/core/Helper/Helper.d.ts +0 -43
- package/framework/es/core/Helper/Storage/WebStorage.d.ts +0 -71
- package/framework/es/core/Libs/Exception.d.ts +0 -24
- package/framework/es/core/Libs/Lib.d.ts +0 -72
- package/framework/es/core/Provider/CommandProvider.d.ts +0 -4
- package/framework/es/core/Provider/HelperProvider.d.ts +0 -4
- package/framework/es/core/Provider/HttpProvider.d.ts +0 -13
- package/framework/es/core/Provider/ServiceProvider.d.ts +0 -15
- package/framework/es/core/Service/HttpService.d.ts +0 -133
- package/framework/es/core/Service/Service.d.ts +0 -6
- package/framework/es/core/Spanner/RESTful.d.ts +0 -30
- package/framework/es/core/Transformer/Transformer.d.ts +0 -46
- package/framework/es/core/Type/adapters.d.ts +0 -25
- package/framework/es/core/Type/types.d.ts +0 -161
- package/framework/es/core/TypeFunc/index.d.ts +0 -6
- package/framework/es/core/Wrenches/EventBus.d.ts +0 -56
- package/framework/es/core/Wrenches/is.d.ts +0 -19
- package/framework/es/ege.js +0 -4
- package/framework/es/ege.js.map +0 -1
- package/framework/es/index.d.ts +0 -13
- package/framework/es/pdd.js +0 -4
- package/framework/es/pdd.js.map +0 -1
- package/framework/es/src/core/Application.d.ts +0 -127
- package/framework/es/src/core/Application.d.ts.map +0 -1
- package/framework/es/src/core/Command/Command.d.ts +0 -8
- package/framework/es/src/core/Command/Command.d.ts.map +0 -1
- package/framework/es/src/core/Container/Container.d.ts +0 -81
- package/framework/es/src/core/Container/Container.d.ts.map +0 -1
- package/framework/es/src/core/Contracts/AxiosAdapter.d.ts +0 -13
- package/framework/es/src/core/Contracts/AxiosAdapter.d.ts.map +0 -1
- package/framework/es/src/core/Helper/Helper.d.ts +0 -45
- package/framework/es/src/core/Helper/Helper.d.ts.map +0 -1
- package/framework/es/src/core/Helper/Storage/WebStorage.d.ts +0 -72
- package/framework/es/src/core/Helper/Storage/WebStorage.d.ts.map +0 -1
- package/framework/es/src/core/Libs/Exception.d.ts +0 -25
- package/framework/es/src/core/Libs/Exception.d.ts.map +0 -1
- package/framework/es/src/core/Libs/Lib.d.ts +0 -73
- package/framework/es/src/core/Libs/Lib.d.ts.map +0 -1
- package/framework/es/src/core/Provider/CommandProvider.d.ts +0 -5
- package/framework/es/src/core/Provider/CommandProvider.d.ts.map +0 -1
- package/framework/es/src/core/Provider/HelperProvider.d.ts +0 -5
- package/framework/es/src/core/Provider/HelperProvider.d.ts.map +0 -1
- package/framework/es/src/core/Provider/HttpProvider.d.ts +0 -14
- package/framework/es/src/core/Provider/HttpProvider.d.ts.map +0 -1
- package/framework/es/src/core/Provider/ServiceProvider.d.ts +0 -16
- package/framework/es/src/core/Provider/ServiceProvider.d.ts.map +0 -1
- package/framework/es/src/core/Service/HttpService.d.ts +0 -128
- package/framework/es/src/core/Service/HttpService.d.ts.map +0 -1
- package/framework/es/src/core/Service/Service.d.ts +0 -7
- package/framework/es/src/core/Service/Service.d.ts.map +0 -1
- package/framework/es/src/core/Spanner/RESTful.d.ts +0 -32
- package/framework/es/src/core/Spanner/RESTful.d.ts.map +0 -1
- package/framework/es/src/core/Transformer/Transformer.d.ts +0 -47
- package/framework/es/src/core/Transformer/Transformer.d.ts.map +0 -1
- package/framework/es/src/core/Type/adapters.d.ts +0 -26
- package/framework/es/src/core/Type/adapters.d.ts.map +0 -1
- package/framework/es/src/core/Type/types.d.ts +0 -186
- package/framework/es/src/core/Type/types.d.ts.map +0 -1
- package/framework/es/src/core/TypeFunc/index.d.ts +0 -8
- package/framework/es/src/core/TypeFunc/index.d.ts.map +0 -1
- package/framework/es/src/core/Wrenches/EventBus.d.ts +0 -57
- package/framework/es/src/core/Wrenches/EventBus.d.ts.map +0 -1
- package/framework/es/src/core/Wrenches/is.d.ts +0 -20
- package/framework/es/src/core/Wrenches/is.d.ts.map +0 -1
- package/framework/es/src/index.d.ts +0 -14
- package/framework/es/src/index.d.ts.map +0 -1
- package/framework/es/src/utils.d.ts +0 -17
- package/framework/es/src/utils.d.ts.map +0 -1
- package/framework/es/utils.d.ts +0 -16
- package/framework/umd/core/Application.d.ts +0 -126
- package/framework/umd/core/Command/Command.d.ts +0 -7
- package/framework/umd/core/Container/Container.d.ts +0 -80
- package/framework/umd/core/Contracts/AxiosAdapter.d.ts +0 -12
- package/framework/umd/core/Helper/Helper.d.ts +0 -43
- package/framework/umd/core/Helper/Storage/WebStorage.d.ts +0 -71
- package/framework/umd/core/Libs/Exception.d.ts +0 -24
- package/framework/umd/core/Libs/Lib.d.ts +0 -72
- package/framework/umd/core/Provider/CommandProvider.d.ts +0 -4
- package/framework/umd/core/Provider/HelperProvider.d.ts +0 -4
- package/framework/umd/core/Provider/HttpProvider.d.ts +0 -13
- package/framework/umd/core/Provider/ServiceProvider.d.ts +0 -15
- package/framework/umd/core/Service/HttpService.d.ts +0 -133
- package/framework/umd/core/Service/Service.d.ts +0 -6
- package/framework/umd/core/Spanner/RESTful.d.ts +0 -30
- package/framework/umd/core/Transformer/Transformer.d.ts +0 -46
- package/framework/umd/core/Type/adapters.d.ts +0 -25
- package/framework/umd/core/Type/types.d.ts +0 -161
- package/framework/umd/core/TypeFunc/index.d.ts +0 -6
- package/framework/umd/core/Wrenches/EventBus.d.ts +0 -56
- package/framework/umd/core/Wrenches/is.d.ts +0 -19
- package/framework/umd/ege.js +0 -4
- package/framework/umd/ege.js.map +0 -1
- package/framework/umd/index.d.ts +0 -13
- package/framework/umd/pdd.js +0 -4
- package/framework/umd/pdd.js.map +0 -1
- package/framework/umd/src/core/Application.d.ts +0 -127
- package/framework/umd/src/core/Application.d.ts.map +0 -1
- package/framework/umd/src/core/Command/Command.d.ts +0 -8
- package/framework/umd/src/core/Command/Command.d.ts.map +0 -1
- package/framework/umd/src/core/Container/Container.d.ts +0 -81
- package/framework/umd/src/core/Container/Container.d.ts.map +0 -1
- package/framework/umd/src/core/Contracts/AxiosAdapter.d.ts +0 -13
- package/framework/umd/src/core/Contracts/AxiosAdapter.d.ts.map +0 -1
- package/framework/umd/src/core/Helper/Helper.d.ts +0 -45
- package/framework/umd/src/core/Helper/Helper.d.ts.map +0 -1
- package/framework/umd/src/core/Helper/Storage/WebStorage.d.ts +0 -72
- package/framework/umd/src/core/Helper/Storage/WebStorage.d.ts.map +0 -1
- package/framework/umd/src/core/Libs/Exception.d.ts +0 -25
- package/framework/umd/src/core/Libs/Exception.d.ts.map +0 -1
- package/framework/umd/src/core/Libs/Lib.d.ts +0 -73
- package/framework/umd/src/core/Libs/Lib.d.ts.map +0 -1
- package/framework/umd/src/core/Provider/CommandProvider.d.ts +0 -5
- package/framework/umd/src/core/Provider/CommandProvider.d.ts.map +0 -1
- package/framework/umd/src/core/Provider/HelperProvider.d.ts +0 -5
- package/framework/umd/src/core/Provider/HelperProvider.d.ts.map +0 -1
- package/framework/umd/src/core/Provider/HttpProvider.d.ts +0 -14
- package/framework/umd/src/core/Provider/HttpProvider.d.ts.map +0 -1
- package/framework/umd/src/core/Provider/ServiceProvider.d.ts +0 -16
- package/framework/umd/src/core/Provider/ServiceProvider.d.ts.map +0 -1
- package/framework/umd/src/core/Service/HttpService.d.ts +0 -128
- package/framework/umd/src/core/Service/HttpService.d.ts.map +0 -1
- package/framework/umd/src/core/Service/Service.d.ts +0 -7
- package/framework/umd/src/core/Service/Service.d.ts.map +0 -1
- package/framework/umd/src/core/Spanner/RESTful.d.ts +0 -32
- package/framework/umd/src/core/Spanner/RESTful.d.ts.map +0 -1
- package/framework/umd/src/core/Transformer/Transformer.d.ts +0 -47
- package/framework/umd/src/core/Transformer/Transformer.d.ts.map +0 -1
- package/framework/umd/src/core/Type/adapters.d.ts +0 -26
- package/framework/umd/src/core/Type/adapters.d.ts.map +0 -1
- package/framework/umd/src/core/Type/types.d.ts +0 -186
- package/framework/umd/src/core/Type/types.d.ts.map +0 -1
- package/framework/umd/src/core/TypeFunc/index.d.ts +0 -8
- package/framework/umd/src/core/TypeFunc/index.d.ts.map +0 -1
- package/framework/umd/src/core/Wrenches/EventBus.d.ts +0 -57
- package/framework/umd/src/core/Wrenches/EventBus.d.ts.map +0 -1
- package/framework/umd/src/core/Wrenches/is.d.ts +0 -20
- package/framework/umd/src/core/Wrenches/is.d.ts.map +0 -1
- package/framework/umd/src/index.d.ts +0 -14
- package/framework/umd/src/index.d.ts.map +0 -1
- package/framework/umd/src/utils.d.ts +0 -17
- package/framework/umd/src/utils.d.ts.map +0 -1
- package/framework/umd/utils.d.ts +0 -16
- package/index.d.ts +0 -724
|
@@ -0,0 +1,529 @@
|
|
|
1
|
+
import { getExternalStyleSheets, getExternalScripts } from "./entry.js";
|
|
2
|
+
import { getSandboxById, rawAppendChild, rawElementContains, rawElementRemoveChild, rawHeadInsertBefore, rawBodyInsertBefore, rawInsertAdjacentElement, rawDocumentQuerySelector, rawAddEventListener, rawRemoveEventListener, } from "./common.js";
|
|
3
|
+
import { isFunction, isHijackingTag, warn, nextTick, getCurUrl, getAbsolutePath, execHooks, isScriptElement, setTagToScript, getTagFromScript, setAttrsToElement, } from "./utils.js";
|
|
4
|
+
import { insertScriptToIframe, patchElementEffect } from "./iframe.js";
|
|
5
|
+
import { getPatchStyleElements } from "./shadow.js";
|
|
6
|
+
import { getCssLoader, getEffectLoaders, isMatchUrl } from "./plugin.js";
|
|
7
|
+
import { XPE_SCRIPT_ID, XPE_DATA_FLAG, XPE_TIPS_REPEAT_RENDER, XPE_TIPS_NO_SCRIPT } from "./constant.js";
|
|
8
|
+
import { parseTagAttributes } from "./template.js";
|
|
9
|
+
import { getXpeRawDocumentHead } from "./xpe-bridge.js";
|
|
10
|
+
function patchCustomEvent(e, elementGetter) {
|
|
11
|
+
Object.defineProperties(e, {
|
|
12
|
+
srcElement: {
|
|
13
|
+
get: elementGetter,
|
|
14
|
+
},
|
|
15
|
+
target: {
|
|
16
|
+
get: elementGetter,
|
|
17
|
+
},
|
|
18
|
+
});
|
|
19
|
+
return e;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* 手动触发事件回调
|
|
23
|
+
*/
|
|
24
|
+
function manualInvokeElementEvent(element, event) {
|
|
25
|
+
const customEvent = new CustomEvent(event);
|
|
26
|
+
const patchedEvent = patchCustomEvent(customEvent, () => element);
|
|
27
|
+
if (isFunction(element[`on${event}`])) {
|
|
28
|
+
element[`on${event}`](patchedEvent);
|
|
29
|
+
}
|
|
30
|
+
else {
|
|
31
|
+
element.dispatchEvent(patchedEvent);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
function getActiveSandboxContext(sandboxId) {
|
|
35
|
+
const sandbox = getSandboxById(sandboxId);
|
|
36
|
+
const iframeWindow = sandbox?.iframe?.contentWindow;
|
|
37
|
+
const iframeDocument = sandbox?.iframe?.contentDocument;
|
|
38
|
+
if (!sandbox || sandbox.isDestroyed() || !iframeWindow || !iframeDocument)
|
|
39
|
+
return null;
|
|
40
|
+
return { sandbox, iframeWindow, iframeDocument };
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* 样式元素的css变量处理,每个stylesheetElement单独节流
|
|
44
|
+
*/
|
|
45
|
+
function handleStylesheetElementPatch(stylesheetElement, sandbox) {
|
|
46
|
+
if (!stylesheetElement.innerHTML || sandbox.degrade)
|
|
47
|
+
return;
|
|
48
|
+
const patcher = () => {
|
|
49
|
+
try {
|
|
50
|
+
if (sandbox.isDestroyed() || !stylesheetElement.sheet || !sandbox.shadowRoot)
|
|
51
|
+
return;
|
|
52
|
+
const shadowHead = sandbox.shadowRoot.head;
|
|
53
|
+
const shadowHost = sandbox.shadowRoot.host;
|
|
54
|
+
if (!shadowHead || !shadowHost)
|
|
55
|
+
return;
|
|
56
|
+
const [hostStyleSheetElement, fontStyleSheetElement] = getPatchStyleElements([stylesheetElement.sheet]);
|
|
57
|
+
if (hostStyleSheetElement) {
|
|
58
|
+
shadowHead.appendChild(hostStyleSheetElement);
|
|
59
|
+
}
|
|
60
|
+
if (fontStyleSheetElement) {
|
|
61
|
+
shadowHost.appendChild(fontStyleSheetElement);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
finally {
|
|
65
|
+
stylesheetElement._patcher = undefined;
|
|
66
|
+
}
|
|
67
|
+
};
|
|
68
|
+
if (stylesheetElement._patcher) {
|
|
69
|
+
clearTimeout(stylesheetElement._patcher);
|
|
70
|
+
}
|
|
71
|
+
stylesheetElement._patcher = setTimeout(patcher, 50);
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* 劫持处理样式元素的属性
|
|
75
|
+
* @internal 仅出于可测性导出,外部不应直接调用
|
|
76
|
+
*/
|
|
77
|
+
export function patchStylesheetElement(stylesheetElement, cssLoader, sandbox, curUrl) {
|
|
78
|
+
if (stylesheetElement._hasPatchStyle)
|
|
79
|
+
return;
|
|
80
|
+
const innerHTMLDesc = Object.getOwnPropertyDescriptor(Element.prototype, "innerHTML");
|
|
81
|
+
const innerTextDesc = Object.getOwnPropertyDescriptor(HTMLElement.prototype, "innerText");
|
|
82
|
+
const textContentDesc = Object.getOwnPropertyDescriptor(Node.prototype, "textContent");
|
|
83
|
+
const RawInsertRule = stylesheetElement.sheet?.insertRule;
|
|
84
|
+
// 这个地方将cssRule加到innerHTML中去,防止子应用切换之后丢失
|
|
85
|
+
function patchSheetInsertRule() {
|
|
86
|
+
if (!RawInsertRule)
|
|
87
|
+
return;
|
|
88
|
+
stylesheetElement.sheet.insertRule = (rule, index) => {
|
|
89
|
+
innerHTMLDesc ? (stylesheetElement.innerHTML += rule) : (stylesheetElement.innerText += rule);
|
|
90
|
+
return RawInsertRule.call(stylesheetElement.sheet, rule, index);
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
patchSheetInsertRule();
|
|
94
|
+
if (innerHTMLDesc) {
|
|
95
|
+
Object.defineProperties(stylesheetElement, {
|
|
96
|
+
innerHTML: {
|
|
97
|
+
get: function () {
|
|
98
|
+
return innerHTMLDesc.get.call(stylesheetElement);
|
|
99
|
+
},
|
|
100
|
+
set: function (code) {
|
|
101
|
+
innerHTMLDesc.set.call(stylesheetElement, cssLoader(code, "", curUrl));
|
|
102
|
+
nextTick(() => handleStylesheetElementPatch(this, sandbox));
|
|
103
|
+
},
|
|
104
|
+
},
|
|
105
|
+
});
|
|
106
|
+
}
|
|
107
|
+
Object.defineProperties(stylesheetElement, {
|
|
108
|
+
innerText: {
|
|
109
|
+
get: function () {
|
|
110
|
+
return innerTextDesc.get.call(stylesheetElement);
|
|
111
|
+
},
|
|
112
|
+
set: function (code) {
|
|
113
|
+
innerTextDesc.set.call(stylesheetElement, cssLoader(code, "", curUrl));
|
|
114
|
+
nextTick(() => handleStylesheetElementPatch(this, sandbox));
|
|
115
|
+
},
|
|
116
|
+
},
|
|
117
|
+
textContent: {
|
|
118
|
+
get: function () {
|
|
119
|
+
return textContentDesc.get.call(stylesheetElement);
|
|
120
|
+
},
|
|
121
|
+
set: function (code) {
|
|
122
|
+
textContentDesc.set.call(stylesheetElement, cssLoader(code, "", curUrl));
|
|
123
|
+
nextTick(() => handleStylesheetElementPatch(this, sandbox));
|
|
124
|
+
},
|
|
125
|
+
},
|
|
126
|
+
appendChild: {
|
|
127
|
+
value: function (node) {
|
|
128
|
+
nextTick(() => handleStylesheetElementPatch(this, sandbox));
|
|
129
|
+
if (node.nodeType === Node.TEXT_NODE) {
|
|
130
|
+
const res = rawAppendChild.call(stylesheetElement, stylesheetElement.ownerDocument.createTextNode(cssLoader(node.textContent, "", curUrl)));
|
|
131
|
+
// 当appendChild之后,样式元素的sheet对象发生改变,要重新patch
|
|
132
|
+
patchSheetInsertRule();
|
|
133
|
+
return res;
|
|
134
|
+
}
|
|
135
|
+
else
|
|
136
|
+
return rawAppendChild.call(stylesheetElement, node);
|
|
137
|
+
},
|
|
138
|
+
},
|
|
139
|
+
insertAdjacentElement: {
|
|
140
|
+
value: function (position, element) {
|
|
141
|
+
if (element.nodeName === "STYLE") {
|
|
142
|
+
// vite dev server 第一个 css 通过 head.appendChild 插入,后续每个 css 都走
|
|
143
|
+
// lastInsertedStyle.insertAdjacentElement("afterend", style),hot update 时
|
|
144
|
+
// 直接 style.textContent = newContent。被 insertAdjacentElement 插入的 style
|
|
145
|
+
// 必须获得与"第一个 style"完全一致的劫持能力,否则:
|
|
146
|
+
// 1) 当前内容里的资源相对路径不会被 cssLoader 改写(@font-face 失效);
|
|
147
|
+
// 2) 后续 textContent / innerHTML / appendChild / sheet.insertRule
|
|
148
|
+
// 绕过 XPE runtime,hot update 全部脱管;
|
|
149
|
+
// 3) 链式 insertAdjacentElement 创建的下游 style 直接走原生实现。
|
|
150
|
+
// 因此这里必须复用与 case "STYLE" 完全一致的处理流程:先用 cssLoader 改写
|
|
151
|
+
// 当前内容,再 patchStylesheetElement 把劫持递归装到新 style 上。
|
|
152
|
+
const stylesheetElement = element;
|
|
153
|
+
const content = stylesheetElement.innerHTML;
|
|
154
|
+
if (content)
|
|
155
|
+
stylesheetElement.innerHTML = cssLoader(content, "", curUrl);
|
|
156
|
+
const res = rawInsertAdjacentElement.call(this, position, element);
|
|
157
|
+
sandbox.styleSheetElements.push(stylesheetElement);
|
|
158
|
+
patchStylesheetElement(stylesheetElement, cssLoader, sandbox, curUrl);
|
|
159
|
+
handleStylesheetElementPatch(stylesheetElement, sandbox);
|
|
160
|
+
return res;
|
|
161
|
+
}
|
|
162
|
+
else
|
|
163
|
+
return rawInsertAdjacentElement.call(this, position, element);
|
|
164
|
+
},
|
|
165
|
+
},
|
|
166
|
+
_hasPatchStyle: { get: () => true },
|
|
167
|
+
});
|
|
168
|
+
}
|
|
169
|
+
// href 延迟赋值的兜底超时(毫秒):超过该时间仍未拿到 href,则放弃监听并触发 error,
|
|
170
|
+
// 防止「href 永不到达」时 observer 闭包长期钉住子应用上下文。沿用 tinymce maxLoadTime 量级。
|
|
171
|
+
const DEFER_STYLE_HREF_TIMEOUT = 5000;
|
|
172
|
+
/**
|
|
173
|
+
* 处理「先 appendChild(link) 后 setAttribute('href')」的延迟 href 场景。
|
|
174
|
+
*
|
|
175
|
+
* 通过 MutationObserver 监听 href 属性赋值,命中后走传入的 loadStyleSheet 完成加载。
|
|
176
|
+
* 生命周期管理(避免内存泄漏):
|
|
177
|
+
* 1. 命中 / 超时 / 子应用已销毁 时立即 disconnect 并从 sandbox 出队;
|
|
178
|
+
* 2. observer 登记到 sandbox.deferredStyleObservers,destroy 阶段统一兜底 disconnect;
|
|
179
|
+
* 3. 回调内通过 sandboxId 动态获取 sandbox,不捕获 sandbox/iframe,子应用销毁后闭包不再 pin 上下文。
|
|
180
|
+
*/
|
|
181
|
+
export function deferStyleSheetByHref(opts) {
|
|
182
|
+
let { element } = opts;
|
|
183
|
+
const { sandboxId, iframeWindow, loadStyleSheet } = opts;
|
|
184
|
+
// 部分环境(jsdom / 老浏览器)可能不支持 MutationObserver,直接放弃延迟处理
|
|
185
|
+
const MutationObserverCtor = iframeWindow.MutationObserver;
|
|
186
|
+
if (typeof MutationObserverCtor !== "function")
|
|
187
|
+
return;
|
|
188
|
+
let settled = false;
|
|
189
|
+
let timer = null;
|
|
190
|
+
const observer = new MutationObserverCtor(() => {
|
|
191
|
+
if (settled)
|
|
192
|
+
return;
|
|
193
|
+
const attrHref = element?.getAttribute("href");
|
|
194
|
+
if (!attrHref)
|
|
195
|
+
return;
|
|
196
|
+
const realHref = element.href || attrHref;
|
|
197
|
+
const target = element;
|
|
198
|
+
finalize(() => target && loadStyleSheet(realHref, target));
|
|
199
|
+
});
|
|
200
|
+
// 统一收尾:disconnect + 出队 + 清理定时器,再执行收尾动作
|
|
201
|
+
function finalize(action) {
|
|
202
|
+
if (settled)
|
|
203
|
+
return;
|
|
204
|
+
settled = true;
|
|
205
|
+
if (timer !== null) {
|
|
206
|
+
clearTimeout(timer);
|
|
207
|
+
timer = null;
|
|
208
|
+
}
|
|
209
|
+
try {
|
|
210
|
+
observer.disconnect();
|
|
211
|
+
}
|
|
212
|
+
catch (_) {
|
|
213
|
+
/* noop */
|
|
214
|
+
}
|
|
215
|
+
// 动态获取 sandbox,子应用销毁后直接放手,闭包不再钉住上下文
|
|
216
|
+
const sandbox = getSandboxById(sandboxId);
|
|
217
|
+
const observers = sandbox?.deferredStyleObservers;
|
|
218
|
+
if (Array.isArray(observers)) {
|
|
219
|
+
const index = observers.indexOf(observer);
|
|
220
|
+
if (index !== -1)
|
|
221
|
+
observers.splice(index, 1);
|
|
222
|
+
}
|
|
223
|
+
if (sandbox)
|
|
224
|
+
action?.();
|
|
225
|
+
element = null;
|
|
226
|
+
}
|
|
227
|
+
const sandbox = getSandboxById(sandboxId);
|
|
228
|
+
// 子应用已不存在则无需监听
|
|
229
|
+
if (!sandbox || !Array.isArray(sandbox.deferredStyleObservers))
|
|
230
|
+
return;
|
|
231
|
+
sandbox.deferredStyleObservers.push(observer);
|
|
232
|
+
observer.observe(element, { attributes: true, attributeFilter: ["href"] });
|
|
233
|
+
// 超时兜底:长时间没等到 href,放弃监听并触发 error,让上游(如 tinymce)的失败回调收尾
|
|
234
|
+
timer = setTimeout(() => {
|
|
235
|
+
const target = element;
|
|
236
|
+
finalize();
|
|
237
|
+
if (target)
|
|
238
|
+
manualInvokeElementEvent(target, "error");
|
|
239
|
+
}, DEFER_STYLE_HREF_TIMEOUT);
|
|
240
|
+
}
|
|
241
|
+
function rewriteAppendOrInsertChild(opts) {
|
|
242
|
+
return function appendChildOrInsertBefore(newChild, refChild) {
|
|
243
|
+
let element = newChild;
|
|
244
|
+
const { rawDOMAppendOrInsertBefore, sandboxId } = opts;
|
|
245
|
+
const activeContext = getActiveSandboxContext(sandboxId);
|
|
246
|
+
if (!activeContext) {
|
|
247
|
+
return rawDOMAppendOrInsertBefore.call(this, element, refChild);
|
|
248
|
+
}
|
|
249
|
+
const { sandbox, iframeWindow, iframeDocument } = activeContext;
|
|
250
|
+
const { styleSheetElements, replace, fetch, plugins, lifecycles, proxyLocation, fiber } = sandbox;
|
|
251
|
+
if (!isHijackingTag(element.tagName) || !sandboxId) {
|
|
252
|
+
const res = rawDOMAppendOrInsertBefore.call(this, element, refChild);
|
|
253
|
+
patchElementEffect(element, iframeWindow);
|
|
254
|
+
execHooks(plugins, "appendOrInsertElementHook", element, iframeWindow);
|
|
255
|
+
return res;
|
|
256
|
+
}
|
|
257
|
+
const curUrl = getCurUrl(proxyLocation);
|
|
258
|
+
// TODO 过滤可以开放
|
|
259
|
+
if (element.tagName) {
|
|
260
|
+
switch (element.tagName?.toUpperCase()) {
|
|
261
|
+
case "LINK": {
|
|
262
|
+
const { href, rel, type } = element;
|
|
263
|
+
const styleFlag = rel === "stylesheet" || type === "text/css" || href.endsWith(".css");
|
|
264
|
+
// 非 stylesheet 不做处理
|
|
265
|
+
if (!styleFlag) {
|
|
266
|
+
const res = rawDOMAppendOrInsertBefore.call(this, element, refChild);
|
|
267
|
+
execHooks(plugins, "appendOrInsertElementHook", element, iframeWindow);
|
|
268
|
+
return res;
|
|
269
|
+
}
|
|
270
|
+
// 拉取 css 内容并以 <style> 注入子应用、回调 link 的 load/error 事件。
|
|
271
|
+
// 抽成闭包以便「append 时已有 href」与「append 后才 setAttribute('href')」两条路径复用。
|
|
272
|
+
const loadStyleSheet = (realHref, linkElement) => {
|
|
273
|
+
const attrHref = linkElement.getAttribute("href");
|
|
274
|
+
const styleHref = attrHref ? getAbsolutePath(attrHref, proxyLocation.href) : realHref;
|
|
275
|
+
const exclude = isMatchUrl(styleHref, getEffectLoaders("cssExcludes", plugins));
|
|
276
|
+
if (!styleHref || exclude)
|
|
277
|
+
return;
|
|
278
|
+
getExternalStyleSheets([{ src: styleHref, ignore: isMatchUrl(styleHref, getEffectLoaders("cssIgnores", plugins)) }], fetch, lifecycles.loadError).forEach(({ src, ignore, contentPromise }) => contentPromise.then((content) => {
|
|
279
|
+
const latestContext = getActiveSandboxContext(sandboxId);
|
|
280
|
+
if (!latestContext)
|
|
281
|
+
return;
|
|
282
|
+
// 处理 ignore 样式
|
|
283
|
+
const rawAttrs = parseTagAttributes(linkElement.outerHTML);
|
|
284
|
+
if (ignore && src) {
|
|
285
|
+
// 忽略的元素应该直接把对应元素插入,而不是用新的 link 标签进行替代插入,保证 element 的上下文正常
|
|
286
|
+
rawDOMAppendOrInsertBefore.call(this, linkElement, refChild);
|
|
287
|
+
}
|
|
288
|
+
else {
|
|
289
|
+
// 记录js插入样式,子应用重新激活时恢复
|
|
290
|
+
const stylesheetElement = latestContext.iframeDocument.createElement("style");
|
|
291
|
+
// 处理css-loader插件
|
|
292
|
+
const cssLoader = getCssLoader({ plugins, replace });
|
|
293
|
+
stylesheetElement.innerHTML = cssLoader(content, src, curUrl);
|
|
294
|
+
latestContext.sandbox.styleSheetElements.push(stylesheetElement);
|
|
295
|
+
setAttrsToElement(stylesheetElement, rawAttrs);
|
|
296
|
+
rawDOMAppendOrInsertBefore.call(this, stylesheetElement, refChild);
|
|
297
|
+
// 处理样式补丁
|
|
298
|
+
handleStylesheetElementPatch(stylesheetElement, latestContext.sandbox);
|
|
299
|
+
manualInvokeElementEvent(linkElement, "load");
|
|
300
|
+
}
|
|
301
|
+
if (element === linkElement)
|
|
302
|
+
element = null;
|
|
303
|
+
}, () => {
|
|
304
|
+
manualInvokeElementEvent(linkElement, "error");
|
|
305
|
+
if (element === linkElement)
|
|
306
|
+
element = null;
|
|
307
|
+
}));
|
|
308
|
+
};
|
|
309
|
+
if (href) {
|
|
310
|
+
// 排除css
|
|
311
|
+
if (!isMatchUrl(href, getEffectLoaders("cssExcludes", plugins))) {
|
|
312
|
+
loadStyleSheet(href, element);
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
else {
|
|
316
|
+
// 部分库(如 tinymce 的 StyleSheetLoader)先 appendChild(link) 再
|
|
317
|
+
// setAttribute('href', url)。此时 href 为空,若直接丢弃则该样式永远不会被加载,
|
|
318
|
+
// 后续在游离 link 上设置 href 也不会触发浏览器加载,skin.min.css 等资源缺失。
|
|
319
|
+
// 这里监听 href 的后续赋值,拿到真实 href 后再走与上面完全一致的加载流程。
|
|
320
|
+
deferStyleSheetByHref({ element, sandboxId, iframeWindow, loadStyleSheet });
|
|
321
|
+
}
|
|
322
|
+
const comment = iframeDocument.createComment(`dynamic link ${href} replaced by xpe`);
|
|
323
|
+
return rawDOMAppendOrInsertBefore.call(this, comment, refChild);
|
|
324
|
+
}
|
|
325
|
+
case "STYLE": {
|
|
326
|
+
const stylesheetElement = newChild;
|
|
327
|
+
styleSheetElements.push(stylesheetElement);
|
|
328
|
+
const content = stylesheetElement.innerHTML;
|
|
329
|
+
const cssLoader = getCssLoader({ plugins, replace });
|
|
330
|
+
content && (stylesheetElement.innerHTML = cssLoader(content, "", curUrl));
|
|
331
|
+
const res = rawDOMAppendOrInsertBefore.call(this, element, refChild);
|
|
332
|
+
// 处理样式补丁
|
|
333
|
+
patchStylesheetElement(stylesheetElement, cssLoader, sandbox, curUrl);
|
|
334
|
+
handleStylesheetElementPatch(stylesheetElement, sandbox);
|
|
335
|
+
execHooks(plugins, "appendOrInsertElementHook", element, iframeWindow);
|
|
336
|
+
return res;
|
|
337
|
+
}
|
|
338
|
+
case "SCRIPT": {
|
|
339
|
+
setTagToScript(element);
|
|
340
|
+
const { src, text, type, crossOrigin } = element;
|
|
341
|
+
// 排除js
|
|
342
|
+
if (src && !isMatchUrl(src, getEffectLoaders("jsExcludes", plugins))) {
|
|
343
|
+
const execScript = (scriptResult) => {
|
|
344
|
+
// 假如子应用被连续渲染两次,两次渲染会导致处理流程的交叉污染
|
|
345
|
+
const latestContext = getActiveSandboxContext(sandboxId);
|
|
346
|
+
if (!latestContext)
|
|
347
|
+
return warn(XPE_TIPS_REPEAT_RENDER);
|
|
348
|
+
const onload = () => {
|
|
349
|
+
manualInvokeElementEvent(element, "load");
|
|
350
|
+
element = null;
|
|
351
|
+
};
|
|
352
|
+
insertScriptToIframe({ ...scriptResult, onload }, latestContext.iframeWindow, element);
|
|
353
|
+
};
|
|
354
|
+
const scriptOptions = {
|
|
355
|
+
src,
|
|
356
|
+
module: type === "module",
|
|
357
|
+
crossorigin: crossOrigin !== null,
|
|
358
|
+
crossoriginType: crossOrigin || "",
|
|
359
|
+
ignore: isMatchUrl(src, getEffectLoaders("jsIgnores", plugins)),
|
|
360
|
+
attrs: parseTagAttributes(element.outerHTML),
|
|
361
|
+
};
|
|
362
|
+
getExternalScripts([scriptOptions], fetch, lifecycles.loadError, fiber).forEach((scriptResult) => {
|
|
363
|
+
sandbox.dynamicScriptExecStack = sandbox.dynamicScriptExecStack.then(() => scriptResult.contentPromise.then((content) => {
|
|
364
|
+
if (sandbox.isDestroyed() || sandbox.execQueue === null)
|
|
365
|
+
return warn(XPE_TIPS_REPEAT_RENDER);
|
|
366
|
+
const execQueueLength = sandbox.execQueue?.length;
|
|
367
|
+
sandbox.execQueue.push(() => fiber
|
|
368
|
+
? sandbox.requestIdleCallback(() => {
|
|
369
|
+
execScript({ ...scriptResult, content });
|
|
370
|
+
})
|
|
371
|
+
: execScript({ ...scriptResult, content }));
|
|
372
|
+
// 同步脚本如果都执行完了,需要手动触发执行
|
|
373
|
+
if (!execQueueLength)
|
|
374
|
+
sandbox.execQueue.shift()();
|
|
375
|
+
}, () => {
|
|
376
|
+
manualInvokeElementEvent(element, "error");
|
|
377
|
+
element = null;
|
|
378
|
+
}));
|
|
379
|
+
});
|
|
380
|
+
}
|
|
381
|
+
else {
|
|
382
|
+
const execQueueLength = sandbox.execQueue?.length;
|
|
383
|
+
sandbox.execQueue.push(() => fiber
|
|
384
|
+
? sandbox.requestIdleCallback(() => {
|
|
385
|
+
const latestContext = getActiveSandboxContext(sandboxId);
|
|
386
|
+
if (!latestContext)
|
|
387
|
+
return warn(XPE_TIPS_REPEAT_RENDER);
|
|
388
|
+
insertScriptToIframe({ src: null, content: text, attrs: parseTagAttributes(element.outerHTML) }, latestContext.iframeWindow, element);
|
|
389
|
+
})
|
|
390
|
+
: (() => {
|
|
391
|
+
const latestContext = getActiveSandboxContext(sandboxId);
|
|
392
|
+
if (!latestContext)
|
|
393
|
+
return warn(XPE_TIPS_REPEAT_RENDER);
|
|
394
|
+
insertScriptToIframe({ src: null, content: text, attrs: parseTagAttributes(element.outerHTML) }, latestContext.iframeWindow, element);
|
|
395
|
+
})());
|
|
396
|
+
if (!execQueueLength)
|
|
397
|
+
sandbox.execQueue.shift()();
|
|
398
|
+
}
|
|
399
|
+
// inline script never trigger the onload and onerror event
|
|
400
|
+
const comment = iframeDocument.createComment(`dynamic script ${src} replaced by xpe`);
|
|
401
|
+
return rawDOMAppendOrInsertBefore.call(this, comment, refChild);
|
|
402
|
+
}
|
|
403
|
+
// 修正子应用内部iframe的window.parent指向
|
|
404
|
+
case "IFRAME": {
|
|
405
|
+
// 嵌套的子应用的js-iframe需要插入子应用的js-iframe内部
|
|
406
|
+
if (element.getAttribute(XPE_DATA_FLAG) === "") {
|
|
407
|
+
return rawAppendChild.call(rawDocumentQuerySelector.call(this.ownerDocument, "html"), element);
|
|
408
|
+
}
|
|
409
|
+
const res = rawDOMAppendOrInsertBefore.call(this, element, refChild);
|
|
410
|
+
execHooks(plugins, "appendOrInsertElementHook", element, iframeWindow);
|
|
411
|
+
return res;
|
|
412
|
+
}
|
|
413
|
+
default: {
|
|
414
|
+
// 命中 isHijackingTag 但不属于 LINK/STYLE/SCRIPT/IFRAME 的标签,
|
|
415
|
+
// 仍需真正插入节点并返回,否则返回 undefined 会让调用方拿不到插入结果、
|
|
416
|
+
// 丢失节点(appendChild/insertBefore 约定返回被插入的节点)。
|
|
417
|
+
const res = rawDOMAppendOrInsertBefore.call(this, element, refChild);
|
|
418
|
+
execHooks(plugins, "appendOrInsertElementHook", element, iframeWindow);
|
|
419
|
+
return res;
|
|
420
|
+
}
|
|
421
|
+
}
|
|
422
|
+
}
|
|
423
|
+
};
|
|
424
|
+
}
|
|
425
|
+
function findScriptElementFromIframe(rawElement, sandboxId) {
|
|
426
|
+
const xpeTag = getTagFromScript(rawElement);
|
|
427
|
+
const activeContext = getActiveSandboxContext(sandboxId);
|
|
428
|
+
if (!activeContext)
|
|
429
|
+
return { targetScript: null, rawHead: null };
|
|
430
|
+
const rawHead = getXpeRawDocumentHead(activeContext.iframeWindow);
|
|
431
|
+
const targetScript = rawHead.querySelector(`script[${XPE_SCRIPT_ID}='${xpeTag}']`);
|
|
432
|
+
if (targetScript === null) {
|
|
433
|
+
warn(XPE_TIPS_NO_SCRIPT, `<script ${XPE_SCRIPT_ID}='${xpeTag}'/>`);
|
|
434
|
+
}
|
|
435
|
+
return { targetScript, rawHead };
|
|
436
|
+
}
|
|
437
|
+
function rewriteContains(opts) {
|
|
438
|
+
return function contains(other) {
|
|
439
|
+
const element = other;
|
|
440
|
+
const { rawElementContains, sandboxId } = opts;
|
|
441
|
+
if (element && isScriptElement(element)) {
|
|
442
|
+
const { targetScript } = findScriptElementFromIframe(element, sandboxId);
|
|
443
|
+
return targetScript !== null;
|
|
444
|
+
}
|
|
445
|
+
return rawElementContains(element);
|
|
446
|
+
};
|
|
447
|
+
}
|
|
448
|
+
function rewriteRemoveChild(opts) {
|
|
449
|
+
return function removeChild(child) {
|
|
450
|
+
const element = child;
|
|
451
|
+
const { rawElementRemoveChild, sandboxId } = opts;
|
|
452
|
+
if (element && isScriptElement(element)) {
|
|
453
|
+
const { targetScript, rawHead } = findScriptElementFromIframe(element, sandboxId);
|
|
454
|
+
if (targetScript !== null && rawHead) {
|
|
455
|
+
return rawHead.removeChild(targetScript);
|
|
456
|
+
}
|
|
457
|
+
return null;
|
|
458
|
+
}
|
|
459
|
+
return rawElementRemoveChild(element);
|
|
460
|
+
};
|
|
461
|
+
}
|
|
462
|
+
/**
|
|
463
|
+
* 记录head和body的事件,等重新渲染复用head和body时需要清空事件
|
|
464
|
+
*/
|
|
465
|
+
function patchEventListener(element) {
|
|
466
|
+
const listenerMap = new Map();
|
|
467
|
+
element._cacheListeners = listenerMap;
|
|
468
|
+
element.addEventListener = (type, listener, options) => {
|
|
469
|
+
const listeners = listenerMap.get(type) || [];
|
|
470
|
+
listenerMap.set(type, [...listeners, listener]);
|
|
471
|
+
return rawAddEventListener.call(element, type, listener, options);
|
|
472
|
+
};
|
|
473
|
+
element.removeEventListener = (type, listener, options) => {
|
|
474
|
+
const typeListeners = listenerMap.get(type);
|
|
475
|
+
const index = typeListeners?.indexOf(listener);
|
|
476
|
+
if (typeListeners?.length && index !== undefined && index !== -1) {
|
|
477
|
+
typeListeners.splice(index, 1);
|
|
478
|
+
}
|
|
479
|
+
return rawRemoveEventListener.call(element, type, listener, options);
|
|
480
|
+
};
|
|
481
|
+
}
|
|
482
|
+
/**
|
|
483
|
+
* 清空head和body的绑定的事件
|
|
484
|
+
*/
|
|
485
|
+
export function removeEventListener(element) {
|
|
486
|
+
const listenerMap = element._cacheListeners;
|
|
487
|
+
[...listenerMap.entries()].forEach(([type, listeners]) => {
|
|
488
|
+
listeners.forEach((listener) => rawRemoveEventListener.call(element, type, listener));
|
|
489
|
+
});
|
|
490
|
+
}
|
|
491
|
+
/**
|
|
492
|
+
* patch head and body in render
|
|
493
|
+
* intercept appendChild and insertBefore
|
|
494
|
+
*/
|
|
495
|
+
export function patchRenderEffect(render, id, degrade) {
|
|
496
|
+
// 降级场景dom渲染在iframe中,iframe移动后事件自动销毁,不需要记录
|
|
497
|
+
if (!degrade) {
|
|
498
|
+
patchEventListener(render.head);
|
|
499
|
+
patchEventListener(render.body);
|
|
500
|
+
}
|
|
501
|
+
render.head.appendChild = rewriteAppendOrInsertChild({
|
|
502
|
+
rawDOMAppendOrInsertBefore: rawAppendChild,
|
|
503
|
+
sandboxId: id,
|
|
504
|
+
});
|
|
505
|
+
render.head.insertBefore = rewriteAppendOrInsertChild({
|
|
506
|
+
rawDOMAppendOrInsertBefore: rawHeadInsertBefore,
|
|
507
|
+
sandboxId: id,
|
|
508
|
+
});
|
|
509
|
+
render.head.removeChild = rewriteRemoveChild({
|
|
510
|
+
rawElementRemoveChild: rawElementRemoveChild.bind(render.head),
|
|
511
|
+
sandboxId: id,
|
|
512
|
+
});
|
|
513
|
+
render.head.contains = rewriteContains({
|
|
514
|
+
rawElementContains: rawElementContains.bind(render.head),
|
|
515
|
+
sandboxId: id,
|
|
516
|
+
});
|
|
517
|
+
render.contains = rewriteContains({
|
|
518
|
+
rawElementContains: rawElementContains.bind(render),
|
|
519
|
+
sandboxId: id,
|
|
520
|
+
});
|
|
521
|
+
render.body.appendChild = rewriteAppendOrInsertChild({
|
|
522
|
+
rawDOMAppendOrInsertBefore: rawAppendChild,
|
|
523
|
+
sandboxId: id,
|
|
524
|
+
});
|
|
525
|
+
render.body.insertBefore = rewriteAppendOrInsertChild({
|
|
526
|
+
rawDOMAppendOrInsertBefore: rawBodyInsertBefore,
|
|
527
|
+
sandboxId: id,
|
|
528
|
+
});
|
|
529
|
+
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { ScriptObject, ScriptBaseObject, StyleObject } from "./template.js";
|
|
2
|
+
import RuntimeSandbox from "./sandbox.js";
|
|
3
|
+
import { plugin, loadErrorHandler } from "./runtime-engine.js";
|
|
4
|
+
export type ScriptResultList = (ScriptBaseObject & {
|
|
5
|
+
contentPromise: Promise<string>;
|
|
6
|
+
})[];
|
|
7
|
+
export type StyleResultList = {
|
|
8
|
+
src: string;
|
|
9
|
+
contentPromise: Promise<string>;
|
|
10
|
+
ignore?: boolean;
|
|
11
|
+
}[];
|
|
12
|
+
interface htmlParseResult {
|
|
13
|
+
template: string;
|
|
14
|
+
assetPublicPath: string;
|
|
15
|
+
getExternalScripts(): ScriptResultList;
|
|
16
|
+
getExternalStyleSheets(): StyleResultList;
|
|
17
|
+
}
|
|
18
|
+
type ImportEntryOpts = {
|
|
19
|
+
fetch?: typeof window.fetch;
|
|
20
|
+
fiber?: boolean;
|
|
21
|
+
plugins?: Array<plugin>;
|
|
22
|
+
loadError?: loadErrorHandler;
|
|
23
|
+
};
|
|
24
|
+
export declare const styleCache: Record<string, any>;
|
|
25
|
+
export declare const scriptCache: Record<string, any>;
|
|
26
|
+
export declare const embedHTMLCache: Record<string, any>;
|
|
27
|
+
/**
|
|
28
|
+
* 清空资源缓存:不传 host 时全清;传单个/数组 host 时按 url 前缀清。
|
|
29
|
+
* 用于热更新或多 host 子应用切换时主动失效,避免缓存命中已变更资源。
|
|
30
|
+
*/
|
|
31
|
+
export declare function clearAssetsCache(host?: string | string[]): void;
|
|
32
|
+
/**
|
|
33
|
+
* 处理css-loader
|
|
34
|
+
*/
|
|
35
|
+
export declare function processCssLoader(sandbox: RuntimeSandbox, template: string, getExternalStyleSheets: () => StyleResultList): Promise<string>;
|
|
36
|
+
export declare function getExternalStyleSheets(styles: StyleObject[], fetch: (input: RequestInfo, init?: RequestInit) => Promise<Response>, loadError: loadErrorHandler): StyleResultList;
|
|
37
|
+
export declare function getExternalScripts(scripts: ScriptObject[], fetch: (input: RequestInfo, init?: RequestInit) => Promise<Response>, loadError: loadErrorHandler, fiber: boolean): ScriptResultList;
|
|
38
|
+
export default function importHTML(params: {
|
|
39
|
+
url: string;
|
|
40
|
+
html?: string;
|
|
41
|
+
opts: ImportEntryOpts;
|
|
42
|
+
}): Promise<htmlParseResult>;
|
|
43
|
+
export {};
|