@micro-zoe/micro-app 1.0.0-beta.3 → 1.0.0-beta.5
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 +2 -2
- package/lib/index.esm.js +358 -184
- 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 +5 -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.5';
|
|
2
2
|
// do not use isUndefined
|
|
3
3
|
const isBrowser = typeof window !== 'undefined';
|
|
4
4
|
// do not use isUndefined
|
|
@@ -1668,21 +1668,33 @@ function runDynamicInlineScript(address, app, scriptInfo) {
|
|
|
1668
1668
|
*/
|
|
1669
1669
|
function runCode2InlineScript(address, code, module, scriptElement, attrs, callback) {
|
|
1670
1670
|
if (module) {
|
|
1671
|
-
|
|
1671
|
+
globalEnv.rawSetAttribute.call(scriptElement, 'type', 'module');
|
|
1672
1672
|
if (isInlineScript(address)) {
|
|
1673
|
-
|
|
1674
|
-
|
|
1673
|
+
/**
|
|
1674
|
+
* inline module script cannot convert to blob mode
|
|
1675
|
+
* Issue: https://github.com/micro-zoe/micro-app/issues/805
|
|
1676
|
+
*/
|
|
1677
|
+
scriptElement.textContent = code;
|
|
1675
1678
|
}
|
|
1676
1679
|
else {
|
|
1677
1680
|
scriptElement.src = address;
|
|
1678
1681
|
}
|
|
1679
|
-
globalEnv.rawSetAttribute.call(scriptElement, 'type', 'module');
|
|
1680
1682
|
if (callback) {
|
|
1681
|
-
|
|
1683
|
+
const onloadHandler = () => {
|
|
1684
|
+
callback.moduleCount && callback.moduleCount--;
|
|
1685
|
+
callback(callback.moduleCount === 0);
|
|
1686
|
+
};
|
|
1682
1687
|
/**
|
|
1683
|
-
*
|
|
1688
|
+
* NOTE:
|
|
1689
|
+
* 1. module script will execute onload method only after it insert to document/iframe
|
|
1690
|
+
* 2. we can't know when the inline module script onload, and we use defer to simulate, this maybe cause some problems
|
|
1684
1691
|
*/
|
|
1685
|
-
|
|
1692
|
+
if (isInlineScript(address)) {
|
|
1693
|
+
defer(onloadHandler);
|
|
1694
|
+
}
|
|
1695
|
+
else {
|
|
1696
|
+
scriptElement.onload = onloadHandler;
|
|
1697
|
+
}
|
|
1686
1698
|
}
|
|
1687
1699
|
}
|
|
1688
1700
|
else {
|
|
@@ -2354,6 +2366,10 @@ function patchDocument() {
|
|
|
2354
2366
|
// const element = globalEnv.rawCreateTextNode.call(getBindTarget(this), data)
|
|
2355
2367
|
// return markElement(element)
|
|
2356
2368
|
// }
|
|
2369
|
+
rawRootDocument.prototype.createComment = function createComment(data) {
|
|
2370
|
+
const element = globalEnv.rawCreateComment.call(getBindTarget(this), data);
|
|
2371
|
+
return markElement(element);
|
|
2372
|
+
};
|
|
2357
2373
|
// query element👇
|
|
2358
2374
|
function querySelector(selectors) {
|
|
2359
2375
|
var _a, _b;
|
|
@@ -2478,8 +2494,6 @@ function rejectMicroAppStyle() {
|
|
|
2478
2494
|
}
|
|
2479
2495
|
|
|
2480
2496
|
const globalEnv = {
|
|
2481
|
-
// mark current application as base application
|
|
2482
|
-
__MICRO_APP_BASE_APPLICATION__: true,
|
|
2483
2497
|
// active sandbox count
|
|
2484
2498
|
activeSandbox: 0,
|
|
2485
2499
|
};
|
|
@@ -2514,6 +2528,7 @@ function initGlobalEnv() {
|
|
|
2514
2528
|
const rawCreateElementNS = rawRootDocument.prototype.createElementNS;
|
|
2515
2529
|
const rawCreateDocumentFragment = rawRootDocument.prototype.createDocumentFragment;
|
|
2516
2530
|
const rawCreateTextNode = rawRootDocument.prototype.createTextNode;
|
|
2531
|
+
const rawCreateComment = rawRootDocument.prototype.createComment;
|
|
2517
2532
|
const rawQuerySelector = rawRootDocument.prototype.querySelector;
|
|
2518
2533
|
const rawQuerySelectorAll = rawRootDocument.prototype.querySelectorAll;
|
|
2519
2534
|
const rawGetElementById = rawRootDocument.prototype.getElementById;
|
|
@@ -2541,6 +2556,8 @@ function initGlobalEnv() {
|
|
|
2541
2556
|
const rawReplaceState = rawWindow.history.replaceState;
|
|
2542
2557
|
const rawAddEventListener = rawRootEventTarget.prototype.addEventListener;
|
|
2543
2558
|
const rawRemoveEventListener = rawRootEventTarget.prototype.removeEventListener;
|
|
2559
|
+
// mark current application as base application
|
|
2560
|
+
window.__MICRO_APP_BASE_APPLICATION__ = true;
|
|
2544
2561
|
assign(globalEnv, {
|
|
2545
2562
|
supportModuleScript: isSupportModuleScript(),
|
|
2546
2563
|
// common global vars
|
|
@@ -2567,6 +2584,7 @@ function initGlobalEnv() {
|
|
|
2567
2584
|
rawCreateElementNS,
|
|
2568
2585
|
rawCreateDocumentFragment,
|
|
2569
2586
|
rawCreateTextNode,
|
|
2587
|
+
rawCreateComment,
|
|
2570
2588
|
rawQuerySelector,
|
|
2571
2589
|
rawQuerySelectorAll,
|
|
2572
2590
|
rawGetElementById,
|
|
@@ -3705,31 +3723,41 @@ function patchWindowEffect(appName, microAppWindow) {
|
|
|
3705
3723
|
|
|
3706
3724
|
// set micro app state to origin state
|
|
3707
3725
|
function setMicroState(appName, microState) {
|
|
3708
|
-
|
|
3709
|
-
|
|
3710
|
-
|
|
3711
|
-
|
|
3712
|
-
|
|
3713
|
-
|
|
3714
|
-
|
|
3715
|
-
|
|
3726
|
+
if (isMemoryRouterEnabled(appName)) {
|
|
3727
|
+
const rawState = globalEnv.rawWindow.history.state;
|
|
3728
|
+
const additionalState = {
|
|
3729
|
+
microAppState: assign({}, rawState === null || rawState === void 0 ? void 0 : rawState.microAppState, {
|
|
3730
|
+
[appName]: microState
|
|
3731
|
+
})
|
|
3732
|
+
};
|
|
3733
|
+
// create new state object
|
|
3734
|
+
return assign({}, rawState, additionalState);
|
|
3735
|
+
}
|
|
3736
|
+
return microState;
|
|
3716
3737
|
}
|
|
3717
3738
|
// delete micro app state form origin state
|
|
3718
3739
|
function removeMicroState(appName, rawState) {
|
|
3719
|
-
if (
|
|
3720
|
-
if (
|
|
3721
|
-
|
|
3722
|
-
|
|
3723
|
-
|
|
3724
|
-
|
|
3740
|
+
if (isMemoryRouterEnabled(appName)) {
|
|
3741
|
+
if (isPlainObject(rawState === null || rawState === void 0 ? void 0 : rawState.microAppState)) {
|
|
3742
|
+
if (!isUndefined(rawState.microAppState[appName])) {
|
|
3743
|
+
delete rawState.microAppState[appName];
|
|
3744
|
+
}
|
|
3745
|
+
if (!Object.keys(rawState.microAppState).length) {
|
|
3746
|
+
delete rawState.microAppState;
|
|
3747
|
+
}
|
|
3725
3748
|
}
|
|
3749
|
+
return assign({}, rawState);
|
|
3726
3750
|
}
|
|
3727
|
-
return
|
|
3751
|
+
return rawState;
|
|
3728
3752
|
}
|
|
3729
3753
|
// get micro app state form origin state
|
|
3730
3754
|
function getMicroState(appName) {
|
|
3731
|
-
var _a
|
|
3732
|
-
|
|
3755
|
+
var _a;
|
|
3756
|
+
const rawState = globalEnv.rawWindow.history.state;
|
|
3757
|
+
if (isMemoryRouterEnabled(appName)) {
|
|
3758
|
+
return ((_a = rawState === null || rawState === void 0 ? void 0 : rawState.microAppState) === null || _a === void 0 ? void 0 : _a[appName]) || null;
|
|
3759
|
+
}
|
|
3760
|
+
return rawState;
|
|
3733
3761
|
}
|
|
3734
3762
|
const ENC_AD_RE = /&/g; // %M1
|
|
3735
3763
|
const ENC_EQ_RE = /=/g; // %M2
|
|
@@ -3767,53 +3795,61 @@ function formatQueryAppName(appName) {
|
|
|
3767
3795
|
function getMicroPathFromURL(appName) {
|
|
3768
3796
|
var _a, _b;
|
|
3769
3797
|
const rawLocation = globalEnv.rawWindow.location;
|
|
3770
|
-
|
|
3771
|
-
|
|
3772
|
-
|
|
3798
|
+
if (isMemoryRouterEnabled(appName)) {
|
|
3799
|
+
const queryObject = getQueryObjectFromURL(rawLocation.search, rawLocation.hash);
|
|
3800
|
+
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)]);
|
|
3801
|
+
return isString(microPath) ? decodeMicroPath(microPath) : null;
|
|
3802
|
+
}
|
|
3803
|
+
return rawLocation.pathname + rawLocation.search + rawLocation.hash;
|
|
3773
3804
|
}
|
|
3774
3805
|
/**
|
|
3775
3806
|
* Attach child app fullPath to browser url
|
|
3776
3807
|
* @param appName app.name
|
|
3777
|
-
* @param
|
|
3808
|
+
* @param targetLocation location of child app or rawLocation of window
|
|
3778
3809
|
*/
|
|
3779
|
-
function setMicroPathToURL(appName,
|
|
3780
|
-
|
|
3781
|
-
const queryObject = getQueryObjectFromURL(search, hash);
|
|
3782
|
-
const encodedMicroPath = encodeMicroPath(microLocation.pathname +
|
|
3783
|
-
microLocation.search +
|
|
3784
|
-
microLocation.hash);
|
|
3785
|
-
/**
|
|
3786
|
-
* Is parent is hash router
|
|
3787
|
-
* In fact, this is not true. It just means that the parameter is added to the hash
|
|
3788
|
-
*/
|
|
3810
|
+
function setMicroPathToURL(appName, targetLocation) {
|
|
3811
|
+
const targetFullPath = targetLocation.pathname + targetLocation.search + targetLocation.hash;
|
|
3789
3812
|
let isAttach2Hash = false;
|
|
3790
|
-
|
|
3791
|
-
|
|
3792
|
-
|
|
3793
|
-
|
|
3794
|
-
|
|
3795
|
-
|
|
3796
|
-
|
|
3797
|
-
|
|
3798
|
-
|
|
3799
|
-
|
|
3800
|
-
|
|
3801
|
-
|
|
3802
|
-
|
|
3803
|
-
|
|
3804
|
-
|
|
3805
|
-
|
|
3806
|
-
|
|
3813
|
+
if (isMemoryRouterEnabled(appName)) {
|
|
3814
|
+
let { pathname, search, hash } = globalEnv.rawWindow.location;
|
|
3815
|
+
const queryObject = getQueryObjectFromURL(search, hash);
|
|
3816
|
+
const encodedMicroPath = encodeMicroPath(targetFullPath);
|
|
3817
|
+
/**
|
|
3818
|
+
* Is parent is hash router
|
|
3819
|
+
* In fact, this is not true. It just means that the parameter is added to the hash
|
|
3820
|
+
*/
|
|
3821
|
+
// If hash exists and search does not exist, it is considered as a hash route
|
|
3822
|
+
if (hash && !search) {
|
|
3823
|
+
isAttach2Hash = true;
|
|
3824
|
+
if (queryObject.hashQuery) {
|
|
3825
|
+
queryObject.hashQuery[formatQueryAppName(appName)] = encodedMicroPath;
|
|
3826
|
+
}
|
|
3827
|
+
else {
|
|
3828
|
+
queryObject.hashQuery = {
|
|
3829
|
+
[formatQueryAppName(appName)]: encodedMicroPath
|
|
3830
|
+
};
|
|
3831
|
+
}
|
|
3832
|
+
const baseHash = hash.includes('?') ? hash.slice(0, hash.indexOf('?') + 1) : hash + '?';
|
|
3833
|
+
hash = baseHash + stringifyQuery(queryObject.hashQuery);
|
|
3807
3834
|
}
|
|
3808
3835
|
else {
|
|
3809
|
-
queryObject.searchQuery
|
|
3810
|
-
[formatQueryAppName(appName)]
|
|
3811
|
-
}
|
|
3836
|
+
if (queryObject.searchQuery) {
|
|
3837
|
+
queryObject.searchQuery[formatQueryAppName(appName)] = encodedMicroPath;
|
|
3838
|
+
}
|
|
3839
|
+
else {
|
|
3840
|
+
queryObject.searchQuery = {
|
|
3841
|
+
[formatQueryAppName(appName)]: encodedMicroPath
|
|
3842
|
+
};
|
|
3843
|
+
}
|
|
3844
|
+
search = '?' + stringifyQuery(queryObject.searchQuery);
|
|
3812
3845
|
}
|
|
3813
|
-
|
|
3846
|
+
return {
|
|
3847
|
+
fullPath: pathname + search + hash,
|
|
3848
|
+
isAttach2Hash,
|
|
3849
|
+
};
|
|
3814
3850
|
}
|
|
3815
3851
|
return {
|
|
3816
|
-
fullPath:
|
|
3852
|
+
fullPath: targetFullPath,
|
|
3817
3853
|
isAttach2Hash,
|
|
3818
3854
|
};
|
|
3819
3855
|
}
|
|
@@ -3825,18 +3861,20 @@ function setMicroPathToURL(appName, microLocation) {
|
|
|
3825
3861
|
function removeMicroPathFromURL(appName, targetLocation) {
|
|
3826
3862
|
var _a, _b, _c, _d;
|
|
3827
3863
|
let { pathname, search, hash } = targetLocation || globalEnv.rawWindow.location;
|
|
3828
|
-
const queryObject = getQueryObjectFromURL(search, hash);
|
|
3829
3864
|
let isAttach2Hash = false;
|
|
3830
|
-
if ((
|
|
3831
|
-
|
|
3832
|
-
(
|
|
3833
|
-
|
|
3834
|
-
|
|
3835
|
-
|
|
3836
|
-
|
|
3837
|
-
|
|
3838
|
-
|
|
3839
|
-
|
|
3865
|
+
if (isMemoryRouterEnabled(appName)) {
|
|
3866
|
+
const queryObject = getQueryObjectFromURL(search, hash);
|
|
3867
|
+
if ((_a = queryObject.hashQuery) === null || _a === void 0 ? void 0 : _a[formatQueryAppName(appName)]) {
|
|
3868
|
+
isAttach2Hash = true;
|
|
3869
|
+
(_b = queryObject.hashQuery) === null || _b === void 0 ? true : delete _b[formatQueryAppName(appName)];
|
|
3870
|
+
const hashQueryStr = stringifyQuery(queryObject.hashQuery);
|
|
3871
|
+
hash = hash.slice(0, hash.indexOf('?') + Number(Boolean(hashQueryStr))) + hashQueryStr;
|
|
3872
|
+
}
|
|
3873
|
+
else if ((_c = queryObject.searchQuery) === null || _c === void 0 ? void 0 : _c[formatQueryAppName(appName)]) {
|
|
3874
|
+
(_d = queryObject.searchQuery) === null || _d === void 0 ? true : delete _d[formatQueryAppName(appName)];
|
|
3875
|
+
const searchQueryStr = stringifyQuery(queryObject.searchQuery);
|
|
3876
|
+
search = searchQueryStr ? '?' + searchQueryStr : '';
|
|
3877
|
+
}
|
|
3840
3878
|
}
|
|
3841
3879
|
return {
|
|
3842
3880
|
fullPath: pathname + search + hash,
|
|
@@ -3876,7 +3914,23 @@ function getNoHashMicroPathFromURL(appName, baseUrl) {
|
|
|
3876
3914
|
*/
|
|
3877
3915
|
function isEffectiveApp(appName) {
|
|
3878
3916
|
const app = appInstanceMap.get(appName);
|
|
3879
|
-
|
|
3917
|
+
/**
|
|
3918
|
+
* !!(app && !app.isPrefetch && !app.isHidden())
|
|
3919
|
+
* 隐藏的keep-alive应用暂时不作为无效应用,原因如下
|
|
3920
|
+
* 1、隐藏后才执行去除浏览器上的微应用的路由信息的操作,导致微应用的路由信息无法去除
|
|
3921
|
+
* 2、如果保持隐藏应用内部正常跳转,阻止同步路由信息到浏览器,这样理论上是好的,但是对于location跳转改如何处理?location跳转是基于修改浏览器地址后发送popstate事件实现的,所以应该是在隐藏后不支持通过location进行跳转
|
|
3922
|
+
*/
|
|
3923
|
+
return !!(app && !app.isPrefetch);
|
|
3924
|
+
}
|
|
3925
|
+
/**
|
|
3926
|
+
* Determine whether the app has enabled memory-router
|
|
3927
|
+
* NOTE:
|
|
3928
|
+
* 1. if sandbox disabled, memory-router is disabled
|
|
3929
|
+
* 2. if app not exist, memory-router is disabled
|
|
3930
|
+
*/
|
|
3931
|
+
function isMemoryRouterEnabled(appName) {
|
|
3932
|
+
const app = appInstanceMap.get(appName);
|
|
3933
|
+
return !!(app && app.sandBox && app.useMemoryRouter);
|
|
3880
3934
|
}
|
|
3881
3935
|
|
|
3882
3936
|
/**
|
|
@@ -3899,26 +3953,7 @@ function addHistoryListener(appName) {
|
|
|
3899
3953
|
excludePreRender: true,
|
|
3900
3954
|
}).includes(appName) &&
|
|
3901
3955
|
!e.onlyForBrowser) {
|
|
3902
|
-
|
|
3903
|
-
const app = appInstanceMap.get(appName);
|
|
3904
|
-
const proxyWindow = app.sandBox.proxyWindow;
|
|
3905
|
-
const microAppWindow = app.sandBox.microAppWindow;
|
|
3906
|
-
let isHashChange = false;
|
|
3907
|
-
// for hashChangeEvent
|
|
3908
|
-
const oldHref = proxyWindow.location.href;
|
|
3909
|
-
// Do not attach micro state to url when microPath is empty
|
|
3910
|
-
if (microPath) {
|
|
3911
|
-
const oldHash = proxyWindow.location.hash;
|
|
3912
|
-
updateMicroLocation(appName, microPath, microAppWindow.location);
|
|
3913
|
-
isHashChange = proxyWindow.location.hash !== oldHash;
|
|
3914
|
-
}
|
|
3915
|
-
// dispatch formatted popStateEvent to child
|
|
3916
|
-
dispatchPopStateEventToMicroApp(appName, proxyWindow, microAppWindow);
|
|
3917
|
-
// dispatch formatted hashChangeEvent to child when hash change
|
|
3918
|
-
if (isHashChange)
|
|
3919
|
-
dispatchHashChangeEventToMicroApp(appName, proxyWindow, microAppWindow, oldHref);
|
|
3920
|
-
// clear element scope before trigger event of next app
|
|
3921
|
-
removeDomScope();
|
|
3956
|
+
updateMicroLocationWithEvent(appName, getMicroPathFromURL(appName));
|
|
3922
3957
|
}
|
|
3923
3958
|
};
|
|
3924
3959
|
rawWindow.addEventListener('popstate', popStateHandler);
|
|
@@ -3926,6 +3961,35 @@ function addHistoryListener(appName) {
|
|
|
3926
3961
|
rawWindow.removeEventListener('popstate', popStateHandler);
|
|
3927
3962
|
};
|
|
3928
3963
|
}
|
|
3964
|
+
/**
|
|
3965
|
+
* Effect: use to trigger child app jump
|
|
3966
|
+
* Actions:
|
|
3967
|
+
* 1. update microLocation with target path
|
|
3968
|
+
* 2. dispatch popStateEvent & hashChangeEvent
|
|
3969
|
+
* @param appName app name
|
|
3970
|
+
* @param targetFullPath target path of child app
|
|
3971
|
+
*/
|
|
3972
|
+
function updateMicroLocationWithEvent(appName, targetFullPath) {
|
|
3973
|
+
const app = appInstanceMap.get(appName);
|
|
3974
|
+
const proxyWindow = app.sandBox.proxyWindow;
|
|
3975
|
+
const microAppWindow = app.sandBox.microAppWindow;
|
|
3976
|
+
let isHashChange = false;
|
|
3977
|
+
// for hashChangeEvent
|
|
3978
|
+
const oldHref = proxyWindow.location.href;
|
|
3979
|
+
// Do not attach micro state to url when targetFullPath is empty
|
|
3980
|
+
if (targetFullPath) {
|
|
3981
|
+
const oldHash = proxyWindow.location.hash;
|
|
3982
|
+
updateMicroLocation(appName, targetFullPath, microAppWindow.location);
|
|
3983
|
+
isHashChange = proxyWindow.location.hash !== oldHash;
|
|
3984
|
+
}
|
|
3985
|
+
// dispatch formatted popStateEvent to child
|
|
3986
|
+
dispatchPopStateEventToMicroApp(appName, proxyWindow, microAppWindow);
|
|
3987
|
+
// dispatch formatted hashChangeEvent to child when hash change
|
|
3988
|
+
if (isHashChange)
|
|
3989
|
+
dispatchHashChangeEventToMicroApp(appName, proxyWindow, microAppWindow, oldHref);
|
|
3990
|
+
// clear element scope before trigger event of next app
|
|
3991
|
+
removeDomScope();
|
|
3992
|
+
}
|
|
3929
3993
|
/**
|
|
3930
3994
|
* dispatch formatted popstate event to microApp
|
|
3931
3995
|
* @param appName app name
|
|
@@ -4088,6 +4152,8 @@ function nativeHistoryNavigate(appName, methodName, fullPath, state = null, titl
|
|
|
4088
4152
|
* 2. proxyHistory.pushState/replaceState with limited popstateEvent
|
|
4089
4153
|
* 3. api microApp.router.push/replace
|
|
4090
4154
|
* 4. proxyLocation.hash = xxx
|
|
4155
|
+
* NOTE:
|
|
4156
|
+
* 1. hidden keep-alive app can jump internally, but will not synchronize to browser
|
|
4091
4157
|
* @param appName app.name
|
|
4092
4158
|
* @param methodName pushState/replaceState
|
|
4093
4159
|
* @param result result of add/remove microApp path on browser url
|
|
@@ -4103,8 +4169,10 @@ function navigateWithNativeEvent(appName, methodName, result, onlyForBrowser, st
|
|
|
4103
4169
|
const oldHref = result.isAttach2Hash && oldFullPath !== result.fullPath ? rawLocation.href : null;
|
|
4104
4170
|
// navigate with native history method
|
|
4105
4171
|
nativeHistoryNavigate(appName, methodName, result.fullPath, state, title);
|
|
4106
|
-
|
|
4172
|
+
// TODO: 如果所有模式统一发送popstate事件,则isMemoryRouterEnabled(appName)要去掉
|
|
4173
|
+
if (oldFullPath !== result.fullPath && isMemoryRouterEnabled(appName)) {
|
|
4107
4174
|
dispatchNativeEvent(appName, onlyForBrowser, oldHref);
|
|
4175
|
+
}
|
|
4108
4176
|
}
|
|
4109
4177
|
}
|
|
4110
4178
|
/**
|
|
@@ -4149,8 +4217,8 @@ function reWriteHistoryMethod(method) {
|
|
|
4149
4217
|
excludeHiddenApp: true,
|
|
4150
4218
|
excludePreRender: true,
|
|
4151
4219
|
}).forEach(appName => {
|
|
4152
|
-
|
|
4153
|
-
|
|
4220
|
+
if (isMemoryRouterEnabled(appName) && !getMicroPathFromURL(appName)) {
|
|
4221
|
+
const app = appInstanceMap.get(appName);
|
|
4154
4222
|
attachRouteToBrowserURL(appName, setMicroPathToURL(appName, app.sandBox.proxyWindow.location), setMicroState(appName, getMicroState(appName)));
|
|
4155
4223
|
}
|
|
4156
4224
|
});
|
|
@@ -4199,12 +4267,14 @@ function createRouterApi() {
|
|
|
4199
4267
|
return function (to) {
|
|
4200
4268
|
const appName = formatAppName(to.name);
|
|
4201
4269
|
if (appName && isString(to.path)) {
|
|
4202
|
-
|
|
4203
|
-
|
|
4204
|
-
|
|
4205
|
-
|
|
4206
|
-
|
|
4207
|
-
|
|
4270
|
+
/**
|
|
4271
|
+
* active apps, exclude prerender app or hidden keep-alive app
|
|
4272
|
+
* NOTE:
|
|
4273
|
+
* 1. prerender app or hidden keep-alive app clear and record popstate event, so we cannot control app jump through the API
|
|
4274
|
+
* 2. disable memory-router
|
|
4275
|
+
*/
|
|
4276
|
+
if (getActiveApps({ excludeHiddenApp: true, excludePreRender: true }).includes(appName)) {
|
|
4277
|
+
const app = appInstanceMap.get(appName);
|
|
4208
4278
|
const microLocation = app.sandBox.proxyWindow.location;
|
|
4209
4279
|
const targetLocation = createURL(to.path, microLocation.href);
|
|
4210
4280
|
// Only get path data, even if the origin is different from microApp
|
|
@@ -4213,20 +4283,48 @@ function createRouterApi() {
|
|
|
4213
4283
|
if (currentFullPath !== targetFullPath || getMicroPathFromURL(appName) !== targetFullPath) {
|
|
4214
4284
|
const methodName = (replace && to.replace !== false) || to.replace === true ? 'replaceState' : 'pushState';
|
|
4215
4285
|
navigateWithRawHistory(appName, methodName, targetLocation, to.state);
|
|
4286
|
+
/**
|
|
4287
|
+
* TODO:
|
|
4288
|
+
* 1. 关闭虚拟路由的跳转地址不同:baseRoute + 子应用地址,文档中要说明
|
|
4289
|
+
* 2. 关闭虚拟路由时跳转方式不同:1、基座跳转但不发送popstate事件 2、控制子应用更新location,内部发送popstate事件。
|
|
4290
|
+
* 补充:
|
|
4291
|
+
* 核心思路:减小对基座的影响(就是子应用跳转不向基座发送popstate事件,其他操作一致),但这是必要的吗,只是多了一个触发popstate的操作
|
|
4292
|
+
* 未来的思路有两种:
|
|
4293
|
+
* 1、减少对基座的影响,主要是解决vue循环刷新的问题
|
|
4294
|
+
* 2、全局发送popstate事件,解决主、子都是vue3的冲突问题
|
|
4295
|
+
* 两者选一个吧,如果选2,则下面这两行代码可以去掉
|
|
4296
|
+
* 要不这样吧,history和search模式采用2,这样可以解决vue3的问题,custom采用1,避免vue循环刷新的问题,这样在用户出现问题时各有解决方案。但反过来说,每种方案又分别导致另外的问题,不统一,导致复杂度增高
|
|
4297
|
+
* 如果关闭虚拟路由,同时发送popstate事件还是无法解决vue3的问题(毕竟history.state理论上还是会冲突),那么就没必要发送popstate事件了。
|
|
4298
|
+
* 。。。。先这样吧
|
|
4299
|
+
*/
|
|
4300
|
+
if (!isMemoryRouterEnabled(appName)) {
|
|
4301
|
+
updateMicroLocationWithEvent(appName, targetFullPath);
|
|
4302
|
+
}
|
|
4216
4303
|
}
|
|
4217
4304
|
}
|
|
4218
4305
|
else {
|
|
4219
|
-
|
|
4220
|
-
* app not exit or unmounted, update browser URL with replaceState
|
|
4221
|
-
* use base app location.origin as baseURL
|
|
4222
|
-
*/
|
|
4223
|
-
const rawLocation = globalEnv.rawWindow.location;
|
|
4224
|
-
const targetLocation = createURL(to.path, rawLocation.origin);
|
|
4225
|
-
const targetFullPath = targetLocation.pathname + targetLocation.search + targetLocation.hash;
|
|
4226
|
-
if (getMicroPathFromURL(appName) !== targetFullPath) {
|
|
4227
|
-
navigateWithRawHistory(appName, to.replace === false ? 'pushState' : 'replaceState', targetLocation, to.state);
|
|
4228
|
-
}
|
|
4306
|
+
logWarn('navigation failed, app does not exist or is inactive');
|
|
4229
4307
|
}
|
|
4308
|
+
// /**
|
|
4309
|
+
// * app not exit or unmounted, update browser URL with replaceState
|
|
4310
|
+
// * use base app location.origin as baseURL
|
|
4311
|
+
// * 应用不存在或已卸载,依然使用replaceState来更新浏览器地址 -- 不合理
|
|
4312
|
+
// */
|
|
4313
|
+
// /**
|
|
4314
|
+
// * TODO: 应用还没渲染或已经卸载最好不要支持跳转了,我知道这是因为解决一些特殊场景,但这么做是非常反直觉的
|
|
4315
|
+
// * 并且在新版本中有多种路由模式,如果应用不存在,我们根本无法知道是哪种模式,那么这里的操作就无意义了。
|
|
4316
|
+
// */
|
|
4317
|
+
// const rawLocation = globalEnv.rawWindow.location
|
|
4318
|
+
// const targetLocation = createURL(to.path, rawLocation.origin)
|
|
4319
|
+
// const targetFullPath = targetLocation.pathname + targetLocation.search + targetLocation.hash
|
|
4320
|
+
// if (getMicroPathFromURL(appName) !== targetFullPath) {
|
|
4321
|
+
// navigateWithRawHistory(
|
|
4322
|
+
// appName,
|
|
4323
|
+
// to.replace === false ? 'pushState' : 'replaceState',
|
|
4324
|
+
// targetLocation,
|
|
4325
|
+
// to.state,
|
|
4326
|
+
// )
|
|
4327
|
+
// }
|
|
4230
4328
|
}
|
|
4231
4329
|
else {
|
|
4232
4330
|
logError(`navigation failed, name & path are required when use router.${replace ? 'replace' : 'push'}`);
|
|
@@ -4286,8 +4384,8 @@ function createRouterApi() {
|
|
|
4286
4384
|
* 2. useMemoryRouter is false
|
|
4287
4385
|
*/
|
|
4288
4386
|
function commonHandlerForAttachToURL(appName) {
|
|
4289
|
-
|
|
4290
|
-
|
|
4387
|
+
if (isMemoryRouterEnabled(appName)) {
|
|
4388
|
+
const app = appInstanceMap.get(appName);
|
|
4291
4389
|
attachRouteToBrowserURL(appName, setMicroPathToURL(appName, app.sandBox.proxyWindow.location), setMicroState(appName, getMicroState(appName)));
|
|
4292
4390
|
}
|
|
4293
4391
|
}
|
|
@@ -4539,37 +4637,40 @@ function createMicroLocation(appName, url, microAppWindow, childStaticLocation,
|
|
|
4539
4637
|
// Even if the origin is the same, developers still have the possibility of want to jump to a new page
|
|
4540
4638
|
if (targetLocation.origin === proxyLocation.origin) {
|
|
4541
4639
|
const setMicroPathResult = setMicroPathToURL(appName, targetLocation);
|
|
4542
|
-
|
|
4543
|
-
|
|
4544
|
-
|
|
4545
|
-
|
|
4546
|
-
|
|
4547
|
-
|
|
4548
|
-
|
|
4549
|
-
|
|
4550
|
-
|
|
4551
|
-
|
|
4552
|
-
|
|
4553
|
-
|
|
4554
|
-
|
|
4555
|
-
|
|
4556
|
-
|
|
4557
|
-
|
|
4558
|
-
|
|
4640
|
+
// if disable memory-router, navigate directly through rawLocation
|
|
4641
|
+
if (isMemoryRouterEnabled(appName)) {
|
|
4642
|
+
/**
|
|
4643
|
+
* change hash with location.href will not trigger the browser reload
|
|
4644
|
+
* so we use pushState & reload to imitate href behavior
|
|
4645
|
+
* NOTE:
|
|
4646
|
+
* 1. if child app only change hash, it should not trigger browser reload
|
|
4647
|
+
* 2. if address is same and has hash, it should not add route stack
|
|
4648
|
+
*/
|
|
4649
|
+
if (targetLocation.pathname === proxyLocation.pathname &&
|
|
4650
|
+
targetLocation.search === proxyLocation.search) {
|
|
4651
|
+
let oldHref = null;
|
|
4652
|
+
if (targetLocation.hash !== proxyLocation.hash) {
|
|
4653
|
+
if (setMicroPathResult.isAttach2Hash)
|
|
4654
|
+
oldHref = rawLocation.href;
|
|
4655
|
+
nativeHistoryNavigate(appName, methodName, setMicroPathResult.fullPath);
|
|
4656
|
+
}
|
|
4657
|
+
if (targetLocation.hash) {
|
|
4658
|
+
dispatchNativeEvent(appName, false, oldHref);
|
|
4659
|
+
}
|
|
4660
|
+
else {
|
|
4661
|
+
reload();
|
|
4662
|
+
}
|
|
4663
|
+
return void 0;
|
|
4664
|
+
/**
|
|
4665
|
+
* when baseApp is hash router, address change of child can not reload browser
|
|
4666
|
+
* so we imitate behavior of browser (reload) manually
|
|
4667
|
+
*/
|
|
4559
4668
|
}
|
|
4560
|
-
else {
|
|
4669
|
+
else if (setMicroPathResult.isAttach2Hash) {
|
|
4670
|
+
nativeHistoryNavigate(appName, methodName, setMicroPathResult.fullPath);
|
|
4561
4671
|
reload();
|
|
4672
|
+
return void 0;
|
|
4562
4673
|
}
|
|
4563
|
-
return void 0;
|
|
4564
|
-
/**
|
|
4565
|
-
* when baseApp is hash router, address change of child can not reload browser
|
|
4566
|
-
* so we imitate behavior of browser (reload) manually
|
|
4567
|
-
*/
|
|
4568
|
-
}
|
|
4569
|
-
else if (setMicroPathResult.isAttach2Hash) {
|
|
4570
|
-
nativeHistoryNavigate(appName, methodName, setMicroPathResult.fullPath);
|
|
4571
|
-
reload();
|
|
4572
|
-
return void 0;
|
|
4573
4674
|
}
|
|
4574
4675
|
return setMicroPathResult.fullPath;
|
|
4575
4676
|
}
|
|
@@ -4661,19 +4762,34 @@ function createMicroLocation(appName, url, microAppWindow, childStaticLocation,
|
|
|
4661
4762
|
}
|
|
4662
4763
|
}
|
|
4663
4764
|
else if (key === 'pathname') {
|
|
4664
|
-
|
|
4665
|
-
|
|
4765
|
+
if (isMemoryRouterEnabled(appName)) {
|
|
4766
|
+
const targetPath = ('/' + value).replace(/^\/+/, '/') + proxyLocation.search + proxyLocation.hash;
|
|
4767
|
+
handleForPathNameAndSearch(targetPath, 'pathname');
|
|
4768
|
+
}
|
|
4769
|
+
else {
|
|
4770
|
+
rawLocation.pathname = value;
|
|
4771
|
+
}
|
|
4666
4772
|
}
|
|
4667
4773
|
else if (key === 'search') {
|
|
4668
|
-
|
|
4669
|
-
|
|
4774
|
+
if (isMemoryRouterEnabled(appName)) {
|
|
4775
|
+
const targetPath = proxyLocation.pathname + ('?' + value).replace(/^\?+/, '?') + proxyLocation.hash;
|
|
4776
|
+
handleForPathNameAndSearch(targetPath, 'search');
|
|
4777
|
+
}
|
|
4778
|
+
else {
|
|
4779
|
+
rawLocation.search = value;
|
|
4780
|
+
}
|
|
4670
4781
|
}
|
|
4671
4782
|
else if (key === 'hash') {
|
|
4672
|
-
|
|
4673
|
-
|
|
4674
|
-
|
|
4675
|
-
|
|
4676
|
-
|
|
4783
|
+
if (isMemoryRouterEnabled(appName)) {
|
|
4784
|
+
const targetPath = proxyLocation.pathname + proxyLocation.search + ('#' + value).replace(/^#+/, '#');
|
|
4785
|
+
const targetLocation = createURL(targetPath, url);
|
|
4786
|
+
// The same hash will not trigger popStateEvent
|
|
4787
|
+
if (targetLocation.hash !== proxyLocation.hash) {
|
|
4788
|
+
navigateWithNativeEvent(appName, 'pushState', setMicroPathToURL(appName, targetLocation), false);
|
|
4789
|
+
}
|
|
4790
|
+
}
|
|
4791
|
+
else {
|
|
4792
|
+
rawLocation.hash = value;
|
|
4677
4793
|
}
|
|
4678
4794
|
}
|
|
4679
4795
|
else {
|
|
@@ -4718,6 +4834,7 @@ function updateMicroLocation(appName, path, microLocation, type) {
|
|
|
4718
4834
|
var _a;
|
|
4719
4835
|
// record old values of microLocation to `from`
|
|
4720
4836
|
const from = createGuardLocation(appName, microLocation);
|
|
4837
|
+
// if is iframeSandbox, microLocation muse be rawLocation of iframe, not proxyLocation
|
|
4721
4838
|
const newLocation = createURL(path, microLocation.href);
|
|
4722
4839
|
if (isIframeSandbox(appName)) {
|
|
4723
4840
|
const microAppWindow = appInstanceMap.get(appName).sandBox.microAppWindow;
|
|
@@ -4736,6 +4853,15 @@ function updateMicroLocation(appName, path, microLocation, type) {
|
|
|
4736
4853
|
}
|
|
4737
4854
|
}
|
|
4738
4855
|
|
|
4856
|
+
/**
|
|
4857
|
+
* TODO: 关于关闭虚拟路由系统的临时笔记
|
|
4858
|
+
* 1. with沙箱关闭虚拟路由最好和iframe保持一致
|
|
4859
|
+
* 2. default-page无法使用,但是用基座的地址可以实现一样的效果
|
|
4860
|
+
* 3. keep-router-state功能失效,因为始终为true
|
|
4861
|
+
* 4. 基座控制子应用跳转地址改变,正确的值为:baseRoute + 子应用地址,这要在文档中说明,否则很容易出错,确实也很难理解
|
|
4862
|
+
* 5. 是否需要发送popstate事件,为了减小对基座的影响,现在不发送
|
|
4863
|
+
* 6. 关闭后导致的vue3路由冲突问题需要在文档中明确指出(2处:在关闭虚拟路由系统的配置那里着重说明,在vue常见问题中说明)
|
|
4864
|
+
*/
|
|
4739
4865
|
/**
|
|
4740
4866
|
* The router system has two operations: read and write
|
|
4741
4867
|
* Read through location and write through history & location
|
|
@@ -4767,7 +4893,9 @@ function initRouteStateWithURL(appName, microLocation, defaultPage) {
|
|
|
4767
4893
|
}
|
|
4768
4894
|
/**
|
|
4769
4895
|
* initialize browser information according to microLocation
|
|
4770
|
-
*
|
|
4896
|
+
* Scenes:
|
|
4897
|
+
* 1. sandbox.start
|
|
4898
|
+
* 2. reshow of keep-alive app
|
|
4771
4899
|
*/
|
|
4772
4900
|
function updateBrowserURLWithLocation(appName, microLocation, defaultPage) {
|
|
4773
4901
|
// update microLocation with defaultPage
|
|
@@ -4790,14 +4918,14 @@ function clearRouteStateFromURL(appName, url, microLocation, keepRouteState) {
|
|
|
4790
4918
|
const { pathname, search, hash } = createURL(url);
|
|
4791
4919
|
updateMicroLocation(appName, pathname + search + hash, microLocation, 'prevent');
|
|
4792
4920
|
}
|
|
4793
|
-
|
|
4921
|
+
removePathFromBrowser(appName);
|
|
4794
4922
|
clearRouterWhenUnmount(appName);
|
|
4795
4923
|
}
|
|
4796
4924
|
/**
|
|
4797
4925
|
* remove microState from history.state and remove microPath from browserURL
|
|
4798
4926
|
* called on sandbox.stop or hidden of keep-alive app
|
|
4799
4927
|
*/
|
|
4800
|
-
function
|
|
4928
|
+
function removePathFromBrowser(appName) {
|
|
4801
4929
|
attachRouteToBrowserURL(appName, removeMicroPathFromURL(appName), removeMicroState(appName, globalEnv.rawWindow.history.state));
|
|
4802
4930
|
}
|
|
4803
4931
|
|
|
@@ -4941,6 +5069,7 @@ class WithSandBox {
|
|
|
4941
5069
|
if (this.active)
|
|
4942
5070
|
return;
|
|
4943
5071
|
this.active = true;
|
|
5072
|
+
// TODO: with沙箱关闭虚拟路由保持和iframe一致
|
|
4944
5073
|
if (useMemoryRouter) {
|
|
4945
5074
|
if (isUndefined(this.microAppWindow.location)) {
|
|
4946
5075
|
this.setMicroAppRouter(this.microAppWindow.__MICRO_APP_NAME__, this.microAppWindow.__MICRO_APP_URL__, this.microAppWindow);
|
|
@@ -4977,16 +5106,18 @@ class WithSandBox {
|
|
|
4977
5106
|
* @param keepRouteState prevent reset route
|
|
4978
5107
|
* @param destroy completely destroy, delete cache resources
|
|
4979
5108
|
* @param clearData clear data from base app
|
|
5109
|
+
* @param useMemoryRouter use virtual router
|
|
4980
5110
|
*/
|
|
4981
|
-
stop({ umdMode, keepRouteState, destroy, clearData, }) {
|
|
5111
|
+
stop({ umdMode, keepRouteState, destroy, clearData, useMemoryRouter, }) {
|
|
5112
|
+
var _a;
|
|
4982
5113
|
if (!this.active)
|
|
4983
5114
|
return;
|
|
4984
5115
|
this.recordAndReleaseEffect({ umdMode, clearData, destroy }, !umdMode || destroy);
|
|
4985
|
-
if (
|
|
5116
|
+
if (useMemoryRouter) {
|
|
4986
5117
|
this.clearRouteState(keepRouteState);
|
|
4987
|
-
// release listener of popstate
|
|
4988
|
-
this.removeHistoryListener();
|
|
4989
5118
|
}
|
|
5119
|
+
// release listener of popstate for child app
|
|
5120
|
+
(_a = this.removeHistoryListener) === null || _a === void 0 ? void 0 : _a.call(this);
|
|
4990
5121
|
/**
|
|
4991
5122
|
* NOTE:
|
|
4992
5123
|
* 1. injectedKeys and escapeKeys must be placed at the back
|
|
@@ -5428,7 +5559,7 @@ class WithSandBox {
|
|
|
5428
5559
|
updateBrowserURLWithLocation(this.microAppWindow.__MICRO_APP_NAME__, this.microAppWindow.location);
|
|
5429
5560
|
}
|
|
5430
5561
|
removeRouteInfoForKeepAliveApp() {
|
|
5431
|
-
|
|
5562
|
+
removePathFromBrowser(this.microAppWindow.__MICRO_APP_NAME__);
|
|
5432
5563
|
}
|
|
5433
5564
|
/**
|
|
5434
5565
|
* Format all html elements when init
|
|
@@ -5628,6 +5759,7 @@ function patchDocumentPrototype(appName, microAppWindow) {
|
|
|
5628
5759
|
const microDocument = microAppWindow.document;
|
|
5629
5760
|
const rawMicroCreateElement = microRootDocument.prototype.createElement;
|
|
5630
5761
|
const rawMicroCreateTextNode = microRootDocument.prototype.createTextNode;
|
|
5762
|
+
const rawMicroCreateComment = microRootDocument.prototype.createComment;
|
|
5631
5763
|
const rawMicroQuerySelector = microRootDocument.prototype.querySelector;
|
|
5632
5764
|
const rawMicroQuerySelectorAll = microRootDocument.prototype.querySelectorAll;
|
|
5633
5765
|
const rawMicroGetElementById = microRootDocument.prototype.getElementById;
|
|
@@ -5642,6 +5774,10 @@ function patchDocumentPrototype(appName, microAppWindow) {
|
|
|
5642
5774
|
const element = rawMicroCreateTextNode.call(this, data);
|
|
5643
5775
|
return updateElementInfo(element, appName);
|
|
5644
5776
|
};
|
|
5777
|
+
microRootDocument.prototype.createComment = function createComment(data) {
|
|
5778
|
+
const element = rawMicroCreateComment.call(this, data);
|
|
5779
|
+
return updateElementInfo(element, appName);
|
|
5780
|
+
};
|
|
5645
5781
|
function getDefaultRawTarget(target) {
|
|
5646
5782
|
return microDocument !== target ? target : rawDocument;
|
|
5647
5783
|
}
|
|
@@ -6206,12 +6342,29 @@ class IframeSandbox {
|
|
|
6206
6342
|
if (this.active)
|
|
6207
6343
|
return;
|
|
6208
6344
|
this.active = true;
|
|
6209
|
-
|
|
6210
|
-
|
|
6211
|
-
|
|
6212
|
-
|
|
6213
|
-
|
|
6214
|
-
|
|
6345
|
+
/**
|
|
6346
|
+
* Sync router info to iframe when exec sandbox.start with disable or enable memory-router
|
|
6347
|
+
* e.g.:
|
|
6348
|
+
* vue-router@4.x get target path by remove the base section from rawLocation.pathname
|
|
6349
|
+
* code: window.location.pathname.slice(base.length) || '/'; (base is baseroute)
|
|
6350
|
+
* NOTE:
|
|
6351
|
+
* 1. iframe router and browser router are separated, we should update iframe router manually
|
|
6352
|
+
* 2. withSandbox location is browser location when disable memory-router, so no need to do anything
|
|
6353
|
+
*/
|
|
6354
|
+
/**
|
|
6355
|
+
* TODO:
|
|
6356
|
+
* 做一些记录:
|
|
6357
|
+
* 1. iframe关闭虚拟路由系统后,default-page无法使用,推荐用户直接使用浏览器地址控制首页渲染
|
|
6358
|
+
* 补充:keep-router-state 也无法配置,因为keep-router-state一定为true。
|
|
6359
|
+
* 2. 导航拦截、current.route 可以正常使用
|
|
6360
|
+
* 3. 可以正常控制子应用跳转,方式还是自上而下(也可以是子应用内部跳转,这种方式更好一点,减小对基座的影响,不会导致vue的循环刷新)
|
|
6361
|
+
* 4. 关闭虚拟路由以后会对应 route-mode='custom' 模式,包括with沙箱也会这么做
|
|
6362
|
+
* 5. 关闭虚拟路由是指尽可能模式没有虚拟路由的情况,子应用直接获取浏览器location和history,控制浏览器跳转
|
|
6363
|
+
*/
|
|
6364
|
+
this.initRouteState(defaultPage);
|
|
6365
|
+
// unique listener of popstate event for child app
|
|
6366
|
+
this.removeHistoryListener = addHistoryListener(this.microAppWindow.__MICRO_APP_NAME__);
|
|
6367
|
+
if (!useMemoryRouter) {
|
|
6215
6368
|
this.microAppWindow.__MICRO_APP_BASE_ROUTE__ = this.microAppWindow.__MICRO_APP_BASE_URL__ = baseroute;
|
|
6216
6369
|
}
|
|
6217
6370
|
/**
|
|
@@ -6227,15 +6380,15 @@ class IframeSandbox {
|
|
|
6227
6380
|
}
|
|
6228
6381
|
if (++IframeSandbox.activeCount === 1) ;
|
|
6229
6382
|
}
|
|
6230
|
-
stop({ umdMode, keepRouteState, destroy, clearData, }) {
|
|
6383
|
+
stop({ umdMode, keepRouteState, destroy, clearData, useMemoryRouter, }) {
|
|
6384
|
+
var _a;
|
|
6231
6385
|
if (!this.active)
|
|
6232
6386
|
return;
|
|
6233
6387
|
this.recordAndReleaseEffect({ clearData }, !umdMode || destroy);
|
|
6234
|
-
if
|
|
6235
|
-
|
|
6236
|
-
|
|
6237
|
-
|
|
6238
|
-
}
|
|
6388
|
+
// if keep-route-state is true or disable memory-router, preserve microLocation state
|
|
6389
|
+
this.clearRouteState(keepRouteState || !useMemoryRouter);
|
|
6390
|
+
// release listener of popstate for child app
|
|
6391
|
+
(_a = this.removeHistoryListener) === null || _a === void 0 ? void 0 : _a.call(this);
|
|
6239
6392
|
if (!umdMode || destroy) {
|
|
6240
6393
|
this.deleteIframeElement();
|
|
6241
6394
|
this.escapeKeys.forEach((key) => {
|
|
@@ -6409,6 +6562,7 @@ class IframeSandbox {
|
|
|
6409
6562
|
}
|
|
6410
6563
|
createProxyWindow(microAppWindow) {
|
|
6411
6564
|
const rawWindow = globalEnv.rawWindow;
|
|
6565
|
+
const customProperties = [];
|
|
6412
6566
|
return new Proxy(microAppWindow, {
|
|
6413
6567
|
get: (target, key) => {
|
|
6414
6568
|
if (key === 'location') {
|
|
@@ -6417,6 +6571,9 @@ class IframeSandbox {
|
|
|
6417
6571
|
if (globalPropertyList.includes(key.toString())) {
|
|
6418
6572
|
return this.proxyWindow;
|
|
6419
6573
|
}
|
|
6574
|
+
if (customProperties.includes(key)) {
|
|
6575
|
+
return Reflect.get(target, key);
|
|
6576
|
+
}
|
|
6420
6577
|
return bindFunctionToRawTarget(Reflect.get(target, key), target);
|
|
6421
6578
|
},
|
|
6422
6579
|
set: (target, key, value) => {
|
|
@@ -6428,6 +6585,9 @@ class IframeSandbox {
|
|
|
6428
6585
|
if (key === 'location') {
|
|
6429
6586
|
return Reflect.set(rawWindow, key, value);
|
|
6430
6587
|
}
|
|
6588
|
+
if (!Reflect.has(target, key)) {
|
|
6589
|
+
customProperties.push(key);
|
|
6590
|
+
}
|
|
6431
6591
|
Reflect.set(target, key, value);
|
|
6432
6592
|
if (this.escapeProperties.includes(key)) {
|
|
6433
6593
|
!Reflect.has(rawWindow, key) && this.escapeKeys.add(key);
|
|
@@ -6478,7 +6638,7 @@ class IframeSandbox {
|
|
|
6478
6638
|
updateBrowserURLWithLocation(this.microAppWindow.__MICRO_APP_NAME__, this.microAppWindow.location);
|
|
6479
6639
|
}
|
|
6480
6640
|
removeRouteInfoForKeepAliveApp() {
|
|
6481
|
-
|
|
6641
|
+
removePathFromBrowser(this.microAppWindow.__MICRO_APP_NAME__);
|
|
6482
6642
|
}
|
|
6483
6643
|
/**
|
|
6484
6644
|
* Format all html elements when init
|
|
@@ -6605,12 +6765,6 @@ class CreateApp {
|
|
|
6605
6765
|
this.source.html = html;
|
|
6606
6766
|
if (!this.isPrefetch && !this.isUnmounted()) {
|
|
6607
6767
|
getRootContainer(this.container).mount(this);
|
|
6608
|
-
// Abandonment plan
|
|
6609
|
-
// if (this.isHidden()) {
|
|
6610
|
-
// getRootContainer(this.container!).unmount()
|
|
6611
|
-
// } else if (!this.isUnmounted()) {
|
|
6612
|
-
// getRootContainer(this.container!).mount(this)
|
|
6613
|
-
// }
|
|
6614
6768
|
}
|
|
6615
6769
|
else if (this.isPrerender) {
|
|
6616
6770
|
/**
|
|
@@ -6678,8 +6832,7 @@ class CreateApp {
|
|
|
6678
6832
|
// mount before prerender exec mount (loading source), set isPrerender to false
|
|
6679
6833
|
this.isPrerender = false;
|
|
6680
6834
|
// reset app state to LOADING
|
|
6681
|
-
this.setAppState(appStates.LOADING);
|
|
6682
|
-
return;
|
|
6835
|
+
return this.setAppState(appStates.LOADING);
|
|
6683
6836
|
}
|
|
6684
6837
|
this.createSandbox();
|
|
6685
6838
|
const nextAction = () => {
|
|
@@ -6726,7 +6879,6 @@ class CreateApp {
|
|
|
6726
6879
|
this.fiber = fiber;
|
|
6727
6880
|
// use in sandbox/effect
|
|
6728
6881
|
this.useMemoryRouter = useMemoryRouter;
|
|
6729
|
-
// this.hiddenRouter = hiddenRouter ?? this.hiddenRouter
|
|
6730
6882
|
const dispatchBeforeMount = () => dispatchLifecyclesEvent(this.container, this.name, lifeCycles.BEFOREMOUNT);
|
|
6731
6883
|
if (this.isPrerender) {
|
|
6732
6884
|
((_d = this.preRenderEvents) !== null && _d !== void 0 ? _d : (this.preRenderEvents = [])).push(dispatchBeforeMount);
|
|
@@ -6832,6 +6984,12 @@ class CreateApp {
|
|
|
6832
6984
|
(_a = this.sandBox) === null || _a === void 0 ? void 0 : _a.recordAndReleaseEffect({ keepAlive: true });
|
|
6833
6985
|
}
|
|
6834
6986
|
}
|
|
6987
|
+
/**
|
|
6988
|
+
* TODO: 这里增加一个处理,如果渲染完成时已经卸载,则进行一些操作
|
|
6989
|
+
* 如果是默认模式:删除所有事件和定时器
|
|
6990
|
+
* 如果是umd模式:重新记录和清空事件
|
|
6991
|
+
* 补充:非必需,优先级低
|
|
6992
|
+
*/
|
|
6835
6993
|
}
|
|
6836
6994
|
/**
|
|
6837
6995
|
* unmount app
|
|
@@ -6913,6 +7071,7 @@ class CreateApp {
|
|
|
6913
7071
|
keepRouteState: keepRouteState && !destroy,
|
|
6914
7072
|
destroy,
|
|
6915
7073
|
clearData: clearData || destroy,
|
|
7074
|
+
useMemoryRouter: this.useMemoryRouter,
|
|
6916
7075
|
});
|
|
6917
7076
|
// dispatch unmount event to base app
|
|
6918
7077
|
dispatchLifecyclesEvent(this.container, this.name, lifeCycles.UNMOUNT);
|
|
@@ -6956,7 +7115,16 @@ class CreateApp {
|
|
|
6956
7115
|
// called after lifeCyclesEvent
|
|
6957
7116
|
(_a = this.sandBox) === null || _a === void 0 ? void 0 : _a.removeRouteInfoForKeepAliveApp();
|
|
6958
7117
|
}
|
|
6959
|
-
|
|
7118
|
+
/**
|
|
7119
|
+
* Hidden app before the resources are loaded, then unmount the app
|
|
7120
|
+
*/
|
|
7121
|
+
if (this.loadSourceLevel !== 2) {
|
|
7122
|
+
getRootContainer(this.container).unmount();
|
|
7123
|
+
}
|
|
7124
|
+
else {
|
|
7125
|
+
this.container = cloneContainer(pureCreateElement('div'), this.container, false);
|
|
7126
|
+
(_b = this.sandBox) === null || _b === void 0 ? void 0 : _b.recordAndReleaseEffect({ keepAlive: true });
|
|
7127
|
+
}
|
|
6960
7128
|
callback === null || callback === void 0 ? void 0 : callback();
|
|
6961
7129
|
}
|
|
6962
7130
|
// show app when connectedCallback called with keep-alive
|
|
@@ -6971,6 +7139,12 @@ class CreateApp {
|
|
|
6971
7139
|
dispatchLifecyclesEvent(container, this.name, lifeCycles.BEFORESHOW);
|
|
6972
7140
|
this.setKeepAliveState(keepAliveStates.KEEP_ALIVE_SHOW);
|
|
6973
7141
|
this.container = cloneContainer(container, this.container, false);
|
|
7142
|
+
/**
|
|
7143
|
+
* TODO:
|
|
7144
|
+
* 1. iframe沙箱在关闭虚拟路由系统时,重新展示时不更新浏览器地址,这样和with沙箱保持一致。
|
|
7145
|
+
* 但是iframe是可以做到重新展示时更新浏览器地址的,这里临时不支持,等待后续with沙箱也支持的时候再优化
|
|
7146
|
+
* 只需要去除 if (this.useMemoryRouter) 的判断即可
|
|
7147
|
+
*/
|
|
6974
7148
|
if (this.useMemoryRouter) {
|
|
6975
7149
|
// called before lifeCyclesEvent
|
|
6976
7150
|
(_b = this.sandBox) === null || _b === void 0 ? void 0 : _b.setRouteInfoForKeepAliveApp();
|