@micro-zoe/micro-app 1.0.0-rc.5 → 1.0.0-rc.6
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 +1 -1
- package/lib/index.d.ts +29 -20
- package/lib/index.esm.js +952 -572
- package/lib/index.esm.js.map +1 -1
- package/lib/index.min.js +1 -1
- package/lib/index.min.js.map +1 -1
- package/lib/index.umd.js +1 -1
- package/lib/index.umd.js.map +1 -1
- package/package.json +2 -1
- package/typings/global.d.ts +21 -16
package/lib/index.esm.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
const version = '1.0.0-rc.
|
|
1
|
+
const version = '1.0.0-rc.6';
|
|
2
2
|
// do not use isUndefined
|
|
3
3
|
const isBrowser = typeof window !== 'undefined';
|
|
4
4
|
// do not use isUndefined
|
|
@@ -56,7 +56,8 @@ function isPromise(target) {
|
|
|
56
56
|
}
|
|
57
57
|
// is bind function
|
|
58
58
|
function isBoundFunction(target) {
|
|
59
|
-
|
|
59
|
+
var _a;
|
|
60
|
+
return isFunction(target) && ((_a = target.name) === null || _a === void 0 ? void 0 : _a.indexOf('bound ')) === 0 && !target.hasOwnProperty('prototype');
|
|
60
61
|
}
|
|
61
62
|
// is constructor function
|
|
62
63
|
function isConstructor(target) {
|
|
@@ -109,9 +110,15 @@ function isImageElement(target) {
|
|
|
109
110
|
function isBaseElement(target) {
|
|
110
111
|
return toTypeString(target) === '[object HTMLBaseElement]';
|
|
111
112
|
}
|
|
113
|
+
function isDocumentFragment(target) {
|
|
114
|
+
return toTypeString(target) === '[object DocumentFragment]';
|
|
115
|
+
}
|
|
112
116
|
function isMicroAppBody(target) {
|
|
113
117
|
return isElement(target) && target.tagName.toUpperCase() === 'MICRO-APP-BODY';
|
|
114
118
|
}
|
|
119
|
+
function isMicroAppHead(target) {
|
|
120
|
+
return isElement(target) && target.tagName.toUpperCase() === 'MICRO-APP-HEAD';
|
|
121
|
+
}
|
|
115
122
|
// is ProxyDocument
|
|
116
123
|
function isProxyDocument(target) {
|
|
117
124
|
return toTypeString(target) === '[object ProxyDocument]';
|
|
@@ -180,6 +187,14 @@ function logWarn(msg, appName = null, ...rest) {
|
|
|
180
187
|
function defer(fn, ...args) {
|
|
181
188
|
Promise.resolve().then(fn.bind(null, ...args));
|
|
182
189
|
}
|
|
190
|
+
/**
|
|
191
|
+
* async execution with macro task
|
|
192
|
+
* @param fn callback
|
|
193
|
+
* @param args params
|
|
194
|
+
*/
|
|
195
|
+
function macro(fn, delay = 0, ...args) {
|
|
196
|
+
setTimeout(fn.bind(null, ...args), delay);
|
|
197
|
+
}
|
|
183
198
|
/**
|
|
184
199
|
* create URL as MicroLocation
|
|
185
200
|
*/
|
|
@@ -244,8 +259,7 @@ function formatAppName(name) {
|
|
|
244
259
|
function getEffectivePath(url) {
|
|
245
260
|
const { origin, pathname } = createURL(url);
|
|
246
261
|
if (/\.(\w+)$/.test(pathname)) {
|
|
247
|
-
const
|
|
248
|
-
const pathArr = fullPath.split('/');
|
|
262
|
+
const pathArr = `${origin}${pathname}`.split('/');
|
|
249
263
|
pathArr.pop();
|
|
250
264
|
return pathArr.join('/') + '/';
|
|
251
265
|
}
|
|
@@ -344,33 +358,65 @@ function promiseRequestIdle(callback) {
|
|
|
344
358
|
/**
|
|
345
359
|
* Record the currently running app.name
|
|
346
360
|
*/
|
|
347
|
-
let
|
|
361
|
+
let currentAppName = null;
|
|
348
362
|
function setCurrentAppName(appName) {
|
|
349
|
-
|
|
363
|
+
currentAppName = appName;
|
|
350
364
|
}
|
|
351
365
|
// get the currently running app.name
|
|
352
366
|
function getCurrentAppName() {
|
|
353
|
-
return
|
|
367
|
+
return currentAppName;
|
|
354
368
|
}
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
setCurrentAppName(null);
|
|
359
|
-
if (force && !preventSetAppName) {
|
|
360
|
-
preventSetAppName = true;
|
|
369
|
+
function throttleDeferForSetAppName(appName) {
|
|
370
|
+
if (currentAppName !== appName && !getPreventSetState()) {
|
|
371
|
+
setCurrentAppName(appName);
|
|
361
372
|
defer(() => {
|
|
362
|
-
|
|
373
|
+
setCurrentAppName(null);
|
|
363
374
|
});
|
|
364
375
|
}
|
|
365
376
|
}
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
377
|
+
// only for iframe document.body(head).querySelector(querySelectorAll)
|
|
378
|
+
let iframeCurrentAppName = null;
|
|
379
|
+
function setIframeCurrentAppName(appName) {
|
|
380
|
+
iframeCurrentAppName = appName;
|
|
381
|
+
}
|
|
382
|
+
function getIframeCurrentAppName() {
|
|
383
|
+
return iframeCurrentAppName;
|
|
384
|
+
}
|
|
385
|
+
function throttleDeferForIframeAppName(appName) {
|
|
386
|
+
if (iframeCurrentAppName !== appName && !getPreventSetState()) {
|
|
387
|
+
setIframeCurrentAppName(appName);
|
|
369
388
|
defer(() => {
|
|
370
|
-
|
|
389
|
+
setIframeCurrentAppName(null);
|
|
371
390
|
});
|
|
372
391
|
}
|
|
373
392
|
}
|
|
393
|
+
// prevent set app name
|
|
394
|
+
let preventSetState = false;
|
|
395
|
+
function getPreventSetState() {
|
|
396
|
+
return preventSetState;
|
|
397
|
+
}
|
|
398
|
+
/**
|
|
399
|
+
* prevent set appName
|
|
400
|
+
* usage:
|
|
401
|
+
* removeDomScope(true)
|
|
402
|
+
* -----> element scope point to base app <-----
|
|
403
|
+
* removeDomScope(false)
|
|
404
|
+
*/
|
|
405
|
+
function removeDomScope(force) {
|
|
406
|
+
if (force !== false) {
|
|
407
|
+
setCurrentAppName(null);
|
|
408
|
+
setIframeCurrentAppName(null);
|
|
409
|
+
if (force && !preventSetState) {
|
|
410
|
+
preventSetState = true;
|
|
411
|
+
defer(() => {
|
|
412
|
+
preventSetState = false;
|
|
413
|
+
});
|
|
414
|
+
}
|
|
415
|
+
}
|
|
416
|
+
else {
|
|
417
|
+
preventSetState = false;
|
|
418
|
+
}
|
|
419
|
+
}
|
|
374
420
|
/**
|
|
375
421
|
* Create pure elements
|
|
376
422
|
*/
|
|
@@ -563,13 +609,21 @@ function clearDOM($dom) {
|
|
|
563
609
|
$dom.removeChild($dom.firstChild);
|
|
564
610
|
}
|
|
565
611
|
}
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
612
|
+
function instanceOf(instance, constructor) {
|
|
613
|
+
if (instance === null || instance === undefined) {
|
|
614
|
+
return false;
|
|
615
|
+
}
|
|
616
|
+
else if (!isFunction(constructor)) {
|
|
617
|
+
throw new TypeError("Right-hand side of 'instanceof' is not callable");
|
|
618
|
+
}
|
|
619
|
+
let proto = Object.getPrototypeOf(instance);
|
|
620
|
+
while (proto) {
|
|
621
|
+
if (proto === constructor.prototype) {
|
|
622
|
+
return true;
|
|
623
|
+
}
|
|
624
|
+
proto = Object.getPrototypeOf(proto);
|
|
625
|
+
}
|
|
626
|
+
return false;
|
|
573
627
|
}
|
|
574
628
|
/**
|
|
575
629
|
* Format event name
|
|
@@ -582,6 +636,13 @@ const formatEventList = ['mounted', 'unmount'];
|
|
|
582
636
|
function formatEventType(type, appName) {
|
|
583
637
|
return formatEventList.includes(type) ? `${type}-${appName}` : type;
|
|
584
638
|
}
|
|
639
|
+
/**
|
|
640
|
+
* Is the object empty
|
|
641
|
+
* target maybe number, string, array ...
|
|
642
|
+
*/
|
|
643
|
+
function isEmptyObject(target) {
|
|
644
|
+
return isPlainObject(target) ? !Object.keys(target).length : true;
|
|
645
|
+
}
|
|
585
646
|
|
|
586
647
|
function formatEventInfo(event, element) {
|
|
587
648
|
Object.defineProperties(event, {
|
|
@@ -608,7 +669,7 @@ function formatEventInfo(event, element) {
|
|
|
608
669
|
function dispatchLifecyclesEvent(element, appName, lifecycleName, error) {
|
|
609
670
|
var _a;
|
|
610
671
|
if (!element) {
|
|
611
|
-
return
|
|
672
|
+
return logWarn(`element does not exist in lifecycle ${lifecycleName}`, appName);
|
|
612
673
|
}
|
|
613
674
|
element = getRootContainer(element);
|
|
614
675
|
// clear dom scope before dispatch lifeCycles event to base app, especially mounted & unmount
|
|
@@ -815,9 +876,24 @@ class CSSParser {
|
|
|
815
876
|
const m = this.commonMatch(/^[^{]+/, skip);
|
|
816
877
|
if (!m)
|
|
817
878
|
return false;
|
|
879
|
+
/**
|
|
880
|
+
* NOTE:
|
|
881
|
+
* 1. :is(h1, h2, h3):has(+ h2, + h3, + h4) {}
|
|
882
|
+
* should be ==> micro-app[name=xxx] :is(h1, h2, h3):has(+ h2, + h3, + h4) {}
|
|
883
|
+
* 2. :dir(ltr) {}
|
|
884
|
+
* should be ==> micro-app[name=xxx] :dir(ltr) {}
|
|
885
|
+
* 3. body :not(div, .fancy) {}
|
|
886
|
+
* should be ==> micro-app[name=xxx] micro-app-body :not(div, .fancy) {}
|
|
887
|
+
* 4. .a, .b, li:nth-child(3)
|
|
888
|
+
* should be ==> micro-app[name=xxx] .a, micro-app[name=xxx] .b, micro-app[name=xxx] li:nth-child(3)
|
|
889
|
+
* 5. :is(.a, .b, .c) a {}
|
|
890
|
+
* should be ==> micro-app[name=xxx] :is(.a, .b, .c) a {}
|
|
891
|
+
* 6. :where(.a, .b, .c) a {}
|
|
892
|
+
* should be ==> micro-app[name=xxx] :where(.a, .b, .c) a {}
|
|
893
|
+
*/
|
|
818
894
|
return m[0].replace(/(^|,[\n\s]*)([^,]+)/g, (_, separator, selector) => {
|
|
819
895
|
selector = trim(selector);
|
|
820
|
-
if (!(this.scopecssDisableNextLine ||
|
|
896
|
+
if (selector && !(this.scopecssDisableNextLine ||
|
|
821
897
|
(this.scopecssDisable && (!this.scopecssDisableSelectors.length ||
|
|
822
898
|
this.scopecssDisableSelectors.includes(selector))) ||
|
|
823
899
|
rootSelectorREG.test(selector))) {
|
|
@@ -840,7 +916,7 @@ class CSSParser {
|
|
|
840
916
|
return parseError("Declaration missing '}'", this.linkPath);
|
|
841
917
|
return true;
|
|
842
918
|
}
|
|
843
|
-
matchAllDeclarations(nesting =
|
|
919
|
+
matchAllDeclarations(nesting = 0) {
|
|
844
920
|
let cssValue = this.commonMatch(/^(?:url\(["']?(?:[^)"'}]+)["']?\)|[^{}/])*/, true)[0];
|
|
845
921
|
if (cssValue) {
|
|
846
922
|
if (!this.scopecssDisableNextLine &&
|
|
@@ -862,14 +938,6 @@ class CSSParser {
|
|
|
862
938
|
this.scopecssDisableNextLine = false;
|
|
863
939
|
if (!this.cssText)
|
|
864
940
|
return;
|
|
865
|
-
if (this.cssText.charAt(0) === '}') {
|
|
866
|
-
if (!nesting)
|
|
867
|
-
return;
|
|
868
|
-
if (nesting > 1) {
|
|
869
|
-
this.commonMatch(/}+/);
|
|
870
|
-
}
|
|
871
|
-
return this.matchAllDeclarations(nesting - 1);
|
|
872
|
-
}
|
|
873
941
|
// extract comments in declarations
|
|
874
942
|
if (this.cssText.charAt(0) === '/') {
|
|
875
943
|
if (this.cssText.charAt(1) === '*') {
|
|
@@ -879,10 +947,16 @@ class CSSParser {
|
|
|
879
947
|
this.commonMatch(/\/+/);
|
|
880
948
|
}
|
|
881
949
|
}
|
|
882
|
-
if (this.cssText.charAt(0) === '{') {
|
|
883
|
-
this.
|
|
950
|
+
else if (this.cssText.charAt(0) === '{') {
|
|
951
|
+
this.matchOpenBrace();
|
|
884
952
|
nesting++;
|
|
885
953
|
}
|
|
954
|
+
else if (this.cssText.charAt(0) === '}') {
|
|
955
|
+
if (nesting < 1)
|
|
956
|
+
return;
|
|
957
|
+
this.matchCloseBrace();
|
|
958
|
+
nesting--;
|
|
959
|
+
}
|
|
886
960
|
return this.matchAllDeclarations(nesting);
|
|
887
961
|
}
|
|
888
962
|
matchAtRule() {
|
|
@@ -901,7 +975,8 @@ class CSSParser {
|
|
|
901
975
|
this.documentRule() ||
|
|
902
976
|
this.pageRule() ||
|
|
903
977
|
this.hostRule() ||
|
|
904
|
-
this.fontFaceRule()
|
|
978
|
+
this.fontFaceRule() ||
|
|
979
|
+
this.layerRule();
|
|
905
980
|
}
|
|
906
981
|
// :global is CSS Modules rule, it will be converted to normal syntax
|
|
907
982
|
// private matchGlobalRule (): boolean | void {
|
|
@@ -963,6 +1038,19 @@ class CSSParser {
|
|
|
963
1038
|
return false;
|
|
964
1039
|
return this.commonHandlerForAtRuleWithSelfRule('font-face');
|
|
965
1040
|
}
|
|
1041
|
+
// https://developer.mozilla.org/en-US/docs/Web/CSS/@layer
|
|
1042
|
+
layerRule() {
|
|
1043
|
+
if (!this.commonMatch(/^@layer\s*([^{;]+)/))
|
|
1044
|
+
return false;
|
|
1045
|
+
if (!this.matchOpenBrace())
|
|
1046
|
+
return !!this.commonMatch(/^[;]+/);
|
|
1047
|
+
this.matchComments();
|
|
1048
|
+
this.matchRules();
|
|
1049
|
+
if (!this.matchCloseBrace())
|
|
1050
|
+
return parseError('@layer missing \'}\'', this.linkPath);
|
|
1051
|
+
this.matchLeadingSpaces();
|
|
1052
|
+
return true;
|
|
1053
|
+
}
|
|
966
1054
|
// common matcher for @media, @supports, @document, @host, :global, @container
|
|
967
1055
|
createMatcherForRuleWithChildRule(reg, name) {
|
|
968
1056
|
return () => {
|
|
@@ -1058,7 +1146,7 @@ class CSSParser {
|
|
|
1058
1146
|
return this.commonMatch(/^{\s*/);
|
|
1059
1147
|
}
|
|
1060
1148
|
matchCloseBrace() {
|
|
1061
|
-
return this.commonMatch(/^}
|
|
1149
|
+
return this.commonMatch(/^}\s*/);
|
|
1062
1150
|
}
|
|
1063
1151
|
// match and slice the leading spaces
|
|
1064
1152
|
matchLeadingSpaces() {
|
|
@@ -1272,7 +1360,7 @@ function extractLinkFromHtml(link, parent, app, isDynamic = false) {
|
|
|
1272
1360
|
return { address: href, linkInfo };
|
|
1273
1361
|
}
|
|
1274
1362
|
}
|
|
1275
|
-
else if (rel && ['prefetch', 'preload', 'prerender', 'modulepreload'].includes(rel)) {
|
|
1363
|
+
else if (rel && ['prefetch', 'preload', 'prerender', 'modulepreload', 'icon'].includes(rel)) {
|
|
1276
1364
|
// preload prefetch prerender ....
|
|
1277
1365
|
if (isDynamic) {
|
|
1278
1366
|
replaceComment = document.createComment(`link element with rel=${rel}${href ? ' & href=' + href : ''} removed by micro-app`);
|
|
@@ -1486,7 +1574,6 @@ var MicroAppConfig;
|
|
|
1486
1574
|
MicroAppConfig["DISABLE_MEMORY_ROUTER"] = "disable-memory-router";
|
|
1487
1575
|
MicroAppConfig["DISABLE_PATCH_REQUEST"] = "disable-patch-request";
|
|
1488
1576
|
MicroAppConfig["KEEP_ROUTER_STATE"] = "keep-router-state";
|
|
1489
|
-
MicroAppConfig["HIDDEN_ROUTER"] = "hidden-router";
|
|
1490
1577
|
MicroAppConfig["KEEP_ALIVE"] = "keep-alive";
|
|
1491
1578
|
MicroAppConfig["CLEAR_DATA"] = "clear-data";
|
|
1492
1579
|
MicroAppConfig["SSR"] = "ssr";
|
|
@@ -1535,7 +1622,6 @@ const BASE_SCOPE_WINDOW_EVENT = [
|
|
|
1535
1622
|
'popstate',
|
|
1536
1623
|
'hashchange',
|
|
1537
1624
|
'load',
|
|
1538
|
-
'beforeunload',
|
|
1539
1625
|
'unload',
|
|
1540
1626
|
'unmount',
|
|
1541
1627
|
'appstate-change',
|
|
@@ -1547,6 +1633,7 @@ const SCOPE_WINDOW_EVENT_OF_WITH = BASE_SCOPE_WINDOW_EVENT;
|
|
|
1547
1633
|
// bind event of iframe sandbox
|
|
1548
1634
|
const SCOPE_WINDOW_EVENT_OF_IFRAME = BASE_SCOPE_WINDOW_EVENT.concat([
|
|
1549
1635
|
'unhandledrejection',
|
|
1636
|
+
'message'
|
|
1550
1637
|
]);
|
|
1551
1638
|
// on event bound to child app window
|
|
1552
1639
|
// TODO: with和iframe处理方式不同,需修改
|
|
@@ -1554,9 +1641,9 @@ const BASE_SCOPE_WINDOW_ON_EVENT = [
|
|
|
1554
1641
|
'onpopstate',
|
|
1555
1642
|
'onhashchange',
|
|
1556
1643
|
'onload',
|
|
1557
|
-
'onbeforeunload',
|
|
1558
1644
|
'onunload',
|
|
1559
1645
|
'onerror'
|
|
1646
|
+
// 'onbeforeunload', // remove at 2024.5.30 by cangdu
|
|
1560
1647
|
];
|
|
1561
1648
|
// bind on event of with sandbox
|
|
1562
1649
|
const SCOPE_WINDOW_ON_EVENT_OF_WITH = BASE_SCOPE_WINDOW_ON_EVENT;
|
|
@@ -1986,6 +2073,7 @@ function execScripts(app, initHook) {
|
|
|
1986
2073
|
* @param callback callback of module script
|
|
1987
2074
|
*/
|
|
1988
2075
|
function runScript(address, app, scriptInfo, callback, replaceElement) {
|
|
2076
|
+
var _a;
|
|
1989
2077
|
try {
|
|
1990
2078
|
actionsBeforeRunScript(app);
|
|
1991
2079
|
const appSpaceData = scriptInfo.appSpace[app.name];
|
|
@@ -2016,7 +2104,7 @@ function runScript(address, app, scriptInfo, callback, replaceElement) {
|
|
|
2016
2104
|
*/
|
|
2017
2105
|
if (!replaceElement) {
|
|
2018
2106
|
// TEST IGNORE
|
|
2019
|
-
const parent = app.iframe ? app.sandBox.microBody : app.querySelector('micro-app-body');
|
|
2107
|
+
const parent = app.iframe ? (_a = app.sandBox) === null || _a === void 0 ? void 0 : _a.microBody : app.querySelector('micro-app-body');
|
|
2020
2108
|
parent === null || parent === void 0 ? void 0 : parent.appendChild(scriptElement);
|
|
2021
2109
|
}
|
|
2022
2110
|
}
|
|
@@ -2038,7 +2126,7 @@ function runScript(address, app, scriptInfo, callback, replaceElement) {
|
|
|
2038
2126
|
* @param originScript origin script element
|
|
2039
2127
|
*/
|
|
2040
2128
|
function runDynamicRemoteScript(address, app, scriptInfo, originScript) {
|
|
2041
|
-
const replaceElement = isInlineMode(app, scriptInfo) ? pureCreateElement('script') : document.createComment(
|
|
2129
|
+
const replaceElement = isInlineMode(app, scriptInfo) ? pureCreateElement('script') : document.createComment(`dynamic script with src='${address}' extract by micro-app`);
|
|
2042
2130
|
const dispatchScriptOnLoadEvent = () => dispatchOnLoadEvent(originScript);
|
|
2043
2131
|
const runDynamicScript = () => {
|
|
2044
2132
|
const descriptor = Object.getOwnPropertyDescriptor(globalEnv.rawDocument, 'currentScript');
|
|
@@ -2072,7 +2160,7 @@ function runDynamicRemoteScript(address, app, scriptInfo, originScript) {
|
|
|
2072
2160
|
* @param scriptInfo scriptInfo
|
|
2073
2161
|
*/
|
|
2074
2162
|
function runDynamicInlineScript(address, app, scriptInfo) {
|
|
2075
|
-
const replaceElement = isInlineMode(app, scriptInfo) ? pureCreateElement('script') : document.createComment('dynamic script extract by micro-app');
|
|
2163
|
+
const replaceElement = isInlineMode(app, scriptInfo) ? pureCreateElement('script') : document.createComment('dynamic inline script extract by micro-app');
|
|
2076
2164
|
runScript(address, app, scriptInfo, void 0, replaceElement);
|
|
2077
2165
|
return replaceElement;
|
|
2078
2166
|
}
|
|
@@ -2250,7 +2338,7 @@ function extractSourceDom(htmlStr, app) {
|
|
|
2250
2338
|
const fiberStyleTasks = app.isPrefetch || app.fiber ? [] : null;
|
|
2251
2339
|
flatChildren(wrapElement, app, microAppHead, fiberStyleTasks);
|
|
2252
2340
|
/**
|
|
2253
|
-
* Style and link are parallel,
|
|
2341
|
+
* Style and link are parallel, as it takes a lot of time for link to request resources. During this period, style processing can be performed to improve efficiency.
|
|
2254
2342
|
*/
|
|
2255
2343
|
const fiberStyleResult = serialExecFiberTasks(fiberStyleTasks);
|
|
2256
2344
|
if (app.source.links.size) {
|
|
@@ -2445,7 +2533,7 @@ const eventCenter = new EventCenter();
|
|
|
2445
2533
|
function createEventName(appName, fromBaseApp) {
|
|
2446
2534
|
if (!isString(appName) || !appName)
|
|
2447
2535
|
return '';
|
|
2448
|
-
return fromBaseApp ? `
|
|
2536
|
+
return fromBaseApp ? `__${appName}_from_base_app__` : `__${appName}_from_micro_app__`;
|
|
2449
2537
|
}
|
|
2450
2538
|
// Global data
|
|
2451
2539
|
class EventCenterForGlobal {
|
|
@@ -2744,7 +2832,15 @@ function isConstructorFunction(value) {
|
|
|
2744
2832
|
}
|
|
2745
2833
|
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
|
|
2746
2834
|
function bindFunctionToRawTarget(value, rawTarget, key = 'WINDOW') {
|
|
2747
|
-
|
|
2835
|
+
/**
|
|
2836
|
+
* In safari, nest app like: A -> B -> C
|
|
2837
|
+
* if B is iframe sandbox, and C is with sandbox, same property of document in C is abnormal
|
|
2838
|
+
* e.g:
|
|
2839
|
+
* document.all:
|
|
2840
|
+
* - typeof document.all ==> 'function'
|
|
2841
|
+
* - document.all.bind ==> undefined
|
|
2842
|
+
*/
|
|
2843
|
+
if (isFunction(value) && !isConstructorFunction(value) && !isBoundedFunction(value) && value.bind) {
|
|
2748
2844
|
const cacheKey = `__MICRO_APP_BOUND_${key}_FUNCTION__`;
|
|
2749
2845
|
if (value[cacheKey])
|
|
2750
2846
|
return value[cacheKey];
|
|
@@ -2765,6 +2861,198 @@ function bindFunctionToRawTarget(value, rawTarget, key = 'WINDOW') {
|
|
|
2765
2861
|
return value;
|
|
2766
2862
|
}
|
|
2767
2863
|
|
|
2864
|
+
class BaseSandbox {
|
|
2865
|
+
constructor(appName, url) {
|
|
2866
|
+
// keys that can only assigned to rawWindow
|
|
2867
|
+
this.rawWindowScopeKeyList = [
|
|
2868
|
+
'location',
|
|
2869
|
+
];
|
|
2870
|
+
// keys that can escape to rawWindow
|
|
2871
|
+
this.staticEscapeProperties = [
|
|
2872
|
+
'System',
|
|
2873
|
+
'__cjsWrapper',
|
|
2874
|
+
];
|
|
2875
|
+
// keys that scoped in child app
|
|
2876
|
+
this.staticScopeProperties = [
|
|
2877
|
+
'webpackJsonp',
|
|
2878
|
+
'webpackHotUpdate',
|
|
2879
|
+
'Vue',
|
|
2880
|
+
// TODO: 是否可以和constants/SCOPE_WINDOW_ON_EVENT合并
|
|
2881
|
+
'onpopstate',
|
|
2882
|
+
'onhashchange',
|
|
2883
|
+
];
|
|
2884
|
+
// Properties that can only get and set in microAppWindow, will not escape to rawWindow
|
|
2885
|
+
this.scopeProperties = Array.from(this.staticScopeProperties);
|
|
2886
|
+
// Properties that can be escape to rawWindow
|
|
2887
|
+
this.escapeProperties = [];
|
|
2888
|
+
// Properties newly added to microAppWindow
|
|
2889
|
+
this.injectedKeys = new Set();
|
|
2890
|
+
// Properties escape to rawWindow, cleared when unmount
|
|
2891
|
+
this.escapeKeys = new Set();
|
|
2892
|
+
this.appName = appName;
|
|
2893
|
+
this.url = url;
|
|
2894
|
+
this.injectReactHMRProperty();
|
|
2895
|
+
}
|
|
2896
|
+
// adapter for react
|
|
2897
|
+
injectReactHMRProperty() {
|
|
2898
|
+
if ((process.env.NODE_ENV !== 'production')) {
|
|
2899
|
+
// react child in non-react env
|
|
2900
|
+
this.staticEscapeProperties.push('__REACT_ERROR_OVERLAY_GLOBAL_HOOK__');
|
|
2901
|
+
// in react parent
|
|
2902
|
+
if (globalEnv.rawWindow.__REACT_ERROR_OVERLAY_GLOBAL_HOOK__) {
|
|
2903
|
+
this.staticScopeProperties = this.staticScopeProperties.concat([
|
|
2904
|
+
'__REACT_ERROR_OVERLAY_GLOBAL_HOOK__',
|
|
2905
|
+
'__reactRefreshInjected',
|
|
2906
|
+
]);
|
|
2907
|
+
}
|
|
2908
|
+
}
|
|
2909
|
+
}
|
|
2910
|
+
}
|
|
2911
|
+
/**
|
|
2912
|
+
* TODO:
|
|
2913
|
+
* 1、将class Adapter去掉,改为CustomWindow,或者让CustomWindow继承Adapter
|
|
2914
|
+
* 2、with沙箱中的常量放入CustomWindow,虽然和iframe沙箱不一致,但更合理
|
|
2915
|
+
* 修改时机:在iframe沙箱支持插件后再修改
|
|
2916
|
+
*/
|
|
2917
|
+
class CustomWindow {
|
|
2918
|
+
}
|
|
2919
|
+
// Fix conflict of babel-polyfill@6.x
|
|
2920
|
+
function fixBabelPolyfill6() {
|
|
2921
|
+
if (globalEnv.rawWindow._babelPolyfill)
|
|
2922
|
+
globalEnv.rawWindow._babelPolyfill = false;
|
|
2923
|
+
}
|
|
2924
|
+
/**
|
|
2925
|
+
* Fix error of hot reload when parent&child created by create-react-app in development environment
|
|
2926
|
+
* Issue: https://github.com/micro-zoe/micro-app/issues/382
|
|
2927
|
+
*/
|
|
2928
|
+
function fixReactHMRConflict(app) {
|
|
2929
|
+
var _a;
|
|
2930
|
+
if ((process.env.NODE_ENV !== 'production')) {
|
|
2931
|
+
const rawReactErrorHook = globalEnv.rawWindow.__REACT_ERROR_OVERLAY_GLOBAL_HOOK__;
|
|
2932
|
+
const childReactErrorHook = (_a = app.sandBox) === null || _a === void 0 ? void 0 : _a.proxyWindow.__REACT_ERROR_OVERLAY_GLOBAL_HOOK__;
|
|
2933
|
+
if (rawReactErrorHook && childReactErrorHook) {
|
|
2934
|
+
globalEnv.rawWindow.__REACT_ERROR_OVERLAY_GLOBAL_HOOK__ = childReactErrorHook;
|
|
2935
|
+
defer(() => {
|
|
2936
|
+
globalEnv.rawWindow.__REACT_ERROR_OVERLAY_GLOBAL_HOOK__ = rawReactErrorHook;
|
|
2937
|
+
});
|
|
2938
|
+
}
|
|
2939
|
+
}
|
|
2940
|
+
}
|
|
2941
|
+
/**
|
|
2942
|
+
* update dom tree of target dom
|
|
2943
|
+
* @param container target dom
|
|
2944
|
+
* @param appName app name
|
|
2945
|
+
*/
|
|
2946
|
+
function patchElementTree(container, appName) {
|
|
2947
|
+
const children = Array.from(container.childNodes);
|
|
2948
|
+
children.length && children.forEach((child) => {
|
|
2949
|
+
patchElementTree(child, appName);
|
|
2950
|
+
});
|
|
2951
|
+
updateElementInfo(container, appName);
|
|
2952
|
+
}
|
|
2953
|
+
/**
|
|
2954
|
+
* rewrite baseURI, ownerDocument, __MICRO_APP_NAME__ of target node
|
|
2955
|
+
* @param node target node
|
|
2956
|
+
* @param appName app name
|
|
2957
|
+
* @returns target node
|
|
2958
|
+
*/
|
|
2959
|
+
function updateElementInfo(node, appName) {
|
|
2960
|
+
var _a, _b;
|
|
2961
|
+
if (appName &&
|
|
2962
|
+
isNode(node) &&
|
|
2963
|
+
node.__MICRO_APP_NAME__ !== appName &&
|
|
2964
|
+
!node.__PURE_ELEMENT__ &&
|
|
2965
|
+
!getPreventSetState()) {
|
|
2966
|
+
/**
|
|
2967
|
+
* TODO:
|
|
2968
|
+
* 1. 测试baseURI和ownerDocument在with沙箱中是否正确
|
|
2969
|
+
* 经过验证with沙箱不能重写ownerDocument,否则react点击事件会触发两次
|
|
2970
|
+
*/
|
|
2971
|
+
rawDefineProperties(node, {
|
|
2972
|
+
__MICRO_APP_NAME__: {
|
|
2973
|
+
configurable: true,
|
|
2974
|
+
enumerable: true,
|
|
2975
|
+
writable: true,
|
|
2976
|
+
value: appName,
|
|
2977
|
+
},
|
|
2978
|
+
});
|
|
2979
|
+
/**
|
|
2980
|
+
* In FireFox, iframe Node.prototype will point to native Node.prototype after insert to document
|
|
2981
|
+
*
|
|
2982
|
+
* Performance:
|
|
2983
|
+
* iframe element.__proto__ === browser HTMLElement.prototype // Chrome: false, FireFox: true
|
|
2984
|
+
* iframe element.__proto__ === iframe HTMLElement.prototype // Chrome: true, FireFox: false
|
|
2985
|
+
*
|
|
2986
|
+
* NOTE:
|
|
2987
|
+
* 1. Node.prototype.baseURI
|
|
2988
|
+
* 2. Node.prototype.ownerDocument
|
|
2989
|
+
* 3. Node.prototype.parentNode
|
|
2990
|
+
* 4. Node.prototype.getRootNode
|
|
2991
|
+
* 5. Node.prototype.cloneNode
|
|
2992
|
+
* 6. Element.prototype.innerHTML
|
|
2993
|
+
* 7. Image
|
|
2994
|
+
*/
|
|
2995
|
+
if (isIframeSandbox(appName)) {
|
|
2996
|
+
const proxyWindow = (_b = (_a = appInstanceMap.get(appName)) === null || _a === void 0 ? void 0 : _a.sandBox) === null || _b === void 0 ? void 0 : _b.proxyWindow;
|
|
2997
|
+
if (proxyWindow) {
|
|
2998
|
+
rawDefineProperties(node, {
|
|
2999
|
+
baseURI: {
|
|
3000
|
+
configurable: true,
|
|
3001
|
+
enumerable: true,
|
|
3002
|
+
get: () => proxyWindow.location.href,
|
|
3003
|
+
},
|
|
3004
|
+
ownerDocument: {
|
|
3005
|
+
configurable: true,
|
|
3006
|
+
enumerable: true,
|
|
3007
|
+
get: () => node !== proxyWindow.document ? proxyWindow.document : null,
|
|
3008
|
+
},
|
|
3009
|
+
parentNode: getIframeParentNodeDesc(appName, globalEnv.rawParentNodeDesc),
|
|
3010
|
+
getRootNode: {
|
|
3011
|
+
configurable: true,
|
|
3012
|
+
enumerable: true,
|
|
3013
|
+
writable: true,
|
|
3014
|
+
value: function getRootNode() {
|
|
3015
|
+
return proxyWindow.document;
|
|
3016
|
+
}
|
|
3017
|
+
},
|
|
3018
|
+
});
|
|
3019
|
+
}
|
|
3020
|
+
}
|
|
3021
|
+
}
|
|
3022
|
+
return node;
|
|
3023
|
+
}
|
|
3024
|
+
/**
|
|
3025
|
+
* get Descriptor of Node.prototype.parentNode for iframe
|
|
3026
|
+
* @param appName app name
|
|
3027
|
+
* @param parentNode parentNode Descriptor of iframe or browser
|
|
3028
|
+
*/
|
|
3029
|
+
function getIframeParentNodeDesc(appName, parentNodeDesc) {
|
|
3030
|
+
return {
|
|
3031
|
+
configurable: true,
|
|
3032
|
+
enumerable: true,
|
|
3033
|
+
get() {
|
|
3034
|
+
var _a, _b, _c, _d;
|
|
3035
|
+
throttleDeferForIframeAppName(appName);
|
|
3036
|
+
const result = (_a = parentNodeDesc.get) === null || _a === void 0 ? void 0 : _a.call(this);
|
|
3037
|
+
/**
|
|
3038
|
+
* If parentNode is <micro-app-body>, return rawDocument.body
|
|
3039
|
+
* Scenes:
|
|
3040
|
+
* 1. element-ui@2/lib/utils/vue-popper.js
|
|
3041
|
+
* if (this.popperElm.parentNode === document.body) ...
|
|
3042
|
+
* e.g.:
|
|
3043
|
+
* 1. element-ui@2.x el-dropdown
|
|
3044
|
+
* WARNING:
|
|
3045
|
+
* Will it cause other problems ?
|
|
3046
|
+
* e.g. target.parentNode.remove(target)
|
|
3047
|
+
*/
|
|
3048
|
+
if (isMicroAppBody(result) && ((_b = appInstanceMap.get(appName)) === null || _b === void 0 ? void 0 : _b.container)) {
|
|
3049
|
+
return ((_d = (_c = microApp.options).getRootElementParentNode) === null || _d === void 0 ? void 0 : _d.call(_c, this, appName)) || globalEnv.rawDocument.body;
|
|
3050
|
+
}
|
|
3051
|
+
return result;
|
|
3052
|
+
}
|
|
3053
|
+
};
|
|
3054
|
+
}
|
|
3055
|
+
|
|
2768
3056
|
/**
|
|
2769
3057
|
* create proxyDocument and MicroDocument, rewrite document of child app
|
|
2770
3058
|
* @param appName app name
|
|
@@ -2805,13 +3093,11 @@ function createProxyDocument(appName, sandbox) {
|
|
|
2805
3093
|
const { rawDocument, rawCreateElement, rawCreateElementNS, rawAddEventListener, rawRemoveEventListener, } = globalEnv;
|
|
2806
3094
|
function createElement(tagName, options) {
|
|
2807
3095
|
const element = rawCreateElement.call(rawDocument, tagName, options);
|
|
2808
|
-
element
|
|
2809
|
-
return element;
|
|
3096
|
+
return updateElementInfo(element, appName);
|
|
2810
3097
|
}
|
|
2811
3098
|
function createElementNS(namespaceURI, name, options) {
|
|
2812
3099
|
const element = rawCreateElementNS.call(rawDocument, namespaceURI, name, options);
|
|
2813
|
-
element
|
|
2814
|
-
return element;
|
|
3100
|
+
return updateElementInfo(element, appName);
|
|
2815
3101
|
}
|
|
2816
3102
|
/**
|
|
2817
3103
|
* TODO:
|
|
@@ -3310,11 +3596,11 @@ function setMicroState(appName, microState, targetLocation) {
|
|
|
3310
3596
|
const additionalState = {
|
|
3311
3597
|
__MICRO_APP_STATE__: assign({}, rawState === null || rawState === void 0 ? void 0 : rawState.__MICRO_APP_STATE__, {
|
|
3312
3598
|
[appName]: {
|
|
3313
|
-
fullPath: targetLocation.pathname + targetLocation.search + targetLocation.hash,
|
|
3314
|
-
state: microState,
|
|
3599
|
+
fullPath: targetLocation ? targetLocation.pathname + targetLocation.search + targetLocation.hash : null,
|
|
3600
|
+
state: microState !== null && microState !== void 0 ? microState : null,
|
|
3315
3601
|
mode: getRouterMode(appName),
|
|
3316
3602
|
}
|
|
3317
|
-
})
|
|
3603
|
+
}),
|
|
3318
3604
|
};
|
|
3319
3605
|
// create new state object
|
|
3320
3606
|
return assign({}, rawState, additionalState);
|
|
@@ -3329,14 +3615,19 @@ function removeMicroState(appName, rawState) {
|
|
|
3329
3615
|
delete rawState.__MICRO_APP_STATE__;
|
|
3330
3616
|
}
|
|
3331
3617
|
}
|
|
3332
|
-
return assign({}, rawState);
|
|
3618
|
+
return !isEmptyObject(rawState) ? assign({}, rawState) : null;
|
|
3333
3619
|
}
|
|
3334
3620
|
// get micro app state form origin state
|
|
3335
3621
|
function getMicroState(appName) {
|
|
3336
3622
|
var _a, _b;
|
|
3337
3623
|
const rawState = globalEnv.rawWindow.history.state;
|
|
3338
|
-
|
|
3339
|
-
|
|
3624
|
+
return ((_b = (_a = rawState === null || rawState === void 0 ? void 0 : rawState.__MICRO_APP_STATE__) === null || _a === void 0 ? void 0 : _a[appName]) === null || _b === void 0 ? void 0 : _b.state) || null;
|
|
3625
|
+
}
|
|
3626
|
+
// get micro app router info state form origin state
|
|
3627
|
+
function getMicroRouterInfoState(appName) {
|
|
3628
|
+
var _a;
|
|
3629
|
+
const rawState = globalEnv.rawWindow.history.state;
|
|
3630
|
+
return ((_a = rawState === null || rawState === void 0 ? void 0 : rawState.__MICRO_APP_STATE__) === null || _a === void 0 ? void 0 : _a[appName]) || null;
|
|
3340
3631
|
}
|
|
3341
3632
|
const ENC_AD_RE = /&/g; // %M1
|
|
3342
3633
|
const ENC_EQ_RE = /=/g; // %M2
|
|
@@ -3385,7 +3676,7 @@ function getMicroPathFromURL(appName) {
|
|
|
3385
3676
|
* NOTE:
|
|
3386
3677
|
* 1. state mode: all base on __MICRO_APP_STATE__
|
|
3387
3678
|
* 2. pure mode: navigate by location.xxx may contain one-time information in __MICRO_APP_STATE__
|
|
3388
|
-
* 3. native
|
|
3679
|
+
* 3. native mode: vue-router@4 will exec replaceState with history.state before pushState, like:
|
|
3389
3680
|
* history.replaceState(
|
|
3390
3681
|
* assign({}, history.state, {...}),
|
|
3391
3682
|
* title,
|
|
@@ -3393,8 +3684,13 @@ function getMicroPathFromURL(appName) {
|
|
|
3393
3684
|
* )
|
|
3394
3685
|
* when base app jump to another page from child page, it will replace child path with base app path
|
|
3395
3686
|
* e.g: base-home --> child-home --> child-about(will replace with child-home before jump to base-home) --> base-home, when go back, it will back to child-home not child-about
|
|
3396
|
-
* So we take the fullPath as
|
|
3687
|
+
* So we take the fullPath as standard
|
|
3397
3688
|
*/
|
|
3689
|
+
// 问题:1、同一个页面多个子应用,一个修改后... --- native模式不支持多个子应用同时渲染,多个子应用推荐使用其它模式
|
|
3690
|
+
// if (isRouterModeCustom(appName)) {
|
|
3691
|
+
// return rawLocation.pathname + rawLocation.search + rawLocation.hash
|
|
3692
|
+
// }
|
|
3693
|
+
// return rawState?.__MICRO_APP_STATE__?.[appName]?.fullPath || null
|
|
3398
3694
|
return ((_d = (_c = rawState === null || rawState === void 0 ? void 0 : rawState.__MICRO_APP_STATE__) === null || _c === void 0 ? void 0 : _c[appName]) === null || _d === void 0 ? void 0 : _d.fullPath) || (isRouterModeCustom(appName) ? rawLocation.pathname + rawLocation.search + rawLocation.hash : null);
|
|
3399
3695
|
}
|
|
3400
3696
|
/**
|
|
@@ -3590,6 +3886,7 @@ function addHistoryListener(appName) {
|
|
|
3590
3886
|
const rawWindow = globalEnv.rawWindow;
|
|
3591
3887
|
// handle popstate event and distribute to child app
|
|
3592
3888
|
const popStateHandler = (e) => {
|
|
3889
|
+
var _a, _b, _c;
|
|
3593
3890
|
/**
|
|
3594
3891
|
* 1. unmount app & hidden keep-alive app will not receive popstate event
|
|
3595
3892
|
* 2. filter out onlyForBrowser
|
|
@@ -3600,20 +3897,27 @@ function addHistoryListener(appName) {
|
|
|
3600
3897
|
}).includes(appName) &&
|
|
3601
3898
|
!e.onlyForBrowser) {
|
|
3602
3899
|
/**
|
|
3603
|
-
*
|
|
3604
|
-
*
|
|
3605
|
-
|
|
3606
|
-
|
|
3607
|
-
|
|
3608
|
-
|
|
3609
|
-
|
|
3610
|
-
|
|
3611
|
-
|
|
3612
|
-
|
|
3613
|
-
|
|
3614
|
-
|
|
3615
|
-
|
|
3616
|
-
|
|
3900
|
+
* base app may respond to popstateEvent async(lazy load page & browser back/forward), but child app will respond to popstateEvent immediately(vue2, react), this will cause some problems
|
|
3901
|
+
* 2 solutions:
|
|
3902
|
+
* 1. child app respond to popstateEvent async -- router-event-delay
|
|
3903
|
+
* 2. child app will not respond to popstateEvent in some scenarios (history.state===null || history.state?__MICRO_APP_STATE__[appName])
|
|
3904
|
+
* NOTE 1:
|
|
3905
|
+
* 1. browser back/forward
|
|
3906
|
+
* 2. location.hash/search/pathname = xxx
|
|
3907
|
+
* 3. <a href="/#/xxx">, <a href="/xxx">
|
|
3908
|
+
* 4. history.back/go/forward
|
|
3909
|
+
* 5. history.pushState/replaceState
|
|
3910
|
+
*
|
|
3911
|
+
* NOTE2:
|
|
3912
|
+
* 1、react16 hash mode navigate by location.hash = xxx, history.state is always null, but react16 respond to popstateEvent sync
|
|
3913
|
+
* 2、multiple child apps may has problems
|
|
3914
|
+
*/
|
|
3915
|
+
if (!isRouterModeCustom(appName) ||
|
|
3916
|
+
!globalEnv.rawWindow.history.state ||
|
|
3917
|
+
getMicroRouterInfoState(appName)) {
|
|
3918
|
+
const container = (_a = appInstanceMap.get(appName)) === null || _a === void 0 ? void 0 : _a.container;
|
|
3919
|
+
macro(() => updateMicroLocationWithEvent(appName, getMicroPathFromURL(appName)), (_c = (_b = (container && getRootContainer(container))) === null || _b === void 0 ? void 0 : _b.getRouterEventDelay()) !== null && _c !== void 0 ? _c : 0);
|
|
3920
|
+
}
|
|
3617
3921
|
}
|
|
3618
3922
|
};
|
|
3619
3923
|
rawWindow.addEventListener('popstate', popStateHandler);
|
|
@@ -3631,24 +3935,26 @@ function addHistoryListener(appName) {
|
|
|
3631
3935
|
*/
|
|
3632
3936
|
function updateMicroLocationWithEvent(appName, targetFullPath) {
|
|
3633
3937
|
const app = appInstanceMap.get(appName);
|
|
3634
|
-
|
|
3635
|
-
|
|
3636
|
-
|
|
3637
|
-
|
|
3638
|
-
|
|
3639
|
-
|
|
3640
|
-
|
|
3641
|
-
|
|
3642
|
-
|
|
3643
|
-
|
|
3644
|
-
|
|
3645
|
-
|
|
3646
|
-
|
|
3647
|
-
|
|
3648
|
-
|
|
3649
|
-
|
|
3650
|
-
|
|
3651
|
-
|
|
3938
|
+
if (app === null || app === void 0 ? void 0 : app.sandBox) {
|
|
3939
|
+
const proxyWindow = app.sandBox.proxyWindow;
|
|
3940
|
+
const microAppWindow = app.sandBox.microAppWindow;
|
|
3941
|
+
let isHashChange = false;
|
|
3942
|
+
// for hashChangeEvent
|
|
3943
|
+
const oldHref = proxyWindow.location.href;
|
|
3944
|
+
// Do not attach micro state to url when targetFullPath is empty
|
|
3945
|
+
if (targetFullPath) {
|
|
3946
|
+
const oldHash = proxyWindow.location.hash;
|
|
3947
|
+
updateMicroLocation(appName, targetFullPath, microAppWindow.location);
|
|
3948
|
+
isHashChange = proxyWindow.location.hash !== oldHash;
|
|
3949
|
+
}
|
|
3950
|
+
// dispatch formatted popStateEvent to child
|
|
3951
|
+
dispatchPopStateEventToMicroApp(appName, proxyWindow, microAppWindow);
|
|
3952
|
+
// dispatch formatted hashChangeEvent to child when hash change
|
|
3953
|
+
if (isHashChange)
|
|
3954
|
+
dispatchHashChangeEventToMicroApp(appName, proxyWindow, microAppWindow, oldHref);
|
|
3955
|
+
// clear element scope before trigger event of next app
|
|
3956
|
+
removeDomScope();
|
|
3957
|
+
}
|
|
3652
3958
|
}
|
|
3653
3959
|
/**
|
|
3654
3960
|
* dispatch formatted popstate event to microApp
|
|
@@ -3747,20 +4053,16 @@ function createMicroHistory(appName, microLocation) {
|
|
|
3747
4053
|
return function (...rests) {
|
|
3748
4054
|
var _a, _b, _c;
|
|
3749
4055
|
// TODO: 测试iframe的URL兼容isURL的情况
|
|
3750
|
-
|
|
3751
|
-
|
|
3752
|
-
|
|
3753
|
-
|
|
3754
|
-
|
|
3755
|
-
}
|
|
3756
|
-
if (targetFullPath !== microLocation.fullPath) {
|
|
3757
|
-
updateMicroLocation(appName, targetFullPath, microLocation);
|
|
3758
|
-
}
|
|
3759
|
-
(_c = (_a = appInstanceMap.get(appName)) === null || _a === void 0 ? void 0 : (_b = _a.sandBox).updateIframeBase) === null || _c === void 0 ? void 0 : _c.call(_b);
|
|
4056
|
+
rests[2] = isUndefined(rests[2]) || isNull(rests[2]) || ('' + rests[2] === '') ? microLocation.href : '' + rests[2];
|
|
4057
|
+
const targetLocation = createURL(rests[2], microLocation.href);
|
|
4058
|
+
const targetFullPath = targetLocation.pathname + targetLocation.search + targetLocation.hash;
|
|
4059
|
+
if (!isRouterModePure(appName)) {
|
|
4060
|
+
navigateWithNativeEvent(appName, methodName, setMicroPathToURL(appName, targetLocation), true, setMicroState(appName, rests[0], targetLocation), rests[1]);
|
|
3760
4061
|
}
|
|
3761
|
-
|
|
3762
|
-
|
|
4062
|
+
if (targetFullPath !== microLocation.fullPath) {
|
|
4063
|
+
updateMicroLocation(appName, targetFullPath, microLocation);
|
|
3763
4064
|
}
|
|
4065
|
+
(_c = (_a = appInstanceMap.get(appName)) === null || _a === void 0 ? void 0 : (_b = _a.sandBox).updateIframeBase) === null || _c === void 0 ? void 0 : _c.call(_b);
|
|
3764
4066
|
};
|
|
3765
4067
|
}
|
|
3766
4068
|
const pushState = getMicroHistoryMethod('pushState');
|
|
@@ -3769,6 +4071,9 @@ function createMicroHistory(appName, microLocation) {
|
|
|
3769
4071
|
return {
|
|
3770
4072
|
pushState,
|
|
3771
4073
|
replaceState,
|
|
4074
|
+
go(delta) {
|
|
4075
|
+
return rawHistory.go(delta);
|
|
4076
|
+
}
|
|
3772
4077
|
};
|
|
3773
4078
|
}
|
|
3774
4079
|
return new Proxy(rawHistory, {
|
|
@@ -3881,10 +4186,24 @@ function reWriteHistoryMethod(method) {
|
|
|
3881
4186
|
excludeHiddenApp: true,
|
|
3882
4187
|
excludePreRender: true,
|
|
3883
4188
|
}).forEach(appName => {
|
|
4189
|
+
// TODO: 大部分情况下,history.pushState 都是先执行,micro-app后卸载,所以会产生一种情况:跳转到新地址后,search模式会在url上添加参数,卸载后再将参数删除,所以会导致浏览器地址闪烁,是否需要去掉这个功能
|
|
3884
4190
|
if ((isRouterModeSearch(appName) || isRouterModeState(appName)) && !getMicroPathFromURL(appName)) {
|
|
3885
4191
|
const app = appInstanceMap.get(appName);
|
|
3886
4192
|
attachRouteToBrowserURL(appName, setMicroPathToURL(appName, app.sandBox.proxyWindow.location), setMicroState(appName, getMicroState(appName), app.sandBox.proxyWindow.location));
|
|
3887
4193
|
}
|
|
4194
|
+
if (isRouterModeCustom(appName) && !getMicroRouterInfoState(appName)) {
|
|
4195
|
+
nativeHistoryNavigate(appName, 'replaceState', rawWindow.location.href, setMicroState(appName));
|
|
4196
|
+
}
|
|
4197
|
+
// if (isRouterModeCustom(appName) || isRouterModeSearch(appName)) {
|
|
4198
|
+
/**
|
|
4199
|
+
* history.pushState/replaceState后主动触发子应用响应
|
|
4200
|
+
* 问题:子应用的卸载可能是异步的,而跳转的地址不一定在基础路径中,太快响应pushState可能会导致url地址被子应用改变或者子应用404,Promise太快卸载时出问题、setTimeout太慢keep-alive二次渲染后出问题
|
|
4201
|
+
* 1、history.pushState/replaceState执行后,子应用以异步的形式被主应用卸载,Promise响应时子应用还在,导致子应用跳转404后者浏览器url被子应用修改,产生异常
|
|
4202
|
+
* 2、keep-alive应用二次渲染时,由于setTimeout响应过慢,子应用在渲染后才接受到popstate事件,响应新的url,从而导致状态丢失
|
|
4203
|
+
* 3、同一个页面多个子应用,修改地址响应
|
|
4204
|
+
* 4、vue3跳转前会执行一次replace,有没有影响?
|
|
4205
|
+
*/
|
|
4206
|
+
// }
|
|
3888
4207
|
});
|
|
3889
4208
|
// fix bug for nest app
|
|
3890
4209
|
removeDomScope();
|
|
@@ -4415,12 +4734,12 @@ function autoTriggerNavigationGuard(appName, microLocation) {
|
|
|
4415
4734
|
* @param microLocation micro app location
|
|
4416
4735
|
* @param type auto prevent
|
|
4417
4736
|
*/
|
|
4418
|
-
function updateMicroLocation(appName,
|
|
4737
|
+
function updateMicroLocation(appName, targetFullPath, microLocation, type) {
|
|
4419
4738
|
var _a;
|
|
4420
4739
|
// record old values of microLocation to `from`
|
|
4421
4740
|
const from = createGuardLocation(appName, microLocation);
|
|
4422
4741
|
// if is iframeSandbox, microLocation muse be rawLocation of iframe, not proxyLocation
|
|
4423
|
-
const newLocation = createURL(
|
|
4742
|
+
const newLocation = createURL(targetFullPath, microLocation.href);
|
|
4424
4743
|
if (isIframeSandbox(appName)) {
|
|
4425
4744
|
const microAppWindow = appInstanceMap.get(appName).sandBox.microAppWindow;
|
|
4426
4745
|
(_a = microAppWindow.rawReplaceState) === null || _a === void 0 ? void 0 : _a.call(microAppWindow.history, getMicroState(appName), '', newLocation.href);
|
|
@@ -4432,6 +4751,20 @@ function updateMicroLocation(appName, path, microLocation, type) {
|
|
|
4432
4751
|
}
|
|
4433
4752
|
microLocation.self.href = targetHref;
|
|
4434
4753
|
}
|
|
4754
|
+
/**
|
|
4755
|
+
* native模式从state中取值,而浏览器地址的修改无法控制,很可能出现浏览器地址和__MICRO_APP_STATE__不一致的情况
|
|
4756
|
+
* 尤其是在初始化和前进后退时,由于vue-router4会主动修改url地址,倒是上述情况经常出现
|
|
4757
|
+
* 为了结局这个问题,在子应用初始化和响应popstate事件后,判断__MICRO_APP_STATE__和浏览器地址是否一致,如果不一致,则将浏览器地址更新为__MICRO_APP_STATE__的地址
|
|
4758
|
+
* 说明:
|
|
4759
|
+
* 1、如果__MICRO_APP_STATE__和url不一样,那么更新url的操作是对的,否则会产生url和渲染页面不一致的问题,开发者会更加困惑
|
|
4760
|
+
* 2、当native模式有多个子应用同时存在,其中一个修改url地址,另外一个并不会改变__MICRO_APP_STATE__,刷新就产生问题,不一致,第二是根据谁更新url?
|
|
4761
|
+
*/
|
|
4762
|
+
const rawLocation = globalEnv.rawWindow.location;
|
|
4763
|
+
if (isRouterModeCustom(appName) &&
|
|
4764
|
+
(targetFullPath !== rawLocation.pathname + rawLocation.search + rawLocation.hash) &&
|
|
4765
|
+
type !== 'prevent') {
|
|
4766
|
+
nativeHistoryNavigate(appName, 'replaceState', targetFullPath, globalEnv.rawWindow.history.state);
|
|
4767
|
+
}
|
|
4435
4768
|
// update latest values of microLocation to `to`
|
|
4436
4769
|
const to = createGuardLocation(appName, microLocation);
|
|
4437
4770
|
// The hook called only when fullPath changed
|
|
@@ -4515,130 +4848,6 @@ function removePathFromBrowser(appName) {
|
|
|
4515
4848
|
attachRouteToBrowserURL(appName, removeMicroPathFromURL(appName), removeMicroState(appName, globalEnv.rawWindow.history.state));
|
|
4516
4849
|
}
|
|
4517
4850
|
|
|
4518
|
-
class BaseSandbox {
|
|
4519
|
-
constructor() {
|
|
4520
|
-
// keys that can only assigned to rawWindow
|
|
4521
|
-
this.rawWindowScopeKeyList = [
|
|
4522
|
-
'location',
|
|
4523
|
-
];
|
|
4524
|
-
// keys that can escape to rawWindow
|
|
4525
|
-
this.staticEscapeProperties = [
|
|
4526
|
-
'System',
|
|
4527
|
-
'__cjsWrapper',
|
|
4528
|
-
];
|
|
4529
|
-
// keys that scoped in child app
|
|
4530
|
-
this.staticScopeProperties = [
|
|
4531
|
-
'webpackJsonp',
|
|
4532
|
-
'webpackHotUpdate',
|
|
4533
|
-
'Vue',
|
|
4534
|
-
// TODO: 是否可以和constants/SCOPE_WINDOW_ON_EVENT合并
|
|
4535
|
-
'onpopstate',
|
|
4536
|
-
'onhashchange',
|
|
4537
|
-
];
|
|
4538
|
-
// Properties that can only get and set in microAppWindow, will not escape to rawWindow
|
|
4539
|
-
this.scopeProperties = Array.from(this.staticScopeProperties);
|
|
4540
|
-
// Properties that can be escape to rawWindow
|
|
4541
|
-
this.escapeProperties = [];
|
|
4542
|
-
// Properties newly added to microAppWindow
|
|
4543
|
-
this.injectedKeys = new Set();
|
|
4544
|
-
// Properties escape to rawWindow, cleared when unmount
|
|
4545
|
-
this.escapeKeys = new Set();
|
|
4546
|
-
this.injectReactHMRProperty();
|
|
4547
|
-
}
|
|
4548
|
-
// adapter for react
|
|
4549
|
-
injectReactHMRProperty() {
|
|
4550
|
-
if ((process.env.NODE_ENV !== 'production')) {
|
|
4551
|
-
// react child in non-react env
|
|
4552
|
-
this.staticEscapeProperties.push('__REACT_ERROR_OVERLAY_GLOBAL_HOOK__');
|
|
4553
|
-
// in react parent
|
|
4554
|
-
if (globalEnv.rawWindow.__REACT_ERROR_OVERLAY_GLOBAL_HOOK__) {
|
|
4555
|
-
this.staticScopeProperties = this.staticScopeProperties.concat([
|
|
4556
|
-
'__REACT_ERROR_OVERLAY_GLOBAL_HOOK__',
|
|
4557
|
-
'__reactRefreshInjected',
|
|
4558
|
-
]);
|
|
4559
|
-
}
|
|
4560
|
-
}
|
|
4561
|
-
}
|
|
4562
|
-
}
|
|
4563
|
-
/**
|
|
4564
|
-
* TODO:
|
|
4565
|
-
* 1、将class Adapter去掉,改为CustomWindow,或者让CustomWindow继承Adapter
|
|
4566
|
-
* 2、with沙箱中的常量放入CustomWindow,虽然和iframe沙箱不一致,但更合理
|
|
4567
|
-
* 修改时机:在iframe沙箱支持插件后再修改
|
|
4568
|
-
*/
|
|
4569
|
-
class CustomWindow {
|
|
4570
|
-
}
|
|
4571
|
-
// Fix conflict of babel-polyfill@6.x
|
|
4572
|
-
function fixBabelPolyfill6() {
|
|
4573
|
-
if (globalEnv.rawWindow._babelPolyfill)
|
|
4574
|
-
globalEnv.rawWindow._babelPolyfill = false;
|
|
4575
|
-
}
|
|
4576
|
-
/**
|
|
4577
|
-
* Fix error of hot reload when parent&child created by create-react-app in development environment
|
|
4578
|
-
* Issue: https://github.com/micro-zoe/micro-app/issues/382
|
|
4579
|
-
*/
|
|
4580
|
-
function fixReactHMRConflict(app) {
|
|
4581
|
-
var _a;
|
|
4582
|
-
if ((process.env.NODE_ENV !== 'production')) {
|
|
4583
|
-
const rawReactErrorHook = globalEnv.rawWindow.__REACT_ERROR_OVERLAY_GLOBAL_HOOK__;
|
|
4584
|
-
const childReactErrorHook = (_a = app.sandBox) === null || _a === void 0 ? void 0 : _a.proxyWindow.__REACT_ERROR_OVERLAY_GLOBAL_HOOK__;
|
|
4585
|
-
if (rawReactErrorHook && childReactErrorHook) {
|
|
4586
|
-
globalEnv.rawWindow.__REACT_ERROR_OVERLAY_GLOBAL_HOOK__ = childReactErrorHook;
|
|
4587
|
-
defer(() => {
|
|
4588
|
-
globalEnv.rawWindow.__REACT_ERROR_OVERLAY_GLOBAL_HOOK__ = rawReactErrorHook;
|
|
4589
|
-
});
|
|
4590
|
-
}
|
|
4591
|
-
}
|
|
4592
|
-
}
|
|
4593
|
-
/**
|
|
4594
|
-
* update dom tree of target dom
|
|
4595
|
-
* @param container target dom
|
|
4596
|
-
* @param appName app name
|
|
4597
|
-
*/
|
|
4598
|
-
function patchElementTree(container, appName) {
|
|
4599
|
-
const children = Array.from(container.children);
|
|
4600
|
-
children.length && children.forEach((child) => {
|
|
4601
|
-
patchElementTree(child, appName);
|
|
4602
|
-
});
|
|
4603
|
-
for (const child of children) {
|
|
4604
|
-
updateElementInfo(child, appName);
|
|
4605
|
-
}
|
|
4606
|
-
}
|
|
4607
|
-
/**
|
|
4608
|
-
* rewrite baseURI, ownerDocument, __MICRO_APP_NAME__ of target node
|
|
4609
|
-
* @param node target node
|
|
4610
|
-
* @param appName app name
|
|
4611
|
-
* @returns target node
|
|
4612
|
-
*/
|
|
4613
|
-
function updateElementInfo(node, appName) {
|
|
4614
|
-
var _a, _b;
|
|
4615
|
-
const proxyWindow = (_b = (_a = appInstanceMap.get(appName)) === null || _a === void 0 ? void 0 : _a.sandBox) === null || _b === void 0 ? void 0 : _b.proxyWindow;
|
|
4616
|
-
if (isNode(node) &&
|
|
4617
|
-
!node.__MICRO_APP_NAME__ &&
|
|
4618
|
-
!node.__PURE_ELEMENT__ &&
|
|
4619
|
-
proxyWindow) {
|
|
4620
|
-
/**
|
|
4621
|
-
* TODO:
|
|
4622
|
-
* 1. 测试baseURI和ownerDocument在with沙箱中是否正确
|
|
4623
|
-
* 经过验证with沙箱不能重写ownerDocument,否则react点击事件会触发两次
|
|
4624
|
-
* 2. with沙箱所有node设置__MICRO_APP_NAME__都使用updateElementInfo
|
|
4625
|
-
*/
|
|
4626
|
-
rawDefineProperties(node, {
|
|
4627
|
-
baseURI: {
|
|
4628
|
-
configurable: true,
|
|
4629
|
-
// if disable-memory-router or router-mode='disable', href point to base app
|
|
4630
|
-
get: () => proxyWindow.location.href,
|
|
4631
|
-
},
|
|
4632
|
-
__MICRO_APP_NAME__: {
|
|
4633
|
-
configurable: true,
|
|
4634
|
-
writable: true,
|
|
4635
|
-
value: appName,
|
|
4636
|
-
},
|
|
4637
|
-
});
|
|
4638
|
-
}
|
|
4639
|
-
return node;
|
|
4640
|
-
}
|
|
4641
|
-
|
|
4642
4851
|
/**
|
|
4643
4852
|
* https://developer.mozilla.org/en-US/docs/Web/API/fetch
|
|
4644
4853
|
* Promise<Response> fetch(input[, init])
|
|
@@ -4743,7 +4952,7 @@ function useMicroEventSource() {
|
|
|
4743
4952
|
const { createMicroEventSource, clearMicroEventSource } = useMicroEventSource();
|
|
4744
4953
|
class WithSandBox extends BaseSandbox {
|
|
4745
4954
|
constructor(appName, url) {
|
|
4746
|
-
super();
|
|
4955
|
+
super(appName, url);
|
|
4747
4956
|
this.active = false;
|
|
4748
4957
|
this.microAppWindow = new CustomWindow(); // Proxy target
|
|
4749
4958
|
this.patchWith((resolve) => {
|
|
@@ -4824,6 +5033,7 @@ class WithSandBox extends BaseSandbox {
|
|
|
4824
5033
|
* 1. injectedKeys and escapeKeys must be placed at the back
|
|
4825
5034
|
* 2. if key in initial microAppWindow, and then rewrite, this key will be delete from microAppWindow when stop, and lost when restart
|
|
4826
5035
|
* 3. umd mode will not delete global keys
|
|
5036
|
+
* 4. mount & unmount hook should delete in default mode when stop
|
|
4827
5037
|
*/
|
|
4828
5038
|
if (!umdMode || destroy) {
|
|
4829
5039
|
clearMicroEventSource(this.microAppWindow.__MICRO_APP_NAME__);
|
|
@@ -4835,6 +5045,7 @@ class WithSandBox extends BaseSandbox {
|
|
|
4835
5045
|
Reflect.deleteProperty(globalEnv.rawWindow, key);
|
|
4836
5046
|
});
|
|
4837
5047
|
this.escapeKeys.clear();
|
|
5048
|
+
this.clearHijackUmdHooks();
|
|
4838
5049
|
}
|
|
4839
5050
|
if (--globalEnv.activeSandbox === 0) {
|
|
4840
5051
|
releasePatchElementAndDocument();
|
|
@@ -4867,6 +5078,7 @@ class WithSandBox extends BaseSandbox {
|
|
|
4867
5078
|
microAppWindow.microApp = assign(new EventCenterForMicroApp(appName), {
|
|
4868
5079
|
removeDomScope,
|
|
4869
5080
|
pureCreateElement,
|
|
5081
|
+
location: microAppWindow.location,
|
|
4870
5082
|
router,
|
|
4871
5083
|
});
|
|
4872
5084
|
}
|
|
@@ -5148,10 +5360,49 @@ class WithSandBox extends BaseSandbox {
|
|
|
5148
5360
|
* action before exec scripts when mount
|
|
5149
5361
|
* Actions:
|
|
5150
5362
|
* 1. patch static elements from html
|
|
5363
|
+
* 2. hijack umd hooks -- mount, unmount, micro-app-appName
|
|
5151
5364
|
* @param container micro app container
|
|
5152
5365
|
*/
|
|
5153
|
-
|
|
5366
|
+
actionsBeforeExecScripts(container, handleUmdHooks) {
|
|
5154
5367
|
this.patchStaticElement(container);
|
|
5368
|
+
this.clearHijackUmdHooks = this.hijackUmdHooks(this.appName, this.microAppWindow, handleUmdHooks);
|
|
5369
|
+
}
|
|
5370
|
+
// hijack mount, unmount, micro-app-appName hook to microAppWindow
|
|
5371
|
+
hijackUmdHooks(appName, microAppWindow, handleUmdHooks) {
|
|
5372
|
+
let mount, unmount, microAppLibrary;
|
|
5373
|
+
rawDefineProperties(microAppWindow, {
|
|
5374
|
+
mount: {
|
|
5375
|
+
configurable: true,
|
|
5376
|
+
get: () => mount,
|
|
5377
|
+
set: (value) => {
|
|
5378
|
+
if (this.active && isFunction(value) && !mount) {
|
|
5379
|
+
handleUmdHooks(mount = value, unmount);
|
|
5380
|
+
}
|
|
5381
|
+
}
|
|
5382
|
+
},
|
|
5383
|
+
unmount: {
|
|
5384
|
+
configurable: true,
|
|
5385
|
+
get: () => unmount,
|
|
5386
|
+
set: (value) => {
|
|
5387
|
+
if (this.active && isFunction(value) && !unmount) {
|
|
5388
|
+
handleUmdHooks(mount, unmount = value);
|
|
5389
|
+
}
|
|
5390
|
+
}
|
|
5391
|
+
},
|
|
5392
|
+
[`micro-app-${appName}`]: {
|
|
5393
|
+
configurable: true,
|
|
5394
|
+
get: () => microAppLibrary,
|
|
5395
|
+
set: (value) => {
|
|
5396
|
+
if (this.active && isPlainObject(value) && !microAppLibrary) {
|
|
5397
|
+
microAppLibrary = value;
|
|
5398
|
+
handleUmdHooks(microAppLibrary.mount, microAppLibrary.unmount);
|
|
5399
|
+
}
|
|
5400
|
+
}
|
|
5401
|
+
}
|
|
5402
|
+
});
|
|
5403
|
+
return () => {
|
|
5404
|
+
mount = unmount = microAppLibrary = null;
|
|
5405
|
+
};
|
|
5155
5406
|
}
|
|
5156
5407
|
setStaticAppState(state) {
|
|
5157
5408
|
this.microAppWindow.__MICRO_APP_STATE__ = state;
|
|
@@ -5196,9 +5447,10 @@ function patchRouter(appName, url, microAppWindow, browserHost) {
|
|
|
5196
5447
|
|
|
5197
5448
|
const escape2RawWindowKeys = [
|
|
5198
5449
|
'getComputedStyle',
|
|
5450
|
+
// FIX ISSUE: https://github.com/micro-zoe/micro-app/issues/1292
|
|
5451
|
+
'DOMParser',
|
|
5199
5452
|
'visualViewport',
|
|
5200
5453
|
'matchMedia',
|
|
5201
|
-
// 'DOMParser',
|
|
5202
5454
|
'ResizeObserver',
|
|
5203
5455
|
'IntersectionObserver',
|
|
5204
5456
|
];
|
|
@@ -5207,7 +5459,6 @@ const escape2RawWindowRegExpKeys = [
|
|
|
5207
5459
|
/mutationObserver$/i,
|
|
5208
5460
|
/height$|width$/i,
|
|
5209
5461
|
/offset$/i,
|
|
5210
|
-
// /event$/i,
|
|
5211
5462
|
/selection$/i,
|
|
5212
5463
|
/^range/i,
|
|
5213
5464
|
/^screen/i,
|
|
@@ -5220,7 +5471,7 @@ const uniqueDocumentElement = [
|
|
|
5220
5471
|
'html',
|
|
5221
5472
|
'title',
|
|
5222
5473
|
];
|
|
5223
|
-
//
|
|
5474
|
+
// proxy to shadowRoot or rawDocument (property)
|
|
5224
5475
|
const proxy2RawDocOrShadowKeys = [
|
|
5225
5476
|
'childElementCount',
|
|
5226
5477
|
'children',
|
|
@@ -5233,7 +5484,7 @@ const proxy2RawDocOrShadowKeys = [
|
|
|
5233
5484
|
'pointerLockElement',
|
|
5234
5485
|
'styleSheets',
|
|
5235
5486
|
];
|
|
5236
|
-
//
|
|
5487
|
+
// proxy to shadowRoot or rawDocument (method)
|
|
5237
5488
|
const proxy2RawDocOrShadowMethods = [
|
|
5238
5489
|
'append',
|
|
5239
5490
|
'contains',
|
|
@@ -5244,7 +5495,7 @@ const proxy2RawDocOrShadowMethods = [
|
|
|
5244
5495
|
'elementsFromPoint',
|
|
5245
5496
|
'getAnimations',
|
|
5246
5497
|
];
|
|
5247
|
-
//
|
|
5498
|
+
// proxy to rawDocument (property)
|
|
5248
5499
|
const proxy2RawDocumentKeys = [
|
|
5249
5500
|
'characterSet',
|
|
5250
5501
|
'compatMode',
|
|
@@ -5264,7 +5515,7 @@ const proxy2RawDocumentKeys = [
|
|
|
5264
5515
|
'visibilityState',
|
|
5265
5516
|
'fonts',
|
|
5266
5517
|
];
|
|
5267
|
-
//
|
|
5518
|
+
// proxy to rawDocument (method)
|
|
5268
5519
|
const proxy2RawDocumentMethods = [
|
|
5269
5520
|
'execCommand',
|
|
5270
5521
|
'createRange',
|
|
@@ -5322,6 +5573,40 @@ function patchWindowProperty$1(appName, microAppWindow) {
|
|
|
5322
5573
|
}
|
|
5323
5574
|
return false;
|
|
5324
5575
|
});
|
|
5576
|
+
/**
|
|
5577
|
+
* In FireFox, iframe Element.prototype will point to native Element.prototype after insert to document
|
|
5578
|
+
* Rewrite all constructor's Symbol.hasInstance of iframeWindow
|
|
5579
|
+
* NOTE:
|
|
5580
|
+
* 1. native event instanceof iframe window.Event
|
|
5581
|
+
* 2. native node instanceof iframe window.Node
|
|
5582
|
+
* 3. native element instanceof iframe window.Element
|
|
5583
|
+
* 4. native url instanceof iframe window.URL
|
|
5584
|
+
* ...
|
|
5585
|
+
*/
|
|
5586
|
+
if (isConstructor(microAppWindow[key]) && key in rawWindow) {
|
|
5587
|
+
rawDefineProperty(microAppWindow[key], Symbol.hasInstance, {
|
|
5588
|
+
configurable: true,
|
|
5589
|
+
enumerable: false,
|
|
5590
|
+
value(target) {
|
|
5591
|
+
return target instanceof rawWindow[key] || instanceOf(target, microAppWindow[key]);
|
|
5592
|
+
},
|
|
5593
|
+
});
|
|
5594
|
+
}
|
|
5595
|
+
// hijackInstanceOfWindowRegExpKeys.some((reg: RegExp) => {
|
|
5596
|
+
// if (reg.test(key) && key in rawWindow) {
|
|
5597
|
+
// rawDefineProperty(microAppWindow[key], Symbol.hasInstance, {
|
|
5598
|
+
// configurable: true,
|
|
5599
|
+
// enumerable: false,
|
|
5600
|
+
// value: (target: unknown) => {
|
|
5601
|
+
// return target instanceof rawWindow[key]
|
|
5602
|
+
// ? true
|
|
5603
|
+
// : instanceOf(target, microAppWindow[key])
|
|
5604
|
+
// },
|
|
5605
|
+
// })
|
|
5606
|
+
// return true
|
|
5607
|
+
// }
|
|
5608
|
+
// return false
|
|
5609
|
+
// })
|
|
5325
5610
|
return /^on/.test(key) && !SCOPE_WINDOW_ON_EVENT_OF_IFRAME.includes(key);
|
|
5326
5611
|
})
|
|
5327
5612
|
.forEach((eventName) => {
|
|
@@ -5407,10 +5692,14 @@ function createProxyWindow$1(microAppWindow, sandbox) {
|
|
|
5407
5692
|
sandbox.proxyWindow = proxyWindow;
|
|
5408
5693
|
}
|
|
5409
5694
|
function patchWindowEffect$1(microAppWindow) {
|
|
5410
|
-
const { rawWindow, rawAddEventListener, rawRemoveEventListener } = globalEnv;
|
|
5695
|
+
const { rawWindow, rawAddEventListener, rawRemoveEventListener, rawDispatchEvent } = globalEnv;
|
|
5411
5696
|
const eventListenerMap = new Map();
|
|
5412
5697
|
const sstEventListenerMap = new Map();
|
|
5413
5698
|
function getEventTarget(type) {
|
|
5699
|
+
/**
|
|
5700
|
+
* TODO: SCOPE_WINDOW_EVENT_OF_IFRAME的事件非常少,有可能导致问题
|
|
5701
|
+
* 1、一些未知的需要绑定到iframe的事件被错误的绑定到原生window上
|
|
5702
|
+
*/
|
|
5414
5703
|
return SCOPE_WINDOW_EVENT_OF_IFRAME.includes(type) ? microAppWindow : rawWindow;
|
|
5415
5704
|
}
|
|
5416
5705
|
// TODO: listener 是否需要绑定microAppWindow,否则函数中的this指向原生window
|
|
@@ -5432,6 +5721,9 @@ function patchWindowEffect$1(microAppWindow) {
|
|
|
5432
5721
|
}
|
|
5433
5722
|
rawRemoveEventListener.call(getEventTarget(type), type, listener, options);
|
|
5434
5723
|
};
|
|
5724
|
+
microAppWindow.dispatchEvent = function (event) {
|
|
5725
|
+
return rawDispatchEvent.call(getEventTarget(event === null || event === void 0 ? void 0 : event.type), event);
|
|
5726
|
+
};
|
|
5435
5727
|
const reset = () => {
|
|
5436
5728
|
sstEventListenerMap.clear();
|
|
5437
5729
|
};
|
|
@@ -5543,34 +5835,43 @@ function patchDocumentPrototype(appName, microAppWindow) {
|
|
|
5543
5835
|
const element = rawMicroCreateComment.call(this, data);
|
|
5544
5836
|
return updateElementInfo(element, appName);
|
|
5545
5837
|
};
|
|
5546
|
-
function
|
|
5547
|
-
|
|
5838
|
+
function getBindTarget(target) {
|
|
5839
|
+
/**
|
|
5840
|
+
* handler for:
|
|
5841
|
+
* 1. document.getElementsByTagName('head')[0].querySelector('script')
|
|
5842
|
+
* 2. document.querySelector('body').querySelectorAll('script')
|
|
5843
|
+
* ...
|
|
5844
|
+
*/
|
|
5845
|
+
throttleDeferForIframeAppName(appName);
|
|
5846
|
+
// DOMParser.document !== microDocument
|
|
5847
|
+
return microDocument === target ? rawDocument : target;
|
|
5548
5848
|
}
|
|
5549
5849
|
// query element👇
|
|
5550
5850
|
function querySelector(selectors) {
|
|
5551
|
-
var _a, _b;
|
|
5851
|
+
var _a, _b, _c;
|
|
5852
|
+
const _this = getBindTarget(this);
|
|
5552
5853
|
if (!selectors ||
|
|
5553
5854
|
isUniqueElement(selectors) ||
|
|
5554
|
-
|
|
5555
|
-
const _this = getDefaultRawTarget(this);
|
|
5855
|
+
rawDocument !== _this) {
|
|
5556
5856
|
return rawMicroQuerySelector.call(_this, selectors);
|
|
5557
5857
|
}
|
|
5558
|
-
return (_b = (_a = appInstanceMap.get(appName)) === null || _a === void 0 ? void 0 : _a.querySelector(selectors)) !== null && _b !== void 0 ? _b : null;
|
|
5858
|
+
return (_c = (_b = (_a = appInstanceMap.get(appName)) === null || _a === void 0 ? void 0 : _a.querySelector(selectors)) !== null && _b !== void 0 ? _b : rawMicroQuerySelector.call(microDocument, selectors)) !== null && _c !== void 0 ? _c : null;
|
|
5559
5859
|
}
|
|
5560
5860
|
function querySelectorAll(selectors) {
|
|
5561
5861
|
var _a, _b;
|
|
5862
|
+
const _this = getBindTarget(this);
|
|
5562
5863
|
if (!selectors ||
|
|
5563
5864
|
isUniqueElement(selectors) ||
|
|
5564
|
-
|
|
5565
|
-
const _this = getDefaultRawTarget(this);
|
|
5865
|
+
rawDocument !== _this) {
|
|
5566
5866
|
return rawMicroQuerySelectorAll.call(_this, selectors);
|
|
5567
5867
|
}
|
|
5568
|
-
|
|
5868
|
+
const result = (_b = (_a = appInstanceMap.get(appName)) === null || _a === void 0 ? void 0 : _a.querySelectorAll(selectors)) !== null && _b !== void 0 ? _b : [];
|
|
5869
|
+
return result.length ? result : rawMicroQuerySelectorAll.call(microDocument, selectors);
|
|
5569
5870
|
}
|
|
5570
5871
|
microRootDocument.prototype.querySelector = querySelector;
|
|
5571
5872
|
microRootDocument.prototype.querySelectorAll = querySelectorAll;
|
|
5572
5873
|
microRootDocument.prototype.getElementById = function getElementById(key) {
|
|
5573
|
-
const _this =
|
|
5874
|
+
const _this = getBindTarget(this);
|
|
5574
5875
|
if (isInvalidQuerySelectorKey(key)) {
|
|
5575
5876
|
return rawMicroGetElementById.call(_this, key);
|
|
5576
5877
|
}
|
|
@@ -5582,7 +5883,7 @@ function patchDocumentPrototype(appName, microAppWindow) {
|
|
|
5582
5883
|
}
|
|
5583
5884
|
};
|
|
5584
5885
|
microRootDocument.prototype.getElementsByClassName = function getElementsByClassName(key) {
|
|
5585
|
-
const _this =
|
|
5886
|
+
const _this = getBindTarget(this);
|
|
5586
5887
|
if (isInvalidQuerySelectorKey(key)) {
|
|
5587
5888
|
return rawMicroGetElementsByClassName.call(_this, key);
|
|
5588
5889
|
}
|
|
@@ -5594,7 +5895,7 @@ function patchDocumentPrototype(appName, microAppWindow) {
|
|
|
5594
5895
|
}
|
|
5595
5896
|
};
|
|
5596
5897
|
microRootDocument.prototype.getElementsByTagName = function getElementsByTagName(key) {
|
|
5597
|
-
const _this =
|
|
5898
|
+
const _this = getBindTarget(this);
|
|
5598
5899
|
if (isUniqueElement(key) ||
|
|
5599
5900
|
isInvalidQuerySelectorKey(key)) {
|
|
5600
5901
|
return rawMicroGetElementsByTagName.call(_this, key);
|
|
@@ -5610,7 +5911,7 @@ function patchDocumentPrototype(appName, microAppWindow) {
|
|
|
5610
5911
|
}
|
|
5611
5912
|
};
|
|
5612
5913
|
microRootDocument.prototype.getElementsByName = function getElementsByName(key) {
|
|
5613
|
-
const _this =
|
|
5914
|
+
const _this = getBindTarget(this);
|
|
5614
5915
|
if (isInvalidQuerySelectorKey(key)) {
|
|
5615
5916
|
return rawMicroGetElementsByName.call(_this, key);
|
|
5616
5917
|
}
|
|
@@ -5677,7 +5978,7 @@ function patchDocumentProperty(appName, microAppWindow, sandbox) {
|
|
|
5677
5978
|
enumerable: true,
|
|
5678
5979
|
configurable: true,
|
|
5679
5980
|
get: () => {
|
|
5680
|
-
|
|
5981
|
+
throttleDeferForIframeAppName(appName);
|
|
5681
5982
|
return rawDocument[tagName];
|
|
5682
5983
|
},
|
|
5683
5984
|
set: (value) => { rawDocument[tagName] = value; },
|
|
@@ -5685,7 +5986,7 @@ function patchDocumentProperty(appName, microAppWindow, sandbox) {
|
|
|
5685
5986
|
});
|
|
5686
5987
|
}
|
|
5687
5988
|
function patchDocumentEffect(appName, microAppWindow) {
|
|
5688
|
-
const { rawDocument, rawAddEventListener, rawRemoveEventListener } = globalEnv;
|
|
5989
|
+
const { rawDocument, rawAddEventListener, rawRemoveEventListener, rawDispatchEvent } = globalEnv;
|
|
5689
5990
|
const eventListenerMap = new Map();
|
|
5690
5991
|
const sstEventListenerMap = new Map();
|
|
5691
5992
|
let onClickHandler = null;
|
|
@@ -5715,6 +6016,9 @@ function patchDocumentEffect(appName, microAppWindow) {
|
|
|
5715
6016
|
const handler = (listener === null || listener === void 0 ? void 0 : listener.__MICRO_APP_BOUND_FUNCTION__) || listener;
|
|
5716
6017
|
rawRemoveEventListener.call(getEventTarget(type, this), type, handler, options);
|
|
5717
6018
|
};
|
|
6019
|
+
microRootDocument.prototype.dispatchEvent = function (event) {
|
|
6020
|
+
return rawDispatchEvent.call(getEventTarget(event === null || event === void 0 ? void 0 : event.type, this), event);
|
|
6021
|
+
};
|
|
5718
6022
|
// 重新定义microRootDocument.prototype 上的on开头方法
|
|
5719
6023
|
function createSetterHandler(eventName) {
|
|
5720
6024
|
if (eventName === 'onclick') {
|
|
@@ -5835,12 +6139,18 @@ function patchElement(appName, url, microAppWindow, sandbox) {
|
|
|
5835
6139
|
patchIframeNode(appName, microAppWindow, sandbox);
|
|
5836
6140
|
patchIframeAttribute(url, microAppWindow);
|
|
5837
6141
|
}
|
|
6142
|
+
/**
|
|
6143
|
+
* patch iframe Node/Element
|
|
6144
|
+
*
|
|
6145
|
+
*/
|
|
5838
6146
|
function patchIframeNode(appName, microAppWindow, sandbox) {
|
|
5839
6147
|
const rawRootElement = globalEnv.rawRootElement; // native root Element
|
|
6148
|
+
const rawRootNode = globalEnv.rawRootNode;
|
|
5840
6149
|
const rawDocument = globalEnv.rawDocument;
|
|
5841
6150
|
const microDocument = microAppWindow.document;
|
|
5842
6151
|
const microRootNode = microAppWindow.Node;
|
|
5843
6152
|
const microRootElement = microAppWindow.Element;
|
|
6153
|
+
const microDocumentFragment = microAppWindow.DocumentFragment;
|
|
5844
6154
|
// const rawMicroGetRootNode = microRootNode.prototype.getRootNode
|
|
5845
6155
|
const rawMicroAppendChild = microRootNode.prototype.appendChild;
|
|
5846
6156
|
const rawMicroInsertBefore = microRootNode.prototype.insertBefore;
|
|
@@ -5848,6 +6158,8 @@ function patchIframeNode(appName, microAppWindow, sandbox) {
|
|
|
5848
6158
|
const rawMicroRemoveChild = microRootNode.prototype.removeChild;
|
|
5849
6159
|
const rawMicroAppend = microRootElement.prototype.append;
|
|
5850
6160
|
const rawMicroPrepend = microRootElement.prototype.prepend;
|
|
6161
|
+
const rawMicroFragmentAppend = microDocumentFragment.prototype.append;
|
|
6162
|
+
const rawMicroFragmentPrepend = microDocumentFragment.prototype.prepend;
|
|
5851
6163
|
const rawMicroInsertAdjacentElement = microRootElement.prototype.insertAdjacentElement;
|
|
5852
6164
|
const rawMicroCloneNode = microRootNode.prototype.cloneNode;
|
|
5853
6165
|
const rawInnerHTMLDesc = Object.getOwnPropertyDescriptor(microRootElement.prototype, 'innerHTML');
|
|
@@ -5865,42 +6177,34 @@ function patchIframeNode(appName, microAppWindow, sandbox) {
|
|
|
5865
6177
|
}
|
|
5866
6178
|
return parent;
|
|
5867
6179
|
};
|
|
5868
|
-
microRootNode.prototype.getRootNode = function getRootNode() {
|
|
5869
|
-
return microDocument;
|
|
5870
|
-
// TODO: 什么情况下返回原生document?
|
|
5871
|
-
// const rootNode = rawMicroGetRootNode.call(this, options)
|
|
5872
|
-
// if (rootNode === appInstanceMap.get(appName)?.container) return microDocument
|
|
5873
|
-
// return rootNode
|
|
5874
|
-
};
|
|
5875
6180
|
microRootNode.prototype.appendChild = function appendChild(node) {
|
|
5876
|
-
// TODO: 有必要执行这么多次updateElementInfo?
|
|
5877
6181
|
updateElementInfo(node, appName);
|
|
5878
6182
|
if (isPureNode(node)) {
|
|
5879
6183
|
return rawMicroAppendChild.call(this, node);
|
|
5880
6184
|
}
|
|
5881
|
-
return
|
|
6185
|
+
return rawRootNode.prototype.appendChild.call(getRawTarget(this), node);
|
|
5882
6186
|
};
|
|
5883
6187
|
microRootNode.prototype.insertBefore = function insertBefore(node, child) {
|
|
5884
6188
|
updateElementInfo(node, appName);
|
|
5885
6189
|
if (isPureNode(node)) {
|
|
5886
6190
|
return rawMicroInsertBefore.call(this, node, child);
|
|
5887
6191
|
}
|
|
5888
|
-
return
|
|
6192
|
+
return rawRootNode.prototype.insertBefore.call(getRawTarget(this), node, child);
|
|
5889
6193
|
};
|
|
5890
6194
|
microRootNode.prototype.replaceChild = function replaceChild(node, child) {
|
|
5891
6195
|
updateElementInfo(node, appName);
|
|
5892
6196
|
if (isPureNode(node)) {
|
|
5893
6197
|
return rawMicroReplaceChild.call(this, node, child);
|
|
5894
6198
|
}
|
|
5895
|
-
return
|
|
6199
|
+
return rawRootNode.prototype.replaceChild.call(getRawTarget(this), node, child);
|
|
5896
6200
|
};
|
|
5897
6201
|
microRootNode.prototype.removeChild = function removeChild(oldChild) {
|
|
5898
6202
|
if (isPureNode(oldChild) || this.contains(oldChild)) {
|
|
5899
6203
|
return rawMicroRemoveChild.call(this, oldChild);
|
|
5900
6204
|
}
|
|
5901
|
-
return
|
|
6205
|
+
return rawRootNode.prototype.removeChild.call(getRawTarget(this), oldChild);
|
|
5902
6206
|
};
|
|
5903
|
-
microRootElement.prototype.append = function append(...nodes) {
|
|
6207
|
+
microDocumentFragment.prototype.append = microRootElement.prototype.append = function append(...nodes) {
|
|
5904
6208
|
let i = 0;
|
|
5905
6209
|
let hasPureNode = false;
|
|
5906
6210
|
while (i < nodes.length) {
|
|
@@ -5910,11 +6214,11 @@ function patchIframeNode(appName, microAppWindow, sandbox) {
|
|
|
5910
6214
|
i++;
|
|
5911
6215
|
}
|
|
5912
6216
|
if (hasPureNode) {
|
|
5913
|
-
return rawMicroAppend.call(this, ...nodes);
|
|
6217
|
+
return (isDocumentFragment(this) ? rawMicroFragmentAppend : rawMicroAppend).call(this, ...nodes);
|
|
5914
6218
|
}
|
|
5915
6219
|
return rawRootElement.prototype.append.call(getRawTarget(this), ...nodes);
|
|
5916
6220
|
};
|
|
5917
|
-
microRootElement.prototype.prepend = function prepend(...nodes) {
|
|
6221
|
+
microDocumentFragment.prototype.prepend = microRootElement.prototype.prepend = function prepend(...nodes) {
|
|
5918
6222
|
let i = 0;
|
|
5919
6223
|
let hasPureNode = false;
|
|
5920
6224
|
while (i < nodes.length) {
|
|
@@ -5924,7 +6228,7 @@ function patchIframeNode(appName, microAppWindow, sandbox) {
|
|
|
5924
6228
|
i++;
|
|
5925
6229
|
}
|
|
5926
6230
|
if (hasPureNode) {
|
|
5927
|
-
return rawMicroPrepend.call(this, ...nodes);
|
|
6231
|
+
return (isDocumentFragment(this) ? rawMicroFragmentPrepend : rawMicroPrepend).call(this, ...nodes);
|
|
5928
6232
|
}
|
|
5929
6233
|
return rawRootElement.prototype.prepend.call(getRawTarget(this), ...nodes);
|
|
5930
6234
|
};
|
|
@@ -5940,28 +6244,53 @@ function patchIframeNode(appName, microAppWindow, sandbox) {
|
|
|
5940
6244
|
}
|
|
5941
6245
|
return rawRootElement.prototype.insertAdjacentElement.call(getRawTarget(this), where, element);
|
|
5942
6246
|
};
|
|
5943
|
-
|
|
5944
|
-
|
|
5945
|
-
|
|
5946
|
-
|
|
5947
|
-
|
|
6247
|
+
/**
|
|
6248
|
+
* Specific prototype properties:
|
|
6249
|
+
* 1. baseURI
|
|
6250
|
+
* 2. ownerDocument
|
|
6251
|
+
* 3. parentNode
|
|
6252
|
+
* 4. innerHTML
|
|
6253
|
+
*/
|
|
6254
|
+
rawDefineProperty(microRootNode.prototype, 'baseURI', {
|
|
6255
|
+
configurable: true,
|
|
6256
|
+
enumerable: true,
|
|
6257
|
+
get() {
|
|
6258
|
+
return sandbox.proxyWindow.location.href;
|
|
6259
|
+
},
|
|
6260
|
+
});
|
|
5948
6261
|
rawDefineProperty(microRootNode.prototype, 'ownerDocument', {
|
|
5949
6262
|
configurable: true,
|
|
5950
6263
|
enumerable: true,
|
|
5951
6264
|
get() {
|
|
6265
|
+
var _a;
|
|
5952
6266
|
return this.__PURE_ELEMENT__ || this === microDocument
|
|
5953
|
-
? rawOwnerDocumentDesc.get.call(this)
|
|
5954
|
-
: microDocument;
|
|
6267
|
+
? (_a = rawOwnerDocumentDesc.get) === null || _a === void 0 ? void 0 : _a.call(this) : microDocument;
|
|
5955
6268
|
},
|
|
5956
6269
|
});
|
|
6270
|
+
// patch parentNode
|
|
6271
|
+
rawDefineProperty(microRootNode.prototype, 'parentNode', getIframeParentNodeDesc(appName, rawParentNodeDesc));
|
|
6272
|
+
microRootNode.prototype.getRootNode = function getRootNode() {
|
|
6273
|
+
return microDocument;
|
|
6274
|
+
// TODO: any case return document?
|
|
6275
|
+
// const rootNode = rawMicroGetRootNode.call(this, options)
|
|
6276
|
+
// if (rootNode === appInstanceMap.get(appName)?.container) return microDocument
|
|
6277
|
+
// return rootNode
|
|
6278
|
+
};
|
|
6279
|
+
// patch cloneNode
|
|
6280
|
+
microRootNode.prototype.cloneNode = function cloneNode(deep) {
|
|
6281
|
+
const clonedNode = rawMicroCloneNode.call(this, deep);
|
|
6282
|
+
return updateElementInfo(clonedNode, appName);
|
|
6283
|
+
};
|
|
5957
6284
|
rawDefineProperty(microRootElement.prototype, 'innerHTML', {
|
|
5958
6285
|
configurable: true,
|
|
5959
6286
|
enumerable: true,
|
|
5960
6287
|
get() {
|
|
5961
|
-
|
|
6288
|
+
var _a;
|
|
6289
|
+
return (_a = rawInnerHTMLDesc.get) === null || _a === void 0 ? void 0 : _a.call(this);
|
|
5962
6290
|
},
|
|
5963
6291
|
set(code) {
|
|
5964
|
-
|
|
6292
|
+
var _a;
|
|
6293
|
+
(_a = rawInnerHTMLDesc.set) === null || _a === void 0 ? void 0 : _a.call(this, code);
|
|
5965
6294
|
Array.from(this.children).forEach((child) => {
|
|
5966
6295
|
if (isElement(child)) {
|
|
5967
6296
|
updateElementInfo(child, appName);
|
|
@@ -5969,34 +6298,6 @@ function patchIframeNode(appName, microAppWindow, sandbox) {
|
|
|
5969
6298
|
});
|
|
5970
6299
|
}
|
|
5971
6300
|
});
|
|
5972
|
-
// patch parentNode
|
|
5973
|
-
rawDefineProperty(microRootNode.prototype, 'parentNode', {
|
|
5974
|
-
configurable: true,
|
|
5975
|
-
enumerable: true,
|
|
5976
|
-
get() {
|
|
5977
|
-
var _a, _b, _c;
|
|
5978
|
-
/**
|
|
5979
|
-
* set current appName for hijack parentNode of html
|
|
5980
|
-
* NOTE:
|
|
5981
|
-
* 1. Is there a problem with setting the current appName in iframe mode
|
|
5982
|
-
*/
|
|
5983
|
-
throttleDeferForSetAppName(appName);
|
|
5984
|
-
const result = rawParentNodeDesc.get.call(this);
|
|
5985
|
-
/**
|
|
5986
|
-
* If parentNode is <micro-app-body>, return rawDocument.body
|
|
5987
|
-
* Scenes:
|
|
5988
|
-
* 1. element-ui@2/lib/utils/vue-popper.js
|
|
5989
|
-
* if (this.popperElm.parentNode === document.body) ...
|
|
5990
|
-
* WARNING:
|
|
5991
|
-
* Will it cause other problems ?
|
|
5992
|
-
* e.g. target.parentNode.remove(target)
|
|
5993
|
-
*/
|
|
5994
|
-
if (isMicroAppBody(result) && ((_a = appInstanceMap.get(appName)) === null || _a === void 0 ? void 0 : _a.container)) {
|
|
5995
|
-
return ((_c = (_b = microApp.options).getRootElementParentNode) === null || _c === void 0 ? void 0 : _c.call(_b, this, appName)) || globalEnv.rawDocument.body;
|
|
5996
|
-
}
|
|
5997
|
-
return result;
|
|
5998
|
-
}
|
|
5999
|
-
});
|
|
6000
6301
|
// Adapt to new image(...) scene
|
|
6001
6302
|
const ImageProxy = new Proxy(microAppWindow.Image, {
|
|
6002
6303
|
construct(Target, args) {
|
|
@@ -6015,16 +6316,24 @@ function patchIframeAttribute(url, microAppWindow) {
|
|
|
6015
6316
|
const microRootElement = microAppWindow.Element;
|
|
6016
6317
|
const rawMicroSetAttribute = microRootElement.prototype.setAttribute;
|
|
6017
6318
|
microRootElement.prototype.setAttribute = function setAttribute(key, value) {
|
|
6018
|
-
if (
|
|
6019
|
-
|
|
6020
|
-
|
|
6319
|
+
if (/^micro-app(-\S+)?/i.test(this.tagName) &&
|
|
6320
|
+
key === 'data' &&
|
|
6321
|
+
this.setAttribute !== microRootElement.prototype.setAttribute) {
|
|
6322
|
+
this.setAttribute(key, value);
|
|
6323
|
+
}
|
|
6324
|
+
else {
|
|
6325
|
+
if (((key === 'src' || key === 'srcset') && /^(img|script|video|audio|source|embed)$/i.test(this.tagName)) ||
|
|
6326
|
+
(key === 'href' && /^(link|image)$/i.test(this.tagName))) {
|
|
6327
|
+
value = CompletionPath(value, url);
|
|
6328
|
+
}
|
|
6329
|
+
rawMicroSetAttribute.call(this, key, value);
|
|
6021
6330
|
}
|
|
6022
|
-
rawMicroSetAttribute.call(this, key, value);
|
|
6023
6331
|
};
|
|
6024
6332
|
const protoAttrList = [
|
|
6025
6333
|
[microAppWindow.HTMLImageElement.prototype, 'src'],
|
|
6026
6334
|
[microAppWindow.HTMLScriptElement.prototype, 'src'],
|
|
6027
6335
|
[microAppWindow.HTMLLinkElement.prototype, 'href'],
|
|
6336
|
+
[microAppWindow.SVGImageElement.prototype, 'href'],
|
|
6028
6337
|
];
|
|
6029
6338
|
/**
|
|
6030
6339
|
* element.setAttribute does not trigger this actions:
|
|
@@ -6101,9 +6410,10 @@ class IframeSandbox {
|
|
|
6101
6410
|
createIframeElement(appName, browserPath) {
|
|
6102
6411
|
this.iframe = pureCreateElement('iframe');
|
|
6103
6412
|
const iframeAttrs = {
|
|
6413
|
+
id: appName,
|
|
6104
6414
|
src: microApp.options.iframeSrc || browserPath,
|
|
6105
6415
|
style: 'display: none',
|
|
6106
|
-
|
|
6416
|
+
'powered-by': 'micro-app',
|
|
6107
6417
|
};
|
|
6108
6418
|
Object.keys(iframeAttrs).forEach((key) => this.iframe.setAttribute(key, iframeAttrs[key]));
|
|
6109
6419
|
// effect action during construct
|
|
@@ -6137,15 +6447,6 @@ class IframeSandbox {
|
|
|
6137
6447
|
* 1. iframe router and browser router are separated, we should update iframe router manually
|
|
6138
6448
|
* 2. withSandbox location is browser location when disable memory-router, so no need to do anything
|
|
6139
6449
|
*/
|
|
6140
|
-
/**
|
|
6141
|
-
* TODO:
|
|
6142
|
-
* 1. iframe关闭虚拟路由系统后,default-page无法使用,推荐用户直接使用浏览器地址控制首页渲染
|
|
6143
|
-
* 补充:keep-router-state 也无法配置,因为keep-router-state一定为true。
|
|
6144
|
-
* 2. 导航拦截、current.route 可以正常使用
|
|
6145
|
-
* 3. 可以正常控制子应用跳转,方式还是自上而下(也可以是子应用内部跳转,这种方式更好一点,减小对基座的影响,不会导致vue的循环刷新)
|
|
6146
|
-
* 4. 关闭虚拟路由以后会对应 route-mode='custom' 模式,包括with沙箱也会这么做
|
|
6147
|
-
* 5. 关闭虚拟路由是指尽可能模拟没有虚拟路由的情况,子应用直接获取浏览器location和history,控制浏览器跳转
|
|
6148
|
-
*/
|
|
6149
6450
|
this.initRouteState(defaultPage);
|
|
6150
6451
|
// unique listener of popstate event for child app
|
|
6151
6452
|
this.removeHistoryListener = addHistoryListener(this.microAppWindow.__MICRO_APP_NAME__);
|
|
@@ -6168,6 +6469,7 @@ class IframeSandbox {
|
|
|
6168
6469
|
}
|
|
6169
6470
|
stop({ umdMode, keepRouteState, destroy, clearData, }) {
|
|
6170
6471
|
var _a;
|
|
6472
|
+
// sandbox.stop may exec before sandbox.start, e.g: iframe sandbox + default mode + remount
|
|
6171
6473
|
if (!this.active)
|
|
6172
6474
|
return;
|
|
6173
6475
|
this.recordAndReleaseEffect({ clearData }, !umdMode || destroy);
|
|
@@ -6183,6 +6485,7 @@ class IframeSandbox {
|
|
|
6183
6485
|
Reflect.deleteProperty(globalEnv.rawWindow, key);
|
|
6184
6486
|
});
|
|
6185
6487
|
this.escapeKeys.clear();
|
|
6488
|
+
this.clearHijackUmdHooks();
|
|
6186
6489
|
}
|
|
6187
6490
|
if (--globalEnv.activeSandbox === 0) {
|
|
6188
6491
|
releasePatchElementAndDocument();
|
|
@@ -6401,10 +6704,49 @@ class IframeSandbox {
|
|
|
6401
6704
|
* action before exec scripts when mount
|
|
6402
6705
|
* Actions:
|
|
6403
6706
|
* 1. patch static elements from html
|
|
6707
|
+
* 2. hijack umd hooks -- mount, unmount, micro-app-appName
|
|
6404
6708
|
* @param container micro app container
|
|
6405
6709
|
*/
|
|
6406
|
-
|
|
6710
|
+
actionsBeforeExecScripts(container, handleUmdHooks) {
|
|
6407
6711
|
this.patchStaticElement(container);
|
|
6712
|
+
this.clearHijackUmdHooks = this.hijackUmdHooks(this.appName, this.microAppWindow, handleUmdHooks);
|
|
6713
|
+
}
|
|
6714
|
+
// hijack mount, unmount, micro-app-appName hook to microAppWindow
|
|
6715
|
+
hijackUmdHooks(appName, microAppWindow, handleUmdHooks) {
|
|
6716
|
+
let mount, unmount, microAppLibrary;
|
|
6717
|
+
rawDefineProperties(microAppWindow, {
|
|
6718
|
+
mount: {
|
|
6719
|
+
configurable: true,
|
|
6720
|
+
get: () => mount,
|
|
6721
|
+
set: (value) => {
|
|
6722
|
+
if (this.active && isFunction(value) && !mount) {
|
|
6723
|
+
handleUmdHooks(mount = value, unmount);
|
|
6724
|
+
}
|
|
6725
|
+
}
|
|
6726
|
+
},
|
|
6727
|
+
unmount: {
|
|
6728
|
+
configurable: true,
|
|
6729
|
+
get: () => unmount,
|
|
6730
|
+
set: (value) => {
|
|
6731
|
+
if (this.active && isFunction(value) && !unmount) {
|
|
6732
|
+
handleUmdHooks(mount, unmount = value);
|
|
6733
|
+
}
|
|
6734
|
+
}
|
|
6735
|
+
},
|
|
6736
|
+
[`micro-app-${appName}`]: {
|
|
6737
|
+
configurable: true,
|
|
6738
|
+
get: () => microAppLibrary,
|
|
6739
|
+
set: (value) => {
|
|
6740
|
+
if (this.active && isPlainObject(value) && !microAppLibrary) {
|
|
6741
|
+
microAppLibrary = value;
|
|
6742
|
+
handleUmdHooks(microAppLibrary.mount, microAppLibrary.unmount);
|
|
6743
|
+
}
|
|
6744
|
+
}
|
|
6745
|
+
}
|
|
6746
|
+
});
|
|
6747
|
+
return () => {
|
|
6748
|
+
mount = unmount = microAppLibrary = null;
|
|
6749
|
+
};
|
|
6408
6750
|
}
|
|
6409
6751
|
setStaticAppState(state) {
|
|
6410
6752
|
this.microAppWindow.__MICRO_APP_STATE__ = state;
|
|
@@ -6421,7 +6763,6 @@ class CreateApp {
|
|
|
6421
6763
|
this.loadSourceLevel = 0;
|
|
6422
6764
|
this.umdHookMount = null;
|
|
6423
6765
|
this.umdHookUnmount = null;
|
|
6424
|
-
this.lifeCycleState = null;
|
|
6425
6766
|
this.umdMode = false;
|
|
6426
6767
|
// TODO: 类型优化,加上iframe沙箱
|
|
6427
6768
|
this.sandBox = null;
|
|
@@ -6466,7 +6807,9 @@ class CreateApp {
|
|
|
6466
6807
|
var _a;
|
|
6467
6808
|
if (++this.loadSourceLevel === 2) {
|
|
6468
6809
|
this.source.html = html;
|
|
6469
|
-
if (
|
|
6810
|
+
if (this.isUnmounted())
|
|
6811
|
+
return;
|
|
6812
|
+
if (!this.isPrefetch) {
|
|
6470
6813
|
getRootContainer(this.container).mount(this);
|
|
6471
6814
|
}
|
|
6472
6815
|
else if (this.isPrerender) {
|
|
@@ -6589,7 +6932,6 @@ class CreateApp {
|
|
|
6589
6932
|
this.fiber = fiber;
|
|
6590
6933
|
this.routerMode = routerMode;
|
|
6591
6934
|
const dispatchBeforeMount = () => {
|
|
6592
|
-
this.setLifeCycleState(lifeCycles.BEFOREMOUNT);
|
|
6593
6935
|
dispatchLifecyclesEvent(this.container, this.name, lifeCycles.BEFOREMOUNT);
|
|
6594
6936
|
};
|
|
6595
6937
|
if (this.isPrerender) {
|
|
@@ -6603,7 +6945,7 @@ class CreateApp {
|
|
|
6603
6945
|
dispatchCustomEventToMicroApp(this, 'statechange', {
|
|
6604
6946
|
appState: appStates.MOUNTING
|
|
6605
6947
|
});
|
|
6606
|
-
// TODO:
|
|
6948
|
+
// TODO: 兼容shadowRoot的场景
|
|
6607
6949
|
this.cloneContainer(this.container, this.source.html, !this.umdMode);
|
|
6608
6950
|
(_e = this.sandBox) === null || _e === void 0 ? void 0 : _e.start({
|
|
6609
6951
|
umdMode: this.umdMode,
|
|
@@ -6612,38 +6954,35 @@ class CreateApp {
|
|
|
6612
6954
|
disablePatchRequest,
|
|
6613
6955
|
});
|
|
6614
6956
|
if (!this.umdMode) {
|
|
6615
|
-
//
|
|
6616
|
-
(_f = this.sandBox) === null || _f === void 0 ? void 0 : _f.
|
|
6617
|
-
|
|
6618
|
-
|
|
6619
|
-
|
|
6620
|
-
|
|
6621
|
-
|
|
6622
|
-
* umdHookUnmount can works in default mode
|
|
6623
|
-
* register through window.unmount
|
|
6624
|
-
*/
|
|
6625
|
-
// TODO: 不对,这里要改,因为unmount不一定是函数
|
|
6626
|
-
this.umdHookUnmount = unmount;
|
|
6957
|
+
// patch element info of html
|
|
6958
|
+
(_f = this.sandBox) === null || _f === void 0 ? void 0 : _f.actionsBeforeExecScripts(this.container, (mount, unmount) => {
|
|
6959
|
+
var _a;
|
|
6960
|
+
if (!this.umdMode && !this.isUnmounted()) {
|
|
6961
|
+
this.umdHookMount = isFunction(mount) ? mount : null;
|
|
6962
|
+
// umdHookUnmount can works in default mode, register by window.unmount
|
|
6963
|
+
this.umdHookUnmount = isFunction(unmount) ? unmount : null;
|
|
6627
6964
|
// if mount & unmount is function, the sub app is umd mode
|
|
6628
|
-
if (isFunction(
|
|
6629
|
-
this.
|
|
6630
|
-
// sandbox must exist
|
|
6631
|
-
this.sandBox.markUmdMode(this.umdMode = true);
|
|
6965
|
+
if (isFunction(this.umdHookMount) && isFunction(this.umdHookUnmount)) {
|
|
6966
|
+
(_a = this.sandBox) === null || _a === void 0 ? void 0 : _a.markUmdMode(this.umdMode = true);
|
|
6632
6967
|
try {
|
|
6633
|
-
this.handleMounted
|
|
6968
|
+
// if appState is mounted, it means that isFinished is true and this.handleMounted has already been executed, just exec this.umdHookMount
|
|
6969
|
+
if (this.getAppState() === appStates.MOUNTED) {
|
|
6970
|
+
this.umdHookMount(microApp.getData(this.name, true));
|
|
6971
|
+
}
|
|
6972
|
+
else {
|
|
6973
|
+
this.handleMounted(this.umdHookMount(microApp.getData(this.name, true)));
|
|
6974
|
+
}
|
|
6634
6975
|
}
|
|
6635
6976
|
catch (e) {
|
|
6636
|
-
|
|
6637
|
-
* TODO:
|
|
6638
|
-
* 1. 是否应该直接抛出错误
|
|
6639
|
-
* 2. 是否应该触发error生命周期
|
|
6640
|
-
*/
|
|
6641
|
-
logError('An error occurred in window.mount \n', this.name, e);
|
|
6977
|
+
logError('An error occurred when mount \n', this.name, e);
|
|
6642
6978
|
}
|
|
6643
6979
|
}
|
|
6644
|
-
|
|
6645
|
-
|
|
6646
|
-
|
|
6980
|
+
}
|
|
6981
|
+
});
|
|
6982
|
+
// if all js are executed, param isFinished will be true
|
|
6983
|
+
execScripts(this, (isFinished) => {
|
|
6984
|
+
if (!this.umdMode && isFinished === true) {
|
|
6985
|
+
this.handleMounted();
|
|
6647
6986
|
}
|
|
6648
6987
|
});
|
|
6649
6988
|
}
|
|
@@ -6653,13 +6992,22 @@ class CreateApp {
|
|
|
6653
6992
|
this.handleMounted(this.umdHookMount(microApp.getData(this.name, true)));
|
|
6654
6993
|
}
|
|
6655
6994
|
catch (e) {
|
|
6656
|
-
logError('An error occurred
|
|
6995
|
+
logError('An error occurred when mount \n', this.name, e);
|
|
6657
6996
|
}
|
|
6658
6997
|
}
|
|
6659
6998
|
}
|
|
6660
6999
|
};
|
|
7000
|
+
/**
|
|
7001
|
+
* Initialization of sandbox is async, especially iframe sandbox are macro tasks
|
|
7002
|
+
* when child apps switch quickly, we need to pay attention to the following points:
|
|
7003
|
+
* NOTE:
|
|
7004
|
+
* 1. unmount app before exec nextAction (especially: iframe sandbox + default mode + remount)
|
|
7005
|
+
* this.container is null, this.sandBox will not start
|
|
7006
|
+
* 2. remount app of note 1
|
|
7007
|
+
* 3. unmount app during exec js
|
|
7008
|
+
*/
|
|
6661
7009
|
// TODO: 可优化?
|
|
6662
|
-
this.sandBox ? this.sandBox.sandboxReady.then(nextAction) : nextAction();
|
|
7010
|
+
this.sandBox ? this.sandBox.sandboxReady.then(() => !this.isUnmounted() && nextAction()) : nextAction();
|
|
6663
7011
|
}
|
|
6664
7012
|
/**
|
|
6665
7013
|
* handle for promise umdHookMount
|
|
@@ -6668,16 +7016,17 @@ class CreateApp {
|
|
|
6668
7016
|
handleMounted(umdHookMountResult) {
|
|
6669
7017
|
var _a, _b;
|
|
6670
7018
|
const dispatchAction = () => {
|
|
7019
|
+
const nextAction = () => this.actionsAfterMounted();
|
|
6671
7020
|
if (isPromise(umdHookMountResult)) {
|
|
6672
7021
|
umdHookMountResult
|
|
6673
|
-
.then(
|
|
7022
|
+
.then(nextAction)
|
|
6674
7023
|
.catch((e) => {
|
|
6675
7024
|
logError('An error occurred in window.mount \n', this.name, e);
|
|
6676
|
-
|
|
7025
|
+
nextAction();
|
|
6677
7026
|
});
|
|
6678
7027
|
}
|
|
6679
7028
|
else {
|
|
6680
|
-
|
|
7029
|
+
nextAction();
|
|
6681
7030
|
}
|
|
6682
7031
|
};
|
|
6683
7032
|
if (this.isPrerender) {
|
|
@@ -6691,7 +7040,7 @@ class CreateApp {
|
|
|
6691
7040
|
/**
|
|
6692
7041
|
* dispatch mounted event when app run finished
|
|
6693
7042
|
*/
|
|
6694
|
-
|
|
7043
|
+
actionsAfterMounted() {
|
|
6695
7044
|
var _a;
|
|
6696
7045
|
if (!this.isUnmounted()) {
|
|
6697
7046
|
this.setAppState(appStates.MOUNTED);
|
|
@@ -6703,7 +7052,6 @@ class CreateApp {
|
|
|
6703
7052
|
});
|
|
6704
7053
|
// dispatch mounted event to micro app
|
|
6705
7054
|
dispatchCustomEventToMicroApp(this, 'mounted');
|
|
6706
|
-
this.setLifeCycleState(lifeCycles.MOUNTED);
|
|
6707
7055
|
// dispatch event mounted to parent
|
|
6708
7056
|
dispatchLifecyclesEvent(this.container, this.name, lifeCycles.MOUNTED);
|
|
6709
7057
|
/**
|
|
@@ -6726,6 +7074,8 @@ class CreateApp {
|
|
|
6726
7074
|
* unmount app
|
|
6727
7075
|
* NOTE:
|
|
6728
7076
|
* 1. do not add any params on account of unmountApp
|
|
7077
|
+
* 2. this.container maybe null: Initialization of sandbox is async, child app may unmount before exec nextAction of mount
|
|
7078
|
+
* 3. unmount app when loading files (this.container is not null)
|
|
6729
7079
|
* @param destroy completely destroy, delete cache resources
|
|
6730
7080
|
* @param clearData clear data of dateCenter
|
|
6731
7081
|
* @param keepRouteState keep route state when unmount, default is false
|
|
@@ -6735,29 +7085,12 @@ class CreateApp {
|
|
|
6735
7085
|
var _a;
|
|
6736
7086
|
destroy = destroy || this.state === appStates.LOAD_FAILED;
|
|
6737
7087
|
this.setAppState(appStates.UNMOUNT);
|
|
6738
|
-
let umdHookUnmountResult = null;
|
|
6739
7088
|
try {
|
|
6740
|
-
|
|
6741
|
-
umdHookUnmountResult = (_a = this.umdHookUnmount) === null || _a === void 0 ? void 0 : _a.call(this, microApp.getData(this.name, true));
|
|
7089
|
+
this.handleUnmounted(destroy, clearData, keepRouteState, unmountcb, (_a = this.umdHookUnmount) === null || _a === void 0 ? void 0 : _a.call(this, microApp.getData(this.name, true)));
|
|
6742
7090
|
}
|
|
6743
7091
|
catch (e) {
|
|
6744
|
-
logError('An error occurred
|
|
7092
|
+
logError('An error occurred when unmount \n', this.name, e);
|
|
6745
7093
|
}
|
|
6746
|
-
// dispatch state event to micro app
|
|
6747
|
-
dispatchCustomEventToMicroApp(this, 'statechange', {
|
|
6748
|
-
appState: appStates.UNMOUNT
|
|
6749
|
-
});
|
|
6750
|
-
// dispatch unmount event to micro app
|
|
6751
|
-
dispatchCustomEventToMicroApp(this, 'unmount');
|
|
6752
|
-
// call window.onunmount of child app
|
|
6753
|
-
execMicroAppGlobalHook(this.getMicroAppGlobalHook(microGlobalEvent.ONUNMOUNT), this.name, microGlobalEvent.ONUNMOUNT);
|
|
6754
|
-
this.handleUnmounted({
|
|
6755
|
-
destroy,
|
|
6756
|
-
clearData,
|
|
6757
|
-
keepRouteState,
|
|
6758
|
-
unmountcb,
|
|
6759
|
-
umdHookUnmountResult,
|
|
6760
|
-
});
|
|
6761
7094
|
}
|
|
6762
7095
|
/**
|
|
6763
7096
|
* handle for promise umdHookUnmount
|
|
@@ -6767,8 +7100,16 @@ class CreateApp {
|
|
|
6767
7100
|
* @param unmountcb callback of unmount
|
|
6768
7101
|
* @param umdHookUnmountResult result of umdHookUnmount
|
|
6769
7102
|
*/
|
|
6770
|
-
handleUnmounted(
|
|
6771
|
-
|
|
7103
|
+
handleUnmounted(destroy, clearData, keepRouteState, unmountcb, umdHookUnmountResult) {
|
|
7104
|
+
// dispatch state event to micro app
|
|
7105
|
+
dispatchCustomEventToMicroApp(this, 'statechange', {
|
|
7106
|
+
appState: appStates.UNMOUNT
|
|
7107
|
+
});
|
|
7108
|
+
// dispatch unmount event to micro app
|
|
7109
|
+
dispatchCustomEventToMicroApp(this, 'unmount');
|
|
7110
|
+
// call window.onunmount of child app
|
|
7111
|
+
execMicroAppGlobalHook(this.getMicroAppGlobalHook(microGlobalEvent.ONUNMOUNT), this.name, microGlobalEvent.ONUNMOUNT);
|
|
7112
|
+
const nextAction = () => this.actionsAfterUnmounted({
|
|
6772
7113
|
destroy,
|
|
6773
7114
|
clearData,
|
|
6774
7115
|
keepRouteState,
|
|
@@ -6777,7 +7118,12 @@ class CreateApp {
|
|
|
6777
7118
|
if (isPromise(umdHookUnmountResult)) {
|
|
6778
7119
|
// async window.unmount will cause appName bind error in nest app
|
|
6779
7120
|
removeDomScope();
|
|
6780
|
-
umdHookUnmountResult
|
|
7121
|
+
umdHookUnmountResult
|
|
7122
|
+
.then(nextAction)
|
|
7123
|
+
.catch((e) => {
|
|
7124
|
+
logError('An error occurred in window.unmount \n', this.name, e);
|
|
7125
|
+
nextAction();
|
|
7126
|
+
});
|
|
6781
7127
|
}
|
|
6782
7128
|
else {
|
|
6783
7129
|
nextAction();
|
|
@@ -6790,7 +7136,7 @@ class CreateApp {
|
|
|
6790
7136
|
* @param keepRouteState keep route state when unmount, default is false
|
|
6791
7137
|
* @param unmountcb callback of unmount
|
|
6792
7138
|
*/
|
|
6793
|
-
|
|
7139
|
+
actionsAfterUnmounted({ destroy, clearData, keepRouteState, unmountcb, }) {
|
|
6794
7140
|
var _a;
|
|
6795
7141
|
if (this.umdMode && this.container && !destroy) {
|
|
6796
7142
|
this.cloneContainer(this.source.html, this.container, false);
|
|
@@ -6807,20 +7153,33 @@ class CreateApp {
|
|
|
6807
7153
|
destroy,
|
|
6808
7154
|
clearData: clearData || destroy,
|
|
6809
7155
|
});
|
|
6810
|
-
this.setLifeCycleState(lifeCycles.UNMOUNT);
|
|
6811
7156
|
// dispatch unmount event to base app
|
|
6812
7157
|
dispatchLifecyclesEvent(this.container, this.name, lifeCycles.UNMOUNT);
|
|
6813
7158
|
this.clearOptions(destroy);
|
|
6814
7159
|
unmountcb === null || unmountcb === void 0 ? void 0 : unmountcb();
|
|
6815
7160
|
}
|
|
6816
7161
|
clearOptions(destroy) {
|
|
6817
|
-
|
|
6818
|
-
this.container = null;
|
|
7162
|
+
var _a, _b;
|
|
6819
7163
|
this.isPrerender = false;
|
|
6820
7164
|
this.preRenderEvents = null;
|
|
6821
7165
|
this.setKeepAliveState(null);
|
|
7166
|
+
if (this.container) {
|
|
7167
|
+
this.container.innerHTML = '';
|
|
7168
|
+
this.container = null;
|
|
7169
|
+
}
|
|
7170
|
+
else if (!this.umdMode) {
|
|
7171
|
+
/**
|
|
7172
|
+
* this.container is null means sandBox.start has not exec, so sandBox.stop won't exec either
|
|
7173
|
+
* we should remove iframeElement in default mode manually
|
|
7174
|
+
*/
|
|
7175
|
+
(_b = (_a = this.sandBox) === null || _a === void 0 ? void 0 : _a.deleteIframeElement) === null || _b === void 0 ? void 0 : _b.call(_a);
|
|
7176
|
+
}
|
|
6822
7177
|
// in iframe sandbox & default mode, delete the sandbox & iframeElement
|
|
6823
|
-
|
|
7178
|
+
/**
|
|
7179
|
+
* TODO:
|
|
7180
|
+
* 1. with沙箱与iframe沙箱保持一致:with沙箱默认模式下删除 或者 iframe沙箱umd模式下保留
|
|
7181
|
+
* 2. 接1.0,this.sandBox置空,还需要注意后续app.sandBox相关操作,比如 scripts.ts --> app.iframe ? app.sandBox!.microBody : app.querySelector('micro-app-body'),如果是fiber或者预加载,会存在卸载后js还在处理的情况
|
|
7182
|
+
*/
|
|
6824
7183
|
if (this.iframe && !this.umdMode)
|
|
6825
7184
|
this.sandBox = null;
|
|
6826
7185
|
if (destroy)
|
|
@@ -6849,7 +7208,6 @@ class CreateApp {
|
|
|
6849
7208
|
dispatchCustomEventToMicroApp(this, 'appstate-change', {
|
|
6850
7209
|
appState: 'afterhidden',
|
|
6851
7210
|
});
|
|
6852
|
-
this.setLifeCycleState(lifeCycles.AFTERHIDDEN);
|
|
6853
7211
|
// dispatch afterHidden event to base app
|
|
6854
7212
|
dispatchLifecyclesEvent(this.container, this.name, lifeCycles.AFTERHIDDEN);
|
|
6855
7213
|
if (isRouterModeSearch(this.name)) {
|
|
@@ -6891,7 +7249,7 @@ class CreateApp {
|
|
|
6891
7249
|
/**
|
|
6892
7250
|
* TODO:
|
|
6893
7251
|
* 问题:当路由模式为custom时,keep-alive应用在重新展示,是否需要根据子应用location信息更新浏览器地址?
|
|
6894
|
-
*
|
|
7252
|
+
* 暂时不这么做,因为无法确定二次展示时新旧地址是否相同,是否带有特殊信息
|
|
6895
7253
|
*/
|
|
6896
7254
|
if (isRouterModeSearch(this.name)) {
|
|
6897
7255
|
// called before lifeCyclesEvent
|
|
@@ -6901,7 +7259,6 @@ class CreateApp {
|
|
|
6901
7259
|
dispatchCustomEventToMicroApp(this, 'appstate-change', {
|
|
6902
7260
|
appState: 'aftershow',
|
|
6903
7261
|
});
|
|
6904
|
-
this.setLifeCycleState(lifeCycles.AFTERSHOW);
|
|
6905
7262
|
// dispatch afterShow event to base app
|
|
6906
7263
|
dispatchLifecyclesEvent(this.container, this.name, lifeCycles.AFTERSHOW);
|
|
6907
7264
|
}
|
|
@@ -6910,7 +7267,6 @@ class CreateApp {
|
|
|
6910
7267
|
* @param e Error
|
|
6911
7268
|
*/
|
|
6912
7269
|
onerror(e) {
|
|
6913
|
-
this.setLifeCycleState(lifeCycles.ERROR);
|
|
6914
7270
|
// dispatch state event to micro app
|
|
6915
7271
|
dispatchCustomEventToMicroApp(this, 'statechange', {
|
|
6916
7272
|
appState: appStates.LOAD_FAILED
|
|
@@ -6931,8 +7287,8 @@ class CreateApp {
|
|
|
6931
7287
|
}
|
|
6932
7288
|
/**
|
|
6933
7289
|
* clone origin elements to target
|
|
6934
|
-
* @param origin Cloned element
|
|
6935
7290
|
* @param target Accept cloned elements
|
|
7291
|
+
* @param origin Cloned element
|
|
6936
7292
|
* @param deep deep clone or transfer dom
|
|
6937
7293
|
*/
|
|
6938
7294
|
cloneContainer(target, origin, deep) {
|
|
@@ -6967,14 +7323,6 @@ class CreateApp {
|
|
|
6967
7323
|
getAppState() {
|
|
6968
7324
|
return this.state;
|
|
6969
7325
|
}
|
|
6970
|
-
// set app lifeCycleState
|
|
6971
|
-
setLifeCycleState(state) {
|
|
6972
|
-
this.lifeCycleState = state;
|
|
6973
|
-
}
|
|
6974
|
-
// get app lifeCycleState
|
|
6975
|
-
getLifeCycleState() {
|
|
6976
|
-
return this.lifeCycleState || '';
|
|
6977
|
-
}
|
|
6978
7326
|
// set keep-alive state
|
|
6979
7327
|
setKeepAliveState(state) {
|
|
6980
7328
|
this.keepAliveState = state;
|
|
@@ -6991,23 +7339,6 @@ class CreateApp {
|
|
|
6991
7339
|
isHidden() {
|
|
6992
7340
|
return keepAliveStates.KEEP_ALIVE_HIDDEN === this.keepAliveState;
|
|
6993
7341
|
}
|
|
6994
|
-
// get umd library, if it not exist, return empty object
|
|
6995
|
-
getUmdLibraryHooks() {
|
|
6996
|
-
// after execScripts, the app maybe unmounted
|
|
6997
|
-
if (!this.isUnmounted() && this.sandBox) {
|
|
6998
|
-
const libraryName = getRootContainer(this.container).getAttribute('library') || `micro-app-${this.name}`;
|
|
6999
|
-
const proxyWindow = this.sandBox.proxyWindow;
|
|
7000
|
-
// compatible with pre versions
|
|
7001
|
-
if (isObject(proxyWindow[libraryName])) {
|
|
7002
|
-
return proxyWindow[libraryName];
|
|
7003
|
-
}
|
|
7004
|
-
return {
|
|
7005
|
-
mount: proxyWindow.mount,
|
|
7006
|
-
unmount: proxyWindow.unmount,
|
|
7007
|
-
};
|
|
7008
|
-
}
|
|
7009
|
-
return {};
|
|
7010
|
-
}
|
|
7011
7342
|
getMicroAppGlobalHook(eventName) {
|
|
7012
7343
|
var _a, _b;
|
|
7013
7344
|
const listener = (_b = (_a = this.sandBox) === null || _a === void 0 ? void 0 : _a.proxyWindow) === null || _b === void 0 ? void 0 : _b[eventName];
|
|
@@ -7113,11 +7444,11 @@ function handleNewNode(child, app) {
|
|
|
7113
7444
|
* @param app app
|
|
7114
7445
|
* @param method raw method
|
|
7115
7446
|
* @param parent parent node
|
|
7116
|
-
* @param
|
|
7117
|
-
* @param
|
|
7447
|
+
* @param targetNode target node
|
|
7448
|
+
* @param passiveNode second param of insertBefore and replaceChild
|
|
7118
7449
|
*/
|
|
7119
|
-
function invokePrototypeMethod(app, rawMethod, parent,
|
|
7120
|
-
const hijackParent = getHijackParent(parent,
|
|
7450
|
+
function invokePrototypeMethod(app, rawMethod, parent, targetNode, passiveNode) {
|
|
7451
|
+
const hijackParent = getHijackParent(parent, targetNode, app);
|
|
7121
7452
|
if (hijackParent) {
|
|
7122
7453
|
/**
|
|
7123
7454
|
* If parentNode is <micro-app-body>, return rawDocument.body
|
|
@@ -7134,9 +7465,9 @@ function invokePrototypeMethod(app, rawMethod, parent, targetChild, passiveChild
|
|
|
7134
7465
|
if (!isIframeSandbox(app.name) &&
|
|
7135
7466
|
isMicroAppBody(hijackParent) &&
|
|
7136
7467
|
rawMethod !== globalEnv.rawRemoveChild) {
|
|
7137
|
-
const descriptor = Object.getOwnPropertyDescriptor(
|
|
7138
|
-
if ((!descriptor || descriptor.configurable) && !
|
|
7139
|
-
rawDefineProperties(
|
|
7468
|
+
const descriptor = Object.getOwnPropertyDescriptor(targetNode, 'parentNode');
|
|
7469
|
+
if ((!descriptor || descriptor.configurable) && !targetNode.__MICRO_APP_HAS_DPN__) {
|
|
7470
|
+
rawDefineProperties(targetNode, {
|
|
7140
7471
|
parentNode: {
|
|
7141
7472
|
configurable: true,
|
|
7142
7473
|
get() {
|
|
@@ -7157,68 +7488,84 @@ function invokePrototypeMethod(app, rawMethod, parent, targetChild, passiveChild
|
|
|
7157
7488
|
}
|
|
7158
7489
|
}
|
|
7159
7490
|
if ((process.env.NODE_ENV !== 'production') &&
|
|
7160
|
-
isIFrameElement(
|
|
7491
|
+
isIFrameElement(targetNode) &&
|
|
7161
7492
|
rawMethod === globalEnv.rawAppendChild) {
|
|
7162
7493
|
fixReactHMRConflict(app);
|
|
7163
7494
|
}
|
|
7164
7495
|
/**
|
|
7165
|
-
* 1. If
|
|
7166
|
-
* 2. When removeChild,
|
|
7496
|
+
* 1. If passiveNode exists, it must be insertBefore or replaceChild
|
|
7497
|
+
* 2. When removeChild, targetNode may not be in microAppHead or head
|
|
7167
7498
|
* NOTE:
|
|
7168
|
-
* 1. If
|
|
7169
|
-
* E.g: document.head.replaceChild(
|
|
7170
|
-
* 2. If
|
|
7171
|
-
* E.g: document.head.insertBefore(
|
|
7499
|
+
* 1. If passiveNode not in hijackParent, insertBefore replaceChild will be degraded to appendChild
|
|
7500
|
+
* E.g: document.head.replaceChild(targetNode, document.scripts[0])
|
|
7501
|
+
* 2. If passiveNode not in hijackParent but in parent and method is insertBefore, try insert it into the position corresponding to hijackParent
|
|
7502
|
+
* E.g: document.head.insertBefore(targetNode, document.head.childNodes[0])
|
|
7172
7503
|
* ISSUE: https://github.com/micro-zoe/micro-app/issues/1071
|
|
7173
7504
|
*/
|
|
7174
|
-
if (
|
|
7175
|
-
if (rawMethod === globalEnv.rawInsertBefore && parent.contains(
|
|
7176
|
-
const indexOfParent = Array.from(parent.childNodes).indexOf(
|
|
7505
|
+
if (passiveNode && !hijackParent.contains(passiveNode)) {
|
|
7506
|
+
if (rawMethod === globalEnv.rawInsertBefore && parent.contains(passiveNode)) {
|
|
7507
|
+
const indexOfParent = Array.from(parent.childNodes).indexOf(passiveNode);
|
|
7177
7508
|
if (hijackParent.childNodes[indexOfParent]) {
|
|
7178
|
-
return invokeRawMethod(rawMethod, hijackParent,
|
|
7509
|
+
return invokeRawMethod(rawMethod, hijackParent, targetNode, hijackParent.childNodes[indexOfParent], app);
|
|
7179
7510
|
}
|
|
7180
7511
|
}
|
|
7181
|
-
return globalEnv.rawAppendChild.call(hijackParent,
|
|
7512
|
+
return globalEnv.rawAppendChild.call(hijackParent, targetNode);
|
|
7182
7513
|
}
|
|
7183
|
-
else if (rawMethod === globalEnv.rawRemoveChild && !hijackParent.contains(
|
|
7184
|
-
if (parent.contains(
|
|
7185
|
-
return rawMethod.call(parent,
|
|
7514
|
+
else if (rawMethod === globalEnv.rawRemoveChild && !hijackParent.contains(targetNode)) {
|
|
7515
|
+
if (parent.contains(targetNode)) {
|
|
7516
|
+
return rawMethod.call(parent, targetNode);
|
|
7186
7517
|
}
|
|
7187
|
-
return
|
|
7518
|
+
return targetNode;
|
|
7188
7519
|
}
|
|
7189
|
-
return invokeRawMethod(rawMethod, hijackParent,
|
|
7520
|
+
return invokeRawMethod(rawMethod, hijackParent, targetNode, passiveNode, app);
|
|
7190
7521
|
}
|
|
7191
|
-
return invokeRawMethod(rawMethod, parent,
|
|
7522
|
+
return invokeRawMethod(rawMethod, parent, targetNode, passiveNode, app);
|
|
7192
7523
|
}
|
|
7193
7524
|
// head/body map to micro-app-head/micro-app-body
|
|
7194
|
-
function getHijackParent(parent,
|
|
7525
|
+
function getHijackParent(parent, targetNode, app) {
|
|
7195
7526
|
if (app) {
|
|
7196
7527
|
if (parent === document.head) {
|
|
7197
|
-
if (app.iframe && isScriptElement(
|
|
7528
|
+
if (app.iframe && isScriptElement(targetNode)) {
|
|
7198
7529
|
return app.sandBox.microHead;
|
|
7199
7530
|
}
|
|
7200
7531
|
return app.querySelector('micro-app-head');
|
|
7201
7532
|
}
|
|
7202
7533
|
if (parent === document.body || parent === document.body.parentNode) {
|
|
7203
|
-
if (app.iframe && isScriptElement(
|
|
7534
|
+
if (app.iframe && isScriptElement(targetNode)) {
|
|
7204
7535
|
return app.sandBox.microBody;
|
|
7205
7536
|
}
|
|
7206
7537
|
return app.querySelector('micro-app-body');
|
|
7207
7538
|
}
|
|
7208
|
-
if (app.iframe && isScriptElement(
|
|
7539
|
+
if (app.iframe && isScriptElement(targetNode)) {
|
|
7209
7540
|
return app.sandBox.microBody;
|
|
7210
7541
|
}
|
|
7211
7542
|
}
|
|
7212
7543
|
return null;
|
|
7213
7544
|
}
|
|
7214
|
-
function invokeRawMethod(rawMethod, parent,
|
|
7545
|
+
function invokeRawMethod(rawMethod, parent, targetNode, passiveNode, app) {
|
|
7215
7546
|
if (isPendMethod(rawMethod)) {
|
|
7216
|
-
|
|
7547
|
+
/**
|
|
7548
|
+
* In iframe sandbox, script will pend to iframe.body, so we should reset rawMethod, because:
|
|
7549
|
+
* Element.prototype.append === DocumentFragment.prototype.append ==> false
|
|
7550
|
+
* Element.prototype.prepend === DocumentFragment.prototype.prepend ==> false
|
|
7551
|
+
*/
|
|
7552
|
+
if ((app === null || app === void 0 ? void 0 : app.iframe) && isScriptElement(targetNode)) {
|
|
7553
|
+
if (rawMethod === globalEnv.rawFragmentAppend) {
|
|
7554
|
+
rawMethod = globalEnv.rawAppend;
|
|
7555
|
+
}
|
|
7556
|
+
else if (rawMethod === globalEnv.rawFragmentPrepend) {
|
|
7557
|
+
rawMethod = globalEnv.rawPrepend;
|
|
7558
|
+
}
|
|
7559
|
+
}
|
|
7560
|
+
return rawMethod.call(parent, targetNode);
|
|
7217
7561
|
}
|
|
7218
|
-
return rawMethod.call(parent,
|
|
7562
|
+
return rawMethod.call(parent, targetNode, passiveNode);
|
|
7219
7563
|
}
|
|
7220
7564
|
function isPendMethod(method) {
|
|
7221
|
-
return method === globalEnv.rawAppend ||
|
|
7565
|
+
return (method === globalEnv.rawAppend ||
|
|
7566
|
+
method === globalEnv.rawPrepend ||
|
|
7567
|
+
method === globalEnv.rawFragmentAppend ||
|
|
7568
|
+
method === globalEnv.rawFragmentPrepend);
|
|
7222
7569
|
}
|
|
7223
7570
|
/**
|
|
7224
7571
|
* Attempt to complete the static resource address again before insert the node
|
|
@@ -7235,7 +7582,7 @@ function completePathDynamic(app, newChild) {
|
|
|
7235
7582
|
globalEnv.rawSetAttribute.call(newChild, 'srcset', CompletionPath(newChild.getAttribute('srcset'), app.url));
|
|
7236
7583
|
}
|
|
7237
7584
|
}
|
|
7238
|
-
else if (/^link$/i.test(newChild.tagName) && newChild.hasAttribute('href')) {
|
|
7585
|
+
else if (/^(link|image)$/i.test(newChild.tagName) && newChild.hasAttribute('href')) {
|
|
7239
7586
|
globalEnv.rawSetAttribute.call(newChild, 'href', CompletionPath(newChild.getAttribute('href'), app.url));
|
|
7240
7587
|
}
|
|
7241
7588
|
}
|
|
@@ -7244,31 +7591,26 @@ function completePathDynamic(app, newChild) {
|
|
|
7244
7591
|
* method of handle new node
|
|
7245
7592
|
* @param parent parent node
|
|
7246
7593
|
* @param newChild new node
|
|
7247
|
-
* @param
|
|
7594
|
+
* @param passiveNode passive node
|
|
7248
7595
|
* @param rawMethod method
|
|
7249
7596
|
*/
|
|
7250
|
-
function commonElementHandler(parent, newChild,
|
|
7597
|
+
function commonElementHandler(parent, newChild, passiveNode, rawMethod) {
|
|
7251
7598
|
const currentAppName = getCurrentAppName();
|
|
7252
7599
|
if (isNode(newChild) &&
|
|
7253
7600
|
!newChild.__PURE_ELEMENT__ &&
|
|
7254
7601
|
(newChild.__MICRO_APP_NAME__ ||
|
|
7255
7602
|
currentAppName)) {
|
|
7256
|
-
newChild
|
|
7603
|
+
updateElementInfo(newChild, newChild.__MICRO_APP_NAME__ || currentAppName);
|
|
7257
7604
|
const app = appInstanceMap.get(newChild.__MICRO_APP_NAME__);
|
|
7258
|
-
if (isStyleElement(newChild)) {
|
|
7259
|
-
const isShadowNode = parent.getRootNode();
|
|
7260
|
-
const isShadowEnvironment = isShadowNode instanceof ShadowRoot;
|
|
7261
|
-
isShadowEnvironment && newChild.setAttribute('ignore', 'true');
|
|
7262
|
-
}
|
|
7263
7605
|
if (app === null || app === void 0 ? void 0 : app.container) {
|
|
7606
|
+
if (isStyleElement(newChild)) {
|
|
7607
|
+
parent.getRootNode() instanceof ShadowRoot && newChild.setAttribute('ignore', 'true');
|
|
7608
|
+
}
|
|
7264
7609
|
completePathDynamic(app, newChild);
|
|
7265
|
-
return invokePrototypeMethod(app, rawMethod, parent, handleNewNode(newChild, app),
|
|
7610
|
+
return invokePrototypeMethod(app, rawMethod, parent, handleNewNode(newChild, app), passiveNode && getMappingNode(passiveNode));
|
|
7266
7611
|
}
|
|
7267
7612
|
}
|
|
7268
|
-
|
|
7269
|
-
return rawMethod.call(parent, newChild);
|
|
7270
|
-
}
|
|
7271
|
-
return rawMethod.call(parent, newChild, passiveChild);
|
|
7613
|
+
return invokeRawMethod(rawMethod, parent, newChild, passiveNode);
|
|
7272
7614
|
}
|
|
7273
7615
|
/**
|
|
7274
7616
|
* Rewrite element prototype method
|
|
@@ -7277,36 +7619,19 @@ function patchElementAndDocument() {
|
|
|
7277
7619
|
patchDocument$2();
|
|
7278
7620
|
const rawRootElement = globalEnv.rawRootElement;
|
|
7279
7621
|
const rawRootNode = globalEnv.rawRootNode;
|
|
7622
|
+
const rawDocumentFragment = globalEnv.rawDocumentFragment;
|
|
7280
7623
|
// prototype methods of add element👇
|
|
7281
|
-
|
|
7624
|
+
rawRootNode.prototype.appendChild = function appendChild(newChild) {
|
|
7282
7625
|
return commonElementHandler(this, newChild, null, globalEnv.rawAppendChild);
|
|
7283
7626
|
};
|
|
7284
|
-
|
|
7627
|
+
rawRootNode.prototype.insertBefore = function insertBefore(newChild, refChild) {
|
|
7285
7628
|
return commonElementHandler(this, newChild, refChild, globalEnv.rawInsertBefore);
|
|
7286
7629
|
};
|
|
7287
|
-
|
|
7630
|
+
rawRootNode.prototype.replaceChild = function replaceChild(newChild, oldChild) {
|
|
7288
7631
|
return commonElementHandler(this, newChild, oldChild, globalEnv.rawReplaceChild);
|
|
7289
7632
|
};
|
|
7290
|
-
rawRootElement.prototype.append = function append(...nodes) {
|
|
7291
|
-
let i = 0;
|
|
7292
|
-
while (i < nodes.length) {
|
|
7293
|
-
let node = nodes[i];
|
|
7294
|
-
node = isNode(node) ? node : globalEnv.rawCreateTextNode.call(globalEnv.rawDocument, node);
|
|
7295
|
-
commonElementHandler(this, markElement(node), null, globalEnv.rawAppend);
|
|
7296
|
-
i++;
|
|
7297
|
-
}
|
|
7298
|
-
};
|
|
7299
|
-
rawRootElement.prototype.prepend = function prepend(...nodes) {
|
|
7300
|
-
let i = nodes.length;
|
|
7301
|
-
while (i > 0) {
|
|
7302
|
-
let node = nodes[i - 1];
|
|
7303
|
-
node = isNode(node) ? node : globalEnv.rawCreateTextNode.call(globalEnv.rawDocument, node);
|
|
7304
|
-
commonElementHandler(this, markElement(node), null, globalEnv.rawPrepend);
|
|
7305
|
-
i--;
|
|
7306
|
-
}
|
|
7307
|
-
};
|
|
7308
7633
|
// prototype methods of delete element👇
|
|
7309
|
-
|
|
7634
|
+
rawRootNode.prototype.removeChild = function removeChild(oldChild) {
|
|
7310
7635
|
if (oldChild === null || oldChild === void 0 ? void 0 : oldChild.__MICRO_APP_NAME__) {
|
|
7311
7636
|
const app = appInstanceMap.get(oldChild.__MICRO_APP_NAME__);
|
|
7312
7637
|
if (app === null || app === void 0 ? void 0 : app.container) {
|
|
@@ -7321,6 +7646,24 @@ function patchElementAndDocument() {
|
|
|
7321
7646
|
}
|
|
7322
7647
|
return globalEnv.rawRemoveChild.call(this, oldChild);
|
|
7323
7648
|
};
|
|
7649
|
+
rawDocumentFragment.prototype.append = rawRootElement.prototype.append = function append(...nodes) {
|
|
7650
|
+
let i = 0;
|
|
7651
|
+
while (i < nodes.length) {
|
|
7652
|
+
let node = nodes[i];
|
|
7653
|
+
node = isNode(node) ? node : globalEnv.rawCreateTextNode.call(globalEnv.rawDocument, node);
|
|
7654
|
+
commonElementHandler(this, markElement(node), null, isDocumentFragment(this) ? globalEnv.rawFragmentAppend : globalEnv.rawAppend);
|
|
7655
|
+
i++;
|
|
7656
|
+
}
|
|
7657
|
+
};
|
|
7658
|
+
rawDocumentFragment.prototype.prepend = rawRootElement.prototype.prepend = function prepend(...nodes) {
|
|
7659
|
+
let i = nodes.length;
|
|
7660
|
+
while (i > 0) {
|
|
7661
|
+
let node = nodes[i - 1];
|
|
7662
|
+
node = isNode(node) ? node : globalEnv.rawCreateTextNode.call(globalEnv.rawDocument, node);
|
|
7663
|
+
commonElementHandler(this, markElement(node), null, isDocumentFragment(this) ? globalEnv.rawFragmentPrepend : globalEnv.rawPrepend);
|
|
7664
|
+
i--;
|
|
7665
|
+
}
|
|
7666
|
+
};
|
|
7324
7667
|
/**
|
|
7325
7668
|
* The insertAdjacentElement method of the Element interface inserts a given element node at a given position relative to the element it is invoked upon.
|
|
7326
7669
|
* NOTE:
|
|
@@ -7340,52 +7683,81 @@ function patchElementAndDocument() {
|
|
|
7340
7683
|
}
|
|
7341
7684
|
return globalEnv.rawInsertAdjacentElement.call(this, where, element);
|
|
7342
7685
|
};
|
|
7343
|
-
// patch cloneNode
|
|
7344
|
-
rawRootElement.prototype.cloneNode = function cloneNode(deep) {
|
|
7345
|
-
const clonedNode = globalEnv.rawCloneNode.call(this, deep);
|
|
7346
|
-
this.__MICRO_APP_NAME__ && (clonedNode.__MICRO_APP_NAME__ = this.__MICRO_APP_NAME__);
|
|
7347
|
-
return clonedNode;
|
|
7348
|
-
};
|
|
7349
7686
|
/**
|
|
7350
7687
|
* document.body(head).querySelector(querySelectorAll) hijack to microAppBody(microAppHead).querySelector(querySelectorAll)
|
|
7351
7688
|
* NOTE:
|
|
7352
7689
|
* 1. May cause some problems!
|
|
7353
7690
|
* 2. Add config options?
|
|
7354
7691
|
*/
|
|
7355
|
-
function
|
|
7356
|
-
const currentAppName = getCurrentAppName();
|
|
7357
|
-
if ((
|
|
7692
|
+
function getElementQueryTarget(targetNode) {
|
|
7693
|
+
const currentAppName = getIframeCurrentAppName() || getCurrentAppName();
|
|
7694
|
+
if ((targetNode === document.body || targetNode === document.head) && currentAppName) {
|
|
7358
7695
|
const app = appInstanceMap.get(currentAppName);
|
|
7359
7696
|
if (app === null || app === void 0 ? void 0 : app.container) {
|
|
7360
|
-
if (
|
|
7697
|
+
if (targetNode === document.body) {
|
|
7361
7698
|
return app.querySelector('micro-app-body');
|
|
7362
7699
|
}
|
|
7363
|
-
else if (
|
|
7700
|
+
else if (targetNode === document.head) {
|
|
7364
7701
|
return app.querySelector('micro-app-head');
|
|
7365
7702
|
}
|
|
7366
7703
|
}
|
|
7367
7704
|
}
|
|
7368
|
-
return
|
|
7705
|
+
return targetNode;
|
|
7706
|
+
}
|
|
7707
|
+
/**
|
|
7708
|
+
* In iframe sandbox, script will render to iframe instead of micro-app-body
|
|
7709
|
+
* So when query elements, we need to search both micro-app and iframe
|
|
7710
|
+
* @param isEmpty get empty result
|
|
7711
|
+
* @param targetNode targetNode element
|
|
7712
|
+
* @param result origin result
|
|
7713
|
+
* @param selectors selectors
|
|
7714
|
+
* @param methodName querySelector or querySelectorAll
|
|
7715
|
+
*/
|
|
7716
|
+
function getElementQueryResult(isEmpty, targetNode, result, selectors, methodName) {
|
|
7717
|
+
if (isEmpty) {
|
|
7718
|
+
const currentAppName = getIframeCurrentAppName() || getCurrentAppName();
|
|
7719
|
+
if (currentAppName && isIframeSandbox(currentAppName)) {
|
|
7720
|
+
const app = appInstanceMap.get(currentAppName);
|
|
7721
|
+
if (isMicroAppHead(targetNode)) {
|
|
7722
|
+
return app.sandBox.microHead[methodName](selectors);
|
|
7723
|
+
}
|
|
7724
|
+
if (isMicroAppBody(targetNode)) {
|
|
7725
|
+
return app.sandBox.microBody[methodName](selectors);
|
|
7726
|
+
}
|
|
7727
|
+
}
|
|
7728
|
+
}
|
|
7729
|
+
return result;
|
|
7369
7730
|
}
|
|
7370
7731
|
rawRootElement.prototype.querySelector = function querySelector(selectors) {
|
|
7371
7732
|
var _a;
|
|
7372
|
-
|
|
7733
|
+
const _this = (_a = getElementQueryTarget(this)) !== null && _a !== void 0 ? _a : this;
|
|
7734
|
+
const result = globalEnv.rawElementQuerySelector.call(_this, selectors);
|
|
7735
|
+
return getElementQueryResult(isNull(result) && _this !== this, _this, result, selectors, 'querySelector');
|
|
7373
7736
|
};
|
|
7374
7737
|
rawRootElement.prototype.querySelectorAll = function querySelectorAll(selectors) {
|
|
7375
7738
|
var _a;
|
|
7376
|
-
|
|
7739
|
+
const _this = (_a = getElementQueryTarget(this)) !== null && _a !== void 0 ? _a : this;
|
|
7740
|
+
const result = globalEnv.rawElementQuerySelectorAll.call(_this, selectors);
|
|
7741
|
+
return getElementQueryResult(!result.length && _this !== this, _this, result, selectors, 'querySelectorAll');
|
|
7377
7742
|
};
|
|
7378
7743
|
// rewrite setAttribute, complete resource address
|
|
7379
7744
|
rawRootElement.prototype.setAttribute = function setAttribute(key, value) {
|
|
7380
|
-
|
|
7381
|
-
|
|
7382
|
-
|
|
7383
|
-
(
|
|
7384
|
-
|
|
7385
|
-
|
|
7386
|
-
|
|
7745
|
+
if (/^micro-app(-\S+)?/i.test(this.tagName) &&
|
|
7746
|
+
key === 'data' &&
|
|
7747
|
+
this.setAttribute !== rawRootElement.prototype.setAttribute) {
|
|
7748
|
+
this.setAttribute(key, value);
|
|
7749
|
+
}
|
|
7750
|
+
else {
|
|
7751
|
+
const appName = this.__MICRO_APP_NAME__ || getCurrentAppName();
|
|
7752
|
+
if (appName &&
|
|
7753
|
+
appInstanceMap.has(appName) &&
|
|
7754
|
+
(((key === 'src' || key === 'srcset') && /^(img|script|video|audio|source|embed)$/i.test(this.tagName)) ||
|
|
7755
|
+
(key === 'href' && /^(link|image)$/i.test(this.tagName)))) {
|
|
7756
|
+
const app = appInstanceMap.get(appName);
|
|
7757
|
+
value = CompletionPath(value, app.url);
|
|
7758
|
+
}
|
|
7759
|
+
globalEnv.rawSetAttribute.call(this, key, value);
|
|
7387
7760
|
}
|
|
7388
|
-
globalEnv.rawSetAttribute.call(this, key, value);
|
|
7389
7761
|
};
|
|
7390
7762
|
/**
|
|
7391
7763
|
* TODO: 兼容直接通过img.src等操作设置的资源
|
|
@@ -7412,7 +7784,7 @@ function patchElementAndDocument() {
|
|
|
7412
7784
|
// return get?.call(this)
|
|
7413
7785
|
// },
|
|
7414
7786
|
// set: function (value) {
|
|
7415
|
-
// const currentAppName = getCurrentAppName()
|
|
7787
|
+
// const currentAppName = this.__MICRO_APP_NAME__ || getCurrentAppName()
|
|
7416
7788
|
// if (currentAppName && appInstanceMap.has(currentAppName)) {
|
|
7417
7789
|
// const app = appInstanceMap.get(currentAppName)
|
|
7418
7790
|
// value = CompletionPath(value, app!.url)
|
|
@@ -7421,41 +7793,25 @@ function patchElementAndDocument() {
|
|
|
7421
7793
|
// },
|
|
7422
7794
|
// })
|
|
7423
7795
|
// })
|
|
7424
|
-
rawDefineProperty(rawRootElement.prototype, 'innerHTML', {
|
|
7425
|
-
configurable: true,
|
|
7426
|
-
enumerable: true,
|
|
7427
|
-
get() {
|
|
7428
|
-
return globalEnv.rawInnerHTMLDesc.get.call(this);
|
|
7429
|
-
},
|
|
7430
|
-
set(code) {
|
|
7431
|
-
globalEnv.rawInnerHTMLDesc.set.call(this, code);
|
|
7432
|
-
const currentAppName = getCurrentAppName();
|
|
7433
|
-
Array.from(this.children).forEach((child) => {
|
|
7434
|
-
if (isElement(child) && currentAppName) {
|
|
7435
|
-
// TODO: 使用updateElementInfo进行更新
|
|
7436
|
-
child.__MICRO_APP_NAME__ = currentAppName;
|
|
7437
|
-
}
|
|
7438
|
-
});
|
|
7439
|
-
}
|
|
7440
|
-
});
|
|
7441
7796
|
rawDefineProperty(rawRootNode.prototype, 'parentNode', {
|
|
7442
7797
|
configurable: true,
|
|
7443
7798
|
enumerable: true,
|
|
7444
7799
|
get() {
|
|
7445
7800
|
var _a, _b, _c;
|
|
7446
7801
|
/**
|
|
7447
|
-
* hijack parentNode of html
|
|
7802
|
+
* hijack parentNode of html for with sandbox
|
|
7448
7803
|
* Scenes:
|
|
7449
7804
|
* 1. element-ui@2/lib/utils/popper.js
|
|
7450
7805
|
* // root is child app window, so root.document is proxyDocument or microDocument
|
|
7451
7806
|
* if (element.parentNode === root.document) ...
|
|
7452
7807
|
*/
|
|
7453
|
-
const currentAppName = getCurrentAppName();
|
|
7808
|
+
const currentAppName = getIframeCurrentAppName() || getCurrentAppName();
|
|
7454
7809
|
if (currentAppName && this === globalEnv.rawDocument.firstElementChild) {
|
|
7455
7810
|
const microDocument = (_c = (_b = (_a = appInstanceMap.get(currentAppName)) === null || _a === void 0 ? void 0 : _a.sandBox) === null || _b === void 0 ? void 0 : _b.proxyWindow) === null || _c === void 0 ? void 0 : _c.document;
|
|
7456
7811
|
if (microDocument)
|
|
7457
7812
|
return microDocument;
|
|
7458
7813
|
}
|
|
7814
|
+
// NOTE: run after hijack html.parentNode
|
|
7459
7815
|
const result = globalEnv.rawParentNodeDesc.get.call(this);
|
|
7460
7816
|
/**
|
|
7461
7817
|
* If parentNode is <micro-app-body>, return rawDocument.body
|
|
@@ -7474,16 +7830,34 @@ function patchElementAndDocument() {
|
|
|
7474
7830
|
return result;
|
|
7475
7831
|
},
|
|
7476
7832
|
});
|
|
7833
|
+
rawDefineProperty(rawRootElement.prototype, 'innerHTML', {
|
|
7834
|
+
configurable: true,
|
|
7835
|
+
enumerable: true,
|
|
7836
|
+
get() {
|
|
7837
|
+
return globalEnv.rawInnerHTMLDesc.get.call(this);
|
|
7838
|
+
},
|
|
7839
|
+
set(code) {
|
|
7840
|
+
globalEnv.rawInnerHTMLDesc.set.call(this, code);
|
|
7841
|
+
const currentAppName = this.__MICRO_APP_NAME__ || getCurrentAppName();
|
|
7842
|
+
Array.from(this.children).forEach((child) => {
|
|
7843
|
+
if (isElement(child) && currentAppName) {
|
|
7844
|
+
updateElementInfo(child, currentAppName);
|
|
7845
|
+
}
|
|
7846
|
+
});
|
|
7847
|
+
}
|
|
7848
|
+
});
|
|
7849
|
+
// patch cloneNode
|
|
7850
|
+
rawRootNode.prototype.cloneNode = function cloneNode(deep) {
|
|
7851
|
+
const clonedNode = globalEnv.rawCloneNode.call(this, deep);
|
|
7852
|
+
return updateElementInfo(clonedNode, this.__MICRO_APP_NAME__);
|
|
7853
|
+
};
|
|
7477
7854
|
}
|
|
7478
7855
|
/**
|
|
7479
7856
|
* Mark the newly created element in the micro application
|
|
7480
7857
|
* @param element new element
|
|
7481
7858
|
*/
|
|
7482
7859
|
function markElement(element) {
|
|
7483
|
-
|
|
7484
|
-
if (currentAppName)
|
|
7485
|
-
element.__MICRO_APP_NAME__ = currentAppName;
|
|
7486
|
-
return element;
|
|
7860
|
+
return updateElementInfo(element, getCurrentAppName());
|
|
7487
7861
|
}
|
|
7488
7862
|
// methods of document
|
|
7489
7863
|
function patchDocument$2() {
|
|
@@ -7614,18 +7988,18 @@ function releasePatchElementAndDocument() {
|
|
|
7614
7988
|
releasePatchDocument();
|
|
7615
7989
|
const rawRootElement = globalEnv.rawRootElement;
|
|
7616
7990
|
const rawRootNode = globalEnv.rawRootNode;
|
|
7617
|
-
|
|
7618
|
-
|
|
7619
|
-
|
|
7620
|
-
|
|
7991
|
+
rawRootNode.prototype.appendChild = globalEnv.rawAppendChild;
|
|
7992
|
+
rawRootNode.prototype.insertBefore = globalEnv.rawInsertBefore;
|
|
7993
|
+
rawRootNode.prototype.replaceChild = globalEnv.rawReplaceChild;
|
|
7994
|
+
rawRootNode.prototype.removeChild = globalEnv.rawRemoveChild;
|
|
7995
|
+
rawRootNode.prototype.cloneNode = globalEnv.rawCloneNode;
|
|
7621
7996
|
rawRootElement.prototype.append = globalEnv.rawAppend;
|
|
7622
7997
|
rawRootElement.prototype.prepend = globalEnv.rawPrepend;
|
|
7623
|
-
rawRootElement.prototype.cloneNode = globalEnv.rawCloneNode;
|
|
7624
7998
|
rawRootElement.prototype.querySelector = globalEnv.rawElementQuerySelector;
|
|
7625
7999
|
rawRootElement.prototype.querySelectorAll = globalEnv.rawElementQuerySelectorAll;
|
|
7626
8000
|
rawRootElement.prototype.setAttribute = globalEnv.rawSetAttribute;
|
|
7627
|
-
rawDefineProperty(rawRootElement.prototype, 'innerHTML', globalEnv.rawInnerHTMLDesc);
|
|
7628
8001
|
rawDefineProperty(rawRootNode.prototype, 'parentNode', globalEnv.rawParentNodeDesc);
|
|
8002
|
+
rawDefineProperty(rawRootElement.prototype, 'innerHTML', globalEnv.rawInnerHTMLDesc);
|
|
7629
8003
|
}
|
|
7630
8004
|
// Set the style of micro-app-head and micro-app-body
|
|
7631
8005
|
let hasRejectMicroAppStyle = false;
|
|
@@ -7655,15 +8029,18 @@ function initGlobalEnv() {
|
|
|
7655
8029
|
const rawRootElement = rawWindow.Element;
|
|
7656
8030
|
const rawRootNode = rawWindow.Node;
|
|
7657
8031
|
const rawRootEventTarget = rawWindow.EventTarget;
|
|
8032
|
+
const rawDocumentFragment = rawWindow.DocumentFragment;
|
|
7658
8033
|
// save patch raw methods, pay attention to this binding
|
|
8034
|
+
const rawAppendChild = rawRootNode.prototype.appendChild;
|
|
8035
|
+
const rawInsertBefore = rawRootNode.prototype.insertBefore;
|
|
8036
|
+
const rawReplaceChild = rawRootNode.prototype.replaceChild;
|
|
8037
|
+
const rawRemoveChild = rawRootNode.prototype.removeChild;
|
|
7659
8038
|
const rawSetAttribute = rawRootElement.prototype.setAttribute;
|
|
7660
|
-
const rawAppendChild = rawRootElement.prototype.appendChild;
|
|
7661
|
-
const rawInsertBefore = rawRootElement.prototype.insertBefore;
|
|
7662
|
-
const rawReplaceChild = rawRootElement.prototype.replaceChild;
|
|
7663
|
-
const rawRemoveChild = rawRootElement.prototype.removeChild;
|
|
7664
8039
|
const rawAppend = rawRootElement.prototype.append;
|
|
7665
8040
|
const rawPrepend = rawRootElement.prototype.prepend;
|
|
7666
|
-
const
|
|
8041
|
+
const rawFragmentAppend = rawDocumentFragment.prototype.append;
|
|
8042
|
+
const rawFragmentPrepend = rawDocumentFragment.prototype.prepend;
|
|
8043
|
+
const rawCloneNode = rawRootNode.prototype.cloneNode;
|
|
7667
8044
|
const rawElementQuerySelector = rawRootElement.prototype.querySelector;
|
|
7668
8045
|
const rawElementQuerySelectorAll = rawRootElement.prototype.querySelectorAll;
|
|
7669
8046
|
const rawInsertAdjacentElement = rawRootElement.prototype.insertAdjacentElement;
|
|
@@ -7681,13 +8058,10 @@ function initGlobalEnv() {
|
|
|
7681
8058
|
const rawGetElementsByClassName = rawRootDocument.prototype.getElementsByClassName;
|
|
7682
8059
|
const rawGetElementsByTagName = rawRootDocument.prototype.getElementsByTagName;
|
|
7683
8060
|
const rawGetElementsByName = rawRootDocument.prototype.getElementsByName;
|
|
7684
|
-
|
|
8061
|
+
// TODO: 将ImageProxy移出去
|
|
8062
|
+
const ImageProxy = new Proxy(rawWindow.Image, {
|
|
7685
8063
|
construct(Target, args) {
|
|
7686
|
-
|
|
7687
|
-
const currentAppName = getCurrentAppName();
|
|
7688
|
-
if (currentAppName)
|
|
7689
|
-
elementImage.__MICRO_APP_NAME__ = currentAppName;
|
|
7690
|
-
return elementImage;
|
|
8064
|
+
return updateElementInfo(new Target(...args), getCurrentAppName());
|
|
7691
8065
|
},
|
|
7692
8066
|
});
|
|
7693
8067
|
/**
|
|
@@ -7713,6 +8087,7 @@ function initGlobalEnv() {
|
|
|
7713
8087
|
rawRootDocument,
|
|
7714
8088
|
rawRootElement,
|
|
7715
8089
|
rawRootNode,
|
|
8090
|
+
rawDocumentFragment,
|
|
7716
8091
|
// source/patch
|
|
7717
8092
|
rawSetAttribute,
|
|
7718
8093
|
rawAppendChild,
|
|
@@ -7721,6 +8096,8 @@ function initGlobalEnv() {
|
|
|
7721
8096
|
rawRemoveChild,
|
|
7722
8097
|
rawAppend,
|
|
7723
8098
|
rawPrepend,
|
|
8099
|
+
rawFragmentAppend,
|
|
8100
|
+
rawFragmentPrepend,
|
|
7724
8101
|
rawCloneNode,
|
|
7725
8102
|
rawElementQuerySelector,
|
|
7726
8103
|
rawElementQuerySelectorAll,
|
|
@@ -7760,7 +8137,7 @@ function initGlobalEnv() {
|
|
|
7760
8137
|
* @param tagName element name
|
|
7761
8138
|
*/
|
|
7762
8139
|
function defineElement(tagName) {
|
|
7763
|
-
class MicroAppElement extends
|
|
8140
|
+
class MicroAppElement extends HTMLElement {
|
|
7764
8141
|
constructor() {
|
|
7765
8142
|
super(...arguments);
|
|
7766
8143
|
this.isWaiting = false;
|
|
@@ -7825,6 +8202,13 @@ function defineElement(tagName) {
|
|
|
7825
8202
|
// baseRoute: route prefix, default is ''
|
|
7826
8203
|
// keep-alive: open keep-alive mode
|
|
7827
8204
|
connectedCallback() {
|
|
8205
|
+
/**
|
|
8206
|
+
* In FireFox, iframe Node.prototype will point to native Node.prototype after insert to document
|
|
8207
|
+
* If <micro-app>.prototype is not MicroAppElement.prototype, we should reset it
|
|
8208
|
+
*/
|
|
8209
|
+
if (Object.getPrototypeOf(this) !== MicroAppElement.prototype) {
|
|
8210
|
+
Object.setPrototypeOf(this, MicroAppElement.prototype);
|
|
8211
|
+
}
|
|
7828
8212
|
const cacheCount = ++this.connectedCount;
|
|
7829
8213
|
this.connectStateMap.set(cacheCount, true);
|
|
7830
8214
|
/**
|
|
@@ -8263,6 +8647,17 @@ function defineElement(tagName) {
|
|
|
8263
8647
|
globalEnv.rawSetAttribute.call(this, key, value);
|
|
8264
8648
|
}
|
|
8265
8649
|
}
|
|
8650
|
+
/**
|
|
8651
|
+
* get delay time of router event
|
|
8652
|
+
* @returns delay time
|
|
8653
|
+
*/
|
|
8654
|
+
getRouterEventDelay() {
|
|
8655
|
+
let delay = parseInt(this.getAttribute('router-event-delay'));
|
|
8656
|
+
if (isNaN(delay)) {
|
|
8657
|
+
delay = parseInt((isFunction(microApp.options['router-event-delay']) ? microApp.options['router-event-delay'](this.appName) : microApp.options['router-event-delay']));
|
|
8658
|
+
}
|
|
8659
|
+
return !isNaN(delay) ? delay : 0;
|
|
8660
|
+
}
|
|
8266
8661
|
/**
|
|
8267
8662
|
* Data from the base application
|
|
8268
8663
|
*/
|
|
@@ -8299,7 +8694,7 @@ function defineElement(tagName) {
|
|
|
8299
8694
|
return this.getBaseRouteCompatible();
|
|
8300
8695
|
}
|
|
8301
8696
|
}
|
|
8302
|
-
|
|
8697
|
+
window.customElements.define(tagName, MicroAppElement);
|
|
8303
8698
|
}
|
|
8304
8699
|
|
|
8305
8700
|
/**
|
|
@@ -8331,7 +8726,7 @@ function preFetch(apps, delay) {
|
|
|
8331
8726
|
const delayTime = isNumber(delay) ? delay : microApp.options.prefetchDelay;
|
|
8332
8727
|
/**
|
|
8333
8728
|
* TODO: remove setTimeout
|
|
8334
|
-
*
|
|
8729
|
+
* 如果要保留setTimeout,则需要考虑清空定时器的情况
|
|
8335
8730
|
*/
|
|
8336
8731
|
setTimeout(() => {
|
|
8337
8732
|
// releasePrefetchEffect()
|
|
@@ -8566,7 +8961,7 @@ function unmountApp(appName, options) {
|
|
|
8566
8961
|
}
|
|
8567
8962
|
}
|
|
8568
8963
|
else {
|
|
8569
|
-
logWarn(`app ${appName} does not exist`);
|
|
8964
|
+
logWarn(`app ${appName} does not exist when unmountApp`);
|
|
8570
8965
|
resolve(false);
|
|
8571
8966
|
}
|
|
8572
8967
|
});
|
|
@@ -8596,7 +8991,7 @@ function reload(appName, destroy) {
|
|
|
8596
8991
|
}
|
|
8597
8992
|
}
|
|
8598
8993
|
else {
|
|
8599
|
-
logWarn(`app ${appName} does not exist`);
|
|
8994
|
+
logWarn(`app ${appName} does not exist when reload app`);
|
|
8600
8995
|
resolve(false);
|
|
8601
8996
|
}
|
|
8602
8997
|
});
|
|
@@ -8651,20 +9046,6 @@ function renderApp(options) {
|
|
|
8651
9046
|
container.appendChild(microAppElement);
|
|
8652
9047
|
});
|
|
8653
9048
|
}
|
|
8654
|
-
/**
|
|
8655
|
-
* get app state
|
|
8656
|
-
* @param appName app.name
|
|
8657
|
-
* @returns app.state
|
|
8658
|
-
*/
|
|
8659
|
-
function getAppStatus(appName) {
|
|
8660
|
-
const app = appInstanceMap.get(formatAppName(appName));
|
|
8661
|
-
if (app) {
|
|
8662
|
-
return app.getLifeCycleState();
|
|
8663
|
-
}
|
|
8664
|
-
else {
|
|
8665
|
-
logWarn(`app ${appName} does not exist`);
|
|
8666
|
-
}
|
|
8667
|
-
}
|
|
8668
9049
|
class MicroApp extends EventCenterForBaseApp {
|
|
8669
9050
|
constructor() {
|
|
8670
9051
|
super(...arguments);
|
|
@@ -8679,7 +9060,6 @@ class MicroApp extends EventCenterForBaseApp {
|
|
|
8679
9060
|
this.getAllApps = getAllApps;
|
|
8680
9061
|
this.reload = reload;
|
|
8681
9062
|
this.renderApp = renderApp;
|
|
8682
|
-
this.getAppStatus = getAppStatus;
|
|
8683
9063
|
}
|
|
8684
9064
|
start(options) {
|
|
8685
9065
|
var _a, _b;
|
|
@@ -8704,7 +9084,7 @@ class MicroApp extends EventCenterForBaseApp {
|
|
|
8704
9084
|
}
|
|
8705
9085
|
}
|
|
8706
9086
|
initGlobalEnv();
|
|
8707
|
-
if (
|
|
9087
|
+
if (window.customElements.get(this.tagName)) {
|
|
8708
9088
|
return logWarn(`element ${this.tagName} is already defined`);
|
|
8709
9089
|
}
|
|
8710
9090
|
if (isPlainObject(options)) {
|
|
@@ -8735,5 +9115,5 @@ class MicroApp extends EventCenterForBaseApp {
|
|
|
8735
9115
|
const microApp = new MicroApp();
|
|
8736
9116
|
|
|
8737
9117
|
export default microApp;
|
|
8738
|
-
export { EventCenterForMicroApp, MicroApp, getActiveApps, getAllApps,
|
|
9118
|
+
export { EventCenterForMicroApp, MicroApp, getActiveApps, getAllApps, preFetch, pureCreateElement, reload, removeDomScope, renderApp, unmountAllApps, unmountApp, version };
|
|
8739
9119
|
//# sourceMappingURL=index.esm.js.map
|