@micro-zoe/micro-app 1.0.0-alpha.2 → 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.2';
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
@@ -72,6 +72,10 @@ function isShadowRoot(target) {
72
72
  function isURL(target) {
73
73
  return target instanceof URL;
74
74
  }
75
+ // is ProxyDocument
76
+ function isProxyDocument(target) {
77
+ return toString.call(target) === '[object ProxyDocument]';
78
+ }
75
79
  /**
76
80
  * format error log
77
81
  * @param msg message
@@ -1363,101 +1367,112 @@ function markElement(element) {
1363
1367
  // methods of document
1364
1368
  function patchDocument() {
1365
1369
  const rawDocument = globalEnv.rawDocument;
1370
+ const rawRootDocument = globalEnv.rawRootDocument;
1371
+ function getBindTarget(target) {
1372
+ return isProxyDocument(target) ? rawDocument : target;
1373
+ }
1366
1374
  // create element 👇
1367
- Document.prototype.createElement = function createElement(tagName, options) {
1368
- 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);
1369
1377
  return markElement(element);
1370
1378
  };
1371
- Document.prototype.createElementNS = function createElementNS(namespaceURI, name, options) {
1372
- 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);
1373
1381
  return markElement(element);
1374
1382
  };
1375
- Document.prototype.createDocumentFragment = function createDocumentFragment() {
1376
- const element = globalEnv.rawCreateDocumentFragment.call(this);
1383
+ rawRootDocument.prototype.createDocumentFragment = function createDocumentFragment() {
1384
+ const element = globalEnv.rawCreateDocumentFragment.call(getBindTarget(this));
1377
1385
  return markElement(element);
1378
1386
  };
1379
1387
  // query element👇
1380
1388
  function querySelector(selectors) {
1381
1389
  var _a, _b, _c, _d;
1390
+ const _this = getBindTarget(this);
1382
1391
  const currentAppName = getCurrentAppName();
1383
1392
  if (!currentAppName ||
1384
1393
  !((_a = appInstanceMap.get(currentAppName)) === null || _a === void 0 ? void 0 : _a.container) ||
1385
1394
  !selectors ||
1386
1395
  isUniqueElement(selectors) ||
1387
1396
  // see https://github.com/micro-zoe/micro-app/issues/56
1388
- rawDocument !== this) {
1389
- return globalEnv.rawQuerySelector.call(this, selectors);
1397
+ rawDocument !== _this) {
1398
+ return globalEnv.rawQuerySelector.call(_this, selectors);
1390
1399
  }
1391
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;
1392
1401
  }
1393
1402
  function querySelectorAll(selectors) {
1394
1403
  var _a, _b, _c, _d;
1404
+ const _this = getBindTarget(this);
1395
1405
  const currentAppName = getCurrentAppName();
1396
1406
  if (!currentAppName ||
1397
1407
  !((_a = appInstanceMap.get(currentAppName)) === null || _a === void 0 ? void 0 : _a.container) ||
1398
1408
  !selectors ||
1399
1409
  isUniqueElement(selectors) ||
1400
- rawDocument !== this) {
1401
- return globalEnv.rawQuerySelectorAll.call(this, selectors);
1410
+ rawDocument !== _this) {
1411
+ return globalEnv.rawQuerySelectorAll.call(_this, selectors);
1402
1412
  }
1403
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 : [];
1404
1414
  }
1405
- Document.prototype.querySelector = querySelector;
1406
- Document.prototype.querySelectorAll = querySelectorAll;
1407
- 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);
1408
1419
  if (!getCurrentAppName() || isInvalidQuerySelectorKey(key)) {
1409
- return globalEnv.rawGetElementById.call(this, key);
1420
+ return globalEnv.rawGetElementById.call(_this, key);
1410
1421
  }
1411
1422
  try {
1412
- return querySelector.call(this, `#${key}`);
1423
+ return querySelector.call(_this, `#${key}`);
1413
1424
  }
1414
1425
  catch (_a) {
1415
- return globalEnv.rawGetElementById.call(this, key);
1426
+ return globalEnv.rawGetElementById.call(_this, key);
1416
1427
  }
1417
1428
  };
1418
- Document.prototype.getElementsByClassName = function getElementsByClassName(key) {
1429
+ rawRootDocument.prototype.getElementsByClassName = function getElementsByClassName(key) {
1430
+ const _this = getBindTarget(this);
1419
1431
  if (!getCurrentAppName() || isInvalidQuerySelectorKey(key)) {
1420
- return globalEnv.rawGetElementsByClassName.call(this, key);
1432
+ return globalEnv.rawGetElementsByClassName.call(_this, key);
1421
1433
  }
1422
1434
  try {
1423
- return querySelectorAll.call(this, `.${key}`);
1435
+ return querySelectorAll.call(_this, `.${key}`);
1424
1436
  }
1425
1437
  catch (_a) {
1426
- return globalEnv.rawGetElementsByClassName.call(this, key);
1438
+ return globalEnv.rawGetElementsByClassName.call(_this, key);
1427
1439
  }
1428
1440
  };
1429
- Document.prototype.getElementsByTagName = function getElementsByTagName(key) {
1441
+ rawRootDocument.prototype.getElementsByTagName = function getElementsByTagName(key) {
1430
1442
  var _a;
1443
+ const _this = getBindTarget(this);
1431
1444
  const currentAppName = getCurrentAppName();
1432
1445
  if (!currentAppName ||
1433
1446
  isUniqueElement(key) ||
1434
1447
  isInvalidQuerySelectorKey(key) ||
1435
1448
  (!((_a = appInstanceMap.get(currentAppName)) === null || _a === void 0 ? void 0 : _a.inline) && /^script$/i.test(key))) {
1436
- return globalEnv.rawGetElementsByTagName.call(this, key);
1449
+ return globalEnv.rawGetElementsByTagName.call(_this, key);
1437
1450
  }
1438
1451
  try {
1439
- return querySelectorAll.call(this, key);
1452
+ return querySelectorAll.call(_this, key);
1440
1453
  }
1441
1454
  catch (_b) {
1442
- return globalEnv.rawGetElementsByTagName.call(this, key);
1455
+ return globalEnv.rawGetElementsByTagName.call(_this, key);
1443
1456
  }
1444
1457
  };
1445
- Document.prototype.getElementsByName = function getElementsByName(key) {
1458
+ rawRootDocument.prototype.getElementsByName = function getElementsByName(key) {
1459
+ const _this = getBindTarget(this);
1446
1460
  if (!getCurrentAppName() || isInvalidQuerySelectorKey(key)) {
1447
- return globalEnv.rawGetElementsByName.call(this, key);
1461
+ return globalEnv.rawGetElementsByName.call(_this, key);
1448
1462
  }
1449
1463
  try {
1450
- return querySelectorAll.call(this, `[name=${key}]`);
1464
+ return querySelectorAll.call(_this, `[name=${key}]`);
1451
1465
  }
1452
1466
  catch (_a) {
1453
- return globalEnv.rawGetElementsByName.call(this, key);
1467
+ return globalEnv.rawGetElementsByName.call(_this, key);
1454
1468
  }
1455
1469
  };
1456
1470
  }
1457
1471
  /**
1458
1472
  * patchSetAttribute is different from other patch
1459
- * it not dependent on sandbox
1460
- * 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
1461
1476
  */
1462
1477
  let hasRewriteSetAttribute = false;
1463
1478
  function patchSetAttribute() {
@@ -1492,24 +1507,21 @@ function patchSetAttribute() {
1492
1507
  }
1493
1508
  };
1494
1509
  }
