@micro-zoe/micro-app 1.0.0-rc.2 → 1.0.0-rc.4
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/lib/index.d.ts +13 -10
- package/lib/index.esm.js +602 -327
- 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 +1 -1
- package/typings/global.d.ts +33 -25
package/lib/index.esm.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
const version = '1.0.0-rc.
|
|
1
|
+
const version = '1.0.0-rc.4';
|
|
2
2
|
// do not use isUndefined
|
|
3
3
|
const isBrowser = typeof window !== 'undefined';
|
|
4
4
|
// do not use isUndefined
|
|
@@ -15,7 +15,9 @@ const assign = Object.assign;
|
|
|
15
15
|
// Object prototype methods
|
|
16
16
|
const rawDefineProperty = Object.defineProperty;
|
|
17
17
|
const rawDefineProperties = Object.defineProperties;
|
|
18
|
+
const rawToString = Object.prototype.toString;
|
|
18
19
|
const rawHasOwnProperty = Object.prototype.hasOwnProperty;
|
|
20
|
+
const toTypeString = (value) => rawToString.call(value);
|
|
19
21
|
// is Undefined
|
|
20
22
|
function isUndefined(target) {
|
|
21
23
|
return target === undefined;
|
|
@@ -42,15 +44,15 @@ function isFunction(target) {
|
|
|
42
44
|
}
|
|
43
45
|
// is PlainObject
|
|
44
46
|
function isPlainObject(target) {
|
|
45
|
-
return
|
|
47
|
+
return toTypeString(target) === '[object Object]';
|
|
46
48
|
}
|
|
47
49
|
// is Object
|
|
48
50
|
function isObject(target) {
|
|
49
|
-
return typeof target === 'object';
|
|
51
|
+
return !isNull(target) && typeof target === 'object';
|
|
50
52
|
}
|
|
51
53
|
// is Promise
|
|
52
54
|
function isPromise(target) {
|
|
53
|
-
return
|
|
55
|
+
return toTypeString(target) === '[object Promise]';
|
|
54
56
|
}
|
|
55
57
|
// is bind function
|
|
56
58
|
function isBoundFunction(target) {
|
|
@@ -87,40 +89,52 @@ function isNode(target) {
|
|
|
87
89
|
return target instanceof Node || isNumber((_a = target) === null || _a === void 0 ? void 0 : _a.nodeType);
|
|
88
90
|
}
|
|
89
91
|
function isLinkElement(target) {
|
|
90
|
-
|
|
91
|
-
return ((_b = (_a = target) === null || _a === void 0 ? void 0 : _a.tagName) === null || _b === void 0 ? void 0 : _b.toUpperCase()) === 'LINK';
|
|
92
|
+
return toTypeString(target) === '[object HTMLLinkElement]';
|
|
92
93
|
}
|
|
93
94
|
function isStyleElement(target) {
|
|
94
|
-
|
|
95
|
-
return ((_b = (_a = target) === null || _a === void 0 ? void 0 : _a.tagName) === null || _b === void 0 ? void 0 : _b.toUpperCase()) === 'STYLE';
|
|
95
|
+
return toTypeString(target) === '[object HTMLStyleElement]';
|
|
96
96
|
}
|
|
97
97
|
function isScriptElement(target) {
|
|
98
|
-
|
|
99
|
-
return ((_b = (_a = target) === null || _a === void 0 ? void 0 : _a.tagName) === null || _b === void 0 ? void 0 : _b.toUpperCase()) === 'SCRIPT';
|
|
98
|
+
return toTypeString(target) === '[object HTMLScriptElement]';
|
|
100
99
|
}
|
|
101
100
|
function isIFrameElement(target) {
|
|
102
|
-
|
|
103
|
-
return ((_b = (_a = target) === null || _a === void 0 ? void 0 : _a.tagName) === null || _b === void 0 ? void 0 : _b.toUpperCase()) === 'IFRAME';
|
|
101
|
+
return toTypeString(target) === '[object HTMLIFrameElement]';
|
|
104
102
|
}
|
|
105
103
|
function isDivElement(target) {
|
|
106
|
-
|
|
107
|
-
return ((_b = (_a = target) === null || _a === void 0 ? void 0 : _a.tagName) === null || _b === void 0 ? void 0 : _b.toUpperCase()) === 'DIV';
|
|
104
|
+
return toTypeString(target) === '[object HTMLDivElement]';
|
|
108
105
|
}
|
|
109
106
|
function isImageElement(target) {
|
|
110
|
-
|
|
111
|
-
return ((_b = (_a = target) === null || _a === void 0 ? void 0 : _a.tagName) === null || _b === void 0 ? void 0 : _b.toUpperCase()) === 'IMG';
|
|
107
|
+
return toTypeString(target) === '[object HTMLImageElement]';
|
|
112
108
|
}
|
|
113
109
|
function isBaseElement(target) {
|
|
114
|
-
|
|
115
|
-
return ((_b = (_a = target) === null || _a === void 0 ? void 0 : _a.tagName) === null || _b === void 0 ? void 0 : _b.toUpperCase()) === 'BASE';
|
|
110
|
+
return toTypeString(target) === '[object HTMLBaseElement]';
|
|
116
111
|
}
|
|
117
112
|
function isMicroAppBody(target) {
|
|
118
|
-
|
|
119
|
-
return ((_b = (_a = target) === null || _a === void 0 ? void 0 : _a.tagName) === null || _b === void 0 ? void 0 : _b.toUpperCase()) === 'MICRO-APP-BODY';
|
|
113
|
+
return isElement(target) && target.tagName.toUpperCase() === 'MICRO-APP-BODY';
|
|
120
114
|
}
|
|
121
115
|
// is ProxyDocument
|
|
122
116
|
function isProxyDocument(target) {
|
|
123
|
-
return
|
|
117
|
+
return toTypeString(target) === '[object ProxyDocument]';
|
|
118
|
+
}
|
|
119
|
+
function includes(target, searchElement, fromIndex) {
|
|
120
|
+
if (target == null) {
|
|
121
|
+
throw new TypeError('includes target is null or undefined');
|
|
122
|
+
}
|
|
123
|
+
const O = Object(target);
|
|
124
|
+
const len = parseInt(O.length, 10) || 0;
|
|
125
|
+
if (len === 0)
|
|
126
|
+
return false;
|
|
127
|
+
// @ts-ignore
|
|
128
|
+
fromIndex = parseInt(fromIndex, 10) || 0;
|
|
129
|
+
let i = Math.max(fromIndex >= 0 ? fromIndex : len + fromIndex, 0);
|
|
130
|
+
while (i < len) {
|
|
131
|
+
// NaN !== NaN
|
|
132
|
+
if (searchElement === O[i] || (searchElement !== searchElement && O[i] !== O[i])) {
|
|
133
|
+
return true;
|
|
134
|
+
}
|
|
135
|
+
i++;
|
|
136
|
+
}
|
|
137
|
+
return false;
|
|
124
138
|
}
|
|
125
139
|
/**
|
|
126
140
|
* format error log
|
|
@@ -185,7 +199,7 @@ function formatAppURL(url, appName = null) {
|
|
|
185
199
|
if (!isString(url) || !url)
|
|
186
200
|
return '';
|
|
187
201
|
try {
|
|
188
|
-
const { origin, pathname, search } = createURL(addProtocol(url));
|
|
202
|
+
const { origin, pathname, search } = createURL(addProtocol(url), (window.rawWindow || window).location.href);
|
|
189
203
|
// If it ends with .html/.node/.php/.net/.etc, don’t need to add /
|
|
190
204
|
if (/\.(\w+)$/.test(pathname)) {
|
|
191
205
|
return `${origin}${pathname}${search}`;
|
|
@@ -324,21 +338,28 @@ let currentMicroAppName = null;
|
|
|
324
338
|
function setCurrentAppName(appName) {
|
|
325
339
|
currentMicroAppName = appName;
|
|
326
340
|
}
|
|
327
|
-
function throttleDeferForSetAppName(appName) {
|
|
328
|
-
if (currentMicroAppName !== appName) {
|
|
329
|
-
setCurrentAppName(appName);
|
|
330
|
-
defer(() => {
|
|
331
|
-
setCurrentAppName(null);
|
|
332
|
-
});
|
|
333
|
-
}
|
|
334
|
-
}
|
|
335
341
|
// get the currently running app.name
|
|
336
342
|
function getCurrentAppName() {
|
|
337
343
|
return currentMicroAppName;
|
|
338
344
|
}
|
|
339
345
|
// Clear appName
|
|
340
|
-
|
|
346
|
+
let preventSetAppName = false;
|
|
347
|
+
function removeDomScope(force) {
|
|
341
348
|
setCurrentAppName(null);
|
|
349
|
+
if (force && !preventSetAppName) {
|
|
350
|
+
preventSetAppName = true;
|
|
351
|
+
defer(() => {
|
|
352
|
+
preventSetAppName = false;
|
|
353
|
+
});
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
function throttleDeferForSetAppName(appName) {
|
|
357
|
+
if (currentMicroAppName !== appName && !preventSetAppName) {
|
|
358
|
+
setCurrentAppName(appName);
|
|
359
|
+
defer(() => {
|
|
360
|
+
setCurrentAppName(null);
|
|
361
|
+
});
|
|
362
|
+
}
|
|
342
363
|
}
|
|
343
364
|
/**
|
|
344
365
|
* Create pure elements
|
|
@@ -350,33 +371,6 @@ function pureCreateElement(tagName, options) {
|
|
|
350
371
|
element.__PURE_ELEMENT__ = true;
|
|
351
372
|
return element;
|
|
352
373
|
}
|
|
353
|
-
/**
|
|
354
|
-
* clone origin elements to target
|
|
355
|
-
* @param origin Cloned element
|
|
356
|
-
* @param target Accept cloned elements
|
|
357
|
-
* @param deep deep clone or transfer dom
|
|
358
|
-
*/
|
|
359
|
-
function cloneContainer(target, origin, deep) {
|
|
360
|
-
// 在基座接受到afterhidden方法后立即执行unmount,彻底destroy应用时,因为unmount时同步执行,所以this.container为null后才执行cloneContainer
|
|
361
|
-
if (origin) {
|
|
362
|
-
target.innerHTML = '';
|
|
363
|
-
if (deep) {
|
|
364
|
-
// TODO: ShadowRoot兼容,ShadowRoot不能直接使用cloneNode
|
|
365
|
-
const clonedNode = origin.cloneNode(true);
|
|
366
|
-
const fragment = document.createDocumentFragment();
|
|
367
|
-
Array.from(clonedNode.childNodes).forEach((node) => {
|
|
368
|
-
fragment.appendChild(node);
|
|
369
|
-
});
|
|
370
|
-
target.appendChild(fragment);
|
|
371
|
-
}
|
|
372
|
-
else {
|
|
373
|
-
Array.from(origin.childNodes).forEach((node) => {
|
|
374
|
-
target.appendChild(node);
|
|
375
|
-
});
|
|
376
|
-
}
|
|
377
|
-
}
|
|
378
|
-
return target;
|
|
379
|
-
}
|
|
380
374
|
// is invalid key of querySelector
|
|
381
375
|
function isInvalidQuerySelectorKey(key) {
|
|
382
376
|
return !key || /(^\d)|([^\w\d-_\u4e00-\u9fa5])/gi.test(key);
|
|
@@ -666,7 +660,10 @@ class HTMLLoader {
|
|
|
666
660
|
run(app, successCb) {
|
|
667
661
|
const appName = app.name;
|
|
668
662
|
const htmlUrl = app.ssrUrl || app.url;
|
|
669
|
-
|
|
663
|
+
const htmlPromise = htmlUrl.includes('.js')
|
|
664
|
+
? Promise.resolve(`<micro-app-head><script src='${htmlUrl}'></script></micro-app-head><micro-app-body></micro-app-body>`)
|
|
665
|
+
: fetchSource(htmlUrl, appName, { cache: 'no-cache' });
|
|
666
|
+
htmlPromise.then((htmlStr) => {
|
|
670
667
|
if (!htmlStr) {
|
|
671
668
|
const msg = 'html is empty, please check in detail';
|
|
672
669
|
app.onerror(new Error(msg));
|
|
@@ -821,8 +818,8 @@ class CSSParser {
|
|
|
821
818
|
return parseError("Declaration missing '}'", this.linkPath);
|
|
822
819
|
return true;
|
|
823
820
|
}
|
|
824
|
-
matchAllDeclarations() {
|
|
825
|
-
let cssValue = this.commonMatch(/^(?:url\(["']?(?:[^)"'}]+)["']?\)|[^}/])*/, true)[0];
|
|
821
|
+
matchAllDeclarations(nesting = 1) {
|
|
822
|
+
let cssValue = this.commonMatch(/^(?:url\(["']?(?:[^)"'}]+)["']?\)|[^{}/])*/, true)[0];
|
|
826
823
|
if (cssValue) {
|
|
827
824
|
if (!this.scopecssDisableNextLine &&
|
|
828
825
|
(!this.scopecssDisable || this.scopecssDisableSelectors.length)) {
|
|
@@ -841,16 +838,30 @@ class CSSParser {
|
|
|
841
838
|
}
|
|
842
839
|
// reset scopecssDisableNextLine
|
|
843
840
|
this.scopecssDisableNextLine = false;
|
|
844
|
-
if (!this.cssText
|
|
841
|
+
if (!this.cssText)
|
|
845
842
|
return;
|
|
843
|
+
if (this.cssText.charAt(0) === '}') {
|
|
844
|
+
if (!nesting)
|
|
845
|
+
return;
|
|
846
|
+
if (nesting > 1) {
|
|
847
|
+
this.commonMatch(/}+/);
|
|
848
|
+
}
|
|
849
|
+
return this.matchAllDeclarations(nesting - 1);
|
|
850
|
+
}
|
|
846
851
|
// extract comments in declarations
|
|
847
|
-
if (this.cssText.charAt(0) === '/'
|
|
848
|
-
this.
|
|
852
|
+
if (this.cssText.charAt(0) === '/') {
|
|
853
|
+
if (this.cssText.charAt(1) === '*') {
|
|
854
|
+
this.matchComments();
|
|
855
|
+
}
|
|
856
|
+
else {
|
|
857
|
+
this.commonMatch(/\/+/);
|
|
858
|
+
}
|
|
849
859
|
}
|
|
850
|
-
|
|
851
|
-
this.commonMatch(
|
|
860
|
+
if (this.cssText.charAt(0) === '{') {
|
|
861
|
+
this.commonMatch(/{+\s*/);
|
|
862
|
+
nesting++;
|
|
852
863
|
}
|
|
853
|
-
return this.matchAllDeclarations();
|
|
864
|
+
return this.matchAllDeclarations(nesting);
|
|
854
865
|
}
|
|
855
866
|
matchAtRule() {
|
|
856
867
|
if (this.cssText[0] !== '@')
|
|
@@ -1284,12 +1295,12 @@ function fetchLinksFromHtml(wrapElement, app, microAppHead, fiberStyleResult) {
|
|
|
1284
1295
|
*/
|
|
1285
1296
|
if (fiberStyleResult) {
|
|
1286
1297
|
fiberStyleResult.then(() => {
|
|
1287
|
-
fiberLinkTasks.push(() => Promise.resolve(app.onLoad(wrapElement)));
|
|
1298
|
+
fiberLinkTasks.push(() => Promise.resolve(app.onLoad({ html: wrapElement })));
|
|
1288
1299
|
serialExecFiberTasks(fiberLinkTasks);
|
|
1289
1300
|
});
|
|
1290
1301
|
}
|
|
1291
1302
|
else {
|
|
1292
|
-
app.onLoad(wrapElement);
|
|
1303
|
+
app.onLoad({ html: wrapElement });
|
|
1293
1304
|
}
|
|
1294
1305
|
});
|
|
1295
1306
|
}
|
|
@@ -1462,13 +1473,24 @@ var MicroAppConfig;
|
|
|
1462
1473
|
// prefetch level
|
|
1463
1474
|
const PREFETCH_LEVEL = [1, 2, 3];
|
|
1464
1475
|
// memory router constants
|
|
1476
|
+
// default mode, child router info will sync to browser url
|
|
1465
1477
|
const DEFAULT_ROUTER_MODE = 'search';
|
|
1466
|
-
|
|
1467
|
-
|
|
1478
|
+
/**
|
|
1479
|
+
* render base on browser url, and location.origin location.href point to base app
|
|
1480
|
+
* equal to disable-memory-router
|
|
1481
|
+
* NOTE:
|
|
1482
|
+
* 1. The only difference between native and native-scope is location.origin, in native-scope mode location.origin point to child app
|
|
1483
|
+
*/
|
|
1484
|
+
const ROUTER_MODE_NATIVE = 'native';
|
|
1485
|
+
// render base on browser url, but location.origin location.href point to child app
|
|
1486
|
+
const ROUTER_MODE_NATIVE_SCOPE = 'native-scope';
|
|
1487
|
+
// search mode, but child router info will not sync to browser url
|
|
1488
|
+
const ROUTER_MODE_PURE = 'pure';
|
|
1468
1489
|
const ROUTER_MODE_LIST = [
|
|
1469
1490
|
DEFAULT_ROUTER_MODE,
|
|
1470
|
-
|
|
1471
|
-
|
|
1491
|
+
ROUTER_MODE_NATIVE,
|
|
1492
|
+
ROUTER_MODE_NATIVE_SCOPE,
|
|
1493
|
+
ROUTER_MODE_PURE,
|
|
1472
1494
|
];
|
|
1473
1495
|
// event bound to child app window
|
|
1474
1496
|
const SCOPE_WINDOW_EVENT = [
|
|
@@ -1479,14 +1501,18 @@ const SCOPE_WINDOW_EVENT = [
|
|
|
1479
1501
|
'unload',
|
|
1480
1502
|
'unmount',
|
|
1481
1503
|
'appstate-change',
|
|
1504
|
+
'statechange',
|
|
1505
|
+
'mounted',
|
|
1482
1506
|
];
|
|
1483
1507
|
// on event bound to child app window
|
|
1508
|
+
// TODO: with和iframe处理方式不同,需修改
|
|
1484
1509
|
const SCOPE_WINDOW_ON_EVENT = [
|
|
1485
1510
|
'onpopstate',
|
|
1486
1511
|
'onhashchange',
|
|
1487
1512
|
'onload',
|
|
1488
1513
|
'onbeforeunload',
|
|
1489
1514
|
'onunload',
|
|
1515
|
+
'onerror'
|
|
1490
1516
|
];
|
|
1491
1517
|
// event bound to child app document
|
|
1492
1518
|
const SCOPE_DOCUMENT_EVENT = [
|
|
@@ -1776,16 +1802,16 @@ function fetchScriptsFromHtml(wrapElement, app) {
|
|
|
1776
1802
|
logError(err, app.name);
|
|
1777
1803
|
}, () => {
|
|
1778
1804
|
if (fiberScriptTasks) {
|
|
1779
|
-
fiberScriptTasks.push(() => Promise.resolve(app.onLoad(wrapElement)));
|
|
1805
|
+
fiberScriptTasks.push(() => Promise.resolve(app.onLoad({ html: wrapElement })));
|
|
1780
1806
|
serialExecFiberTasks(fiberScriptTasks);
|
|
1781
1807
|
}
|
|
1782
1808
|
else {
|
|
1783
|
-
app.onLoad(wrapElement);
|
|
1809
|
+
app.onLoad({ html: wrapElement });
|
|
1784
1810
|
}
|
|
1785
1811
|
});
|
|
1786
1812
|
}
|
|
1787
1813
|
else {
|
|
1788
|
-
app.onLoad(wrapElement);
|
|
1814
|
+
app.onLoad({ html: wrapElement });
|
|
1789
1815
|
}
|
|
1790
1816
|
}
|
|
1791
1817
|
/**
|
|
@@ -1952,6 +1978,8 @@ function runScript(address, app, scriptInfo, callback, replaceElement) {
|
|
|
1952
1978
|
}
|
|
1953
1979
|
catch (e) {
|
|
1954
1980
|
console.error(`[micro-app from ${replaceElement ? 'runDynamicScript' : 'runScript'}] app ${app.name}: `, e, address);
|
|
1981
|
+
// throw error in with sandbox to parent app
|
|
1982
|
+
throw e;
|
|
1955
1983
|
}
|
|
1956
1984
|
}
|
|
1957
1985
|
/**
|
|
@@ -2107,15 +2135,6 @@ function processCode(configs, code, address) {
|
|
|
2107
2135
|
}, code);
|
|
2108
2136
|
}
|
|
2109
2137
|
|
|
2110
|
-
/**
|
|
2111
|
-
* transform html string to dom
|
|
2112
|
-
* @param str string dom
|
|
2113
|
-
*/
|
|
2114
|
-
function getWrapElement(str) {
|
|
2115
|
-
const wrapDiv = pureCreateElement('div');
|
|
2116
|
-
wrapDiv.innerHTML = str;
|
|
2117
|
-
return wrapDiv;
|
|
2118
|
-
}
|
|
2119
2138
|
/**
|
|
2120
2139
|
* Recursively process each child element
|
|
2121
2140
|
* @param parent parent element
|
|
@@ -2172,7 +2191,7 @@ function flatChildren(parent, app, microAppHead, fiberStyleTasks) {
|
|
|
2172
2191
|
* @param app app
|
|
2173
2192
|
*/
|
|
2174
2193
|
function extractSourceDom(htmlStr, app) {
|
|
2175
|
-
const wrapElement =
|
|
2194
|
+
const wrapElement = app.parseHtmlString(htmlStr);
|
|
2176
2195
|
const microAppHead = globalEnv.rawElementQuerySelector.call(wrapElement, 'micro-app-head');
|
|
2177
2196
|
const microAppBody = globalEnv.rawElementQuerySelector.call(wrapElement, 'micro-app-body');
|
|
2178
2197
|
if (!microAppHead || !microAppBody) {
|
|
@@ -2190,16 +2209,16 @@ function extractSourceDom(htmlStr, app) {
|
|
|
2190
2209
|
fetchLinksFromHtml(wrapElement, app, microAppHead, fiberStyleResult);
|
|
2191
2210
|
}
|
|
2192
2211
|
else if (fiberStyleResult) {
|
|
2193
|
-
fiberStyleResult.then(() => app.onLoad(wrapElement));
|
|
2212
|
+
fiberStyleResult.then(() => app.onLoad({ html: wrapElement }));
|
|
2194
2213
|
}
|
|
2195
2214
|
else {
|
|
2196
|
-
app.onLoad(wrapElement);
|
|
2215
|
+
app.onLoad({ html: wrapElement });
|
|
2197
2216
|
}
|
|
2198
2217
|
if (app.source.scripts.size) {
|
|
2199
2218
|
fetchScriptsFromHtml(wrapElement, app);
|
|
2200
2219
|
}
|
|
2201
2220
|
else {
|
|
2202
|
-
app.onLoad(wrapElement);
|
|
2221
|
+
app.onLoad({ html: wrapElement });
|
|
2203
2222
|
}
|
|
2204
2223
|
}
|
|
2205
2224
|
|
|
@@ -2735,12 +2754,17 @@ function createProxyDocument(appName, sandbox) {
|
|
|
2735
2754
|
const sstEventListenerMap = new Map();
|
|
2736
2755
|
let onClickHandler = null;
|
|
2737
2756
|
let sstOnClickHandler = null;
|
|
2738
|
-
const { rawDocument, rawCreateElement, rawAddEventListener, rawRemoveEventListener, } = globalEnv;
|
|
2757
|
+
const { rawDocument, rawCreateElement, rawCreateElementNS, rawAddEventListener, rawRemoveEventListener, } = globalEnv;
|
|
2739
2758
|
function createElement(tagName, options) {
|
|
2740
2759
|
const element = rawCreateElement.call(rawDocument, tagName, options);
|
|
2741
2760
|
element.__MICRO_APP_NAME__ = appName;
|
|
2742
2761
|
return element;
|
|
2743
2762
|
}
|
|
2763
|
+
function createElementNS(namespaceURI, name, options) {
|
|
2764
|
+
const element = rawCreateElementNS.call(rawDocument, namespaceURI, name, options);
|
|
2765
|
+
element.__MICRO_APP_NAME__ = appName;
|
|
2766
|
+
return element;
|
|
2767
|
+
}
|
|
2744
2768
|
/**
|
|
2745
2769
|
* TODO:
|
|
2746
2770
|
* 1. listener 是否需要绑定proxyDocument,否则函数中的this指向原生window
|
|
@@ -2856,6 +2880,8 @@ function createProxyDocument(appName, sandbox) {
|
|
|
2856
2880
|
// TODO: 转换成数据形式,类似iframe的方式
|
|
2857
2881
|
if (key === 'createElement')
|
|
2858
2882
|
return createElement;
|
|
2883
|
+
if (key === 'createElementNS')
|
|
2884
|
+
return createElementNS;
|
|
2859
2885
|
if (key === Symbol.toStringTag)
|
|
2860
2886
|
return 'ProxyDocument';
|
|
2861
2887
|
if (key === 'defaultView')
|
|
@@ -2908,7 +2934,8 @@ function createMicroDocument(appName, proxyDocument) {
|
|
|
2908
2934
|
class MicroDocument {
|
|
2909
2935
|
static [Symbol.hasInstance](target) {
|
|
2910
2936
|
let proto = target;
|
|
2911
|
-
while (proto
|
|
2937
|
+
while (proto) {
|
|
2938
|
+
proto = Object.getPrototypeOf(proto);
|
|
2912
2939
|
if (proto === MicroDocument.prototype) {
|
|
2913
2940
|
return true;
|
|
2914
2941
|
}
|
|
@@ -2951,7 +2978,7 @@ function createMicroDocument(appName, proxyDocument) {
|
|
|
2951
2978
|
function patchWindow(appName, microAppWindow, sandbox) {
|
|
2952
2979
|
patchWindowProperty(microAppWindow);
|
|
2953
2980
|
createProxyWindow(appName, microAppWindow, sandbox);
|
|
2954
|
-
return patchWindowEffect(microAppWindow);
|
|
2981
|
+
return patchWindowEffect(microAppWindow, appName);
|
|
2955
2982
|
}
|
|
2956
2983
|
/**
|
|
2957
2984
|
* rewrite special properties of window
|
|
@@ -2992,22 +3019,22 @@ function createProxyWindow(appName, microAppWindow, sandbox) {
|
|
|
2992
3019
|
throttleDeferForSetAppName(appName);
|
|
2993
3020
|
if (Reflect.has(target, key) ||
|
|
2994
3021
|
(isString(key) && /^__MICRO_APP_/.test(key)) ||
|
|
2995
|
-
sandbox.scopeProperties
|
|
2996
|
-
if (
|
|
3022
|
+
includes(sandbox.scopeProperties, key)) {
|
|
3023
|
+
if (includes(RAW_GLOBAL_TARGET, key))
|
|
2997
3024
|
removeDomScope();
|
|
2998
3025
|
return Reflect.get(target, key);
|
|
2999
3026
|
}
|
|
3000
3027
|
return bindFunctionToRawTarget(Reflect.get(rawWindow, key), rawWindow);
|
|
3001
3028
|
},
|
|
3002
3029
|
set: (target, key, value) => {
|
|
3003
|
-
if (sandbox.
|
|
3030
|
+
if (includes(sandbox.rawWindowScopeKeyList, key)) {
|
|
3004
3031
|
Reflect.set(rawWindow, key, value);
|
|
3005
3032
|
}
|
|
3006
3033
|
else if (
|
|
3007
3034
|
// target.hasOwnProperty has been rewritten
|
|
3008
3035
|
!rawHasOwnProperty.call(target, key) &&
|
|
3009
3036
|
rawHasOwnProperty.call(rawWindow, key) &&
|
|
3010
|
-
!sandbox.scopeProperties
|
|
3037
|
+
!includes(sandbox.scopeProperties, key)) {
|
|
3011
3038
|
const descriptor = Object.getOwnPropertyDescriptor(rawWindow, key);
|
|
3012
3039
|
const { configurable, enumerable, writable, set } = descriptor;
|
|
3013
3040
|
// set value because it can be set
|
|
@@ -3020,32 +3047,37 @@ function createProxyWindow(appName, microAppWindow, sandbox) {
|
|
|
3020
3047
|
sandbox.injectedKeys.add(key);
|
|
3021
3048
|
}
|
|
3022
3049
|
else {
|
|
3023
|
-
|
|
3050
|
+
// all scopeProperties will add to injectedKeys, use for key in window (Proxy.has)
|
|
3051
|
+
if (!Reflect.has(target, key) || includes(sandbox.scopeProperties, key)) {
|
|
3052
|
+
sandbox.injectedKeys.add(key);
|
|
3053
|
+
}
|
|
3024
3054
|
Reflect.set(target, key, value);
|
|
3025
3055
|
}
|
|
3026
|
-
if ((sandbox.escapeProperties
|
|
3027
|
-
(
|
|
3056
|
+
if ((includes(sandbox.escapeProperties, key) ||
|
|
3057
|
+
(
|
|
3058
|
+
// TODO: staticEscapeProperties 合并到 escapeProperties
|
|
3059
|
+
includes(sandbox.staticEscapeProperties, key) &&
|
|
3028
3060
|
!Reflect.has(rawWindow, key))) &&
|
|
3029
|
-
!sandbox.scopeProperties
|
|
3061
|
+
!includes(sandbox.scopeProperties, key)) {
|
|
3030
3062
|
!Reflect.has(rawWindow, key) && sandbox.escapeKeys.add(key);
|
|
3031
3063
|
Reflect.set(rawWindow, key, value);
|
|
3032
3064
|
}
|
|
3033
3065
|
return true;
|
|
3034
3066
|
},
|
|
3035
3067
|
has: (target, key) => {
|
|
3036
|
-
|
|
3037
|
-
|
|
3038
|
-
|
|
3039
|
-
|
|
3040
|
-
|
|
3041
|
-
|
|
3042
|
-
|
|
3043
|
-
if (sandbox.
|
|
3044
|
-
return
|
|
3068
|
+
/**
|
|
3069
|
+
* Some keywords, such as Vue, need to meet two conditions at the same time:
|
|
3070
|
+
* 1. window.Vue --> undefined
|
|
3071
|
+
* 2. 'Vue' in window --> false
|
|
3072
|
+
* Issue https://github.com/micro-zoe/micro-app/issues/686
|
|
3073
|
+
*/
|
|
3074
|
+
if (includes(sandbox.scopeProperties, key)) {
|
|
3075
|
+
if (sandbox.injectedKeys.has(key)) {
|
|
3076
|
+
return Reflect.has(target, key); // true
|
|
3045
3077
|
}
|
|
3046
|
-
return key
|
|
3078
|
+
return !!target[key]; // false
|
|
3047
3079
|
}
|
|
3048
|
-
return
|
|
3080
|
+
return Reflect.has(target, key) || Reflect.has(rawWindow, key);
|
|
3049
3081
|
},
|
|
3050
3082
|
// Object.getOwnPropertyDescriptor(window, key)
|
|
3051
3083
|
getOwnPropertyDescriptor: (target, key) => {
|
|
@@ -3090,14 +3122,26 @@ function createProxyWindow(appName, microAppWindow, sandbox) {
|
|
|
3090
3122
|
* Rewrite side-effect events
|
|
3091
3123
|
* @param microAppWindow micro window
|
|
3092
3124
|
*/
|
|
3093
|
-
function patchWindowEffect(microAppWindow) {
|
|
3125
|
+
function patchWindowEffect(microAppWindow, appName) {
|
|
3094
3126
|
const eventListenerMap = new Map();
|
|
3095
3127
|
const sstEventListenerMap = new Map();
|
|
3096
3128
|
const intervalIdMap = new Map();
|
|
3097
3129
|
const timeoutIdMap = new Map();
|
|
3098
3130
|
const { rawWindow, rawAddEventListener, rawRemoveEventListener, rawDispatchEvent, rawSetInterval, rawSetTimeout, rawClearInterval, rawClearTimeout, } = globalEnv;
|
|
3131
|
+
/**
|
|
3132
|
+
* All events will bind to microAppElement or rawWindow
|
|
3133
|
+
* Some special events, such as popstate、load、unmount、appstate-change、statechange..., bind to microAppElement, others bind to rawWindow
|
|
3134
|
+
* NOTE:
|
|
3135
|
+
* 1、At first, microAppWindow = new EventTarget(), but it can not compatible with iOS 14 or below, so microAppElement was used instead. (2024.1.22)
|
|
3136
|
+
* @param type event name
|
|
3137
|
+
* @returns microAppElement/rawWindow
|
|
3138
|
+
*/
|
|
3099
3139
|
function getEventTarget(type) {
|
|
3100
|
-
|
|
3140
|
+
var _a;
|
|
3141
|
+
if (SCOPE_WINDOW_EVENT.includes(type) && ((_a = appInstanceMap.get(appName)) === null || _a === void 0 ? void 0 : _a.container)) {
|
|
3142
|
+
return getRootContainer(appInstanceMap.get(appName).container);
|
|
3143
|
+
}
|
|
3144
|
+
return rawWindow;
|
|
3101
3145
|
}
|
|
3102
3146
|
/**
|
|
3103
3147
|
* listener may be null, e.g test-passive
|
|
@@ -3211,7 +3255,7 @@ function patchWindowEffect(microAppWindow) {
|
|
|
3211
3255
|
|
|
3212
3256
|
// set micro app state to origin state
|
|
3213
3257
|
function setMicroState(appName, microState) {
|
|
3214
|
-
if (
|
|
3258
|
+
if (isRouterModeSearch(appName)) {
|
|
3215
3259
|
const rawState = globalEnv.rawWindow.history.state;
|
|
3216
3260
|
const additionalState = {
|
|
3217
3261
|
microAppState: assign({}, rawState === null || rawState === void 0 ? void 0 : rawState.microAppState, {
|
|
@@ -3225,7 +3269,7 @@ function setMicroState(appName, microState) {
|
|
|
3225
3269
|
}
|
|
3226
3270
|
// delete micro app state form origin state
|
|
3227
3271
|
function removeMicroState(appName, rawState) {
|
|
3228
|
-
if (
|
|
3272
|
+
if (isRouterModeSearch(appName)) {
|
|
3229
3273
|
if (isPlainObject(rawState === null || rawState === void 0 ? void 0 : rawState.microAppState)) {
|
|
3230
3274
|
if (!isUndefined(rawState.microAppState[appName])) {
|
|
3231
3275
|
delete rawState.microAppState[appName];
|
|
@@ -3242,7 +3286,7 @@ function removeMicroState(appName, rawState) {
|
|
|
3242
3286
|
function getMicroState(appName) {
|
|
3243
3287
|
var _a;
|
|
3244
3288
|
const rawState = globalEnv.rawWindow.history.state;
|
|
3245
|
-
if (
|
|
3289
|
+
if (isRouterModeSearch(appName)) {
|
|
3246
3290
|
return ((_a = rawState === null || rawState === void 0 ? void 0 : rawState.microAppState) === null || _a === void 0 ? void 0 : _a[appName]) || null;
|
|
3247
3291
|
}
|
|
3248
3292
|
return rawState;
|
|
@@ -3282,8 +3326,11 @@ function formatQueryAppName(appName) {
|
|
|
3282
3326
|
*/
|
|
3283
3327
|
function getMicroPathFromURL(appName) {
|
|
3284
3328
|
var _a, _b;
|
|
3329
|
+
// TODO: pure模式从state中获取地址
|
|
3330
|
+
if (isRouterModePure(appName))
|
|
3331
|
+
return null;
|
|
3285
3332
|
const rawLocation = globalEnv.rawWindow.location;
|
|
3286
|
-
if (
|
|
3333
|
+
if (isRouterModeSearch(appName)) {
|
|
3287
3334
|
const queryObject = getQueryObjectFromURL(rawLocation.search, rawLocation.hash);
|
|
3288
3335
|
const microPath = ((_a = queryObject.hashQuery) === null || _a === void 0 ? void 0 : _a[formatQueryAppName(appName)]) || ((_b = queryObject.searchQuery) === null || _b === void 0 ? void 0 : _b[formatQueryAppName(appName)]);
|
|
3289
3336
|
return isString(microPath) ? decodeMicroPath(microPath) : null;
|
|
@@ -3298,7 +3345,7 @@ function getMicroPathFromURL(appName) {
|
|
|
3298
3345
|
function setMicroPathToURL(appName, targetLocation) {
|
|
3299
3346
|
const targetFullPath = targetLocation.pathname + targetLocation.search + targetLocation.hash;
|
|
3300
3347
|
let isAttach2Hash = false;
|
|
3301
|
-
if (
|
|
3348
|
+
if (isRouterModeSearch(appName)) {
|
|
3302
3349
|
let { pathname, search, hash } = globalEnv.rawWindow.location;
|
|
3303
3350
|
const queryObject = getQueryObjectFromURL(search, hash);
|
|
3304
3351
|
const encodedMicroPath = encodeMicroPath(targetFullPath);
|
|
@@ -3350,7 +3397,7 @@ function removeMicroPathFromURL(appName, targetLocation) {
|
|
|
3350
3397
|
var _a, _b, _c, _d;
|
|
3351
3398
|
let { pathname, search, hash } = targetLocation || globalEnv.rawWindow.location;
|
|
3352
3399
|
let isAttach2Hash = false;
|
|
3353
|
-
if (
|
|
3400
|
+
if (isRouterModeSearch(appName)) {
|
|
3354
3401
|
const queryObject = getQueryObjectFromURL(search, hash);
|
|
3355
3402
|
if ((_a = queryObject.hashQuery) === null || _a === void 0 ? void 0 : _a[formatQueryAppName(appName)]) {
|
|
3356
3403
|
isAttach2Hash = true;
|
|
@@ -3410,15 +3457,31 @@ function isEffectiveApp(appName) {
|
|
|
3410
3457
|
*/
|
|
3411
3458
|
return !!(app && !app.isPrefetch);
|
|
3412
3459
|
}
|
|
3460
|
+
// router mode is search
|
|
3461
|
+
function isRouterModeSearch(appName) {
|
|
3462
|
+
const app = appInstanceMap.get(appName);
|
|
3463
|
+
return !!(app && app.sandBox && app.routerMode === DEFAULT_ROUTER_MODE);
|
|
3464
|
+
}
|
|
3465
|
+
// router mode is history
|
|
3466
|
+
function isRouterModeNative(appName) {
|
|
3467
|
+
const app = appInstanceMap.get(appName);
|
|
3468
|
+
return !!(app && app.sandBox && app.routerMode === ROUTER_MODE_NATIVE);
|
|
3469
|
+
}
|
|
3470
|
+
// router mode is disable
|
|
3471
|
+
function isRouterModeNativeScope(appName) {
|
|
3472
|
+
const app = appInstanceMap.get(appName);
|
|
3473
|
+
return !!(app && app.sandBox && app.routerMode === ROUTER_MODE_NATIVE_SCOPE);
|
|
3474
|
+
}
|
|
3475
|
+
// router mode is pure
|
|
3476
|
+
function isRouterModePure(appName) {
|
|
3477
|
+
const app = appInstanceMap.get(appName);
|
|
3478
|
+
return !!(app && app.sandBox && app.routerMode === ROUTER_MODE_PURE);
|
|
3479
|
+
}
|
|
3413
3480
|
/**
|
|
3414
|
-
* router mode is
|
|
3415
|
-
* NOTE:
|
|
3416
|
-
* 1. if sandbox disabled, router mode defaults to custom
|
|
3417
|
-
* 2. if app not exist, router mode defaults to custom
|
|
3481
|
+
* router mode is history or disable
|
|
3418
3482
|
*/
|
|
3419
3483
|
function isRouterModeCustom(appName) {
|
|
3420
|
-
|
|
3421
|
-
return !app || !app.sandBox || app.routerMode === ROUTER_MODE_CUSTOM;
|
|
3484
|
+
return isRouterModeNative(appName) || isRouterModeNativeScope(appName);
|
|
3422
3485
|
}
|
|
3423
3486
|
/**
|
|
3424
3487
|
* get memory router mode of child app
|
|
@@ -3426,21 +3489,21 @@ function isRouterModeCustom(appName) {
|
|
|
3426
3489
|
* 1. if microAppElement exists, it means the app render by the micro-app element
|
|
3427
3490
|
* 2. if microAppElement not exists, it means it is prerender app
|
|
3428
3491
|
* @param mode native config
|
|
3429
|
-
* @param
|
|
3430
|
-
* @returns mode
|
|
3492
|
+
* @param inlineDisableMemoryRouter disable-memory-router set by micro-app element or prerender
|
|
3493
|
+
* @returns router mode
|
|
3431
3494
|
*/
|
|
3432
|
-
function getRouterMode(mode,
|
|
3433
|
-
let routerMode;
|
|
3495
|
+
function getRouterMode(mode, inlineDisableMemoryRouter) {
|
|
3434
3496
|
/**
|
|
3435
3497
|
* compatible with disable-memory-router in older versions
|
|
3436
|
-
* if disable-memory-router is true, router-mode will be
|
|
3498
|
+
* if disable-memory-router is true, router-mode will be disable
|
|
3499
|
+
* Priority:
|
|
3500
|
+
* inline disable-memory-router > inline router-mode > global disable-memory-router > global router-mode
|
|
3437
3501
|
*/
|
|
3438
|
-
|
|
3439
|
-
|
|
3440
|
-
|
|
3441
|
-
|
|
3442
|
-
|
|
3443
|
-
}
|
|
3502
|
+
const routerMode = ((inlineDisableMemoryRouter && ROUTER_MODE_NATIVE) ||
|
|
3503
|
+
mode ||
|
|
3504
|
+
(microApp.options['disable-memory-router'] && ROUTER_MODE_NATIVE) ||
|
|
3505
|
+
microApp.options['router-mode'] ||
|
|
3506
|
+
DEFAULT_ROUTER_MODE);
|
|
3444
3507
|
return ROUTER_MODE_LIST.includes(routerMode) ? routerMode : DEFAULT_ROUTER_MODE;
|
|
3445
3508
|
}
|
|
3446
3509
|
|
|
@@ -3586,7 +3649,7 @@ function dispatchNativeEvent(appName, onlyForBrowser, oldHref) {
|
|
|
3586
3649
|
* create proxyHistory for microApp
|
|
3587
3650
|
* MDN https://developer.mozilla.org/en-US/docs/Web/API/History
|
|
3588
3651
|
* @param appName app name
|
|
3589
|
-
* @param microLocation microApp location
|
|
3652
|
+
* @param microLocation microApp location(with: proxyLocation iframe: iframeWindow.location)
|
|
3590
3653
|
*/
|
|
3591
3654
|
function createMicroHistory(appName, microLocation) {
|
|
3592
3655
|
const rawHistory = globalEnv.rawWindow.history;
|
|
@@ -3597,7 +3660,9 @@ function createMicroHistory(appName, microLocation) {
|
|
|
3597
3660
|
if (isString(rests[2]) || isURL(rests[2])) {
|
|
3598
3661
|
const targetLocation = createURL(rests[2], microLocation.href);
|
|
3599
3662
|
const targetFullPath = targetLocation.pathname + targetLocation.search + targetLocation.hash;
|
|
3600
|
-
|
|
3663
|
+
if (!isRouterModePure(appName)) {
|
|
3664
|
+
navigateWithNativeEvent(appName, methodName, setMicroPathToURL(appName, targetLocation), true, setMicroState(appName, rests[0]), rests[1]);
|
|
3665
|
+
}
|
|
3601
3666
|
if (targetFullPath !== microLocation.fullPath) {
|
|
3602
3667
|
updateMicroLocation(appName, targetFullPath, microLocation);
|
|
3603
3668
|
}
|
|
@@ -3676,10 +3741,10 @@ function navigateWithNativeEvent(appName, methodName, result, onlyForBrowser, st
|
|
|
3676
3741
|
nativeHistoryNavigate(appName, methodName, result.fullPath, state, title);
|
|
3677
3742
|
/**
|
|
3678
3743
|
* TODO:
|
|
3679
|
-
* 1. 如果所有模式统一发送popstate
|
|
3744
|
+
* 1. 如果所有模式统一发送popstate事件,则isRouterModeSearch(appName)要去掉
|
|
3680
3745
|
* 2. 如果发送事件,则会导致vue router-view :key='router.path'绑定,无限卸载应用,死循环
|
|
3681
3746
|
*/
|
|
3682
|
-
if (oldFullPath !== result.fullPath &&
|
|
3747
|
+
if (oldFullPath !== result.fullPath && isRouterModeSearch(appName)) {
|
|
3683
3748
|
dispatchNativeEvent(appName, onlyForBrowser, oldHref);
|
|
3684
3749
|
}
|
|
3685
3750
|
}
|
|
@@ -3726,7 +3791,7 @@ function reWriteHistoryMethod(method) {
|
|
|
3726
3791
|
excludeHiddenApp: true,
|
|
3727
3792
|
excludePreRender: true,
|
|
3728
3793
|
}).forEach(appName => {
|
|
3729
|
-
if (
|
|
3794
|
+
if (isRouterModeSearch(appName) && !getMicroPathFromURL(appName)) {
|
|
3730
3795
|
const app = appInstanceMap.get(appName);
|
|
3731
3796
|
attachRouteToBrowserURL(appName, setMicroPathToURL(appName, app.sandBox.proxyWindow.location), setMicroState(appName, getMicroState(appName)));
|
|
3732
3797
|
}
|
|
@@ -3778,8 +3843,10 @@ function createRouterApi() {
|
|
|
3778
3843
|
const currentFullPath = microLocation.pathname + microLocation.search + microLocation.hash;
|
|
3779
3844
|
const targetFullPath = targetLocation.pathname + targetLocation.search + targetLocation.hash;
|
|
3780
3845
|
if (currentFullPath !== targetFullPath || getMicroPathFromURL(appName) !== targetFullPath) {
|
|
3781
|
-
|
|
3782
|
-
|
|
3846
|
+
if (!isRouterModePure(appName)) {
|
|
3847
|
+
const methodName = (replace && to.replace !== false) || to.replace === true ? 'replaceState' : 'pushState';
|
|
3848
|
+
navigateWithRawHistory(appName, methodName, targetLocation, to.state);
|
|
3849
|
+
}
|
|
3783
3850
|
/**
|
|
3784
3851
|
* TODO:
|
|
3785
3852
|
* 1. 关闭虚拟路由的跳转地址不同:baseRoute + 子应用地址,文档中要说明
|
|
@@ -3792,7 +3859,7 @@ function createRouterApi() {
|
|
|
3792
3859
|
* NOTE1: history和search模式采用2,这样可以解决vue3的问题,custom采用1,避免vue循环刷新的问题,这样在用户出现问题时各有解决方案。但反过来说,每种方案又分别导致另外的问题,不统一,导致复杂度增高
|
|
3793
3860
|
* NOTE2: 关闭虚拟路由,同时发送popstate事件还是无法解决vue3的问题(毕竟history.state理论上还是会冲突),那么就没必要发送popstate事件了。
|
|
3794
3861
|
*/
|
|
3795
|
-
if (isRouterModeCustom(appName)) {
|
|
3862
|
+
if (isRouterModeCustom(appName) || isRouterModePure(appName)) {
|
|
3796
3863
|
updateMicroLocationWithEvent(appName, targetFullPath);
|
|
3797
3864
|
}
|
|
3798
3865
|
}
|
|
@@ -3807,52 +3874,53 @@ function createRouterApi() {
|
|
|
3807
3874
|
*/
|
|
3808
3875
|
function createNavigationMethod(replace) {
|
|
3809
3876
|
return function (to) {
|
|
3810
|
-
|
|
3811
|
-
|
|
3812
|
-
|
|
3813
|
-
|
|
3814
|
-
|
|
3815
|
-
|
|
3816
|
-
|
|
3817
|
-
|
|
3818
|
-
|
|
3819
|
-
|
|
3820
|
-
|
|
3821
|
-
|
|
3822
|
-
|
|
3823
|
-
|
|
3824
|
-
|
|
3825
|
-
|
|
3826
|
-
|
|
3827
|
-
|
|
3877
|
+
return new Promise((resolve, reject) => {
|
|
3878
|
+
const appName = formatAppName(to.name);
|
|
3879
|
+
if (appName && isString(to.path)) {
|
|
3880
|
+
/**
|
|
3881
|
+
* active apps, exclude prerender app or hidden keep-alive app
|
|
3882
|
+
* NOTE:
|
|
3883
|
+
* 1. prerender app or hidden keep-alive app clear and record popstate event, so we cannot control app jump through the API
|
|
3884
|
+
* 2. disable memory-router
|
|
3885
|
+
*/
|
|
3886
|
+
/**
|
|
3887
|
+
* TODO: 子应用开始渲染但是还没渲染完成
|
|
3888
|
+
* 1、调用跳转改如何处理
|
|
3889
|
+
* 2、iframe的沙箱还没初始化时执行跳转报错,如何处理。。。
|
|
3890
|
+
* 3、hidden app 是否支持跳转
|
|
3891
|
+
*/
|
|
3892
|
+
if (getActiveApps({ excludeHiddenApp: true, excludePreRender: true }).includes(appName)) {
|
|
3893
|
+
const app = appInstanceMap.get(appName);
|
|
3894
|
+
resolve(app.sandBox.sandboxReady.then(() => handleNavigate(appName, app, to, replace)));
|
|
3895
|
+
}
|
|
3896
|
+
else {
|
|
3897
|
+
reject(logError('navigation failed, app does not exist or is inactive'));
|
|
3898
|
+
}
|
|
3899
|
+
// /**
|
|
3900
|
+
// * app not exit or unmounted, update browser URL with replaceState
|
|
3901
|
+
// * use base app location.origin as baseURL
|
|
3902
|
+
// * 应用不存在或已卸载,依然使用replaceState来更新浏览器地址 -- 不合理
|
|
3903
|
+
// */
|
|
3904
|
+
// /**
|
|
3905
|
+
// * TODO: 应用还没渲染或已经卸载最好不要支持跳转了,我知道这是因为解决一些特殊场景,但这么做是非常反直觉的
|
|
3906
|
+
// * 并且在新版本中有多种路由模式,如果应用不存在,我们根本无法知道是哪种模式,那么这里的操作就无意义了。
|
|
3907
|
+
// */
|
|
3908
|
+
// const rawLocation = globalEnv.rawWindow.location
|
|
3909
|
+
// const targetLocation = createURL(to.path, rawLocation.origin)
|
|
3910
|
+
// const targetFullPath = targetLocation.pathname + targetLocation.search + targetLocation.hash
|
|
3911
|
+
// if (getMicroPathFromURL(appName) !== targetFullPath) {
|
|
3912
|
+
// navigateWithRawHistory(
|
|
3913
|
+
// appName,
|
|
3914
|
+
// to.replace === false ? 'pushState' : 'replaceState',
|
|
3915
|
+
// targetLocation,
|
|
3916
|
+
// to.state,
|
|
3917
|
+
// )
|
|
3918
|
+
// }
|
|
3828
3919
|
}
|
|
3829
3920
|
else {
|
|
3830
|
-
|
|
3921
|
+
reject(logError(`navigation failed, name & path are required when use router.${replace ? 'replace' : 'push'}`));
|
|
3831
3922
|
}
|
|
3832
|
-
|
|
3833
|
-
// * app not exit or unmounted, update browser URL with replaceState
|
|
3834
|
-
// * use base app location.origin as baseURL
|
|
3835
|
-
// * 应用不存在或已卸载,依然使用replaceState来更新浏览器地址 -- 不合理
|
|
3836
|
-
// */
|
|
3837
|
-
// /**
|
|
3838
|
-
// * TODO: 应用还没渲染或已经卸载最好不要支持跳转了,我知道这是因为解决一些特殊场景,但这么做是非常反直觉的
|
|
3839
|
-
// * 并且在新版本中有多种路由模式,如果应用不存在,我们根本无法知道是哪种模式,那么这里的操作就无意义了。
|
|
3840
|
-
// */
|
|
3841
|
-
// const rawLocation = globalEnv.rawWindow.location
|
|
3842
|
-
// const targetLocation = createURL(to.path, rawLocation.origin)
|
|
3843
|
-
// const targetFullPath = targetLocation.pathname + targetLocation.search + targetLocation.hash
|
|
3844
|
-
// if (getMicroPathFromURL(appName) !== targetFullPath) {
|
|
3845
|
-
// navigateWithRawHistory(
|
|
3846
|
-
// appName,
|
|
3847
|
-
// to.replace === false ? 'pushState' : 'replaceState',
|
|
3848
|
-
// targetLocation,
|
|
3849
|
-
// to.state,
|
|
3850
|
-
// )
|
|
3851
|
-
// }
|
|
3852
|
-
}
|
|
3853
|
-
else {
|
|
3854
|
-
logError(`navigation failed, name & path are required when use router.${replace ? 'replace' : 'push'}`);
|
|
3855
|
-
}
|
|
3923
|
+
});
|
|
3856
3924
|
};
|
|
3857
3925
|
}
|
|
3858
3926
|
// create method of router.go/back/forward
|
|
@@ -3909,7 +3977,7 @@ function createRouterApi() {
|
|
|
3909
3977
|
* 3. router mode is custom
|
|
3910
3978
|
*/
|
|
3911
3979
|
function commonHandlerForAttachToURL(appName) {
|
|
3912
|
-
if (
|
|
3980
|
+
if (isRouterModeSearch(appName)) {
|
|
3913
3981
|
const app = appInstanceMap.get(appName);
|
|
3914
3982
|
attachRouteToBrowserURL(appName, setMicroPathToURL(appName, app.sandBox.proxyWindow.location), setMicroState(appName, getMicroState(appName)));
|
|
3915
3983
|
}
|
|
@@ -4141,7 +4209,7 @@ function createMicroLocation(appName, url, microAppWindow, childStaticLocation,
|
|
|
4141
4209
|
if (targetLocation.origin === proxyLocation.origin) {
|
|
4142
4210
|
const setMicroPathResult = setMicroPathToURL(appName, targetLocation);
|
|
4143
4211
|
// if disable memory-router, navigate directly through rawLocation
|
|
4144
|
-
if (
|
|
4212
|
+
if (isRouterModeSearch(appName)) {
|
|
4145
4213
|
/**
|
|
4146
4214
|
* change hash with location.href will not trigger the browser reload
|
|
4147
4215
|
* so we use pushState & reload to imitate href behavior
|
|
@@ -4227,6 +4295,20 @@ function createMicroLocation(appName, url, microAppWindow, childStaticLocation,
|
|
|
4227
4295
|
const proxyLocation = new Proxy({}, {
|
|
4228
4296
|
get: (_, key) => {
|
|
4229
4297
|
const target = getTarget();
|
|
4298
|
+
if (key === 'assign')
|
|
4299
|
+
return assign;
|
|
4300
|
+
if (key === 'replace')
|
|
4301
|
+
return replace;
|
|
4302
|
+
if (key === 'reload')
|
|
4303
|
+
return reload;
|
|
4304
|
+
if (key === 'self')
|
|
4305
|
+
return target;
|
|
4306
|
+
if (key === 'fullPath')
|
|
4307
|
+
return target.fullPath;
|
|
4308
|
+
if (isRouterModeNative(appName)) {
|
|
4309
|
+
return bindFunctionToRawTarget(Reflect.get(rawLocation, key), rawLocation, 'LOCATION');
|
|
4310
|
+
}
|
|
4311
|
+
// src of iframe is base app address, it needs to be replaced separately
|
|
4230
4312
|
if (isIframe) {
|
|
4231
4313
|
// host hostname port protocol
|
|
4232
4314
|
if (hijackMicroLocationKeys.includes(key)) {
|
|
@@ -4237,29 +4319,21 @@ function createMicroLocation(appName, url, microAppWindow, childStaticLocation,
|
|
|
4237
4319
|
return target[key].replace(browserHost, childHost);
|
|
4238
4320
|
}
|
|
4239
4321
|
}
|
|
4240
|
-
if (key === 'assign')
|
|
4241
|
-
return assign;
|
|
4242
|
-
if (key === 'replace')
|
|
4243
|
-
return replace;
|
|
4244
|
-
if (key === 'reload')
|
|
4245
|
-
return reload;
|
|
4246
|
-
if (key === 'self')
|
|
4247
|
-
return target;
|
|
4248
4322
|
return bindFunctionToRawTarget(Reflect.get(target, key), target, 'LOCATION');
|
|
4249
4323
|
},
|
|
4250
4324
|
set: (_, key, value) => {
|
|
4251
4325
|
if (isEffectiveApp(appName)) {
|
|
4252
4326
|
const target = getTarget();
|
|
4253
4327
|
if (key === 'href') {
|
|
4254
|
-
const targetPath = commonHandler(value, 'pushState');
|
|
4255
4328
|
/**
|
|
4256
4329
|
* In vite, targetPath without origin will be completed with child origin
|
|
4257
4330
|
* So we use browser origin to complete targetPath to avoid this problem
|
|
4258
|
-
*
|
|
4259
|
-
*
|
|
4260
|
-
*
|
|
4261
|
-
*
|
|
4331
|
+
* NOTE:
|
|
4332
|
+
* 1. history mode & value is childOrigin + path ==> jump to browserOrigin + path
|
|
4333
|
+
* 2. disable mode & value is childOrigin + path ==> jump to childOrigin + path
|
|
4334
|
+
* 3. search mode & value is browserOrigin + path ==> jump to browserOrigin + path
|
|
4262
4335
|
*/
|
|
4336
|
+
const targetPath = commonHandler(value, 'pushState');
|
|
4263
4337
|
if (targetPath) {
|
|
4264
4338
|
rawLocation.href = createURL(targetPath, rawLocation.origin).href;
|
|
4265
4339
|
}
|
|
@@ -4344,9 +4418,11 @@ function updateMicroLocation(appName, path, microLocation, type) {
|
|
|
4344
4418
|
(_a = microAppWindow.rawReplaceState) === null || _a === void 0 ? void 0 : _a.call(microAppWindow.history, getMicroState(appName), '', newLocation.href);
|
|
4345
4419
|
}
|
|
4346
4420
|
else {
|
|
4347
|
-
|
|
4348
|
-
|
|
4421
|
+
let targetHref = newLocation.href;
|
|
4422
|
+
if (microLocation.self.origin !== newLocation.origin) {
|
|
4423
|
+
targetHref = targetHref.replace(newLocation.origin, microLocation.self.origin);
|
|
4349
4424
|
}
|
|
4425
|
+
microLocation.self.href = targetHref;
|
|
4350
4426
|
}
|
|
4351
4427
|
// update latest values of microLocation to `to`
|
|
4352
4428
|
const to = createGuardLocation(appName, microLocation);
|
|
@@ -4357,13 +4433,9 @@ function updateMicroLocation(appName, path, microLocation, type) {
|
|
|
4357
4433
|
}
|
|
4358
4434
|
|
|
4359
4435
|
/**
|
|
4360
|
-
* TODO:
|
|
4361
|
-
* 1.
|
|
4362
|
-
* 2.
|
|
4363
|
-
* 3. keep-router-state功能失效,因为始终为true
|
|
4364
|
-
* 4. 基座控制子应用跳转地址改变,正确的值为:baseRoute + 子应用地址,这要在文档中说明,否则很容易出错,确实也很难理解
|
|
4365
|
-
* 5. 是否需要发送popstate事件,为了减小对基座的影响,现在不发送
|
|
4366
|
-
* 6. 关闭后导致的vue3路由冲突问题需要在文档中明确指出(2处:在关闭虚拟路由系统的配置那里着重说明,在vue常见问题中说明)
|
|
4436
|
+
* TODO: 关于关闭虚拟路由系统的custom、history模式
|
|
4437
|
+
* 1. 是否需要发送popstate事件,为了减小对基座的影响,现在不发送
|
|
4438
|
+
* 2. 关闭后导致的vue3路由冲突问题需要在文档中明确指出(2处:在关闭虚拟路由系统的配置那里着重说明,在vue常见问题中说明)
|
|
4367
4439
|
*/
|
|
4368
4440
|
/**
|
|
4369
4441
|
* The router system has two operations: read and write
|
|
@@ -4404,8 +4476,10 @@ function updateBrowserURLWithLocation(appName, microLocation, defaultPage) {
|
|
|
4404
4476
|
// update microLocation with defaultPage
|
|
4405
4477
|
if (defaultPage)
|
|
4406
4478
|
updateMicroLocation(appName, defaultPage, microLocation, 'prevent');
|
|
4407
|
-
|
|
4408
|
-
|
|
4479
|
+
if (!isRouterModePure(appName)) {
|
|
4480
|
+
// attach microApp route info to browser URL
|
|
4481
|
+
attachRouteToBrowserURL(appName, setMicroPathToURL(appName, microLocation), setMicroState(appName, null));
|
|
4482
|
+
}
|
|
4409
4483
|
// trigger guards after change browser URL
|
|
4410
4484
|
autoTriggerNavigationGuard(appName, microLocation);
|
|
4411
4485
|
}
|
|
@@ -4422,7 +4496,9 @@ function clearRouteStateFromURL(appName, url, microLocation, keepRouteState) {
|
|
|
4422
4496
|
const { pathname, search, hash } = createURL(url);
|
|
4423
4497
|
updateMicroLocation(appName, pathname + search + hash, microLocation, 'prevent');
|
|
4424
4498
|
}
|
|
4425
|
-
|
|
4499
|
+
if (!isRouterModePure(appName)) {
|
|
4500
|
+
removePathFromBrowser(appName);
|
|
4501
|
+
}
|
|
4426
4502
|
}
|
|
4427
4503
|
clearRouterWhenUnmount(appName);
|
|
4428
4504
|
}
|
|
@@ -4434,10 +4510,10 @@ function removePathFromBrowser(appName) {
|
|
|
4434
4510
|
attachRouteToBrowserURL(appName, removeMicroPathFromURL(appName), removeMicroState(appName, globalEnv.rawWindow.history.state));
|
|
4435
4511
|
}
|
|
4436
4512
|
|
|
4437
|
-
class
|
|
4513
|
+
class BaseSandbox {
|
|
4438
4514
|
constructor() {
|
|
4439
4515
|
// keys that can only assigned to rawWindow
|
|
4440
|
-
this.
|
|
4516
|
+
this.rawWindowScopeKeyList = [
|
|
4441
4517
|
'location',
|
|
4442
4518
|
];
|
|
4443
4519
|
// keys that can escape to rawWindow
|
|
@@ -4450,7 +4526,18 @@ class Adapter {
|
|
|
4450
4526
|
'webpackJsonp',
|
|
4451
4527
|
'webpackHotUpdate',
|
|
4452
4528
|
'Vue',
|
|
4529
|
+
// TODO: 是否可以和constants/SCOPE_WINDOW_ON_EVENT合并
|
|
4530
|
+
'onpopstate',
|
|
4531
|
+
'onhashchange',
|
|
4453
4532
|
];
|
|
4533
|
+
// Properties that can only get and set in microAppWindow, will not escape to rawWindow
|
|
4534
|
+
this.scopeProperties = Array.from(this.staticScopeProperties);
|
|
4535
|
+
// Properties that can be escape to rawWindow
|
|
4536
|
+
this.escapeProperties = [];
|
|
4537
|
+
// Properties newly added to microAppWindow
|
|
4538
|
+
this.injectedKeys = new Set();
|
|
4539
|
+
// Properties escape to rawWindow, cleared when unmount
|
|
4540
|
+
this.escapeKeys = new Set();
|
|
4454
4541
|
this.injectReactHMRProperty();
|
|
4455
4542
|
}
|
|
4456
4543
|
// adapter for react
|
|
@@ -4468,6 +4555,14 @@ class Adapter {
|
|
|
4468
4555
|
}
|
|
4469
4556
|
}
|
|
4470
4557
|
}
|
|
4558
|
+
/**
|
|
4559
|
+
* TODO:
|
|
4560
|
+
* 1、将class Adapter去掉,改为CustomWindow,或者让CustomWindow继承Adapter
|
|
4561
|
+
* 2、with沙箱中的常量放入CustomWindow,虽然和iframe沙箱不一致,但更合理
|
|
4562
|
+
* 修改时机:在iframe沙箱支持插件后再修改
|
|
4563
|
+
*/
|
|
4564
|
+
class CustomWindow {
|
|
4565
|
+
}
|
|
4471
4566
|
// Fix conflict of babel-polyfill@6.x
|
|
4472
4567
|
function fixBabelPolyfill6() {
|
|
4473
4568
|
if (globalEnv.rawWindow._babelPolyfill)
|
|
@@ -4522,11 +4617,11 @@ function updateElementInfo(node, appName) {
|
|
|
4522
4617
|
* 1. 测试baseURI和ownerDocument在with沙箱中是否正确
|
|
4523
4618
|
* 经过验证with沙箱不能重写ownerDocument,否则react点击事件会触发两次
|
|
4524
4619
|
* 2. with沙箱所有node设置__MICRO_APP_NAME__都使用updateElementInfo
|
|
4525
|
-
* 3. 性能: defineProperty的性能肯定不如直接设置
|
|
4526
4620
|
*/
|
|
4527
4621
|
rawDefineProperties(node, {
|
|
4528
4622
|
baseURI: {
|
|
4529
4623
|
configurable: true,
|
|
4624
|
+
// if disable-memory-router or router-mode='disable', href point to base app
|
|
4530
4625
|
get: () => proxyWindow.location.href,
|
|
4531
4626
|
},
|
|
4532
4627
|
__MICRO_APP_NAME__: {
|
|
@@ -4535,12 +4630,6 @@ function updateElementInfo(node, appName) {
|
|
|
4535
4630
|
value: appName,
|
|
4536
4631
|
},
|
|
4537
4632
|
});
|
|
4538
|
-
if (isIframeSandbox(appName)) {
|
|
4539
|
-
rawDefineProperty(node, 'ownerDocument', {
|
|
4540
|
-
configurable: true,
|
|
4541
|
-
get: () => proxyWindow.document,
|
|
4542
|
-
});
|
|
4543
|
-
}
|
|
4544
4633
|
}
|
|
4545
4634
|
return node;
|
|
4546
4635
|
}
|
|
@@ -4647,32 +4736,26 @@ function useMicroEventSource() {
|
|
|
4647
4736
|
}
|
|
4648
4737
|
|
|
4649
4738
|
const { createMicroEventSource, clearMicroEventSource } = useMicroEventSource();
|
|
4650
|
-
class WithSandBox {
|
|
4739
|
+
class WithSandBox extends BaseSandbox {
|
|
4651
4740
|
constructor(appName, url) {
|
|
4741
|
+
super();
|
|
4652
4742
|
this.active = false;
|
|
4653
|
-
|
|
4654
|
-
|
|
4655
|
-
|
|
4656
|
-
|
|
4657
|
-
|
|
4658
|
-
|
|
4659
|
-
|
|
4660
|
-
|
|
4661
|
-
|
|
4662
|
-
|
|
4663
|
-
|
|
4664
|
-
|
|
4665
|
-
|
|
4666
|
-
|
|
4667
|
-
|
|
4668
|
-
|
|
4669
|
-
this.patchRouter(appName, url, this.microAppWindow);
|
|
4670
|
-
// patch window of child app
|
|
4671
|
-
this.windowEffect = patchWindow(appName, this.microAppWindow, this);
|
|
4672
|
-
// patch document of child app
|
|
4673
|
-
this.documentEffect = patchDocument(appName, this.microAppWindow, this);
|
|
4674
|
-
// inject global properties
|
|
4675
|
-
this.initStaticGlobalKeys(appName, url, this.microAppWindow);
|
|
4743
|
+
this.microAppWindow = new CustomWindow(); // Proxy target
|
|
4744
|
+
this.patchWith((resolve) => {
|
|
4745
|
+
// get scopeProperties and escapeProperties from plugins
|
|
4746
|
+
this.getSpecialProperties(appName);
|
|
4747
|
+
// create location, history for child app
|
|
4748
|
+
this.patchRouter(appName, url, this.microAppWindow);
|
|
4749
|
+
// patch window of child app
|
|
4750
|
+
this.windowEffect = patchWindow(appName, this.microAppWindow, this);
|
|
4751
|
+
// patch document of child app
|
|
4752
|
+
this.documentEffect = patchDocument(appName, this.microAppWindow, this);
|
|
4753
|
+
// properties associated with the native window
|
|
4754
|
+
this.setMappingPropertiesWithRawDescriptor(this.microAppWindow);
|
|
4755
|
+
// inject global properties
|
|
4756
|
+
this.initStaticGlobalKeys(appName, url, this.microAppWindow);
|
|
4757
|
+
resolve();
|
|
4758
|
+
});
|
|
4676
4759
|
}
|
|
4677
4760
|
/**
|
|
4678
4761
|
* open sandbox and perform some initial actions
|
|
@@ -4690,7 +4773,9 @@ class WithSandBox {
|
|
|
4690
4773
|
this.initRouteState(defaultPage);
|
|
4691
4774
|
// unique listener of popstate event for sub app
|
|
4692
4775
|
this.removeHistoryListener = addHistoryListener(this.microAppWindow.__MICRO_APP_NAME__);
|
|
4693
|
-
|
|
4776
|
+
if (isRouterModeCustom(this.microAppWindow.__MICRO_APP_NAME__)) {
|
|
4777
|
+
this.microAppWindow.__MICRO_APP_BASE_ROUTE__ = this.microAppWindow.__MICRO_APP_BASE_URL__ = baseroute;
|
|
4778
|
+
}
|
|
4694
4779
|
/* --- memory router part --- end */
|
|
4695
4780
|
/**
|
|
4696
4781
|
* Target: Ensure default mode action exactly same to first time when render again
|
|
@@ -4755,6 +4840,7 @@ class WithSandBox {
|
|
|
4755
4840
|
}
|
|
4756
4841
|
/**
|
|
4757
4842
|
* inject global properties to microAppWindow
|
|
4843
|
+
* TODO: 设置为只读变量
|
|
4758
4844
|
* @param appName app name
|
|
4759
4845
|
* @param url app url
|
|
4760
4846
|
* @param microAppWindow micro window
|
|
@@ -4768,6 +4854,7 @@ class WithSandBox {
|
|
|
4768
4854
|
microAppWindow.__MICRO_APP_WINDOW__ = microAppWindow;
|
|
4769
4855
|
microAppWindow.__MICRO_APP_PRE_RENDER__ = false;
|
|
4770
4856
|
microAppWindow.__MICRO_APP_UMD_MODE__ = false;
|
|
4857
|
+
microAppWindow.__MICRO_APP_PROXY_WINDOW__ = this.proxyWindow;
|
|
4771
4858
|
microAppWindow.__MICRO_APP_SANDBOX__ = this;
|
|
4772
4859
|
microAppWindow.__MICRO_APP_SANDBOX_TYPE__ = 'with';
|
|
4773
4860
|
microAppWindow.rawWindow = globalEnv.rawWindow;
|
|
@@ -4777,7 +4864,6 @@ class WithSandBox {
|
|
|
4777
4864
|
pureCreateElement,
|
|
4778
4865
|
router,
|
|
4779
4866
|
});
|
|
4780
|
-
this.setMappingPropertiesWithRawDescriptor(microAppWindow);
|
|
4781
4867
|
}
|
|
4782
4868
|
/**
|
|
4783
4869
|
* Record global effect and then release (effect: global event, timeout, data listener)
|
|
@@ -4860,7 +4946,6 @@ class WithSandBox {
|
|
|
4860
4946
|
*/
|
|
4861
4947
|
getSpecialProperties(appName) {
|
|
4862
4948
|
var _a;
|
|
4863
|
-
this.scopeProperties = this.scopeProperties.concat(this.adapter.staticScopeProperties);
|
|
4864
4949
|
if (isPlainObject(microApp.options.plugins)) {
|
|
4865
4950
|
this.commonActionForSpecialProperties(microApp.options.plugins.global);
|
|
4866
4951
|
this.commonActionForSpecialProperties((_a = microApp.options.plugins.modules) === null || _a === void 0 ? void 0 : _a[appName]);
|
|
@@ -4888,6 +4973,9 @@ class WithSandBox {
|
|
|
4888
4973
|
markUmdMode(state) {
|
|
4889
4974
|
this.microAppWindow.__MICRO_APP_UMD_MODE__ = state;
|
|
4890
4975
|
}
|
|
4976
|
+
patchWith(cb) {
|
|
4977
|
+
this.sandboxReady = new Promise((resolve) => cb(resolve));
|
|
4978
|
+
}
|
|
4891
4979
|
// properties associated with the native window
|
|
4892
4980
|
setMappingPropertiesWithRawDescriptor(microAppWindow) {
|
|
4893
4981
|
let topValue, parentValue;
|
|
@@ -4899,9 +4987,10 @@ class WithSandBox {
|
|
|
4899
4987
|
topValue = rawWindow.top;
|
|
4900
4988
|
parentValue = rawWindow.parent;
|
|
4901
4989
|
}
|
|
4902
|
-
|
|
4903
|
-
|
|
4904
|
-
|
|
4990
|
+
rawDefineProperties(microAppWindow, {
|
|
4991
|
+
top: this.createDescriptorForMicroAppWindow('top', topValue),
|
|
4992
|
+
parent: this.createDescriptorForMicroAppWindow('parent', parentValue),
|
|
4993
|
+
});
|
|
4905
4994
|
GLOBAL_KEY_TO_WINDOW.forEach((key) => {
|
|
4906
4995
|
rawDefineProperty(microAppWindow, key, this.createDescriptorForMicroAppWindow(key, this.proxyWindow));
|
|
4907
4996
|
});
|
|
@@ -5059,11 +5148,14 @@ class WithSandBox {
|
|
|
5059
5148
|
actionBeforeExecScripts(container) {
|
|
5060
5149
|
this.patchStaticElement(container);
|
|
5061
5150
|
}
|
|
5151
|
+
setStaticAppState(state) {
|
|
5152
|
+
this.microAppWindow.__MICRO_APP_STATE__ = state;
|
|
5153
|
+
}
|
|
5062
5154
|
}
|
|
5063
5155
|
WithSandBox.activeCount = 0; // number of active sandbox
|
|
5064
5156
|
|
|
5065
5157
|
function patchRouter(appName, url, microAppWindow, browserHost) {
|
|
5066
|
-
const childStaticLocation =
|
|
5158
|
+
const childStaticLocation = createURL(url);
|
|
5067
5159
|
const childHost = childStaticLocation.protocol + '//' + childStaticLocation.host;
|
|
5068
5160
|
const childFullPath = childStaticLocation.pathname + childStaticLocation.search + childStaticLocation.hash;
|
|
5069
5161
|
// rewrite microAppWindow.history
|
|
@@ -5156,18 +5248,35 @@ function patchWindowProperty$1(appName, microAppWindow) {
|
|
|
5156
5248
|
*/
|
|
5157
5249
|
function createProxyWindow$1(microAppWindow, sandbox) {
|
|
5158
5250
|
const rawWindow = globalEnv.rawWindow;
|
|
5159
|
-
const customProperties =
|
|
5251
|
+
const customProperties = new Set();
|
|
5252
|
+
/**
|
|
5253
|
+
* proxyWindow will only take effect in certain scenes, such as window.key
|
|
5254
|
+
* e.g:
|
|
5255
|
+
* 1. window.key in normal app --> fall into proxyWindow
|
|
5256
|
+
* 2. window.key in module app(vite), fall into microAppWindow(iframeWindow)
|
|
5257
|
+
* 3. if (key)... --> fall into microAppWindow(iframeWindow)
|
|
5258
|
+
*/
|
|
5160
5259
|
const proxyWindow = new Proxy(microAppWindow, {
|
|
5161
5260
|
get: (target, key) => {
|
|
5162
5261
|
if (key === 'location') {
|
|
5163
5262
|
return sandbox.proxyLocation;
|
|
5164
5263
|
}
|
|
5165
|
-
if (
|
|
5264
|
+
if (includes(GLOBAL_KEY_TO_WINDOW, key)) {
|
|
5166
5265
|
return proxyWindow;
|
|
5167
5266
|
}
|
|
5168
|
-
if (customProperties.
|
|
5267
|
+
if (customProperties.has(key)) {
|
|
5169
5268
|
return Reflect.get(target, key);
|
|
5170
5269
|
}
|
|
5270
|
+
/**
|
|
5271
|
+
* Same as proxyWindow, escapeProperties will only take effect in certain scenes
|
|
5272
|
+
* e.g:
|
|
5273
|
+
* 1. window.key in normal app --> fall into proxyWindow, escapeProperties will effect
|
|
5274
|
+
* 2. window.key in module app(vite), fall into microAppWindow(iframeWindow), escapeProperties will not take effect
|
|
5275
|
+
* 3. if (key)... --> fall into microAppWindow(iframeWindow), escapeProperties will not take effect
|
|
5276
|
+
*/
|
|
5277
|
+
if (includes(sandbox.escapeProperties, key) && !Reflect.has(target, key)) {
|
|
5278
|
+
return bindFunctionToRawTarget(Reflect.get(rawWindow, key), rawWindow);
|
|
5279
|
+
}
|
|
5171
5280
|
return bindFunctionToRawTarget(Reflect.get(target, key), target);
|
|
5172
5281
|
},
|
|
5173
5282
|
set: (target, key, value) => {
|
|
@@ -5175,10 +5284,10 @@ function createProxyWindow$1(microAppWindow, sandbox) {
|
|
|
5175
5284
|
return Reflect.set(rawWindow, key, value);
|
|
5176
5285
|
}
|
|
5177
5286
|
if (!Reflect.has(target, key)) {
|
|
5178
|
-
customProperties.
|
|
5287
|
+
customProperties.add(key);
|
|
5179
5288
|
}
|
|
5180
5289
|
Reflect.set(target, key, value);
|
|
5181
|
-
if (sandbox.escapeProperties
|
|
5290
|
+
if (includes(sandbox.escapeProperties, key)) {
|
|
5182
5291
|
!Reflect.has(rawWindow, key) && sandbox.escapeKeys.add(key);
|
|
5183
5292
|
Reflect.set(rawWindow, key, value);
|
|
5184
5293
|
}
|
|
@@ -5293,7 +5402,9 @@ function patchDocumentPrototype(appName, microAppWindow) {
|
|
|
5293
5402
|
const microRootDocument = microAppWindow.Document;
|
|
5294
5403
|
const microDocument = microAppWindow.document;
|
|
5295
5404
|
const rawMicroCreateElement = microRootDocument.prototype.createElement;
|
|
5405
|
+
const rawMicroCreateElementNS = microRootDocument.prototype.createElementNS;
|
|
5296
5406
|
const rawMicroCreateTextNode = microRootDocument.prototype.createTextNode;
|
|
5407
|
+
const rawMicroCreateDocumentFragment = microRootDocument.prototype.createDocumentFragment;
|
|
5297
5408
|
const rawMicroCreateComment = microRootDocument.prototype.createComment;
|
|
5298
5409
|
const rawMicroQuerySelector = microRootDocument.prototype.querySelector;
|
|
5299
5410
|
const rawMicroQuerySelectorAll = microRootDocument.prototype.querySelectorAll;
|
|
@@ -5314,10 +5425,18 @@ function patchDocumentPrototype(appName, microAppWindow) {
|
|
|
5314
5425
|
const element = rawMicroCreateElement.call(this, tagName, options);
|
|
5315
5426
|
return updateElementInfo(element, appName);
|
|
5316
5427
|
};
|
|
5428
|
+
microRootDocument.prototype.createElementNS = function createElementNS(namespaceURI, name, options) {
|
|
5429
|
+
const element = rawMicroCreateElementNS.call(this, namespaceURI, name, options);
|
|
5430
|
+
return updateElementInfo(element, appName);
|
|
5431
|
+
};
|
|
5317
5432
|
microRootDocument.prototype.createTextNode = function createTextNode(data) {
|
|
5318
5433
|
const element = rawMicroCreateTextNode.call(this, data);
|
|
5319
5434
|
return updateElementInfo(element, appName);
|
|
5320
5435
|
};
|
|
5436
|
+
microRootDocument.prototype.createDocumentFragment = function createDocumentFragment() {
|
|
5437
|
+
const element = rawMicroCreateDocumentFragment.call(this);
|
|
5438
|
+
return updateElementInfo(element, appName);
|
|
5439
|
+
};
|
|
5321
5440
|
microRootDocument.prototype.createComment = function createComment(data) {
|
|
5322
5441
|
const element = rawMicroCreateComment.call(this, data);
|
|
5323
5442
|
return updateElementInfo(element, appName);
|
|
@@ -5418,6 +5537,7 @@ function patchDocumentProperty(appName, microAppWindow, sandbox) {
|
|
|
5418
5537
|
const createDescriptors = () => {
|
|
5419
5538
|
const result = {};
|
|
5420
5539
|
const descList = [
|
|
5540
|
+
// if disable-memory-router or router-mode='disable', href point to base app
|
|
5421
5541
|
['documentURI', () => sandbox.proxyLocation.href],
|
|
5422
5542
|
['URL', () => sandbox.proxyLocation.href],
|
|
5423
5543
|
['documentElement', () => rawDocument.documentElement],
|
|
@@ -5454,7 +5574,10 @@ function patchDocumentProperty(appName, microAppWindow, sandbox) {
|
|
|
5454
5574
|
rawDefineProperty(microDocument, tagName, {
|
|
5455
5575
|
enumerable: true,
|
|
5456
5576
|
configurable: true,
|
|
5457
|
-
get: () =>
|
|
5577
|
+
get: () => {
|
|
5578
|
+
throttleDeferForSetAppName(appName);
|
|
5579
|
+
return rawDocument[tagName];
|
|
5580
|
+
},
|
|
5458
5581
|
set: (value) => { rawDocument[tagName] = value; },
|
|
5459
5582
|
});
|
|
5460
5583
|
});
|
|
@@ -5626,7 +5749,8 @@ function patchIframeNode(appName, microAppWindow, sandbox) {
|
|
|
5626
5749
|
const rawMicroInsertAdjacentElement = microRootElement.prototype.insertAdjacentElement;
|
|
5627
5750
|
const rawMicroCloneNode = microRootNode.prototype.cloneNode;
|
|
5628
5751
|
const rawInnerHTMLDesc = Object.getOwnPropertyDescriptor(microRootElement.prototype, 'innerHTML');
|
|
5629
|
-
const
|
|
5752
|
+
const rawParentNodeDesc = Object.getOwnPropertyDescriptor(microRootNode.prototype, 'parentNode');
|
|
5753
|
+
const rawOwnerDocumentDesc = Object.getOwnPropertyDescriptor(microRootNode.prototype, 'ownerDocument');
|
|
5630
5754
|
const isPureNode = (target) => {
|
|
5631
5755
|
return (isScriptElement(target) || isBaseElement(target)) && target.__PURE_ELEMENT__;
|
|
5632
5756
|
};
|
|
@@ -5647,6 +5771,7 @@ function patchIframeNode(appName, microAppWindow, sandbox) {
|
|
|
5647
5771
|
// return rootNode
|
|
5648
5772
|
};
|
|
5649
5773
|
microRootNode.prototype.appendChild = function appendChild(node) {
|
|
5774
|
+
// TODO: 有必要执行这么多次updateElementInfo?
|
|
5650
5775
|
updateElementInfo(node, appName);
|
|
5651
5776
|
if (isPureNode(node)) {
|
|
5652
5777
|
return rawMicroAppendChild.call(this, node);
|
|
@@ -5718,6 +5843,15 @@ function patchIframeNode(appName, microAppWindow, sandbox) {
|
|
|
5718
5843
|
const clonedNode = rawMicroCloneNode.call(this, deep);
|
|
5719
5844
|
return updateElementInfo(clonedNode, appName);
|
|
5720
5845
|
};
|
|
5846
|
+
rawDefineProperty(microRootNode.prototype, 'ownerDocument', {
|
|
5847
|
+
configurable: true,
|
|
5848
|
+
enumerable: true,
|
|
5849
|
+
get() {
|
|
5850
|
+
return this.__PURE_ELEMENT__
|
|
5851
|
+
? rawOwnerDocumentDesc.get.call(this)
|
|
5852
|
+
: microDocument;
|
|
5853
|
+
},
|
|
5854
|
+
});
|
|
5721
5855
|
rawDefineProperty(microRootElement.prototype, 'innerHTML', {
|
|
5722
5856
|
configurable: true,
|
|
5723
5857
|
enumerable: true,
|
|
@@ -5745,21 +5879,21 @@ function patchIframeNode(appName, microAppWindow, sandbox) {
|
|
|
5745
5879
|
* 1. Is there a problem with setting the current appName in iframe mode
|
|
5746
5880
|
*/
|
|
5747
5881
|
throttleDeferForSetAppName(appName);
|
|
5748
|
-
const result =
|
|
5882
|
+
const result = rawParentNodeDesc.get.call(this);
|
|
5749
5883
|
/**
|
|
5750
|
-
|
|
5751
|
-
|
|
5752
|
-
|
|
5753
|
-
|
|
5754
|
-
|
|
5755
|
-
|
|
5756
|
-
|
|
5757
|
-
|
|
5884
|
+
* If parentNode is <micro-app-body>, return rawDocument.body
|
|
5885
|
+
* Scenes:
|
|
5886
|
+
* 1. element-ui@2/lib/utils/vue-popper.js
|
|
5887
|
+
* if (this.popperElm.parentNode === document.body) ...
|
|
5888
|
+
* WARNING:
|
|
5889
|
+
* Will it cause other problems ?
|
|
5890
|
+
* e.g. target.parentNode.remove(target)
|
|
5891
|
+
*/
|
|
5758
5892
|
if (isMicroAppBody(result) && ((_a = appInstanceMap.get(appName)) === null || _a === void 0 ? void 0 : _a.container)) {
|
|
5759
|
-
return ((_c = (_b = microApp.options).getRootElementParentNode) === null || _c === void 0 ? void 0 : _c.call(_b, this, appName)) || rawDocument.body;
|
|
5893
|
+
return ((_c = (_b = microApp.options).getRootElementParentNode) === null || _c === void 0 ? void 0 : _c.call(_b, this, appName)) || globalEnv.rawDocument.body;
|
|
5760
5894
|
}
|
|
5761
5895
|
return result;
|
|
5762
|
-
}
|
|
5896
|
+
}
|
|
5763
5897
|
});
|
|
5764
5898
|
// Adapt to new image(...) scene
|
|
5765
5899
|
const ImageProxy = new Proxy(microAppWindow.Image, {
|
|
@@ -5821,14 +5955,17 @@ class IframeSandbox {
|
|
|
5821
5955
|
this.escapeProperties = [];
|
|
5822
5956
|
// Properties escape to rawWindow, cleared when unmount
|
|
5823
5957
|
this.escapeKeys = new Set();
|
|
5824
|
-
//
|
|
5958
|
+
// 初始化和每次跳转时都要更新base的href
|
|
5825
5959
|
this.updateIframeBase = () => {
|
|
5826
5960
|
var _a;
|
|
5827
|
-
|
|
5961
|
+
// origin must be child app origin
|
|
5962
|
+
(_a = this.baseElement) === null || _a === void 0 ? void 0 : _a.setAttribute('href', createURL(this.url).origin + this.proxyLocation.pathname);
|
|
5828
5963
|
};
|
|
5964
|
+
this.appName = appName;
|
|
5965
|
+
this.url = url;
|
|
5829
5966
|
const rawLocation = globalEnv.rawWindow.location;
|
|
5830
5967
|
const browserHost = rawLocation.protocol + '//' + rawLocation.host;
|
|
5831
|
-
this.deleteIframeElement = this.createIframeElement(appName, browserHost);
|
|
5968
|
+
this.deleteIframeElement = this.createIframeElement(appName, browserHost + rawLocation.pathname);
|
|
5832
5969
|
this.microAppWindow = this.iframe.contentWindow;
|
|
5833
5970
|
this.patchIframe(this.microAppWindow, (resolve) => {
|
|
5834
5971
|
// create new html to iframe
|
|
@@ -5856,13 +5993,13 @@ class IframeSandbox {
|
|
|
5856
5993
|
/**
|
|
5857
5994
|
* create iframe for sandbox
|
|
5858
5995
|
* @param appName app name
|
|
5859
|
-
* @param
|
|
5996
|
+
* @param browserPath browser origin
|
|
5860
5997
|
* @returns release callback
|
|
5861
5998
|
*/
|
|
5862
|
-
createIframeElement(appName,
|
|
5999
|
+
createIframeElement(appName, browserPath) {
|
|
5863
6000
|
this.iframe = pureCreateElement('iframe');
|
|
5864
6001
|
const iframeAttrs = {
|
|
5865
|
-
src:
|
|
6002
|
+
src: microApp.options.iframeSrc || browserPath,
|
|
5866
6003
|
style: 'display: none',
|
|
5867
6004
|
id: appName,
|
|
5868
6005
|
};
|
|
@@ -5910,7 +6047,9 @@ class IframeSandbox {
|
|
|
5910
6047
|
this.initRouteState(defaultPage);
|
|
5911
6048
|
// unique listener of popstate event for child app
|
|
5912
6049
|
this.removeHistoryListener = addHistoryListener(this.microAppWindow.__MICRO_APP_NAME__);
|
|
5913
|
-
|
|
6050
|
+
if (isRouterModeCustom(this.microAppWindow.__MICRO_APP_NAME__)) {
|
|
6051
|
+
this.microAppWindow.__MICRO_APP_BASE_ROUTE__ = this.microAppWindow.__MICRO_APP_BASE_URL__ = baseroute;
|
|
6052
|
+
}
|
|
5914
6053
|
/* --- memory router part --- end */
|
|
5915
6054
|
/**
|
|
5916
6055
|
* create base element to iframe
|
|
@@ -5955,6 +6094,7 @@ class IframeSandbox {
|
|
|
5955
6094
|
* NOTE:
|
|
5956
6095
|
* 1. execute as early as possible
|
|
5957
6096
|
* 2. run after patchRouter & createProxyWindow
|
|
6097
|
+
* TODO: 设置为只读变量
|
|
5958
6098
|
*/
|
|
5959
6099
|
initStaticGlobalKeys(appName, url, microAppWindow) {
|
|
5960
6100
|
microAppWindow.__MICRO_APP_ENVIRONMENT__ = true;
|
|
@@ -6156,6 +6296,7 @@ class IframeSandbox {
|
|
|
6156
6296
|
patchElementTree(container, this.microAppWindow.__MICRO_APP_NAME__);
|
|
6157
6297
|
}
|
|
6158
6298
|
/**
|
|
6299
|
+
* action before exec scripts when mount
|
|
6159
6300
|
* Actions:
|
|
6160
6301
|
* 1. patch static elements from html
|
|
6161
6302
|
* @param container micro app container
|
|
@@ -6163,6 +6304,9 @@ class IframeSandbox {
|
|
|
6163
6304
|
actionBeforeExecScripts(container) {
|
|
6164
6305
|
this.patchStaticElement(container);
|
|
6165
6306
|
}
|
|
6307
|
+
setStaticAppState(state) {
|
|
6308
|
+
this.microAppWindow.__MICRO_APP_STATE__ = state;
|
|
6309
|
+
}
|
|
6166
6310
|
}
|
|
6167
6311
|
IframeSandbox.activeCount = 0; // number of active sandbox
|
|
6168
6312
|
|
|
@@ -6175,6 +6319,7 @@ class CreateApp {
|
|
|
6175
6319
|
this.loadSourceLevel = 0;
|
|
6176
6320
|
this.umdHookMount = null;
|
|
6177
6321
|
this.umdHookUnmount = null;
|
|
6322
|
+
this.lifeCycleState = null;
|
|
6178
6323
|
this.umdMode = false;
|
|
6179
6324
|
// TODO: 类型优化,加上iframe沙箱
|
|
6180
6325
|
this.sandBox = null;
|
|
@@ -6211,8 +6356,11 @@ class CreateApp {
|
|
|
6211
6356
|
}
|
|
6212
6357
|
/**
|
|
6213
6358
|
* When resource is loaded, mount app if it is not prefetch or unmount
|
|
6359
|
+
* defaultPage disablePatchRequest routerMode baseroute is only for prerender app
|
|
6214
6360
|
*/
|
|
6215
|
-
onLoad(html,
|
|
6361
|
+
onLoad({ html,
|
|
6362
|
+
// below params is only for prerender app
|
|
6363
|
+
defaultPage, routerMode, baseroute, disablePatchRequest, }) {
|
|
6216
6364
|
var _a;
|
|
6217
6365
|
if (++this.loadSourceLevel === 2) {
|
|
6218
6366
|
this.source.html = html;
|
|
@@ -6243,11 +6391,11 @@ class CreateApp {
|
|
|
6243
6391
|
this.mount({
|
|
6244
6392
|
container,
|
|
6245
6393
|
inline: this.inline,
|
|
6246
|
-
routerMode: routerMode,
|
|
6247
|
-
baseroute: baseroute || '',
|
|
6248
6394
|
fiber: true,
|
|
6249
6395
|
defaultPage: defaultPage || '',
|
|
6250
6396
|
disablePatchRequest: disablePatchRequest !== null && disablePatchRequest !== void 0 ? disablePatchRequest : false,
|
|
6397
|
+
routerMode: routerMode,
|
|
6398
|
+
baseroute: baseroute || '',
|
|
6251
6399
|
});
|
|
6252
6400
|
}
|
|
6253
6401
|
}
|
|
@@ -6284,6 +6432,10 @@ class CreateApp {
|
|
|
6284
6432
|
this.container = container;
|
|
6285
6433
|
// mount before prerender exec mount (loading source), set isPrerender to false
|
|
6286
6434
|
this.isPrerender = false;
|
|
6435
|
+
// dispatch state event to micro app
|
|
6436
|
+
dispatchCustomEventToMicroApp(this, 'statechange', {
|
|
6437
|
+
appState: appStates.LOADING
|
|
6438
|
+
});
|
|
6287
6439
|
// reset app state to LOADING
|
|
6288
6440
|
return this.setAppState(appStates.LOADING);
|
|
6289
6441
|
}
|
|
@@ -6313,7 +6465,7 @@ class CreateApp {
|
|
|
6313
6465
|
*/
|
|
6314
6466
|
(_a = this.sandBox) === null || _a === void 0 ? void 0 : _a.rebuildEffectSnapshot();
|
|
6315
6467
|
// current this.container is <div prerender='true'></div>
|
|
6316
|
-
cloneContainer(container, this.container, false);
|
|
6468
|
+
this.cloneContainer(container, this.container, false);
|
|
6317
6469
|
/**
|
|
6318
6470
|
* set this.container to <micro-app></micro-app>
|
|
6319
6471
|
* NOTE:
|
|
@@ -6333,7 +6485,10 @@ class CreateApp {
|
|
|
6333
6485
|
this.inline = this.getInlineModeState(inline);
|
|
6334
6486
|
this.fiber = fiber;
|
|
6335
6487
|
this.routerMode = routerMode;
|
|
6336
|
-
const dispatchBeforeMount = () =>
|
|
6488
|
+
const dispatchBeforeMount = () => {
|
|
6489
|
+
this.setLifeCycleState(lifeCycles.BEFOREMOUNT);
|
|
6490
|
+
dispatchLifecyclesEvent(this.container, this.name, lifeCycles.BEFOREMOUNT);
|
|
6491
|
+
};
|
|
6337
6492
|
if (this.isPrerender) {
|
|
6338
6493
|
((_d = this.preRenderEvents) !== null && _d !== void 0 ? _d : (this.preRenderEvents = [])).push(dispatchBeforeMount);
|
|
6339
6494
|
}
|
|
@@ -6341,8 +6496,12 @@ class CreateApp {
|
|
|
6341
6496
|
dispatchBeforeMount();
|
|
6342
6497
|
}
|
|
6343
6498
|
this.setAppState(appStates.MOUNTING);
|
|
6499
|
+
// dispatch state event to micro app
|
|
6500
|
+
dispatchCustomEventToMicroApp(this, 'statechange', {
|
|
6501
|
+
appState: appStates.MOUNTING
|
|
6502
|
+
});
|
|
6344
6503
|
// TODO: 将所有cloneContainer中的'as Element'去掉,兼容shadowRoot的场景
|
|
6345
|
-
cloneContainer(this.container, this.source.html, !this.umdMode);
|
|
6504
|
+
this.cloneContainer(this.container, this.source.html, !this.umdMode);
|
|
6346
6505
|
(_e = this.sandBox) === null || _e === void 0 ? void 0 : _e.start({
|
|
6347
6506
|
umdMode: this.umdMode,
|
|
6348
6507
|
baseroute,
|
|
@@ -6360,6 +6519,7 @@ class CreateApp {
|
|
|
6360
6519
|
* umdHookUnmount can works in default mode
|
|
6361
6520
|
* register through window.unmount
|
|
6362
6521
|
*/
|
|
6522
|
+
// TODO: 不对,这里要改,因为unmount不一定是函数
|
|
6363
6523
|
this.umdHookUnmount = unmount;
|
|
6364
6524
|
// if mount & unmount is function, the sub app is umd mode
|
|
6365
6525
|
if (isFunction(mount) && isFunction(unmount)) {
|
|
@@ -6395,8 +6555,8 @@ class CreateApp {
|
|
|
6395
6555
|
}
|
|
6396
6556
|
}
|
|
6397
6557
|
};
|
|
6398
|
-
// TODO:
|
|
6399
|
-
this.
|
|
6558
|
+
// TODO: 可优化?
|
|
6559
|
+
this.sandBox ? this.sandBox.sandboxReady.then(nextAction) : nextAction();
|
|
6400
6560
|
}
|
|
6401
6561
|
/**
|
|
6402
6562
|
* handle for promise umdHookMount
|
|
@@ -6434,6 +6594,13 @@ class CreateApp {
|
|
|
6434
6594
|
this.setAppState(appStates.MOUNTED);
|
|
6435
6595
|
// call window.onmount of child app
|
|
6436
6596
|
execMicroAppGlobalHook(this.getMicroAppGlobalHook(microGlobalEvent.ONMOUNT), this.name, microGlobalEvent.ONMOUNT, microApp.getData(this.name, true));
|
|
6597
|
+
// dispatch state event to micro app
|
|
6598
|
+
dispatchCustomEventToMicroApp(this, 'statechange', {
|
|
6599
|
+
appState: appStates.MOUNTED
|
|
6600
|
+
});
|
|
6601
|
+
// dispatch mounted event to micro app
|
|
6602
|
+
dispatchCustomEventToMicroApp(this, 'mounted');
|
|
6603
|
+
this.setLifeCycleState(lifeCycles.MOUNTED);
|
|
6437
6604
|
// dispatch event mounted to parent
|
|
6438
6605
|
dispatchLifecyclesEvent(this.container, this.name, lifeCycles.MOUNTED);
|
|
6439
6606
|
/**
|
|
@@ -6473,6 +6640,10 @@ class CreateApp {
|
|
|
6473
6640
|
catch (e) {
|
|
6474
6641
|
logError('An error occurred in window.unmount \n', this.name, e);
|
|
6475
6642
|
}
|
|
6643
|
+
// dispatch state event to micro app
|
|
6644
|
+
dispatchCustomEventToMicroApp(this, 'statechange', {
|
|
6645
|
+
appState: appStates.UNMOUNT
|
|
6646
|
+
});
|
|
6476
6647
|
// dispatch unmount event to micro app
|
|
6477
6648
|
dispatchCustomEventToMicroApp(this, 'unmount');
|
|
6478
6649
|
// call window.onunmount of child app
|
|
@@ -6519,7 +6690,7 @@ class CreateApp {
|
|
|
6519
6690
|
actionsForUnmount({ destroy, clearData, keepRouteState, unmountcb, }) {
|
|
6520
6691
|
var _a;
|
|
6521
6692
|
if (this.umdMode && this.container && !destroy) {
|
|
6522
|
-
cloneContainer(this.source.html, this.container, false);
|
|
6693
|
+
this.cloneContainer(this.source.html, this.container, false);
|
|
6523
6694
|
}
|
|
6524
6695
|
/**
|
|
6525
6696
|
* this.container maybe contains micro-app element, stop sandbox should exec after cloneContainer
|
|
@@ -6533,6 +6704,7 @@ class CreateApp {
|
|
|
6533
6704
|
destroy,
|
|
6534
6705
|
clearData: clearData || destroy,
|
|
6535
6706
|
});
|
|
6707
|
+
this.setLifeCycleState(lifeCycles.UNMOUNT);
|
|
6536
6708
|
// dispatch unmount event to base app
|
|
6537
6709
|
dispatchLifecyclesEvent(this.container, this.name, lifeCycles.UNMOUNT);
|
|
6538
6710
|
this.clearOptions(destroy);
|
|
@@ -6545,6 +6717,7 @@ class CreateApp {
|
|
|
6545
6717
|
this.preRenderEvents = null;
|
|
6546
6718
|
this.setKeepAliveState(null);
|
|
6547
6719
|
// in iframe sandbox & default mode, delete the sandbox & iframeElement
|
|
6720
|
+
// TODO: with沙箱与iframe沙箱保持一致:with沙箱默认模式下删除 或者 iframe沙箱umd模式下保留
|
|
6548
6721
|
if (this.iframe && !this.umdMode)
|
|
6549
6722
|
this.sandBox = null;
|
|
6550
6723
|
if (destroy)
|
|
@@ -6573,9 +6746,10 @@ class CreateApp {
|
|
|
6573
6746
|
dispatchCustomEventToMicroApp(this, 'appstate-change', {
|
|
6574
6747
|
appState: 'afterhidden',
|
|
6575
6748
|
});
|
|
6749
|
+
this.setLifeCycleState(lifeCycles.AFTERHIDDEN);
|
|
6576
6750
|
// dispatch afterHidden event to base app
|
|
6577
6751
|
dispatchLifecyclesEvent(this.container, this.name, lifeCycles.AFTERHIDDEN);
|
|
6578
|
-
if (this.
|
|
6752
|
+
if (isRouterModeSearch(this.name)) {
|
|
6579
6753
|
// called after lifeCyclesEvent
|
|
6580
6754
|
(_a = this.sandBox) === null || _a === void 0 ? void 0 : _a.removeRouteInfoForKeepAliveApp();
|
|
6581
6755
|
}
|
|
@@ -6586,7 +6760,7 @@ class CreateApp {
|
|
|
6586
6760
|
getRootContainer(this.container).unmount();
|
|
6587
6761
|
}
|
|
6588
6762
|
else {
|
|
6589
|
-
this.container = cloneContainer(pureCreateElement('div'), this.container, false);
|
|
6763
|
+
this.container = this.cloneContainer(pureCreateElement('div'), this.container, false);
|
|
6590
6764
|
(_b = this.sandBox) === null || _b === void 0 ? void 0 : _b.recordAndReleaseEffect({ keepAlive: true });
|
|
6591
6765
|
}
|
|
6592
6766
|
callback === null || callback === void 0 ? void 0 : callback();
|
|
@@ -6602,13 +6776,13 @@ class CreateApp {
|
|
|
6602
6776
|
// dispatch beforeShow event to base app
|
|
6603
6777
|
dispatchLifecyclesEvent(container, this.name, lifeCycles.BEFORESHOW);
|
|
6604
6778
|
this.setKeepAliveState(keepAliveStates.KEEP_ALIVE_SHOW);
|
|
6605
|
-
this.container = cloneContainer(container, this.container, false);
|
|
6779
|
+
this.container = this.cloneContainer(container, this.container, false);
|
|
6606
6780
|
/**
|
|
6607
6781
|
* TODO:
|
|
6608
6782
|
* 问题:当路由模式为custom时,keep-alive应用在重新展示,是否需要根据子应用location信息更新浏览器地址?
|
|
6609
6783
|
* 暂时不这么做吧,因为无法确定二次展示时新旧地址是否相同,是否带有特殊信息
|
|
6610
6784
|
*/
|
|
6611
|
-
if (this.
|
|
6785
|
+
if (isRouterModeSearch(this.name)) {
|
|
6612
6786
|
// called before lifeCyclesEvent
|
|
6613
6787
|
(_b = this.sandBox) === null || _b === void 0 ? void 0 : _b.setRouteInfoForKeepAliveApp();
|
|
6614
6788
|
}
|
|
@@ -6616,6 +6790,7 @@ class CreateApp {
|
|
|
6616
6790
|
dispatchCustomEventToMicroApp(this, 'appstate-change', {
|
|
6617
6791
|
appState: 'aftershow',
|
|
6618
6792
|
});
|
|
6793
|
+
this.setLifeCycleState(lifeCycles.AFTERSHOW);
|
|
6619
6794
|
// dispatch afterShow event to base app
|
|
6620
6795
|
dispatchLifecyclesEvent(this.container, this.name, lifeCycles.AFTERSHOW);
|
|
6621
6796
|
}
|
|
@@ -6624,8 +6799,41 @@ class CreateApp {
|
|
|
6624
6799
|
* @param e Error
|
|
6625
6800
|
*/
|
|
6626
6801
|
onerror(e) {
|
|
6802
|
+
this.setLifeCycleState(lifeCycles.ERROR);
|
|
6803
|
+
// dispatch state event to micro app
|
|
6804
|
+
dispatchCustomEventToMicroApp(this, 'statechange', {
|
|
6805
|
+
appState: appStates.LOAD_FAILED
|
|
6806
|
+
});
|
|
6627
6807
|
dispatchLifecyclesEvent(this.container, this.name, lifeCycles.ERROR, e);
|
|
6628
6808
|
}
|
|
6809
|
+
/**
|
|
6810
|
+
* Parse htmlString to DOM
|
|
6811
|
+
* NOTE: iframe sandbox will use DOMParser of iframeWindow, with sandbox will use DOMParser of base app
|
|
6812
|
+
* @param htmlString DOMString
|
|
6813
|
+
* @returns parsed DOM
|
|
6814
|
+
*/
|
|
6815
|
+
parseHtmlString(htmlString) {
|
|
6816
|
+
var _a;
|
|
6817
|
+
const DOMParser = ((_a = this.sandBox) === null || _a === void 0 ? void 0 : _a.proxyWindow) ? this.sandBox.proxyWindow.DOMParser
|
|
6818
|
+
: globalEnv.rawWindow.DOMParser;
|
|
6819
|
+
return (new DOMParser()).parseFromString(htmlString, 'text/html').body;
|
|
6820
|
+
}
|
|
6821
|
+
/**
|
|
6822
|
+
* clone origin elements to target
|
|
6823
|
+
* @param origin Cloned element
|
|
6824
|
+
* @param target Accept cloned elements
|
|
6825
|
+
* @param deep deep clone or transfer dom
|
|
6826
|
+
*/
|
|
6827
|
+
cloneContainer(target, origin, deep) {
|
|
6828
|
+
// 在基座接受到afterhidden方法后立即执行unmount,彻底destroy应用时,因为unmount时同步执行,所以this.container为null后才执行cloneContainer
|
|
6829
|
+
if (origin) {
|
|
6830
|
+
target.innerHTML = '';
|
|
6831
|
+
Array.from(deep ? this.parseHtmlString(origin.innerHTML).childNodes : origin.childNodes).forEach((node) => {
|
|
6832
|
+
target.appendChild(node);
|
|
6833
|
+
});
|
|
6834
|
+
}
|
|
6835
|
+
return target;
|
|
6836
|
+
}
|
|
6629
6837
|
/**
|
|
6630
6838
|
* Scene:
|
|
6631
6839
|
* 1. create app
|
|
@@ -6634,22 +6842,28 @@ class CreateApp {
|
|
|
6634
6842
|
*/
|
|
6635
6843
|
createSandbox() {
|
|
6636
6844
|
if (this.useSandbox && !this.sandBox) {
|
|
6637
|
-
|
|
6638
|
-
this.sandBox = new IframeSandbox(this.name, this.url);
|
|
6639
|
-
}
|
|
6640
|
-
else {
|
|
6641
|
-
this.sandBox = new WithSandBox(this.name, this.url);
|
|
6642
|
-
}
|
|
6845
|
+
this.sandBox = this.iframe ? new IframeSandbox(this.name, this.url) : new WithSandBox(this.name, this.url);
|
|
6643
6846
|
}
|
|
6644
6847
|
}
|
|
6645
6848
|
// set app state
|
|
6646
6849
|
setAppState(state) {
|
|
6850
|
+
var _a;
|
|
6647
6851
|
this.state = state;
|
|
6852
|
+
// set window.__MICRO_APP_STATE__
|
|
6853
|
+
(_a = this.sandBox) === null || _a === void 0 ? void 0 : _a.setStaticAppState(state);
|
|
6648
6854
|
}
|
|
6649
6855
|
// get app state
|
|
6650
6856
|
getAppState() {
|
|
6651
6857
|
return this.state;
|
|
6652
6858
|
}
|
|
6859
|
+
// set app lifeCycleState
|
|
6860
|
+
setLifeCycleState(state) {
|
|
6861
|
+
this.lifeCycleState = state;
|
|
6862
|
+
}
|
|
6863
|
+
// get app lifeCycleState
|
|
6864
|
+
getLifeCycleState() {
|
|
6865
|
+
return this.lifeCycleState || '';
|
|
6866
|
+
}
|
|
6653
6867
|
// set keep-alive state
|
|
6654
6868
|
setKeepAliveState(state) {
|
|
6655
6869
|
this.keepAliveState = state;
|
|
@@ -6793,10 +7007,6 @@ function handleNewNode(child, app) {
|
|
|
6793
7007
|
*/
|
|
6794
7008
|
function invokePrototypeMethod(app, rawMethod, parent, targetChild, passiveChild) {
|
|
6795
7009
|
const hijackParent = getHijackParent(parent, targetChild, app);
|
|
6796
|
-
/**
|
|
6797
|
-
* If passiveChild is not the child node, insertBefore replaceChild will have a problem, at this time, it will be degraded to appendChild
|
|
6798
|
-
* E.g: document.head.insertBefore(targetChild, document.head.childNodes[0])
|
|
6799
|
-
*/
|
|
6800
7010
|
if (hijackParent) {
|
|
6801
7011
|
/**
|
|
6802
7012
|
* If parentNode is <micro-app-body>, return rawDocument.body
|
|
@@ -6835,11 +7045,28 @@ function invokePrototypeMethod(app, rawMethod, parent, targetChild, passiveChild
|
|
|
6835
7045
|
});
|
|
6836
7046
|
}
|
|
6837
7047
|
}
|
|
7048
|
+
if ((process.env.NODE_ENV !== 'production') &&
|
|
7049
|
+
isIFrameElement(targetChild) &&
|
|
7050
|
+
rawMethod === globalEnv.rawAppendChild) {
|
|
7051
|
+
fixReactHMRConflict(app);
|
|
7052
|
+
}
|
|
6838
7053
|
/**
|
|
6839
7054
|
* 1. If passiveChild exists, it must be insertBefore or replaceChild
|
|
6840
7055
|
* 2. When removeChild, targetChild may not be in microAppHead or head
|
|
7056
|
+
* NOTE:
|
|
7057
|
+
* 1. If passiveChild not in hijackParent, insertBefore replaceChild will be degraded to appendChild
|
|
7058
|
+
* E.g: document.head.replaceChild(targetChild, document.scripts[0])
|
|
7059
|
+
* 2. If passiveChild not in hijackParent but in parent and method is insertBefore, try insert it into the position corresponding to hijackParent
|
|
7060
|
+
* E.g: document.head.insertBefore(targetChild, document.head.childNodes[0])
|
|
7061
|
+
* ISSUE: https://github.com/micro-zoe/micro-app/issues/1071
|
|
6841
7062
|
*/
|
|
6842
7063
|
if (passiveChild && !hijackParent.contains(passiveChild)) {
|
|
7064
|
+
if (rawMethod === globalEnv.rawInsertBefore && parent.contains(passiveChild)) {
|
|
7065
|
+
const indexOfParent = Array.from(parent.childNodes).indexOf(passiveChild);
|
|
7066
|
+
if (hijackParent.childNodes[indexOfParent]) {
|
|
7067
|
+
return invokeRawMethod(rawMethod, hijackParent, targetChild, hijackParent.childNodes[indexOfParent]);
|
|
7068
|
+
}
|
|
7069
|
+
}
|
|
6843
7070
|
return globalEnv.rawAppendChild.call(hijackParent, targetChild);
|
|
6844
7071
|
}
|
|
6845
7072
|
else if (rawMethod === globalEnv.rawRemoveChild && !hijackParent.contains(targetChild)) {
|
|
@@ -6848,11 +7075,6 @@ function invokePrototypeMethod(app, rawMethod, parent, targetChild, passiveChild
|
|
|
6848
7075
|
}
|
|
6849
7076
|
return targetChild;
|
|
6850
7077
|
}
|
|
6851
|
-
if ((process.env.NODE_ENV !== 'production') &&
|
|
6852
|
-
isIFrameElement(targetChild) &&
|
|
6853
|
-
rawMethod === globalEnv.rawAppendChild) {
|
|
6854
|
-
fixReactHMRConflict(app);
|
|
6855
|
-
}
|
|
6856
7078
|
return invokeRawMethod(rawMethod, hijackParent, targetChild, passiveChild);
|
|
6857
7079
|
}
|
|
6858
7080
|
return invokeRawMethod(rawMethod, parent, targetChild, passiveChild);
|
|
@@ -6922,6 +7144,11 @@ function commonElementHandler(parent, newChild, passiveChild, rawMethod) {
|
|
|
6922
7144
|
currentAppName)) {
|
|
6923
7145
|
newChild.__MICRO_APP_NAME__ = newChild.__MICRO_APP_NAME__ || currentAppName;
|
|
6924
7146
|
const app = appInstanceMap.get(newChild.__MICRO_APP_NAME__);
|
|
7147
|
+
if (isStyleElement(newChild)) {
|
|
7148
|
+
const isShadowNode = parent.getRootNode();
|
|
7149
|
+
const isShadowEnvironment = isShadowNode instanceof ShadowRoot;
|
|
7150
|
+
isShadowEnvironment && newChild.setAttribute('ignore', 'true');
|
|
7151
|
+
}
|
|
6925
7152
|
if (app === null || app === void 0 ? void 0 : app.container) {
|
|
6926
7153
|
completePathDynamic(app, newChild);
|
|
6927
7154
|
return invokePrototypeMethod(app, rawMethod, parent, handleNewNode(newChild, app), passiveChild && getMappingNode(passiveChild));
|
|
@@ -7008,30 +7235,34 @@ function patchElementAndDocument() {
|
|
|
7008
7235
|
this.__MICRO_APP_NAME__ && (clonedNode.__MICRO_APP_NAME__ = this.__MICRO_APP_NAME__);
|
|
7009
7236
|
return clonedNode;
|
|
7010
7237
|
};
|
|
7011
|
-
|
|
7238
|
+
/**
|
|
7239
|
+
* document.body(head).querySelector(querySelectorAll) hijack to microAppBody(microAppHead).querySelector(querySelectorAll)
|
|
7240
|
+
* NOTE:
|
|
7241
|
+
* 1. May cause some problems!
|
|
7242
|
+
* 2. Add config options?
|
|
7243
|
+
*/
|
|
7244
|
+
function getQueryTarget(target) {
|
|
7012
7245
|
const currentAppName = getCurrentAppName();
|
|
7013
|
-
if ((
|
|
7246
|
+
if ((target === document.body || target === document.head) && currentAppName) {
|
|
7014
7247
|
const app = appInstanceMap.get(currentAppName);
|
|
7015
7248
|
if (app === null || app === void 0 ? void 0 : app.container) {
|
|
7016
|
-
if (
|
|
7249
|
+
if (target === document.body) {
|
|
7017
7250
|
return app.querySelector('micro-app-body');
|
|
7018
7251
|
}
|
|
7019
|
-
else if (
|
|
7252
|
+
else if (target === document.head) {
|
|
7020
7253
|
return app.querySelector('micro-app-head');
|
|
7021
7254
|
}
|
|
7022
7255
|
}
|
|
7023
7256
|
}
|
|
7024
|
-
return
|
|
7257
|
+
return target;
|
|
7025
7258
|
}
|
|
7026
7259
|
rawRootElement.prototype.querySelector = function querySelector(selectors) {
|
|
7027
7260
|
var _a;
|
|
7028
|
-
|
|
7029
|
-
return globalEnv.rawElementQuerySelector.call(target, selectors);
|
|
7261
|
+
return globalEnv.rawElementQuerySelector.call((_a = getQueryTarget(this)) !== null && _a !== void 0 ? _a : this, selectors);
|
|
7030
7262
|
};
|
|
7031
7263
|
rawRootElement.prototype.querySelectorAll = function querySelectorAll(selectors) {
|
|
7032
7264
|
var _a;
|
|
7033
|
-
|
|
7034
|
-
return globalEnv.rawElementQuerySelectorAll.call(target, selectors);
|
|
7265
|
+
return globalEnv.rawElementQuerySelectorAll.call((_a = getQueryTarget(this)) !== null && _a !== void 0 ? _a : this, selectors);
|
|
7035
7266
|
};
|
|
7036
7267
|
// rewrite setAttribute, complete resource address
|
|
7037
7268
|
rawRootElement.prototype.setAttribute = function setAttribute(key, value) {
|
|
@@ -7090,6 +7321,7 @@ function patchElementAndDocument() {
|
|
|
7090
7321
|
const currentAppName = getCurrentAppName();
|
|
7091
7322
|
Array.from(this.children).forEach((child) => {
|
|
7092
7323
|
if (isElement(child) && currentAppName) {
|
|
7324
|
+
// TODO: 使用updateElementInfo进行更新
|
|
7093
7325
|
child.__MICRO_APP_NAME__ = currentAppName;
|
|
7094
7326
|
}
|
|
7095
7327
|
});
|
|
@@ -7106,7 +7338,7 @@ function patchElementAndDocument() {
|
|
|
7106
7338
|
* 1. element-ui@2/lib/utils/popper.js
|
|
7107
7339
|
* // root is child app window, so root.document is proxyDocument or microDocument
|
|
7108
7340
|
* if (element.parentNode === root.document) ...
|
|
7109
|
-
|
|
7341
|
+
*/
|
|
7110
7342
|
const currentAppName = getCurrentAppName();
|
|
7111
7343
|
if (currentAppName && this === globalEnv.rawDocument.firstElementChild) {
|
|
7112
7344
|
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;
|
|
@@ -7158,14 +7390,15 @@ function patchDocument$2() {
|
|
|
7158
7390
|
const element = globalEnv.rawCreateElementNS.call(getBindTarget(this), namespaceURI, name, options);
|
|
7159
7391
|
return markElement(element);
|
|
7160
7392
|
};
|
|
7161
|
-
|
|
7162
|
-
const element = globalEnv.rawCreateDocumentFragment.call(getBindTarget(this));
|
|
7163
|
-
return markElement(element);
|
|
7164
|
-
};
|
|
7393
|
+
// TODO: 放开
|
|
7165
7394
|
// rawRootDocument.prototype.createTextNode = function createTextNode (data: string): Text {
|
|
7166
7395
|
// const element = globalEnv.rawCreateTextNode.call(getBindTarget(this), data)
|
|
7167
7396
|
// return markElement(element)
|
|
7168
7397
|
// }
|
|
7398
|
+
rawRootDocument.prototype.createDocumentFragment = function createDocumentFragment() {
|
|
7399
|
+
const element = globalEnv.rawCreateDocumentFragment.call(getBindTarget(this));
|
|
7400
|
+
return markElement(element);
|
|
7401
|
+
};
|
|
7169
7402
|
rawRootDocument.prototype.createComment = function createComment(data) {
|
|
7170
7403
|
const element = globalEnv.rawCreateComment.call(getBindTarget(this), data);
|
|
7171
7404
|
return markElement(element);
|
|
@@ -7178,7 +7411,7 @@ function patchDocument$2() {
|
|
|
7178
7411
|
if (!currentAppName ||
|
|
7179
7412
|
!selectors ||
|
|
7180
7413
|
isUniqueElement(selectors) ||
|
|
7181
|
-
//
|
|
7414
|
+
// ISSUE: https://github.com/micro-zoe/micro-app/issues/56
|
|
7182
7415
|
rawDocument !== _this) {
|
|
7183
7416
|
return globalEnv.rawQuerySelector.call(_this, selectors);
|
|
7184
7417
|
}
|
|
@@ -7328,8 +7561,8 @@ function initGlobalEnv() {
|
|
|
7328
7561
|
// Document proto methods
|
|
7329
7562
|
const rawCreateElement = rawRootDocument.prototype.createElement;
|
|
7330
7563
|
const rawCreateElementNS = rawRootDocument.prototype.createElementNS;
|
|
7331
|
-
const rawCreateDocumentFragment = rawRootDocument.prototype.createDocumentFragment;
|
|
7332
7564
|
const rawCreateTextNode = rawRootDocument.prototype.createTextNode;
|
|
7565
|
+
const rawCreateDocumentFragment = rawRootDocument.prototype.createDocumentFragment;
|
|
7333
7566
|
const rawCreateComment = rawRootDocument.prototype.createComment;
|
|
7334
7567
|
const rawQuerySelector = rawRootDocument.prototype.querySelector;
|
|
7335
7568
|
const rawQuerySelectorAll = rawRootDocument.prototype.querySelectorAll;
|
|
@@ -7889,7 +8122,9 @@ function defineElement(tagName) {
|
|
|
7889
8122
|
* @returns router-mode
|
|
7890
8123
|
*/
|
|
7891
8124
|
getMemoryRouterMode() {
|
|
7892
|
-
return getRouterMode(this.getAttribute('router-mode'),
|
|
8125
|
+
return getRouterMode(this.getAttribute('router-mode'),
|
|
8126
|
+
// is micro-app element set disable-memory-router, like <micro-app disable-memory-router></micro-app>
|
|
8127
|
+
this.compatibleProperties('disable-memory-router') && this.compatibleDisableProperties('disable-memory-router'));
|
|
7893
8128
|
}
|
|
7894
8129
|
/**
|
|
7895
8130
|
* rewrite micro-app.setAttribute, process attr data
|
|
@@ -7938,6 +8173,18 @@ function defineElement(tagName) {
|
|
|
7938
8173
|
}
|
|
7939
8174
|
return null;
|
|
7940
8175
|
}
|
|
8176
|
+
/**
|
|
8177
|
+
* get publicPath from a valid address,it can used in micro-app-devtools
|
|
8178
|
+
*/
|
|
8179
|
+
get publicPath() {
|
|
8180
|
+
return getEffectivePath(this.appUrl);
|
|
8181
|
+
}
|
|
8182
|
+
/**
|
|
8183
|
+
* get baseRoute from attribute,it can used in micro-app-devtools
|
|
8184
|
+
*/
|
|
8185
|
+
get baseRoute() {
|
|
8186
|
+
return this.getBaseRouteCompatible();
|
|
8187
|
+
}
|
|
7941
8188
|
}
|
|
7942
8189
|
globalEnv.rawWindow.customElements.define(tagName, MicroAppElement);
|
|
7943
8190
|
}
|
|
@@ -8016,9 +8263,22 @@ function preFetchAction(options) {
|
|
|
8016
8263
|
});
|
|
8017
8264
|
const oldOnload = app.onLoad;
|
|
8018
8265
|
const oldOnLoadError = app.onLoadError;
|
|
8019
|
-
app.onLoad = (
|
|
8266
|
+
app.onLoad = (onLoadParam) => {
|
|
8267
|
+
if (app.isPrerender) {
|
|
8268
|
+
assign(onLoadParam, {
|
|
8269
|
+
defaultPage: options['default-page'],
|
|
8270
|
+
/**
|
|
8271
|
+
* TODO: 预渲染支持disable-memory-router,默认渲染首页即可,文档中也要保留
|
|
8272
|
+
* 问题:
|
|
8273
|
+
* 1、如何确保子应用进行跳转时不影响到浏览器地址??pure??
|
|
8274
|
+
*/
|
|
8275
|
+
routerMode: getRouterMode(options['router-mode']),
|
|
8276
|
+
baseroute: options.baseroute,
|
|
8277
|
+
disablePatchRequest: options['disable-patch-request'],
|
|
8278
|
+
});
|
|
8279
|
+
}
|
|
8020
8280
|
resolve();
|
|
8021
|
-
oldOnload.call(app,
|
|
8281
|
+
oldOnload.call(app, onLoadParam);
|
|
8022
8282
|
};
|
|
8023
8283
|
app.onLoadError = (...rests) => {
|
|
8024
8284
|
resolve();
|
|
@@ -8278,6 +8538,20 @@ function renderApp(options) {
|
|
|
8278
8538
|
container.appendChild(microAppElement);
|
|
8279
8539
|
});
|
|
8280
8540
|
}
|
|
8541
|
+
/**
|
|
8542
|
+
* get app state
|
|
8543
|
+
* @param appName app.name
|
|
8544
|
+
* @returns app.state
|
|
8545
|
+
*/
|
|
8546
|
+
function getAppStatus(appName) {
|
|
8547
|
+
const app = appInstanceMap.get(formatAppName(appName));
|
|
8548
|
+
if (app) {
|
|
8549
|
+
return app.getLifeCycleState();
|
|
8550
|
+
}
|
|
8551
|
+
else {
|
|
8552
|
+
logWarn(`app ${appName} does not exist`);
|
|
8553
|
+
}
|
|
8554
|
+
}
|
|
8281
8555
|
class MicroApp extends EventCenterForBaseApp {
|
|
8282
8556
|
constructor() {
|
|
8283
8557
|
super(...arguments);
|
|
@@ -8292,6 +8566,7 @@ class MicroApp extends EventCenterForBaseApp {
|
|
|
8292
8566
|
this.getAllApps = getAllApps;
|
|
8293
8567
|
this.reload = reload;
|
|
8294
8568
|
this.renderApp = renderApp;
|
|
8569
|
+
this.getAppStatus = getAppStatus;
|
|
8295
8570
|
}
|
|
8296
8571
|
start(options) {
|
|
8297
8572
|
var _a, _b;
|
|
@@ -8347,5 +8622,5 @@ class MicroApp extends EventCenterForBaseApp {
|
|
|
8347
8622
|
const microApp = new MicroApp();
|
|
8348
8623
|
|
|
8349
8624
|
export default microApp;
|
|
8350
|
-
export { EventCenterForMicroApp, MicroApp, getActiveApps, getAllApps, preFetch, pureCreateElement, reload, removeDomScope, renderApp, unmountAllApps, unmountApp, version };
|
|
8625
|
+
export { EventCenterForMicroApp, MicroApp, getActiveApps, getAllApps, getAppStatus, preFetch, pureCreateElement, reload, removeDomScope, renderApp, unmountAllApps, unmountApp, version };
|
|
8351
8626
|
//# sourceMappingURL=index.esm.js.map
|