@micro-zoe/micro-app 1.0.0-alpha.0 → 1.0.0-alpha.3

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.esm.js CHANGED
@@ -1,4 +1,4 @@
1
- const version = '1.0.0-alpha.0';
1
+ const version = '1.0.0-alpha.3';
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;
@@ -56,6 +72,10 @@ function isShadowRoot(target) {
56
72
  function isURL(target) {
57
73
  return target instanceof URL;
58
74
  }
75
+ // is ProxyDocument
76
+ function isProxyDocument(target) {
77
+ return toString.call(target) === '[object ProxyDocument]';
78
+ }
59
79
  /**
60
80
  * format error log
61
81
  * @param msg message
@@ -107,7 +127,7 @@ const createURL = (function () {
107
127
  * @param url address
108
128
  */
109
129
  function addProtocol(url) {
110
- return url.startsWith('//') ? `${location.protocol}${url}` : url;
130
+ return url.startsWith('//') ? `${globalThis.location.protocol}${url}` : url;
111
131
  }
112
132
  /**
113
133
  * format URL address
@@ -199,24 +219,15 @@ function promiseStream(promiseList, successCb, errorCb, finallyCb) {
199
219
  promiseList.forEach((p, i) => {
200
220
  if (isPromise(p)) {
201
221
  p.then((res) => {
202
- successCb({
203
- data: res,
204
- index: i,
205
- });
222
+ successCb({ data: res, index: i });
206
223
  isFinished();
207
224
  }).catch((err) => {
208
- errorCb({
209
- error: err,
210
- index: i,
211
- });
225
+ errorCb({ error: err, index: i });
212
226
  isFinished();
213
227
  });
214
228
  }
215
229
  else {
216
- successCb({
217
- data: p,
218
- index: i,
219
- });
230
+ successCb({ data: p, index: i });
220
231
  isFinished();
221
232
  }
222
233
  });
@@ -279,6 +290,7 @@ function pureCreateElement(tagName, options) {
279
290
  const element = document.createElement(tagName, options);
280
291
  if (element.__MICRO_APP_NAME__)
281
292
  delete element.__MICRO_APP_NAME__;
293
+ element.__PURE_ELEMENT__ = true;
282
294
  return element;
283
295
  }
284
296
  /**
@@ -457,7 +469,15 @@ var keepAliveStates;
457
469
  keepAliveStates["KEEP_ALIVE_SHOW"] = "keep_alive_show";
458
470
  keepAliveStates["KEEP_ALIVE_HIDDEN"] = "keep_alive_hidden";
459
471
  })(keepAliveStates || (keepAliveStates = {}));
460
- const globalKeyToBeCached = 'window,self,globalThis,Array,Object,String,Boolean,Math,Number,Symbol,Date,Promise,Function,Proxy,WeakMap,WeakSet,Set,Map,Reflect,Element,Node,Document,RegExp,Error,TypeError,JSON,isNaN,parseFloat,parseInt,performance,console,decodeURI,encodeURI,decodeURIComponent,encodeURIComponent,navigator,undefined,location,history,EventSource,fetch,XMLHttpRequest';
472
+ /**
473
+ * global key must be static key, they can not rewrite
474
+ * e.g.
475
+ * window.Promise = newValue
476
+ * new Promise ==> still get old value, not newValue, because they are cached by top function
477
+ * NOTE:
478
+ * 1. Do not add fetch, XMLHttpRequest, EventSource
479
+ */
480
+ const globalKeyToBeCached = 'window,self,globalThis,Array,Object,String,Boolean,Math,Number,Symbol,Date,Function,Proxy,WeakMap,WeakSet,Set,Map,Reflect,Element,Node,Document,RegExp,Error,TypeError,JSON,isNaN,parseFloat,parseInt,performance,console,decodeURI,encodeURI,decodeURIComponent,encodeURIComponent,navigator,undefined,location,history';
461
481
 
462
482
  /**
463
483
  * fetch source of html, js, css
@@ -466,10 +486,18 @@ const globalKeyToBeCached = 'window,self,globalThis,Array,Object,String,Boolean,
466
486
  * @param config fetch options
467
487
  */
468
488
  function fetchSource(url, appName = null, options = {}) {
489
+ /**
490
+ * When child navigate to new async page, click event will scope dom to child and then fetch new source
491
+ * this may cause error when fetch rewrite by baseApp
492
+ * e.g.
493
+ * baseApp: <script crossorigin src="https://sgm-static.jd.com/sgm-2.8.0.js" name="SGMH5" sid="6f88a6e4ba4b4ae5acef2ec22c075085" appKey="jdb-adminb2b-pc"></script>
494
+ */
495
+ removeDomScope();
469
496
  if (isFunction(microApp.fetch)) {
470
497
  return microApp.fetch(url, options, appName);
471
498
  }
472
- return fetch(url, options).then((res) => {
499
+ // Don’t use globalEnv.rawWindow.fetch, will cause sgm-2.8.0.js throw error in nest app
500
+ return window.fetch(url, options).then((res) => {
473
501
  return res.text();
474
502
  });
475
503
  }
@@ -552,7 +580,7 @@ class CSSParser {
552
580
  return true;
553
581
  }
554
582
  formatSelector(skip) {
555
- const m = this.commonMatch(/^([^{]+)/, skip);
583
+ const m = this.commonMatch(/^[^{]+/, skip);
556
584
  if (!m)
557
585
  return false;
558
586
  return m[0].replace(/(^|,[\n\s]*)([^,]+)/g, (_, separator, selector) => {
@@ -632,7 +660,7 @@ class CSSParser {
632
660
  keyframesRule() {
633
661
  if (!this.commonMatch(/^@([-\w]+)?keyframes\s*/))
634
662
  return false;
635
- if (!this.commonMatch(/^([-\w]+)\s*/))
663
+ if (!this.commonMatch(/^[^{]+/))
636
664
  return parseError('@keyframes missing name', this.linkPath);
637
665
  this.matchComments();
638
666
  if (!this.matchOpenBrace())
@@ -784,7 +812,7 @@ class CSSParser {
784
812
  }
785
813
  // splice string
786
814
  recordResult(strFragment) {
787
- // Firefox is slow when string contain special characters, see https://github.com/micro-zoe/micro-app/issues/256
815
+ // Firefox performance degradation when string contain special characters, see https://github.com/micro-zoe/micro-app/issues/256
788
816
  if (isFireFox()) {
789
817
  this.result += encodeURIComponent(strFragment);
790
818
  }
@@ -1015,6 +1043,85 @@ function formatDynamicLink(url, info, app, originLink, replaceStyle) {
1015
1043
  });
1016
1044
  }
1017
1045
 
1046
+ class Adapter {
1047
+ constructor() {
1048
+ // keys that can only assigned to rawWindow
1049
+ this.escapeSetterKeyList = [
1050
+ 'location',
1051
+ ];
1052
+ // keys that can escape to rawWindow
1053
+ this.staticEscapeProperties = [
1054
+ 'System',
1055
+ '__cjsWrapper',
1056
+ ];
1057
+ // keys that scoped in child app
1058
+ this.staticScopeProperties = [
1059
+ 'webpackJsonp',
1060
+ 'webpackHotUpdate',
1061
+ 'Vue',
1062
+ ];
1063
+ this.injectReactHRMProperty();
1064
+ }
1065
+ // TODO: __DEV__ process.env.NODE_ENV !== 'production'
1066
+ // adapter for react
1067
+ injectReactHRMProperty() {
1068
+ if (process.env.NODE_ENV !== 'production') {
1069
+ // react child in non-react env
1070
+ this.staticEscapeProperties.push('__REACT_ERROR_OVERLAY_GLOBAL_HOOK__');
1071
+ // in react parent
1072
+ if (globalEnv.rawWindow.__REACT_ERROR_OVERLAY_GLOBAL_HOOK__) {
1073
+ this.staticScopeProperties = this.staticScopeProperties.concat([
1074
+ '__REACT_ERROR_OVERLAY_GLOBAL_HOOK__',
1075
+ '__reactRefreshInjected',
1076
+ ]);
1077
+ }
1078
+ }
1079
+ }
1080
+ }
1081
+ // Fix conflict of babel-polyfill@6.x
1082
+ function fixBabelPolyfill6() {
1083
+ if (globalEnv.rawWindow._babelPolyfill)
1084
+ globalEnv.rawWindow._babelPolyfill = false;
1085
+ }
1086
+ /**
1087
+ * Fix error of hot reload when parent&child created by create-react-app in development environment
1088
+ * Issue: https://github.com/micro-zoe/micro-app/issues/382
1089
+ */
1090
+ function fixReactHMRConflict(app) {
1091
+ var _a;
1092
+ if (process.env.NODE_ENV !== 'production') {
1093
+ const rawReactErrorHook = globalEnv.rawWindow.__REACT_ERROR_OVERLAY_GLOBAL_HOOK__;
1094
+ const childReactErrorHook = (_a = app.sandBox) === null || _a === void 0 ? void 0 : _a.proxyWindow.__REACT_ERROR_OVERLAY_GLOBAL_HOOK__;
1095
+ if (rawReactErrorHook && childReactErrorHook) {
1096
+ globalEnv.rawWindow.__REACT_ERROR_OVERLAY_GLOBAL_HOOK__ = childReactErrorHook;
1097
+ defer(() => {
1098
+ globalEnv.rawWindow.__REACT_ERROR_OVERLAY_GLOBAL_HOOK__ = rawReactErrorHook;
1099
+ });
1100
+ }
1101
+ }
1102
+ }
1103
+ /**
1104
+ * reDefine parentNode of html
1105
+ * Scenes:
1106
+ * 1. element-ui popover.js
1107
+ * if (html.parentNode === document) ...
1108
+ */
1109
+ function throttleDeferForParentNode(proxyDocument) {
1110
+ const html = globalEnv.rawDocument.firstElementChild;
1111
+ if (html && html.parentNode !== proxyDocument) {
1112
+ setRootParentNode(html, proxyDocument);
1113
+ defer(() => {
1114
+ setRootParentNode(html, globalEnv.rawDocument);
1115
+ });
1116
+ }
1117
+ }
1118
+ function setRootParentNode(root, value) {
1119
+ Object.defineProperty(root, 'parentNode', {
1120
+ value,
1121
+ configurable: true,
1122
+ });
1123
+ }
1124
+
1018
1125
  // Record element and map element
1019
1126
  const dynamicElementInMicroAppMap = new WeakMap();
1020
1127
  /**
@@ -1108,6 +1215,12 @@ function invokePrototypeMethod(app, rawMethod, parent, targetChild, passiveChild
1108
1215
  }
1109
1216
  return targetChild;
1110
1217
  }
1218
+ // TODO: __DEV__
1219
+ if (process.env.NODE_ENV !== 'production' &&
1220
+ targetChild instanceof HTMLIFrameElement &&
1221
+ rawMethod === globalEnv.rawAppendChild) {
1222
+ fixReactHMRConflict(app);
1223
+ }
1111
1224
  return invokeRawMethod(rawMethod, hijackElement, targetChild, passiveChild);
1112
1225
  }
1113
1226
  return invokeRawMethod(rawMethod, parent, targetChild, passiveChild);
@@ -1145,20 +1258,35 @@ function getMappingNode(node) {
1145
1258
  * @param rawMethod method
1146
1259
  */
1147
1260
  function commonElementHandler(parent, newChild, passiveChild, rawMethod) {
1148
- if (newChild === null || newChild === void 0 ? void 0 : newChild.__MICRO_APP_NAME__) {
1261
+ const currentAppName = getCurrentAppName();
1262
+ if (newChild instanceof Node &&
1263
+ (newChild.__MICRO_APP_NAME__ ||
1264
+ (currentAppName && !newChild.__PURE_ELEMENT__))) {
1265
+ newChild.__MICRO_APP_NAME__ = newChild.__MICRO_APP_NAME__ || currentAppName;
1149
1266
  const app = appInstanceMap.get(newChild.__MICRO_APP_NAME__);
1150
1267
  if (app === null || app === void 0 ? void 0 : app.container) {
1268
+ if (newChild instanceof Element) {
1269
+ if (/^(img|script)$/i.test(newChild.tagName)) {
1270
+ if (newChild.hasAttribute('src')) {
1271
+ globalEnv.rawSetAttribute.call(newChild, 'src', CompletionPath(newChild.getAttribute('src'), app.url));
1272
+ }
1273
+ if (newChild.hasAttribute('srcset')) {
1274
+ globalEnv.rawSetAttribute.call(newChild, 'srcset', CompletionPath(newChild.getAttribute('srcset'), app.url));
1275
+ }
1276
+ }
1277
+ else if (/^link$/i.test(newChild.tagName) && newChild.hasAttribute('href')) {
1278
+ globalEnv.rawSetAttribute.call(newChild, 'href', CompletionPath(newChild.getAttribute('href'), app.url));
1279
+ }
1280
+ }
1151
1281
  return invokePrototypeMethod(app, rawMethod, parent, handleNewNode(parent, newChild, app), passiveChild && getMappingNode(passiveChild));
1152
1282
  }
1153
1283
  else if (rawMethod === globalEnv.rawAppend || rawMethod === globalEnv.rawPrepend) {
1154
1284
  return rawMethod.call(parent, newChild);
1155
1285
  }
1156
- return rawMethod.call(parent, newChild, passiveChild);
1157
1286
  }
1158
1287
  else if (rawMethod === globalEnv.rawAppend || rawMethod === globalEnv.rawPrepend) {
1159
- const appName = getCurrentAppName();
1160
- if (!(newChild instanceof Node) && appName) {
1161
- const app = appInstanceMap.get(appName);
1288
+ if (!(newChild instanceof Node) && currentAppName) {
1289
+ const app = appInstanceMap.get(currentAppName);
1162
1290
  if (app === null || app === void 0 ? void 0 : app.container) {
1163
1291
  if (parent === document.head) {
1164
1292
  return rawMethod.call(app.container.querySelector('micro-app-head'), newChild);
@@ -1204,12 +1332,18 @@ function patchElementPrototypeMethods() {
1204
1332
  };
1205
1333
  // prototype methods of delete element👇
1206
1334
  Element.prototype.removeChild = function removeChild(oldChild) {
1335
+ var _a;
1207
1336
  if (oldChild === null || oldChild === void 0 ? void 0 : oldChild.__MICRO_APP_NAME__) {
1208
1337
  const app = appInstanceMap.get(oldChild.__MICRO_APP_NAME__);
1209
1338
  if (app === null || app === void 0 ? void 0 : app.container) {
1210
1339
  return invokePrototypeMethod(app, globalEnv.rawRemoveChild, this, getMappingNode(oldChild));
1211
1340
  }
1212
- return globalEnv.rawRemoveChild.call(this, oldChild);
1341
+ try {
1342
+ return globalEnv.rawRemoveChild.call(this, oldChild);
1343
+ }
1344
+ catch (_b) {
1345
+ return (_a = oldChild === null || oldChild === void 0 ? void 0 : oldChild.parentNode) === null || _a === void 0 ? void 0 : _a.removeChild(oldChild);
1346
+ }
1213
1347
  }
1214
1348
  return globalEnv.rawRemoveChild.call(this, oldChild);
1215
1349
  };
@@ -1225,109 +1359,120 @@ function patchElementPrototypeMethods() {
1225
1359
  * @param element new element
1226
1360
  */
1227
1361
  function markElement(element) {
1228
- const appName = getCurrentAppName();
1229
- if (appName)
1230
- element.__MICRO_APP_NAME__ = appName;
1362
+ const currentAppName = getCurrentAppName();
1363
+ if (currentAppName)
1364
+ element.__MICRO_APP_NAME__ = currentAppName;
1231
1365
  return element;
1232
1366
  }
1233
1367
  // methods of document
1234
1368
  function patchDocument() {
1235
1369
  const rawDocument = globalEnv.rawDocument;
1370
+ const rawRootDocument = globalEnv.rawRootDocument;
1371
+ function getBindTarget(target) {
1372
+ return isProxyDocument(target) ? rawDocument : target;
1373
+ }
1236
1374
  // create element 👇
1237
- Document.prototype.createElement = function createElement(tagName, options) {
1238
- const element = globalEnv.rawCreateElement.call(this, tagName, options);
1375
+ rawRootDocument.prototype.createElement = function createElement(tagName, options) {
1376
+ const element = globalEnv.rawCreateElement.call(getBindTarget(this), tagName, options);
1239
1377
  return markElement(element);
1240
1378
  };
1241
- Document.prototype.createElementNS = function createElementNS(namespaceURI, name, options) {
1242
- const element = globalEnv.rawCreateElementNS.call(this, namespaceURI, name, options);
1379
+ rawRootDocument.prototype.createElementNS = function createElementNS(namespaceURI, name, options) {
1380
+ const element = globalEnv.rawCreateElementNS.call(getBindTarget(this), namespaceURI, name, options);
1243
1381
  return markElement(element);
1244
1382
  };
1245
- Document.prototype.createDocumentFragment = function createDocumentFragment() {
1246
- const element = globalEnv.rawCreateDocumentFragment.call(this);
1383
+ rawRootDocument.prototype.createDocumentFragment = function createDocumentFragment() {
1384
+ const element = globalEnv.rawCreateDocumentFragment.call(getBindTarget(this));
1247
1385
  return markElement(element);
1248
1386
  };
1249
1387
  // query element👇
1250
1388
  function querySelector(selectors) {
1251
1389
  var _a, _b, _c, _d;
1252
- const appName = getCurrentAppName();
1253
- if (!appName ||
1254
- !((_a = appInstanceMap.get(appName)) === null || _a === void 0 ? void 0 : _a.container) ||
1390
+ const _this = getBindTarget(this);
1391
+ const currentAppName = getCurrentAppName();
1392
+ if (!currentAppName ||
1393
+ !((_a = appInstanceMap.get(currentAppName)) === null || _a === void 0 ? void 0 : _a.container) ||
1255
1394
  !selectors ||
1256
1395
  isUniqueElement(selectors) ||
1257
1396
  // see https://github.com/micro-zoe/micro-app/issues/56
1258
- rawDocument !== this) {
1259
- return globalEnv.rawQuerySelector.call(this, selectors);
1397
+ rawDocument !== _this) {
1398
+ return globalEnv.rawQuerySelector.call(_this, selectors);
1260
1399
  }
1261
- return (_d = (_c = (_b = appInstanceMap.get(appName)) === null || _b === void 0 ? void 0 : _b.container) === null || _c === void 0 ? void 0 : _c.querySelector(selectors)) !== null && _d !== void 0 ? _d : null;
1400
+ 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;
1262
1401
  }
1263
1402
  function querySelectorAll(selectors) {
1264
1403
  var _a, _b, _c, _d;
1265
- const appName = getCurrentAppName();
1266
- if (!appName ||
1267
- !((_a = appInstanceMap.get(appName)) === null || _a === void 0 ? void 0 : _a.container) ||
1404
+ const _this = getBindTarget(this);
1405
+ const currentAppName = getCurrentAppName();
1406
+ if (!currentAppName ||
1407
+ !((_a = appInstanceMap.get(currentAppName)) === null || _a === void 0 ? void 0 : _a.container) ||
1268
1408
  !selectors ||
1269
1409
  isUniqueElement(selectors) ||
1270
- rawDocument !== this) {
1271
- return globalEnv.rawQuerySelectorAll.call(this, selectors);
1410
+ rawDocument !== _this) {
1411
+ return globalEnv.rawQuerySelectorAll.call(_this, selectors);
1272
1412
  }
1273
- return (_d = (_c = (_b = appInstanceMap.get(appName)) === null || _b === void 0 ? void 0 : _b.container) === null || _c === void 0 ? void 0 : _c.querySelectorAll(selectors)) !== null && _d !== void 0 ? _d : [];
1413
+ 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 : [];
1274
1414
  }
1275
- Document.prototype.querySelector = querySelector;
1276
- Document.prototype.querySelectorAll = querySelectorAll;
1277
- Document.prototype.getElementById = function getElementById(key) {
1415
+ rawRootDocument.prototype.querySelector = querySelector;
1416
+ rawRootDocument.prototype.querySelectorAll = querySelectorAll;
1417
+ rawRootDocument.prototype.getElementById = function getElementById(key) {
1418
+ const _this = getBindTarget(this);
1278
1419
  if (!getCurrentAppName() || isInvalidQuerySelectorKey(key)) {
1279
- return globalEnv.rawGetElementById.call(this, key);
1420
+ return globalEnv.rawGetElementById.call(_this, key);
1280
1421
  }
1281
1422
  try {
1282
- return querySelector.call(this, `#${key}`);
1423
+ return querySelector.call(_this, `#${key}`);
1283
1424
  }
1284
1425
  catch (_a) {
1285
- return globalEnv.rawGetElementById.call(this, key);
1426
+ return globalEnv.rawGetElementById.call(_this, key);
1286
1427
  }
1287
1428
  };
1288
- Document.prototype.getElementsByClassName = function getElementsByClassName(key) {
1429
+ rawRootDocument.prototype.getElementsByClassName = function getElementsByClassName(key) {
1430
+ const _this = getBindTarget(this);
1289
1431
  if (!getCurrentAppName() || isInvalidQuerySelectorKey(key)) {
1290
- return globalEnv.rawGetElementsByClassName.call(this, key);
1432
+ return globalEnv.rawGetElementsByClassName.call(_this, key);
1291
1433
  }
1292
1434
  try {
1293
- return querySelectorAll.call(this, `.${key}`);
1435
+ return querySelectorAll.call(_this, `.${key}`);
1294
1436
  }
1295
1437
  catch (_a) {
1296
- return globalEnv.rawGetElementsByClassName.call(this, key);
1438
+ return globalEnv.rawGetElementsByClassName.call(_this, key);
1297
1439
  }
1298
1440
  };
1299
- Document.prototype.getElementsByTagName = function getElementsByTagName(key) {
1441
+ rawRootDocument.prototype.getElementsByTagName = function getElementsByTagName(key) {
1300
1442
  var _a;
1301
- const appName = getCurrentAppName();
1302
- if (!appName ||
1443
+ const _this = getBindTarget(this);
1444
+ const currentAppName = getCurrentAppName();
1445
+ if (!currentAppName ||
1303
1446
  isUniqueElement(key) ||
1304
1447
  isInvalidQuerySelectorKey(key) ||
1305
- (!((_a = appInstanceMap.get(appName)) === null || _a === void 0 ? void 0 : _a.inline) && /^script$/i.test(key))) {
1306
- return globalEnv.rawGetElementsByTagName.call(this, key);
1448
+ (!((_a = appInstanceMap.get(currentAppName)) === null || _a === void 0 ? void 0 : _a.inline) && /^script$/i.test(key))) {
1449
+ return globalEnv.rawGetElementsByTagName.call(_this, key);
1307
1450
  }
1308
1451
  try {
1309
- return querySelectorAll.call(this, key);
1452
+ return querySelectorAll.call(_this, key);
1310
1453
  }
1311
1454
  catch (_b) {
1312
- return globalEnv.rawGetElementsByTagName.call(this, key);
1455
+ return globalEnv.rawGetElementsByTagName.call(_this, key);
1313
1456
  }
1314
1457
  };
1315
- Document.prototype.getElementsByName = function getElementsByName(key) {
1458
+ rawRootDocument.prototype.getElementsByName = function getElementsByName(key) {
1459
+ const _this = getBindTarget(this);
1316
1460
  if (!getCurrentAppName() || isInvalidQuerySelectorKey(key)) {
1317
- return globalEnv.rawGetElementsByName.call(this, key);
1461
+ return globalEnv.rawGetElementsByName.call(_this, key);
1318
1462
  }
1319
1463
  try {
1320
- return querySelectorAll.call(this, `[name=${key}]`);
1464
+ return querySelectorAll.call(_this, `[name=${key}]`);
1321
1465
  }
1322
1466
  catch (_a) {
1323
- return globalEnv.rawGetElementsByName.call(this, key);
1467
+ return globalEnv.rawGetElementsByName.call(_this, key);
1324
1468
  }
1325
1469
  };
1326
1470
  }
1327
1471
  /**
1328
1472
  * patchSetAttribute is different from other patch
1329
- * it not dependent on sandbox
1330
- * it should exec when micro-app first created & release when all app unmounted
1473
+ * NOTE:
1474
+ * 1. it not dependent on sandbox
1475
+ * 2. it should exec when first micro-app-element created & release when all app unmounted
1331
1476
  */
1332
1477
  let hasRewriteSetAttribute = false;
1333
1478
  function patchSetAttribute() {
@@ -1338,9 +1483,9 @@ function patchSetAttribute() {
1338
1483
  if (/^micro-app(-\S+)?/i.test(this.tagName) && key === 'data') {
1339
1484
  if (isPlainObject(value)) {
1340
1485
  const cloneValue = {};
1341
- Object.getOwnPropertyNames(value).forEach((key) => {
1342
- if (!(isString(key) && key.indexOf('__') === 0)) {
1343
- cloneValue[key] = value[key];
1486
+ Object.getOwnPropertyNames(value).forEach((ownKey) => {
1487
+ if (!(isString(ownKey) && ownKey.indexOf('__') === 0)) {
1488
+ cloneValue[ownKey] = value[ownKey];
1344
1489
  }
1345
1490
  });
1346
1491
  this.data = cloneValue;
@@ -1349,36 +1494,34 @@ function patchSetAttribute() {
1349
1494
  logWarn('property data must be an object', this.getAttribute('name'));
1350
1495
  }
1351
1496
  }
1352
- else if ((((key === 'src' || key === 'srcset') && /^(img|script)$/i.test(this.tagName)) ||
1353
- (key === 'href' && /^link$/i.test(this.tagName))) &&
1354
- this.__MICRO_APP_NAME__ &&
1355
- appInstanceMap.has(this.__MICRO_APP_NAME__)) {
1356
- const app = appInstanceMap.get(this.__MICRO_APP_NAME__);
1357
- globalEnv.rawSetAttribute.call(this, key, CompletionPath(value, app.url));
1358
- }
1359
1497
  else {
1498
+ const appName = this.__MICRO_APP_NAME__ || getCurrentAppName();
1499
+ if (appName &&
1500
+ appInstanceMap.has(appName) &&
1501
+ (((key === 'src' || key === 'srcset') && /^(img|script)$/i.test(this.tagName)) ||
1502
+ (key === 'href' && /^link$/i.test(this.tagName)))) {
1503
+ const app = appInstanceMap.get(appName);
1504
+ value = CompletionPath(value, app.url);
1505
+ }
1360
1506
  globalEnv.rawSetAttribute.call(this, key, value);
1361
1507
  }
1362
1508
  };
1363
1509
  }
1364
- function releasePatchSetAttribute() {
1365
- hasRewriteSetAttribute = false;
1366
- Element.prototype.setAttribute = globalEnv.rawSetAttribute;
1367
- }
1368
1510
  function releasePatchDocument() {
1369
- Document.prototype.createElement = globalEnv.rawCreateElement;
1370
- Document.prototype.createElementNS = globalEnv.rawCreateElementNS;
1371
- Document.prototype.createDocumentFragment = globalEnv.rawCreateDocumentFragment;
1372
- Document.prototype.querySelector = globalEnv.rawQuerySelector;
1373
- Document.prototype.querySelectorAll = globalEnv.rawQuerySelectorAll;
1374
- Document.prototype.getElementById = globalEnv.rawGetElementById;
1375
- Document.prototype.getElementsByClassName = globalEnv.rawGetElementsByClassName;
1376
- Document.prototype.getElementsByTagName = globalEnv.rawGetElementsByTagName;
1377
- Document.prototype.getElementsByName = globalEnv.rawGetElementsByName;
1511
+ const rawRootDocument = globalEnv.rawRootDocument;
1512
+ rawRootDocument.prototype.createElement = globalEnv.rawCreateElement;
1513
+ rawRootDocument.prototype.createElementNS = globalEnv.rawCreateElementNS;
1514
+ rawRootDocument.prototype.createDocumentFragment = globalEnv.rawCreateDocumentFragment;
1515
+ rawRootDocument.prototype.querySelector = globalEnv.rawQuerySelector;
1516
+ rawRootDocument.prototype.querySelectorAll = globalEnv.rawQuerySelectorAll;
1517
+ rawRootDocument.prototype.getElementById = globalEnv.rawGetElementById;
1518
+ rawRootDocument.prototype.getElementsByClassName = globalEnv.rawGetElementsByClassName;
1519
+ rawRootDocument.prototype.getElementsByTagName = globalEnv.rawGetElementsByTagName;
1520
+ rawRootDocument.prototype.getElementsByName = globalEnv.rawGetElementsByName;
1378
1521
  }
1379
1522
  // release patch
1380
1523
  function releasePatches() {
1381
- setCurrentAppName(null);
1524
+ removeDomScope();
1382
1525
  releasePatchDocument();
1383
1526
  Element.prototype.appendChild = globalEnv.rawAppendChild;
1384
1527
  Element.prototype.insertBefore = globalEnv.rawInsertBefore;
@@ -1388,6 +1531,11 @@ function releasePatches() {
1388
1531
  Element.prototype.prepend = globalEnv.rawPrepend;
1389
1532
  Element.prototype.cloneNode = globalEnv.rawCloneNode;
1390
1533
  }
1534
+ // exec when last child unmount
1535
+ function releasePatchSetAttribute() {
1536
+ hasRewriteSetAttribute = false;
1537
+ Element.prototype.setAttribute = globalEnv.rawSetAttribute;
1538
+ }
1391
1539
  // Set the style of micro-app-head and micro-app-body
1392
1540
  let hasRejectMicroAppStyle = false;
1393
1541
  function rejectMicroAppStyle() {
@@ -1407,6 +1555,10 @@ const globalEnv = {};
1407
1555
  */
1408
1556
  function initGlobalEnv() {
1409
1557
  if (isBrowser) {
1558
+ const rawWindow = Function('return window')();
1559
+ const rawDocument = Function('return document')();
1560
+ const rawRootDocument = Function('return Document')();
1561
+ const supportModuleScript = isSupportModuleScript();
1410
1562
  /**
1411
1563
  * save patch raw methods
1412
1564
  * pay attention to this binding
@@ -1419,15 +1571,15 @@ function initGlobalEnv() {
1419
1571
  const rawAppend = Element.prototype.append;
1420
1572
  const rawPrepend = Element.prototype.prepend;
1421
1573
  const rawCloneNode = Element.prototype.cloneNode;
1422
- const rawCreateElement = Document.prototype.createElement;
1423
- const rawCreateElementNS = Document.prototype.createElementNS;
1424
- const rawCreateDocumentFragment = Document.prototype.createDocumentFragment;
1425
- const rawQuerySelector = Document.prototype.querySelector;
1426
- const rawQuerySelectorAll = Document.prototype.querySelectorAll;
1427
- const rawGetElementById = Document.prototype.getElementById;
1428
- const rawGetElementsByClassName = Document.prototype.getElementsByClassName;
1429
- const rawGetElementsByTagName = Document.prototype.getElementsByTagName;
1430
- const rawGetElementsByName = Document.prototype.getElementsByName;
1574
+ const rawCreateElement = rawRootDocument.prototype.createElement;
1575
+ const rawCreateElementNS = rawRootDocument.prototype.createElementNS;
1576
+ const rawCreateDocumentFragment = rawRootDocument.prototype.createDocumentFragment;
1577
+ const rawQuerySelector = rawRootDocument.prototype.querySelector;
1578
+ const rawQuerySelectorAll = rawRootDocument.prototype.querySelectorAll;
1579
+ const rawGetElementById = rawRootDocument.prototype.getElementById;
1580
+ const rawGetElementsByClassName = rawRootDocument.prototype.getElementsByClassName;
1581
+ const rawGetElementsByTagName = rawRootDocument.prototype.getElementsByTagName;
1582
+ const rawGetElementsByName = rawRootDocument.prototype.getElementsByName;
1431
1583
  const ImageProxy = new Proxy(Image, {
1432
1584
  construct(Target, args) {
1433
1585
  const elementImage = new Target(...args);
@@ -1435,9 +1587,6 @@ function initGlobalEnv() {
1435
1587
  return elementImage;
1436
1588
  },
1437
1589
  });
1438
- const rawWindow = Function('return window')();
1439
- const rawDocument = Function('return document')();
1440
- const supportModuleScript = isSupportModuleScript();
1441
1590
  /**
1442
1591
  * save effect raw methods
1443
1592
  * pay attention to this binding, especially setInterval, setTimeout, clearInterval, clearTimeout
@@ -1448,11 +1597,18 @@ function initGlobalEnv() {
1448
1597
  const rawSetTimeout = rawWindow.setTimeout;
1449
1598
  const rawClearInterval = rawWindow.clearInterval;
1450
1599
  const rawClearTimeout = rawWindow.clearTimeout;
1600
+ const rawPushState = rawWindow.history.pushState;
1601
+ const rawReplaceState = rawWindow.history.replaceState;
1451
1602
  const rawDocumentAddEventListener = rawDocument.addEventListener;
1452
1603
  const rawDocumentRemoveEventListener = rawDocument.removeEventListener;
1453
1604
  // mark current application as base application
1454
1605
  window.__MICRO_APP_BASE_APPLICATION__ = true;
1455
1606
  assign(globalEnv, {
1607
+ // common global vars
1608
+ rawWindow,
1609
+ rawDocument,
1610
+ rawRootDocument,
1611
+ supportModuleScript,
1456
1612
  // source/patch
1457
1613
  rawSetAttribute,
1458
1614
  rawAppendChild,
@@ -1472,10 +1628,6 @@ function initGlobalEnv() {
1472
1628
  rawGetElementsByTagName,
1473
1629
  rawGetElementsByName,
1474
1630
  ImageProxy,
1475
- // common global vars
1476
- rawWindow,
1477
- rawDocument,
1478
- supportModuleScript,
1479
1631
  // sandbox/effect
1480
1632
  rawWindowAddEventListener,
1481
1633
  rawWindowRemoveEventListener,
@@ -1485,6 +1637,8 @@ function initGlobalEnv() {
1485
1637
  rawClearTimeout,
1486
1638
  rawDocumentAddEventListener,
1487
1639
  rawDocumentRemoveEventListener,
1640
+ rawPushState,
1641
+ rawReplaceState,
1488
1642
  });
1489
1643
  // global effect
1490
1644
  rejectMicroAppStyle();
@@ -1705,6 +1859,13 @@ function runDynamicRemoteScript(url, info, app, originScript) {
1705
1859
  if (app.source.scripts.has(url)) {
1706
1860
  const existInfo = app.source.scripts.get(url);
1707
1861
  !existInfo.module && defer(dispatchScriptOnLoadEvent);
1862
+ /**
1863
+ * TODO: 这里要改,当script初始化时动态创建远程script时,初次渲染和二次渲染的顺序不一致,会导致错误
1864
+ * 1、url不存在缓存,初始化的时候肯定是要异步请求,那么执行顺序就会靠后,至少落后于html自带的script
1865
+ * 2、url存在缓存,那么二次渲染的时候这里会同步执行,就会先于html自带的script执行
1866
+ * 3、测试一下,初次渲染和二次渲染时,onload的执行时机,是在js执行完成,还是执行之前
1867
+ * 4、将上述问题做成注释,方便后续阅读和理解
1868
+ */
1708
1869
  return runScript(url, app, existInfo, true, dispatchScriptOnLoadEvent);
1709
1870
  }
1710
1871
  if (globalScripts.has(url)) {
@@ -2223,7 +2384,7 @@ function releaseUnmountOfNestedApp() {
2223
2384
  }
2224
2385
  // if micro-app run in micro application, delete all next generation application when unmount event received
2225
2386
  // unmount event will auto release by sandbox
2226
- function listenUmountOfNestedApp() {
2387
+ function initEnvOfNestedApp() {
2227
2388
  if (window.__MICRO_APP_ENVIRONMENT__) {
2228
2389
  releaseUnmountOfNestedApp();
2229
2390
  window.addEventListener('unmount', unmountNestedApp, false);
@@ -2236,35 +2397,30 @@ function isBoundedFunction(value) {
2236
2397
  return value.__MICRO_APP_IS_BOUND_FUNCTION__;
2237
2398
  return value.__MICRO_APP_IS_BOUND_FUNCTION__ = isBoundFunction(value);
2238
2399
  }
2239
- function isConstructor(value) {
2240
- var _a;
2400
+ function isConstructorFunction(value) {
2241
2401
  if (isBoolean(value.__MICRO_APP_IS_CONSTRUCTOR__))
2242
2402
  return value.__MICRO_APP_IS_CONSTRUCTOR__;
2243
- const valueStr = value.toString();
2244
- const result = (((_a = value.prototype) === null || _a === void 0 ? void 0 : _a.constructor) === value &&
2245
- Object.getOwnPropertyNames(value.prototype).length > 1) ||
2246
- /^function\s+[A-Z]/.test(valueStr) ||
2247
- /^class\s+/.test(valueStr);
2248
- return value.__MICRO_APP_IS_CONSTRUCTOR__ = result;
2403
+ return value.__MICRO_APP_IS_CONSTRUCTOR__ = isConstructor(value);
2249
2404
  }
2250
2405
  // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
2251
- function bindFunctionToRawWindow(rawWindow, value) {
2252
- if (value.__MICRO_APP_BOUND_WINDOW_FUNCTION__)
2253
- return value.__MICRO_APP_BOUND_WINDOW_FUNCTION__;
2254
- if (!isConstructor(value) && !isBoundedFunction(value)) {
2255
- const bindRawWindowValue = value.bind(rawWindow);
2406
+ function bindFunctionToRawObject(rawObject, value, key = 'WINDOW') {
2407
+ const cacheKey = `__MICRO_APP_BOUND_${key}_FUNCTION__`;
2408
+ if (value[cacheKey])
2409
+ return value[cacheKey];
2410
+ if (!isConstructorFunction(value) && !isBoundedFunction(value)) {
2411
+ const bindRawObjectValue = value.bind(rawObject);
2256
2412
  for (const key in value) {
2257
- bindRawWindowValue[key] = value[key];
2413
+ bindRawObjectValue[key] = value[key];
2258
2414
  }
2259
2415
  if (value.hasOwnProperty('prototype')) {
2260
- rawDefineProperty(bindRawWindowValue, 'prototype', {
2416
+ rawDefineProperty(bindRawObjectValue, 'prototype', {
2261
2417
  value: value.prototype,
2262
2418
  configurable: true,
2263
2419
  enumerable: false,
2264
2420
  writable: true,
2265
2421
  });
2266
2422
  }
2267
- return value.__MICRO_APP_BOUND_WINDOW_FUNCTION__ = bindRawWindowValue;
2423
+ return value[cacheKey] = bindRawObjectValue;
2268
2424
  }
2269
2425
  return value;
2270
2426
  }
@@ -2381,8 +2537,7 @@ function releaseEffectDocumentEvent() {
2381
2537
  * Rewrite side-effect events
2382
2538
  * @param microAppWindow micro window
2383
2539
  */
2384
- function effect(microAppWindow) {
2385
- const appName = microAppWindow.__MICRO_APP_NAME__;
2540
+ function effect(appName, microAppWindow) {
2386
2541
  const eventListenerMap = new Map();
2387
2542
  const intervalIdMap = new Map();
2388
2543
  const timeoutIdMap = new Map();
@@ -2529,7 +2684,8 @@ function effect(microAppWindow) {
2529
2684
  }
2530
2685
 
2531
2686
  // set micro app state to origin state
2532
- function setMicroState(appName, rawState, microState) {
2687
+ function setMicroState(appName, microState) {
2688
+ const rawState = globalEnv.rawWindow.history.state;
2533
2689
  const additionalState = {
2534
2690
  microAppState: assign({}, rawState === null || rawState === void 0 ? void 0 : rawState.microAppState, {
2535
2691
  [appName]: microState
@@ -2552,9 +2708,9 @@ function removeMicroState(appName, rawState) {
2552
2708
  return assign({}, rawState);
2553
2709
  }
2554
2710
  // get micro app state form origin state
2555
- function getMicroState(appName, state) {
2556
- var _a;
2557
- return ((_a = state === null || state === void 0 ? void 0 : state.microAppState) === null || _a === void 0 ? void 0 : _a[appName]) || null;
2711
+ function getMicroState(appName) {
2712
+ var _a, _b;
2713
+ return ((_b = (_a = globalEnv.rawWindow.history.state) === null || _a === void 0 ? void 0 : _a.microAppState) === null || _b === void 0 ? void 0 : _b[appName]) || null;
2558
2714
  }
2559
2715
  const ENC_AD_RE = /&/g; // %M1
2560
2716
  const ENC_EQ_RE = /=/g; // %M2
@@ -2579,7 +2735,8 @@ function commonDecode(path) {
2579
2735
  }
2580
2736
  // 格式化query参数key,防止与原有参数的冲突
2581
2737
  function formatQueryAppName(appName) {
2582
- return `app-${appName}`;
2738
+ // return `app-${appName}`
2739
+ return appName;
2583
2740
  }
2584
2741
  // 根据浏览器url参数,获取当前子应用的path
2585
2742
  function getMicroPathFromURL(appName) {
@@ -2684,7 +2841,10 @@ function addHistoryListener(appName) {
2684
2841
  const rawWindow = globalEnv.rawWindow;
2685
2842
  // handle popstate event and distribute to child app
2686
2843
  const popStateHandler = (e) => {
2687
- // exclude hidden keep-alive app
2844
+ /**
2845
+ * 1. unmount app & hidden keep-alive app will not receive popstate event
2846
+ * 2. filter out onlyForBrowser
2847
+ */
2688
2848
  if (getActiveApps(true).includes(appName) && !e.onlyForBrowser) {
2689
2849
  const microPath = getMicroPathFromURL(appName);
2690
2850
  const app = appInstanceMap.get(appName);
@@ -2699,7 +2859,7 @@ function addHistoryListener(appName) {
2699
2859
  isHashChange = proxyWindow.location.hash !== oldHash;
2700
2860
  }
2701
2861
  // dispatch formatted popStateEvent to child
2702
- dispatchPopStateEventToMicroApp(appName, proxyWindow, rawWindow.history.state);
2862
+ dispatchPopStateEventToMicroApp(appName, proxyWindow);
2703
2863
  // dispatch formatted hashChangeEvent to child when hash change
2704
2864
  if (isHashChange)
2705
2865
  dispatchHashChangeEventToMicroApp(appName, proxyWindow, oldHref);
@@ -2718,9 +2878,9 @@ function addHistoryListener(appName) {
2718
2878
  * @param proxyWindow sandbox window
2719
2879
  * @param eventState history.state
2720
2880
  */
2721
- function dispatchPopStateEventToMicroApp(appName, proxyWindow, eventState) {
2881
+ function dispatchPopStateEventToMicroApp(appName, proxyWindow) {
2722
2882
  // create PopStateEvent named popstate-appName with sub app state
2723
- const newPopStateEvent = new PopStateEvent(formatEventName$1('popstate', appName), { state: getMicroState(appName, eventState) });
2883
+ const newPopStateEvent = new PopStateEvent(formatEventName$1('popstate', appName), { state: getMicroState(appName) });
2724
2884
  globalEnv.rawWindow.dispatchEvent(newPopStateEvent);
2725
2885
  // call function window.onpopstate if it exists
2726
2886
  typeof proxyWindow.onpopstate === 'function' && proxyWindow.onpopstate(newPopStateEvent);
@@ -2785,37 +2945,35 @@ function createMicroHistory(appName, microLocation) {
2785
2945
  const rawHistory = globalEnv.rawWindow.history;
2786
2946
  function getMicroHistoryMethod(methodName) {
2787
2947
  return function (...rests) {
2788
- if ((methodName === 'pushState' || methodName === 'replaceState') &&
2789
- (isString(rests[2]) || isURL(rests[2]))) {
2948
+ if (isString(rests[2]) || isURL(rests[2])) {
2790
2949
  const targetLocation = createURL(rests[2], microLocation.href);
2791
2950
  if (targetLocation.origin === microLocation.origin) {
2792
- navigateWithNativeEvent(methodName, setMicroPathToURL(appName, targetLocation), true, setMicroState(appName, rawHistory.state, rests[0]), rests[1]);
2951
+ navigateWithNativeEvent(methodName, setMicroPathToURL(appName, targetLocation), true, setMicroState(appName, rests[0]), rests[1]);
2793
2952
  const targetFullPath = targetLocation.pathname + targetLocation.search + targetLocation.hash;
2794
2953
  if (targetFullPath !== microLocation.fullPath) {
2795
2954
  updateMicroLocation(appName, targetFullPath, microLocation);
2796
2955
  }
2797
- }
2798
- else {
2799
- rawHistory[methodName].apply(rawHistory, rests);
2956
+ return void 0;
2800
2957
  }
2801
2958
  }
2802
- else {
2803
- rawHistory[methodName].apply(rawHistory, rests);
2804
- }
2959
+ nativeHistoryNavigate(methodName, rests[2], rests[0], rests[1]);
2805
2960
  };
2806
2961
  }
2962
+ const pushState = getMicroHistoryMethod('pushState');
2963
+ const replaceState = getMicroHistoryMethod('replaceState');
2807
2964
  return new Proxy(rawHistory, {
2808
2965
  get(target, key) {
2809
2966
  if (key === 'state') {
2810
- return getMicroState(appName, rawHistory.state);
2967
+ return getMicroState(appName);
2811
2968
  }
2812
- else if (isFunction(Reflect.get(target, key))) {
2813
- return getMicroHistoryMethod(key);
2969
+ else if (key === 'pushState') {
2970
+ return pushState;
2814
2971
  }
2815
- return Reflect.get(target, key);
2816
- },
2817
- set(target, key, value) {
2818
- return Reflect.set(target, key, value);
2972
+ else if (key === 'replaceState') {
2973
+ return replaceState;
2974
+ }
2975
+ const rawValue = Reflect.get(target, key);
2976
+ return isFunction(rawValue) ? bindFunctionToRawObject(target, rawValue, 'HISTORY') : rawValue;
2819
2977
  }
2820
2978
  });
2821
2979
  }
@@ -2827,12 +2985,13 @@ function createMicroHistory(appName, microLocation) {
2827
2985
  * @param title history.title, default is ''
2828
2986
  */
2829
2987
  function nativeHistoryNavigate(methodName, fullPath, state = null, title = '') {
2830
- globalEnv.rawWindow.history[methodName](state, title, fullPath);
2988
+ const method = methodName === 'pushState' ? globalEnv.rawPushState : globalEnv.rawReplaceState;
2989
+ method.call(globalEnv.rawWindow.history, state, title, fullPath);
2831
2990
  }
2832
2991
  /**
2833
2992
  * Navigate to new path, and dispatch native popStateEvent/hashChangeEvent to browser
2834
2993
  * Use scenes:
2835
- * 1. mount/unmount through updateBrowserURL with limited popstateEvent
2994
+ * 1. mount/unmount through attachRouteToBrowserURL with limited popstateEvent
2836
2995
  * 2. proxyHistory.pushState/replaceState with limited popstateEvent
2837
2996
  * 3. api microApp.router.push/replace
2838
2997
  * 4. proxyLocation.hash = xxx
@@ -2852,19 +3011,20 @@ function navigateWithNativeEvent(methodName, result, onlyForBrowser, state, titl
2852
3011
  dispatchNativeEvent(onlyForBrowser, oldHref);
2853
3012
  }
2854
3013
  /**
2855
- * update browser url when mount/unmount/hidden/show
3014
+ * update browser url when mount/unmount/hidden/show/attachToURL/attachAllToURL
3015
+ * just attach microRoute info to browser, dispatch event to base app(exclude child)
2856
3016
  * @param result result of add/remove microApp path on browser url
2857
3017
  * @param state history.state
2858
3018
  */
2859
- function updateBrowserURL(result, state) {
3019
+ function attachRouteToBrowserURL(result, state) {
2860
3020
  navigateWithNativeEvent('replaceState', result, true, state);
2861
3021
  }
2862
3022
  /**
2863
3023
  * When path is same, keep the microAppState in history.state
2864
- * Fix bug of missing microAppState in next.js & angular
3024
+ * Fix bug of missing microAppState when base app is next.js or angular
2865
3025
  * @param method history.pushState/replaceState
2866
3026
  */
2867
- function patchHistoryState(method) {
3027
+ function reWriteHistoryMethod(method) {
2868
3028
  const rawWindow = globalEnv.rawWindow;
2869
3029
  return function (...rests) {
2870
3030
  var _a;
@@ -2880,22 +3040,38 @@ function patchHistoryState(method) {
2880
3040
  }
2881
3041
  }
2882
3042
  method.apply(rawWindow.history, rests);
3043
+ /**
3044
+ * Attach child router info to browser url when base app navigate with pushState/replaceState
3045
+ * NOTE:
3046
+ * 1. Exec after apply pushState/replaceState
3047
+ * 2. Unable to catch when base app navigate with location
3048
+ * 3. When in nest app, rawPushState/rawReplaceState has been modified by parent
3049
+ * 4.
3050
+ */
3051
+ getActiveApps(true).forEach(appName => {
3052
+ const app = appInstanceMap.get(appName);
3053
+ if (app.sandBox && app.useMemoryRouter && !getMicroPathFromURL(appName)) {
3054
+ attachRouteToBrowserURL(setMicroPathToURL(appName, app.sandBox.proxyWindow.location), setMicroState(appName, getMicroState(appName)));
3055
+ }
3056
+ });
3057
+ // fix bug for nest app
3058
+ removeDomScope();
2883
3059
  };
2884
3060
  }
2885
- let isReWriteHistoryState = false;
2886
3061
  /**
2887
3062
  * rewrite history.pushState/replaceState
2888
3063
  * used to fix the problem that the microAppState maybe missing when mainApp navigate to same path
2889
3064
  * e.g: when nextjs, angular receive popstate event, they will use history.replaceState to update browser url with a new state object
2890
3065
  */
2891
- function rewriteHistoryState() {
2892
- // filter nest app
2893
- if (!isReWriteHistoryState && !window.__MICRO_APP_ENVIRONMENT__) {
2894
- isReWriteHistoryState = true;
2895
- const rawWindow = globalEnv.rawWindow;
2896
- rawWindow.history.pushState = patchHistoryState(rawWindow.history.pushState);
2897
- rawWindow.history.replaceState = patchHistoryState(rawWindow.history.replaceState);
2898
- }
3066
+ function patchHistory() {
3067
+ const rawWindow = globalEnv.rawWindow;
3068
+ rawWindow.history.pushState = reWriteHistoryMethod(globalEnv.rawPushState);
3069
+ rawWindow.history.replaceState = reWriteHistoryMethod(globalEnv.rawReplaceState);
3070
+ }
3071
+ function releasePatchHistory() {
3072
+ const rawWindow = globalEnv.rawWindow;
3073
+ rawWindow.history.pushState = globalEnv.rawPushState;
3074
+ rawWindow.history.replaceState = globalEnv.rawReplaceState;
2899
3075
  }
2900
3076
 
2901
3077
  function createRouterApi() {
@@ -2907,7 +3083,7 @@ function createRouterApi() {
2907
3083
  * @param state to.state
2908
3084
  */
2909
3085
  function navigateWithRawHistory(appName, methodName, targetLocation, state) {
2910
- navigateWithNativeEvent(methodName, setMicroPathToURL(appName, targetLocation), false, setMicroState(appName, globalEnv.rawWindow.history.state, state !== null && state !== void 0 ? state : null));
3086
+ navigateWithNativeEvent(methodName, setMicroPathToURL(appName, targetLocation), false, setMicroState(appName, state !== null && state !== void 0 ? state : null));
2911
3087
  // clear element scope after navigate
2912
3088
  removeDomScope();
2913
3089
  }
@@ -2922,11 +3098,11 @@ function createRouterApi() {
2922
3098
  function createNavigationMethod(replace) {
2923
3099
  return function (to) {
2924
3100
  const appName = formatAppName(to.name);
2925
- // console.log(3333333, appInstanceMap.get(appName))
2926
3101
  if (appName && isString(to.path)) {
2927
3102
  const app = appInstanceMap.get(appName);
2928
- if (app && !app.sandBox)
2929
- return logError(`navigation failed, sandBox of app ${appName} is closed`);
3103
+ if (app && (!app.sandBox || !app.useMemoryRouter)) {
3104
+ return logError(`navigation failed, memory router of app ${appName} is closed`);
3105
+ }
2930
3106
  // active apps, include hidden keep-alive app
2931
3107
  if (getActiveApps().includes(appName)) {
2932
3108
  const microLocation = app.sandBox.proxyWindow.location;
@@ -3003,43 +3179,96 @@ function createRouterApi() {
3003
3179
  function clearRouterWhenUnmount(appName) {
3004
3180
  router.current.delete(appName);
3005
3181
  }
3006
- // defaultPage data
3007
- const defaultPageRecord = useMapRecord();
3008
3182
  /**
3009
- * defaultPage只在子应用初始化时生效,且优先级比浏览器上的子应用路由地址低
3183
+ * NOTE:
3184
+ * 1. sandbox not open
3185
+ * 2. useMemoryRouter is false
3186
+ */
3187
+ function commonHandlerForAttachToURL(appName) {
3188
+ const app = appInstanceMap.get(appName);
3189
+ if (app.sandBox && app.useMemoryRouter) {
3190
+ attachRouteToBrowserURL(setMicroPathToURL(appName, app.sandBox.proxyWindow.location), setMicroState(appName, getMicroState(appName)));
3191
+ }
3192
+ }
3193
+ /**
3194
+ * Attach specified active app router info to browser url
3010
3195
  * @param appName app name
3011
- * @param path page path
3012
3196
  */
3013
- function setDefaultPage(appName, path) {
3197
+ function attachToURL(appName) {
3014
3198
  appName = formatAppName(appName);
3015
- if (!appName)
3016
- return noopFalse;
3017
- return defaultPageRecord.add(appName, path);
3199
+ if (appName && getActiveApps().includes(appName)) {
3200
+ commonHandlerForAttachToURL(appName);
3201
+ }
3018
3202
  }
3019
- function removeDefaultPage(appName) {
3020
- appName = formatAppName(appName);
3021
- if (!appName)
3022
- return false;
3023
- return defaultPageRecord.delete(appName);
3203
+ /**
3204
+ * Attach all active app router info to browser url
3205
+ * exclude hidden keep-alive app
3206
+ */
3207
+ function attachAllToURL(includeHiddenApp = false) {
3208
+ getActiveApps(!includeHiddenApp).forEach(appName => commonHandlerForAttachToURL(appName));
3209
+ }
3210
+ function createDefaultPageApi() {
3211
+ // defaultPage data
3212
+ const defaultPageRecord = useMapRecord();
3213
+ /**
3214
+ * defaultPage only effect when mount, and has lower priority than query on browser url
3215
+ * @param appName app name
3216
+ * @param path page path
3217
+ */
3218
+ function setDefaultPage(appName, path) {
3219
+ appName = formatAppName(appName);
3220
+ if (!appName || !path) {
3221
+ if (process.env.NODE_ENV !== 'production') {
3222
+ if (!appName) {
3223
+ logWarn(`setDefaultPage: invalid appName "${appName}"`);
3224
+ }
3225
+ else {
3226
+ logWarn('setDefaultPage: path is required');
3227
+ }
3228
+ }
3229
+ return noopFalse;
3230
+ }
3231
+ return defaultPageRecord.add(appName, path);
3232
+ }
3233
+ function removeDefaultPage(appName) {
3234
+ appName = formatAppName(appName);
3235
+ if (!appName)
3236
+ return false;
3237
+ return defaultPageRecord.delete(appName);
3238
+ }
3239
+ return {
3240
+ setDefaultPage,
3241
+ removeDefaultPage,
3242
+ getDefaultPage: defaultPageRecord.get,
3243
+ };
3244
+ }
3245
+ function createBaseRouterApi() {
3246
+ /**
3247
+ * Record base app router, let child app control base app navigation
3248
+ */
3249
+ let baseRouterProxy = null;
3250
+ function setBaseAppRouter(baseRouter) {
3251
+ if (isObject(baseRouter)) {
3252
+ baseRouterProxy = new Proxy(baseRouter, {
3253
+ get(target, key) {
3254
+ removeDomScope();
3255
+ const rawValue = Reflect.get(target, key);
3256
+ return isFunction(rawValue) ? bindFunctionToRawObject(target, rawValue, 'BASEROUTER') : rawValue;
3257
+ }
3258
+ });
3259
+ }
3260
+ else if (process.env.NODE_ENV !== 'production') {
3261
+ logWarn('setBaseAppRouter: Invalid base router');
3262
+ }
3263
+ }
3264
+ return {
3265
+ setBaseAppRouter,
3266
+ getBaseAppRouter: () => baseRouterProxy,
3267
+ };
3024
3268
  }
3025
3269
  // Router API for developer
3026
- const router = {
3027
- current: new Map(),
3028
- encode: encodeMicroPath,
3029
- decode: decodeMicroPath,
3030
- push: createNavigationMethod(false),
3031
- replace: createNavigationMethod(true),
3032
- go: createRawHistoryMethod('go'),
3033
- back: createRawHistoryMethod('back'),
3034
- forward: createRawHistoryMethod('forward'),
3035
- beforeEach: beforeGuards.add,
3036
- afterEach: afterGuards.add,
3037
- // attachToURL: 将指定的子应用路由信息添加到浏览器地址上
3038
- // attachAllToURL: 将所有正在运行的子应用路由信息添加到浏览器地址上
3039
- setDefaultPage,
3040
- removeDefaultPage,
3041
- getDefaultPage: defaultPageRecord.get,
3042
- };
3270
+ 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,
3271
+ attachAllToURL }, createDefaultPageApi()), createBaseRouterApi());
3043
3272
  return {
3044
3273
  router,
3045
3274
  executeNavigationGuard,
@@ -3053,56 +3282,6 @@ const shadowLocationKeys = ['href', 'pathname', 'search', 'hash'];
3053
3282
  const locationKeys = [...shadowLocationKeys, 'host', 'hostname', 'port', 'protocol', 'search'];
3054
3283
  // origin, fullPath is necessary for guardLocation
3055
3284
  const guardLocationKeys = [...locationKeys, 'origin', 'fullPath'];
3056
- /**
3057
- * create guardLocation by microLocation, used for router guard
3058
- */
3059
- function createGuardLocation(appName, microLocation) {
3060
- const guardLocation = assign({ name: appName }, microLocation);
3061
- // The prototype values on the URL needs to be manually transferred
3062
- for (const key of guardLocationKeys)
3063
- guardLocation[key] = microLocation[key];
3064
- return guardLocation;
3065
- }
3066
- // for updateBrowserURLWithLocation when initial
3067
- function autoTriggerNavigationGuard(appName, microLocation) {
3068
- executeNavigationGuard(appName, createGuardLocation(appName, microLocation), createGuardLocation(appName, microLocation));
3069
- }
3070
- /**
3071
- * The following scenes will trigger location update:
3072
- * 1. pushState/replaceState
3073
- * 2. popStateEvent
3074
- * 3. query on browser url when init sub app
3075
- * 4. set defaultPage when when init sub app
3076
- * NOTE:
3077
- * 1. update browser URL first, and then update microLocation
3078
- * 2. the same fullPath will not trigger router guards
3079
- * @param appName app name
3080
- * @param path target path
3081
- * @param base base url
3082
- * @param microLocation micro app location
3083
- * @param type auto prevent
3084
- */
3085
- function updateMicroLocation(appName, path, microLocation, type) {
3086
- const newLocation = createURL(path, microLocation.href);
3087
- // record old values of microLocation to `from`
3088
- const from = createGuardLocation(appName, microLocation);
3089
- for (const key of locationKeys) {
3090
- if (shadowLocationKeys.includes(key)) {
3091
- // reference of shadowLocation
3092
- microLocation.shadowLocation[key] = newLocation[key];
3093
- }
3094
- else {
3095
- // @ts-ignore reference of microLocation
3096
- microLocation[key] = newLocation[key];
3097
- }
3098
- }
3099
- // update latest values of microLocation to `to`
3100
- const to = createGuardLocation(appName, microLocation);
3101
- // The hook called only when fullPath changed
3102
- if (type === 'auto' || (from.fullPath !== to.fullPath && type !== 'prevent')) {
3103
- executeNavigationGuard(appName, to, from);
3104
- }
3105
- }
3106
3285
  /**
3107
3286
  * Create location for microApp, each microApp has only one location object, it is a reference type
3108
3287
  * MDN https://developer.mozilla.org/en-US/docs/Web/API/Location
@@ -3247,6 +3426,56 @@ function createMicroLocation(appName, url) {
3247
3426
  shadowLocation,
3248
3427
  });
3249
3428
  }
3429
+ /**
3430
+ * create guardLocation by microLocation, used for router guard
3431
+ */
3432
+ function createGuardLocation(appName, microLocation) {
3433
+ const guardLocation = assign({ name: appName }, microLocation);
3434
+ // The prototype values on the URL needs to be manually transferred
3435
+ for (const key of guardLocationKeys)
3436
+ guardLocation[key] = microLocation[key];
3437
+ return guardLocation;
3438
+ }
3439
+ // for updateBrowserURLWithLocation when initial
3440
+ function autoTriggerNavigationGuard(appName, microLocation) {
3441
+ executeNavigationGuard(appName, createGuardLocation(appName, microLocation), createGuardLocation(appName, microLocation));
3442
+ }
3443
+ /**
3444
+ * The following scenes will trigger location update:
3445
+ * 1. pushState/replaceState
3446
+ * 2. popStateEvent
3447
+ * 3. query on browser url when init sub app
3448
+ * 4. set defaultPage when when init sub app
3449
+ * NOTE:
3450
+ * 1. update browser URL first, and then update microLocation
3451
+ * 2. the same fullPath will not trigger router guards
3452
+ * @param appName app name
3453
+ * @param path target path
3454
+ * @param base base url
3455
+ * @param microLocation micro app location
3456
+ * @param type auto prevent
3457
+ */
3458
+ function updateMicroLocation(appName, path, microLocation, type) {
3459
+ const newLocation = createURL(path, microLocation.href);
3460
+ // record old values of microLocation to `from`
3461
+ const from = createGuardLocation(appName, microLocation);
3462
+ for (const key of locationKeys) {
3463
+ if (shadowLocationKeys.includes(key)) {
3464
+ // reference of shadowLocation
3465
+ microLocation.shadowLocation[key] = newLocation[key];
3466
+ }
3467
+ else {
3468
+ // @ts-ignore reference of microLocation
3469
+ microLocation[key] = newLocation[key];
3470
+ }
3471
+ }
3472
+ // update latest values of microLocation to `to`
3473
+ const to = createGuardLocation(appName, microLocation);
3474
+ // The hook called only when fullPath changed
3475
+ if (type === 'auto' || (from.fullPath !== to.fullPath && type !== 'prevent')) {
3476
+ executeNavigationGuard(appName, to, from);
3477
+ }
3478
+ }
3250
3479
 
3251
3480
  /**
3252
3481
  * The router system has two operations: read and write
@@ -3256,7 +3485,6 @@ function createMicroLocation(appName, url) {
3256
3485
  * @returns MicroRouter
3257
3486
  */
3258
3487
  function createMicroRouter(appName, url) {
3259
- rewriteHistoryState();
3260
3488
  const microLocation = createMicroLocation(appName, url);
3261
3489
  return {
3262
3490
  microLocation,
@@ -3282,7 +3510,7 @@ function updateBrowserURLWithLocation(appName, microLocation, defaultPage) {
3282
3510
  if (defaultPage)
3283
3511
  updateMicroLocation(appName, defaultPage, microLocation, 'prevent');
3284
3512
  // attach microApp route info to browser URL
3285
- updateBrowserURL(setMicroPathToURL(appName, microLocation), setMicroState(appName, globalEnv.rawWindow.history.state, null));
3513
+ attachRouteToBrowserURL(setMicroPathToURL(appName, microLocation), setMicroState(appName, null));
3286
3514
  // trigger guards after change browser URL
3287
3515
  autoTriggerNavigationGuard(appName, microLocation);
3288
3516
  }
@@ -3306,27 +3534,121 @@ function clearRouteStateFromURL(appName, url, microLocation, keepRouteState) {
3306
3534
  * called on sandbox.stop or hidden of keep-alive app
3307
3535
  */
3308
3536
  function removeStateAndPathFromBrowser(appName) {
3309
- updateBrowserURL(removeMicroPathFromURL(appName), removeMicroState(appName, globalEnv.rawWindow.history.state));
3537
+ attachRouteToBrowserURL(removeMicroPathFromURL(appName), removeMicroState(appName, globalEnv.rawWindow.history.state));
3310
3538
  }
3311
3539
 
3312
- // Variables that can escape to rawWindow
3313
- const staticEscapeProperties = [
3314
- '__REACT_ERROR_OVERLAY_GLOBAL_HOOK__',
3315
- 'System',
3316
- '__cjsWrapper',
3317
- ];
3318
- // Variables that can only assigned to rawWindow
3319
- const escapeSetterKeyList = [
3320
- 'location',
3321
- ];
3540
+ /**
3541
+ * https://developer.mozilla.org/en-US/docs/Web/API/fetch
3542
+ * Promise<Response> fetch(input[, init])
3543
+ * input: string/Request
3544
+ * init?: object
3545
+ * @param url app url
3546
+ * @param target proxy target
3547
+ */
3548
+ function createMicroFetch(url, target) {
3549
+ const rawFetch = !isUndefined(target) ? target : globalEnv.rawWindow.fetch;
3550
+ if (!isFunction(rawFetch))
3551
+ return rawFetch;
3552
+ return function microFetch(input, init, ...rests) {
3553
+ if (isString(input) || isURL(input)) {
3554
+ input = createURL(input, url).toString();
3555
+ }
3556
+ /**
3557
+ * When fetch rewrite by baseApp, domScope still active when exec rawWindow.fetch
3558
+ * If baseApp operate dom in fetch, it will cause error
3559
+ * The same for XMLHttpRequest, EventSource
3560
+ * e.g.
3561
+ * baseApp: <script crossorigin src="https://sgm-static.jd.com/sgm-2.8.0.js" name="SGMH5" sid="6f88a6e4ba4b4ae5acef2ec22c075085" appKey="jdb-adminb2b-pc"></script>
3562
+ */
3563
+ removeDomScope();
3564
+ return rawFetch.call(globalEnv.rawWindow, input, init, ...rests);
3565
+ };
3566
+ }
3567
+ /**
3568
+ * https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest
3569
+ * https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/Using_XMLHttpRequest
3570
+ * @param url app url
3571
+ * @param target proxy target
3572
+ */
3573
+ function createMicroXMLHttpRequest(url, target) {
3574
+ const rawXMLHttpRequest = !isUndefined(target) ? target : globalEnv.rawWindow.XMLHttpRequest;
3575
+ if (!isConstructor(rawXMLHttpRequest))
3576
+ return rawXMLHttpRequest;
3577
+ return class MicroXMLHttpRequest extends rawXMLHttpRequest {
3578
+ open(method, reqUrl, ...rests) {
3579
+ if ((isString(reqUrl) && !/^f(ile|tp):\/\//.test(reqUrl)) || isURL(reqUrl)) {
3580
+ reqUrl = createURL(reqUrl, url).toString();
3581
+ }
3582
+ removeDomScope();
3583
+ super.open(method, reqUrl, ...rests);
3584
+ }
3585
+ };
3586
+ }
3587
+ function useMicroEventSource() {
3588
+ let eventSourceMap;
3589
+ /**
3590
+ * https://developer.mozilla.org/en-US/docs/Web/API/EventSource
3591
+ * pc = new EventSource(url[, configuration])
3592
+ * url: string/Request
3593
+ * configuration?: object
3594
+ * @param url app url
3595
+ * @param target proxy target
3596
+ */
3597
+ function createMicroEventSource(appName, url, target) {
3598
+ const rawEventSource = !isUndefined(target) ? target : globalEnv.rawWindow.EventSource;
3599
+ if (!isConstructor(rawEventSource))
3600
+ return rawEventSource;
3601
+ return class MicroEventSource extends rawEventSource {
3602
+ constructor(eventSourceUrl, eventSourceInitDict, ...rests) {
3603
+ if (isString(eventSourceUrl) || isURL(eventSourceUrl)) {
3604
+ eventSourceUrl = createURL(eventSourceUrl, url).toString();
3605
+ }
3606
+ removeDomScope();
3607
+ super(eventSourceUrl, eventSourceInitDict, ...rests);
3608
+ if (eventSourceMap) {
3609
+ const eventSourceList = eventSourceMap.get(appName);
3610
+ if (eventSourceList) {
3611
+ eventSourceList.add(this);
3612
+ }
3613
+ else {
3614
+ eventSourceMap.set(appName, new Set([this]));
3615
+ }
3616
+ }
3617
+ else {
3618
+ eventSourceMap = new Map([[appName, new Set([this])]]);
3619
+ }
3620
+ }
3621
+ close() {
3622
+ var _a;
3623
+ super.close();
3624
+ (_a = eventSourceMap.get(appName)) === null || _a === void 0 ? void 0 : _a.delete(this);
3625
+ }
3626
+ };
3627
+ }
3628
+ function clearMicroEventSource(appName) {
3629
+ const eventSourceList = eventSourceMap === null || eventSourceMap === void 0 ? void 0 : eventSourceMap.get(appName);
3630
+ if (eventSourceList === null || eventSourceList === void 0 ? void 0 : eventSourceList.size) {
3631
+ eventSourceList.forEach(item => {
3632
+ item.close();
3633
+ });
3634
+ eventSourceList.clear();
3635
+ }
3636
+ }
3637
+ return {
3638
+ createMicroEventSource,
3639
+ clearMicroEventSource,
3640
+ };
3641
+ }
3642
+
3643
+ const { createMicroEventSource, clearMicroEventSource } = useMicroEventSource();
3322
3644
  const globalPropertyList = ['window', 'self', 'globalThis'];
3323
3645
  class SandBox {
3324
3646
  constructor(appName, url, useMemoryRouter = true) {
3325
3647
  /**
3326
3648
  * Scoped global Properties(Properties that can only get and set in microAppWindow, will not escape to rawWindow)
3327
- * https://github.com/micro-zoe/micro-app/issues/234
3649
+ * Fix https://github.com/micro-zoe/micro-app/issues/234
3328
3650
  */
3329
- this.scopeProperties = ['webpackJsonp', 'Vue'];
3651
+ this.scopeProperties = [];
3330
3652
  // Properties that can be escape to rawWindow
3331
3653
  this.escapeProperties = [];
3332
3654
  // Properties newly added to microAppWindow
@@ -3336,14 +3658,15 @@ class SandBox {
3336
3658
  // sandbox state
3337
3659
  this.active = false;
3338
3660
  this.microAppWindow = {}; // Proxy target
3661
+ this.adapter = new Adapter();
3339
3662
  // get scopeProperties and escapeProperties from plugins
3340
3663
  this.getSpecialProperties(appName);
3341
3664
  // create proxyWindow with Proxy(microAppWindow)
3342
3665
  this.proxyWindow = this.createProxyWindow(appName);
3343
- // inject global properties
3344
- this.initMicroAppWindow(this.microAppWindow, appName, url, useMemoryRouter);
3345
3666
  // Rewrite global event listener & timeout
3346
- assign(this, effect(this.microAppWindow));
3667
+ assign(this, effect(appName, this.microAppWindow));
3668
+ // inject global properties
3669
+ this.initStaticGlobalKeys(this.microAppWindow, appName, url, useMemoryRouter);
3347
3670
  }
3348
3671
  start(baseRoute, useMemoryRouter = true, defaultPage = '') {
3349
3672
  if (!this.active) {
@@ -3356,20 +3679,35 @@ class SandBox {
3356
3679
  else {
3357
3680
  this.microAppWindow.__MICRO_APP_BASE_ROUTE__ = this.microAppWindow.__MICRO_APP_BASE_URL__ = baseRoute;
3358
3681
  }
3682
+ // prevent the key deleted during sandBox.stop after rewrite
3683
+ this.initGlobalKeysWhenStart(this.microAppWindow, this.proxyWindow.__MICRO_APP_NAME__, this.proxyWindow.__MICRO_APP_URL__);
3359
3684
  if (++SandBox.activeCount === 1) {
3360
3685
  effectDocumentEvent();
3361
3686
  patchElementPrototypeMethods();
3362
- listenUmountOfNestedApp();
3687
+ initEnvOfNestedApp();
3688
+ patchHistory();
3363
3689
  }
3364
- // BUG FIX: bable-polyfill@6.x
3365
- globalEnv.rawWindow._babelPolyfill && (globalEnv.rawWindow._babelPolyfill = false);
3690
+ fixBabelPolyfill6();
3366
3691
  }
3367
3692
  }
3368
- stop(keepRouteState = false) {
3693
+ stop(keepRouteState, clearEventSource) {
3369
3694
  if (this.active) {
3370
3695
  this.releaseEffect();
3371
3696
  this.microAppWindow.microApp.clearDataListener();
3372
3697
  this.microAppWindow.microApp.clearGlobalDataListener();
3698
+ if (this.removeHistoryListener) {
3699
+ this.clearRouteState(keepRouteState);
3700
+ // release listener of popstate
3701
+ this.removeHistoryListener();
3702
+ }
3703
+ if (clearEventSource) {
3704
+ clearMicroEventSource(this.proxyWindow.__MICRO_APP_NAME__);
3705
+ }
3706
+ /**
3707
+ * NOTE:
3708
+ * 1. injectedKeys and escapeKeys must be placed at the back
3709
+ * 2. if key in initial microAppWindow, and then rewrite, this key will be delete from microAppWindow when stop, and lost when restart
3710
+ */
3373
3711
  this.injectedKeys.forEach((key) => {
3374
3712
  Reflect.deleteProperty(this.microAppWindow, key);
3375
3713
  });
@@ -3378,14 +3716,10 @@ class SandBox {
3378
3716
  Reflect.deleteProperty(globalEnv.rawWindow, key);
3379
3717
  });
3380
3718
  this.escapeKeys.clear();
3381
- if (this.removeHistoryListener) {
3382
- this.clearRouteState(keepRouteState);
3383
- // release listener of popstate
3384
- this.removeHistoryListener();
3385
- }
3386
3719
  if (--SandBox.activeCount === 0) {
3387
3720
  releaseEffectDocumentEvent();
3388
3721
  releasePatches();
3722
+ releasePatchHistory();
3389
3723
  }
3390
3724
  this.active = false;
3391
3725
  }
@@ -3409,15 +3743,16 @@ class SandBox {
3409
3743
  rebuildDataCenterSnapshot(this.microAppWindow.microApp);
3410
3744
  }
3411
3745
  /**
3412
- * get scopeProperties and escapeProperties from plugins
3746
+ * get scopeProperties and escapeProperties from plugins & adapter
3413
3747
  * @param appName app name
3414
3748
  */
3415
3749
  getSpecialProperties(appName) {
3416
3750
  var _a;
3417
- if (!isPlainObject(microApp.plugins))
3418
- return;
3419
- this.commonActionForSpecialProperties(microApp.plugins.global);
3420
- this.commonActionForSpecialProperties((_a = microApp.plugins.modules) === null || _a === void 0 ? void 0 : _a[appName]);
3751
+ this.scopeProperties = this.scopeProperties.concat(this.adapter.staticScopeProperties);
3752
+ if (isPlainObject(microApp.plugins)) {
3753
+ this.commonActionForSpecialProperties(microApp.plugins.global);
3754
+ this.commonActionForSpecialProperties((_a = microApp.plugins.modules) === null || _a === void 0 ? void 0 : _a[appName]);
3755
+ }
3421
3756
  }
3422
3757
  // common action for global plugins and module plugins
3423
3758
  commonActionForSpecialProperties(plugins) {
@@ -3447,11 +3782,11 @@ class SandBox {
3447
3782
  this.scopeProperties.includes(key))
3448
3783
  return Reflect.get(target, key);
3449
3784
  const rawValue = Reflect.get(rawWindow, key);
3450
- return isFunction(rawValue) ? bindFunctionToRawWindow(rawWindow, rawValue) : rawValue;
3785
+ return isFunction(rawValue) ? bindFunctionToRawObject(rawWindow, rawValue) : rawValue;
3451
3786
  },
3452
3787
  set: (target, key, value) => {
3453
3788
  if (this.active) {
3454
- if (escapeSetterKeyList.includes(key)) {
3789
+ if (this.adapter.escapeSetterKeyList.includes(key)) {
3455
3790
  Reflect.set(rawWindow, key, value);
3456
3791
  }
3457
3792
  else if (
@@ -3475,7 +3810,8 @@ class SandBox {
3475
3810
  this.injectedKeys.add(key);
3476
3811
  }
3477
3812
  if ((this.escapeProperties.includes(key) ||
3478
- (staticEscapeProperties.includes(key) && !Reflect.has(rawWindow, key))) &&
3813
+ (this.adapter.staticEscapeProperties.includes(key) &&
3814
+ !Reflect.has(rawWindow, key))) &&
3479
3815
  !this.scopeProperties.includes(key)) {
3480
3816
  Reflect.set(rawWindow, key, value);
3481
3817
  this.escapeKeys.add(key);
@@ -3531,26 +3867,48 @@ class SandBox {
3531
3867
  * @param microAppWindow micro window
3532
3868
  * @param appName app name
3533
3869
  * @param url app url
3870
+ * @param useMemoryRouter whether use memory router
3534
3871
  */
3535
- initMicroAppWindow(microAppWindow, appName, url, useMemoryRouter) {
3872
+ initStaticGlobalKeys(microAppWindow, appName, url, useMemoryRouter) {
3536
3873
  microAppWindow.__MICRO_APP_ENVIRONMENT__ = true;
3537
3874
  microAppWindow.__MICRO_APP_NAME__ = appName;
3538
3875
  microAppWindow.__MICRO_APP_URL__ = url;
3539
3876
  microAppWindow.__MICRO_APP_PUBLIC_PATH__ = getEffectivePath(url);
3540
3877
  microAppWindow.__MICRO_APP_WINDOW__ = microAppWindow;
3878
+ microAppWindow.rawWindow = globalEnv.rawWindow;
3879
+ microAppWindow.rawDocument = globalEnv.rawDocument;
3541
3880
  microAppWindow.microApp = assign(new EventCenterForMicroApp(appName), {
3542
3881
  removeDomScope,
3543
3882
  pureCreateElement,
3544
3883
  router,
3545
3884
  });
3546
- microAppWindow.rawWindow = globalEnv.rawWindow;
3547
- microAppWindow.rawDocument = globalEnv.rawDocument;
3548
- microAppWindow.hasOwnProperty = (key) => rawHasOwnProperty.call(microAppWindow, key) || rawHasOwnProperty.call(globalEnv.rawWindow, key);
3885
+ this.setProxyDocument(microAppWindow, appName);
3549
3886
  this.setMappingPropertiesWithRawDescriptor(microAppWindow);
3550
- this.setHijackProperties(microAppWindow, appName);
3551
- // this.patchHijackRequest(microAppWindow, appName, url)
3552
3887
  if (useMemoryRouter)
3553
- this.setRouterApi(microAppWindow, appName, url);
3888
+ this.setMicroAppRouter(microAppWindow, appName, url);
3889
+ }
3890
+ setProxyDocument(microAppWindow, appName) {
3891
+ const { proxyDocument, MicroDocument } = this.createProxyDocument(appName);
3892
+ rawDefineProperties(microAppWindow, {
3893
+ document: {
3894
+ configurable: false,
3895
+ enumerable: true,
3896
+ get() {
3897
+ throttleDeferForSetAppName(appName);
3898
+ // return globalEnv.rawDocument
3899
+ return proxyDocument;
3900
+ },
3901
+ },
3902
+ Document: {
3903
+ configurable: false,
3904
+ enumerable: false,
3905
+ get() {
3906
+ throttleDeferForSetAppName(appName);
3907
+ // return globalEnv.rawRootDocument
3908
+ return MicroDocument;
3909
+ },
3910
+ }
3911
+ });
3554
3912
  }
3555
3913
  // properties associated with the native window
3556
3914
  setMappingPropertiesWithRawDescriptor(microAppWindow) {
@@ -3579,18 +3937,21 @@ class SandBox {
3579
3937
  };
3580
3938
  return descriptor;
3581
3939
  }
3940
+ /**
3941
+ * init global properties of microAppWindow when exec sandBox.start
3942
+ * @param microAppWindow micro window
3943
+ * @param appName app name
3944
+ * @param url app url
3945
+ */
3946
+ initGlobalKeysWhenStart(microAppWindow, appName, url) {
3947
+ microAppWindow.hasOwnProperty = (key) => rawHasOwnProperty.call(microAppWindow, key) || rawHasOwnProperty.call(globalEnv.rawWindow, key);
3948
+ this.setHijackProperty(microAppWindow, appName);
3949
+ this.patchRequestApi(microAppWindow, appName, url);
3950
+ }
3582
3951
  // set hijack Properties to microAppWindow
3583
- setHijackProperties(microAppWindow, appName) {
3952
+ setHijackProperty(microAppWindow, appName) {
3584
3953
  let modifiedEval, modifiedImage;
3585
3954
  rawDefineProperties(microAppWindow, {
3586
- document: {
3587
- configurable: false,
3588
- enumerable: true,
3589
- get() {
3590
- throttleDeferForSetAppName(appName);
3591
- return globalEnv.rawDocument;
3592
- },
3593
- },
3594
3955
  eval: {
3595
3956
  configurable: true,
3596
3957
  enumerable: false,
@@ -3615,65 +3976,46 @@ class SandBox {
3615
3976
  },
3616
3977
  });
3617
3978
  }
3618
- // private patchHijackRequest (microAppWindow: microAppWindowType, appName: string, url: string) {
3619
- // let modifiedImage: unknown
3620
- // function EventSource (...rests: any[]) {
3621
- // console.log(appName + ' EventSource', rests)
3622
- // if (typeof rests[0] === 'string') {
3623
- // rests[0] = (new URL(rests[0], url)).toString()
3624
- // }
3625
- // return new globalEnv.rawWindow.EventSource(...rests)
3626
- // }
3627
- // function patchFetch (...rests: any[]) {
3628
- // console.log(appName + ' fetch', rests)
3629
- // if (typeof rests[0] === 'string') {
3630
- // rests[0] = (new URL(rests[0], url)).toString()
3631
- // }
3632
- // return globalEnv.rawWindow.fetch(...rests)
3633
- // }
3634
- // const rawXMLHttpRequest = globalEnv.rawWindow.XMLHttpRequest
3635
- // class XMLHttpRequest extends rawXMLHttpRequest {
3636
- // open (method: string, reqUrl: string) {
3637
- // console.log(appName + ' XMLHttpRequest', method, reqUrl)
3638
- // reqUrl = (new URL(reqUrl, url)).toString()
3639
- // super.open(method, reqUrl)
3640
- // }
3641
- // }
3642
- // rawDefineProperties(microAppWindow, {
3643
- // EventSource: {
3644
- // configurable: true,
3645
- // enumerable: true,
3646
- // get () {
3647
- // return EventSource
3648
- // },
3649
- // set: (value) => {
3650
- // modifiedImage = value
3651
- // },
3652
- // },
3653
- // fetch: {
3654
- // configurable: true,
3655
- // enumerable: true,
3656
- // get () {
3657
- // return patchFetch
3658
- // },
3659
- // set: (value) => {
3660
- // modifiedImage = value
3661
- // },
3662
- // },
3663
- // XMLHttpRequest: {
3664
- // configurable: true,
3665
- // enumerable: true,
3666
- // get () {
3667
- // return XMLHttpRequest
3668
- // },
3669
- // set: (value) => {
3670
- // modifiedImage = value
3671
- // },
3672
- // },
3673
- // })
3674
- // }
3979
+ // rewrite fetch, XMLHttpRequest, EventSource
3980
+ patchRequestApi(microAppWindow, appName, url) {
3981
+ let microFetch = createMicroFetch(url);
3982
+ let microXMLHttpRequest = createMicroXMLHttpRequest(url);
3983
+ let microEventSource = createMicroEventSource(appName, url);
3984
+ rawDefineProperties(microAppWindow, {
3985
+ fetch: {
3986
+ configurable: true,
3987
+ enumerable: true,
3988
+ get() {
3989
+ return microFetch;
3990
+ },
3991
+ set(value) {
3992
+ microFetch = createMicroFetch(url, value);
3993
+ },
3994
+ },
3995
+ XMLHttpRequest: {
3996
+ configurable: true,
3997
+ enumerable: true,
3998
+ get() {
3999
+ return microXMLHttpRequest;
4000
+ },
4001
+ set(value) {
4002
+ microXMLHttpRequest = createMicroXMLHttpRequest(url, value);
4003
+ },
4004
+ },
4005
+ EventSource: {
4006
+ configurable: true,
4007
+ enumerable: true,
4008
+ get() {
4009
+ return microEventSource;
4010
+ },
4011
+ set(value) {
4012
+ microEventSource = createMicroEventSource(appName, url, value);
4013
+ },
4014
+ },
4015
+ });
4016
+ }
3675
4017
  // set location & history for memory router
3676
- setRouterApi(microAppWindow, appName, url) {
4018
+ setMicroAppRouter(microAppWindow, appName, url) {
3677
4019
  const { microLocation, microHistory } = createMicroRouter(appName, url);
3678
4020
  rawDefineProperties(microAppWindow, {
3679
4021
  location: {
@@ -3707,6 +4049,63 @@ class SandBox {
3707
4049
  removeRouteInfoForKeepAliveApp() {
3708
4050
  removeStateAndPathFromBrowser(this.proxyWindow.__MICRO_APP_NAME__);
3709
4051
  }
4052
+ /**
4053
+ * Create new document and Document
4054
+ */
4055
+ createProxyDocument(appName) {
4056
+ const rawDocument = globalEnv.rawDocument;
4057
+ const rawRootDocument = globalEnv.rawRootDocument;
4058
+ const createElement = function (tagName, options) {
4059
+ const element = globalEnv.rawCreateElement.call(rawDocument, tagName, options);
4060
+ element.__MICRO_APP_NAME__ = appName;
4061
+ return element;
4062
+ };
4063
+ const proxyDocument = new Proxy(rawDocument, {
4064
+ get(target, key) {
4065
+ throttleDeferForSetAppName(appName);
4066
+ throttleDeferForParentNode(proxyDocument);
4067
+ if (key === 'createElement')
4068
+ return createElement;
4069
+ if (key === Symbol.toStringTag)
4070
+ return 'ProxyDocument';
4071
+ const rawValue = Reflect.get(target, key);
4072
+ return isFunction(rawValue) ? bindFunctionToRawObject(rawDocument, rawValue, 'DOCUMENT') : rawValue;
4073
+ },
4074
+ });
4075
+ class MicroDocument {
4076
+ static [Symbol.hasInstance](target) {
4077
+ let proto = target;
4078
+ while (proto = Object.getPrototypeOf(proto)) {
4079
+ if (proto === MicroDocument.prototype) {
4080
+ return true;
4081
+ }
4082
+ }
4083
+ return (target === proxyDocument ||
4084
+ target instanceof rawRootDocument);
4085
+ }
4086
+ }
4087
+ /**
4088
+ * TIP:
4089
+ * 1. child class __proto__, which represents the inherit of the constructor, always points to the parent class
4090
+ * 2. child class prototype.__proto__, which represents the inherit of methods, always points to parent class prototype
4091
+ * e.g.
4092
+ * class B extends A {}
4093
+ * B.__proto__ === A // true
4094
+ * B.prototype.__proto__ === A.prototype // true
4095
+ */
4096
+ Object.setPrototypeOf(MicroDocument, rawRootDocument);
4097
+ Object.setPrototypeOf(MicroDocument.prototype, new Proxy(rawRootDocument.prototype, {
4098
+ get(target, key) {
4099
+ throttleDeferForSetAppName(appName);
4100
+ const rawValue = Reflect.get(target, key);
4101
+ return isFunction(rawValue) ? bindFunctionToRawObject(rawDocument, rawValue, 'DOCUMENT') : rawValue;
4102
+ }
4103
+ }));
4104
+ return {
4105
+ proxyDocument,
4106
+ MicroDocument,
4107
+ };
4108
+ }
3710
4109
  }
3711
4110
  SandBox.activeCount = 0; // number of active sandbox
3712
4111
 
@@ -3774,7 +4173,7 @@ function dispatchCustomEventToMicroApp(eventName, appName, detail = {}) {
3774
4173
  // micro app instances
3775
4174
  const appInstanceMap = new Map();
3776
4175
  class CreateApp {
3777
- constructor({ name, url, ssrUrl, container, inline, scopecss, useSandbox, useMemoryRouter, baseroute, keepRouteState, defaultPage, }) {
4176
+ constructor({ name, url, ssrUrl, container, inline, scopecss, useSandbox, useMemoryRouter, baseroute, keepRouteState, hiddenRouter, defaultPage, }) {
3778
4177
  this.state = appStates.CREATED;
3779
4178
  this.keepAliveState = null;
3780
4179
  this.keepAliveContainer = null;
@@ -3787,17 +4186,18 @@ class CreateApp {
3787
4186
  this.prefetchResolve = null;
3788
4187
  this.container = null;
3789
4188
  this.sandBox = null;
3790
- this.container = container !== null && container !== void 0 ? container : null;
3791
- this.inline = inline !== null && inline !== void 0 ? inline : false;
3792
- this.baseroute = baseroute !== null && baseroute !== void 0 ? baseroute : '';
3793
- this.keepRouteState = keepRouteState !== null && keepRouteState !== void 0 ? keepRouteState : false;
3794
- this.ssrUrl = ssrUrl !== null && ssrUrl !== void 0 ? ssrUrl : '';
3795
- // optional during init👆
3796
4189
  this.name = name;
3797
4190
  this.url = url;
3798
4191
  this.useSandbox = useSandbox;
3799
4192
  this.scopecss = this.useSandbox && scopecss;
3800
4193
  this.useMemoryRouter = this.useSandbox && useMemoryRouter;
4194
+ // optional during init base on prefetch 👇
4195
+ this.container = container !== null && container !== void 0 ? container : null;
4196
+ this.ssrUrl = ssrUrl !== null && ssrUrl !== void 0 ? ssrUrl : '';
4197
+ this.inline = inline !== null && inline !== void 0 ? inline : false;
4198
+ this.baseroute = baseroute !== null && baseroute !== void 0 ? baseroute : '';
4199
+ this.keepRouteState = keepRouteState !== null && keepRouteState !== void 0 ? keepRouteState : false;
4200
+ this.hiddenRouter = hiddenRouter !== null && hiddenRouter !== void 0 ? hiddenRouter : false;
3801
4201
  this.defaultPage = defaultPage !== null && defaultPage !== void 0 ? defaultPage : '';
3802
4202
  this.source = {
3803
4203
  links: new Map(),
@@ -3850,16 +4250,14 @@ class CreateApp {
3850
4250
  * @param baseroute route prefix, default is ''
3851
4251
  * @param keepRouteState keep route state when unmount, default is false
3852
4252
  */
3853
- mount(container, inline, baseroute, keepRouteState, defaultPage) {
4253
+ mount(container, inline, baseroute, keepRouteState, defaultPage, hiddenRouter) {
3854
4254
  var _a, _b, _c;
3855
- if (isBoolean(inline))
3856
- this.inline = inline;
3857
- // keepRouteState effective on unmount
3858
- if (isBoolean(keepRouteState))
3859
- this.keepRouteState = keepRouteState;
4255
+ this.inline = inline !== null && inline !== void 0 ? inline : this.inline;
4256
+ this.keepRouteState = keepRouteState !== null && keepRouteState !== void 0 ? keepRouteState : this.keepRouteState;
3860
4257
  this.container = (_a = this.container) !== null && _a !== void 0 ? _a : container;
3861
4258
  this.baseroute = baseroute !== null && baseroute !== void 0 ? baseroute : this.baseroute;
3862
4259
  this.defaultPage = defaultPage !== null && defaultPage !== void 0 ? defaultPage : this.defaultPage;
4260
+ this.hiddenRouter = hiddenRouter !== null && hiddenRouter !== void 0 ? hiddenRouter : this.hiddenRouter;
3863
4261
  if (this.loadSourceLevel !== 2) {
3864
4262
  this.state = appStates.LOADING;
3865
4263
  return;
@@ -3990,8 +4388,13 @@ class CreateApp {
3990
4388
  else if (this.umdMode && this.container.childElementCount) {
3991
4389
  cloneContainer(this.container, this.source.html, false);
3992
4390
  }
3993
- // this.container maybe contains micro-app element, stop sandbox should exec after cloneContainer
3994
- (_a = this.sandBox) === null || _a === void 0 ? void 0 : _a.stop(this.keepRouteState && !destroy);
4391
+ /**
4392
+ * this.container maybe contains micro-app element, stop sandbox should exec after cloneContainer
4393
+ * NOTE:
4394
+ * 1. if destroy is true, clear route state
4395
+ * 2. umd mode and keep-alive will not clear EventSource
4396
+ */
4397
+ (_a = this.sandBox) === null || _a === void 0 ? void 0 : _a.stop(this.keepRouteState && !destroy, !this.umdMode || destroy);
3995
4398
  if (!getActiveApps().length) {
3996
4399
  releasePatchSetAttribute();
3997
4400
  }
@@ -4129,6 +4532,7 @@ function defineElement(tagName) {
4129
4532
  this.setAttribute('name', this.appName);
4130
4533
  }
4131
4534
  };
4535
+ // patchSetAttribute hijiack data attribute, it needs exec first
4132
4536
  patchSetAttribute();
4133
4537
  }
4134
4538
  static get observedAttributes() {
@@ -4305,7 +4709,7 @@ function defineElement(tagName) {
4305
4709
  app.isPrefetch = false;
4306
4710
  defer(() => {
4307
4711
  var _a;
4308
- return app.mount((_a = this.shadowRoot) !== null && _a !== void 0 ? _a : this, this.getDisposeResult('inline'), this.getBaseRouteCompatible(), this.getDisposeResult('keep-router-state'), this.getDefaultPageValue());
4712
+ return app.mount((_a = this.shadowRoot) !== null && _a !== void 0 ? _a : this, this.getDisposeResult('inline'), this.getBaseRouteCompatible(), this.getDisposeResult('keep-router-state'), this.getDefaultPageValue(), this.getDisposeResult('hidden-router'));
4309
4713
  });
4310
4714
  }
4311
4715
  // create app instance
@@ -4324,12 +4728,13 @@ function defineElement(tagName) {
4324
4728
  ssrUrl: this.ssrUrl,
4325
4729
  container: (_a = this.shadowRoot) !== null && _a !== void 0 ? _a : this,
4326
4730
  inline: this.getDisposeResult('inline'),
4327
- scopecss: !(this.getDisposeResult('disableScopecss') || this.getDisposeResult('shadowDOM')),
4328
- useSandbox: !this.getDisposeResult('disableSandbox'),
4731
+ scopecss: !(this.getDisposeResult('disable-scopecss') || this.getDisposeResult('shadowDOM')),
4732
+ useSandbox: !this.getDisposeResult('disable-sandbox'),
4329
4733
  useMemoryRouter: !this.getDisposeResult('disable-memory-router'),
4330
4734
  baseroute: this.getBaseRouteCompatible(),
4331
4735
  keepRouteState: this.getDisposeResult('keep-router-state'),
4332
4736
  defaultPage: this.getDefaultPageValue(),
4737
+ hiddenRouter: this.getDisposeResult('hidden-router'),
4333
4738
  });
4334
4739
  appInstanceMap.set(this.appName, instance);
4335
4740
  }
@@ -4364,25 +4769,25 @@ function defineElement(tagName) {
4364
4769
  */
4365
4770
  getDisposeResult(name) {
4366
4771
  // @ts-ignore
4367
- return (this.compatibleSpecialProperties(name) || microApp[name]) && this.compatibleDisableSpecialProperties(name);
4772
+ return (this.compatibleSpecialProperties(name) || !!microApp[name]) && this.compatibleDisableSpecialProperties(name);
4368
4773
  }
4369
4774
  // compatible of disableScopecss & disableSandbox
4370
4775
  compatibleSpecialProperties(name) {
4371
- if (name === 'disableScopecss') {
4372
- return this.hasAttribute('disableScopecss') || this.hasAttribute('disable-scopecss');
4776
+ if (name === 'disable-scopecss') {
4777
+ return this.hasAttribute('disable-scopecss') || this.hasAttribute('disableScopecss');
4373
4778
  }
4374
- else if (name === 'disableSandbox') {
4375
- return this.hasAttribute('disableSandbox') || this.hasAttribute('disable-sandbox');
4779
+ else if (name === 'disable-sandbox') {
4780
+ return this.hasAttribute('disable-sandbox') || this.hasAttribute('disableSandbox');
4376
4781
  }
4377
4782
  return this.hasAttribute(name);
4378
4783
  }
4379
4784
  // compatible of disableScopecss & disableSandbox
4380
4785
  compatibleDisableSpecialProperties(name) {
4381
- if (name === 'disableScopecss') {
4382
- return this.getAttribute('disableScopecss') !== 'false' && this.getAttribute('disable-scopecss') !== 'false';
4786
+ if (name === 'disable-scopecss') {
4787
+ return this.getAttribute('disable-scopecss') !== 'false' && this.getAttribute('disableScopecss') !== 'false';
4383
4788
  }
4384
- else if (name === 'disableSandbox') {
4385
- return this.getAttribute('disableSandbox') !== 'false' && this.getAttribute('disable-sandbox') !== 'false';
4789
+ else if (name === 'disable-sandbox') {
4790
+ return this.getAttribute('disable-sandbox') !== 'false' && this.getAttribute('disableSandbox') !== 'false';
4386
4791
  }
4387
4792
  return this.getAttribute(name) !== 'false';
4388
4793
  }
@@ -4410,7 +4815,7 @@ function defineElement(tagName) {
4410
4815
  */
4411
4816
  updateSsrUrl(baseUrl) {
4412
4817
  if (this.getDisposeResult('ssr')) {
4413
- if (this.getDisposeResult('disable-memory-router')) {
4818
+ if (this.getDisposeResult('disable-memory-router') || this.getDisposeResult('disableSandbox')) {
4414
4819
  const rawLocation = globalEnv.rawWindow.location;
4415
4820
  this.ssrUrl = CompletionPath(rawLocation.pathname + rawLocation.search, baseUrl);
4416
4821
  }
@@ -4494,7 +4899,7 @@ function preFetch(apps) {
4494
4899
  function preFetchInSerial(prefetchApp) {
4495
4900
  return new Promise((resolve) => {
4496
4901
  requestIdleCallback(() => {
4497
- var _a, _b, _c;
4902
+ var _a, _b, _c, _d, _e;
4498
4903
  if (isPlainObject(prefetchApp) && navigator.onLine) {
4499
4904
  prefetchApp.name = formatAppName(prefetchApp.name);
4500
4905
  prefetchApp.url = formatAppURL(prefetchApp.url, prefetchApp.name);
@@ -4502,9 +4907,9 @@ function preFetchInSerial(prefetchApp) {
4502
4907
  const app = new CreateApp({
4503
4908
  name: prefetchApp.name,
4504
4909
  url: prefetchApp.url,
4505
- scopecss: !((_a = prefetchApp.disableScopecss) !== null && _a !== void 0 ? _a : microApp.disableScopecss),
4506
- useSandbox: !((_b = prefetchApp.disableSandbox) !== null && _b !== void 0 ? _b : microApp.disableSandbox),
4507
- useMemoryRouter: !((_c = prefetchApp.disableMemoryRouter) !== null && _c !== void 0 ? _c : microApp.disableMemoryRouter),
4910
+ scopecss: !((_b = (_a = prefetchApp['disable-scopecss']) !== null && _a !== void 0 ? _a : prefetchApp.disableScopecss) !== null && _b !== void 0 ? _b : microApp['disable-scopecss']),
4911
+ useSandbox: !((_d = (_c = prefetchApp['disable-sandbox']) !== null && _c !== void 0 ? _c : prefetchApp.disableSandbox) !== null && _d !== void 0 ? _d : microApp['disable-sandbox']),
4912
+ useMemoryRouter: !((_e = prefetchApp['disable-memory-router']) !== null && _e !== void 0 ? _e : microApp['disable-memory-router']),
4508
4913
  });
4509
4914
  app.isPrefetch = true;
4510
4915
  app.prefetchResolve = resolve;
@@ -4554,7 +4959,7 @@ function fetchGlobalResources(resources, suffix, cache) {
4554
4959
  * @param excludeHiddenApp exclude hidden keep-alive app, default is false
4555
4960
  * @returns active apps
4556
4961
  */
4557
- function getActiveApps(excludeHiddenApp) {
4962
+ function getActiveApps(excludeHiddenApp = false) {
4558
4963
  const activeApps = [];
4559
4964
  appInstanceMap.forEach((app, appName) => {
4560
4965
  if (appStates.UNMOUNT !== app.getAppState() &&
@@ -4650,6 +5055,7 @@ class MicroApp extends EventCenterForBaseApp {
4650
5055
  this.router = router;
4651
5056
  }
4652
5057
  start(options) {
5058
+ var _a, _b;
4653
5059
  if (!isBrowser || !window.customElements) {
4654
5060
  return logError('micro-app is not supported in this environment');
4655
5061
  }
@@ -4675,9 +5081,12 @@ class MicroApp extends EventCenterForBaseApp {
4675
5081
  // @ts-ignore
4676
5082
  this.destory = options.destory;
4677
5083
  this.inline = options.inline;
4678
- this.disableScopecss = options.disableScopecss;
4679
- this.disableSandbox = options.disableSandbox;
4680
- this.disableMemoryRouter = options.disableMemoryRouter;
5084
+ this['disable-scopecss'] = (_a = options['disable-scopecss']) !== null && _a !== void 0 ? _a : options.disableScopecss;
5085
+ this['disable-sandbox'] = (_b = options['disable-sandbox']) !== null && _b !== void 0 ? _b : options.disableSandbox;
5086
+ this['disable-memory-router'] = options['disable-memory-router'];
5087
+ this['keep-router-state'] = options['keep-router-state'];
5088
+ this['hidden-router'] = options['hidden-router'];
5089
+ this.esmodule = options.esmodule;
4681
5090
  this.ssr = options.ssr;
4682
5091
  isFunction(options.fetch) && (this.fetch = options.fetch);
4683
5092
  isPlainObject(options.lifeCycles) && (this.lifeCycles = options.lifeCycles);