@micro-zoe/micro-app 1.0.0-alpha.1 → 1.0.0-alpha.2
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 +5 -3
- package/lib/index.esm.js +335 -181
- 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 +31 -1
package/lib/index.esm.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
const version = '1.0.0-alpha.
|
|
1
|
+
const version = '1.0.0-alpha.2';
|
|
2
2
|
// do not use isUndefined
|
|
3
3
|
const isBrowser = typeof window !== 'undefined';
|
|
4
4
|
// do not use isUndefined
|
|
@@ -41,6 +41,10 @@ function isFunction(target) {
|
|
|
41
41
|
function isPlainObject(target) {
|
|
42
42
|
return toString.call(target) === '[object Object]';
|
|
43
43
|
}
|
|
44
|
+
// is Object
|
|
45
|
+
function isObject(target) {
|
|
46
|
+
return typeof target === 'object';
|
|
47
|
+
}
|
|
44
48
|
// is Promise
|
|
45
49
|
function isPromise(target) {
|
|
46
50
|
return toString.call(target) === '[object Promise]';
|
|
@@ -49,6 +53,18 @@ function isPromise(target) {
|
|
|
49
53
|
function isBoundFunction(target) {
|
|
50
54
|
return isFunction(target) && target.name.indexOf('bound ') === 0 && !target.hasOwnProperty('prototype');
|
|
51
55
|
}
|
|
56
|
+
// is constructor function
|
|
57
|
+
function isConstructor(target) {
|
|
58
|
+
var _a;
|
|
59
|
+
if (isFunction(target)) {
|
|
60
|
+
const targetStr = target.toString();
|
|
61
|
+
return (((_a = target.prototype) === null || _a === void 0 ? void 0 : _a.constructor) === target &&
|
|
62
|
+
Object.getOwnPropertyNames(target.prototype).length > 1) ||
|
|
63
|
+
/^function\s+[A-Z]/.test(targetStr) ||
|
|
64
|
+
/^class\s+/.test(targetStr);
|
|
65
|
+
}
|
|
66
|
+
return false;
|
|
67
|
+
}
|
|
52
68
|
// is ShadowRoot
|
|
53
69
|
function isShadowRoot(target) {
|
|
54
70
|
return typeof ShadowRoot !== 'undefined' && target instanceof ShadowRoot;
|
|
@@ -270,6 +286,7 @@ function pureCreateElement(tagName, options) {
|
|
|
270
286
|
const element = document.createElement(tagName, options);
|
|
271
287
|
if (element.__MICRO_APP_NAME__)
|
|
272
288
|
delete element.__MICRO_APP_NAME__;
|
|
289
|
+
element.__PURE_ELEMENT__ = true;
|
|
273
290
|
return element;
|
|
274
291
|
}
|
|
275
292
|
/**
|
|
@@ -465,10 +482,18 @@ const globalKeyToBeCached = 'window,self,globalThis,Array,Object,String,Boolean,
|
|
|
465
482
|
* @param config fetch options
|
|
466
483
|
*/
|
|
467
484
|
function fetchSource(url, appName = null, options = {}) {
|
|
485
|
+
/**
|
|
486
|
+
* When child navigate to new async page, click event will scope dom to child and then fetch new source
|
|
487
|
+
* this may cause error when fetch rewrite by baseApp
|
|
488
|
+
* e.g.
|
|
489
|
+
* baseApp: <script crossorigin src="https://sgm-static.jd.com/sgm-2.8.0.js" name="SGMH5" sid="6f88a6e4ba4b4ae5acef2ec22c075085" appKey="jdb-adminb2b-pc"></script>
|
|
490
|
+
*/
|
|
491
|
+
removeDomScope();
|
|
468
492
|
if (isFunction(microApp.fetch)) {
|
|
469
493
|
return microApp.fetch(url, options, appName);
|
|
470
494
|
}
|
|
471
|
-
|
|
495
|
+
// Don’t use globalEnv.rawWindow.fetch, will cause sgm-2.8.0.js throw error in nest app
|
|
496
|
+
return window.fetch(url, options).then((res) => {
|
|
472
497
|
return res.text();
|
|
473
498
|
});
|
|
474
499
|
}
|
|
@@ -551,7 +576,7 @@ class CSSParser {
|
|
|
551
576
|
return true;
|
|
552
577
|
}
|
|
553
578
|
formatSelector(skip) {
|
|
554
|
-
const m = this.commonMatch(/^
|
|
579
|
+
const m = this.commonMatch(/^[^{]+/, skip);
|
|
555
580
|
if (!m)
|
|
556
581
|
return false;
|
|
557
582
|
return m[0].replace(/(^|,[\n\s]*)([^,]+)/g, (_, separator, selector) => {
|
|
@@ -631,7 +656,7 @@ class CSSParser {
|
|
|
631
656
|
keyframesRule() {
|
|
632
657
|
if (!this.commonMatch(/^@([-\w]+)?keyframes\s*/))
|
|
633
658
|
return false;
|
|
634
|
-
if (!this.commonMatch(/^
|
|
659
|
+
if (!this.commonMatch(/^[^{]+/))
|
|
635
660
|
return parseError('@keyframes missing name', this.linkPath);
|
|
636
661
|
this.matchComments();
|
|
637
662
|
if (!this.matchOpenBrace())
|
|
@@ -783,7 +808,7 @@ class CSSParser {
|
|
|
783
808
|
}
|
|
784
809
|
// splice string
|
|
785
810
|
recordResult(strFragment) {
|
|
786
|
-
// Firefox
|
|
811
|
+
// Firefox performance degradation when string contain special characters, see https://github.com/micro-zoe/micro-app/issues/256
|
|
787
812
|
if (isFireFox()) {
|
|
788
813
|
this.result += encodeURIComponent(strFragment);
|
|
789
814
|
}
|
|
@@ -1071,6 +1096,27 @@ function fixReactHMRConflict(app) {
|
|
|
1071
1096
|
}
|
|
1072
1097
|
}
|
|
1073
1098
|
}
|
|
1099
|
+
/**
|
|
1100
|
+
* reDefine parentNode of html
|
|
1101
|
+
* Scenes:
|
|
1102
|
+
* 1. element-ui popover.js
|
|
1103
|
+
* if (html.parentNode === document) ...
|
|
1104
|
+
*/
|
|
1105
|
+
function throttleDeferForParentNode(proxyDocument) {
|
|
1106
|
+
const html = globalEnv.rawDocument.firstElementChild;
|
|
1107
|
+
if (html && html.parentNode !== proxyDocument) {
|
|
1108
|
+
setRootParentNode(html, proxyDocument);
|
|
1109
|
+
defer(() => {
|
|
1110
|
+
setRootParentNode(html, globalEnv.rawDocument);
|
|
1111
|
+
});
|
|
1112
|
+
}
|
|
1113
|
+
}
|
|
1114
|
+
function setRootParentNode(root, value) {
|
|
1115
|
+
Object.defineProperty(root, 'parentNode', {
|
|
1116
|
+
value,
|
|
1117
|
+
configurable: true,
|
|
1118
|
+
});
|
|
1119
|
+
}
|
|
1074
1120
|
|
|
1075
1121
|
// Record element and map element
|
|
1076
1122
|
const dynamicElementInMicroAppMap = new WeakMap();
|
|
@@ -1208,20 +1254,35 @@ function getMappingNode(node) {
|
|
|
1208
1254
|
* @param rawMethod method
|
|
1209
1255
|
*/
|
|
1210
1256
|
function commonElementHandler(parent, newChild, passiveChild, rawMethod) {
|
|
1211
|
-
|
|
1257
|
+
const currentAppName = getCurrentAppName();
|
|
1258
|
+
if (newChild instanceof Node &&
|
|
1259
|
+
(newChild.__MICRO_APP_NAME__ ||
|
|
1260
|
+
(currentAppName && !newChild.__PURE_ELEMENT__))) {
|
|
1261
|
+
newChild.__MICRO_APP_NAME__ = newChild.__MICRO_APP_NAME__ || currentAppName;
|
|
1212
1262
|
const app = appInstanceMap.get(newChild.__MICRO_APP_NAME__);
|
|
1213
1263
|
if (app === null || app === void 0 ? void 0 : app.container) {
|
|
1264
|
+
if (newChild instanceof Element) {
|
|
1265
|
+
if (/^(img|script)$/i.test(newChild.tagName)) {
|
|
1266
|
+
if (newChild.hasAttribute('src')) {
|
|
1267
|
+
globalEnv.rawSetAttribute.call(newChild, 'src', CompletionPath(newChild.getAttribute('src'), app.url));
|
|
1268
|
+
}
|
|
1269
|
+
if (newChild.hasAttribute('srcset')) {
|
|
1270
|
+
globalEnv.rawSetAttribute.call(newChild, 'srcset', CompletionPath(newChild.getAttribute('srcset'), app.url));
|
|
1271
|
+
}
|
|
1272
|
+
}
|
|
1273
|
+
else if (/^link$/i.test(newChild.tagName) && newChild.hasAttribute('href')) {
|
|
1274
|
+
globalEnv.rawSetAttribute.call(newChild, 'href', CompletionPath(newChild.getAttribute('href'), app.url));
|
|
1275
|
+
}
|
|
1276
|
+
}
|
|
1214
1277
|
return invokePrototypeMethod(app, rawMethod, parent, handleNewNode(parent, newChild, app), passiveChild && getMappingNode(passiveChild));
|
|
1215
1278
|
}
|
|
1216
1279
|
else if (rawMethod === globalEnv.rawAppend || rawMethod === globalEnv.rawPrepend) {
|
|
1217
1280
|
return rawMethod.call(parent, newChild);
|
|
1218
1281
|
}
|
|
1219
|
-
return rawMethod.call(parent, newChild, passiveChild);
|
|
1220
1282
|
}
|
|
1221
1283
|
else if (rawMethod === globalEnv.rawAppend || rawMethod === globalEnv.rawPrepend) {
|
|
1222
|
-
|
|
1223
|
-
|
|
1224
|
-
const app = appInstanceMap.get(appName);
|
|
1284
|
+
if (!(newChild instanceof Node) && currentAppName) {
|
|
1285
|
+
const app = appInstanceMap.get(currentAppName);
|
|
1225
1286
|
if (app === null || app === void 0 ? void 0 : app.container) {
|
|
1226
1287
|
if (parent === document.head) {
|
|
1227
1288
|
return rawMethod.call(app.container.querySelector('micro-app-head'), newChild);
|
|
@@ -1267,12 +1328,18 @@ function patchElementPrototypeMethods() {
|
|
|
1267
1328
|
};
|
|
1268
1329
|
// prototype methods of delete element👇
|
|
1269
1330
|
Element.prototype.removeChild = function removeChild(oldChild) {
|
|
1331
|
+
var _a;
|
|
1270
1332
|
if (oldChild === null || oldChild === void 0 ? void 0 : oldChild.__MICRO_APP_NAME__) {
|
|
1271
1333
|
const app = appInstanceMap.get(oldChild.__MICRO_APP_NAME__);
|
|
1272
1334
|
if (app === null || app === void 0 ? void 0 : app.container) {
|
|
1273
1335
|
return invokePrototypeMethod(app, globalEnv.rawRemoveChild, this, getMappingNode(oldChild));
|
|
1274
1336
|
}
|
|
1275
|
-
|
|
1337
|
+
try {
|
|
1338
|
+
return globalEnv.rawRemoveChild.call(this, oldChild);
|
|
1339
|
+
}
|
|
1340
|
+
catch (_b) {
|
|
1341
|
+
return (_a = oldChild === null || oldChild === void 0 ? void 0 : oldChild.parentNode) === null || _a === void 0 ? void 0 : _a.removeChild(oldChild);
|
|
1342
|
+
}
|
|
1276
1343
|
}
|
|
1277
1344
|
return globalEnv.rawRemoveChild.call(this, oldChild);
|
|
1278
1345
|
};
|
|
@@ -1288,9 +1355,9 @@ function patchElementPrototypeMethods() {
|
|
|
1288
1355
|
* @param element new element
|
|
1289
1356
|
*/
|
|
1290
1357
|
function markElement(element) {
|
|
1291
|
-
const
|
|
1292
|
-
if (
|
|
1293
|
-
element.__MICRO_APP_NAME__ =
|
|
1358
|
+
const currentAppName = getCurrentAppName();
|
|
1359
|
+
if (currentAppName)
|
|
1360
|
+
element.__MICRO_APP_NAME__ = currentAppName;
|
|
1294
1361
|
return element;
|
|
1295
1362
|
}
|
|
1296
1363
|
// methods of document
|
|
@@ -1312,28 +1379,28 @@ function patchDocument() {
|
|
|
1312
1379
|
// query element👇
|
|
1313
1380
|
function querySelector(selectors) {
|
|
1314
1381
|
var _a, _b, _c, _d;
|
|
1315
|
-
const
|
|
1316
|
-
if (!
|
|
1317
|
-
!((_a = appInstanceMap.get(
|
|
1382
|
+
const currentAppName = getCurrentAppName();
|
|
1383
|
+
if (!currentAppName ||
|
|
1384
|
+
!((_a = appInstanceMap.get(currentAppName)) === null || _a === void 0 ? void 0 : _a.container) ||
|
|
1318
1385
|
!selectors ||
|
|
1319
1386
|
isUniqueElement(selectors) ||
|
|
1320
1387
|
// see https://github.com/micro-zoe/micro-app/issues/56
|
|
1321
1388
|
rawDocument !== this) {
|
|
1322
1389
|
return globalEnv.rawQuerySelector.call(this, selectors);
|
|
1323
1390
|
}
|
|
1324
|
-
return (_d = (_c = (_b = appInstanceMap.get(
|
|
1391
|
+
return (_d = (_c = (_b = appInstanceMap.get(currentAppName)) === null || _b === void 0 ? void 0 : _b.container) === null || _c === void 0 ? void 0 : _c.querySelector(selectors)) !== null && _d !== void 0 ? _d : null;
|
|
1325
1392
|
}
|
|
1326
1393
|
function querySelectorAll(selectors) {
|
|
1327
1394
|
var _a, _b, _c, _d;
|
|
1328
|
-
const
|
|
1329
|
-
if (!
|
|
1330
|
-
!((_a = appInstanceMap.get(
|
|
1395
|
+
const currentAppName = getCurrentAppName();
|
|
1396
|
+
if (!currentAppName ||
|
|
1397
|
+
!((_a = appInstanceMap.get(currentAppName)) === null || _a === void 0 ? void 0 : _a.container) ||
|
|
1331
1398
|
!selectors ||
|
|
1332
1399
|
isUniqueElement(selectors) ||
|
|
1333
1400
|
rawDocument !== this) {
|
|
1334
1401
|
return globalEnv.rawQuerySelectorAll.call(this, selectors);
|
|
1335
1402
|
}
|
|
1336
|
-
return (_d = (_c = (_b = appInstanceMap.get(
|
|
1403
|
+
return (_d = (_c = (_b = appInstanceMap.get(currentAppName)) === null || _b === void 0 ? void 0 : _b.container) === null || _c === void 0 ? void 0 : _c.querySelectorAll(selectors)) !== null && _d !== void 0 ? _d : [];
|
|
1337
1404
|
}
|
|
1338
1405
|
Document.prototype.querySelector = querySelector;
|
|
1339
1406
|
Document.prototype.querySelectorAll = querySelectorAll;
|
|
@@ -1361,11 +1428,11 @@ function patchDocument() {
|
|
|
1361
1428
|
};
|
|
1362
1429
|
Document.prototype.getElementsByTagName = function getElementsByTagName(key) {
|
|
1363
1430
|
var _a;
|
|
1364
|
-
const
|
|
1365
|
-
if (!
|
|
1431
|
+
const currentAppName = getCurrentAppName();
|
|
1432
|
+
if (!currentAppName ||
|
|
1366
1433
|
isUniqueElement(key) ||
|
|
1367
1434
|
isInvalidQuerySelectorKey(key) ||
|
|
1368
|
-
(!((_a = appInstanceMap.get(
|
|
1435
|
+
(!((_a = appInstanceMap.get(currentAppName)) === null || _a === void 0 ? void 0 : _a.inline) && /^script$/i.test(key))) {
|
|
1369
1436
|
return globalEnv.rawGetElementsByTagName.call(this, key);
|
|
1370
1437
|
}
|
|
1371
1438
|
try {
|
|
@@ -1401,9 +1468,9 @@ function patchSetAttribute() {
|
|
|
1401
1468
|
if (/^micro-app(-\S+)?/i.test(this.tagName) && key === 'data') {
|
|
1402
1469
|
if (isPlainObject(value)) {
|
|
1403
1470
|
const cloneValue = {};
|
|
1404
|
-
Object.getOwnPropertyNames(value).forEach((
|
|
1405
|
-
if (!(isString(
|
|
1406
|
-
cloneValue[
|
|
1471
|
+
Object.getOwnPropertyNames(value).forEach((ownKey) => {
|
|
1472
|
+
if (!(isString(ownKey) && ownKey.indexOf('__') === 0)) {
|
|
1473
|
+
cloneValue[ownKey] = value[ownKey];
|
|
1407
1474
|
}
|
|
1408
1475
|
});
|
|
1409
1476
|
this.data = cloneValue;
|
|
@@ -1412,14 +1479,15 @@ function patchSetAttribute() {
|
|
|
1412
1479
|
logWarn('property data must be an object', this.getAttribute('name'));
|
|
1413
1480
|
}
|
|
1414
1481
|
}
|
|
1415
|
-
else if ((((key === 'src' || key === 'srcset') && /^(img|script)$/i.test(this.tagName)) ||
|
|
1416
|
-
(key === 'href' && /^link$/i.test(this.tagName))) &&
|
|
1417
|
-
this.__MICRO_APP_NAME__ &&
|
|
1418
|
-
appInstanceMap.has(this.__MICRO_APP_NAME__)) {
|
|
1419
|
-
const app = appInstanceMap.get(this.__MICRO_APP_NAME__);
|
|
1420
|
-
globalEnv.rawSetAttribute.call(this, key, CompletionPath(value, app.url));
|
|
1421
|
-
}
|
|
1422
1482
|
else {
|
|
1483
|
+
const appName = this.__MICRO_APP_NAME__ || getCurrentAppName();
|
|
1484
|
+
if (appName &&
|
|
1485
|
+
appInstanceMap.has(appName) &&
|
|
1486
|
+
(((key === 'src' || key === 'srcset') && /^(img|script)$/i.test(this.tagName)) ||
|
|
1487
|
+
(key === 'href' && /^link$/i.test(this.tagName)))) {
|
|
1488
|
+
const app = appInstanceMap.get(appName);
|
|
1489
|
+
value = CompletionPath(value, app.url);
|
|
1490
|
+
}
|
|
1423
1491
|
globalEnv.rawSetAttribute.call(this, key, value);
|
|
1424
1492
|
}
|
|
1425
1493
|
};
|
|
@@ -2286,7 +2354,7 @@ function releaseUnmountOfNestedApp() {
|
|
|
2286
2354
|
}
|
|
2287
2355
|
// if micro-app run in micro application, delete all next generation application when unmount event received
|
|
2288
2356
|
// unmount event will auto release by sandbox
|
|
2289
|
-
function
|
|
2357
|
+
function initEnvOfNestedApp() {
|
|
2290
2358
|
if (window.__MICRO_APP_ENVIRONMENT__) {
|
|
2291
2359
|
releaseUnmountOfNestedApp();
|
|
2292
2360
|
window.addEventListener('unmount', unmountNestedApp, false);
|
|
@@ -2299,35 +2367,30 @@ function isBoundedFunction(value) {
|
|
|
2299
2367
|
return value.__MICRO_APP_IS_BOUND_FUNCTION__;
|
|
2300
2368
|
return value.__MICRO_APP_IS_BOUND_FUNCTION__ = isBoundFunction(value);
|
|
2301
2369
|
}
|
|
2302
|
-
function
|
|
2303
|
-
var _a;
|
|
2370
|
+
function isConstructorFunction(value) {
|
|
2304
2371
|
if (isBoolean(value.__MICRO_APP_IS_CONSTRUCTOR__))
|
|
2305
2372
|
return value.__MICRO_APP_IS_CONSTRUCTOR__;
|
|
2306
|
-
|
|
2307
|
-
const result = (((_a = value.prototype) === null || _a === void 0 ? void 0 : _a.constructor) === value &&
|
|
2308
|
-
Object.getOwnPropertyNames(value.prototype).length > 1) ||
|
|
2309
|
-
/^function\s+[A-Z]/.test(valueStr) ||
|
|
2310
|
-
/^class\s+/.test(valueStr);
|
|
2311
|
-
return value.__MICRO_APP_IS_CONSTRUCTOR__ = result;
|
|
2373
|
+
return value.__MICRO_APP_IS_CONSTRUCTOR__ = isConstructor(value);
|
|
2312
2374
|
}
|
|
2313
2375
|
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
|
|
2314
|
-
function
|
|
2315
|
-
|
|
2316
|
-
|
|
2317
|
-
|
|
2318
|
-
|
|
2376
|
+
function bindFunctionToRawObject(rawObject, value, key = 'WINDOW') {
|
|
2377
|
+
const cacheKey = `__MICRO_APP_BOUND_${key}_FUNCTION__`;
|
|
2378
|
+
if (value[cacheKey])
|
|
2379
|
+
return value[cacheKey];
|
|
2380
|
+
if (!isConstructorFunction(value) && !isBoundedFunction(value)) {
|
|
2381
|
+
const bindRawObjectValue = value.bind(rawObject);
|
|
2319
2382
|
for (const key in value) {
|
|
2320
|
-
|
|
2383
|
+
bindRawObjectValue[key] = value[key];
|
|
2321
2384
|
}
|
|
2322
2385
|
if (value.hasOwnProperty('prototype')) {
|
|
2323
|
-
rawDefineProperty(
|
|
2386
|
+
rawDefineProperty(bindRawObjectValue, 'prototype', {
|
|
2324
2387
|
value: value.prototype,
|
|
2325
2388
|
configurable: true,
|
|
2326
2389
|
enumerable: false,
|
|
2327
2390
|
writable: true,
|
|
2328
2391
|
});
|
|
2329
2392
|
}
|
|
2330
|
-
return value
|
|
2393
|
+
return value[cacheKey] = bindRawObjectValue;
|
|
2331
2394
|
}
|
|
2332
2395
|
return value;
|
|
2333
2396
|
}
|
|
@@ -2746,7 +2809,10 @@ function addHistoryListener(appName) {
|
|
|
2746
2809
|
const rawWindow = globalEnv.rawWindow;
|
|
2747
2810
|
// handle popstate event and distribute to child app
|
|
2748
2811
|
const popStateHandler = (e) => {
|
|
2749
|
-
|
|
2812
|
+
/**
|
|
2813
|
+
* 1. unmount app & hidden keep-alive app will not receive popstate event
|
|
2814
|
+
* 2. filter out onlyForBrowser
|
|
2815
|
+
*/
|
|
2750
2816
|
if (getActiveApps(true).includes(appName) && !e.onlyForBrowser) {
|
|
2751
2817
|
const microPath = getMicroPathFromURL(appName);
|
|
2752
2818
|
const app = appInstanceMap.get(appName);
|
|
@@ -2847,8 +2913,7 @@ function createMicroHistory(appName, microLocation) {
|
|
|
2847
2913
|
const rawHistory = globalEnv.rawWindow.history;
|
|
2848
2914
|
function getMicroHistoryMethod(methodName) {
|
|
2849
2915
|
return function (...rests) {
|
|
2850
|
-
if ((
|
|
2851
|
-
(isString(rests[2]) || isURL(rests[2]))) {
|
|
2916
|
+
if (isString(rests[2]) || isURL(rests[2])) {
|
|
2852
2917
|
const targetLocation = createURL(rests[2], microLocation.href);
|
|
2853
2918
|
if (targetLocation.origin === microLocation.origin) {
|
|
2854
2919
|
navigateWithNativeEvent(methodName, setMicroPathToURL(appName, targetLocation), true, setMicroState(appName, rawHistory.state, rests[0]), rests[1]);
|
|
@@ -2866,18 +2931,21 @@ function createMicroHistory(appName, microLocation) {
|
|
|
2866
2931
|
}
|
|
2867
2932
|
};
|
|
2868
2933
|
}
|
|
2934
|
+
const pushState = getMicroHistoryMethod('pushState');
|
|
2935
|
+
const replaceState = getMicroHistoryMethod('replaceState');
|
|
2869
2936
|
return new Proxy(rawHistory, {
|
|
2870
2937
|
get(target, key) {
|
|
2871
2938
|
if (key === 'state') {
|
|
2872
2939
|
return getMicroState(appName, rawHistory.state);
|
|
2873
2940
|
}
|
|
2874
|
-
else if (
|
|
2875
|
-
return
|
|
2941
|
+
else if (key === 'pushState') {
|
|
2942
|
+
return pushState;
|
|
2876
2943
|
}
|
|
2877
|
-
|
|
2878
|
-
|
|
2879
|
-
|
|
2880
|
-
|
|
2944
|
+
else if (key === 'replaceState') {
|
|
2945
|
+
return replaceState;
|
|
2946
|
+
}
|
|
2947
|
+
const rawValue = Reflect.get(target, key);
|
|
2948
|
+
return isFunction(rawValue) ? bindFunctionToRawObject(target, rawValue, 'HISTORY') : rawValue;
|
|
2881
2949
|
}
|
|
2882
2950
|
});
|
|
2883
2951
|
}
|
|
@@ -2894,7 +2962,7 @@ function nativeHistoryNavigate(methodName, fullPath, state = null, title = '') {
|
|
|
2894
2962
|
/**
|
|
2895
2963
|
* Navigate to new path, and dispatch native popStateEvent/hashChangeEvent to browser
|
|
2896
2964
|
* Use scenes:
|
|
2897
|
-
* 1. mount/unmount through
|
|
2965
|
+
* 1. mount/unmount through attachRouteToBrowserURL with limited popstateEvent
|
|
2898
2966
|
* 2. proxyHistory.pushState/replaceState with limited popstateEvent
|
|
2899
2967
|
* 3. api microApp.router.push/replace
|
|
2900
2968
|
* 4. proxyLocation.hash = xxx
|
|
@@ -2914,11 +2982,12 @@ function navigateWithNativeEvent(methodName, result, onlyForBrowser, state, titl
|
|
|
2914
2982
|
dispatchNativeEvent(onlyForBrowser, oldHref);
|
|
2915
2983
|
}
|
|
2916
2984
|
/**
|
|
2917
|
-
* update browser url when mount/unmount/hidden/show
|
|
2985
|
+
* update browser url when mount/unmount/hidden/show/attachToURL/attachAllToURL
|
|
2986
|
+
* just attach microRoute info to browser, dispatch event to base app(exclude child)
|
|
2918
2987
|
* @param result result of add/remove microApp path on browser url
|
|
2919
2988
|
* @param state history.state
|
|
2920
2989
|
*/
|
|
2921
|
-
function
|
|
2990
|
+
function attachRouteToBrowserURL(result, state) {
|
|
2922
2991
|
navigateWithNativeEvent('replaceState', result, true, state);
|
|
2923
2992
|
}
|
|
2924
2993
|
/**
|
|
@@ -2984,11 +3053,11 @@ function createRouterApi() {
|
|
|
2984
3053
|
function createNavigationMethod(replace) {
|
|
2985
3054
|
return function (to) {
|
|
2986
3055
|
const appName = formatAppName(to.name);
|
|
2987
|
-
// console.log(3333333, appInstanceMap.get(appName))
|
|
2988
3056
|
if (appName && isString(to.path)) {
|
|
2989
3057
|
const app = appInstanceMap.get(appName);
|
|
2990
|
-
if (app && !app.sandBox)
|
|
2991
|
-
return logError(`navigation failed,
|
|
3058
|
+
if (app && (!app.sandBox || !app.useMemoryRouter)) {
|
|
3059
|
+
return logError(`navigation failed, memory router of app ${appName} is closed`);
|
|
3060
|
+
}
|
|
2992
3061
|
// active apps, include hidden keep-alive app
|
|
2993
3062
|
if (getActiveApps().includes(appName)) {
|
|
2994
3063
|
const microLocation = app.sandBox.proxyWindow.location;
|
|
@@ -3065,43 +3134,95 @@ function createRouterApi() {
|
|
|
3065
3134
|
function clearRouterWhenUnmount(appName) {
|
|
3066
3135
|
router.current.delete(appName);
|
|
3067
3136
|
}
|
|
3068
|
-
// defaultPage data
|
|
3069
|
-
const defaultPageRecord = useMapRecord();
|
|
3070
3137
|
/**
|
|
3071
|
-
*
|
|
3138
|
+
* NOTE:
|
|
3139
|
+
* 1. sandbox not open
|
|
3140
|
+
* 2. useMemoryRouter is false
|
|
3141
|
+
*/
|
|
3142
|
+
function commonHandlerForAttachToURL(appName) {
|
|
3143
|
+
const app = appInstanceMap.get(appName);
|
|
3144
|
+
if (app.sandBox && app.useMemoryRouter) {
|
|
3145
|
+
attachRouteToBrowserURL(setMicroPathToURL(appName, app.sandBox.proxyWindow.location), setMicroState(appName, globalEnv.rawWindow.history.state, null));
|
|
3146
|
+
}
|
|
3147
|
+
}
|
|
3148
|
+
/**
|
|
3149
|
+
* Attach specified active app router info to browser url
|
|
3072
3150
|
* @param appName app name
|
|
3073
|
-
* @param path page path
|
|
3074
3151
|
*/
|
|
3075
|
-
function
|
|
3152
|
+
function attachToURL(appName) {
|
|
3076
3153
|
appName = formatAppName(appName);
|
|
3077
|
-
if (
|
|
3078
|
-
|
|
3079
|
-
|
|
3154
|
+
if (appName && getActiveApps().includes(appName)) {
|
|
3155
|
+
commonHandlerForAttachToURL(appName);
|
|
3156
|
+
}
|
|
3080
3157
|
}
|
|
3081
|
-
|
|
3082
|
-
|
|
3083
|
-
|
|
3084
|
-
|
|
3085
|
-
|
|
3158
|
+
/**
|
|
3159
|
+
* Attach all active app router info to browser url
|
|
3160
|
+
*/
|
|
3161
|
+
function attachAllToURL() {
|
|
3162
|
+
getActiveApps().forEach(appName => commonHandlerForAttachToURL(appName));
|
|
3163
|
+
}
|
|
3164
|
+
function createDefaultPageApi() {
|
|
3165
|
+
// defaultPage data
|
|
3166
|
+
const defaultPageRecord = useMapRecord();
|
|
3167
|
+
/**
|
|
3168
|
+
* defaultPage only effect when mount, and has lower priority than query on browser url
|
|
3169
|
+
* @param appName app name
|
|
3170
|
+
* @param path page path
|
|
3171
|
+
*/
|
|
3172
|
+
function setDefaultPage(appName, path) {
|
|
3173
|
+
appName = formatAppName(appName);
|
|
3174
|
+
if (!appName || !path) {
|
|
3175
|
+
if (process.env.NODE_ENV !== 'production') {
|
|
3176
|
+
if (!appName) {
|
|
3177
|
+
logWarn(`setDefaultPage: invalid appName "${appName}"`);
|
|
3178
|
+
}
|
|
3179
|
+
else {
|
|
3180
|
+
logWarn('setDefaultPage: path is required');
|
|
3181
|
+
}
|
|
3182
|
+
}
|
|
3183
|
+
return noopFalse;
|
|
3184
|
+
}
|
|
3185
|
+
return defaultPageRecord.add(appName, path);
|
|
3186
|
+
}
|
|
3187
|
+
function removeDefaultPage(appName) {
|
|
3188
|
+
appName = formatAppName(appName);
|
|
3189
|
+
if (!appName)
|
|
3190
|
+
return false;
|
|
3191
|
+
return defaultPageRecord.delete(appName);
|
|
3192
|
+
}
|
|
3193
|
+
return {
|
|
3194
|
+
setDefaultPage,
|
|
3195
|
+
removeDefaultPage,
|
|
3196
|
+
getDefaultPage: defaultPageRecord.get,
|
|
3197
|
+
};
|
|
3198
|
+
}
|
|
3199
|
+
function createBaseRouterApi() {
|
|
3200
|
+
/**
|
|
3201
|
+
* Record base app router, let child app control base app navigation
|
|
3202
|
+
*/
|
|
3203
|
+
let baseRouterProxy = null;
|
|
3204
|
+
function setBaseAppRouter(baseRouter) {
|
|
3205
|
+
if (isObject(baseRouter)) {
|
|
3206
|
+
baseRouterProxy = new Proxy(baseRouter, {
|
|
3207
|
+
get(target, key) {
|
|
3208
|
+
removeDomScope();
|
|
3209
|
+
const rawValue = Reflect.get(target, key);
|
|
3210
|
+
return isFunction(rawValue) ? bindFunctionToRawObject(target, rawValue, 'BASEROUTER') : rawValue;
|
|
3211
|
+
}
|
|
3212
|
+
});
|
|
3213
|
+
}
|
|
3214
|
+
else if (process.env.NODE_ENV !== 'production') {
|
|
3215
|
+
logWarn('setBaseAppRouter: Invalid base router');
|
|
3216
|
+
}
|
|
3217
|
+
}
|
|
3218
|
+
return {
|
|
3219
|
+
setBaseAppRouter,
|
|
3220
|
+
getBaseAppRouter: () => baseRouterProxy,
|
|
3221
|
+
};
|
|
3086
3222
|
}
|
|
3087
3223
|
// Router API for developer
|
|
3088
|
-
const router = {
|
|
3089
|
-
|
|
3090
|
-
encode: encodeMicroPath,
|
|
3091
|
-
decode: decodeMicroPath,
|
|
3092
|
-
push: createNavigationMethod(false),
|
|
3093
|
-
replace: createNavigationMethod(true),
|
|
3094
|
-
go: createRawHistoryMethod('go'),
|
|
3095
|
-
back: createRawHistoryMethod('back'),
|
|
3096
|
-
forward: createRawHistoryMethod('forward'),
|
|
3097
|
-
beforeEach: beforeGuards.add,
|
|
3098
|
-
afterEach: afterGuards.add,
|
|
3099
|
-
// attachToURL: 将指定的子应用路由信息添加到浏览器地址上
|
|
3100
|
-
// attachAllToURL: 将所有正在运行的子应用路由信息添加到浏览器地址上
|
|
3101
|
-
setDefaultPage,
|
|
3102
|
-
removeDefaultPage,
|
|
3103
|
-
getDefaultPage: defaultPageRecord.get,
|
|
3104
|
-
};
|
|
3224
|
+
const router = Object.assign(Object.assign({ current: new Map(), encode: encodeMicroPath, decode: decodeMicroPath, push: createNavigationMethod(false), replace: createNavigationMethod(true), go: createRawHistoryMethod('go'), back: createRawHistoryMethod('back'), forward: createRawHistoryMethod('forward'), beforeEach: beforeGuards.add, afterEach: afterGuards.add, attachToURL,
|
|
3225
|
+
attachAllToURL }, createDefaultPageApi()), createBaseRouterApi());
|
|
3105
3226
|
return {
|
|
3106
3227
|
router,
|
|
3107
3228
|
executeNavigationGuard,
|
|
@@ -3115,56 +3236,6 @@ const shadowLocationKeys = ['href', 'pathname', 'search', 'hash'];
|
|
|
3115
3236
|
const locationKeys = [...shadowLocationKeys, 'host', 'hostname', 'port', 'protocol', 'search'];
|
|
3116
3237
|
// origin, fullPath is necessary for guardLocation
|
|
3117
3238
|
const guardLocationKeys = [...locationKeys, 'origin', 'fullPath'];
|
|
3118
|
-
/**
|
|
3119
|
-
* create guardLocation by microLocation, used for router guard
|
|
3120
|
-
*/
|
|
3121
|
-
function createGuardLocation(appName, microLocation) {
|
|
3122
|
-
const guardLocation = assign({ name: appName }, microLocation);
|
|
3123
|
-
// The prototype values on the URL needs to be manually transferred
|
|
3124
|
-
for (const key of guardLocationKeys)
|
|
3125
|
-
guardLocation[key] = microLocation[key];
|
|
3126
|
-
return guardLocation;
|
|
3127
|
-
}
|
|
3128
|
-
// for updateBrowserURLWithLocation when initial
|
|
3129
|
-
function autoTriggerNavigationGuard(appName, microLocation) {
|
|
3130
|
-
executeNavigationGuard(appName, createGuardLocation(appName, microLocation), createGuardLocation(appName, microLocation));
|
|
3131
|
-
}
|
|
3132
|
-
/**
|
|
3133
|
-
* The following scenes will trigger location update:
|
|
3134
|
-
* 1. pushState/replaceState
|
|
3135
|
-
* 2. popStateEvent
|
|
3136
|
-
* 3. query on browser url when init sub app
|
|
3137
|
-
* 4. set defaultPage when when init sub app
|
|
3138
|
-
* NOTE:
|
|
3139
|
-
* 1. update browser URL first, and then update microLocation
|
|
3140
|
-
* 2. the same fullPath will not trigger router guards
|
|
3141
|
-
* @param appName app name
|
|
3142
|
-
* @param path target path
|
|
3143
|
-
* @param base base url
|
|
3144
|
-
* @param microLocation micro app location
|
|
3145
|
-
* @param type auto prevent
|
|
3146
|
-
*/
|
|
3147
|
-
function updateMicroLocation(appName, path, microLocation, type) {
|
|
3148
|
-
const newLocation = createURL(path, microLocation.href);
|
|
3149
|
-
// record old values of microLocation to `from`
|
|
3150
|
-
const from = createGuardLocation(appName, microLocation);
|
|
3151
|
-
for (const key of locationKeys) {
|
|
3152
|
-
if (shadowLocationKeys.includes(key)) {
|
|
3153
|
-
// reference of shadowLocation
|
|
3154
|
-
microLocation.shadowLocation[key] = newLocation[key];
|
|
3155
|
-
}
|
|
3156
|
-
else {
|
|
3157
|
-
// @ts-ignore reference of microLocation
|
|
3158
|
-
microLocation[key] = newLocation[key];
|
|
3159
|
-
}
|
|
3160
|
-
}
|
|
3161
|
-
// update latest values of microLocation to `to`
|
|
3162
|
-
const to = createGuardLocation(appName, microLocation);
|
|
3163
|
-
// The hook called only when fullPath changed
|
|
3164
|
-
if (type === 'auto' || (from.fullPath !== to.fullPath && type !== 'prevent')) {
|
|
3165
|
-
executeNavigationGuard(appName, to, from);
|
|
3166
|
-
}
|
|
3167
|
-
}
|
|
3168
3239
|
/**
|
|
3169
3240
|
* Create location for microApp, each microApp has only one location object, it is a reference type
|
|
3170
3241
|
* MDN https://developer.mozilla.org/en-US/docs/Web/API/Location
|
|
@@ -3309,6 +3380,56 @@ function createMicroLocation(appName, url) {
|
|
|
3309
3380
|
shadowLocation,
|
|
3310
3381
|
});
|
|
3311
3382
|
}
|
|
3383
|
+
/**
|
|
3384
|
+
* create guardLocation by microLocation, used for router guard
|
|
3385
|
+
*/
|
|
3386
|
+
function createGuardLocation(appName, microLocation) {
|
|
3387
|
+
const guardLocation = assign({ name: appName }, microLocation);
|
|
3388
|
+
// The prototype values on the URL needs to be manually transferred
|
|
3389
|
+
for (const key of guardLocationKeys)
|
|
3390
|
+
guardLocation[key] = microLocation[key];
|
|
3391
|
+
return guardLocation;
|
|
3392
|
+
}
|
|
3393
|
+
// for updateBrowserURLWithLocation when initial
|
|
3394
|
+
function autoTriggerNavigationGuard(appName, microLocation) {
|
|
3395
|
+
executeNavigationGuard(appName, createGuardLocation(appName, microLocation), createGuardLocation(appName, microLocation));
|
|
3396
|
+
}
|
|
3397
|
+
/**
|
|
3398
|
+
* The following scenes will trigger location update:
|
|
3399
|
+
* 1. pushState/replaceState
|
|
3400
|
+
* 2. popStateEvent
|
|
3401
|
+
* 3. query on browser url when init sub app
|
|
3402
|
+
* 4. set defaultPage when when init sub app
|
|
3403
|
+
* NOTE:
|
|
3404
|
+
* 1. update browser URL first, and then update microLocation
|
|
3405
|
+
* 2. the same fullPath will not trigger router guards
|
|
3406
|
+
* @param appName app name
|
|
3407
|
+
* @param path target path
|
|
3408
|
+
* @param base base url
|
|
3409
|
+
* @param microLocation micro app location
|
|
3410
|
+
* @param type auto prevent
|
|
3411
|
+
*/
|
|
3412
|
+
function updateMicroLocation(appName, path, microLocation, type) {
|
|
3413
|
+
const newLocation = createURL(path, microLocation.href);
|
|
3414
|
+
// record old values of microLocation to `from`
|
|
3415
|
+
const from = createGuardLocation(appName, microLocation);
|
|
3416
|
+
for (const key of locationKeys) {
|
|
3417
|
+
if (shadowLocationKeys.includes(key)) {
|
|
3418
|
+
// reference of shadowLocation
|
|
3419
|
+
microLocation.shadowLocation[key] = newLocation[key];
|
|
3420
|
+
}
|
|
3421
|
+
else {
|
|
3422
|
+
// @ts-ignore reference of microLocation
|
|
3423
|
+
microLocation[key] = newLocation[key];
|
|
3424
|
+
}
|
|
3425
|
+
}
|
|
3426
|
+
// update latest values of microLocation to `to`
|
|
3427
|
+
const to = createGuardLocation(appName, microLocation);
|
|
3428
|
+
// The hook called only when fullPath changed
|
|
3429
|
+
if (type === 'auto' || (from.fullPath !== to.fullPath && type !== 'prevent')) {
|
|
3430
|
+
executeNavigationGuard(appName, to, from);
|
|
3431
|
+
}
|
|
3432
|
+
}
|
|
3312
3433
|
|
|
3313
3434
|
/**
|
|
3314
3435
|
* The router system has two operations: read and write
|
|
@@ -3344,7 +3465,7 @@ function updateBrowserURLWithLocation(appName, microLocation, defaultPage) {
|
|
|
3344
3465
|
if (defaultPage)
|
|
3345
3466
|
updateMicroLocation(appName, defaultPage, microLocation, 'prevent');
|
|
3346
3467
|
// attach microApp route info to browser URL
|
|
3347
|
-
|
|
3468
|
+
attachRouteToBrowserURL(setMicroPathToURL(appName, microLocation), setMicroState(appName, globalEnv.rawWindow.history.state, null));
|
|
3348
3469
|
// trigger guards after change browser URL
|
|
3349
3470
|
autoTriggerNavigationGuard(appName, microLocation);
|
|
3350
3471
|
}
|
|
@@ -3368,7 +3489,7 @@ function clearRouteStateFromURL(appName, url, microLocation, keepRouteState) {
|
|
|
3368
3489
|
* called on sandbox.stop or hidden of keep-alive app
|
|
3369
3490
|
*/
|
|
3370
3491
|
function removeStateAndPathFromBrowser(appName) {
|
|
3371
|
-
|
|
3492
|
+
attachRouteToBrowserURL(removeMicroPathFromURL(appName), removeMicroState(appName, globalEnv.rawWindow.history.state));
|
|
3372
3493
|
}
|
|
3373
3494
|
|
|
3374
3495
|
/**
|
|
@@ -3380,13 +3501,21 @@ function removeStateAndPathFromBrowser(appName) {
|
|
|
3380
3501
|
* @param target proxy target
|
|
3381
3502
|
*/
|
|
3382
3503
|
function createMicroFetch(url, target) {
|
|
3383
|
-
|
|
3384
|
-
|
|
3385
|
-
|
|
3504
|
+
const rawFetch = !isUndefined(target) ? target : globalEnv.rawWindow.fetch;
|
|
3505
|
+
if (!isFunction(rawFetch))
|
|
3506
|
+
return rawFetch;
|
|
3386
3507
|
return function microFetch(input, init, ...rests) {
|
|
3387
3508
|
if (isString(input) || isURL(input)) {
|
|
3388
3509
|
input = createURL(input, url).toString();
|
|
3389
3510
|
}
|
|
3511
|
+
/**
|
|
3512
|
+
* When fetch rewrite by baseApp, domScope still active when exec rawWindow.fetch
|
|
3513
|
+
* If baseApp operate dom in fetch, it will cause error
|
|
3514
|
+
* The same for XMLHttpRequest, EventSource
|
|
3515
|
+
* e.g.
|
|
3516
|
+
* baseApp: <script crossorigin src="https://sgm-static.jd.com/sgm-2.8.0.js" name="SGMH5" sid="6f88a6e4ba4b4ae5acef2ec22c075085" appKey="jdb-adminb2b-pc"></script>
|
|
3517
|
+
*/
|
|
3518
|
+
removeDomScope();
|
|
3390
3519
|
return rawFetch.call(globalEnv.rawWindow, input, init, ...rests);
|
|
3391
3520
|
};
|
|
3392
3521
|
}
|
|
@@ -3397,14 +3526,15 @@ function createMicroFetch(url, target) {
|
|
|
3397
3526
|
* @param target proxy target
|
|
3398
3527
|
*/
|
|
3399
3528
|
function createMicroXMLHttpRequest(url, target) {
|
|
3400
|
-
|
|
3401
|
-
|
|
3402
|
-
|
|
3529
|
+
const rawXMLHttpRequest = !isUndefined(target) ? target : globalEnv.rawWindow.XMLHttpRequest;
|
|
3530
|
+
if (!isConstructor(rawXMLHttpRequest))
|
|
3531
|
+
return rawXMLHttpRequest;
|
|
3403
3532
|
return class MicroXMLHttpRequest extends rawXMLHttpRequest {
|
|
3404
3533
|
open(method, reqUrl, ...rests) {
|
|
3405
3534
|
if ((isString(reqUrl) && !/^f(ile|tp):\/\//.test(reqUrl)) || isURL(reqUrl)) {
|
|
3406
3535
|
reqUrl = createURL(reqUrl, url).toString();
|
|
3407
3536
|
}
|
|
3537
|
+
removeDomScope();
|
|
3408
3538
|
super.open(method, reqUrl, ...rests);
|
|
3409
3539
|
}
|
|
3410
3540
|
};
|
|
@@ -3420,14 +3550,15 @@ function useMicroEventSource() {
|
|
|
3420
3550
|
* @param target proxy target
|
|
3421
3551
|
*/
|
|
3422
3552
|
function createMicroEventSource(appName, url, target) {
|
|
3423
|
-
|
|
3424
|
-
|
|
3425
|
-
|
|
3553
|
+
const rawEventSource = !isUndefined(target) ? target : globalEnv.rawWindow.EventSource;
|
|
3554
|
+
if (!isConstructor(rawEventSource))
|
|
3555
|
+
return rawEventSource;
|
|
3426
3556
|
return class MicroEventSource extends rawEventSource {
|
|
3427
3557
|
constructor(eventSourceUrl, eventSourceInitDict, ...rests) {
|
|
3428
3558
|
if (isString(eventSourceUrl) || isURL(eventSourceUrl)) {
|
|
3429
3559
|
eventSourceUrl = createURL(eventSourceUrl, url).toString();
|
|
3430
3560
|
}
|
|
3561
|
+
removeDomScope();
|
|
3431
3562
|
super(eventSourceUrl, eventSourceInitDict, ...rests);
|
|
3432
3563
|
if (eventSourceMap) {
|
|
3433
3564
|
const eventSourceList = eventSourceMap.get(appName);
|
|
@@ -3508,7 +3639,7 @@ class SandBox {
|
|
|
3508
3639
|
if (++SandBox.activeCount === 1) {
|
|
3509
3640
|
effectDocumentEvent();
|
|
3510
3641
|
patchElementPrototypeMethods();
|
|
3511
|
-
|
|
3642
|
+
initEnvOfNestedApp();
|
|
3512
3643
|
}
|
|
3513
3644
|
fixBabelPolyfill6();
|
|
3514
3645
|
}
|
|
@@ -3604,7 +3735,7 @@ class SandBox {
|
|
|
3604
3735
|
this.scopeProperties.includes(key))
|
|
3605
3736
|
return Reflect.get(target, key);
|
|
3606
3737
|
const rawValue = Reflect.get(rawWindow, key);
|
|
3607
|
-
return isFunction(rawValue) ?
|
|
3738
|
+
return isFunction(rawValue) ? bindFunctionToRawObject(rawWindow, rawValue) : rawValue;
|
|
3608
3739
|
},
|
|
3609
3740
|
set: (target, key, value) => {
|
|
3610
3741
|
if (this.active) {
|
|
@@ -3704,20 +3835,22 @@ class SandBox {
|
|
|
3704
3835
|
pureCreateElement,
|
|
3705
3836
|
router,
|
|
3706
3837
|
});
|
|
3838
|
+
this.setProxyDocument(microAppWindow, appName);
|
|
3707
3839
|
this.setMappingPropertiesWithRawDescriptor(microAppWindow);
|
|
3708
3840
|
if (useMemoryRouter)
|
|
3709
3841
|
this.setMicroAppRouter(microAppWindow, appName, url);
|
|
3710
3842
|
}
|
|
3711
|
-
|
|
3712
|
-
|
|
3713
|
-
|
|
3714
|
-
|
|
3715
|
-
|
|
3716
|
-
|
|
3717
|
-
|
|
3718
|
-
|
|
3719
|
-
|
|
3720
|
-
|
|
3843
|
+
setProxyDocument(microAppWindow, appName) {
|
|
3844
|
+
const proxyDocument = this.createProxyDocument(appName);
|
|
3845
|
+
rawDefineProperty(microAppWindow, 'document', {
|
|
3846
|
+
configurable: false,
|
|
3847
|
+
enumerable: true,
|
|
3848
|
+
get() {
|
|
3849
|
+
throttleDeferForSetAppName(appName);
|
|
3850
|
+
// return globalEnv.rawDocument
|
|
3851
|
+
return proxyDocument;
|
|
3852
|
+
},
|
|
3853
|
+
});
|
|
3721
3854
|
}
|
|
3722
3855
|
// properties associated with the native window
|
|
3723
3856
|
setMappingPropertiesWithRawDescriptor(microAppWindow) {
|
|
@@ -3746,18 +3879,21 @@ class SandBox {
|
|
|
3746
3879
|
};
|
|
3747
3880
|
return descriptor;
|
|
3748
3881
|
}
|
|
3882
|
+
/**
|
|
3883
|
+
* init global properties of microAppWindow when exec sandBox.start
|
|
3884
|
+
* @param microAppWindow micro window
|
|
3885
|
+
* @param appName app name
|
|
3886
|
+
* @param url app url
|
|
3887
|
+
*/
|
|
3888
|
+
initGlobalKeysWhenStart(microAppWindow, appName, url) {
|
|
3889
|
+
microAppWindow.hasOwnProperty = (key) => rawHasOwnProperty.call(microAppWindow, key) || rawHasOwnProperty.call(globalEnv.rawWindow, key);
|
|
3890
|
+
this.setHijackProperty(microAppWindow, appName);
|
|
3891
|
+
this.patchRequestApi(microAppWindow, appName, url);
|
|
3892
|
+
}
|
|
3749
3893
|
// set hijack Properties to microAppWindow
|
|
3750
|
-
|
|
3894
|
+
setHijackProperty(microAppWindow, appName) {
|
|
3751
3895
|
let modifiedEval, modifiedImage;
|
|
3752
3896
|
rawDefineProperties(microAppWindow, {
|
|
3753
|
-
document: {
|
|
3754
|
-
configurable: true,
|
|
3755
|
-
enumerable: true,
|
|
3756
|
-
get() {
|
|
3757
|
-
throttleDeferForSetAppName(appName);
|
|
3758
|
-
return globalEnv.rawDocument;
|
|
3759
|
-
},
|
|
3760
|
-
},
|
|
3761
3897
|
eval: {
|
|
3762
3898
|
configurable: true,
|
|
3763
3899
|
enumerable: false,
|
|
@@ -3783,7 +3919,7 @@ class SandBox {
|
|
|
3783
3919
|
});
|
|
3784
3920
|
}
|
|
3785
3921
|
// rewrite fetch, XMLHttpRequest, EventSource
|
|
3786
|
-
|
|
3922
|
+
patchRequestApi(microAppWindow, appName, url) {
|
|
3787
3923
|
let microFetch = createMicroFetch(url);
|
|
3788
3924
|
let microXMLHttpRequest = createMicroXMLHttpRequest(url);
|
|
3789
3925
|
let microEventSource = createMicroEventSource(appName, url);
|
|
@@ -3855,6 +3991,24 @@ class SandBox {
|
|
|
3855
3991
|
removeRouteInfoForKeepAliveApp() {
|
|
3856
3992
|
removeStateAndPathFromBrowser(this.proxyWindow.__MICRO_APP_NAME__);
|
|
3857
3993
|
}
|
|
3994
|
+
createProxyDocument(appName) {
|
|
3995
|
+
const createElement = function (tagName, options) {
|
|
3996
|
+
const element = globalEnv.rawCreateElement.call(globalEnv.rawDocument, tagName, options);
|
|
3997
|
+
element.__MICRO_APP_NAME__ = appName;
|
|
3998
|
+
return element;
|
|
3999
|
+
};
|
|
4000
|
+
const proxyDocument = new Proxy(globalEnv.rawDocument, {
|
|
4001
|
+
get(target, key) {
|
|
4002
|
+
throttleDeferForSetAppName(appName);
|
|
4003
|
+
throttleDeferForParentNode(proxyDocument);
|
|
4004
|
+
if (key === 'createElement')
|
|
4005
|
+
return createElement;
|
|
4006
|
+
const rawValue = Reflect.get(target, key);
|
|
4007
|
+
return isFunction(rawValue) ? bindFunctionToRawObject(target, rawValue, 'DOCUMENT') : rawValue;
|
|
4008
|
+
},
|
|
4009
|
+
});
|
|
4010
|
+
return proxyDocument;
|
|
4011
|
+
}
|
|
3858
4012
|
}
|
|
3859
4013
|
SandBox.activeCount = 0; // number of active sandbox
|
|
3860
4014
|
|
|
@@ -4563,7 +4717,7 @@ function defineElement(tagName) {
|
|
|
4563
4717
|
*/
|
|
4564
4718
|
updateSsrUrl(baseUrl) {
|
|
4565
4719
|
if (this.getDisposeResult('ssr')) {
|
|
4566
|
-
if (this.getDisposeResult('disable-memory-router')) {
|
|
4720
|
+
if (this.getDisposeResult('disable-memory-router') || this.getDisposeResult('disableSandbox')) {
|
|
4567
4721
|
const rawLocation = globalEnv.rawWindow.location;
|
|
4568
4722
|
this.ssrUrl = CompletionPath(rawLocation.pathname + rawLocation.search, baseUrl);
|
|
4569
4723
|
}
|