@micro-zoe/micro-app 1.0.0-beta.2 → 1.0.0-beta.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 +1 -1
- package/lib/index.esm.js +432 -241
- 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 +8 -0
package/lib/index.esm.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
const version = '1.0.0-beta.
|
|
1
|
+
const version = '1.0.0-beta.4';
|
|
2
2
|
// do not use isUndefined
|
|
3
3
|
const isBrowser = typeof window !== 'undefined';
|
|
4
4
|
// do not use isUndefined
|
|
@@ -356,7 +356,7 @@ function pureCreateElement(tagName, options) {
|
|
|
356
356
|
* @param target Accept cloned elements
|
|
357
357
|
* @param deep deep clone or transfer dom
|
|
358
358
|
*/
|
|
359
|
-
function cloneContainer(
|
|
359
|
+
function cloneContainer(target, origin, deep) {
|
|
360
360
|
target.innerHTML = '';
|
|
361
361
|
if (deep) {
|
|
362
362
|
// TODO: ShadowRoot兼容,ShadowRoot不能直接使用cloneNode
|
|
@@ -562,7 +562,6 @@ var appStates;
|
|
|
562
562
|
(function (appStates) {
|
|
563
563
|
appStates["CREATED"] = "created";
|
|
564
564
|
appStates["LOADING"] = "loading";
|
|
565
|
-
appStates["LOADED"] = "loaded";
|
|
566
565
|
appStates["LOAD_FAILED"] = "load_failed";
|
|
567
566
|
appStates["MOUNTING"] = "mounting";
|
|
568
567
|
appStates["MOUNTED"] = "mounted";
|
|
@@ -1501,7 +1500,7 @@ function execScripts(app, initHook) {
|
|
|
1501
1500
|
// Notice the second render
|
|
1502
1501
|
if (appSpaceData.defer || appSpaceData.async) {
|
|
1503
1502
|
// TODO: defer和module彻底分开,不要混在一起
|
|
1504
|
-
if (scriptInfo.isExternal && !scriptInfo.code && !(app
|
|
1503
|
+
if (scriptInfo.isExternal && !scriptInfo.code && !isTypeModule(app, scriptInfo)) {
|
|
1505
1504
|
deferScriptPromise.push(fetchSource(address, app.name));
|
|
1506
1505
|
}
|
|
1507
1506
|
else {
|
|
@@ -1585,9 +1584,19 @@ function runScript(address, app, scriptInfo, callback, replaceElement) {
|
|
|
1585
1584
|
appSpaceData.sandboxType = sandboxType;
|
|
1586
1585
|
appSpaceData.parsedFunction = null;
|
|
1587
1586
|
}
|
|
1587
|
+
/**
|
|
1588
|
+
* TODO: 优化逻辑
|
|
1589
|
+
* 是否是内联模式应该由外部传入,这样自外而内更加统一,逻辑更加清晰
|
|
1590
|
+
*/
|
|
1588
1591
|
if (isInlineMode(app, scriptInfo)) {
|
|
1589
1592
|
const scriptElement = replaceElement || pureCreateElement('script');
|
|
1590
1593
|
runCode2InlineScript(address, appSpaceData.parsedCode, isTypeModule(app, scriptInfo), scriptElement, appSpaceData.attrs, callback);
|
|
1594
|
+
/**
|
|
1595
|
+
* TODO: 优化逻辑
|
|
1596
|
+
* replaceElement不存在说明是初始化执行,需要主动插入script
|
|
1597
|
+
* 但这里的逻辑不清晰,应该明确声明是什么环境下才需要主动插入,而不是用replaceElement间接判断
|
|
1598
|
+
* replaceElement还有可能是注释类型(一定是在后台执行),这里的判断都是间接判断,不够直观
|
|
1599
|
+
*/
|
|
1591
1600
|
if (!replaceElement) {
|
|
1592
1601
|
// TEST IGNORE
|
|
1593
1602
|
const parent = app.iframe ? app.sandBox.microBody : app.querySelector('micro-app-body');
|
|
@@ -1623,7 +1632,7 @@ function runDynamicRemoteScript(address, app, scriptInfo, originScript) {
|
|
|
1623
1632
|
runScript(address, app, scriptInfo, dispatchScriptOnLoadEvent, replaceElement);
|
|
1624
1633
|
!isTypeModule(app, scriptInfo) && dispatchScriptOnLoadEvent();
|
|
1625
1634
|
};
|
|
1626
|
-
if (scriptInfo.code || (app
|
|
1635
|
+
if (scriptInfo.code || isTypeModule(app, scriptInfo)) {
|
|
1627
1636
|
defer(runDynamicScript);
|
|
1628
1637
|
}
|
|
1629
1638
|
else {
|
|
@@ -2172,14 +2181,21 @@ function patchElementAndDocument() {
|
|
|
2172
2181
|
}
|
|
2173
2182
|
return globalEnv.rawRemoveChild.call(this, oldChild);
|
|
2174
2183
|
};
|
|
2184
|
+
/**
|
|
2185
|
+
* The insertAdjacentElement method of the Element interface inserts a given element node at a given position relative to the element it is invoked upon.
|
|
2186
|
+
* NOTE:
|
|
2187
|
+
* 1. parameter 2 of insertAdjacentElement must type 'Element'
|
|
2188
|
+
*/
|
|
2175
2189
|
rawRootElement.prototype.insertAdjacentElement = function (where, element) {
|
|
2176
2190
|
var _a;
|
|
2177
|
-
if (element === null || element === void 0 ? void 0 : element.__MICRO_APP_NAME__) {
|
|
2191
|
+
if ((element === null || element === void 0 ? void 0 : element.__MICRO_APP_NAME__) && isElement(element)) {
|
|
2178
2192
|
const app = appInstanceMap.get(element.__MICRO_APP_NAME__);
|
|
2179
2193
|
if (app === null || app === void 0 ? void 0 : app.container) {
|
|
2180
|
-
|
|
2181
|
-
|
|
2182
|
-
|
|
2194
|
+
const processedEle = handleNewNode(element, app);
|
|
2195
|
+
if (!isElement(processedEle))
|
|
2196
|
+
return element;
|
|
2197
|
+
const realParent = (_a = getHijackParent(this, processedEle, app)) !== null && _a !== void 0 ? _a : this;
|
|
2198
|
+
return globalEnv.rawInsertAdjacentElement.call(realParent, where, processedEle);
|
|
2183
2199
|
}
|
|
2184
2200
|
}
|
|
2185
2201
|
return globalEnv.rawInsertAdjacentElement.call(this, where, element);
|
|
@@ -3294,8 +3310,12 @@ class EventCenterForMicroApp extends EventCenterForGlobal {
|
|
|
3294
3310
|
* @param microAppEventCenter instance of EventCenterForMicroApp
|
|
3295
3311
|
*/
|
|
3296
3312
|
function recordDataCenterSnapshot(microAppEventCenter) {
|
|
3297
|
-
|
|
3298
|
-
|
|
3313
|
+
var _a, _b;
|
|
3314
|
+
if (microAppEventCenter) {
|
|
3315
|
+
microAppEventCenter.umdDataListeners = {
|
|
3316
|
+
global: new Set((_a = microAppEventCenter.umdDataListeners) === null || _a === void 0 ? void 0 : _a.global),
|
|
3317
|
+
normal: new Set((_b = microAppEventCenter.umdDataListeners) === null || _b === void 0 ? void 0 : _b.normal),
|
|
3318
|
+
};
|
|
3299
3319
|
const globalEventInfo = eventCenter.eventList.get('global');
|
|
3300
3320
|
if (globalEventInfo) {
|
|
3301
3321
|
for (const cb of globalEventInfo.callbacks) {
|
|
@@ -3306,7 +3326,9 @@ function recordDataCenterSnapshot(microAppEventCenter) {
|
|
|
3306
3326
|
}
|
|
3307
3327
|
const subAppEventInfo = eventCenter.eventList.get(createEventName(microAppEventCenter.appName, true));
|
|
3308
3328
|
if (subAppEventInfo) {
|
|
3309
|
-
|
|
3329
|
+
for (const cb of subAppEventInfo.callbacks) {
|
|
3330
|
+
microAppEventCenter.umdDataListeners.normal.add(cb);
|
|
3331
|
+
}
|
|
3310
3332
|
}
|
|
3311
3333
|
}
|
|
3312
3334
|
}
|
|
@@ -3331,7 +3353,7 @@ function rebuildDataCenterSnapshot(microAppEventCenter) {
|
|
|
3331
3353
|
* @param microAppEventCenter instance of EventCenterForMicroApp
|
|
3332
3354
|
*/
|
|
3333
3355
|
function resetDataCenterSnapshot(microAppEventCenter) {
|
|
3334
|
-
delete microAppEventCenter.umdDataListeners;
|
|
3356
|
+
microAppEventCenter === null || microAppEventCenter === void 0 ? true : delete microAppEventCenter.umdDataListeners;
|
|
3335
3357
|
}
|
|
3336
3358
|
|
|
3337
3359
|
// 管理 app 的单例
|
|
@@ -3473,19 +3495,23 @@ function createProxyDocument(appName, sandbox) {
|
|
|
3473
3495
|
* 3. prerender/keep-alive(default, umd): not clear timers, record & rebuild events
|
|
3474
3496
|
*/
|
|
3475
3497
|
const record = () => {
|
|
3476
|
-
|
|
3477
|
-
|
|
3498
|
+
/**
|
|
3499
|
+
* record onclick handler
|
|
3500
|
+
* onClickHandler maybe set again after prerender/keep-alive app hidden
|
|
3501
|
+
*/
|
|
3502
|
+
sstOnClickHandler = onClickHandler || sstOnClickHandler;
|
|
3478
3503
|
// record document event
|
|
3479
3504
|
eventListenerMap.forEach((listenerList, type) => {
|
|
3480
3505
|
if (listenerList.size) {
|
|
3481
|
-
sstEventListenerMap.
|
|
3506
|
+
const cacheList = sstEventListenerMap.get(type) || [];
|
|
3507
|
+
sstEventListenerMap.set(type, new Set([...cacheList, ...listenerList]));
|
|
3482
3508
|
}
|
|
3483
3509
|
});
|
|
3484
3510
|
};
|
|
3485
3511
|
// rebuild event and timer before remount app
|
|
3486
3512
|
const rebuild = () => {
|
|
3487
3513
|
// rebuild onclick event
|
|
3488
|
-
if (sstOnClickHandler)
|
|
3514
|
+
if (sstOnClickHandler && !onClickHandler)
|
|
3489
3515
|
proxyDocument.onclick = sstOnClickHandler;
|
|
3490
3516
|
// rebuild document event
|
|
3491
3517
|
sstEventListenerMap.forEach((listenerList, type) => {
|
|
@@ -3500,8 +3526,8 @@ function createProxyDocument(appName, sandbox) {
|
|
|
3500
3526
|
// Clear the function bound by micro app through document.onclick
|
|
3501
3527
|
if (isFunction(onClickHandler)) {
|
|
3502
3528
|
rawRemoveEventListener.call(rawDocument, 'click', onClickHandler);
|
|
3503
|
-
onClickHandler = null;
|
|
3504
3529
|
}
|
|
3530
|
+
onClickHandler = null;
|
|
3505
3531
|
// Clear document binding event
|
|
3506
3532
|
if (eventListenerMap.size) {
|
|
3507
3533
|
eventListenerMap.forEach((listenerList, type) => {
|
|
@@ -3631,7 +3657,8 @@ function patchWindowEffect(appName, microAppWindow) {
|
|
|
3631
3657
|
// record window event
|
|
3632
3658
|
eventListenerMap.forEach((listenerList, type) => {
|
|
3633
3659
|
if (listenerList.size) {
|
|
3634
|
-
sstEventListenerMap.
|
|
3660
|
+
const cacheList = sstEventListenerMap.get(type) || [];
|
|
3661
|
+
sstEventListenerMap.set(type, new Set([...cacheList, ...listenerList]));
|
|
3635
3662
|
}
|
|
3636
3663
|
});
|
|
3637
3664
|
};
|
|
@@ -3678,31 +3705,41 @@ function patchWindowEffect(appName, microAppWindow) {
|
|
|
3678
3705
|
|
|
3679
3706
|
// set micro app state to origin state
|
|
3680
3707
|
function setMicroState(appName, microState) {
|
|
3681
|
-
|
|
3682
|
-
|
|
3683
|
-
|
|
3684
|
-
|
|
3685
|
-
|
|
3686
|
-
|
|
3687
|
-
|
|
3688
|
-
|
|
3708
|
+
if (isMemoryRouterEnabled(appName)) {
|
|
3709
|
+
const rawState = globalEnv.rawWindow.history.state;
|
|
3710
|
+
const additionalState = {
|
|
3711
|
+
microAppState: assign({}, rawState === null || rawState === void 0 ? void 0 : rawState.microAppState, {
|
|
3712
|
+
[appName]: microState
|
|
3713
|
+
})
|
|
3714
|
+
};
|
|
3715
|
+
// create new state object
|
|
3716
|
+
return assign({}, rawState, additionalState);
|
|
3717
|
+
}
|
|
3718
|
+
return microState;
|
|
3689
3719
|
}
|
|
3690
3720
|
// delete micro app state form origin state
|
|
3691
3721
|
function removeMicroState(appName, rawState) {
|
|
3692
|
-
if (
|
|
3693
|
-
if (
|
|
3694
|
-
|
|
3695
|
-
|
|
3696
|
-
|
|
3697
|
-
|
|
3722
|
+
if (isMemoryRouterEnabled(appName)) {
|
|
3723
|
+
if (isPlainObject(rawState === null || rawState === void 0 ? void 0 : rawState.microAppState)) {
|
|
3724
|
+
if (!isUndefined(rawState.microAppState[appName])) {
|
|
3725
|
+
delete rawState.microAppState[appName];
|
|
3726
|
+
}
|
|
3727
|
+
if (!Object.keys(rawState.microAppState).length) {
|
|
3728
|
+
delete rawState.microAppState;
|
|
3729
|
+
}
|
|
3698
3730
|
}
|
|
3731
|
+
return assign({}, rawState);
|
|
3699
3732
|
}
|
|
3700
|
-
return
|
|
3733
|
+
return rawState;
|
|
3701
3734
|
}
|
|
3702
3735
|
// get micro app state form origin state
|
|
3703
3736
|
function getMicroState(appName) {
|
|
3704
|
-
var _a
|
|
3705
|
-
|
|
3737
|
+
var _a;
|
|
3738
|
+
const rawState = globalEnv.rawWindow.history.state;
|
|
3739
|
+
if (isMemoryRouterEnabled(appName)) {
|
|
3740
|
+
return ((_a = rawState === null || rawState === void 0 ? void 0 : rawState.microAppState) === null || _a === void 0 ? void 0 : _a[appName]) || null;
|
|
3741
|
+
}
|
|
3742
|
+
return rawState;
|
|
3706
3743
|
}
|
|
3707
3744
|
const ENC_AD_RE = /&/g; // %M1
|
|
3708
3745
|
const ENC_EQ_RE = /=/g; // %M2
|
|
@@ -3740,53 +3777,61 @@ function formatQueryAppName(appName) {
|
|
|
3740
3777
|
function getMicroPathFromURL(appName) {
|
|
3741
3778
|
var _a, _b;
|
|
3742
3779
|
const rawLocation = globalEnv.rawWindow.location;
|
|
3743
|
-
|
|
3744
|
-
|
|
3745
|
-
|
|
3780
|
+
if (isMemoryRouterEnabled(appName)) {
|
|
3781
|
+
const queryObject = getQueryObjectFromURL(rawLocation.search, rawLocation.hash);
|
|
3782
|
+
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)]);
|
|
3783
|
+
return isString(microPath) ? decodeMicroPath(microPath) : null;
|
|
3784
|
+
}
|
|
3785
|
+
return rawLocation.pathname + rawLocation.search + rawLocation.hash;
|
|
3746
3786
|
}
|
|
3747
3787
|
/**
|
|
3748
3788
|
* Attach child app fullPath to browser url
|
|
3749
3789
|
* @param appName app.name
|
|
3750
|
-
* @param
|
|
3790
|
+
* @param targetLocation location of child app or rawLocation of window
|
|
3751
3791
|
*/
|
|
3752
|
-
function setMicroPathToURL(appName,
|
|
3753
|
-
|
|
3754
|
-
const queryObject = getQueryObjectFromURL(search, hash);
|
|
3755
|
-
const encodedMicroPath = encodeMicroPath(microLocation.pathname +
|
|
3756
|
-
microLocation.search +
|
|
3757
|
-
microLocation.hash);
|
|
3758
|
-
/**
|
|
3759
|
-
* Is parent is hash router
|
|
3760
|
-
* In fact, this is not true. It just means that the parameter is added to the hash
|
|
3761
|
-
*/
|
|
3792
|
+
function setMicroPathToURL(appName, targetLocation) {
|
|
3793
|
+
const targetFullPath = targetLocation.pathname + targetLocation.search + targetLocation.hash;
|
|
3762
3794
|
let isAttach2Hash = false;
|
|
3763
|
-
|
|
3764
|
-
|
|
3765
|
-
|
|
3766
|
-
|
|
3767
|
-
|
|
3768
|
-
|
|
3769
|
-
|
|
3770
|
-
|
|
3771
|
-
|
|
3772
|
-
|
|
3773
|
-
|
|
3774
|
-
|
|
3775
|
-
|
|
3776
|
-
|
|
3777
|
-
|
|
3778
|
-
|
|
3779
|
-
|
|
3795
|
+
if (isMemoryRouterEnabled(appName)) {
|
|
3796
|
+
let { pathname, search, hash } = globalEnv.rawWindow.location;
|
|
3797
|
+
const queryObject = getQueryObjectFromURL(search, hash);
|
|
3798
|
+
const encodedMicroPath = encodeMicroPath(targetFullPath);
|
|
3799
|
+
/**
|
|
3800
|
+
* Is parent is hash router
|
|
3801
|
+
* In fact, this is not true. It just means that the parameter is added to the hash
|
|
3802
|
+
*/
|
|
3803
|
+
// If hash exists and search does not exist, it is considered as a hash route
|
|
3804
|
+
if (hash && !search) {
|
|
3805
|
+
isAttach2Hash = true;
|
|
3806
|
+
if (queryObject.hashQuery) {
|
|
3807
|
+
queryObject.hashQuery[formatQueryAppName(appName)] = encodedMicroPath;
|
|
3808
|
+
}
|
|
3809
|
+
else {
|
|
3810
|
+
queryObject.hashQuery = {
|
|
3811
|
+
[formatQueryAppName(appName)]: encodedMicroPath
|
|
3812
|
+
};
|
|
3813
|
+
}
|
|
3814
|
+
const baseHash = hash.includes('?') ? hash.slice(0, hash.indexOf('?') + 1) : hash + '?';
|
|
3815
|
+
hash = baseHash + stringifyQuery(queryObject.hashQuery);
|
|
3780
3816
|
}
|
|
3781
3817
|
else {
|
|
3782
|
-
queryObject.searchQuery
|
|
3783
|
-
[formatQueryAppName(appName)]
|
|
3784
|
-
}
|
|
3818
|
+
if (queryObject.searchQuery) {
|
|
3819
|
+
queryObject.searchQuery[formatQueryAppName(appName)] = encodedMicroPath;
|
|
3820
|
+
}
|
|
3821
|
+
else {
|
|
3822
|
+
queryObject.searchQuery = {
|
|
3823
|
+
[formatQueryAppName(appName)]: encodedMicroPath
|
|
3824
|
+
};
|
|
3825
|
+
}
|
|
3826
|
+
search = '?' + stringifyQuery(queryObject.searchQuery);
|
|
3785
3827
|
}
|
|
3786
|
-
|
|
3828
|
+
return {
|
|
3829
|
+
fullPath: pathname + search + hash,
|
|
3830
|
+
isAttach2Hash,
|
|
3831
|
+
};
|
|
3787
3832
|
}
|
|
3788
3833
|
return {
|
|
3789
|
-
fullPath:
|
|
3834
|
+
fullPath: targetFullPath,
|
|
3790
3835
|
isAttach2Hash,
|
|
3791
3836
|
};
|
|
3792
3837
|
}
|
|
@@ -3798,18 +3843,20 @@ function setMicroPathToURL(appName, microLocation) {
|
|
|
3798
3843
|
function removeMicroPathFromURL(appName, targetLocation) {
|
|
3799
3844
|
var _a, _b, _c, _d;
|
|
3800
3845
|
let { pathname, search, hash } = targetLocation || globalEnv.rawWindow.location;
|
|
3801
|
-
const queryObject = getQueryObjectFromURL(search, hash);
|
|
3802
3846
|
let isAttach2Hash = false;
|
|
3803
|
-
if ((
|
|
3804
|
-
|
|
3805
|
-
(
|
|
3806
|
-
|
|
3807
|
-
|
|
3808
|
-
|
|
3809
|
-
|
|
3810
|
-
|
|
3811
|
-
|
|
3812
|
-
|
|
3847
|
+
if (isMemoryRouterEnabled(appName)) {
|
|
3848
|
+
const queryObject = getQueryObjectFromURL(search, hash);
|
|
3849
|
+
if ((_a = queryObject.hashQuery) === null || _a === void 0 ? void 0 : _a[formatQueryAppName(appName)]) {
|
|
3850
|
+
isAttach2Hash = true;
|
|
3851
|
+
(_b = queryObject.hashQuery) === null || _b === void 0 ? true : delete _b[formatQueryAppName(appName)];
|
|
3852
|
+
const hashQueryStr = stringifyQuery(queryObject.hashQuery);
|
|
3853
|
+
hash = hash.slice(0, hash.indexOf('?') + Number(Boolean(hashQueryStr))) + hashQueryStr;
|
|
3854
|
+
}
|
|
3855
|
+
else if ((_c = queryObject.searchQuery) === null || _c === void 0 ? void 0 : _c[formatQueryAppName(appName)]) {
|
|
3856
|
+
(_d = queryObject.searchQuery) === null || _d === void 0 ? true : delete _d[formatQueryAppName(appName)];
|
|
3857
|
+
const searchQueryStr = stringifyQuery(queryObject.searchQuery);
|
|
3858
|
+
search = searchQueryStr ? '?' + searchQueryStr : '';
|
|
3859
|
+
}
|
|
3813
3860
|
}
|
|
3814
3861
|
return {
|
|
3815
3862
|
fullPath: pathname + search + hash,
|
|
@@ -3849,8 +3896,24 @@ function getNoHashMicroPathFromURL(appName, baseUrl) {
|
|
|
3849
3896
|
*/
|
|
3850
3897
|
function isEffectiveApp(appName) {
|
|
3851
3898
|
const app = appInstanceMap.get(appName);
|
|
3899
|
+
/**
|
|
3900
|
+
* !!(app && !app.isPrefetch && !app.isHidden())
|
|
3901
|
+
* 隐藏的keep-alive应用暂时不作为无效应用,原因如下
|
|
3902
|
+
* 1、隐藏后才执行去除浏览器上的微应用的路由信息的操作,导致微应用的路由信息无法去除
|
|
3903
|
+
* 2、如果保持隐藏应用内部正常跳转,阻止同步路由信息到浏览器,这样理论上是好的,但是对于location跳转改如何处理?location跳转是基于修改浏览器地址后发送popstate事件实现的,所以应该是在隐藏后不支持通过location进行跳转
|
|
3904
|
+
*/
|
|
3852
3905
|
return !!(app && !app.isPrefetch);
|
|
3853
3906
|
}
|
|
3907
|
+
/**
|
|
3908
|
+
* Determine whether the app has enabled memory-router
|
|
3909
|
+
* NOTE:
|
|
3910
|
+
* 1. if sandbox disabled, memory-router is disabled
|
|
3911
|
+
* 2. if app not exist, memory-router is disabled
|
|
3912
|
+
*/
|
|
3913
|
+
function isMemoryRouterEnabled(appName) {
|
|
3914
|
+
const app = appInstanceMap.get(appName);
|
|
3915
|
+
return !!(app && app.sandBox && app.useMemoryRouter);
|
|
3916
|
+
}
|
|
3854
3917
|
|
|
3855
3918
|
/**
|
|
3856
3919
|
* dispatch PopStateEvent & HashChangeEvent to child app
|
|
@@ -3872,26 +3935,7 @@ function addHistoryListener(appName) {
|
|
|
3872
3935
|
excludePreRender: true,
|
|
3873
3936
|
}).includes(appName) &&
|
|
3874
3937
|
!e.onlyForBrowser) {
|
|
3875
|
-
|
|
3876
|
-
const app = appInstanceMap.get(appName);
|
|
3877
|
-
const proxyWindow = app.sandBox.proxyWindow;
|
|
3878
|
-
const microAppWindow = app.sandBox.microAppWindow;
|
|
3879
|
-
let isHashChange = false;
|
|
3880
|
-
// for hashChangeEvent
|
|
3881
|
-
const oldHref = proxyWindow.location.href;
|
|
3882
|
-
// Do not attach micro state to url when microPath is empty
|
|
3883
|
-
if (microPath) {
|
|
3884
|
-
const oldHash = proxyWindow.location.hash;
|
|
3885
|
-
updateMicroLocation(appName, microPath, microAppWindow.location);
|
|
3886
|
-
isHashChange = proxyWindow.location.hash !== oldHash;
|
|
3887
|
-
}
|
|
3888
|
-
// dispatch formatted popStateEvent to child
|
|
3889
|
-
dispatchPopStateEventToMicroApp(appName, proxyWindow, microAppWindow);
|
|
3890
|
-
// dispatch formatted hashChangeEvent to child when hash change
|
|
3891
|
-
if (isHashChange)
|
|
3892
|
-
dispatchHashChangeEventToMicroApp(appName, proxyWindow, microAppWindow, oldHref);
|
|
3893
|
-
// clear element scope before trigger event of next app
|
|
3894
|
-
removeDomScope();
|
|
3938
|
+
updateMicroLocationWithEvent(appName, getMicroPathFromURL(appName));
|
|
3895
3939
|
}
|
|
3896
3940
|
};
|
|
3897
3941
|
rawWindow.addEventListener('popstate', popStateHandler);
|
|
@@ -3899,6 +3943,35 @@ function addHistoryListener(appName) {
|
|
|
3899
3943
|
rawWindow.removeEventListener('popstate', popStateHandler);
|
|
3900
3944
|
};
|
|
3901
3945
|
}
|
|
3946
|
+
/**
|
|
3947
|
+
* Effect: use to trigger child app jump
|
|
3948
|
+
* Actions:
|
|
3949
|
+
* 1. update microLocation with target path
|
|
3950
|
+
* 2. dispatch popStateEvent & hashChangeEvent
|
|
3951
|
+
* @param appName app name
|
|
3952
|
+
* @param targetFullPath target path of child app
|
|
3953
|
+
*/
|
|
3954
|
+
function updateMicroLocationWithEvent(appName, targetFullPath) {
|
|
3955
|
+
const app = appInstanceMap.get(appName);
|
|
3956
|
+
const proxyWindow = app.sandBox.proxyWindow;
|
|
3957
|
+
const microAppWindow = app.sandBox.microAppWindow;
|
|
3958
|
+
let isHashChange = false;
|
|
3959
|
+
// for hashChangeEvent
|
|
3960
|
+
const oldHref = proxyWindow.location.href;
|
|
3961
|
+
// Do not attach micro state to url when targetFullPath is empty
|
|
3962
|
+
if (targetFullPath) {
|
|
3963
|
+
const oldHash = proxyWindow.location.hash;
|
|
3964
|
+
updateMicroLocation(appName, targetFullPath, microAppWindow.location);
|
|
3965
|
+
isHashChange = proxyWindow.location.hash !== oldHash;
|
|
3966
|
+
}
|
|
3967
|
+
// dispatch formatted popStateEvent to child
|
|
3968
|
+
dispatchPopStateEventToMicroApp(appName, proxyWindow, microAppWindow);
|
|
3969
|
+
// dispatch formatted hashChangeEvent to child when hash change
|
|
3970
|
+
if (isHashChange)
|
|
3971
|
+
dispatchHashChangeEventToMicroApp(appName, proxyWindow, microAppWindow, oldHref);
|
|
3972
|
+
// clear element scope before trigger event of next app
|
|
3973
|
+
removeDomScope();
|
|
3974
|
+
}
|
|
3902
3975
|
/**
|
|
3903
3976
|
* dispatch formatted popstate event to microApp
|
|
3904
3977
|
* @param appName app name
|
|
@@ -4061,6 +4134,8 @@ function nativeHistoryNavigate(appName, methodName, fullPath, state = null, titl
|
|
|
4061
4134
|
* 2. proxyHistory.pushState/replaceState with limited popstateEvent
|
|
4062
4135
|
* 3. api microApp.router.push/replace
|
|
4063
4136
|
* 4. proxyLocation.hash = xxx
|
|
4137
|
+
* NOTE:
|
|
4138
|
+
* 1. hidden keep-alive app can jump internally, but will not synchronize to browser
|
|
4064
4139
|
* @param appName app.name
|
|
4065
4140
|
* @param methodName pushState/replaceState
|
|
4066
4141
|
* @param result result of add/remove microApp path on browser url
|
|
@@ -4076,8 +4151,10 @@ function navigateWithNativeEvent(appName, methodName, result, onlyForBrowser, st
|
|
|
4076
4151
|
const oldHref = result.isAttach2Hash && oldFullPath !== result.fullPath ? rawLocation.href : null;
|
|
4077
4152
|
// navigate with native history method
|
|
4078
4153
|
nativeHistoryNavigate(appName, methodName, result.fullPath, state, title);
|
|
4079
|
-
|
|
4154
|
+
// TODO: 如果所有模式统一发送popstate事件,则isMemoryRouterEnabled(appName)要去掉
|
|
4155
|
+
if (oldFullPath !== result.fullPath && isMemoryRouterEnabled(appName)) {
|
|
4080
4156
|
dispatchNativeEvent(appName, onlyForBrowser, oldHref);
|
|
4157
|
+
}
|
|
4081
4158
|
}
|
|
4082
4159
|
}
|
|
4083
4160
|
/**
|
|
@@ -4122,8 +4199,8 @@ function reWriteHistoryMethod(method) {
|
|
|
4122
4199
|
excludeHiddenApp: true,
|
|
4123
4200
|
excludePreRender: true,
|
|
4124
4201
|
}).forEach(appName => {
|
|
4125
|
-
|
|
4126
|
-
|
|
4202
|
+
if (isMemoryRouterEnabled(appName) && !getMicroPathFromURL(appName)) {
|
|
4203
|
+
const app = appInstanceMap.get(appName);
|
|
4127
4204
|
attachRouteToBrowserURL(appName, setMicroPathToURL(appName, app.sandBox.proxyWindow.location), setMicroState(appName, getMicroState(appName)));
|
|
4128
4205
|
}
|
|
4129
4206
|
});
|
|
@@ -4172,12 +4249,14 @@ function createRouterApi() {
|
|
|
4172
4249
|
return function (to) {
|
|
4173
4250
|
const appName = formatAppName(to.name);
|
|
4174
4251
|
if (appName && isString(to.path)) {
|
|
4175
|
-
|
|
4176
|
-
|
|
4177
|
-
|
|
4178
|
-
|
|
4179
|
-
|
|
4180
|
-
|
|
4252
|
+
/**
|
|
4253
|
+
* active apps, exclude prerender app or hidden keep-alive app
|
|
4254
|
+
* NOTE:
|
|
4255
|
+
* 1. prerender app or hidden keep-alive app clear and record popstate event, so we cannot control app jump through the API
|
|
4256
|
+
* 2. disable memory-router
|
|
4257
|
+
*/
|
|
4258
|
+
if (getActiveApps({ excludeHiddenApp: true, excludePreRender: true }).includes(appName)) {
|
|
4259
|
+
const app = appInstanceMap.get(appName);
|
|
4181
4260
|
const microLocation = app.sandBox.proxyWindow.location;
|
|
4182
4261
|
const targetLocation = createURL(to.path, microLocation.href);
|
|
4183
4262
|
// Only get path data, even if the origin is different from microApp
|
|
@@ -4186,20 +4265,48 @@ function createRouterApi() {
|
|
|
4186
4265
|
if (currentFullPath !== targetFullPath || getMicroPathFromURL(appName) !== targetFullPath) {
|
|
4187
4266
|
const methodName = (replace && to.replace !== false) || to.replace === true ? 'replaceState' : 'pushState';
|
|
4188
4267
|
navigateWithRawHistory(appName, methodName, targetLocation, to.state);
|
|
4268
|
+
/**
|
|
4269
|
+
* TODO:
|
|
4270
|
+
* 1. 关闭虚拟路由的跳转地址不同:baseRoute + 子应用地址,文档中要说明
|
|
4271
|
+
* 2. 关闭虚拟路由时跳转方式不同:1、基座跳转但不发送popstate事件 2、控制子应用更新location,内部发送popstate事件。
|
|
4272
|
+
* 补充:
|
|
4273
|
+
* 核心思路:减小对基座的影响(就是子应用跳转不向基座发送popstate事件,其他操作一致),但这是必要的吗,只是多了一个触发popstate的操作
|
|
4274
|
+
* 未来的思路有两种:
|
|
4275
|
+
* 1、减少对基座的影响,主要是解决vue循环刷新的问题
|
|
4276
|
+
* 2、全局发送popstate事件,解决主、子都是vue3的冲突问题
|
|
4277
|
+
* 两者选一个吧,如果选2,则下面这两行代码可以去掉
|
|
4278
|
+
* 要不这样吧,history和search模式采用2,这样可以解决vue3的问题,custom采用1,避免vue循环刷新的问题,这样在用户出现问题时各有解决方案。但反过来说,每种方案又分别导致另外的问题,不统一,导致复杂度增高
|
|
4279
|
+
* 如果关闭虚拟路由,同时发送popstate事件还是无法解决vue3的问题(毕竟history.state理论上还是会冲突),那么就没必要发送popstate事件了。
|
|
4280
|
+
* 。。。。先这样吧
|
|
4281
|
+
*/
|
|
4282
|
+
if (!isMemoryRouterEnabled(appName)) {
|
|
4283
|
+
updateMicroLocationWithEvent(appName, targetFullPath);
|
|
4284
|
+
}
|
|
4189
4285
|
}
|
|
4190
4286
|
}
|
|
4191
4287
|
else {
|
|
4192
|
-
|
|
4193
|
-
* app not exit or unmounted, update browser URL with replaceState
|
|
4194
|
-
* use base app location.origin as baseURL
|
|
4195
|
-
*/
|
|
4196
|
-
const rawLocation = globalEnv.rawWindow.location;
|
|
4197
|
-
const targetLocation = createURL(to.path, rawLocation.origin);
|
|
4198
|
-
const targetFullPath = targetLocation.pathname + targetLocation.search + targetLocation.hash;
|
|
4199
|
-
if (getMicroPathFromURL(appName) !== targetFullPath) {
|
|
4200
|
-
navigateWithRawHistory(appName, to.replace === false ? 'pushState' : 'replaceState', targetLocation, to.state);
|
|
4201
|
-
}
|
|
4288
|
+
logWarn('navigation failed, app does not exist or is inactive');
|
|
4202
4289
|
}
|
|
4290
|
+
// /**
|
|
4291
|
+
// * app not exit or unmounted, update browser URL with replaceState
|
|
4292
|
+
// * use base app location.origin as baseURL
|
|
4293
|
+
// * 应用不存在或已卸载,依然使用replaceState来更新浏览器地址 -- 不合理
|
|
4294
|
+
// */
|
|
4295
|
+
// /**
|
|
4296
|
+
// * TODO: 应用还没渲染或已经卸载最好不要支持跳转了,我知道这是因为解决一些特殊场景,但这么做是非常反直觉的
|
|
4297
|
+
// * 并且在新版本中有多种路由模式,如果应用不存在,我们根本无法知道是哪种模式,那么这里的操作就无意义了。
|
|
4298
|
+
// */
|
|
4299
|
+
// const rawLocation = globalEnv.rawWindow.location
|
|
4300
|
+
// const targetLocation = createURL(to.path, rawLocation.origin)
|
|
4301
|
+
// const targetFullPath = targetLocation.pathname + targetLocation.search + targetLocation.hash
|
|
4302
|
+
// if (getMicroPathFromURL(appName) !== targetFullPath) {
|
|
4303
|
+
// navigateWithRawHistory(
|
|
4304
|
+
// appName,
|
|
4305
|
+
// to.replace === false ? 'pushState' : 'replaceState',
|
|
4306
|
+
// targetLocation,
|
|
4307
|
+
// to.state,
|
|
4308
|
+
// )
|
|
4309
|
+
// }
|
|
4203
4310
|
}
|
|
4204
4311
|
else {
|
|
4205
4312
|
logError(`navigation failed, name & path are required when use router.${replace ? 'replace' : 'push'}`);
|
|
@@ -4259,8 +4366,8 @@ function createRouterApi() {
|
|
|
4259
4366
|
* 2. useMemoryRouter is false
|
|
4260
4367
|
*/
|
|
4261
4368
|
function commonHandlerForAttachToURL(appName) {
|
|
4262
|
-
|
|
4263
|
-
|
|
4369
|
+
if (isMemoryRouterEnabled(appName)) {
|
|
4370
|
+
const app = appInstanceMap.get(appName);
|
|
4264
4371
|
attachRouteToBrowserURL(appName, setMicroPathToURL(appName, app.sandBox.proxyWindow.location), setMicroState(appName, getMicroState(appName)));
|
|
4265
4372
|
}
|
|
4266
4373
|
}
|
|
@@ -4512,37 +4619,40 @@ function createMicroLocation(appName, url, microAppWindow, childStaticLocation,
|
|
|
4512
4619
|
// Even if the origin is the same, developers still have the possibility of want to jump to a new page
|
|
4513
4620
|
if (targetLocation.origin === proxyLocation.origin) {
|
|
4514
4621
|
const setMicroPathResult = setMicroPathToURL(appName, targetLocation);
|
|
4515
|
-
|
|
4516
|
-
|
|
4517
|
-
|
|
4518
|
-
|
|
4519
|
-
|
|
4520
|
-
|
|
4521
|
-
|
|
4522
|
-
|
|
4523
|
-
|
|
4524
|
-
|
|
4525
|
-
|
|
4526
|
-
|
|
4527
|
-
|
|
4528
|
-
|
|
4529
|
-
|
|
4530
|
-
|
|
4531
|
-
|
|
4622
|
+
// if disable memory-router, navigate directly through rawLocation
|
|
4623
|
+
if (isMemoryRouterEnabled(appName)) {
|
|
4624
|
+
/**
|
|
4625
|
+
* change hash with location.href will not trigger the browser reload
|
|
4626
|
+
* so we use pushState & reload to imitate href behavior
|
|
4627
|
+
* NOTE:
|
|
4628
|
+
* 1. if child app only change hash, it should not trigger browser reload
|
|
4629
|
+
* 2. if address is same and has hash, it should not add route stack
|
|
4630
|
+
*/
|
|
4631
|
+
if (targetLocation.pathname === proxyLocation.pathname &&
|
|
4632
|
+
targetLocation.search === proxyLocation.search) {
|
|
4633
|
+
let oldHref = null;
|
|
4634
|
+
if (targetLocation.hash !== proxyLocation.hash) {
|
|
4635
|
+
if (setMicroPathResult.isAttach2Hash)
|
|
4636
|
+
oldHref = rawLocation.href;
|
|
4637
|
+
nativeHistoryNavigate(appName, methodName, setMicroPathResult.fullPath);
|
|
4638
|
+
}
|
|
4639
|
+
if (targetLocation.hash) {
|
|
4640
|
+
dispatchNativeEvent(appName, false, oldHref);
|
|
4641
|
+
}
|
|
4642
|
+
else {
|
|
4643
|
+
reload();
|
|
4644
|
+
}
|
|
4645
|
+
return void 0;
|
|
4646
|
+
/**
|
|
4647
|
+
* when baseApp is hash router, address change of child can not reload browser
|
|
4648
|
+
* so we imitate behavior of browser (reload) manually
|
|
4649
|
+
*/
|
|
4532
4650
|
}
|
|
4533
|
-
else {
|
|
4651
|
+
else if (setMicroPathResult.isAttach2Hash) {
|
|
4652
|
+
nativeHistoryNavigate(appName, methodName, setMicroPathResult.fullPath);
|
|
4534
4653
|
reload();
|
|
4654
|
+
return void 0;
|
|
4535
4655
|
}
|
|
4536
|
-
return void 0;
|
|
4537
|
-
/**
|
|
4538
|
-
* when baseApp is hash router, address change of child can not reload browser
|
|
4539
|
-
* so we imitate behavior of browser (reload) manually
|
|
4540
|
-
*/
|
|
4541
|
-
}
|
|
4542
|
-
else if (setMicroPathResult.isAttach2Hash) {
|
|
4543
|
-
nativeHistoryNavigate(appName, methodName, setMicroPathResult.fullPath);
|
|
4544
|
-
reload();
|
|
4545
|
-
return void 0;
|
|
4546
4656
|
}
|
|
4547
4657
|
return setMicroPathResult.fullPath;
|
|
4548
4658
|
}
|
|
@@ -4634,19 +4744,34 @@ function createMicroLocation(appName, url, microAppWindow, childStaticLocation,
|
|
|
4634
4744
|
}
|
|
4635
4745
|
}
|
|
4636
4746
|
else if (key === 'pathname') {
|
|
4637
|
-
|
|
4638
|
-
|
|
4747
|
+
if (isMemoryRouterEnabled(appName)) {
|
|
4748
|
+
const targetPath = ('/' + value).replace(/^\/+/, '/') + proxyLocation.search + proxyLocation.hash;
|
|
4749
|
+
handleForPathNameAndSearch(targetPath, 'pathname');
|
|
4750
|
+
}
|
|
4751
|
+
else {
|
|
4752
|
+
rawLocation.pathname = value;
|
|
4753
|
+
}
|
|
4639
4754
|
}
|
|
4640
4755
|
else if (key === 'search') {
|
|
4641
|
-
|
|
4642
|
-
|
|
4756
|
+
if (isMemoryRouterEnabled(appName)) {
|
|
4757
|
+
const targetPath = proxyLocation.pathname + ('?' + value).replace(/^\?+/, '?') + proxyLocation.hash;
|
|
4758
|
+
handleForPathNameAndSearch(targetPath, 'search');
|
|
4759
|
+
}
|
|
4760
|
+
else {
|
|
4761
|
+
rawLocation.search = value;
|
|
4762
|
+
}
|
|
4643
4763
|
}
|
|
4644
4764
|
else if (key === 'hash') {
|
|
4645
|
-
|
|
4646
|
-
|
|
4647
|
-
|
|
4648
|
-
|
|
4649
|
-
|
|
4765
|
+
if (isMemoryRouterEnabled(appName)) {
|
|
4766
|
+
const targetPath = proxyLocation.pathname + proxyLocation.search + ('#' + value).replace(/^#+/, '#');
|
|
4767
|
+
const targetLocation = createURL(targetPath, url);
|
|
4768
|
+
// The same hash will not trigger popStateEvent
|
|
4769
|
+
if (targetLocation.hash !== proxyLocation.hash) {
|
|
4770
|
+
navigateWithNativeEvent(appName, 'pushState', setMicroPathToURL(appName, targetLocation), false);
|
|
4771
|
+
}
|
|
4772
|
+
}
|
|
4773
|
+
else {
|
|
4774
|
+
rawLocation.hash = value;
|
|
4650
4775
|
}
|
|
4651
4776
|
}
|
|
4652
4777
|
else {
|
|
@@ -4691,6 +4816,7 @@ function updateMicroLocation(appName, path, microLocation, type) {
|
|
|
4691
4816
|
var _a;
|
|
4692
4817
|
// record old values of microLocation to `from`
|
|
4693
4818
|
const from = createGuardLocation(appName, microLocation);
|
|
4819
|
+
// if is iframeSandbox, microLocation muse be rawLocation of iframe, not proxyLocation
|
|
4694
4820
|
const newLocation = createURL(path, microLocation.href);
|
|
4695
4821
|
if (isIframeSandbox(appName)) {
|
|
4696
4822
|
const microAppWindow = appInstanceMap.get(appName).sandBox.microAppWindow;
|
|
@@ -4709,6 +4835,15 @@ function updateMicroLocation(appName, path, microLocation, type) {
|
|
|
4709
4835
|
}
|
|
4710
4836
|
}
|
|
4711
4837
|
|
|
4838
|
+
/**
|
|
4839
|
+
* TODO: 关于关闭虚拟路由系统的临时笔记
|
|
4840
|
+
* 1. with沙箱关闭虚拟路由最好和iframe保持一致
|
|
4841
|
+
* 2. default-page无法使用,但是用基座的地址可以实现一样的效果
|
|
4842
|
+
* 3. keep-router-state功能失效,因为始终为true
|
|
4843
|
+
* 4. 基座控制子应用跳转地址改变,正确的值为:baseRoute + 子应用地址,这要在文档中说明,否则很容易出错,确实也很难理解
|
|
4844
|
+
* 5. 是否需要发送popstate事件,为了减小对基座的影响,现在不发送
|
|
4845
|
+
* 6. 关闭后导致的vue3路由冲突问题需要在文档中明确指出(2处:在关闭虚拟路由系统的配置那里着重说明,在vue常见问题中说明)
|
|
4846
|
+
*/
|
|
4712
4847
|
/**
|
|
4713
4848
|
* The router system has two operations: read and write
|
|
4714
4849
|
* Read through location and write through history & location
|
|
@@ -4740,7 +4875,9 @@ function initRouteStateWithURL(appName, microLocation, defaultPage) {
|
|
|
4740
4875
|
}
|
|
4741
4876
|
/**
|
|
4742
4877
|
* initialize browser information according to microLocation
|
|
4743
|
-
*
|
|
4878
|
+
* Scenes:
|
|
4879
|
+
* 1. sandbox.start
|
|
4880
|
+
* 2. reshow of keep-alive app
|
|
4744
4881
|
*/
|
|
4745
4882
|
function updateBrowserURLWithLocation(appName, microLocation, defaultPage) {
|
|
4746
4883
|
// update microLocation with defaultPage
|
|
@@ -4763,14 +4900,14 @@ function clearRouteStateFromURL(appName, url, microLocation, keepRouteState) {
|
|
|
4763
4900
|
const { pathname, search, hash } = createURL(url);
|
|
4764
4901
|
updateMicroLocation(appName, pathname + search + hash, microLocation, 'prevent');
|
|
4765
4902
|
}
|
|
4766
|
-
|
|
4903
|
+
removePathFromBrowser(appName);
|
|
4767
4904
|
clearRouterWhenUnmount(appName);
|
|
4768
4905
|
}
|
|
4769
4906
|
/**
|
|
4770
4907
|
* remove microState from history.state and remove microPath from browserURL
|
|
4771
4908
|
* called on sandbox.stop or hidden of keep-alive app
|
|
4772
4909
|
*/
|
|
4773
|
-
function
|
|
4910
|
+
function removePathFromBrowser(appName) {
|
|
4774
4911
|
attachRouteToBrowserURL(appName, removeMicroPathFromURL(appName), removeMicroState(appName, globalEnv.rawWindow.history.state));
|
|
4775
4912
|
}
|
|
4776
4913
|
|
|
@@ -4914,6 +5051,7 @@ class WithSandBox {
|
|
|
4914
5051
|
if (this.active)
|
|
4915
5052
|
return;
|
|
4916
5053
|
this.active = true;
|
|
5054
|
+
// TODO: with沙箱关闭虚拟路由保持和iframe一致
|
|
4917
5055
|
if (useMemoryRouter) {
|
|
4918
5056
|
if (isUndefined(this.microAppWindow.location)) {
|
|
4919
5057
|
this.setMicroAppRouter(this.microAppWindow.__MICRO_APP_NAME__, this.microAppWindow.__MICRO_APP_URL__, this.microAppWindow);
|
|
@@ -4950,16 +5088,18 @@ class WithSandBox {
|
|
|
4950
5088
|
* @param keepRouteState prevent reset route
|
|
4951
5089
|
* @param destroy completely destroy, delete cache resources
|
|
4952
5090
|
* @param clearData clear data from base app
|
|
5091
|
+
* @param useMemoryRouter use virtual router
|
|
4953
5092
|
*/
|
|
4954
|
-
stop({ umdMode, keepRouteState, destroy, clearData, }) {
|
|
5093
|
+
stop({ umdMode, keepRouteState, destroy, clearData, useMemoryRouter, }) {
|
|
5094
|
+
var _a;
|
|
4955
5095
|
if (!this.active)
|
|
4956
5096
|
return;
|
|
4957
5097
|
this.recordAndReleaseEffect({ umdMode, clearData, destroy }, !umdMode || destroy);
|
|
4958
|
-
if (
|
|
5098
|
+
if (useMemoryRouter) {
|
|
4959
5099
|
this.clearRouteState(keepRouteState);
|
|
4960
|
-
// release listener of popstate
|
|
4961
|
-
this.removeHistoryListener();
|
|
4962
5100
|
}
|
|
5101
|
+
// release listener of popstate for child app
|
|
5102
|
+
(_a = this.removeHistoryListener) === null || _a === void 0 ? void 0 : _a.call(this);
|
|
4963
5103
|
/**
|
|
4964
5104
|
* NOTE:
|
|
4965
5105
|
* 1. injectedKeys and escapeKeys must be placed at the back
|
|
@@ -5401,7 +5541,7 @@ class WithSandBox {
|
|
|
5401
5541
|
updateBrowserURLWithLocation(this.microAppWindow.__MICRO_APP_NAME__, this.microAppWindow.location);
|
|
5402
5542
|
}
|
|
5403
5543
|
removeRouteInfoForKeepAliveApp() {
|
|
5404
|
-
|
|
5544
|
+
removePathFromBrowser(this.microAppWindow.__MICRO_APP_NAME__);
|
|
5405
5545
|
}
|
|
5406
5546
|
/**
|
|
5407
5547
|
* Format all html elements when init
|
|
@@ -5551,7 +5691,8 @@ function patchWindowEffect$1(microAppWindow) {
|
|
|
5551
5691
|
// record window event
|
|
5552
5692
|
eventListenerMap.forEach((listenerList, type) => {
|
|
5553
5693
|
if (listenerList.size) {
|
|
5554
|
-
sstEventListenerMap.
|
|
5694
|
+
const cacheList = sstEventListenerMap.get(type) || [];
|
|
5695
|
+
sstEventListenerMap.set(type, new Set([...cacheList, ...listenerList]));
|
|
5555
5696
|
}
|
|
5556
5697
|
});
|
|
5557
5698
|
};
|
|
@@ -5839,19 +5980,23 @@ function patchDocumentEffect(appName, microAppWindow) {
|
|
|
5839
5980
|
* 3. after init prerender app
|
|
5840
5981
|
*/
|
|
5841
5982
|
const record = () => {
|
|
5842
|
-
|
|
5843
|
-
|
|
5983
|
+
/**
|
|
5984
|
+
* record onclick handler
|
|
5985
|
+
* onClickHandler maybe set again after prerender/keep-alive app hidden
|
|
5986
|
+
*/
|
|
5987
|
+
sstOnClickHandler = onClickHandler || sstOnClickHandler;
|
|
5844
5988
|
// record document event
|
|
5845
5989
|
eventListenerMap.forEach((listenerList, type) => {
|
|
5846
5990
|
if (listenerList.size) {
|
|
5847
|
-
sstEventListenerMap.
|
|
5991
|
+
const cacheList = sstEventListenerMap.get(type) || [];
|
|
5992
|
+
sstEventListenerMap.set(type, new Set([...cacheList, ...listenerList]));
|
|
5848
5993
|
}
|
|
5849
5994
|
});
|
|
5850
5995
|
};
|
|
5851
5996
|
// rebuild event and timer before remount app
|
|
5852
5997
|
const rebuild = () => {
|
|
5853
5998
|
// rebuild onclick event
|
|
5854
|
-
if (sstOnClickHandler)
|
|
5999
|
+
if (sstOnClickHandler && !onClickHandler)
|
|
5855
6000
|
microDocument.onclick = sstOnClickHandler;
|
|
5856
6001
|
sstEventListenerMap.forEach((listenerList, type) => {
|
|
5857
6002
|
for (const listener of listenerList) {
|
|
@@ -5864,8 +6009,8 @@ function patchDocumentEffect(appName, microAppWindow) {
|
|
|
5864
6009
|
// Clear the function bound by micro app through document.onclick
|
|
5865
6010
|
if (isFunction(onClickHandler)) {
|
|
5866
6011
|
rawRemoveEventListener.call(rawDocument, 'click', onClickHandler);
|
|
5867
|
-
onClickHandler = null;
|
|
5868
6012
|
}
|
|
6013
|
+
onClickHandler = null;
|
|
5869
6014
|
// Clear document binding event
|
|
5870
6015
|
if (eventListenerMap.size) {
|
|
5871
6016
|
eventListenerMap.forEach((listenerList, type) => {
|
|
@@ -6174,14 +6319,29 @@ class IframeSandbox {
|
|
|
6174
6319
|
if (this.active)
|
|
6175
6320
|
return;
|
|
6176
6321
|
this.active = true;
|
|
6177
|
-
|
|
6178
|
-
|
|
6179
|
-
|
|
6180
|
-
|
|
6181
|
-
|
|
6182
|
-
|
|
6183
|
-
|
|
6184
|
-
|
|
6322
|
+
/**
|
|
6323
|
+
* Sync router info to iframe when exec sandbox.start with disable or enable memory-router
|
|
6324
|
+
* e.g.:
|
|
6325
|
+
* vue-router@4.x get target path by remove the base section from rawLocation.pathname
|
|
6326
|
+
* code: window.location.pathname.slice(base.length) || '/'; (base is baseroute)
|
|
6327
|
+
* NOTE:
|
|
6328
|
+
* 1. iframe router and browser router are separated, we should update iframe router manually
|
|
6329
|
+
* 2. withSandbox location is browser location when disable memory-router, so no need to do anything
|
|
6330
|
+
*/
|
|
6331
|
+
/**
|
|
6332
|
+
* TODO:
|
|
6333
|
+
* 做一些记录:
|
|
6334
|
+
* 1. iframe关闭虚拟路由系统后,default-page无法使用,推荐用户直接使用浏览器地址控制首页渲染
|
|
6335
|
+
* 补充:keep-router-state 也无法配置,因为keep-router-state一定为true。
|
|
6336
|
+
* 2. 导航拦截、current.route 可以正常使用
|
|
6337
|
+
* 3. 可以正常控制子应用跳转,方式还是自上而下(也可以是子应用内部跳转,这种方式更好一点,减小对基座的影响,不会导致vue的循环刷新)
|
|
6338
|
+
* 4. 关闭虚拟路由以后会对应 route-mode='custom' 模式,包括with沙箱也会这么做
|
|
6339
|
+
* 5. 关闭虚拟路由是指尽可能模式没有虚拟路由的情况,子应用直接获取浏览器location和history,控制浏览器跳转
|
|
6340
|
+
*/
|
|
6341
|
+
this.initRouteState(defaultPage);
|
|
6342
|
+
// unique listener of popstate event for child app
|
|
6343
|
+
this.removeHistoryListener = addHistoryListener(this.microAppWindow.__MICRO_APP_NAME__);
|
|
6344
|
+
if (!useMemoryRouter) {
|
|
6185
6345
|
this.microAppWindow.__MICRO_APP_BASE_ROUTE__ = this.microAppWindow.__MICRO_APP_BASE_URL__ = baseroute;
|
|
6186
6346
|
}
|
|
6187
6347
|
/**
|
|
@@ -6197,15 +6357,15 @@ class IframeSandbox {
|
|
|
6197
6357
|
}
|
|
6198
6358
|
if (++IframeSandbox.activeCount === 1) ;
|
|
6199
6359
|
}
|
|
6200
|
-
stop({ umdMode, keepRouteState, destroy, clearData, }) {
|
|
6360
|
+
stop({ umdMode, keepRouteState, destroy, clearData, useMemoryRouter, }) {
|
|
6361
|
+
var _a;
|
|
6201
6362
|
if (!this.active)
|
|
6202
6363
|
return;
|
|
6203
6364
|
this.recordAndReleaseEffect({ clearData }, !umdMode || destroy);
|
|
6204
|
-
if
|
|
6205
|
-
|
|
6206
|
-
|
|
6207
|
-
|
|
6208
|
-
}
|
|
6365
|
+
// if keep-route-state is true or disable memory-router, preserve microLocation state
|
|
6366
|
+
this.clearRouteState(keepRouteState || !useMemoryRouter);
|
|
6367
|
+
// release listener of popstate for child app
|
|
6368
|
+
(_a = this.removeHistoryListener) === null || _a === void 0 ? void 0 : _a.call(this);
|
|
6209
6369
|
if (!umdMode || destroy) {
|
|
6210
6370
|
this.deleteIframeElement();
|
|
6211
6371
|
this.escapeKeys.forEach((key) => {
|
|
@@ -6275,8 +6435,9 @@ class IframeSandbox {
|
|
|
6275
6435
|
* 2. unmount prerender app manually
|
|
6276
6436
|
*/
|
|
6277
6437
|
resetEffectSnapshot() {
|
|
6278
|
-
|
|
6279
|
-
this.
|
|
6438
|
+
var _a, _b;
|
|
6439
|
+
(_a = this.windowEffect) === null || _a === void 0 ? void 0 : _a.reset();
|
|
6440
|
+
(_b = this.documentEffect) === null || _b === void 0 ? void 0 : _b.reset();
|
|
6280
6441
|
resetDataCenterSnapshot(this.microAppWindow.microApp);
|
|
6281
6442
|
}
|
|
6282
6443
|
/**
|
|
@@ -6287,14 +6448,16 @@ class IframeSandbox {
|
|
|
6287
6448
|
* 3. after init prerender app
|
|
6288
6449
|
*/
|
|
6289
6450
|
recordEffectSnapshot() {
|
|
6290
|
-
|
|
6291
|
-
this.
|
|
6451
|
+
var _a, _b;
|
|
6452
|
+
(_a = this.windowEffect) === null || _a === void 0 ? void 0 : _a.record();
|
|
6453
|
+
(_b = this.documentEffect) === null || _b === void 0 ? void 0 : _b.record();
|
|
6292
6454
|
recordDataCenterSnapshot(this.microAppWindow.microApp);
|
|
6293
6455
|
}
|
|
6294
6456
|
// rebuild umd snapshot before remount umd app
|
|
6295
6457
|
rebuildEffectSnapshot() {
|
|
6296
|
-
|
|
6297
|
-
this.
|
|
6458
|
+
var _a, _b;
|
|
6459
|
+
(_a = this.windowEffect) === null || _a === void 0 ? void 0 : _a.rebuild();
|
|
6460
|
+
(_b = this.documentEffect) === null || _b === void 0 ? void 0 : _b.rebuild();
|
|
6298
6461
|
rebuildDataCenterSnapshot(this.microAppWindow.microApp);
|
|
6299
6462
|
}
|
|
6300
6463
|
/**
|
|
@@ -6308,14 +6471,14 @@ class IframeSandbox {
|
|
|
6308
6471
|
* @param keepAlive is keep-alive app
|
|
6309
6472
|
*/
|
|
6310
6473
|
releaseGlobalEffect({ clearData = false }) {
|
|
6311
|
-
var _a, _b, _c;
|
|
6312
|
-
this.windowEffect.release();
|
|
6313
|
-
this.documentEffect.release();
|
|
6314
|
-
(
|
|
6315
|
-
(
|
|
6474
|
+
var _a, _b, _c, _d, _e;
|
|
6475
|
+
(_a = this.windowEffect) === null || _a === void 0 ? void 0 : _a.release();
|
|
6476
|
+
(_b = this.documentEffect) === null || _b === void 0 ? void 0 : _b.release();
|
|
6477
|
+
(_c = this.microAppWindow.microApp) === null || _c === void 0 ? void 0 : _c.clearDataListener();
|
|
6478
|
+
(_d = this.microAppWindow.microApp) === null || _d === void 0 ? void 0 : _d.clearGlobalDataListener();
|
|
6316
6479
|
if (clearData) {
|
|
6317
6480
|
microApp.clearData(this.microAppWindow.__MICRO_APP_NAME__);
|
|
6318
|
-
(
|
|
6481
|
+
(_e = this.microAppWindow.microApp) === null || _e === void 0 ? void 0 : _e.clearData();
|
|
6319
6482
|
}
|
|
6320
6483
|
}
|
|
6321
6484
|
// set __MICRO_APP_PRE_RENDER__ state
|
|
@@ -6445,7 +6608,7 @@ class IframeSandbox {
|
|
|
6445
6608
|
updateBrowserURLWithLocation(this.microAppWindow.__MICRO_APP_NAME__, this.microAppWindow.location);
|
|
6446
6609
|
}
|
|
6447
6610
|
removeRouteInfoForKeepAliveApp() {
|
|
6448
|
-
|
|
6611
|
+
removePathFromBrowser(this.microAppWindow.__MICRO_APP_NAME__);
|
|
6449
6612
|
}
|
|
6450
6613
|
/**
|
|
6451
6614
|
* Format all html elements when init
|
|
@@ -6570,9 +6733,14 @@ class CreateApp {
|
|
|
6570
6733
|
var _a;
|
|
6571
6734
|
if (++this.loadSourceLevel === 2) {
|
|
6572
6735
|
this.source.html = html;
|
|
6573
|
-
this.
|
|
6574
|
-
if (!this.isPrefetch && appStates.UNMOUNT !== this.state) {
|
|
6736
|
+
if (!this.isPrefetch && !this.isUnmounted()) {
|
|
6575
6737
|
getRootContainer(this.container).mount(this);
|
|
6738
|
+
// Abandonment plan
|
|
6739
|
+
// if (this.isHidden()) {
|
|
6740
|
+
// getRootContainer(this.container!).unmount()
|
|
6741
|
+
// } else if (!this.isUnmounted()) {
|
|
6742
|
+
// getRootContainer(this.container!).mount(this)
|
|
6743
|
+
// }
|
|
6576
6744
|
}
|
|
6577
6745
|
else if (this.isPrerender) {
|
|
6578
6746
|
/**
|
|
@@ -6613,7 +6781,7 @@ class CreateApp {
|
|
|
6613
6781
|
*/
|
|
6614
6782
|
onLoadError(e) {
|
|
6615
6783
|
this.loadSourceLevel = -1;
|
|
6616
|
-
if (
|
|
6784
|
+
if (!this.isUnmounted()) {
|
|
6617
6785
|
this.onerror(e);
|
|
6618
6786
|
this.setAppState(appStates.LOAD_FAILED);
|
|
6619
6787
|
}
|
|
@@ -6667,7 +6835,7 @@ class CreateApp {
|
|
|
6667
6835
|
*/
|
|
6668
6836
|
(_a = this.sandBox) === null || _a === void 0 ? void 0 : _a.rebuildEffectSnapshot();
|
|
6669
6837
|
// current this.container is <div prerender='true'></div>
|
|
6670
|
-
cloneContainer(
|
|
6838
|
+
cloneContainer(container, this.container, false);
|
|
6671
6839
|
/**
|
|
6672
6840
|
* set this.container to <micro-app></micro-app>
|
|
6673
6841
|
* NOTE:
|
|
@@ -6698,7 +6866,7 @@ class CreateApp {
|
|
|
6698
6866
|
}
|
|
6699
6867
|
this.setAppState(appStates.MOUNTING);
|
|
6700
6868
|
// TODO: 将所有cloneContainer中的'as Element'去掉,兼容shadowRoot的场景
|
|
6701
|
-
cloneContainer(this.
|
|
6869
|
+
cloneContainer(this.container, this.source.html, !this.umdMode);
|
|
6702
6870
|
(_e = this.sandBox) === null || _e === void 0 ? void 0 : _e.start({
|
|
6703
6871
|
umdMode: this.umdMode,
|
|
6704
6872
|
baseroute,
|
|
@@ -6778,13 +6946,28 @@ class CreateApp {
|
|
|
6778
6946
|
* dispatch mounted event when app run finished
|
|
6779
6947
|
*/
|
|
6780
6948
|
dispatchMountedEvent() {
|
|
6781
|
-
|
|
6949
|
+
var _a;
|
|
6950
|
+
if (!this.isUnmounted()) {
|
|
6782
6951
|
this.setAppState(appStates.MOUNTED);
|
|
6783
6952
|
// call window.onmount of child app
|
|
6784
6953
|
execMicroAppGlobalHook(this.getMicroAppGlobalHook(microGlobalEvent.ONMOUNT), this.name, microGlobalEvent.ONMOUNT, microApp.getData(this.name, true));
|
|
6785
6954
|
// dispatch event mounted to parent
|
|
6786
6955
|
dispatchLifecyclesEvent(this.container, this.name, lifeCycles.MOUNTED);
|
|
6956
|
+
/**
|
|
6957
|
+
* Hidden Keep-alive app during resource loading, render normally to ensure their liveliness (running in the background) characteristics.
|
|
6958
|
+
* Actions:
|
|
6959
|
+
* 1. Record & release all global events after mount
|
|
6960
|
+
*/
|
|
6961
|
+
if (this.isHidden()) {
|
|
6962
|
+
(_a = this.sandBox) === null || _a === void 0 ? void 0 : _a.recordAndReleaseEffect({ keepAlive: true });
|
|
6963
|
+
}
|
|
6787
6964
|
}
|
|
6965
|
+
/**
|
|
6966
|
+
* TODO: 这里增加一个处理,如果渲染完成时已经卸载,则进行一些操作
|
|
6967
|
+
* 如果是默认模式:删除所有事件和定时器
|
|
6968
|
+
* 如果是umd模式:重新记录和清空事件
|
|
6969
|
+
* 补充:非必需,优先级低
|
|
6970
|
+
*/
|
|
6788
6971
|
}
|
|
6789
6972
|
/**
|
|
6790
6973
|
* unmount app
|
|
@@ -6853,7 +7036,7 @@ class CreateApp {
|
|
|
6853
7036
|
actionsForUnmount({ destroy, clearData, keepRouteState, unmountcb, }) {
|
|
6854
7037
|
var _a;
|
|
6855
7038
|
if (this.umdMode && this.container && !destroy) {
|
|
6856
|
-
cloneContainer(this.
|
|
7039
|
+
cloneContainer(this.source.html, this.container, false);
|
|
6857
7040
|
}
|
|
6858
7041
|
/**
|
|
6859
7042
|
* this.container maybe contains micro-app element, stop sandbox should exec after cloneContainer
|
|
@@ -6866,6 +7049,7 @@ class CreateApp {
|
|
|
6866
7049
|
keepRouteState: keepRouteState && !destroy,
|
|
6867
7050
|
destroy,
|
|
6868
7051
|
clearData: clearData || destroy,
|
|
7052
|
+
useMemoryRouter: this.useMemoryRouter,
|
|
6869
7053
|
});
|
|
6870
7054
|
// dispatch unmount event to base app
|
|
6871
7055
|
dispatchLifecyclesEvent(this.container, this.name, lifeCycles.UNMOUNT);
|
|
@@ -6909,7 +7093,6 @@ class CreateApp {
|
|
|
6909
7093
|
// called after lifeCyclesEvent
|
|
6910
7094
|
(_a = this.sandBox) === null || _a === void 0 ? void 0 : _a.removeRouteInfoForKeepAliveApp();
|
|
6911
7095
|
}
|
|
6912
|
-
this.container = cloneContainer(this.container, pureCreateElement('div'), false);
|
|
6913
7096
|
(_b = this.sandBox) === null || _b === void 0 ? void 0 : _b.recordAndReleaseEffect({ keepAlive: true });
|
|
6914
7097
|
callback === null || callback === void 0 ? void 0 : callback();
|
|
6915
7098
|
}
|
|
@@ -6924,7 +7107,13 @@ class CreateApp {
|
|
|
6924
7107
|
// dispatch beforeShow event to base app
|
|
6925
7108
|
dispatchLifecyclesEvent(container, this.name, lifeCycles.BEFORESHOW);
|
|
6926
7109
|
this.setKeepAliveState(keepAliveStates.KEEP_ALIVE_SHOW);
|
|
6927
|
-
this.container = cloneContainer(
|
|
7110
|
+
this.container = cloneContainer(container, this.container, false);
|
|
7111
|
+
/**
|
|
7112
|
+
* TODO:
|
|
7113
|
+
* 1. iframe沙箱在关闭虚拟路由系统时,重新展示时不更新浏览器地址,这样和with沙箱保持一致。
|
|
7114
|
+
* 但是iframe是可以做到重新展示时更新浏览器地址的,这里临时不支持,等待后续with沙箱也支持的时候再优化
|
|
7115
|
+
* 只需要去除 if (this.useMemoryRouter) 的判断即可
|
|
7116
|
+
*/
|
|
6928
7117
|
if (this.useMemoryRouter) {
|
|
6929
7118
|
// called before lifeCyclesEvent
|
|
6930
7119
|
(_b = this.sandBox) === null || _b === void 0 ? void 0 : _b.setRouteInfoForKeepAliveApp();
|
|
@@ -6975,10 +7164,18 @@ class CreateApp {
|
|
|
6975
7164
|
getKeepAliveState() {
|
|
6976
7165
|
return this.keepAliveState;
|
|
6977
7166
|
}
|
|
7167
|
+
// is app unmounted
|
|
7168
|
+
isUnmounted() {
|
|
7169
|
+
return appStates.UNMOUNT === this.state;
|
|
7170
|
+
}
|
|
7171
|
+
// is app already hidden
|
|
7172
|
+
isHidden() {
|
|
7173
|
+
return keepAliveStates.KEEP_ALIVE_HIDDEN === this.keepAliveState;
|
|
7174
|
+
}
|
|
6978
7175
|
// get umd library, if it not exist, return empty object
|
|
6979
7176
|
getUmdLibraryHooks() {
|
|
6980
7177
|
// after execScripts, the app maybe unmounted
|
|
6981
|
-
if (
|
|
7178
|
+
if (!this.isUnmounted() && this.sandBox) {
|
|
6982
7179
|
const libraryName = getRootContainer(this.container).getAttribute('library') || `micro-app-${this.name}`;
|
|
6983
7180
|
const proxyWindow = this.sandBox.proxyWindow;
|
|
6984
7181
|
// compatible with pre versions
|
|
@@ -7041,16 +7238,14 @@ function defineElement(tagName) {
|
|
|
7041
7238
|
* If oldApp exist & appName is different, determine whether oldApp is running
|
|
7042
7239
|
*/
|
|
7043
7240
|
if (formatAttrName !== this.appName && oldApp) {
|
|
7044
|
-
if (oldApp.
|
|
7045
|
-
oldApp.getKeepAliveState() !== keepAliveStates.KEEP_ALIVE_HIDDEN &&
|
|
7046
|
-
!oldApp.isPrefetch) {
|
|
7241
|
+
if (!oldApp.isUnmounted() && !oldApp.isHidden() && !oldApp.isPrefetch) {
|
|
7047
7242
|
this.setAttribute('name', this.appName);
|
|
7048
7243
|
return logError(`app name conflict, an app named ${formatAttrName} is running`);
|
|
7049
7244
|
}
|
|
7050
7245
|
}
|
|
7051
7246
|
if (formatAttrName !== this.appName || formatAttrUrl !== this.appUrl) {
|
|
7052
7247
|
if (formatAttrName === this.appName) {
|
|
7053
|
-
this.
|
|
7248
|
+
this.unmount(true, () => {
|
|
7054
7249
|
this.actionsForAttributeChange(formatAttrName, formatAttrUrl, oldApp);
|
|
7055
7250
|
});
|
|
7056
7251
|
}
|
|
@@ -7059,7 +7254,7 @@ function defineElement(tagName) {
|
|
|
7059
7254
|
this.actionsForAttributeChange(formatAttrName, formatAttrUrl, oldApp);
|
|
7060
7255
|
}
|
|
7061
7256
|
else {
|
|
7062
|
-
this.
|
|
7257
|
+
this.unmount(false, () => {
|
|
7063
7258
|
this.actionsForAttributeChange(formatAttrName, formatAttrUrl, oldApp);
|
|
7064
7259
|
});
|
|
7065
7260
|
}
|
|
@@ -7131,15 +7326,13 @@ function defineElement(tagName) {
|
|
|
7131
7326
|
*/
|
|
7132
7327
|
handleDisconnected(destroy = false, callback) {
|
|
7133
7328
|
const app = appInstanceMap.get(this.appName);
|
|
7134
|
-
if (app &&
|
|
7135
|
-
app.getAppState() !== appStates.UNMOUNT &&
|
|
7136
|
-
app.getKeepAliveState() !== keepAliveStates.KEEP_ALIVE_HIDDEN) {
|
|
7329
|
+
if (app && !app.isUnmounted() && !app.isHidden()) {
|
|
7137
7330
|
// keep-alive
|
|
7138
7331
|
if (this.getKeepAliveModeResult() && !destroy) {
|
|
7139
7332
|
this.handleHiddenKeepAliveApp(callback);
|
|
7140
7333
|
}
|
|
7141
7334
|
else {
|
|
7142
|
-
this.
|
|
7335
|
+
this.unmount(destroy, callback);
|
|
7143
7336
|
}
|
|
7144
7337
|
}
|
|
7145
7338
|
}
|
|
@@ -7199,16 +7392,16 @@ function defineElement(tagName) {
|
|
|
7199
7392
|
* 2. Even if the keep-alive app is pushed into the background, it is still active and cannot be replaced. Otherwise, it is difficult for developers to troubleshoot in case of conflict and will leave developers at a loss
|
|
7200
7393
|
* 3. When scopecss, useSandbox of prefetch app different from target app, delete prefetch app and create new one
|
|
7201
7394
|
*/
|
|
7202
|
-
if (oldApp.
|
|
7395
|
+
if (oldApp.isHidden() &&
|
|
7203
7396
|
oldApp.url === this.appUrl) {
|
|
7204
7397
|
this.handleShowKeepAliveApp(oldApp);
|
|
7205
7398
|
}
|
|
7206
|
-
else if (oldAppUrl === targetUrl && (oldApp.
|
|
7399
|
+
else if (oldAppUrl === targetUrl && (oldApp.isUnmounted() ||
|
|
7207
7400
|
(oldApp.isPrefetch &&
|
|
7208
7401
|
this.sameCoreOptions(oldApp)))) {
|
|
7209
|
-
this.
|
|
7402
|
+
this.handleMount(oldApp);
|
|
7210
7403
|
}
|
|
7211
|
-
else if (oldApp.isPrefetch || oldApp.
|
|
7404
|
+
else if (oldApp.isPrefetch || oldApp.isUnmounted()) {
|
|
7212
7405
|
if ((process.env.NODE_ENV !== 'production') && this.sameCoreOptions(oldApp)) {
|
|
7213
7406
|
/**
|
|
7214
7407
|
* url is different & old app is unmounted or prefetch, create new app to replace old one
|
|
@@ -7247,7 +7440,7 @@ function defineElement(tagName) {
|
|
|
7247
7440
|
* scene5: if oldApp is KEEP_ALIVE_HIDDEN, name must different
|
|
7248
7441
|
*/
|
|
7249
7442
|
if (oldApp) {
|
|
7250
|
-
if (oldApp.
|
|
7443
|
+
if (oldApp.isHidden()) {
|
|
7251
7444
|
if (oldApp.url === this.appUrl) {
|
|
7252
7445
|
this.handleShowKeepAliveApp(oldApp);
|
|
7253
7446
|
}
|
|
@@ -7262,7 +7455,7 @@ function defineElement(tagName) {
|
|
|
7262
7455
|
* 推荐:if (
|
|
7263
7456
|
* oldApp.url === this.appUrl &&
|
|
7264
7457
|
* oldApp.ssrUrl === this.ssrUrl && (
|
|
7265
|
-
* oldApp.
|
|
7458
|
+
* oldApp.isUnmounted() ||
|
|
7266
7459
|
* (oldApp.isPrefetch && this.sameCoreOptions(oldApp))
|
|
7267
7460
|
* )
|
|
7268
7461
|
* )
|
|
@@ -7270,7 +7463,7 @@ function defineElement(tagName) {
|
|
|
7270
7463
|
}
|
|
7271
7464
|
else if (oldApp.url === this.appUrl && oldApp.ssrUrl === this.ssrUrl) {
|
|
7272
7465
|
// mount app
|
|
7273
|
-
this.
|
|
7466
|
+
this.handleMount(oldApp);
|
|
7274
7467
|
}
|
|
7275
7468
|
else {
|
|
7276
7469
|
this.handleCreateApp();
|
|
@@ -7317,7 +7510,7 @@ function defineElement(tagName) {
|
|
|
7317
7510
|
const oldApp = appInstanceMap.get(this.appName);
|
|
7318
7511
|
if (oldApp) {
|
|
7319
7512
|
if (oldApp.isPrerender) {
|
|
7320
|
-
this.
|
|
7513
|
+
this.unmount(true, createAppInstance);
|
|
7321
7514
|
}
|
|
7322
7515
|
else {
|
|
7323
7516
|
oldApp.actionsForCompletelyDestroy();
|
|
@@ -7335,7 +7528,7 @@ function defineElement(tagName) {
|
|
|
7335
7528
|
* 2. is remount in another container ?
|
|
7336
7529
|
* 3. is remount with change properties of the container ?
|
|
7337
7530
|
*/
|
|
7338
|
-
|
|
7531
|
+
handleMount(app) {
|
|
7339
7532
|
app.isPrefetch = false;
|
|
7340
7533
|
// TODO: Can defer be removed?
|
|
7341
7534
|
defer(() => this.mount(app));
|
|
@@ -7358,13 +7551,13 @@ function defineElement(tagName) {
|
|
|
7358
7551
|
/**
|
|
7359
7552
|
* unmount app
|
|
7360
7553
|
* @param destroy delete cache resources when unmount
|
|
7554
|
+
* @param unmountcb callback
|
|
7361
7555
|
*/
|
|
7362
|
-
|
|
7556
|
+
unmount(destroy, unmountcb) {
|
|
7363
7557
|
const app = appInstanceMap.get(this.appName);
|
|
7364
|
-
if (app &&
|
|
7365
|
-
app.getAppState() !== appStates.UNMOUNT) {
|
|
7558
|
+
if (app && !app.isUnmounted()) {
|
|
7366
7559
|
app.unmount({
|
|
7367
|
-
destroy,
|
|
7560
|
+
destroy: destroy || this.getDestroyCompatibleResult(),
|
|
7368
7561
|
clearData: this.getDisposeResult('clear-data'),
|
|
7369
7562
|
keepRouteState: this.getDisposeResult('keep-router-state'),
|
|
7370
7563
|
unmountcb,
|
|
@@ -7374,9 +7567,7 @@ function defineElement(tagName) {
|
|
|
7374
7567
|
// hidden app when disconnectedCallback called with keep-alive
|
|
7375
7568
|
handleHiddenKeepAliveApp(callback) {
|
|
7376
7569
|
const app = appInstanceMap.get(this.appName);
|
|
7377
|
-
if (app &&
|
|
7378
|
-
app.getAppState() !== appStates.UNMOUNT &&
|
|
7379
|
-
app.getKeepAliveState() !== keepAliveStates.KEEP_ALIVE_HIDDEN) {
|
|
7570
|
+
if (app && !app.isUnmounted() && !app.isHidden()) {
|
|
7380
7571
|
app.hiddenKeepAliveApp(callback);
|
|
7381
7572
|
}
|
|
7382
7573
|
}
|
|
@@ -7674,10 +7865,10 @@ function fetchGlobalResources(resources, suffix, sourceHandler) {
|
|
|
7674
7865
|
function getActiveApps({ excludeHiddenApp = false, excludePreRender = false, } = {}) {
|
|
7675
7866
|
const activeApps = [];
|
|
7676
7867
|
appInstanceMap.forEach((app, appName) => {
|
|
7677
|
-
if (
|
|
7868
|
+
if (!app.isUnmounted() &&
|
|
7678
7869
|
(!app.isPrefetch || (app.isPrerender && !excludePreRender)) &&
|
|
7679
7870
|
(!excludeHiddenApp ||
|
|
7680
|
-
|
|
7871
|
+
!app.isHidden())) {
|
|
7681
7872
|
activeApps.push(appName);
|
|
7682
7873
|
}
|
|
7683
7874
|
});
|
|
@@ -7697,7 +7888,7 @@ function unmountApp(appName, options) {
|
|
|
7697
7888
|
const app = appInstanceMap.get(formatAppName(appName));
|
|
7698
7889
|
return new Promise((resolve) => {
|
|
7699
7890
|
if (app) {
|
|
7700
|
-
if (app.
|
|
7891
|
+
if (app.isUnmounted() || app.isPrefetch) {
|
|
7701
7892
|
if (app.isPrerender) {
|
|
7702
7893
|
app.unmount({
|
|
7703
7894
|
destroy: !!(options === null || options === void 0 ? void 0 : options.destroy),
|
|
@@ -7712,7 +7903,7 @@ function unmountApp(appName, options) {
|
|
|
7712
7903
|
resolve(true);
|
|
7713
7904
|
}
|
|
7714
7905
|
}
|
|
7715
|
-
else if (app.
|
|
7906
|
+
else if (app.isHidden()) {
|
|
7716
7907
|
if (options === null || options === void 0 ? void 0 : options.destroy) {
|
|
7717
7908
|
app.unmount({
|
|
7718
7909
|
destroy: true,
|