1495
- function releasePatchSetAttribute() {
1496
- hasRewriteSetAttribute = false;
1497
- Element.prototype.setAttribute = globalEnv.rawSetAttribute;
1498
- }
1499
1510
  function releasePatchDocument() {
1500
- Document.prototype.createElement = globalEnv.rawCreateElement;
1501
- Document.prototype.createElementNS = globalEnv.rawCreateElementNS;
1502
- Document.prototype.createDocumentFragment = globalEnv.rawCreateDocumentFragment;
1503
- Document.prototype.querySelector = globalEnv.rawQuerySelector;
1504
- Document.prototype.querySelectorAll = globalEnv.rawQuerySelectorAll;
1505
- Document.prototype.getElementById = globalEnv.rawGetElementById;
1506
- Document.prototype.getElementsByClassName = globalEnv.rawGetElementsByClassName;
1507
- Document.prototype.getElementsByTagName = globalEnv.rawGetElementsByTagName;
1508
- 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;
1509
1521
  }
1510
1522
  // release patch
1511
1523
  function releasePatches() {
1512
- setCurrentAppName(null);
1524
+ removeDomScope();
1513
1525
  releasePatchDocument();
1514
1526
  Element.prototype.appendChild = globalEnv.rawAppendChild;
1515
1527
  Element.prototype.insertBefore = globalEnv.rawInsertBefore;
@@ -1519,6 +1531,11 @@ function releasePatches() {
1519
1531
  Element.prototype.prepend = globalEnv.rawPrepend;
1520
1532
  Element.prototype.cloneNode = globalEnv.rawCloneNode;
1521
1533
  }
1534
+ // exec when last child unmount
1535
+ function releasePatchSetAttribute() {
1536
+ hasRewriteSetAttribute = false;
1537
+ Element.prototype.setAttribute = globalEnv.rawSetAttribute;
1538
+ }
1522
1539
  // Set the style of micro-app-head and micro-app-body
1523
1540
  let hasRejectMicroAppStyle = false;
1524
1541
  function rejectMicroAppStyle() {
@@ -1538,6 +1555,10 @@ const globalEnv = {};
1538
1555
  */
1539
1556
  function initGlobalEnv() {
1540
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();
1541
1562
  /**
1542
1563
  * save patch raw methods
1543
1564
  * pay attention to this binding
@@ -1550,15 +1571,15 @@ function initGlobalEnv() {
1550
1571
  const rawAppend = Element.prototype.append;
1551
1572
  const rawPrepend = Element.prototype.prepend;
1552
1573
  const rawCloneNode = Element.prototype.cloneNode;
1553
- const rawCreateElement = Document.prototype.createElement;
1554
- const rawCreateElementNS = Document.prototype.createElementNS;
1555
- const rawCreateDocumentFragment = Document.prototype.createDocumentFragment;
1556
- const rawQuerySelector = Document.prototype.querySelector;
1557
- const rawQuerySelectorAll = Document.prototype.querySelectorAll;
1558
- const rawGetElementById = Document.prototype.getElementById;
1559
- const rawGetElementsByClassName = Document.prototype.getElementsByClassName;
1560
- const rawGetElementsByTagName = Document.prototype.getElementsByTagName;
1561
- 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;
1562
1583
  const ImageProxy = new Proxy(Image, {
1563
1584
  construct(Target, args) {
1564
1585
  const elementImage = new Target(...args);
@@ -1566,9 +1587,6 @@ function initGlobalEnv() {
1566
1587
  return elementImage;
1567
1588
  },
1568
1589
  });
1569
- const rawWindow = Function('return window')();
1570
- const rawDocument = Function('return document')();
1571
- const supportModuleScript = isSupportModuleScript();
1572
1590
  /**
1573
1591
  * save effect raw methods
1574
1592
  * pay attention to this binding, especially setInterval, setTimeout, clearInterval, clearTimeout
@@ -1579,11 +1597,18 @@ function initGlobalEnv() {
1579
1597
  const rawSetTimeout = rawWindow.setTimeout;
1580
1598
  const rawClearInterval = rawWindow.clearInterval;
1581
1599
  const rawClearTimeout = rawWindow.clearTimeout;
1600
+ const rawPushState = rawWindow.history.pushState;
1601
+ const rawReplaceState = rawWindow.history.replaceState;
1582
1602
  const rawDocumentAddEventListener = rawDocument.addEventListener;
1583
1603
  const rawDocumentRemoveEventListener = rawDocument.removeEventListener;
1584
1604
  // mark current application as base application
1585
1605
  window.__MICRO_APP_BASE_APPLICATION__ = true;
1586
1606
  assign(globalEnv, {
1607
+ // common global vars
1608
+ rawWindow,
1609
+ rawDocument,
1610
+ rawRootDocument,
1611
+ supportModuleScript,
1587
1612
  // source/patch
1588
1613
  rawSetAttribute,
1589
1614
  rawAppendChild,
@@ -1603,10 +1628,6 @@ function initGlobalEnv() {
1603
1628
  rawGetElementsByTagName,
1604
1629
  rawGetElementsByName,
1605
1630
  ImageProxy,
1606
- // common global vars
1607
- rawWindow,
1608
- rawDocument,
1609
- supportModuleScript,
1610
1631
  // sandbox/effect
1611
1632
  rawWindowAddEventListener,
1612
1633
  rawWindowRemoveEventListener,
@@ -1616,6 +1637,8 @@ function initGlobalEnv() {
1616
1637
  rawClearTimeout,
1617
1638
  rawDocumentAddEventListener,
1618
1639
  rawDocumentRemoveEventListener,
1640
+ rawPushState,
1641
+ rawReplaceState,
1619
1642
  });
1620
1643
  // global effect
1621
1644
  rejectMicroAppStyle();
@@ -1836,6 +1859,13 @@ function runDynamicRemoteScript(url, info, app, originScript) {
1836
1859
  if (app.source.scripts.has(url)) {
1837
1860
  const existInfo = app.source.scripts.get(url);
1838
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
+ */
1839
1869
  return runScript(url, app, existInfo, true, dispatchScriptOnLoadEvent);
1840
1870
  }
1841
1871
  if (globalScripts.has(url)) {
@@ -2654,7 +2684,8 @@ function effect(appName, microAppWindow) {
2654
2684
  }
2655
2685
 
2656
2686
  // set micro app state to origin state
2657
- function setMicroState(appName, rawState, microState) {
2687
+ function setMicroState(appName, microState) {
2688
+ const rawState = globalEnv.rawWindow.history.state;
2658
2689
  const additionalState = {
2659
2690
  microAppState: assign({}, rawState === null || rawState === void 0 ? void 0 : rawState.microAppState, {
2660
2691
  [appName]: microState
@@ -2677,9 +2708,9 @@ function removeMicroState(appName, rawState) {
2677
2708
  return assign({}, rawState);
2678
2709
  }
2679
2710
  // get micro app state form origin state
2680
- function getMicroState(appName, state) {
2681
- var _a;
2682
- 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;
2683
2714
  }
2684
2715
  const ENC_AD_RE = /&/g; // %M1
2685
2716
  const ENC_EQ_RE = /=/g; // %M2
@@ -2704,7 +2735,8 @@ function commonDecode(path) {
2704
2735
  }
2705
2736
  // 格式化query参数key,防止与原有参数的冲突
2706
2737
  function formatQueryAppName(appName) {
2707
- return `app-${appName}`;
2738
+ // return `app-${appName}`
2739
+ return appName;
2708
2740
  }
2709
2741
  // 根据浏览器url参数,获取当前子应用的path
2710
2742
  function getMicroPathFromURL(appName) {
@@ -2827,7 +2859,7 @@ function addHistoryListener(appName) {
2827
2859
  isHashChange = proxyWindow.location.hash !== oldHash;
2828
2860
  }
2829
2861
  // dispatch formatted popStateEvent to child
2830
- dispatchPopStateEventToMicroApp(appName, proxyWindow, rawWindow.history.state);
2862
+ dispatchPopStateEventToMicroApp(appName, proxyWindow);
2831
2863
  // dispatch formatted hashChangeEvent to child when hash change
2832
2864
  if (isHashChange)
2833
2865
  dispatchHashChangeEventToMicroApp(appName, proxyWindow, oldHref);
@@ -2846,9 +2878,9 @@ function addHistoryListener(appName) {
2846
2878
  * @param proxyWindow sandbox window
2847
2879
  * @param eventState history.state
2848
2880
  */
2849
- function dispatchPopStateEventToMicroApp(appName, proxyWindow, eventState) {
2881
+ function dispatchPopStateEventToMicroApp(appName, proxyWindow) {
2850
2882
  // create PopStateEvent named popstate-appName with sub app state
2851
- const newPopStateEvent = new PopStateEvent(formatEventName$1('popstate', appName), { state: getMicroState(appName, eventState) });
2883
+ const newPopStateEvent = new PopStateEvent(formatEventName$1('popstate', appName), { state: getMicroState(appName) });
2852
2884
  globalEnv.rawWindow.dispatchEvent(newPopStateEvent);
2853
2885
  // call function window.onpopstate if it exists
2854
2886
  typeof proxyWindow.onpopstate === 'function' && proxyWindow.onpopstate(newPopStateEvent);
@@ -2916,19 +2948,15 @@ function createMicroHistory(appName, microLocation) {
2916
2948
  if (isString(rests[2]) || isURL(rests[2])) {
2917
2949
  const targetLocation = createURL(rests[2], microLocation.href);
2918
2950
  if (targetLocation.origin === microLocation.origin) {
2919
- 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]);
2920
2952
  const targetFullPath = targetLocation.pathname + targetLocation.search + targetLocation.hash;
2921
2953
  if (targetFullPath !== microLocation.fullPath) {
2922
2954
  updateMicroLocation(appName, targetFullPath, microLocation);
2923
2955
  }
2956
+ return void 0;
2924
2957
  }
2925
- else {
2926
- rawHistory[methodName].apply(rawHistory, rests);
2927
- }
2928
- }
2929
- else {
2930
- rawHistory[methodName].apply(rawHistory, rests);
2931
2958
  }
2959
+ nativeHistoryNavigate(methodName, rests[2], rests[0], rests[1]);
2932
2960
  };
2933
2961
  }
2934
2962
  const pushState = getMicroHistoryMethod('pushState');
@@ -2936,7 +2964,7 @@ function createMicroHistory(appName, microLocation) {
2936
2964
  return new Proxy(rawHistory, {
2937
2965
  get(target, key) {
2938
2966
  if (key === 'state') {
2939
- return getMicroState(appName, rawHistory.state);
2967
+ return getMicroState(appName);
2940
2968
  }
2941
2969
  else if (key === 'pushState') {
2942
2970
  return pushState;
@@ -2957,7 +2985,8 @@ function createMicroHistory(appName, microLocation) {
2957
2985
  * @param title history.title, default is ''
2958
2986
  */
2959
2987
  function nativeHistoryNavigate(methodName, fullPath, state = null, title = '') {
2960
- 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);
2961
2990
  }
2962
2991
  /**
2963
2992
  * Navigate to new path, and dispatch native popStateEvent/hashChangeEvent to browser
@@ -2992,10 +3021,10 @@ function attachRouteToBrowserURL(result, state) {
2992
3021
  }
2993
3022
  /**
2994
3023
  * When path is same, keep the microAppState in history.state
2995
- * Fix bug of missing microAppState in next.js & angular
3024
+ * Fix bug of missing microAppState when base app is next.js or angular
2996
3025
  * @param method history.pushState/replaceState
2997
3026
  */
2998
- function patchHistoryState(method) {
3027
+ function reWriteHistoryMethod(method) {
2999
3028
  const rawWindow = globalEnv.rawWindow;
3000
3029
  return function (...rests) {
3001
3030
  var _a;
@@ -3011,22 +3040,38 @@ function patchHistoryState(method) {
3011
3040
  }
3012
3041
  }
3013
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();
3014
3059
  };
3015
3060
  }
3016
- let isReWriteHistoryState = false;
3017
3061
  /**
3018
3062
  * rewrite history.pushState/replaceState
3019
3063
  * used to fix the problem that the microAppState maybe missing when mainApp navigate to same path
3020
3064
  * e.g: when nextjs, angular receive popstate event, they will use history.replaceState to update browser url with a new state object
3021
3065
  */
3022
- function rewriteHistoryState() {
3023
- // filter nest app
3024
- if (!isReWriteHistoryState && !window.__MICRO_APP_ENVIRONMENT__) {
3025
- isReWriteHistoryState = true;
3026
- const rawWindow = globalEnv.rawWindow;
3027
- rawWindow.history.pushState = patchHistoryState(rawWindow.history.pushState);
3028
- rawWindow.history.replaceState = patchHistoryState(rawWindow.history.replaceState);
3029
- }
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;
3030
3075
  }
3031
3076
 
3032
3077
  function createRouterApi() {
@@ -3038,7 +3083,7 @@ function createRouterApi() {
3038
3083
  * @param state to.state
3039
3084
  */
3040
3085
  function navigateWithRawHistory(appName, methodName, targetLocation, state) {
3041
- 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));
3042
3087
  // clear element scope after navigate
3043
3088
  removeDomScope();
3044
3089
  }
@@ -3142,7 +3187,7 @@ function createRouterApi() {
3142
3187
  function commonHandlerForAttachToURL(appName) {
3143
3188
  const app = appInstanceMap.get(appName);
3144
3189
  if (app.sandBox && app.useMemoryRouter) {
3145
- attachRouteToBrowserURL(setMicroPathToURL(appName, app.sandBox.proxyWindow.location), setMicroState(appName, globalEnv.rawWindow.history.state, null));
3190
+ attachRouteToBrowserURL(setMicroPathToURL(appName, app.sandBox.proxyWindow.location), setMicroState(appName, getMicroState(appName)));
3146
3191
  }
3147
3192
  }
3148
3193
  /**
@@ -3157,9 +3202,10 @@ function createRouterApi() {
3157
3202
  }
3158
3203
  /**
3159
3204
  * Attach all active app router info to browser url
3205
+ * exclude hidden keep-alive app
3160
3206
  */
3161
- function attachAllToURL() {
3162
- getActiveApps().forEach(appName => commonHandlerForAttachToURL(appName));
3207
+ function attachAllToURL(includeHiddenApp = false) {
3208
+ getActiveApps(!includeHiddenApp).forEach(appName => commonHandlerForAttachToURL(appName));
3163
3209
  }
3164
3210
  function createDefaultPageApi() {
3165
3211
  // defaultPage data
@@ -3439,7 +3485,6 @@ function updateMicroLocation(appName, path, microLocation, type) {
3439
3485
  * @returns MicroRouter
3440
3486
  */
3441
3487
  function createMicroRouter(appName, url) {
3442
- rewriteHistoryState();
3443
3488
  const microLocation = createMicroLocation(appName, url);
3444
3489
  return {
3445
3490
  microLocation,
@@ -3465,7 +3510,7 @@ function updateBrowserURLWithLocation(appName, microLocation, defaultPage) {
3465
3510
  if (defaultPage)
3466
3511
  updateMicroLocation(appName, defaultPage, microLocation, 'prevent');
3467
3512
  // attach microApp route info to browser URL
3468
- attachRouteToBrowserURL(setMicroPathToURL(appName, microLocation), setMicroState(appName, globalEnv.rawWindow.history.state, null));
3513
+ attachRouteToBrowserURL(setMicroPathToURL(appName, microLocation), setMicroState(appName, null));
3469
3514
  // trigger guards after change browser URL
3470
3515
  autoTriggerNavigationGuard(appName, microLocation);
3471
3516
  }
@@ -3640,6 +3685,7 @@ class SandBox {
3640
3685
  effectDocumentEvent();
3641
3686
  patchElementPrototypeMethods();
3642
3687
  initEnvOfNestedApp();
3688
+ patchHistory();
3643
3689
  }
3644
3690
  fixBabelPolyfill6();
3645
3691
  }
@@ -3673,6 +3719,7 @@ class SandBox {
3673
3719
  if (--SandBox.activeCount === 0) {
3674
3720
  releaseEffectDocumentEvent();
3675
3721
  releasePatches();
3722
+ releasePatchHistory();
3676
3723
  }
3677
3724
  this.active = false;
3678
3725
  }
@@ -3841,15 +3888,26 @@ class SandBox {
3841
3888
  this.setMicroAppRouter(microAppWindow, appName, url);
3842
3889
  }
3843
3890
  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;
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
+ },
3852
3901
  },
3902
+ Document: {
3903
+ configurable: false,
3904
+ enumerable: false,
3905
+ get() {
3906
+ throttleDeferForSetAppName(appName);
3907
+ // return globalEnv.rawRootDocument
3908
+ return MicroDocument;
3909
+ },
3910
+ }
3853
3911
  });
3854
3912
  }
3855
3913
  // properties associated with the native window
@@ -3991,23 +4049,62 @@ class SandBox {
3991
4049
  removeRouteInfoForKeepAliveApp() {
3992
4050
  removeStateAndPathFromBrowser(this.proxyWindow.__MICRO_APP_NAME__);
3993
4051
  }
4052
+ /**
4053
+ * Create new document and Document
4054
+ */
3994
4055
  createProxyDocument(appName) {
4056
+ const rawDocument = globalEnv.rawDocument;
4057
+ const rawRootDocument = globalEnv.rawRootDocument;
3995
4058
  const createElement = function (tagName, options) {
3996
- const element = globalEnv.rawCreateElement.call(globalEnv.rawDocument, tagName, options);
4059
+ const element = globalEnv.rawCreateElement.call(rawDocument, tagName, options);
3997
4060
  element.__MICRO_APP_NAME__ = appName;
3998
4061
  return element;
3999
4062
  };
4000
- const proxyDocument = new Proxy(globalEnv.rawDocument, {
4063
+ const proxyDocument = new Proxy(rawDocument, {
4001
4064
  get(target, key) {
4002
4065
  throttleDeferForSetAppName(appName);
4003
4066
  throttleDeferForParentNode(proxyDocument);
4004
4067
  if (key === 'createElement')
4005
4068
  return createElement;
4069
+ if (key === Symbol.toStringTag)
4070
+ return 'ProxyDocument';
4006
4071
  const rawValue = Reflect.get(target, key);
4007
- return isFunction(rawValue) ? bindFunctionToRawObject(target, rawValue, 'DOCUMENT') : rawValue;
4072
+ return isFunction(rawValue) ? bindFunctionToRawObject(rawDocument, rawValue, 'DOCUMENT') : rawValue;
4008
4073
  },
4009
4074
  });
4010
- return proxyDocument;
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
+ };
4011
4108
  }
4012
4109
  }
4013
4110
  SandBox.activeCount = 0; // number of active sandbox
@@ -4076,7 +4173,7 @@ function dispatchCustomEventToMicroApp(eventName, appName, detail = {}) {
4076
4173
  // micro app instances
4077
4174
  const appInstanceMap = new Map();
4078
4175
  class CreateApp {
4079
- 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, }) {
4080
4177
  this.state = appStates.CREATED;
4081
4178
  this.keepAliveState = null;
4082
4179
  this.keepAliveContainer = null;
@@ -4089,17 +4186,18 @@ class CreateApp {
4089
4186
  this.prefetchResolve = null;
4090
4187
  this.container = null;
4091
4188
  this.sandBox = null;
4092
- this.container = container !== null && container !== void 0 ? container : null;
4093
- this.inline = inline !== null && inline !== void 0 ? inline : false;
4094
- this.baseroute = baseroute !== null && baseroute !== void 0 ? baseroute : '';
4095
- this.keepRouteState = keepRouteState !== null && keepRouteState !== void 0 ? keepRouteState : false;
4096
- this.ssrUrl = ssrUrl !== null && ssrUrl !== void 0 ? ssrUrl : '';
4097
- // optional during init👆
4098
4189
  this.name = name;
4099
4190
  this.url = url;
4100
4191
  this.useSandbox = useSandbox;
4101
4192
  this.scopecss = this.useSandbox && scopecss;
4102
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;
4103
4201
  this.defaultPage = defaultPage !== null && defaultPage !== void 0 ? defaultPage : '';
4104
4202
  this.source = {
4105
4203
  links: new Map(),
@@ -4152,16 +4250,14 @@ class CreateApp {
4152
4250
  * @param baseroute route prefix, default is ''
4153
4251
  * @param keepRouteState keep route state when unmount, default is false
4154
4252
  */
4155
- mount(container, inline, baseroute, keepRouteState, defaultPage) {
4253
+ mount(container, inline, baseroute, keepRouteState, defaultPage, hiddenRouter) {
4156
4254
  var _a, _b, _c;
4157
- if (isBoolean(inline))
4158
- this.inline = inline;
4159
- // keepRouteState effective on unmount
4160
- if (isBoolean(keepRouteState))
4161
- 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;
4162
4257
  this.container = (_a = this.container) !== null && _a !== void 0 ? _a : container;
4163
4258
  this.baseroute = baseroute !== null && baseroute !== void 0 ? baseroute : this.baseroute;
4164
4259
  this.defaultPage = defaultPage !== null && defaultPage !== void 0 ? defaultPage : this.defaultPage;
4260
+ this.hiddenRouter = hiddenRouter !== null && hiddenRouter !== void 0 ? hiddenRouter : this.hiddenRouter;
4165
4261
  if (this.loadSourceLevel !== 2) {
4166
4262
  this.state = appStates.LOADING;
4167
4263
  return;
@@ -4436,6 +4532,7 @@ function defineElement(tagName) {
4436
4532
  this.setAttribute('name', this.appName);
4437
4533
  }
4438
4534
  };
4535
+ // patchSetAttribute hijiack data attribute, it needs exec first
4439
4536
  patchSetAttribute();
4440
4537
  }
4441
4538
  static get observedAttributes() {
@@ -4612,7 +4709,7 @@ function defineElement(tagName) {
4612
4709
  app.isPrefetch = false;
4613
4710
  defer(() => {
4614
4711
  var _a;
4615
- 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'));
4616
4713
  });
4617
4714
  }
4618
4715
  // create app instance
@@ -4631,12 +4728,13 @@ function defineElement(tagName) {
4631
4728
  ssrUrl: this.ssrUrl,
4632
4729
  container: (_a = this.shadowRoot) !== null && _a !== void 0 ? _a : this,
4633
4730
  inline: this.getDisposeResult('inline'),
4634
- scopecss: !(this.getDisposeResult('disableScopecss') || this.getDisposeResult('shadowDOM')),
4635
- useSandbox: !this.getDisposeResult('disableSandbox'),
4731
+ scopecss: !(this.getDisposeResult('disable-scopecss') || this.getDisposeResult('shadowDOM')),
4732
+ useSandbox: !this.getDisposeResult('disable-sandbox'),
4636
4733
  useMemoryRouter: !this.getDisposeResult('disable-memory-router'),
4637
4734
  baseroute: this.getBaseRouteCompatible(),
4638
4735
  keepRouteState: this.getDisposeResult('keep-router-state'),
4639
4736
  defaultPage: this.getDefaultPageValue(),
4737
+ hiddenRouter: this.getDisposeResult('hidden-router'),
4640
4738
  });
4641
4739
  appInstanceMap.set(this.appName, instance);
4642
4740
  }
@@ -4671,25 +4769,25 @@ function defineElement(tagName) {
4671
4769
  */
4672
4770
  getDisposeResult(name) {
4673
4771
  // @ts-ignore
4674
- return (this.compatibleSpecialProperties(name) || microApp[name]) && this.compatibleDisableSpecialProperties(name);
4772
+ return (this.compatibleSpecialProperties(name) || !!microApp[name]) && this.compatibleDisableSpecialProperties(name);
4675
4773
  }
4676
4774
  // compatible of disableScopecss & disableSandbox
4677
4775
  compatibleSpecialProperties(name) {
4678
- if (name === 'disableScopecss') {
4679
- return this.hasAttribute('disableScopecss') || this.hasAttribute('disable-scopecss');
4776
+ if (name === 'disable-scopecss') {
4777
+ return this.hasAttribute('disable-scopecss') || this.hasAttribute('disableScopecss');
4680
4778
  }
4681
- else if (name === 'disableSandbox') {
4682
- return this.hasAttribute('disableSandbox') || this.hasAttribute('disable-sandbox');
4779
+ else if (name === 'disable-sandbox') {
4780
+ return this.hasAttribute('disable-sandbox') || this.hasAttribute('disableSandbox');
4683
4781
  }
4684
4782
  return this.hasAttribute(name);
4685
4783
  }
4686
4784
  // compatible of disableScopecss & disableSandbox
4687
4785
  compatibleDisableSpecialProperties(name) {
4688
- if (name === 'disableScopecss') {
4689
- 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';
4690
4788
  }
4691
- else if (name === 'disableSandbox') {
4692
- 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';
4693
4791
  }
4694
4792
  return this.getAttribute(name) !== 'false';
4695
4793
  }
@@ -4801,7 +4899,7 @@ function preFetch(apps) {
4801
4899
  function preFetchInSerial(prefetchApp) {
4802
4900
  return new Promise((resolve) => {
4803
4901
  requestIdleCallback(() => {
4804
- var _a, _b, _c;
4902
+ var _a, _b, _c, _d, _e;
4805
4903
  if (isPlainObject(prefetchApp) && navigator.onLine) {
4806
4904
  prefetchApp.name = formatAppName(prefetchApp.name);
4807
4905
  prefetchApp.url = formatAppURL(prefetchApp.url, prefetchApp.name);
@@ -4809,9 +4907,9 @@ function preFetchInSerial(prefetchApp) {
4809
4907
  const app = new CreateApp({
4810
4908
  name: prefetchApp.name,
4811
4909
  url: prefetchApp.url,
4812
- scopecss: !((_a = prefetchApp.disableScopecss) !== null && _a !== void 0 ? _a : microApp.disableScopecss),
4813
- useSandbox: !((_b = prefetchApp.disableSandbox) !== null && _b !== void 0 ? _b : microApp.disableSandbox),
4814
- 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']),
4815
4913
  });
4816
4914
  app.isPrefetch = true;
4817
4915
  app.prefetchResolve = resolve;
@@ -4861,7 +4959,7 @@ function fetchGlobalResources(resources, suffix, cache) {
4861
4959
  * @param excludeHiddenApp exclude hidden keep-alive app, default is false
4862
4960
  * @returns active apps
4863
4961
  */
4864
- function getActiveApps(excludeHiddenApp) {
4962
+ function getActiveApps(excludeHiddenApp = false) {
4865
4963
  const activeApps = [];
4866
4964
  appInstanceMap.forEach((app, appName) => {
4867
4965
  if (appStates.UNMOUNT !== app.getAppState() &&
@@ -4957,6 +5055,7 @@ class MicroApp extends EventCenterForBaseApp {
4957
5055
  this.router = router;
4958
5056
  }
4959
5057
  start(options) {
5058
+ var _a, _b;
4960
5059
  if (!isBrowser || !window.customElements) {
4961
5060
  return logError('micro-app is not supported in this environment');
4962
5061
  }
@@ -4982,9 +5081,12 @@ class MicroApp extends EventCenterForBaseApp {
4982
5081
  // @ts-ignore
4983
5082
  this.destory = options.destory;
4984
5083
  this.inline = options.inline;
4985
- this.disableScopecss = options.disableScopecss;
4986
- this.disableSandbox = options.disableSandbox;
4987
- 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;
4988
5090
  this.ssr = options.ssr;
4989
5091
  isFunction(options.fetch) && (this.fetch = options.fetch);
4990
5092
  isPlainObject(options.lifeCycles) && (this.lifeCycles = options.lifeCycles);