@micro-zoe/micro-app 0.6.0 → 0.6.1
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/README.zh-cn.md +2 -2
- package/lib/index.d.ts +13 -1
- package/lib/index.esm.js +486 -364
- package/lib/index.esm.js.map +1 -1
- package/lib/index.min.js +1 -1
- package/lib/index.min.js.map +1 -1
- package/lib/index.umd.js +1 -1
- package/lib/index.umd.js.map +1 -1
- package/package.json +2 -3
- package/polyfill/jsx-custom-event.js.map +1 -1
package/lib/index.esm.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
const version = '0.6.
|
|
1
|
+
const version = '0.6.1';
|
|
2
2
|
// do not use isUndefined
|
|
3
3
|
const isBrowser = typeof window !== 'undefined';
|
|
4
4
|
// do not use isUndefined
|
|
@@ -350,12 +350,13 @@ function initGlobalEnv() {
|
|
|
350
350
|
* pay attention to this binding
|
|
351
351
|
*/
|
|
352
352
|
const rawSetAttribute = Element.prototype.setAttribute;
|
|
353
|
-
const rawAppendChild =
|
|
354
|
-
const rawInsertBefore =
|
|
355
|
-
const rawReplaceChild =
|
|
356
|
-
const rawRemoveChild =
|
|
353
|
+
const rawAppendChild = Element.prototype.appendChild;
|
|
354
|
+
const rawInsertBefore = Element.prototype.insertBefore;
|
|
355
|
+
const rawReplaceChild = Element.prototype.replaceChild;
|
|
356
|
+
const rawRemoveChild = Element.prototype.removeChild;
|
|
357
357
|
const rawAppend = Element.prototype.append;
|
|
358
358
|
const rawPrepend = Element.prototype.prepend;
|
|
359
|
+
const rawCloneNode = Element.prototype.cloneNode;
|
|
359
360
|
const rawCreateElement = Document.prototype.createElement;
|
|
360
361
|
const rawCreateElementNS = Document.prototype.createElementNS;
|
|
361
362
|
const rawCreateDocumentFragment = Document.prototype.createDocumentFragment;
|
|
@@ -392,6 +393,7 @@ function initGlobalEnv() {
|
|
|
392
393
|
rawRemoveChild,
|
|
393
394
|
rawAppend,
|
|
394
395
|
rawPrepend,
|
|
396
|
+
rawCloneNode,
|
|
395
397
|
rawCreateElement,
|
|
396
398
|
rawCreateElementNS,
|
|
397
399
|
rawCreateDocumentFragment,
|
|
@@ -1190,307 +1192,6 @@ function extractHtml(app) {
|
|
|
1190
1192
|
});
|
|
1191
1193
|
}
|
|
1192
1194
|
|
|
1193
|
-
const boundedMap = new WeakMap();
|
|
1194
|
-
function isBoundedFunction(value) {
|
|
1195
|
-
if (boundedMap.has(value)) {
|
|
1196
|
-
return boundedMap.get(value);
|
|
1197
|
-
}
|
|
1198
|
-
// bind function
|
|
1199
|
-
const boundFunction = isBoundFunction(value);
|
|
1200
|
-
boundedMap.set(value, boundFunction);
|
|
1201
|
-
return boundFunction;
|
|
1202
|
-
}
|
|
1203
|
-
const constructorMap = new WeakMap();
|
|
1204
|
-
function isConstructor(value) {
|
|
1205
|
-
if (constructorMap.has(value)) {
|
|
1206
|
-
return constructorMap.get(value);
|
|
1207
|
-
}
|
|
1208
|
-
const valueStr = value.toString();
|
|
1209
|
-
const result = (value.prototype &&
|
|
1210
|
-
value.prototype.constructor === value &&
|
|
1211
|
-
Object.getOwnPropertyNames(value.prototype).length > 1) ||
|
|
1212
|
-
/^function\s+[A-Z]/.test(valueStr) ||
|
|
1213
|
-
/^class\s+/.test(valueStr);
|
|
1214
|
-
constructorMap.set(value, result);
|
|
1215
|
-
return result;
|
|
1216
|
-
}
|
|
1217
|
-
const rawWindowMethodMap = new WeakMap();
|
|
1218
|
-
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
|
|
1219
|
-
function bindFunctionToRawWidow(rawWindow, value) {
|
|
1220
|
-
if (rawWindowMethodMap.has(value)) {
|
|
1221
|
-
return rawWindowMethodMap.get(value);
|
|
1222
|
-
}
|
|
1223
|
-
if (isFunction(value) && !isConstructor(value) && !isBoundedFunction(value)) {
|
|
1224
|
-
const bindRawWindowValue = value.bind(rawWindow);
|
|
1225
|
-
for (const key in value) {
|
|
1226
|
-
bindRawWindowValue[key] = value[key];
|
|
1227
|
-
}
|
|
1228
|
-
if (value.hasOwnProperty('prototype') && !bindRawWindowValue.hasOwnProperty('prototype')) {
|
|
1229
|
-
bindRawWindowValue.prototype = value.prototype;
|
|
1230
|
-
}
|
|
1231
|
-
rawWindowMethodMap.set(value, bindRawWindowValue);
|
|
1232
|
-
return bindRawWindowValue;
|
|
1233
|
-
}
|
|
1234
|
-
return value;
|
|
1235
|
-
}
|
|
1236
|
-
|
|
1237
|
-
// document.onclick binding list, the binding function of each application is unique
|
|
1238
|
-
const documentClickListMap = new Map();
|
|
1239
|
-
let hasRewriteDocumentOnClick = false;
|
|
1240
|
-
/**
|
|
1241
|
-
* Rewrite document.onclick and execute it only once
|
|
1242
|
-
*/
|
|
1243
|
-
function overwriteDocumentOnClick() {
|
|
1244
|
-
hasRewriteDocumentOnClick = true;
|
|
1245
|
-
if (Object.getOwnPropertyDescriptor(document, 'onclick')) {
|
|
1246
|
-
return logWarn('Cannot redefine document property onclick');
|
|
1247
|
-
}
|
|
1248
|
-
const rawOnClick = document.onclick;
|
|
1249
|
-
document.onclick = null;
|
|
1250
|
-
let hasDocumentClickInited = false;
|
|
1251
|
-
function onClickHandler(e) {
|
|
1252
|
-
documentClickListMap.forEach((f) => {
|
|
1253
|
-
isFunction(f) && f.call(document, e);
|
|
1254
|
-
});
|
|
1255
|
-
}
|
|
1256
|
-
Object.defineProperty(document, 'onclick', {
|
|
1257
|
-
configurable: true,
|
|
1258
|
-
enumerable: true,
|
|
1259
|
-
get() {
|
|
1260
|
-
const appName = getCurrentAppName();
|
|
1261
|
-
return appName ? documentClickListMap.get(appName) : documentClickListMap.get('base');
|
|
1262
|
-
},
|
|
1263
|
-
set(f) {
|
|
1264
|
-
const appName = getCurrentAppName();
|
|
1265
|
-
if (appName) {
|
|
1266
|
-
documentClickListMap.set(appName, f);
|
|
1267
|
-
}
|
|
1268
|
-
else {
|
|
1269
|
-
documentClickListMap.set('base', f);
|
|
1270
|
-
}
|
|
1271
|
-
if (!hasDocumentClickInited && isFunction(f)) {
|
|
1272
|
-
hasDocumentClickInited = true;
|
|
1273
|
-
globalEnv.rawDocumentAddEventListener.call(globalEnv.rawDocument, 'click', onClickHandler, false);
|
|
1274
|
-
}
|
|
1275
|
-
}
|
|
1276
|
-
});
|
|
1277
|
-
rawOnClick && (document.onclick = rawOnClick);
|
|
1278
|
-
}
|
|
1279
|
-
/**
|
|
1280
|
-
* The document event is globally, we need to clear these event bindings when micro application unmounted
|
|
1281
|
-
*/
|
|
1282
|
-
const documentEventListenerMap = new Map();
|
|
1283
|
-
function effectDocumentEvent() {
|
|
1284
|
-
const { rawDocument, rawDocumentAddEventListener, rawDocumentRemoveEventListener, } = globalEnv;
|
|
1285
|
-
!hasRewriteDocumentOnClick && overwriteDocumentOnClick();
|
|
1286
|
-
document.addEventListener = function (type, listener, options) {
|
|
1287
|
-
var _a;
|
|
1288
|
-
const appName = getCurrentAppName();
|
|
1289
|
-
/**
|
|
1290
|
-
* ignore bound function of document event in umd mode, used to solve problem of react global events
|
|
1291
|
-
*/
|
|
1292
|
-
if (appName && !(((_a = appInstanceMap.get(appName)) === null || _a === void 0 ? void 0 : _a.umdMode) && isBoundFunction(listener))) {
|
|
1293
|
-
const appListenersMap = documentEventListenerMap.get(appName);
|
|
1294
|
-
if (appListenersMap) {
|
|
1295
|
-
const appListenerList = appListenersMap.get(type);
|
|
1296
|
-
if (appListenerList) {
|
|
1297
|
-
appListenerList.add(listener);
|
|
1298
|
-
}
|
|
1299
|
-
else {
|
|
1300
|
-
appListenersMap.set(type, new Set([listener]));
|
|
1301
|
-
}
|
|
1302
|
-
}
|
|
1303
|
-
else {
|
|
1304
|
-
documentEventListenerMap.set(appName, new Map([[type, new Set([listener])]]));
|
|
1305
|
-
}
|
|
1306
|
-
listener && (listener.__MICRO_MARK_OPTIONS__ = options);
|
|
1307
|
-
}
|
|
1308
|
-
rawDocumentAddEventListener.call(rawDocument, type, listener, options);
|
|
1309
|
-
};
|
|
1310
|
-
document.removeEventListener = function (type, listener, options) {
|
|
1311
|
-
var _a;
|
|
1312
|
-
const appName = getCurrentAppName();
|
|
1313
|
-
if (appName && !(((_a = appInstanceMap.get(appName)) === null || _a === void 0 ? void 0 : _a.umdMode) && isBoundFunction(listener))) {
|
|
1314
|
-
const appListenersMap = documentEventListenerMap.get(appName);
|
|
1315
|
-
if (appListenersMap) {
|
|
1316
|
-
const appListenerList = appListenersMap.get(type);
|
|
1317
|
-
if ((appListenerList === null || appListenerList === void 0 ? void 0 : appListenerList.size) && appListenerList.has(listener)) {
|
|
1318
|
-
appListenerList.delete(listener);
|
|
1319
|
-
}
|
|
1320
|
-
}
|
|
1321
|
-
}
|
|
1322
|
-
rawDocumentRemoveEventListener.call(rawDocument, type, listener, options);
|
|
1323
|
-
};
|
|
1324
|
-
}
|
|
1325
|
-
// Clear the document event agent
|
|
1326
|
-
function releaseEffectDocumentEvent() {
|
|
1327
|
-
document.addEventListener = globalEnv.rawDocumentAddEventListener;
|
|
1328
|
-
document.removeEventListener = globalEnv.rawDocumentRemoveEventListener;
|
|
1329
|
-
}
|
|
1330
|
-
// this events should be sent to the specified app
|
|
1331
|
-
const formatEventList = ['unmount', 'appstate-change'];
|
|
1332
|
-
/**
|
|
1333
|
-
* Format event name
|
|
1334
|
-
* @param type event name
|
|
1335
|
-
* @param microWindow micro window
|
|
1336
|
-
*/
|
|
1337
|
-
function formatEventType(type, microWindow) {
|
|
1338
|
-
if (formatEventList.includes(type)) {
|
|
1339
|
-
return `${type}-${microWindow.__MICRO_APP_NAME__}`;
|
|
1340
|
-
}
|
|
1341
|
-
return type;
|
|
1342
|
-
}
|
|
1343
|
-
/**
|
|
1344
|
-
* Rewrite side-effect events
|
|
1345
|
-
* @param microWindow micro window
|
|
1346
|
-
*/
|
|
1347
|
-
function effect(microWindow) {
|
|
1348
|
-
const appName = microWindow.__MICRO_APP_NAME__;
|
|
1349
|
-
const eventListenerMap = new Map();
|
|
1350
|
-
const intervalIdMap = new Map();
|
|
1351
|
-
const timeoutIdMap = new Map();
|
|
1352
|
-
const { rawWindow, rawDocument, rawWindowAddEventListener, rawWindowRemoveEventListener, rawSetInterval, rawSetTimeout, rawClearInterval, rawClearTimeout, rawDocumentRemoveEventListener, } = globalEnv;
|
|
1353
|
-
// listener may be null, e.g test-passive
|
|
1354
|
-
microWindow.addEventListener = function (type, listener, options) {
|
|
1355
|
-
type = formatEventType(type, microWindow);
|
|
1356
|
-
const listenerList = eventListenerMap.get(type);
|
|
1357
|
-
if (listenerList) {
|
|
1358
|
-
listenerList.add(listener);
|
|
1359
|
-
}
|
|
1360
|
-
else {
|
|
1361
|
-
eventListenerMap.set(type, new Set([listener]));
|
|
1362
|
-
}
|
|
1363
|
-
listener && (listener.__MICRO_MARK_OPTIONS__ = options);
|
|
1364
|
-
rawWindowAddEventListener.call(rawWindow, type, listener, options);
|
|
1365
|
-
};
|
|
1366
|
-
microWindow.removeEventListener = function (type, listener, options) {
|
|
1367
|
-
type = formatEventType(type, microWindow);
|
|
1368
|
-
const listenerList = eventListenerMap.get(type);
|
|
1369
|
-
if ((listenerList === null || listenerList === void 0 ? void 0 : listenerList.size) && listenerList.has(listener)) {
|
|
1370
|
-
listenerList.delete(listener);
|
|
1371
|
-
}
|
|
1372
|
-
rawWindowRemoveEventListener.call(rawWindow, type, listener, options);
|
|
1373
|
-
};
|
|
1374
|
-
microWindow.setInterval = function (handler, timeout, ...args) {
|
|
1375
|
-
const intervalId = rawSetInterval.call(rawWindow, handler, timeout, ...args);
|
|
1376
|
-
intervalIdMap.set(intervalId, { handler, timeout, args });
|
|
1377
|
-
return intervalId;
|
|
1378
|
-
};
|
|
1379
|
-
microWindow.setTimeout = function (handler, timeout, ...args) {
|
|
1380
|
-
const timeoutId = rawSetTimeout.call(rawWindow, handler, timeout, ...args);
|
|
1381
|
-
timeoutIdMap.set(timeoutId, { handler, timeout, args });
|
|
1382
|
-
return timeoutId;
|
|
1383
|
-
};
|
|
1384
|
-
microWindow.clearInterval = function (intervalId) {
|
|
1385
|
-
intervalIdMap.delete(intervalId);
|
|
1386
|
-
rawClearInterval.call(rawWindow, intervalId);
|
|
1387
|
-
};
|
|
1388
|
-
microWindow.clearTimeout = function (timeoutId) {
|
|
1389
|
-
timeoutIdMap.delete(timeoutId);
|
|
1390
|
-
rawClearTimeout.call(rawWindow, timeoutId);
|
|
1391
|
-
};
|
|
1392
|
-
const umdWindowListenerMap = new Map();
|
|
1393
|
-
const umdDocumentListenerMap = new Map();
|
|
1394
|
-
let umdIntervalIdMap = new Map();
|
|
1395
|
-
let umdTimeoutIdMap = new Map();
|
|
1396
|
-
let umdOnClickHandler;
|
|
1397
|
-
// record event and timer before exec umdMountHook
|
|
1398
|
-
const recordUmdEffect = () => {
|
|
1399
|
-
// record window event
|
|
1400
|
-
eventListenerMap.forEach((listenerList, type) => {
|
|
1401
|
-
if (listenerList.size) {
|
|
1402
|
-
umdWindowListenerMap.set(type, new Set(listenerList));
|
|
1403
|
-
}
|
|
1404
|
-
});
|
|
1405
|
-
// record timers
|
|
1406
|
-
if (intervalIdMap.size) {
|
|
1407
|
-
umdIntervalIdMap = new Map(intervalIdMap);
|
|
1408
|
-
}
|
|
1409
|
-
if (timeoutIdMap.size) {
|
|
1410
|
-
umdTimeoutIdMap = new Map(timeoutIdMap);
|
|
1411
|
-
}
|
|
1412
|
-
// record onclick handler
|
|
1413
|
-
umdOnClickHandler = documentClickListMap.get(appName);
|
|
1414
|
-
// record document event
|
|
1415
|
-
const documentAppListenersMap = documentEventListenerMap.get(appName);
|
|
1416
|
-
if (documentAppListenersMap) {
|
|
1417
|
-
documentAppListenersMap.forEach((listenerList, type) => {
|
|
1418
|
-
if (listenerList.size) {
|
|
1419
|
-
umdDocumentListenerMap.set(type, new Set(listenerList));
|
|
1420
|
-
}
|
|
1421
|
-
});
|
|
1422
|
-
}
|
|
1423
|
-
};
|
|
1424
|
-
// rebuild event and timer before remount umd app
|
|
1425
|
-
const rebuildUmdEffect = () => {
|
|
1426
|
-
// rebuild window event
|
|
1427
|
-
umdWindowListenerMap.forEach((listenerList, type) => {
|
|
1428
|
-
for (const listener of listenerList) {
|
|
1429
|
-
microWindow.addEventListener(type, listener, listener === null || listener === void 0 ? void 0 : listener.__MICRO_MARK_OPTIONS__);
|
|
1430
|
-
}
|
|
1431
|
-
});
|
|
1432
|
-
// rebuild timer
|
|
1433
|
-
umdIntervalIdMap.forEach((info) => {
|
|
1434
|
-
microWindow.setInterval(info.handler, info.timeout, ...info.args);
|
|
1435
|
-
});
|
|
1436
|
-
umdTimeoutIdMap.forEach((info) => {
|
|
1437
|
-
microWindow.setTimeout(info.handler, info.timeout, ...info.args);
|
|
1438
|
-
});
|
|
1439
|
-
// rebuild onclick event
|
|
1440
|
-
umdOnClickHandler && documentClickListMap.set(appName, umdOnClickHandler);
|
|
1441
|
-
// rebuild document event
|
|
1442
|
-
setCurrentAppName(appName);
|
|
1443
|
-
umdDocumentListenerMap.forEach((listenerList, type) => {
|
|
1444
|
-
for (const listener of listenerList) {
|
|
1445
|
-
document.addEventListener(type, listener, listener === null || listener === void 0 ? void 0 : listener.__MICRO_MARK_OPTIONS__);
|
|
1446
|
-
}
|
|
1447
|
-
});
|
|
1448
|
-
setCurrentAppName(null);
|
|
1449
|
-
};
|
|
1450
|
-
// release all event listener & interval & timeout when unmount app
|
|
1451
|
-
const releaseEffect = () => {
|
|
1452
|
-
// Clear window binding events
|
|
1453
|
-
if (eventListenerMap.size) {
|
|
1454
|
-
eventListenerMap.forEach((listenerList, type) => {
|
|
1455
|
-
for (const listener of listenerList) {
|
|
1456
|
-
rawWindowRemoveEventListener.call(rawWindow, type, listener);
|
|
1457
|
-
}
|
|
1458
|
-
});
|
|
1459
|
-
eventListenerMap.clear();
|
|
1460
|
-
}
|
|
1461
|
-
// Clear timers
|
|
1462
|
-
if (intervalIdMap.size) {
|
|
1463
|
-
intervalIdMap.forEach((_, intervalId) => {
|
|
1464
|
-
rawClearInterval.call(rawWindow, intervalId);
|
|
1465
|
-
});
|
|
1466
|
-
intervalIdMap.clear();
|
|
1467
|
-
}
|
|
1468
|
-
if (timeoutIdMap.size) {
|
|
1469
|
-
timeoutIdMap.forEach((_, timeoutId) => {
|
|
1470
|
-
rawClearTimeout.call(rawWindow, timeoutId);
|
|
1471
|
-
});
|
|
1472
|
-
timeoutIdMap.clear();
|
|
1473
|
-
}
|
|
1474
|
-
// Clear the function bound by micro application through document.onclick
|
|
1475
|
-
documentClickListMap.delete(appName);
|
|
1476
|
-
// Clear document binding event
|
|
1477
|
-
const documentAppListenersMap = documentEventListenerMap.get(appName);
|
|
1478
|
-
if (documentAppListenersMap) {
|
|
1479
|
-
documentAppListenersMap.forEach((listenerList, type) => {
|
|
1480
|
-
for (const listener of listenerList) {
|
|
1481
|
-
rawDocumentRemoveEventListener.call(rawDocument, type, listener);
|
|
1482
|
-
}
|
|
1483
|
-
});
|
|
1484
|
-
documentAppListenersMap.clear();
|
|
1485
|
-
}
|
|
1486
|
-
};
|
|
1487
|
-
return {
|
|
1488
|
-
recordUmdEffect,
|
|
1489
|
-
rebuildUmdEffect,
|
|
1490
|
-
releaseEffect,
|
|
1491
|
-
};
|
|
1492
|
-
}
|
|
1493
|
-
|
|
1494
1195
|
class EventCenter {
|
|
1495
1196
|
constructor() {
|
|
1496
1197
|
this.eventList = new Map();
|
|
@@ -1728,50 +1429,359 @@ class EventCenterForMicroApp extends EventCenterForGlobal {
|
|
|
1728
1429
|
detail: {
|
|
1729
1430
|
data,
|
|
1730
1431
|
}
|
|
1731
|
-
});
|
|
1732
|
-
getRootContainer(app.container).dispatchEvent(event);
|
|
1432
|
+
});
|
|
1433
|
+
getRootContainer(app.container).dispatchEvent(event);
|
|
1434
|
+
}
|
|
1435
|
+
}
|
|
1436
|
+
/**
|
|
1437
|
+
* clear all listeners
|
|
1438
|
+
*/
|
|
1439
|
+
clearDataListener() {
|
|
1440
|
+
eventCenter.off(formatEventName(this.appName, true));
|
|
1441
|
+
}
|
|
1442
|
+
}
|
|
1443
|
+
/**
|
|
1444
|
+
* Record UMD function before exec umdHookMount
|
|
1445
|
+
* @param microAppEventCneter
|
|
1446
|
+
*/
|
|
1447
|
+
function recordDataCenterSnapshot(microAppEventCneter) {
|
|
1448
|
+
const appName = microAppEventCneter.appName;
|
|
1449
|
+
microAppEventCneter.umdDataListeners = { global: new Set(), normal: new Set() };
|
|
1450
|
+
const globalEventInfo = eventCenter.eventList.get('global');
|
|
1451
|
+
if (globalEventInfo) {
|
|
1452
|
+
for (const cb of globalEventInfo.callbacks) {
|
|
1453
|
+
if (appName === cb.__APP_NAME__) {
|
|
1454
|
+
microAppEventCneter.umdDataListeners.global.add(cb);
|
|
1455
|
+
}
|
|
1456
|
+
}
|
|
1457
|
+
}
|
|
1458
|
+
const subAppEventInfo = eventCenter.eventList.get(formatEventName(appName, true));
|
|
1459
|
+
if (subAppEventInfo) {
|
|
1460
|
+
microAppEventCneter.umdDataListeners.normal = new Set(subAppEventInfo.callbacks);
|
|
1461
|
+
}
|
|
1462
|
+
}
|
|
1463
|
+
/**
|
|
1464
|
+
* Rebind the UMD function of the record before remount
|
|
1465
|
+
* @param microAppEventCneter instance of EventCenterForMicroApp
|
|
1466
|
+
*/
|
|
1467
|
+
function rebuildDataCenterSnapshot(microAppEventCneter) {
|
|
1468
|
+
for (const cb of microAppEventCneter.umdDataListeners.global) {
|
|
1469
|
+
microAppEventCneter.addGlobalDataListener(cb, cb.__AUTO_TRIGGER__);
|
|
1470
|
+
}
|
|
1471
|
+
for (const cb of microAppEventCneter.umdDataListeners.normal) {
|
|
1472
|
+
microAppEventCneter.addDataListener(cb, cb.__AUTO_TRIGGER__);
|
|
1473
|
+
}
|
|
1474
|
+
}
|
|
1475
|
+
|
|
1476
|
+
const boundedMap = new WeakMap();
|
|
1477
|
+
function isBoundedFunction(value) {
|
|
1478
|
+
if (boundedMap.has(value)) {
|
|
1479
|
+
return boundedMap.get(value);
|
|
1480
|
+
}
|
|
1481
|
+
// bind function
|
|
1482
|
+
const boundFunction = isBoundFunction(value);
|
|
1483
|
+
boundedMap.set(value, boundFunction);
|
|
1484
|
+
return boundFunction;
|
|
1485
|
+
}
|
|
1486
|
+
const constructorMap = new WeakMap();
|
|
1487
|
+
function isConstructor(value) {
|
|
1488
|
+
if (constructorMap.has(value)) {
|
|
1489
|
+
return constructorMap.get(value);
|
|
1490
|
+
}
|
|
1491
|
+
const valueStr = value.toString();
|
|
1492
|
+
const result = (value.prototype &&
|
|
1493
|
+
value.prototype.constructor === value &&
|
|
1494
|
+
Object.getOwnPropertyNames(value.prototype).length > 1) ||
|
|
1495
|
+
/^function\s+[A-Z]/.test(valueStr) ||
|
|
1496
|
+
/^class\s+/.test(valueStr);
|
|
1497
|
+
constructorMap.set(value, result);
|
|
1498
|
+
return result;
|
|
1499
|
+
}
|
|
1500
|
+
const rawWindowMethodMap = new WeakMap();
|
|
1501
|
+
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
|
|
1502
|
+
function bindFunctionToRawWidow(rawWindow, value) {
|
|
1503
|
+
if (rawWindowMethodMap.has(value)) {
|
|
1504
|
+
return rawWindowMethodMap.get(value);
|
|
1505
|
+
}
|
|
1506
|
+
if (isFunction(value) && !isConstructor(value) && !isBoundedFunction(value)) {
|
|
1507
|
+
const bindRawWindowValue = value.bind(rawWindow);
|
|
1508
|
+
for (const key in value) {
|
|
1509
|
+
bindRawWindowValue[key] = value[key];
|
|
1510
|
+
}
|
|
1511
|
+
if (value.hasOwnProperty('prototype') && !bindRawWindowValue.hasOwnProperty('prototype')) {
|
|
1512
|
+
bindRawWindowValue.prototype = value.prototype;
|
|
1513
|
+
}
|
|
1514
|
+
rawWindowMethodMap.set(value, bindRawWindowValue);
|
|
1515
|
+
return bindRawWindowValue;
|
|
1516
|
+
}
|
|
1517
|
+
return value;
|
|
1518
|
+
}
|
|
1519
|
+
|
|
1520
|
+
// document.onclick binding list, the binding function of each application is unique
|
|
1521
|
+
const documentClickListMap = new Map();
|
|
1522
|
+
let hasRewriteDocumentOnClick = false;
|
|
1523
|
+
/**
|
|
1524
|
+
* Rewrite document.onclick and execute it only once
|
|
1525
|
+
*/
|
|
1526
|
+
function overwriteDocumentOnClick() {
|
|
1527
|
+
hasRewriteDocumentOnClick = true;
|
|
1528
|
+
if (Object.getOwnPropertyDescriptor(document, 'onclick')) {
|
|
1529
|
+
return logWarn('Cannot redefine document property onclick');
|
|
1530
|
+
}
|
|
1531
|
+
const rawOnClick = document.onclick;
|
|
1532
|
+
document.onclick = null;
|
|
1533
|
+
let hasDocumentClickInited = false;
|
|
1534
|
+
function onClickHandler(e) {
|
|
1535
|
+
documentClickListMap.forEach((f) => {
|
|
1536
|
+
isFunction(f) && f.call(document, e);
|
|
1537
|
+
});
|
|
1538
|
+
}
|
|
1539
|
+
Object.defineProperty(document, 'onclick', {
|
|
1540
|
+
configurable: true,
|
|
1541
|
+
enumerable: true,
|
|
1542
|
+
get() {
|
|
1543
|
+
const appName = getCurrentAppName();
|
|
1544
|
+
return appName ? documentClickListMap.get(appName) : documentClickListMap.get('base');
|
|
1545
|
+
},
|
|
1546
|
+
set(f) {
|
|
1547
|
+
const appName = getCurrentAppName();
|
|
1548
|
+
if (appName) {
|
|
1549
|
+
documentClickListMap.set(appName, f);
|
|
1550
|
+
}
|
|
1551
|
+
else {
|
|
1552
|
+
documentClickListMap.set('base', f);
|
|
1553
|
+
}
|
|
1554
|
+
if (!hasDocumentClickInited && isFunction(f)) {
|
|
1555
|
+
hasDocumentClickInited = true;
|
|
1556
|
+
globalEnv.rawDocumentAddEventListener.call(globalEnv.rawDocument, 'click', onClickHandler, false);
|
|
1557
|
+
}
|
|
1558
|
+
}
|
|
1559
|
+
});
|
|
1560
|
+
rawOnClick && (document.onclick = rawOnClick);
|
|
1561
|
+
}
|
|
1562
|
+
/**
|
|
1563
|
+
* The document event is globally, we need to clear these event bindings when micro application unmounted
|
|
1564
|
+
*/
|
|
1565
|
+
const documentEventListenerMap = new Map();
|
|
1566
|
+
function effectDocumentEvent() {
|
|
1567
|
+
const { rawDocument, rawDocumentAddEventListener, rawDocumentRemoveEventListener, } = globalEnv;
|
|
1568
|
+
!hasRewriteDocumentOnClick && overwriteDocumentOnClick();
|
|
1569
|
+
document.addEventListener = function (type, listener, options) {
|
|
1570
|
+
var _a;
|
|
1571
|
+
const appName = getCurrentAppName();
|
|
1572
|
+
/**
|
|
1573
|
+
* ignore bound function of document event in umd mode, used to solve problem of react global events
|
|
1574
|
+
*/
|
|
1575
|
+
if (appName && !(((_a = appInstanceMap.get(appName)) === null || _a === void 0 ? void 0 : _a.umdMode) && isBoundFunction(listener))) {
|
|
1576
|
+
const appListenersMap = documentEventListenerMap.get(appName);
|
|
1577
|
+
if (appListenersMap) {
|
|
1578
|
+
const appListenerList = appListenersMap.get(type);
|
|
1579
|
+
if (appListenerList) {
|
|
1580
|
+
appListenerList.add(listener);
|
|
1581
|
+
}
|
|
1582
|
+
else {
|
|
1583
|
+
appListenersMap.set(type, new Set([listener]));
|
|
1584
|
+
}
|
|
1585
|
+
}
|
|
1586
|
+
else {
|
|
1587
|
+
documentEventListenerMap.set(appName, new Map([[type, new Set([listener])]]));
|
|
1588
|
+
}
|
|
1589
|
+
listener && (listener.__MICRO_MARK_OPTIONS__ = options);
|
|
1590
|
+
}
|
|
1591
|
+
rawDocumentAddEventListener.call(rawDocument, type, listener, options);
|
|
1592
|
+
};
|
|
1593
|
+
document.removeEventListener = function (type, listener, options) {
|
|
1594
|
+
var _a;
|
|
1595
|
+
const appName = getCurrentAppName();
|
|
1596
|
+
if (appName && !(((_a = appInstanceMap.get(appName)) === null || _a === void 0 ? void 0 : _a.umdMode) && isBoundFunction(listener))) {
|
|
1597
|
+
const appListenersMap = documentEventListenerMap.get(appName);
|
|
1598
|
+
if (appListenersMap) {
|
|
1599
|
+
const appListenerList = appListenersMap.get(type);
|
|
1600
|
+
if ((appListenerList === null || appListenerList === void 0 ? void 0 : appListenerList.size) && appListenerList.has(listener)) {
|
|
1601
|
+
appListenerList.delete(listener);
|
|
1602
|
+
}
|
|
1603
|
+
}
|
|
1733
1604
|
}
|
|
1734
|
-
|
|
1735
|
-
|
|
1736
|
-
|
|
1737
|
-
|
|
1738
|
-
|
|
1739
|
-
|
|
1740
|
-
|
|
1605
|
+
rawDocumentRemoveEventListener.call(rawDocument, type, listener, options);
|
|
1606
|
+
};
|
|
1607
|
+
}
|
|
1608
|
+
// Clear the document event agent
|
|
1609
|
+
function releaseEffectDocumentEvent() {
|
|
1610
|
+
document.addEventListener = globalEnv.rawDocumentAddEventListener;
|
|
1611
|
+
document.removeEventListener = globalEnv.rawDocumentRemoveEventListener;
|
|
1741
1612
|
}
|
|
1613
|
+
// this events should be sent to the specified app
|
|
1614
|
+
const formatEventList = ['unmount', 'appstate-change'];
|
|
1742
1615
|
/**
|
|
1743
|
-
*
|
|
1744
|
-
* @param
|
|
1616
|
+
* Format event name
|
|
1617
|
+
* @param type event name
|
|
1618
|
+
* @param microWindow micro window
|
|
1745
1619
|
*/
|
|
1746
|
-
function
|
|
1747
|
-
|
|
1748
|
-
|
|
1749
|
-
const globalEventInfo = eventCenter.eventList.get('global');
|
|
1750
|
-
if (globalEventInfo) {
|
|
1751
|
-
for (const cb of globalEventInfo.callbacks) {
|
|
1752
|
-
if (appName === cb.__APP_NAME__) {
|
|
1753
|
-
microAppEventCneter.umdDataListeners.global.add(cb);
|
|
1754
|
-
}
|
|
1755
|
-
}
|
|
1756
|
-
}
|
|
1757
|
-
const subAppEventInfo = eventCenter.eventList.get(formatEventName(appName, true));
|
|
1758
|
-
if (subAppEventInfo) {
|
|
1759
|
-
microAppEventCneter.umdDataListeners.normal = new Set(subAppEventInfo.callbacks);
|
|
1620
|
+
function formatEventType(type, microWindow) {
|
|
1621
|
+
if (formatEventList.includes(type)) {
|
|
1622
|
+
return `${type}-${microWindow.__MICRO_APP_NAME__}`;
|
|
1760
1623
|
}
|
|
1624
|
+
return type;
|
|
1761
1625
|
}
|
|
1762
1626
|
/**
|
|
1763
|
-
*
|
|
1764
|
-
* @param
|
|
1627
|
+
* Rewrite side-effect events
|
|
1628
|
+
* @param microWindow micro window
|
|
1765
1629
|
*/
|
|
1766
|
-
function
|
|
1767
|
-
|
|
1768
|
-
|
|
1769
|
-
|
|
1770
|
-
|
|
1771
|
-
|
|
1772
|
-
|
|
1630
|
+
function effect(microWindow) {
|
|
1631
|
+
const appName = microWindow.__MICRO_APP_NAME__;
|
|
1632
|
+
const eventListenerMap = new Map();
|
|
1633
|
+
const intervalIdMap = new Map();
|
|
1634
|
+
const timeoutIdMap = new Map();
|
|
1635
|
+
const { rawWindow, rawDocument, rawWindowAddEventListener, rawWindowRemoveEventListener, rawSetInterval, rawSetTimeout, rawClearInterval, rawClearTimeout, rawDocumentRemoveEventListener, } = globalEnv;
|
|
1636
|
+
// listener may be null, e.g test-passive
|
|
1637
|
+
microWindow.addEventListener = function (type, listener, options) {
|
|
1638
|
+
type = formatEventType(type, microWindow);
|
|
1639
|
+
const listenerList = eventListenerMap.get(type);
|
|
1640
|
+
if (listenerList) {
|
|
1641
|
+
listenerList.add(listener);
|
|
1642
|
+
}
|
|
1643
|
+
else {
|
|
1644
|
+
eventListenerMap.set(type, new Set([listener]));
|
|
1645
|
+
}
|
|
1646
|
+
listener && (listener.__MICRO_MARK_OPTIONS__ = options);
|
|
1647
|
+
rawWindowAddEventListener.call(rawWindow, type, listener, options);
|
|
1648
|
+
};
|
|
1649
|
+
microWindow.removeEventListener = function (type, listener, options) {
|
|
1650
|
+
type = formatEventType(type, microWindow);
|
|
1651
|
+
const listenerList = eventListenerMap.get(type);
|
|
1652
|
+
if ((listenerList === null || listenerList === void 0 ? void 0 : listenerList.size) && listenerList.has(listener)) {
|
|
1653
|
+
listenerList.delete(listener);
|
|
1654
|
+
}
|
|
1655
|
+
rawWindowRemoveEventListener.call(rawWindow, type, listener, options);
|
|
1656
|
+
};
|
|
1657
|
+
microWindow.setInterval = function (handler, timeout, ...args) {
|
|
1658
|
+
const intervalId = rawSetInterval.call(rawWindow, handler, timeout, ...args);
|
|
1659
|
+
intervalIdMap.set(intervalId, { handler, timeout, args });
|
|
1660
|
+
return intervalId;
|
|
1661
|
+
};
|
|
1662
|
+
microWindow.setTimeout = function (handler, timeout, ...args) {
|
|
1663
|
+
const timeoutId = rawSetTimeout.call(rawWindow, handler, timeout, ...args);
|
|
1664
|
+
timeoutIdMap.set(timeoutId, { handler, timeout, args });
|
|
1665
|
+
return timeoutId;
|
|
1666
|
+
};
|
|
1667
|
+
microWindow.clearInterval = function (intervalId) {
|
|
1668
|
+
intervalIdMap.delete(intervalId);
|
|
1669
|
+
rawClearInterval.call(rawWindow, intervalId);
|
|
1670
|
+
};
|
|
1671
|
+
microWindow.clearTimeout = function (timeoutId) {
|
|
1672
|
+
timeoutIdMap.delete(timeoutId);
|
|
1673
|
+
rawClearTimeout.call(rawWindow, timeoutId);
|
|
1674
|
+
};
|
|
1675
|
+
const umdWindowListenerMap = new Map();
|
|
1676
|
+
const umdDocumentListenerMap = new Map();
|
|
1677
|
+
let umdIntervalIdMap = new Map();
|
|
1678
|
+
let umdTimeoutIdMap = new Map();
|
|
1679
|
+
let umdOnClickHandler;
|
|
1680
|
+
// record event and timer before exec umdMountHook
|
|
1681
|
+
const recordUmdEffect = () => {
|
|
1682
|
+
// record window event
|
|
1683
|
+
eventListenerMap.forEach((listenerList, type) => {
|
|
1684
|
+
if (listenerList.size) {
|
|
1685
|
+
umdWindowListenerMap.set(type, new Set(listenerList));
|
|
1686
|
+
}
|
|
1687
|
+
});
|
|
1688
|
+
// record timers
|
|
1689
|
+
if (intervalIdMap.size) {
|
|
1690
|
+
umdIntervalIdMap = new Map(intervalIdMap);
|
|
1691
|
+
}
|
|
1692
|
+
if (timeoutIdMap.size) {
|
|
1693
|
+
umdTimeoutIdMap = new Map(timeoutIdMap);
|
|
1694
|
+
}
|
|
1695
|
+
// record onclick handler
|
|
1696
|
+
umdOnClickHandler = documentClickListMap.get(appName);
|
|
1697
|
+
// record document event
|
|
1698
|
+
const documentAppListenersMap = documentEventListenerMap.get(appName);
|
|
1699
|
+
if (documentAppListenersMap) {
|
|
1700
|
+
documentAppListenersMap.forEach((listenerList, type) => {
|
|
1701
|
+
if (listenerList.size) {
|
|
1702
|
+
umdDocumentListenerMap.set(type, new Set(listenerList));
|
|
1703
|
+
}
|
|
1704
|
+
});
|
|
1705
|
+
}
|
|
1706
|
+
};
|
|
1707
|
+
// rebuild event and timer before remount umd app
|
|
1708
|
+
const rebuildUmdEffect = () => {
|
|
1709
|
+
// rebuild window event
|
|
1710
|
+
umdWindowListenerMap.forEach((listenerList, type) => {
|
|
1711
|
+
for (const listener of listenerList) {
|
|
1712
|
+
microWindow.addEventListener(type, listener, listener === null || listener === void 0 ? void 0 : listener.__MICRO_MARK_OPTIONS__);
|
|
1713
|
+
}
|
|
1714
|
+
});
|
|
1715
|
+
// rebuild timer
|
|
1716
|
+
umdIntervalIdMap.forEach((info) => {
|
|
1717
|
+
microWindow.setInterval(info.handler, info.timeout, ...info.args);
|
|
1718
|
+
});
|
|
1719
|
+
umdTimeoutIdMap.forEach((info) => {
|
|
1720
|
+
microWindow.setTimeout(info.handler, info.timeout, ...info.args);
|
|
1721
|
+
});
|
|
1722
|
+
// rebuild onclick event
|
|
1723
|
+
umdOnClickHandler && documentClickListMap.set(appName, umdOnClickHandler);
|
|
1724
|
+
// rebuild document event
|
|
1725
|
+
setCurrentAppName(appName);
|
|
1726
|
+
umdDocumentListenerMap.forEach((listenerList, type) => {
|
|
1727
|
+
for (const listener of listenerList) {
|
|
1728
|
+
document.addEventListener(type, listener, listener === null || listener === void 0 ? void 0 : listener.__MICRO_MARK_OPTIONS__);
|
|
1729
|
+
}
|
|
1730
|
+
});
|
|
1731
|
+
setCurrentAppName(null);
|
|
1732
|
+
};
|
|
1733
|
+
// release all event listener & interval & timeout when unmount app
|
|
1734
|
+
const releaseEffect = () => {
|
|
1735
|
+
// Clear window binding events
|
|
1736
|
+
if (eventListenerMap.size) {
|
|
1737
|
+
eventListenerMap.forEach((listenerList, type) => {
|
|
1738
|
+
for (const listener of listenerList) {
|
|
1739
|
+
rawWindowRemoveEventListener.call(rawWindow, type, listener);
|
|
1740
|
+
}
|
|
1741
|
+
});
|
|
1742
|
+
eventListenerMap.clear();
|
|
1743
|
+
}
|
|
1744
|
+
// Clear timers
|
|
1745
|
+
if (intervalIdMap.size) {
|
|
1746
|
+
intervalIdMap.forEach((_, intervalId) => {
|
|
1747
|
+
rawClearInterval.call(rawWindow, intervalId);
|
|
1748
|
+
});
|
|
1749
|
+
intervalIdMap.clear();
|
|
1750
|
+
}
|
|
1751
|
+
if (timeoutIdMap.size) {
|
|
1752
|
+
timeoutIdMap.forEach((_, timeoutId) => {
|
|
1753
|
+
rawClearTimeout.call(rawWindow, timeoutId);
|
|
1754
|
+
});
|
|
1755
|
+
timeoutIdMap.clear();
|
|
1756
|
+
}
|
|
1757
|
+
// Clear the function bound by micro application through document.onclick
|
|
1758
|
+
documentClickListMap.delete(appName);
|
|
1759
|
+
// Clear document binding event
|
|
1760
|
+
const documentAppListenersMap = documentEventListenerMap.get(appName);
|
|
1761
|
+
if (documentAppListenersMap) {
|
|
1762
|
+
documentAppListenersMap.forEach((listenerList, type) => {
|
|
1763
|
+
for (const listener of listenerList) {
|
|
1764
|
+
rawDocumentRemoveEventListener.call(rawDocument, type, listener);
|
|
1765
|
+
}
|
|
1766
|
+
});
|
|
1767
|
+
documentAppListenersMap.clear();
|
|
1768
|
+
}
|
|
1769
|
+
};
|
|
1770
|
+
return {
|
|
1771
|
+
recordUmdEffect,
|
|
1772
|
+
rebuildUmdEffect,
|
|
1773
|
+
releaseEffect,
|
|
1774
|
+
};
|
|
1773
1775
|
}
|
|
1774
1776
|
|
|
1777
|
+
const ImageProxy = new Proxy(Image, {
|
|
1778
|
+
construct(Target, args) {
|
|
1779
|
+
const elementImage = new Target(...args);
|
|
1780
|
+
elementImage.__MICRO_APP_NAME__ = getCurrentAppName();
|
|
1781
|
+
return elementImage;
|
|
1782
|
+
},
|
|
1783
|
+
});
|
|
1784
|
+
|
|
1775
1785
|
// Variables that can escape to rawWindow
|
|
1776
1786
|
const staticEscapeProperties = [
|
|
1777
1787
|
'System',
|
|
@@ -1840,7 +1850,7 @@ class SandBox {
|
|
|
1840
1850
|
}
|
|
1841
1851
|
if (key === 'hasOwnProperty')
|
|
1842
1852
|
return hasOwnProperty;
|
|
1843
|
-
if (key === 'document' || key === 'eval') {
|
|
1853
|
+
if (key === 'document' || key === 'eval' || key === 'Image') {
|
|
1844
1854
|
if (this.active) {
|
|
1845
1855
|
setCurrentAppName(appName);
|
|
1846
1856
|
(macro ? macroTask : defer)(() => setCurrentAppName(null));
|
|
@@ -1850,6 +1860,8 @@ class SandBox {
|
|
|
1850
1860
|
return rawDocument;
|
|
1851
1861
|
case 'eval':
|
|
1852
1862
|
return eval;
|
|
1863
|
+
case 'Image':
|
|
1864
|
+
return ImageProxy;
|
|
1853
1865
|
}
|
|
1854
1866
|
}
|
|
1855
1867
|
if (Reflect.has(target, key)) {
|
|
@@ -2039,7 +2051,7 @@ class SandBox {
|
|
|
2039
2051
|
}
|
|
2040
2052
|
SandBox.activeCount = 0; // number of active sandbox
|
|
2041
2053
|
|
|
2042
|
-
function
|
|
2054
|
+
function formatEventInfo(event, element) {
|
|
2043
2055
|
Object.defineProperties(event, {
|
|
2044
2056
|
currentTarget: {
|
|
2045
2057
|
get() {
|
|
@@ -2078,7 +2090,7 @@ function dispatchLifecyclesEvent(element, appName, lifecycleName, error) {
|
|
|
2078
2090
|
const event = new CustomEvent(lifecycleName, {
|
|
2079
2091
|
detail,
|
|
2080
2092
|
});
|
|
2081
|
-
|
|
2093
|
+
formatEventInfo(event, element);
|
|
2082
2094
|
// global hooks
|
|
2083
2095
|
// @ts-ignore
|
|
2084
2096
|
if (isFunction((_a = microApp.lifeCycles) === null || _a === void 0 ? void 0 : _a[lifecycleName])) {
|
|
@@ -2298,8 +2310,6 @@ class CreateApp {
|
|
|
2298
2310
|
*/
|
|
2299
2311
|
actionsForUnmount(destroy, unmountcb) {
|
|
2300
2312
|
var _a;
|
|
2301
|
-
// dispatch unmount event to base app
|
|
2302
|
-
dispatchLifecyclesEvent(this.container, this.name, lifeCycles.UNMOUNT);
|
|
2303
2313
|
(_a = this.sandBox) === null || _a === void 0 ? void 0 : _a.stop();
|
|
2304
2314
|
if (destroy) {
|
|
2305
2315
|
this.actionsForCompletelyDestory();
|
|
@@ -2307,6 +2317,8 @@ class CreateApp {
|
|
|
2307
2317
|
else if (this.umdMode && this.container.childElementCount) {
|
|
2308
2318
|
cloneContainer(this.container, this.source.html, false);
|
|
2309
2319
|
}
|
|
2320
|
+
// dispatch unmount event to base app
|
|
2321
|
+
dispatchLifecyclesEvent(this.container, this.name, lifeCycles.UNMOUNT);
|
|
2310
2322
|
this.container.innerHTML = '';
|
|
2311
2323
|
this.container = null;
|
|
2312
2324
|
unmountcb && unmountcb();
|
|
@@ -2320,6 +2332,9 @@ class CreateApp {
|
|
|
2320
2332
|
}
|
|
2321
2333
|
// hidden app when disconnectedCallback called with keep-alive
|
|
2322
2334
|
hiddenKeepAliveApp() {
|
|
2335
|
+
const oldContainer = this.container;
|
|
2336
|
+
cloneContainer(this.container, this.keepAliveContainer ? this.keepAliveContainer : (this.keepAliveContainer = document.createElement('div')), false);
|
|
2337
|
+
this.container = this.keepAliveContainer;
|
|
2323
2338
|
this.keepAliveState = keepAliveStates.KEEP_ALIVE_HIDDEN;
|
|
2324
2339
|
// event should dispatch before clone node
|
|
2325
2340
|
// dispatch afterhidden event to micro-app
|
|
@@ -2327,9 +2342,7 @@ class CreateApp {
|
|
|
2327
2342
|
appState: 'afterhidden',
|
|
2328
2343
|
});
|
|
2329
2344
|
// dispatch afterhidden event to base app
|
|
2330
|
-
dispatchLifecyclesEvent(
|
|
2331
|
-
cloneContainer(this.container, this.keepAliveContainer ? this.keepAliveContainer : (this.keepAliveContainer = document.createElement('div')), false);
|
|
2332
|
-
this.container = this.keepAliveContainer;
|
|
2345
|
+
dispatchLifecyclesEvent(oldContainer, this.name, lifeCycles.AFTERHIDDEN);
|
|
2333
2346
|
}
|
|
2334
2347
|
// show app when connectedCallback called with keep-alive
|
|
2335
2348
|
showKeepAliveApp(container) {
|
|
@@ -2391,6 +2404,78 @@ function getActiveApps() {
|
|
|
2391
2404
|
function getAllApps() {
|
|
2392
2405
|
return Array.from(appInstanceMap.keys());
|
|
2393
2406
|
}
|
|
2407
|
+
/**
|
|
2408
|
+
* unmount app by appname
|
|
2409
|
+
* @param appName
|
|
2410
|
+
* @param options unmountAppParams
|
|
2411
|
+
* @returns Promise<void>
|
|
2412
|
+
*/
|
|
2413
|
+
function unmountApp(appName, options) {
|
|
2414
|
+
const app = appInstanceMap.get(formatAppName(appName));
|
|
2415
|
+
return new Promise((reslove) => {
|
|
2416
|
+
if (app) {
|
|
2417
|
+
if (app.getAppState() === appStates.UNMOUNT || app.isPrefetch) {
|
|
2418
|
+
if (options === null || options === void 0 ? void 0 : options.destroy) {
|
|
2419
|
+
app.actionsForCompletelyDestory();
|
|
2420
|
+
}
|
|
2421
|
+
reslove();
|
|
2422
|
+
}
|
|
2423
|
+
else if (app.getKeepAliveState() === keepAliveStates.KEEP_ALIVE_HIDDEN) {
|
|
2424
|
+
if (options === null || options === void 0 ? void 0 : options.destroy) {
|
|
2425
|
+
app.unmount(true, reslove);
|
|
2426
|
+
}
|
|
2427
|
+
else if (options === null || options === void 0 ? void 0 : options.clearAliveState) {
|
|
2428
|
+
app.unmount(false, reslove);
|
|
2429
|
+
}
|
|
2430
|
+
else {
|
|
2431
|
+
reslove();
|
|
2432
|
+
}
|
|
2433
|
+
}
|
|
2434
|
+
else {
|
|
2435
|
+
const container = getRootContainer(app.container);
|
|
2436
|
+
const unmountHandler = () => {
|
|
2437
|
+
container.removeEventListener('unmount', unmountHandler);
|
|
2438
|
+
container.removeEventListener('afterhidden', afterhiddenHandler);
|
|
2439
|
+
reslove();
|
|
2440
|
+
};
|
|
2441
|
+
const afterhiddenHandler = () => {
|
|
2442
|
+
container.removeEventListener('unmount', unmountHandler);
|
|
2443
|
+
container.removeEventListener('afterhidden', afterhiddenHandler);
|
|
2444
|
+
reslove();
|
|
2445
|
+
};
|
|
2446
|
+
container.addEventListener('unmount', unmountHandler);
|
|
2447
|
+
container.addEventListener('afterhidden', afterhiddenHandler);
|
|
2448
|
+
if (options === null || options === void 0 ? void 0 : options.destroy) {
|
|
2449
|
+
let destroyAttrValue, destoryAttrValue;
|
|
2450
|
+
container.hasAttribute('destroy') && (destroyAttrValue = container.getAttribute('destroy'));
|
|
2451
|
+
container.hasAttribute('destory') && (destoryAttrValue = container.getAttribute('destory'));
|
|
2452
|
+
container.setAttribute('destroy', 'true');
|
|
2453
|
+
container.parentNode.removeChild(container);
|
|
2454
|
+
container.removeAttribute('destroy');
|
|
2455
|
+
typeof destroyAttrValue === 'string' && container.setAttribute('destroy', destroyAttrValue);
|
|
2456
|
+
typeof destoryAttrValue === 'string' && container.setAttribute('destory', destoryAttrValue);
|
|
2457
|
+
}
|
|
2458
|
+
else if ((options === null || options === void 0 ? void 0 : options.clearAliveState) && container.hasAttribute('keep-alive')) {
|
|
2459
|
+
const keepAliveAttrValue = container.getAttribute('keep-alive');
|
|
2460
|
+
container.removeAttribute('keep-alive');
|
|
2461
|
+
container.parentNode.removeChild(container);
|
|
2462
|
+
container.setAttribute('keep-alive', keepAliveAttrValue);
|
|
2463
|
+
}
|
|
2464
|
+
else {
|
|
2465
|
+
container.parentNode.removeChild(container);
|
|
2466
|
+
}
|
|
2467
|
+
}
|
|
2468
|
+
}
|
|
2469
|
+
else {
|
|
2470
|
+
logWarn(`app ${appName} does not exist`);
|
|
2471
|
+
reslove();
|
|
2472
|
+
}
|
|
2473
|
+
});
|
|
2474
|
+
}
|
|
2475
|
+
// unmount all apps in turn
|
|
2476
|
+
function unmountAllApps(options) {
|
|
2477
|
+
return Array.from(appInstanceMap.keys()).reduce((pre, next) => pre.then(() => unmountApp(next, options)), Promise.resolve());
|
|
2478
|
+
}
|
|
2394
2479
|
|
|
2395
2480
|
// Record element and map element
|
|
2396
2481
|
const dynamicElementInMicroAppMap = new WeakMap();
|
|
@@ -2585,13 +2670,13 @@ function patchElementPrototypeMethods() {
|
|
|
2585
2670
|
}
|
|
2586
2671
|
};
|
|
2587
2672
|
// prototype methods of add element👇
|
|
2588
|
-
|
|
2673
|
+
Element.prototype.appendChild = function appendChild(newChild) {
|
|
2589
2674
|
return commonElementHander(this, newChild, null, globalEnv.rawAppendChild);
|
|
2590
2675
|
};
|
|
2591
|
-
|
|
2676
|
+
Element.prototype.insertBefore = function insertBefore(newChild, refChild) {
|
|
2592
2677
|
return commonElementHander(this, newChild, refChild, globalEnv.rawInsertBefore);
|
|
2593
2678
|
};
|
|
2594
|
-
|
|
2679
|
+
Element.prototype.replaceChild = function replaceChild(newChild, oldChild) {
|
|
2595
2680
|
return commonElementHander(this, newChild, oldChild, globalEnv.rawReplaceChild);
|
|
2596
2681
|
};
|
|
2597
2682
|
Element.prototype.append = function append(...nodes) {
|
|
@@ -2610,7 +2695,7 @@ function patchElementPrototypeMethods() {
|
|
|
2610
2695
|
}
|
|
2611
2696
|
};
|
|
2612
2697
|
// prototype methods of delete element👇
|
|
2613
|
-
|
|
2698
|
+
Element.prototype.removeChild = function removeChild(oldChild) {
|
|
2614
2699
|
if (oldChild === null || oldChild === void 0 ? void 0 : oldChild.__MICRO_APP_NAME__) {
|
|
2615
2700
|
const app = appInstanceMap.get(oldChild.__MICRO_APP_NAME__);
|
|
2616
2701
|
if (app === null || app === void 0 ? void 0 : app.container) {
|
|
@@ -2620,6 +2705,12 @@ function patchElementPrototypeMethods() {
|
|
|
2620
2705
|
}
|
|
2621
2706
|
return globalEnv.rawRemoveChild.call(this, oldChild);
|
|
2622
2707
|
};
|
|
2708
|
+
// patch cloneNode
|
|
2709
|
+
Element.prototype.cloneNode = function cloneNode(deep) {
|
|
2710
|
+
const clonedNode = globalEnv.rawCloneNode.call(this, deep);
|
|
2711
|
+
this.__MICRO_APP_NAME__ && (clonedNode.__MICRO_APP_NAME__ = this.__MICRO_APP_NAME__);
|
|
2712
|
+
return clonedNode;
|
|
2713
|
+
};
|
|
2623
2714
|
}
|
|
2624
2715
|
/**
|
|
2625
2716
|
* Mark the newly created element in the micro application
|
|
@@ -2738,12 +2829,13 @@ function releasePatches() {
|
|
|
2738
2829
|
setCurrentAppName(null);
|
|
2739
2830
|
releasePatchDocument();
|
|
2740
2831
|
Element.prototype.setAttribute = globalEnv.rawSetAttribute;
|
|
2741
|
-
|
|
2742
|
-
|
|
2743
|
-
|
|
2744
|
-
|
|
2832
|
+
Element.prototype.appendChild = globalEnv.rawAppendChild;
|
|
2833
|
+
Element.prototype.insertBefore = globalEnv.rawInsertBefore;
|
|
2834
|
+
Element.prototype.replaceChild = globalEnv.rawReplaceChild;
|
|
2835
|
+
Element.prototype.removeChild = globalEnv.rawRemoveChild;
|
|
2745
2836
|
Element.prototype.append = globalEnv.rawAppend;
|
|
2746
2837
|
Element.prototype.prepend = globalEnv.rawPrepend;
|
|
2838
|
+
Element.prototype.cloneNode = globalEnv.rawCloneNode;
|
|
2747
2839
|
}
|
|
2748
2840
|
// Set the style of micro-app-head and micro-app-body
|
|
2749
2841
|
let hasRejectMicroAppStyle = false;
|
|
@@ -2823,12 +2915,12 @@ function defineElement(tagName) {
|
|
|
2823
2915
|
this.actionsForAttributeChange(formatAttrName, formatAttrUrl, existApp);
|
|
2824
2916
|
});
|
|
2825
2917
|
}
|
|
2826
|
-
else if (this.
|
|
2918
|
+
else if (this.getKeepAliveModeResult()) {
|
|
2827
2919
|
this.handleHiddenKeepAliveApp();
|
|
2828
2920
|
this.actionsForAttributeChange(formatAttrName, formatAttrUrl, existApp);
|
|
2829
2921
|
}
|
|
2830
2922
|
else {
|
|
2831
|
-
this.handleUnmount(this.
|
|
2923
|
+
this.handleUnmount(this.getDestroyCompatibleResult(), () => {
|
|
2832
2924
|
this.actionsForAttributeChange(formatAttrName, formatAttrUrl, existApp);
|
|
2833
2925
|
});
|
|
2834
2926
|
}
|
|
@@ -2856,7 +2948,7 @@ function defineElement(tagName) {
|
|
|
2856
2948
|
// disableSandbox: whether disable sandbox, default is false
|
|
2857
2949
|
// macro: used to solve the async render problem of vue3, default is false
|
|
2858
2950
|
// baseRoute: route prefix, default is ''
|
|
2859
|
-
// keep-alive: open keep-alive mode
|
|
2951
|
+
// keep-alive: open keep-alive mode
|
|
2860
2952
|
connectedCallback() {
|
|
2861
2953
|
this.hasConnected = true;
|
|
2862
2954
|
if (!elementInstanceMap.has(this)) {
|
|
@@ -2867,13 +2959,13 @@ function defineElement(tagName) {
|
|
|
2867
2959
|
}
|
|
2868
2960
|
disconnectedCallback() {
|
|
2869
2961
|
this.hasConnected = false;
|
|
2870
|
-
// keep-alive
|
|
2871
|
-
if (this.
|
|
2962
|
+
// keep-alive
|
|
2963
|
+
if (this.getKeepAliveModeResult()) {
|
|
2872
2964
|
this.handleHiddenKeepAliveApp();
|
|
2873
2965
|
}
|
|
2874
2966
|
else {
|
|
2875
2967
|
elementInstanceMap.delete(this);
|
|
2876
|
-
this.handleUnmount(this.
|
|
2968
|
+
this.handleUnmount(this.getDestroyCompatibleResult(), () => {
|
|
2877
2969
|
if (elementInstanceMap.size === 0) {
|
|
2878
2970
|
releasePatches();
|
|
2879
2971
|
}
|
|
@@ -3097,7 +3189,27 @@ function defineElement(tagName) {
|
|
|
3097
3189
|
*/
|
|
3098
3190
|
getDisposeResult(name) {
|
|
3099
3191
|
// @ts-ignore
|
|
3100
|
-
return (this.
|
|
3192
|
+
return (this.compatibleSpecialProperties(name) || microApp[name]) && this.compatibleDisablSpecialProperties(name);
|
|
3193
|
+
}
|
|
3194
|
+
// compatible of disableScopecss & disableSandbox
|
|
3195
|
+
compatibleSpecialProperties(name) {
|
|
3196
|
+
if (name === 'disableScopecss') {
|
|
3197
|
+
return this.hasAttribute('disableScopecss') || this.hasAttribute('disable-scopecss');
|
|
3198
|
+
}
|
|
3199
|
+
else if (name === 'disableSandbox') {
|
|
3200
|
+
return this.hasAttribute('disableSandbox') || this.hasAttribute('disable-sandbox');
|
|
3201
|
+
}
|
|
3202
|
+
return this.hasAttribute(name);
|
|
3203
|
+
}
|
|
3204
|
+
// compatible of disableScopecss & disableSandbox
|
|
3205
|
+
compatibleDisablSpecialProperties(name) {
|
|
3206
|
+
if (name === 'disableScopecss') {
|
|
3207
|
+
return this.getAttribute('disableScopecss') !== 'false' && this.getAttribute('disable-scopecss') !== 'false';
|
|
3208
|
+
}
|
|
3209
|
+
else if (name === 'disableSandbox') {
|
|
3210
|
+
return this.getAttribute('disableSandbox') !== 'false' && this.getAttribute('disable-sandbox') !== 'false';
|
|
3211
|
+
}
|
|
3212
|
+
return this.getAttribute(name) !== 'false';
|
|
3101
3213
|
}
|
|
3102
3214
|
/**
|
|
3103
3215
|
* 2021-09-08
|
|
@@ -3108,6 +3220,16 @@ function defineElement(tagName) {
|
|
|
3108
3220
|
var _a, _b;
|
|
3109
3221
|
return (_b = (_a = this.getAttribute('baseroute')) !== null && _a !== void 0 ? _a : this.getAttribute('baseurl')) !== null && _b !== void 0 ? _b : '';
|
|
3110
3222
|
}
|
|
3223
|
+
// compatible of destroy
|
|
3224
|
+
getDestroyCompatibleResult() {
|
|
3225
|
+
return this.getDisposeResult('destroy') || this.getDisposeResult('destory');
|
|
3226
|
+
}
|
|
3227
|
+
/**
|
|
3228
|
+
* destroy has priority over destroy keep-alive
|
|
3229
|
+
*/
|
|
3230
|
+
getKeepAliveModeResult() {
|
|
3231
|
+
return this.getDisposeResult('keep-alive') && !this.getDestroyCompatibleResult();
|
|
3232
|
+
}
|
|
3111
3233
|
/**
|
|
3112
3234
|
* Data from the base application
|
|
3113
3235
|
*/
|
|
@@ -3292,5 +3414,5 @@ class MicroApp extends EventCenterForBaseApp {
|
|
|
3292
3414
|
var microApp = new MicroApp();
|
|
3293
3415
|
|
|
3294
3416
|
export default microApp;
|
|
3295
|
-
export { EventCenterForMicroApp, getActiveApps, getAllApps, preFetch, pureCreateElement, removeDomScope, version };
|
|
3417
|
+
export { EventCenterForMicroApp, getActiveApps, getAllApps, preFetch, pureCreateElement, removeDomScope, unmountAllApps, unmountApp, version };
|
|
3296
3418
|
//# sourceMappingURL=index.esm.js.map
|