@micro-zoe/micro-app 1.0.0-rc.5 → 1.0.0-rc.7
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 +967 -574
- 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.7';
|
|
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
|
+
* The native mode also base of history.state, and the modification of the browser url cannot be controlled. It is very likely that the browser url and __MICRO_APP_STATE__ are different.
|
|
4756
|
+
* Especially during init of child or forward and backward of browser, because vue-router@4 will actively modify the browser URL, the above situation often occurs
|
|
4757
|
+
* To solve this problem, after child app is initialized and responds to the popstateEvent, it is determined whether __MICRO_APP_STATE__ and the browser url are different. If they are different, the browser url will updated to the address of __MICRO_APP_STATE__
|
|
4758
|
+
* NOTE:
|
|
4759
|
+
* 1. If __MICRO_APP_STATE__ is different from the URL, then the operation of updating the URL is correct, otherwise there will be a problem of inconsistency between the URL and the rendered page
|
|
4760
|
+
* 2. When there are multiple child app in native mode, if one of them changes the URL address, the other one will not change __MICRO_APP_STATE__, and refresh browser will cause problems
|
|
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,55 @@ 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
|
|
5851
|
+
var _a;
|
|
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
|
-
|
|
5858
|
+
/**
|
|
5859
|
+
* The child app cannot query the base element inside iframe
|
|
5860
|
+
* Same for querySelectorAll
|
|
5861
|
+
*
|
|
5862
|
+
* Scenes:
|
|
5863
|
+
* 1. vue-router@4.x --> createWebHistory(base?: string)
|
|
5864
|
+
* const baseEl = document.querySelector('base')
|
|
5865
|
+
* base = (baseEl && baseEl.getAttribute('href')) || '/'
|
|
5866
|
+
*
|
|
5867
|
+
* Issue: https://github.com/micro-zoe/micro-app/issues/1335
|
|
5868
|
+
*/
|
|
5869
|
+
const result = (_a = appInstanceMap.get(appName)) === null || _a === void 0 ? void 0 : _a.querySelector(selectors);
|
|
5870
|
+
return result || selectors === 'base' ? result : rawMicroQuerySelector.call(microDocument, selectors);
|
|
5559
5871
|
}
|
|
5560
5872
|
function querySelectorAll(selectors) {
|
|
5561
5873
|
var _a, _b;
|
|
5874
|
+
const _this = getBindTarget(this);
|
|
5562
5875
|
if (!selectors ||
|
|
5563
5876
|
isUniqueElement(selectors) ||
|
|
5564
|
-
|
|
5565
|
-
const _this = getDefaultRawTarget(this);
|
|
5877
|
+
rawDocument !== _this) {
|
|
5566
5878
|
return rawMicroQuerySelectorAll.call(_this, selectors);
|
|
5567
5879
|
}
|
|
5568
|
-
|
|
5880
|
+
const result = (_b = (_a = appInstanceMap.get(appName)) === null || _a === void 0 ? void 0 : _a.querySelectorAll(selectors)) !== null && _b !== void 0 ? _b : [];
|
|
5881
|
+
return result.length || selectors === 'base' ? result : rawMicroQuerySelectorAll.call(microDocument, selectors);
|
|
5569
5882
|
}
|
|
5570
5883
|
microRootDocument.prototype.querySelector = querySelector;
|
|
5571
5884
|
microRootDocument.prototype.querySelectorAll = querySelectorAll;
|
|
5572
5885
|
microRootDocument.prototype.getElementById = function getElementById(key) {
|
|
5573
|
-
const _this =
|
|
5886
|
+
const _this = getBindTarget(this);
|
|
5574
5887
|
if (isInvalidQuerySelectorKey(key)) {
|
|
5575
5888
|
return rawMicroGetElementById.call(_this, key);
|
|
5576
5889
|
}
|
|
@@ -5582,7 +5895,7 @@ function patchDocumentPrototype(appName, microAppWindow) {
|
|
|
5582
5895
|
}
|
|
5583
5896
|
};
|
|
5584
5897
|
microRootDocument.prototype.getElementsByClassName = function getElementsByClassName(key) {
|
|
5585
|
-
const _this =
|
|
5898
|
+
const _this = getBindTarget(this);
|
|
5586
5899
|
if (isInvalidQuerySelectorKey(key)) {
|
|
5587
5900
|
return rawMicroGetElementsByClassName.call(_this, key);
|
|
5588
5901
|
}
|
|
@@ -5594,12 +5907,13 @@ function patchDocumentPrototype(appName, microAppWindow) {
|
|
|
5594
5907
|
}
|
|
5595
5908
|
};
|
|
5596
5909
|
microRootDocument.prototype.getElementsByTagName = function getElementsByTagName(key) {
|
|
5597
|
-
const _this =
|
|
5910
|
+
const _this = getBindTarget(this);
|
|
5598
5911
|
if (isUniqueElement(key) ||
|
|
5599
5912
|
isInvalidQuerySelectorKey(key)) {
|
|
5600
5913
|
return rawMicroGetElementsByTagName.call(_this, key);
|
|
5914
|
+
// just script, not base
|
|
5601
5915
|
}
|
|
5602
|
-
else if (/^script
|
|
5916
|
+
else if (/^script$/i.test(key)) {
|
|
5603
5917
|
return rawMicroGetElementsByTagName.call(microDocument, key);
|
|
5604
5918
|
}
|
|
5605
5919
|
try {
|
|
@@ -5610,7 +5924,7 @@ function patchDocumentPrototype(appName, microAppWindow) {
|
|
|
5610
5924
|
}
|
|
5611
5925
|
};
|
|
5612
5926
|
microRootDocument.prototype.getElementsByName = function getElementsByName(key) {
|
|
5613
|
-
const _this =
|
|
5927
|
+
const _this = getBindTarget(this);
|
|
5614
5928
|
if (isInvalidQuerySelectorKey(key)) {
|
|
5615
5929
|
return rawMicroGetElementsByName.call(_this, key);
|
|
5616
5930
|
}
|
|
@@ -5677,7 +5991,7 @@ function patchDocumentProperty(appName, microAppWindow, sandbox) {
|
|
|
5677
5991
|
enumerable: true,
|
|
5678
5992
|
configurable: true,
|
|
5679
5993
|
get: () => {
|
|
5680
|
-
|
|
5994
|
+
throttleDeferForIframeAppName(appName);
|
|
5681
5995
|
return rawDocument[tagName];
|
|
5682
5996
|
},
|
|
5683
5997
|
set: (value) => { rawDocument[tagName] = value; },
|
|
@@ -5685,7 +5999,7 @@ function patchDocumentProperty(appName, microAppWindow, sandbox) {
|
|
|
5685
5999
|
});
|
|
5686
6000
|
}
|
|
5687
6001
|
function patchDocumentEffect(appName, microAppWindow) {
|
|
5688
|
-
const { rawDocument, rawAddEventListener, rawRemoveEventListener } = globalEnv;
|
|
6002
|
+
const { rawDocument, rawAddEventListener, rawRemoveEventListener, rawDispatchEvent } = globalEnv;
|
|
5689
6003
|
const eventListenerMap = new Map();
|
|
5690
6004
|
const sstEventListenerMap = new Map();
|
|
5691
6005
|
let onClickHandler = null;
|
|
@@ -5715,6 +6029,9 @@ function patchDocumentEffect(appName, microAppWindow) {
|
|
|
5715
6029
|
const handler = (listener === null || listener === void 0 ? void 0 : listener.__MICRO_APP_BOUND_FUNCTION__) || listener;
|
|
5716
6030
|
rawRemoveEventListener.call(getEventTarget(type, this), type, handler, options);
|
|
5717
6031
|
};
|
|
6032
|
+
microRootDocument.prototype.dispatchEvent = function (event) {
|
|
6033
|
+
return rawDispatchEvent.call(getEventTarget(event === null || event === void 0 ? void 0 : event.type, this), event);
|
|
6034
|
+
};
|
|
5718
6035
|
// 重新定义microRootDocument.prototype 上的on开头方法
|
|
5719
6036
|
function createSetterHandler(eventName) {
|
|
5720
6037
|
if (eventName === 'onclick') {
|
|
@@ -5835,12 +6152,18 @@ function patchElement(appName, url, microAppWindow, sandbox) {
|
|
|
5835
6152
|
patchIframeNode(appName, microAppWindow, sandbox);
|
|
5836
6153
|
patchIframeAttribute(url, microAppWindow);
|
|
5837
6154
|
}
|
|
6155
|
+
/**
|
|
6156
|
+
* patch iframe Node/Element
|
|
6157
|
+
*
|
|
6158
|
+
*/
|
|
5838
6159
|
function patchIframeNode(appName, microAppWindow, sandbox) {
|
|
5839
6160
|
const rawRootElement = globalEnv.rawRootElement; // native root Element
|
|
6161
|
+
const rawRootNode = globalEnv.rawRootNode;
|
|
5840
6162
|
const rawDocument = globalEnv.rawDocument;
|
|
5841
6163
|
const microDocument = microAppWindow.document;
|
|
5842
6164
|
const microRootNode = microAppWindow.Node;
|
|
5843
6165
|
const microRootElement = microAppWindow.Element;
|
|
6166
|
+
const microDocumentFragment = microAppWindow.DocumentFragment;
|
|
5844
6167
|
// const rawMicroGetRootNode = microRootNode.prototype.getRootNode
|
|
5845
6168
|
const rawMicroAppendChild = microRootNode.prototype.appendChild;
|
|
5846
6169
|
const rawMicroInsertBefore = microRootNode.prototype.insertBefore;
|
|
@@ -5848,6 +6171,8 @@ function patchIframeNode(appName, microAppWindow, sandbox) {
|
|
|
5848
6171
|
const rawMicroRemoveChild = microRootNode.prototype.removeChild;
|
|
5849
6172
|
const rawMicroAppend = microRootElement.prototype.append;
|
|
5850
6173
|
const rawMicroPrepend = microRootElement.prototype.prepend;
|
|
6174
|
+
const rawMicroFragmentAppend = microDocumentFragment.prototype.append;
|
|
6175
|
+
const rawMicroFragmentPrepend = microDocumentFragment.prototype.prepend;
|
|
5851
6176
|
const rawMicroInsertAdjacentElement = microRootElement.prototype.insertAdjacentElement;
|
|
5852
6177
|
const rawMicroCloneNode = microRootNode.prototype.cloneNode;
|
|
5853
6178
|
const rawInnerHTMLDesc = Object.getOwnPropertyDescriptor(microRootElement.prototype, 'innerHTML');
|
|
@@ -5865,42 +6190,34 @@ function patchIframeNode(appName, microAppWindow, sandbox) {
|
|
|
5865
6190
|
}
|
|
5866
6191
|
return parent;
|
|
5867
6192
|
};
|
|
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
6193
|
microRootNode.prototype.appendChild = function appendChild(node) {
|
|
5876
|
-
// TODO: 有必要执行这么多次updateElementInfo?
|
|
5877
6194
|
updateElementInfo(node, appName);
|
|
5878
6195
|
if (isPureNode(node)) {
|
|
5879
6196
|
return rawMicroAppendChild.call(this, node);
|
|
5880
6197
|
}
|
|
5881
|
-
return
|
|
6198
|
+
return rawRootNode.prototype.appendChild.call(getRawTarget(this), node);
|
|
5882
6199
|
};
|
|
5883
6200
|
microRootNode.prototype.insertBefore = function insertBefore(node, child) {
|
|
5884
6201
|
updateElementInfo(node, appName);
|
|
5885
6202
|
if (isPureNode(node)) {
|
|
5886
6203
|
return rawMicroInsertBefore.call(this, node, child);
|
|
5887
6204
|
}
|
|
5888
|
-
return
|
|
6205
|
+
return rawRootNode.prototype.insertBefore.call(getRawTarget(this), node, child);
|
|
5889
6206
|
};
|
|
5890
6207
|
microRootNode.prototype.replaceChild = function replaceChild(node, child) {
|
|
5891
6208
|
updateElementInfo(node, appName);
|
|
5892
6209
|
if (isPureNode(node)) {
|
|
5893
6210
|
return rawMicroReplaceChild.call(this, node, child);
|
|
5894
6211
|
}
|
|
5895
|
-
return
|
|
6212
|
+
return rawRootNode.prototype.replaceChild.call(getRawTarget(this), node, child);
|
|
5896
6213
|
};
|
|
5897
6214
|
microRootNode.prototype.removeChild = function removeChild(oldChild) {
|
|
5898
6215
|
if (isPureNode(oldChild) || this.contains(oldChild)) {
|
|
5899
6216
|
return rawMicroRemoveChild.call(this, oldChild);
|
|
5900
6217
|
}
|
|
5901
|
-
return
|
|
6218
|
+
return rawRootNode.prototype.removeChild.call(getRawTarget(this), oldChild);
|
|
5902
6219
|
};
|
|
5903
|
-
microRootElement.prototype.append = function append(...nodes) {
|
|
6220
|
+
microDocumentFragment.prototype.append = microRootElement.prototype.append = function append(...nodes) {
|
|
5904
6221
|
let i = 0;
|
|
5905
6222
|
let hasPureNode = false;
|
|
5906
6223
|
while (i < nodes.length) {
|
|
@@ -5910,11 +6227,11 @@ function patchIframeNode(appName, microAppWindow, sandbox) {
|
|
|
5910
6227
|
i++;
|
|
5911
6228
|
}
|
|
5912
6229
|
if (hasPureNode) {
|
|
5913
|
-
return rawMicroAppend.call(this, ...nodes);
|
|
6230
|
+
return (isDocumentFragment(this) ? rawMicroFragmentAppend : rawMicroAppend).call(this, ...nodes);
|
|
5914
6231
|
}
|
|
5915
6232
|
return rawRootElement.prototype.append.call(getRawTarget(this), ...nodes);
|
|
5916
6233
|
};
|
|
5917
|
-
microRootElement.prototype.prepend = function prepend(...nodes) {
|
|
6234
|
+
microDocumentFragment.prototype.prepend = microRootElement.prototype.prepend = function prepend(...nodes) {
|
|
5918
6235
|
let i = 0;
|
|
5919
6236
|
let hasPureNode = false;
|
|
5920
6237
|
while (i < nodes.length) {
|
|
@@ -5924,7 +6241,7 @@ function patchIframeNode(appName, microAppWindow, sandbox) {
|
|
|
5924
6241
|
i++;
|
|
5925
6242
|
}
|
|
5926
6243
|
if (hasPureNode) {
|
|
5927
|
-
return rawMicroPrepend.call(this, ...nodes);
|
|
6244
|
+
return (isDocumentFragment(this) ? rawMicroFragmentPrepend : rawMicroPrepend).call(this, ...nodes);
|
|
5928
6245
|
}
|
|
5929
6246
|
return rawRootElement.prototype.prepend.call(getRawTarget(this), ...nodes);
|
|
5930
6247
|
};
|
|
@@ -5940,28 +6257,53 @@ function patchIframeNode(appName, microAppWindow, sandbox) {
|
|
|
5940
6257
|
}
|
|
5941
6258
|
return rawRootElement.prototype.insertAdjacentElement.call(getRawTarget(this), where, element);
|
|
5942
6259
|
};
|
|
5943
|
-
|
|
5944
|
-
|
|
5945
|
-
|
|
5946
|
-
|
|
5947
|
-
|
|
6260
|
+
/**
|
|
6261
|
+
* Specific prototype properties:
|
|
6262
|
+
* 1. baseURI
|
|
6263
|
+
* 2. ownerDocument
|
|
6264
|
+
* 3. parentNode
|
|
6265
|
+
* 4. innerHTML
|
|
6266
|
+
*/
|
|
6267
|
+
rawDefineProperty(microRootNode.prototype, 'baseURI', {
|
|
6268
|
+
configurable: true,
|
|
6269
|
+
enumerable: true,
|
|
6270
|
+
get() {
|
|
6271
|
+
return sandbox.proxyWindow.location.href;
|
|
6272
|
+
},
|
|
6273
|
+
});
|
|
5948
6274
|
rawDefineProperty(microRootNode.prototype, 'ownerDocument', {
|
|
5949
6275
|
configurable: true,
|
|
5950
6276
|
enumerable: true,
|
|
5951
6277
|
get() {
|
|
6278
|
+
var _a;
|
|
5952
6279
|
return this.__PURE_ELEMENT__ || this === microDocument
|
|
5953
|
-
? rawOwnerDocumentDesc.get.call(this)
|
|
5954
|
-
: microDocument;
|
|
6280
|
+
? (_a = rawOwnerDocumentDesc.get) === null || _a === void 0 ? void 0 : _a.call(this) : microDocument;
|
|
5955
6281
|
},
|
|
5956
6282
|
});
|
|
6283
|
+
// patch parentNode
|
|
6284
|
+
rawDefineProperty(microRootNode.prototype, 'parentNode', getIframeParentNodeDesc(appName, rawParentNodeDesc));
|
|
6285
|
+
microRootNode.prototype.getRootNode = function getRootNode() {
|
|
6286
|
+
return microDocument;
|
|
6287
|
+
// TODO: any case return document?
|
|
6288
|
+
// const rootNode = rawMicroGetRootNode.call(this, options)
|
|
6289
|
+
// if (rootNode === appInstanceMap.get(appName)?.container) return microDocument
|
|
6290
|
+
// return rootNode
|
|
6291
|
+
};
|
|
6292
|
+
// patch cloneNode
|
|
6293
|
+
microRootNode.prototype.cloneNode = function cloneNode(deep) {
|
|
6294
|
+
const clonedNode = rawMicroCloneNode.call(this, deep);
|
|
6295
|
+
return updateElementInfo(clonedNode, appName);
|
|
6296
|
+
};
|
|
5957
6297
|
rawDefineProperty(microRootElement.prototype, 'innerHTML', {
|
|
5958
6298
|
configurable: true,
|
|
5959
6299
|
enumerable: true,
|
|
5960
6300
|
get() {
|
|
5961
|
-
|
|
6301
|
+
var _a;
|
|
6302
|
+
return (_a = rawInnerHTMLDesc.get) === null || _a === void 0 ? void 0 : _a.call(this);
|
|
5962
6303
|
},
|
|
5963
6304
|
set(code) {
|
|
5964
|
-
|
|
6305
|
+
var _a;
|
|
6306
|
+
(_a = rawInnerHTMLDesc.set) === null || _a === void 0 ? void 0 : _a.call(this, code);
|
|
5965
6307
|
Array.from(this.children).forEach((child) => {
|
|
5966
6308
|
if (isElement(child)) {
|
|
5967
6309
|
updateElementInfo(child, appName);
|
|
@@ -5969,34 +6311,6 @@ function patchIframeNode(appName, microAppWindow, sandbox) {
|
|
|
5969
6311
|
});
|
|
5970
6312
|
}
|
|
5971
6313
|
});
|
|
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
6314
|
// Adapt to new image(...) scene
|
|
6001
6315
|
const ImageProxy = new Proxy(microAppWindow.Image, {
|
|
6002
6316
|
construct(Target, args) {
|
|
@@ -6015,16 +6329,24 @@ function patchIframeAttribute(url, microAppWindow) {
|
|
|
6015
6329
|
const microRootElement = microAppWindow.Element;
|
|
6016
6330
|
const rawMicroSetAttribute = microRootElement.prototype.setAttribute;
|
|
6017
6331
|
microRootElement.prototype.setAttribute = function setAttribute(key, value) {
|
|
6018
|
-
if (
|
|
6019
|
-
|
|
6020
|
-
|
|
6332
|
+
if (/^micro-app(-\S+)?/i.test(this.tagName) &&
|
|
6333
|
+
key === 'data' &&
|
|
6334
|
+
this.setAttribute !== microRootElement.prototype.setAttribute) {
|
|
6335
|
+
this.setAttribute(key, value);
|
|
6336
|
+
}
|
|
6337
|
+
else {
|
|
6338
|
+
if (((key === 'src' || key === 'srcset') && /^(img|script|video|audio|source|embed)$/i.test(this.tagName)) ||
|
|
6339
|
+
(key === 'href' && /^(link|image)$/i.test(this.tagName))) {
|
|
6340
|
+
value = CompletionPath(value, url);
|
|
6341
|
+
}
|
|
6342
|
+
rawMicroSetAttribute.call(this, key, value);
|
|
6021
6343
|
}
|
|
6022
|
-
rawMicroSetAttribute.call(this, key, value);
|
|
6023
6344
|
};
|
|
6024
6345
|
const protoAttrList = [
|
|
6025
6346
|
[microAppWindow.HTMLImageElement.prototype, 'src'],
|
|
6026
6347
|
[microAppWindow.HTMLScriptElement.prototype, 'src'],
|
|
6027
6348
|
[microAppWindow.HTMLLinkElement.prototype, 'href'],
|
|
6349
|
+
[microAppWindow.SVGImageElement.prototype, 'href'],
|
|
6028
6350
|
];
|
|
6029
6351
|
/**
|
|
6030
6352
|
* element.setAttribute does not trigger this actions:
|
|
@@ -6057,7 +6379,7 @@ class IframeSandbox {
|
|
|
6057
6379
|
this.escapeProperties = [];
|
|
6058
6380
|
// Properties escape to rawWindow, cleared when unmount
|
|
6059
6381
|
this.escapeKeys = new Set();
|
|
6060
|
-
//
|
|
6382
|
+
// Update the base.href when initial and each redirect
|
|
6061
6383
|
this.updateIframeBase = () => {
|
|
6062
6384
|
var _a;
|
|
6063
6385
|
// origin must be child app origin
|
|
@@ -6101,9 +6423,10 @@ class IframeSandbox {
|
|
|
6101
6423
|
createIframeElement(appName, browserPath) {
|
|
6102
6424
|
this.iframe = pureCreateElement('iframe');
|
|
6103
6425
|
const iframeAttrs = {
|
|
6426
|
+
id: appName,
|
|
6104
6427
|
src: microApp.options.iframeSrc || browserPath,
|
|
6105
6428
|
style: 'display: none',
|
|
6106
|
-
|
|
6429
|
+
'powered-by': 'micro-app',
|
|
6107
6430
|
};
|
|
6108
6431
|
Object.keys(iframeAttrs).forEach((key) => this.iframe.setAttribute(key, iframeAttrs[key]));
|
|
6109
6432
|
// effect action during construct
|
|
@@ -6137,15 +6460,6 @@ class IframeSandbox {
|
|
|
6137
6460
|
* 1. iframe router and browser router are separated, we should update iframe router manually
|
|
6138
6461
|
* 2. withSandbox location is browser location when disable memory-router, so no need to do anything
|
|
6139
6462
|
*/
|
|
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
6463
|
this.initRouteState(defaultPage);
|
|
6150
6464
|
// unique listener of popstate event for child app
|
|
6151
6465
|
this.removeHistoryListener = addHistoryListener(this.microAppWindow.__MICRO_APP_NAME__);
|
|
@@ -6168,6 +6482,7 @@ class IframeSandbox {
|
|
|
6168
6482
|
}
|
|
6169
6483
|
stop({ umdMode, keepRouteState, destroy, clearData, }) {
|
|
6170
6484
|
var _a;
|
|
6485
|
+
// sandbox.stop may exec before sandbox.start, e.g: iframe sandbox + default mode + remount
|
|
6171
6486
|
if (!this.active)
|
|
6172
6487
|
return;
|
|
6173
6488
|
this.recordAndReleaseEffect({ clearData }, !umdMode || destroy);
|
|
@@ -6183,6 +6498,7 @@ class IframeSandbox {
|
|
|
6183
6498
|
Reflect.deleteProperty(globalEnv.rawWindow, key);
|
|
6184
6499
|
});
|
|
6185
6500
|
this.escapeKeys.clear();
|
|
6501
|
+
this.clearHijackUmdHooks();
|
|
6186
6502
|
}
|
|
6187
6503
|
if (--globalEnv.activeSandbox === 0) {
|
|
6188
6504
|
releasePatchElementAndDocument();
|
|
@@ -6401,10 +6717,49 @@ class IframeSandbox {
|
|
|
6401
6717
|
* action before exec scripts when mount
|
|
6402
6718
|
* Actions:
|
|
6403
6719
|
* 1. patch static elements from html
|
|
6720
|
+
* 2. hijack umd hooks -- mount, unmount, micro-app-appName
|
|
6404
6721
|
* @param container micro app container
|
|
6405
6722
|
*/
|
|
6406
|
-
|
|
6723
|
+
actionsBeforeExecScripts(container, handleUmdHooks) {
|
|
6407
6724
|
this.patchStaticElement(container);
|
|
6725
|
+
this.clearHijackUmdHooks = this.hijackUmdHooks(this.appName, this.microAppWindow, handleUmdHooks);
|
|
6726
|
+
}
|
|
6727
|
+
// hijack mount, unmount, micro-app-appName hook to microAppWindow
|
|
6728
|
+
hijackUmdHooks(appName, microAppWindow, handleUmdHooks) {
|
|
6729
|
+
let mount, unmount, microAppLibrary;
|
|
6730
|
+
rawDefineProperties(microAppWindow, {
|
|
6731
|
+
mount: {
|
|
6732
|
+
configurable: true,
|
|
6733
|
+
get: () => mount,
|
|
6734
|
+
set: (value) => {
|
|
6735
|
+
if (this.active && isFunction(value) && !mount) {
|
|
6736
|
+
handleUmdHooks(mount = value, unmount);
|
|
6737
|
+
}
|
|
6738
|
+
}
|
|
6739
|
+
},
|
|
6740
|
+
unmount: {
|
|
6741
|
+
configurable: true,
|
|
6742
|
+
get: () => unmount,
|
|
6743
|
+
set: (value) => {
|
|
6744
|
+
if (this.active && isFunction(value) && !unmount) {
|
|
6745
|
+
handleUmdHooks(mount, unmount = value);
|
|
6746
|
+
}
|
|
6747
|
+
}
|
|
6748
|
+
},
|
|
6749
|
+
[`micro-app-${appName}`]: {
|
|
6750
|
+
configurable: true,
|
|
6751
|
+
get: () => microAppLibrary,
|
|
6752
|
+
set: (value) => {
|
|
6753
|
+
if (this.active && isPlainObject(value) && !microAppLibrary) {
|
|
6754
|
+
microAppLibrary = value;
|
|
6755
|
+
handleUmdHooks(microAppLibrary.mount, microAppLibrary.unmount);
|
|
6756
|
+
}
|
|
6757
|
+
}
|
|
6758
|
+
}
|
|
6759
|
+
});
|
|
6760
|
+
return () => {
|
|
6761
|
+
mount = unmount = microAppLibrary = null;
|
|
6762
|
+
};
|
|
6408
6763
|
}
|
|
6409
6764
|
setStaticAppState(state) {
|
|
6410
6765
|
this.microAppWindow.__MICRO_APP_STATE__ = state;
|
|
@@ -6421,7 +6776,6 @@ class CreateApp {
|
|
|
6421
6776
|
this.loadSourceLevel = 0;
|
|
6422
6777
|
this.umdHookMount = null;
|
|
6423
6778
|
this.umdHookUnmount = null;
|
|
6424
|
-
this.lifeCycleState = null;
|
|
6425
6779
|
this.umdMode = false;
|
|
6426
6780
|
// TODO: 类型优化,加上iframe沙箱
|
|
6427
6781
|
this.sandBox = null;
|
|
@@ -6466,7 +6820,9 @@ class CreateApp {
|
|
|
6466
6820
|
var _a;
|
|
6467
6821
|
if (++this.loadSourceLevel === 2) {
|
|
6468
6822
|
this.source.html = html;
|
|
6469
|
-
if (
|
|
6823
|
+
if (this.isUnmounted())
|
|
6824
|
+
return;
|
|
6825
|
+
if (!this.isPrefetch) {
|
|
6470
6826
|
getRootContainer(this.container).mount(this);
|
|
6471
6827
|
}
|
|
6472
6828
|
else if (this.isPrerender) {
|
|
@@ -6589,7 +6945,6 @@ class CreateApp {
|
|
|
6589
6945
|
this.fiber = fiber;
|
|
6590
6946
|
this.routerMode = routerMode;
|
|
6591
6947
|
const dispatchBeforeMount = () => {
|
|
6592
|
-
this.setLifeCycleState(lifeCycles.BEFOREMOUNT);
|
|
6593
6948
|
dispatchLifecyclesEvent(this.container, this.name, lifeCycles.BEFOREMOUNT);
|
|
6594
6949
|
};
|
|
6595
6950
|
if (this.isPrerender) {
|
|
@@ -6603,7 +6958,7 @@ class CreateApp {
|
|
|
6603
6958
|
dispatchCustomEventToMicroApp(this, 'statechange', {
|
|
6604
6959
|
appState: appStates.MOUNTING
|
|
6605
6960
|
});
|
|
6606
|
-
// TODO:
|
|
6961
|
+
// TODO: 兼容shadowRoot的场景
|
|
6607
6962
|
this.cloneContainer(this.container, this.source.html, !this.umdMode);
|
|
6608
6963
|
(_e = this.sandBox) === null || _e === void 0 ? void 0 : _e.start({
|
|
6609
6964
|
umdMode: this.umdMode,
|
|
@@ -6612,38 +6967,35 @@ class CreateApp {
|
|
|
6612
6967
|
disablePatchRequest,
|
|
6613
6968
|
});
|
|
6614
6969
|
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;
|
|
6970
|
+
// patch element info of html
|
|
6971
|
+
(_f = this.sandBox) === null || _f === void 0 ? void 0 : _f.actionsBeforeExecScripts(this.container, (mount, unmount) => {
|
|
6972
|
+
var _a;
|
|
6973
|
+
if (!this.umdMode && !this.isUnmounted()) {
|
|
6974
|
+
this.umdHookMount = isFunction(mount) ? mount : null;
|
|
6975
|
+
// umdHookUnmount can works in default mode, register by window.unmount
|
|
6976
|
+
this.umdHookUnmount = isFunction(unmount) ? unmount : null;
|
|
6627
6977
|
// 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);
|
|
6978
|
+
if (isFunction(this.umdHookMount) && isFunction(this.umdHookUnmount)) {
|
|
6979
|
+
(_a = this.sandBox) === null || _a === void 0 ? void 0 : _a.markUmdMode(this.umdMode = true);
|
|
6632
6980
|
try {
|
|
6633
|
-
this.handleMounted
|
|
6981
|
+
// if appState is mounted, it means that isFinished is true and this.handleMounted has already been executed, just exec this.umdHookMount
|
|
6982
|
+
if (this.getAppState() === appStates.MOUNTED) {
|
|
6983
|
+
this.umdHookMount(microApp.getData(this.name, true));
|
|
6984
|
+
}
|
|
6985
|
+
else {
|
|
6986
|
+
this.handleMounted(this.umdHookMount(microApp.getData(this.name, true)));
|
|
6987
|
+
}
|
|
6634
6988
|
}
|
|
6635
6989
|
catch (e) {
|
|
6636
|
-
|
|
6637
|
-
* TODO:
|
|
6638
|
-
* 1. 是否应该直接抛出错误
|
|
6639
|
-
* 2. 是否应该触发error生命周期
|
|
6640
|
-
*/
|
|
6641
|
-
logError('An error occurred in window.mount \n', this.name, e);
|
|
6990
|
+
logError('An error occurred when mount \n', this.name, e);
|
|
6642
6991
|
}
|
|
6643
6992
|
}
|
|
6644
|
-
|
|
6645
|
-
|
|
6646
|
-
|
|
6993
|
+
}
|
|
6994
|
+
});
|
|
6995
|
+
// if all js are executed, param isFinished will be true
|
|
6996
|
+
execScripts(this, (isFinished) => {
|
|
6997
|
+
if (!this.umdMode && isFinished === true) {
|
|
6998
|
+
this.handleMounted();
|
|
6647
6999
|
}
|
|
6648
7000
|
});
|
|
6649
7001
|
}
|
|
@@ -6653,13 +7005,22 @@ class CreateApp {
|
|
|
6653
7005
|
this.handleMounted(this.umdHookMount(microApp.getData(this.name, true)));
|
|
6654
7006
|
}
|
|
6655
7007
|
catch (e) {
|
|
6656
|
-
logError('An error occurred
|
|
7008
|
+
logError('An error occurred when mount \n', this.name, e);
|
|
6657
7009
|
}
|
|
6658
7010
|
}
|
|
6659
7011
|
}
|
|
6660
7012
|
};
|
|
7013
|
+
/**
|
|
7014
|
+
* Initialization of sandbox is async, especially iframe sandbox are macro tasks
|
|
7015
|
+
* when child apps switch quickly, we need to pay attention to the following points:
|
|
7016
|
+
* NOTE:
|
|
7017
|
+
* 1. unmount app before exec nextAction (especially: iframe sandbox + default mode + remount)
|
|
7018
|
+
* this.container is null, this.sandBox will not start
|
|
7019
|
+
* 2. remount app of note 1
|
|
7020
|
+
* 3. unmount app during exec js
|
|
7021
|
+
*/
|
|
6661
7022
|
// TODO: 可优化?
|
|
6662
|
-
this.sandBox ? this.sandBox.sandboxReady.then(nextAction) : nextAction();
|
|
7023
|
+
this.sandBox ? this.sandBox.sandboxReady.then(() => !this.isUnmounted() && nextAction()) : nextAction();
|
|
6663
7024
|
}
|
|
6664
7025
|
/**
|
|
6665
7026
|
* handle for promise umdHookMount
|
|
@@ -6668,16 +7029,17 @@ class CreateApp {
|
|
|
6668
7029
|
handleMounted(umdHookMountResult) {
|
|
6669
7030
|
var _a, _b;
|
|
6670
7031
|
const dispatchAction = () => {
|
|
7032
|
+
const nextAction = () => this.actionsAfterMounted();
|
|
6671
7033
|
if (isPromise(umdHookMountResult)) {
|
|
6672
7034
|
umdHookMountResult
|
|
6673
|
-
.then(
|
|
7035
|
+
.then(nextAction)
|
|
6674
7036
|
.catch((e) => {
|
|
6675
7037
|
logError('An error occurred in window.mount \n', this.name, e);
|
|
6676
|
-
|
|
7038
|
+
nextAction();
|
|
6677
7039
|
});
|
|
6678
7040
|
}
|
|
6679
7041
|
else {
|
|
6680
|
-
|
|
7042
|
+
nextAction();
|
|
6681
7043
|
}
|
|
6682
7044
|
};
|
|
6683
7045
|
if (this.isPrerender) {
|
|
@@ -6691,7 +7053,7 @@ class CreateApp {
|
|
|
6691
7053
|
/**
|
|
6692
7054
|
* dispatch mounted event when app run finished
|
|
6693
7055
|
*/
|
|
6694
|
-
|
|
7056
|
+
actionsAfterMounted() {
|
|
6695
7057
|
var _a;
|
|
6696
7058
|
if (!this.isUnmounted()) {
|
|
6697
7059
|
this.setAppState(appStates.MOUNTED);
|
|
@@ -6703,7 +7065,6 @@ class CreateApp {
|
|
|
6703
7065
|
});
|
|
6704
7066
|
// dispatch mounted event to micro app
|
|
6705
7067
|
dispatchCustomEventToMicroApp(this, 'mounted');
|
|
6706
|
-
this.setLifeCycleState(lifeCycles.MOUNTED);
|
|
6707
7068
|
// dispatch event mounted to parent
|
|
6708
7069
|
dispatchLifecyclesEvent(this.container, this.name, lifeCycles.MOUNTED);
|
|
6709
7070
|
/**
|
|
@@ -6726,6 +7087,8 @@ class CreateApp {
|
|
|
6726
7087
|
* unmount app
|
|
6727
7088
|
* NOTE:
|
|
6728
7089
|
* 1. do not add any params on account of unmountApp
|
|
7090
|
+
* 2. this.container maybe null: Initialization of sandbox is async, child app may unmount before exec nextAction of mount
|
|
7091
|
+
* 3. unmount app when loading files (this.container is not null)
|
|
6729
7092
|
* @param destroy completely destroy, delete cache resources
|
|
6730
7093
|
* @param clearData clear data of dateCenter
|
|
6731
7094
|
* @param keepRouteState keep route state when unmount, default is false
|
|
@@ -6735,29 +7098,12 @@ class CreateApp {
|
|
|
6735
7098
|
var _a;
|
|
6736
7099
|
destroy = destroy || this.state === appStates.LOAD_FAILED;
|
|
6737
7100
|
this.setAppState(appStates.UNMOUNT);
|
|
6738
|
-
let umdHookUnmountResult = null;
|
|
6739
7101
|
try {
|
|
6740
|
-
|
|
6741
|
-
umdHookUnmountResult = (_a = this.umdHookUnmount) === null || _a === void 0 ? void 0 : _a.call(this, microApp.getData(this.name, true));
|
|
7102
|
+
this.handleUnmounted(destroy, clearData, keepRouteState, unmountcb, (_a = this.umdHookUnmount) === null || _a === void 0 ? void 0 : _a.call(this, microApp.getData(this.name, true)));
|
|
6742
7103
|
}
|
|
6743
7104
|
catch (e) {
|
|
6744
|
-
logError('An error occurred
|
|
7105
|
+
logError('An error occurred when unmount \n', this.name, e);
|
|
6745
7106
|
}
|
|
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
7107
|
}
|
|
6762
7108
|
/**
|
|
6763
7109
|
* handle for promise umdHookUnmount
|
|
@@ -6767,8 +7113,16 @@ class CreateApp {
|
|
|
6767
7113
|
* @param unmountcb callback of unmount
|
|
6768
7114
|
* @param umdHookUnmountResult result of umdHookUnmount
|
|
6769
7115
|
*/
|
|
6770
|
-
handleUnmounted(
|
|
6771
|
-
|
|
7116
|
+
handleUnmounted(destroy, clearData, keepRouteState, unmountcb, umdHookUnmountResult) {
|
|
7117
|
+
// dispatch state event to micro app
|
|
7118
|
+
dispatchCustomEventToMicroApp(this, 'statechange', {
|
|
7119
|
+
appState: appStates.UNMOUNT
|
|
7120
|
+
});
|
|
7121
|
+
// dispatch unmount event to micro app
|
|
7122
|
+
dispatchCustomEventToMicroApp(this, 'unmount');
|
|
7123
|
+
// call window.onunmount of child app
|
|
7124
|
+
execMicroAppGlobalHook(this.getMicroAppGlobalHook(microGlobalEvent.ONUNMOUNT), this.name, microGlobalEvent.ONUNMOUNT);
|
|
7125
|
+
const nextAction = () => this.actionsAfterUnmounted({
|
|
6772
7126
|
destroy,
|
|
6773
7127
|
clearData,
|
|
6774
7128
|
keepRouteState,
|
|
@@ -6777,7 +7131,12 @@ class CreateApp {
|
|
|
6777
7131
|
if (isPromise(umdHookUnmountResult)) {
|
|
6778
7132
|
// async window.unmount will cause appName bind error in nest app
|
|
6779
7133
|
removeDomScope();
|
|
6780
|
-
umdHookUnmountResult
|
|
7134
|
+
umdHookUnmountResult
|
|
7135
|
+
.then(nextAction)
|
|
7136
|
+
.catch((e) => {
|
|
7137
|
+
logError('An error occurred in window.unmount \n', this.name, e);
|
|
7138
|
+
nextAction();
|
|
7139
|
+
});
|
|
6781
7140
|
}
|
|
6782
7141
|
else {
|
|
6783
7142
|
nextAction();
|
|
@@ -6790,7 +7149,7 @@ class CreateApp {
|
|
|
6790
7149
|
* @param keepRouteState keep route state when unmount, default is false
|
|
6791
7150
|
* @param unmountcb callback of unmount
|
|
6792
7151
|
*/
|
|
6793
|
-
|
|
7152
|
+
actionsAfterUnmounted({ destroy, clearData, keepRouteState, unmountcb, }) {
|
|
6794
7153
|
var _a;
|
|
6795
7154
|
if (this.umdMode && this.container && !destroy) {
|
|
6796
7155
|
this.cloneContainer(this.source.html, this.container, false);
|
|
@@ -6807,20 +7166,33 @@ class CreateApp {
|
|
|
6807
7166
|
destroy,
|
|
6808
7167
|
clearData: clearData || destroy,
|
|
6809
7168
|
});
|
|
6810
|
-
this.setLifeCycleState(lifeCycles.UNMOUNT);
|
|
6811
7169
|
// dispatch unmount event to base app
|
|
6812
7170
|
dispatchLifecyclesEvent(this.container, this.name, lifeCycles.UNMOUNT);
|
|
6813
7171
|
this.clearOptions(destroy);
|
|
6814
7172
|
unmountcb === null || unmountcb === void 0 ? void 0 : unmountcb();
|
|
6815
7173
|
}
|
|
6816
7174
|
clearOptions(destroy) {
|
|
6817
|
-
|
|
6818
|
-
this.container = null;
|
|
7175
|
+
var _a, _b;
|
|
6819
7176
|
this.isPrerender = false;
|
|
6820
7177
|
this.preRenderEvents = null;
|
|
6821
7178
|
this.setKeepAliveState(null);
|
|
7179
|
+
if (this.container) {
|
|
7180
|
+
this.container.innerHTML = '';
|
|
7181
|
+
this.container = null;
|
|
7182
|
+
}
|
|
7183
|
+
else if (!this.umdMode) {
|
|
7184
|
+
/**
|
|
7185
|
+
* this.container is null means sandBox.start has not exec, so sandBox.stop won't exec either
|
|
7186
|
+
* we should remove iframeElement in default mode manually
|
|
7187
|
+
*/
|
|
7188
|
+
(_b = (_a = this.sandBox) === null || _a === void 0 ? void 0 : _a.deleteIframeElement) === null || _b === void 0 ? void 0 : _b.call(_a);
|
|
7189
|
+
}
|
|
6822
7190
|
// in iframe sandbox & default mode, delete the sandbox & iframeElement
|
|
6823
|
-
|
|
7191
|
+
/**
|
|
7192
|
+
* TODO:
|
|
7193
|
+
* 1. with沙箱与iframe沙箱保持一致:with沙箱默认模式下删除 或者 iframe沙箱umd模式下保留
|
|
7194
|
+
* 2. 接1.0,this.sandBox置空,还需要注意后续app.sandBox相关操作,比如 scripts.ts --> app.iframe ? app.sandBox!.microBody : app.querySelector('micro-app-body'),如果是fiber或者预加载,会存在卸载后js还在处理的情况
|
|
7195
|
+
*/
|
|
6824
7196
|
if (this.iframe && !this.umdMode)
|
|
6825
7197
|
this.sandBox = null;
|
|
6826
7198
|
if (destroy)
|
|
@@ -6849,7 +7221,6 @@ class CreateApp {
|
|
|
6849
7221
|
dispatchCustomEventToMicroApp(this, 'appstate-change', {
|
|
6850
7222
|
appState: 'afterhidden',
|
|
6851
7223
|
});
|
|
6852
|
-
this.setLifeCycleState(lifeCycles.AFTERHIDDEN);
|
|
6853
7224
|
// dispatch afterHidden event to base app
|
|
6854
7225
|
dispatchLifecyclesEvent(this.container, this.name, lifeCycles.AFTERHIDDEN);
|
|
6855
7226
|
if (isRouterModeSearch(this.name)) {
|
|
@@ -6891,7 +7262,7 @@ class CreateApp {
|
|
|
6891
7262
|
/**
|
|
6892
7263
|
* TODO:
|
|
6893
7264
|
* 问题:当路由模式为custom时,keep-alive应用在重新展示,是否需要根据子应用location信息更新浏览器地址?
|
|
6894
|
-
*
|
|
7265
|
+
* 暂时不这么做,因为无法确定二次展示时新旧地址是否相同,是否带有特殊信息
|
|
6895
7266
|
*/
|
|
6896
7267
|
if (isRouterModeSearch(this.name)) {
|
|
6897
7268
|
// called before lifeCyclesEvent
|
|
@@ -6901,7 +7272,6 @@ class CreateApp {
|
|
|
6901
7272
|
dispatchCustomEventToMicroApp(this, 'appstate-change', {
|
|
6902
7273
|
appState: 'aftershow',
|
|
6903
7274
|
});
|
|
6904
|
-
this.setLifeCycleState(lifeCycles.AFTERSHOW);
|
|
6905
7275
|
// dispatch afterShow event to base app
|
|
6906
7276
|
dispatchLifecyclesEvent(this.container, this.name, lifeCycles.AFTERSHOW);
|
|
6907
7277
|
}
|
|
@@ -6910,7 +7280,6 @@ class CreateApp {
|
|
|
6910
7280
|
* @param e Error
|
|
6911
7281
|
*/
|
|
6912
7282
|
onerror(e) {
|
|
6913
|
-
this.setLifeCycleState(lifeCycles.ERROR);
|
|
6914
7283
|
// dispatch state event to micro app
|
|
6915
7284
|
dispatchCustomEventToMicroApp(this, 'statechange', {
|
|
6916
7285
|
appState: appStates.LOAD_FAILED
|
|
@@ -6931,8 +7300,8 @@ class CreateApp {
|
|
|
6931
7300
|
}
|
|
6932
7301
|
/**
|
|
6933
7302
|
* clone origin elements to target
|
|
6934
|
-
* @param origin Cloned element
|
|
6935
7303
|
* @param target Accept cloned elements
|
|
7304
|
+
* @param origin Cloned element
|
|
6936
7305
|
* @param deep deep clone or transfer dom
|
|
6937
7306
|
*/
|
|
6938
7307
|
cloneContainer(target, origin, deep) {
|
|
@@ -6967,14 +7336,6 @@ class CreateApp {
|
|
|
6967
7336
|
getAppState() {
|
|
6968
7337
|
return this.state;
|
|
6969
7338
|
}
|
|
6970
|
-
// set app lifeCycleState
|
|
6971
|
-
setLifeCycleState(state) {
|
|
6972
|
-
this.lifeCycleState = state;
|
|
6973
|
-
}
|
|
6974
|
-
// get app lifeCycleState
|
|
6975
|
-
getLifeCycleState() {
|
|
6976
|
-
return this.lifeCycleState || '';
|
|
6977
|
-
}
|
|
6978
7339
|
// set keep-alive state
|
|
6979
7340
|
setKeepAliveState(state) {
|
|
6980
7341
|
this.keepAliveState = state;
|
|
@@ -6991,23 +7352,6 @@ class CreateApp {
|
|
|
6991
7352
|
isHidden() {
|
|
6992
7353
|
return keepAliveStates.KEEP_ALIVE_HIDDEN === this.keepAliveState;
|
|
6993
7354
|
}
|
|
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
7355
|
getMicroAppGlobalHook(eventName) {
|
|
7012
7356
|
var _a, _b;
|
|
7013
7357
|
const listener = (_b = (_a = this.sandBox) === null || _a === void 0 ? void 0 : _a.proxyWindow) === null || _b === void 0 ? void 0 : _b[eventName];
|
|
@@ -7113,11 +7457,11 @@ function handleNewNode(child, app) {
|
|
|
7113
7457
|
* @param app app
|
|
7114
7458
|
* @param method raw method
|
|
7115
7459
|
* @param parent parent node
|
|
7116
|
-
* @param
|
|
7117
|
-
* @param
|
|
7460
|
+
* @param targetNode target node
|
|
7461
|
+
* @param passiveNode second param of insertBefore and replaceChild
|
|
7118
7462
|
*/
|
|
7119
|
-
function invokePrototypeMethod(app, rawMethod, parent,
|
|
7120
|
-
const hijackParent = getHijackParent(parent,
|
|
7463
|
+
function invokePrototypeMethod(app, rawMethod, parent, targetNode, passiveNode) {
|
|
7464
|
+
const hijackParent = getHijackParent(parent, targetNode, app);
|
|
7121
7465
|
if (hijackParent) {
|
|
7122
7466
|
/**
|
|
7123
7467
|
* If parentNode is <micro-app-body>, return rawDocument.body
|
|
@@ -7134,9 +7478,9 @@ function invokePrototypeMethod(app, rawMethod, parent, targetChild, passiveChild
|
|
|
7134
7478
|
if (!isIframeSandbox(app.name) &&
|
|
7135
7479
|
isMicroAppBody(hijackParent) &&
|
|
7136
7480
|
rawMethod !== globalEnv.rawRemoveChild) {
|
|
7137
|
-
const descriptor = Object.getOwnPropertyDescriptor(
|
|
7138
|
-
if ((!descriptor || descriptor.configurable) && !
|
|
7139
|
-
rawDefineProperties(
|
|
7481
|
+
const descriptor = Object.getOwnPropertyDescriptor(targetNode, 'parentNode');
|
|
7482
|
+
if ((!descriptor || descriptor.configurable) && !targetNode.__MICRO_APP_HAS_DPN__) {
|
|
7483
|
+
rawDefineProperties(targetNode, {
|
|
7140
7484
|
parentNode: {
|
|
7141
7485
|
configurable: true,
|
|
7142
7486
|
get() {
|
|
@@ -7157,68 +7501,84 @@ function invokePrototypeMethod(app, rawMethod, parent, targetChild, passiveChild
|
|
|
7157
7501
|
}
|
|
7158
7502
|
}
|
|
7159
7503
|
if ((process.env.NODE_ENV !== 'production') &&
|
|
7160
|
-
isIFrameElement(
|
|
7504
|
+
isIFrameElement(targetNode) &&
|
|
7161
7505
|
rawMethod === globalEnv.rawAppendChild) {
|
|
7162
7506
|
fixReactHMRConflict(app);
|
|
7163
7507
|
}
|
|
7164
7508
|
/**
|
|
7165
|
-
* 1. If
|
|
7166
|
-
* 2. When removeChild,
|
|
7509
|
+
* 1. If passiveNode exists, it must be insertBefore or replaceChild
|
|
7510
|
+
* 2. When removeChild, targetNode may not be in microAppHead or head
|
|
7167
7511
|
* NOTE:
|
|
7168
|
-
* 1. If
|
|
7169
|
-
* E.g: document.head.replaceChild(
|
|
7170
|
-
* 2. If
|
|
7171
|
-
* E.g: document.head.insertBefore(
|
|
7512
|
+
* 1. If passiveNode not in hijackParent, insertBefore replaceChild will be degraded to appendChild
|
|
7513
|
+
* E.g: document.head.replaceChild(targetNode, document.scripts[0])
|
|
7514
|
+
* 2. If passiveNode not in hijackParent but in parent and method is insertBefore, try insert it into the position corresponding to hijackParent
|
|
7515
|
+
* E.g: document.head.insertBefore(targetNode, document.head.childNodes[0])
|
|
7172
7516
|
* ISSUE: https://github.com/micro-zoe/micro-app/issues/1071
|
|
7173
7517
|
*/
|
|
7174
|
-
if (
|
|
7175
|
-
if (rawMethod === globalEnv.rawInsertBefore && parent.contains(
|
|
7176
|
-
const indexOfParent = Array.from(parent.childNodes).indexOf(
|
|
7518
|
+
if (passiveNode && !hijackParent.contains(passiveNode)) {
|
|
7519
|
+
if (rawMethod === globalEnv.rawInsertBefore && parent.contains(passiveNode)) {
|
|
7520
|
+
const indexOfParent = Array.from(parent.childNodes).indexOf(passiveNode);
|
|
7177
7521
|
if (hijackParent.childNodes[indexOfParent]) {
|
|
7178
|
-
return invokeRawMethod(rawMethod, hijackParent,
|
|
7522
|
+
return invokeRawMethod(rawMethod, hijackParent, targetNode, hijackParent.childNodes[indexOfParent], app);
|
|
7179
7523
|
}
|
|
7180
7524
|
}
|
|
7181
|
-
return globalEnv.rawAppendChild.call(hijackParent,
|
|
7525
|
+
return globalEnv.rawAppendChild.call(hijackParent, targetNode);
|
|
7182
7526
|
}
|
|
7183
|
-
else if (rawMethod === globalEnv.rawRemoveChild && !hijackParent.contains(
|
|
7184
|
-
if (parent.contains(
|
|
7185
|
-
return rawMethod.call(parent,
|
|
7527
|
+
else if (rawMethod === globalEnv.rawRemoveChild && !hijackParent.contains(targetNode)) {
|
|
7528
|
+
if (parent.contains(targetNode)) {
|
|
7529
|
+
return rawMethod.call(parent, targetNode);
|
|
7186
7530
|
}
|
|
7187
|
-
return
|
|
7531
|
+
return targetNode;
|
|
7188
7532
|
}
|
|
7189
|
-
return invokeRawMethod(rawMethod, hijackParent,
|
|
7533
|
+
return invokeRawMethod(rawMethod, hijackParent, targetNode, passiveNode, app);
|
|
7190
7534
|
}
|
|
7191
|
-
return invokeRawMethod(rawMethod, parent,
|
|
7535
|
+
return invokeRawMethod(rawMethod, parent, targetNode, passiveNode, app);
|
|
7192
7536
|
}
|
|
7193
7537
|
// head/body map to micro-app-head/micro-app-body
|
|
7194
|
-
function getHijackParent(parent,
|
|
7538
|
+
function getHijackParent(parent, targetNode, app) {
|
|
7195
7539
|
if (app) {
|
|
7196
7540
|
if (parent === document.head) {
|
|
7197
|
-
if (app.iframe && isScriptElement(
|
|
7541
|
+
if (app.iframe && isScriptElement(targetNode)) {
|
|
7198
7542
|
return app.sandBox.microHead;
|
|
7199
7543
|
}
|
|
7200
7544
|
return app.querySelector('micro-app-head');
|
|
7201
7545
|
}
|
|
7202
7546
|
if (parent === document.body || parent === document.body.parentNode) {
|
|
7203
|
-
if (app.iframe && isScriptElement(
|
|
7547
|
+
if (app.iframe && isScriptElement(targetNode)) {
|
|
7204
7548
|
return app.sandBox.microBody;
|
|
7205
7549
|
}
|
|
7206
7550
|
return app.querySelector('micro-app-body');
|
|
7207
7551
|
}
|
|
7208
|
-
if (app.iframe && isScriptElement(
|
|
7552
|
+
if (app.iframe && isScriptElement(targetNode)) {
|
|
7209
7553
|
return app.sandBox.microBody;
|
|
7210
7554
|
}
|
|
7211
7555
|
}
|
|
7212
7556
|
return null;
|
|
7213
7557
|
}
|
|
7214
|
-
function invokeRawMethod(rawMethod, parent,
|
|
7558
|
+
function invokeRawMethod(rawMethod, parent, targetNode, passiveNode, app) {
|
|
7215
7559
|
if (isPendMethod(rawMethod)) {
|
|
7216
|
-
|
|
7560
|
+
/**
|
|
7561
|
+
* In iframe sandbox, script will pend to iframe.body, so we should reset rawMethod, because:
|
|
7562
|
+
* Element.prototype.append === DocumentFragment.prototype.append ==> false
|
|
7563
|
+
* Element.prototype.prepend === DocumentFragment.prototype.prepend ==> false
|
|
7564
|
+
*/
|
|
7565
|
+
if ((app === null || app === void 0 ? void 0 : app.iframe) && isScriptElement(targetNode)) {
|
|
7566
|
+
if (rawMethod === globalEnv.rawFragmentAppend) {
|
|
7567
|
+
rawMethod = globalEnv.rawAppend;
|
|
7568
|
+
}
|
|
7569
|
+
else if (rawMethod === globalEnv.rawFragmentPrepend) {
|
|
7570
|
+
rawMethod = globalEnv.rawPrepend;
|
|
7571
|
+
}
|
|
7572
|
+
}
|
|
7573
|
+
return rawMethod.call(parent, targetNode);
|
|
7217
7574
|
}
|
|
7218
|
-
return rawMethod.call(parent,
|
|
7575
|
+
return rawMethod.call(parent, targetNode, passiveNode);
|
|
7219
7576
|
}
|
|
7220
7577
|
function isPendMethod(method) {
|
|
7221
|
-
return method === globalEnv.rawAppend ||
|
|
7578
|
+
return (method === globalEnv.rawAppend ||
|
|
7579
|
+
method === globalEnv.rawPrepend ||
|
|
7580
|
+
method === globalEnv.rawFragmentAppend ||
|
|
7581
|
+
method === globalEnv.rawFragmentPrepend);
|
|
7222
7582
|
}
|
|
7223
7583
|
/**
|
|
7224
7584
|
* Attempt to complete the static resource address again before insert the node
|
|
@@ -7235,7 +7595,7 @@ function completePathDynamic(app, newChild) {
|
|
|
7235
7595
|
globalEnv.rawSetAttribute.call(newChild, 'srcset', CompletionPath(newChild.getAttribute('srcset'), app.url));
|
|
7236
7596
|
}
|
|
7237
7597
|
}
|
|
7238
|
-
else if (/^link$/i.test(newChild.tagName) && newChild.hasAttribute('href')) {
|
|
7598
|
+
else if (/^(link|image)$/i.test(newChild.tagName) && newChild.hasAttribute('href')) {
|
|
7239
7599
|
globalEnv.rawSetAttribute.call(newChild, 'href', CompletionPath(newChild.getAttribute('href'), app.url));
|
|
7240
7600
|
}
|
|
7241
7601
|
}
|
|
@@ -7244,31 +7604,26 @@ function completePathDynamic(app, newChild) {
|
|
|
7244
7604
|
* method of handle new node
|
|
7245
7605
|
* @param parent parent node
|
|
7246
7606
|
* @param newChild new node
|
|
7247
|
-
* @param
|
|
7607
|
+
* @param passiveNode passive node
|
|
7248
7608
|
* @param rawMethod method
|
|
7249
7609
|
*/
|
|
7250
|
-
function commonElementHandler(parent, newChild,
|
|
7610
|
+
function commonElementHandler(parent, newChild, passiveNode, rawMethod) {
|
|
7251
7611
|
const currentAppName = getCurrentAppName();
|
|
7252
7612
|
if (isNode(newChild) &&
|
|
7253
7613
|
!newChild.__PURE_ELEMENT__ &&
|
|
7254
7614
|
(newChild.__MICRO_APP_NAME__ ||
|
|
7255
7615
|
currentAppName)) {
|
|
7256
|
-
newChild
|
|
7616
|
+
updateElementInfo(newChild, newChild.__MICRO_APP_NAME__ || currentAppName);
|
|
7257
7617
|
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
7618
|
if (app === null || app === void 0 ? void 0 : app.container) {
|
|
7619
|
+
if (isStyleElement(newChild)) {
|
|
7620
|
+
parent.getRootNode() instanceof ShadowRoot && newChild.setAttribute('ignore', 'true');
|
|
7621
|
+
}
|
|
7264
7622
|
completePathDynamic(app, newChild);
|
|
7265
|
-
return invokePrototypeMethod(app, rawMethod, parent, handleNewNode(newChild, app),
|
|
7623
|
+
return invokePrototypeMethod(app, rawMethod, parent, handleNewNode(newChild, app), passiveNode && getMappingNode(passiveNode));
|
|
7266
7624
|
}
|
|
7267
7625
|
}
|
|
7268
|
-
|
|
7269
|
-
return rawMethod.call(parent, newChild);
|
|
7270
|
-
}
|
|
7271
|
-
return rawMethod.call(parent, newChild, passiveChild);
|
|
7626
|
+
return invokeRawMethod(rawMethod, parent, newChild, passiveNode);
|
|
7272
7627
|
}
|
|
7273
7628
|
/**
|
|
7274
7629
|
* Rewrite element prototype method
|
|
@@ -7277,36 +7632,19 @@ function patchElementAndDocument() {
|
|
|
7277
7632
|
patchDocument$2();
|
|
7278
7633
|
const rawRootElement = globalEnv.rawRootElement;
|
|
7279
7634
|
const rawRootNode = globalEnv.rawRootNode;
|
|
7635
|
+
const rawDocumentFragment = globalEnv.rawDocumentFragment;
|
|
7280
7636
|
// prototype methods of add element👇
|
|
7281
|
-
|
|
7637
|
+
rawRootNode.prototype.appendChild = function appendChild(newChild) {
|
|
7282
7638
|
return commonElementHandler(this, newChild, null, globalEnv.rawAppendChild);
|
|
7283
7639
|
};
|
|
7284
|
-
|
|
7640
|
+
rawRootNode.prototype.insertBefore = function insertBefore(newChild, refChild) {
|
|
7285
7641
|
return commonElementHandler(this, newChild, refChild, globalEnv.rawInsertBefore);
|
|
7286
7642
|
};
|
|
7287
|
-
|
|
7643
|
+
rawRootNode.prototype.replaceChild = function replaceChild(newChild, oldChild) {
|
|
7288
7644
|
return commonElementHandler(this, newChild, oldChild, globalEnv.rawReplaceChild);
|
|
7289
7645
|
};
|
|
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
7646
|
// prototype methods of delete element👇
|
|
7309
|
-
|
|
7647
|
+
rawRootNode.prototype.removeChild = function removeChild(oldChild) {
|
|
7310
7648
|
if (oldChild === null || oldChild === void 0 ? void 0 : oldChild.__MICRO_APP_NAME__) {
|
|
7311
7649
|
const app = appInstanceMap.get(oldChild.__MICRO_APP_NAME__);
|
|
7312
7650
|
if (app === null || app === void 0 ? void 0 : app.container) {
|
|
@@ -7321,6 +7659,24 @@ function patchElementAndDocument() {
|
|
|
7321
7659
|
}
|
|
7322
7660
|
return globalEnv.rawRemoveChild.call(this, oldChild);
|
|
7323
7661
|
};
|
|
7662
|
+
rawDocumentFragment.prototype.append = rawRootElement.prototype.append = function append(...nodes) {
|
|
7663
|
+
let i = 0;
|
|
7664
|
+
while (i < nodes.length) {
|
|
7665
|
+
let node = nodes[i];
|
|
7666
|
+
node = isNode(node) ? node : globalEnv.rawCreateTextNode.call(globalEnv.rawDocument, node);
|
|
7667
|
+
commonElementHandler(this, markElement(node), null, isDocumentFragment(this) ? globalEnv.rawFragmentAppend : globalEnv.rawAppend);
|
|
7668
|
+
i++;
|
|
7669
|
+
}
|
|
7670
|
+
};
|
|
7671
|
+
rawDocumentFragment.prototype.prepend = rawRootElement.prototype.prepend = function prepend(...nodes) {
|
|
7672
|
+
let i = nodes.length;
|
|
7673
|
+
while (i > 0) {
|
|
7674
|
+
let node = nodes[i - 1];
|
|
7675
|
+
node = isNode(node) ? node : globalEnv.rawCreateTextNode.call(globalEnv.rawDocument, node);
|
|
7676
|
+
commonElementHandler(this, markElement(node), null, isDocumentFragment(this) ? globalEnv.rawFragmentPrepend : globalEnv.rawPrepend);
|
|
7677
|
+
i--;
|
|
7678
|
+
}
|
|
7679
|
+
};
|
|
7324
7680
|
/**
|
|
7325
7681
|
* 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
7682
|
* NOTE:
|
|
@@ -7340,52 +7696,81 @@ function patchElementAndDocument() {
|
|
|
7340
7696
|
}
|
|
7341
7697
|
return globalEnv.rawInsertAdjacentElement.call(this, where, element);
|
|
7342
7698
|
};
|
|
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
7699
|
/**
|
|
7350
7700
|
* document.body(head).querySelector(querySelectorAll) hijack to microAppBody(microAppHead).querySelector(querySelectorAll)
|
|
7351
7701
|
* NOTE:
|
|
7352
7702
|
* 1. May cause some problems!
|
|
7353
7703
|
* 2. Add config options?
|
|
7354
7704
|
*/
|
|
7355
|
-
function
|
|
7356
|
-
const currentAppName = getCurrentAppName();
|
|
7357
|
-
if ((
|
|
7705
|
+
function getElementQueryTarget(targetNode) {
|
|
7706
|
+
const currentAppName = getIframeCurrentAppName() || getCurrentAppName();
|
|
7707
|
+
if ((targetNode === document.body || targetNode === document.head) && currentAppName) {
|
|
7358
7708
|
const app = appInstanceMap.get(currentAppName);
|
|
7359
7709
|
if (app === null || app === void 0 ? void 0 : app.container) {
|
|
7360
|
-
if (
|
|
7710
|
+
if (targetNode === document.body) {
|
|
7361
7711
|
return app.querySelector('micro-app-body');
|
|
7362
7712
|
}
|
|
7363
|
-
else if (
|
|
7713
|
+
else if (targetNode === document.head) {
|
|
7364
7714
|
return app.querySelector('micro-app-head');
|
|
7365
7715
|
}
|
|
7366
7716
|
}
|
|
7367
7717
|
}
|
|
7368
|
-
return
|
|
7718
|
+
return targetNode;
|
|
7719
|
+
}
|
|
7720
|
+
/**
|
|
7721
|
+
* In iframe sandbox, script will render to iframe instead of micro-app-body
|
|
7722
|
+
* So when query elements, we need to search both micro-app and iframe
|
|
7723
|
+
* @param isEmpty get empty result
|
|
7724
|
+
* @param targetNode targetNode element
|
|
7725
|
+
* @param result origin result
|
|
7726
|
+
* @param selectors selectors
|
|
7727
|
+
* @param methodName querySelector or querySelectorAll
|
|
7728
|
+
*/
|
|
7729
|
+
function getElementQueryResult(isEmpty, targetNode, result, selectors, methodName) {
|
|
7730
|
+
if (isEmpty) {
|
|
7731
|
+
const currentAppName = getIframeCurrentAppName() || getCurrentAppName();
|
|
7732
|
+
if (currentAppName && isIframeSandbox(currentAppName)) {
|
|
7733
|
+
const app = appInstanceMap.get(currentAppName);
|
|
7734
|
+
if (isMicroAppHead(targetNode)) {
|
|
7735
|
+
return app.sandBox.microHead[methodName](selectors);
|
|
7736
|
+
}
|
|
7737
|
+
if (isMicroAppBody(targetNode)) {
|
|
7738
|
+
return app.sandBox.microBody[methodName](selectors);
|
|
7739
|
+
}
|
|
7740
|
+
}
|
|
7741
|
+
}
|
|
7742
|
+
return result;
|
|
7369
7743
|
}
|
|
7370
7744
|
rawRootElement.prototype.querySelector = function querySelector(selectors) {
|
|
7371
7745
|
var _a;
|
|
7372
|
-
|
|
7746
|
+
const _this = (_a = getElementQueryTarget(this)) !== null && _a !== void 0 ? _a : this;
|
|
7747
|
+
const result = globalEnv.rawElementQuerySelector.call(_this, selectors);
|
|
7748
|
+
return getElementQueryResult(isNull(result) && _this !== this, _this, result, selectors, 'querySelector');
|
|
7373
7749
|
};
|
|
7374
7750
|
rawRootElement.prototype.querySelectorAll = function querySelectorAll(selectors) {
|
|
7375
7751
|
var _a;
|
|
7376
|
-
|
|
7752
|
+
const _this = (_a = getElementQueryTarget(this)) !== null && _a !== void 0 ? _a : this;
|
|
7753
|
+
const result = globalEnv.rawElementQuerySelectorAll.call(_this, selectors);
|
|
7754
|
+
return getElementQueryResult(!result.length && _this !== this, _this, result, selectors, 'querySelectorAll');
|
|
7377
7755
|
};
|
|
7378
7756
|
// rewrite setAttribute, complete resource address
|
|
7379
7757
|
rawRootElement.prototype.setAttribute = function setAttribute(key, value) {
|
|
7380
|
-
|
|
7381
|
-
|
|
7382
|
-
|
|
7383
|
-
(
|
|
7384
|
-
|
|
7385
|
-
|
|
7386
|
-
|
|
7758
|
+
if (/^micro-app(-\S+)?/i.test(this.tagName) &&
|
|
7759
|
+
key === 'data' &&
|
|
7760
|
+
this.setAttribute !== rawRootElement.prototype.setAttribute) {
|
|
7761
|
+
this.setAttribute(key, value);
|
|
7762
|
+
}
|
|
7763
|
+
else {
|
|
7764
|
+
const appName = this.__MICRO_APP_NAME__ || getCurrentAppName();
|
|
7765
|
+
if (appName &&
|
|
7766
|
+
appInstanceMap.has(appName) &&
|
|
7767
|
+
(((key === 'src' || key === 'srcset') && /^(img|script|video|audio|source|embed)$/i.test(this.tagName)) ||
|
|
7768
|
+
(key === 'href' && /^(link|image)$/i.test(this.tagName)))) {
|
|
7769
|
+
const app = appInstanceMap.get(appName);
|
|
7770
|
+
value = CompletionPath(value, app.url);
|
|
7771
|
+
}
|
|
7772
|
+
globalEnv.rawSetAttribute.call(this, key, value);
|
|
7387
7773
|
}
|
|
7388
|
-
globalEnv.rawSetAttribute.call(this, key, value);
|
|
7389
7774
|
};
|
|
7390
7775
|
/**
|
|
7391
7776
|
* TODO: 兼容直接通过img.src等操作设置的资源
|
|
@@ -7412,7 +7797,7 @@ function patchElementAndDocument() {
|
|
|
7412
7797
|
// return get?.call(this)
|
|
7413
7798
|
// },
|
|
7414
7799
|
// set: function (value) {
|
|
7415
|
-
// const currentAppName = getCurrentAppName()
|
|
7800
|
+
// const currentAppName = this.__MICRO_APP_NAME__ || getCurrentAppName()
|
|
7416
7801
|
// if (currentAppName && appInstanceMap.has(currentAppName)) {
|
|
7417
7802
|
// const app = appInstanceMap.get(currentAppName)
|
|
7418
7803
|
// value = CompletionPath(value, app!.url)
|
|
@@ -7421,41 +7806,25 @@ function patchElementAndDocument() {
|
|
|
7421
7806
|
// },
|
|
7422
7807
|
// })
|
|
7423
7808
|
// })
|
|
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
7809
|
rawDefineProperty(rawRootNode.prototype, 'parentNode', {
|
|
7442
7810
|
configurable: true,
|
|
7443
7811
|
enumerable: true,
|
|
7444
7812
|
get() {
|
|
7445
7813
|
var _a, _b, _c;
|
|
7446
7814
|
/**
|
|
7447
|
-
* hijack parentNode of html
|
|
7815
|
+
* hijack parentNode of html for with sandbox
|
|
7448
7816
|
* Scenes:
|
|
7449
7817
|
* 1. element-ui@2/lib/utils/popper.js
|
|
7450
7818
|
* // root is child app window, so root.document is proxyDocument or microDocument
|
|
7451
7819
|
* if (element.parentNode === root.document) ...
|
|
7452
7820
|
*/
|
|
7453
|
-
const currentAppName = getCurrentAppName();
|
|
7821
|
+
const currentAppName = getIframeCurrentAppName() || getCurrentAppName();
|
|
7454
7822
|
if (currentAppName && this === globalEnv.rawDocument.firstElementChild) {
|
|
7455
7823
|
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
7824
|
if (microDocument)
|
|
7457
7825
|
return microDocument;
|
|
7458
7826
|
}
|
|
7827
|
+
// NOTE: run after hijack html.parentNode
|
|
7459
7828
|
const result = globalEnv.rawParentNodeDesc.get.call(this);
|
|
7460
7829
|
/**
|
|
7461
7830
|
* If parentNode is <micro-app-body>, return rawDocument.body
|
|
@@ -7474,16 +7843,34 @@ function patchElementAndDocument() {
|
|
|
7474
7843
|
return result;
|
|
7475
7844
|
},
|
|
7476
7845
|
});
|
|
7846
|
+
rawDefineProperty(rawRootElement.prototype, 'innerHTML', {
|
|
7847
|
+
configurable: true,
|
|
7848
|
+
enumerable: true,
|
|
7849
|
+
get() {
|
|
7850
|
+
return globalEnv.rawInnerHTMLDesc.get.call(this);
|
|
7851
|
+
},
|
|
7852
|
+
set(code) {
|
|
7853
|
+
globalEnv.rawInnerHTMLDesc.set.call(this, code);
|
|
7854
|
+
const currentAppName = this.__MICRO_APP_NAME__ || getCurrentAppName();
|
|
7855
|
+
Array.from(this.children).forEach((child) => {
|
|
7856
|
+
if (isElement(child) && currentAppName) {
|
|
7857
|
+
updateElementInfo(child, currentAppName);
|
|
7858
|
+
}
|
|
7859
|
+
});
|
|
7860
|
+
}
|
|
7861
|
+
});
|
|
7862
|
+
// patch cloneNode
|
|
7863
|
+
rawRootNode.prototype.cloneNode = function cloneNode(deep) {
|
|
7864
|
+
const clonedNode = globalEnv.rawCloneNode.call(this, deep);
|
|
7865
|
+
return updateElementInfo(clonedNode, this.__MICRO_APP_NAME__);
|
|
7866
|
+
};
|
|
7477
7867
|
}
|
|
7478
7868
|
/**
|
|
7479
7869
|
* Mark the newly created element in the micro application
|
|
7480
7870
|
* @param element new element
|
|
7481
7871
|
*/
|
|
7482
7872
|
function markElement(element) {
|
|
7483
|
-
|
|
7484
|
-
if (currentAppName)
|
|
7485
|
-
element.__MICRO_APP_NAME__ = currentAppName;
|
|
7486
|
-
return element;
|
|
7873
|
+
return updateElementInfo(element, getCurrentAppName());
|
|
7487
7874
|
}
|
|
7488
7875
|
// methods of document
|
|
7489
7876
|
function patchDocument$2() {
|
|
@@ -7614,18 +8001,18 @@ function releasePatchElementAndDocument() {
|
|
|
7614
8001
|
releasePatchDocument();
|
|
7615
8002
|
const rawRootElement = globalEnv.rawRootElement;
|
|
7616
8003
|
const rawRootNode = globalEnv.rawRootNode;
|
|
7617
|
-
|
|
7618
|
-
|
|
7619
|
-
|
|
7620
|
-
|
|
8004
|
+
rawRootNode.prototype.appendChild = globalEnv.rawAppendChild;
|
|
8005
|
+
rawRootNode.prototype.insertBefore = globalEnv.rawInsertBefore;
|
|
8006
|
+
rawRootNode.prototype.replaceChild = globalEnv.rawReplaceChild;
|
|
8007
|
+
rawRootNode.prototype.removeChild = globalEnv.rawRemoveChild;
|
|
8008
|
+
rawRootNode.prototype.cloneNode = globalEnv.rawCloneNode;
|
|
7621
8009
|
rawRootElement.prototype.append = globalEnv.rawAppend;
|
|
7622
8010
|
rawRootElement.prototype.prepend = globalEnv.rawPrepend;
|
|
7623
|
-
rawRootElement.prototype.cloneNode = globalEnv.rawCloneNode;
|
|
7624
8011
|
rawRootElement.prototype.querySelector = globalEnv.rawElementQuerySelector;
|
|
7625
8012
|
rawRootElement.prototype.querySelectorAll = globalEnv.rawElementQuerySelectorAll;
|
|
7626
8013
|
rawRootElement.prototype.setAttribute = globalEnv.rawSetAttribute;
|
|
7627
|
-
rawDefineProperty(rawRootElement.prototype, 'innerHTML', globalEnv.rawInnerHTMLDesc);
|
|
7628
8014
|
rawDefineProperty(rawRootNode.prototype, 'parentNode', globalEnv.rawParentNodeDesc);
|
|
8015
|
+
rawDefineProperty(rawRootElement.prototype, 'innerHTML', globalEnv.rawInnerHTMLDesc);
|
|
7629
8016
|
}
|
|
7630
8017
|
// Set the style of micro-app-head and micro-app-body
|
|
7631
8018
|
let hasRejectMicroAppStyle = false;
|
|
@@ -7655,15 +8042,18 @@ function initGlobalEnv() {
|
|
|
7655
8042
|
const rawRootElement = rawWindow.Element;
|
|
7656
8043
|
const rawRootNode = rawWindow.Node;
|
|
7657
8044
|
const rawRootEventTarget = rawWindow.EventTarget;
|
|
8045
|
+
const rawDocumentFragment = rawWindow.DocumentFragment;
|
|
7658
8046
|
// save patch raw methods, pay attention to this binding
|
|
8047
|
+
const rawAppendChild = rawRootNode.prototype.appendChild;
|
|
8048
|
+
const rawInsertBefore = rawRootNode.prototype.insertBefore;
|
|
8049
|
+
const rawReplaceChild = rawRootNode.prototype.replaceChild;
|
|
8050
|
+
const rawRemoveChild = rawRootNode.prototype.removeChild;
|
|
7659
8051
|
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
8052
|
const rawAppend = rawRootElement.prototype.append;
|
|
7665
8053
|
const rawPrepend = rawRootElement.prototype.prepend;
|
|
7666
|
-
const
|
|
8054
|
+
const rawFragmentAppend = rawDocumentFragment.prototype.append;
|
|
8055
|
+
const rawFragmentPrepend = rawDocumentFragment.prototype.prepend;
|
|
8056
|
+
const rawCloneNode = rawRootNode.prototype.cloneNode;
|
|
7667
8057
|
const rawElementQuerySelector = rawRootElement.prototype.querySelector;
|
|
7668
8058
|
const rawElementQuerySelectorAll = rawRootElement.prototype.querySelectorAll;
|
|
7669
8059
|
const rawInsertAdjacentElement = rawRootElement.prototype.insertAdjacentElement;
|
|
@@ -7681,13 +8071,10 @@ function initGlobalEnv() {
|
|
|
7681
8071
|
const rawGetElementsByClassName = rawRootDocument.prototype.getElementsByClassName;
|
|
7682
8072
|
const rawGetElementsByTagName = rawRootDocument.prototype.getElementsByTagName;
|
|
7683
8073
|
const rawGetElementsByName = rawRootDocument.prototype.getElementsByName;
|
|
7684
|
-
|
|
8074
|
+
// TODO: 将ImageProxy移出去
|
|
8075
|
+
const ImageProxy = new Proxy(rawWindow.Image, {
|
|
7685
8076
|
construct(Target, args) {
|
|
7686
|
-
|
|
7687
|
-
const currentAppName = getCurrentAppName();
|
|
7688
|
-
if (currentAppName)
|
|
7689
|
-
elementImage.__MICRO_APP_NAME__ = currentAppName;
|
|
7690
|
-
return elementImage;
|
|
8077
|
+
return updateElementInfo(new Target(...args), getCurrentAppName());
|
|
7691
8078
|
},
|
|
7692
8079
|
});
|
|
7693
8080
|
/**
|
|
@@ -7713,6 +8100,7 @@ function initGlobalEnv() {
|
|
|
7713
8100
|
rawRootDocument,
|
|
7714
8101
|
rawRootElement,
|
|
7715
8102
|
rawRootNode,
|
|
8103
|
+
rawDocumentFragment,
|
|
7716
8104
|
// source/patch
|
|
7717
8105
|
rawSetAttribute,
|
|
7718
8106
|
rawAppendChild,
|
|
@@ -7721,6 +8109,8 @@ function initGlobalEnv() {
|
|
|
7721
8109
|
rawRemoveChild,
|
|
7722
8110
|
rawAppend,
|
|
7723
8111
|
rawPrepend,
|
|
8112
|
+
rawFragmentAppend,
|
|
8113
|
+
rawFragmentPrepend,
|
|
7724
8114
|
rawCloneNode,
|
|
7725
8115
|
rawElementQuerySelector,
|
|
7726
8116
|
rawElementQuerySelectorAll,
|
|
@@ -7760,7 +8150,7 @@ function initGlobalEnv() {
|
|
|
7760
8150
|
* @param tagName element name
|
|
7761
8151
|
*/
|
|
7762
8152
|
function defineElement(tagName) {
|
|
7763
|
-
class MicroAppElement extends
|
|
8153
|
+
class MicroAppElement extends HTMLElement {
|
|
7764
8154
|
constructor() {
|
|
7765
8155
|
super(...arguments);
|
|
7766
8156
|
this.isWaiting = false;
|
|
@@ -7825,6 +8215,13 @@ function defineElement(tagName) {
|
|
|
7825
8215
|
// baseRoute: route prefix, default is ''
|
|
7826
8216
|
// keep-alive: open keep-alive mode
|
|
7827
8217
|
connectedCallback() {
|
|
8218
|
+
/**
|
|
8219
|
+
* In FireFox, iframe Node.prototype will point to native Node.prototype after insert to document
|
|
8220
|
+
* If <micro-app>.prototype is not MicroAppElement.prototype, we should reset it
|
|
8221
|
+
*/
|
|
8222
|
+
if (Object.getPrototypeOf(this) !== MicroAppElement.prototype) {
|
|
8223
|
+
Object.setPrototypeOf(this, MicroAppElement.prototype);
|
|
8224
|
+
}
|
|
7828
8225
|
const cacheCount = ++this.connectedCount;
|
|
7829
8226
|
this.connectStateMap.set(cacheCount, true);
|
|
7830
8227
|
/**
|
|
@@ -8263,6 +8660,17 @@ function defineElement(tagName) {
|
|
|
8263
8660
|
globalEnv.rawSetAttribute.call(this, key, value);
|
|
8264
8661
|
}
|
|
8265
8662
|
}
|
|
8663
|
+
/**
|
|
8664
|
+
* get delay time of router event
|
|
8665
|
+
* @returns delay time
|
|
8666
|
+
*/
|
|
8667
|
+
getRouterEventDelay() {
|
|
8668
|
+
let delay = parseInt(this.getAttribute('router-event-delay'));
|
|
8669
|
+
if (isNaN(delay)) {
|
|
8670
|
+
delay = parseInt((isFunction(microApp.options['router-event-delay']) ? microApp.options['router-event-delay'](this.appName) : microApp.options['router-event-delay']));
|
|
8671
|
+
}
|
|
8672
|
+
return !isNaN(delay) ? delay : 0;
|
|
8673
|
+
}
|
|
8266
8674
|
/**
|
|
8267
8675
|
* Data from the base application
|
|
8268
8676
|
*/
|
|
@@ -8299,7 +8707,7 @@ function defineElement(tagName) {
|
|
|
8299
8707
|
return this.getBaseRouteCompatible();
|
|
8300
8708
|
}
|
|
8301
8709
|
}
|
|
8302
|
-
|
|
8710
|
+
window.customElements.define(tagName, MicroAppElement);
|
|
8303
8711
|
}
|
|
8304
8712
|
|
|
8305
8713
|
/**
|
|
@@ -8331,7 +8739,7 @@ function preFetch(apps, delay) {
|
|
|
8331
8739
|
const delayTime = isNumber(delay) ? delay : microApp.options.prefetchDelay;
|
|
8332
8740
|
/**
|
|
8333
8741
|
* TODO: remove setTimeout
|
|
8334
|
-
*
|
|
8742
|
+
* 如果要保留setTimeout,则需要考虑清空定时器的情况
|
|
8335
8743
|
*/
|
|
8336
8744
|
setTimeout(() => {
|
|
8337
8745
|
// releasePrefetchEffect()
|
|
@@ -8566,7 +8974,7 @@ function unmountApp(appName, options) {
|
|
|
8566
8974
|
}
|
|
8567
8975
|
}
|
|
8568
8976
|
else {
|
|
8569
|
-
logWarn(`app ${appName} does not exist`);
|
|
8977
|
+
logWarn(`app ${appName} does not exist when unmountApp`);
|
|
8570
8978
|
resolve(false);
|
|
8571
8979
|
}
|
|
8572
8980
|
});
|
|
@@ -8596,7 +9004,7 @@ function reload(appName, destroy) {
|
|
|
8596
9004
|
}
|
|
8597
9005
|
}
|
|
8598
9006
|
else {
|
|
8599
|
-
logWarn(`app ${appName} does not exist`);
|
|
9007
|
+
logWarn(`app ${appName} does not exist when reload app`);
|
|
8600
9008
|
resolve(false);
|
|
8601
9009
|
}
|
|
8602
9010
|
});
|
|
@@ -8651,20 +9059,6 @@ function renderApp(options) {
|
|
|
8651
9059
|
container.appendChild(microAppElement);
|
|
8652
9060
|
});
|
|
8653
9061
|
}
|
|
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
9062
|
class MicroApp extends EventCenterForBaseApp {
|
|
8669
9063
|
constructor() {
|
|
8670
9064
|
super(...arguments);
|
|
@@ -8679,7 +9073,6 @@ class MicroApp extends EventCenterForBaseApp {
|
|
|
8679
9073
|
this.getAllApps = getAllApps;
|
|
8680
9074
|
this.reload = reload;
|
|
8681
9075
|
this.renderApp = renderApp;
|
|
8682
|
-
this.getAppStatus = getAppStatus;
|
|
8683
9076
|
}
|
|
8684
9077
|
start(options) {
|
|
8685
9078
|
var _a, _b;
|
|
@@ -8704,7 +9097,7 @@ class MicroApp extends EventCenterForBaseApp {
|
|
|
8704
9097
|
}
|
|
8705
9098
|
}
|
|
8706
9099
|
initGlobalEnv();
|
|
8707
|
-
if (
|
|
9100
|
+
if (window.customElements.get(this.tagName)) {
|
|
8708
9101
|
return logWarn(`element ${this.tagName} is already defined`);
|
|
8709
9102
|
}
|
|
8710
9103
|
if (isPlainObject(options)) {
|
|
@@ -8735,5 +9128,5 @@ class MicroApp extends EventCenterForBaseApp {
|
|
|
8735
9128
|
const microApp = new MicroApp();
|
|
8736
9129
|
|
|
8737
9130
|
export default microApp;
|
|
8738
|
-
export { EventCenterForMicroApp, MicroApp, getActiveApps, getAllApps,
|
|
9131
|
+
export { EventCenterForMicroApp, MicroApp, getActiveApps, getAllApps, preFetch, pureCreateElement, reload, removeDomScope, renderApp, unmountAllApps, unmountApp, version };
|
|
8739
9132
|
//# sourceMappingURL=index.esm.js.map
|