@micro-zoe/micro-app 0.6.1 → 0.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/index.d.ts +43 -98
- package/lib/index.esm.js +832 -552
- 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 +3 -2
- package/typings/global.d.ts +3 -7
package/lib/index.esm.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
const version = '0.
|
|
1
|
+
const version = '0.8.0';
|
|
2
2
|
// do not use isUndefined
|
|
3
3
|
const isBrowser = typeof window !== 'undefined';
|
|
4
4
|
// do not use isUndefined
|
|
@@ -41,6 +41,9 @@ function isBoundFunction(target) {
|
|
|
41
41
|
function isShadowRoot(target) {
|
|
42
42
|
return typeof ShadowRoot !== 'undefined' && target instanceof ShadowRoot;
|
|
43
43
|
}
|
|
44
|
+
const rawDefineProperty = Object.defineProperty;
|
|
45
|
+
const rawDefineProperties = Object.defineProperties;
|
|
46
|
+
const rawHasOwnProperty = Object.prototype.hasOwnProperty;
|
|
44
47
|
/**
|
|
45
48
|
* format error log
|
|
46
49
|
* @param msg message
|
|
@@ -230,6 +233,17 @@ let currentMicroAppName = null;
|
|
|
230
233
|
function setCurrentAppName(appName) {
|
|
231
234
|
currentMicroAppName = appName;
|
|
232
235
|
}
|
|
236
|
+
let isWaitingForReset = false;
|
|
237
|
+
function throttleDeferForSetAppName(appName) {
|
|
238
|
+
if (!isWaitingForReset || currentMicroAppName !== appName) {
|
|
239
|
+
isWaitingForReset = true;
|
|
240
|
+
setCurrentAppName(appName);
|
|
241
|
+
defer(() => {
|
|
242
|
+
isWaitingForReset = false;
|
|
243
|
+
setCurrentAppName(null);
|
|
244
|
+
});
|
|
245
|
+
}
|
|
246
|
+
}
|
|
233
247
|
// get the currently running app.name
|
|
234
248
|
function getCurrentAppName() {
|
|
235
249
|
return currentMicroAppName;
|
|
@@ -238,10 +252,6 @@ function getCurrentAppName() {
|
|
|
238
252
|
function removeDomScope() {
|
|
239
253
|
setCurrentAppName(null);
|
|
240
254
|
}
|
|
241
|
-
// is safari browser
|
|
242
|
-
function isSafari() {
|
|
243
|
-
return /Safari/.test(navigator.userAgent) && !/Chrome/.test(navigator.userAgent);
|
|
244
|
-
}
|
|
245
255
|
/**
|
|
246
256
|
* Create pure elements
|
|
247
257
|
*/
|
|
@@ -290,6 +300,12 @@ function isUniqueElement(key) {
|
|
|
290
300
|
function getRootContainer(target) {
|
|
291
301
|
return (isShadowRoot(target) ? target.host : target);
|
|
292
302
|
}
|
|
303
|
+
/**
|
|
304
|
+
* trim start & end
|
|
305
|
+
*/
|
|
306
|
+
function trim(str) {
|
|
307
|
+
return str ? str.replace(/^\s+|\s+$/g, '') : '';
|
|
308
|
+
}
|
|
293
309
|
|
|
294
310
|
var ObservedAttrName;
|
|
295
311
|
(function (ObservedAttrName) {
|
|
@@ -326,6 +342,7 @@ var keepAliveStates;
|
|
|
326
342
|
keepAliveStates["KEEP_ALIVE_SHOW"] = "KEEP_ALIVE_SHOW";
|
|
327
343
|
keepAliveStates["KEEP_ALIVE_HIDDEN"] = "KEEP_ALIVE_HIDDEN";
|
|
328
344
|
})(keepAliveStates || (keepAliveStates = {}));
|
|
345
|
+
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,location,navigator,undefined';
|
|
329
346
|
|
|
330
347
|
/**
|
|
331
348
|
* fetch source of html, js, css
|
|
@@ -342,215 +359,355 @@ function fetchSource(url, appName = null, options = {}) {
|
|
|
342
359
|
});
|
|
343
360
|
}
|
|
344
361
|
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
const rawAppend = Element.prototype.append;
|
|
358
|
-
const rawPrepend = Element.prototype.prepend;
|
|
359
|
-
const rawCloneNode = Element.prototype.cloneNode;
|
|
360
|
-
const rawCreateElement = Document.prototype.createElement;
|
|
361
|
-
const rawCreateElementNS = Document.prototype.createElementNS;
|
|
362
|
-
const rawCreateDocumentFragment = Document.prototype.createDocumentFragment;
|
|
363
|
-
const rawQuerySelector = Document.prototype.querySelector;
|
|
364
|
-
const rawQuerySelectorAll = Document.prototype.querySelectorAll;
|
|
365
|
-
const rawGetElementById = Document.prototype.getElementById;
|
|
366
|
-
const rawGetElementsByClassName = Document.prototype.getElementsByClassName;
|
|
367
|
-
const rawGetElementsByTagName = Document.prototype.getElementsByTagName;
|
|
368
|
-
const rawGetElementsByName = Document.prototype.getElementsByName;
|
|
369
|
-
const rawWindow = Function('return window')();
|
|
370
|
-
const rawDocument = Function('return document')();
|
|
371
|
-
const supportModuleScript = isSupportModuleScript();
|
|
372
|
-
const templateStyle = rawDocument.body.querySelector('#micro-app-template-style');
|
|
373
|
-
/**
|
|
374
|
-
* save effect raw methods
|
|
375
|
-
* pay attention to this binding, especially setInterval, setTimeout, clearInterval, clearTimeout
|
|
376
|
-
*/
|
|
377
|
-
const rawWindowAddEventListener = rawWindow.addEventListener;
|
|
378
|
-
const rawWindowRemoveEventListener = rawWindow.removeEventListener;
|
|
379
|
-
const rawSetInterval = rawWindow.setInterval;
|
|
380
|
-
const rawSetTimeout = rawWindow.setTimeout;
|
|
381
|
-
const rawClearInterval = rawWindow.clearInterval;
|
|
382
|
-
const rawClearTimeout = rawWindow.clearTimeout;
|
|
383
|
-
const rawDocumentAddEventListener = rawDocument.addEventListener;
|
|
384
|
-
const rawDocumentRemoveEventListener = rawDocument.removeEventListener;
|
|
385
|
-
// mark current application as base application
|
|
386
|
-
window.__MICRO_APP_BASE_APPLICATION__ = true;
|
|
387
|
-
Object.assign(globalEnv, {
|
|
388
|
-
// source/patch
|
|
389
|
-
rawSetAttribute,
|
|
390
|
-
rawAppendChild,
|
|
391
|
-
rawInsertBefore,
|
|
392
|
-
rawReplaceChild,
|
|
393
|
-
rawRemoveChild,
|
|
394
|
-
rawAppend,
|
|
395
|
-
rawPrepend,
|
|
396
|
-
rawCloneNode,
|
|
397
|
-
rawCreateElement,
|
|
398
|
-
rawCreateElementNS,
|
|
399
|
-
rawCreateDocumentFragment,
|
|
400
|
-
rawQuerySelector,
|
|
401
|
-
rawQuerySelectorAll,
|
|
402
|
-
rawGetElementById,
|
|
403
|
-
rawGetElementsByClassName,
|
|
404
|
-
rawGetElementsByTagName,
|
|
405
|
-
rawGetElementsByName,
|
|
406
|
-
// common global vars
|
|
407
|
-
rawWindow,
|
|
408
|
-
rawDocument,
|
|
409
|
-
supportModuleScript,
|
|
410
|
-
templateStyle,
|
|
411
|
-
// sandbox/effect
|
|
412
|
-
rawWindowAddEventListener,
|
|
413
|
-
rawWindowRemoveEventListener,
|
|
414
|
-
rawSetInterval,
|
|
415
|
-
rawSetTimeout,
|
|
416
|
-
rawClearInterval,
|
|
417
|
-
rawClearTimeout,
|
|
418
|
-
rawDocumentAddEventListener,
|
|
419
|
-
rawDocumentRemoveEventListener,
|
|
420
|
-
});
|
|
421
|
-
}
|
|
422
|
-
}
|
|
423
|
-
|
|
424
|
-
// https://developer.mozilla.org/zh-CN/docs/Web/API/CSSRule
|
|
425
|
-
var CSSRuleType;
|
|
426
|
-
(function (CSSRuleType) {
|
|
427
|
-
CSSRuleType[CSSRuleType["STYLE_RULE"] = 1] = "STYLE_RULE";
|
|
428
|
-
CSSRuleType[CSSRuleType["MEDIA_RULE"] = 4] = "MEDIA_RULE";
|
|
429
|
-
CSSRuleType[CSSRuleType["SUPPORTS_RULE"] = 12] = "SUPPORTS_RULE";
|
|
430
|
-
})(CSSRuleType || (CSSRuleType = {}));
|
|
431
|
-
/**
|
|
432
|
-
* Bind css scope
|
|
433
|
-
* Special case:
|
|
434
|
-
* 1. html-abc | abc-html
|
|
435
|
-
* 2. html body.abc
|
|
436
|
-
* 3. abchtml | htmlabc | abcbody | bodyabc
|
|
437
|
-
* 4. html + body | html > body | html.body | html[name=xx] | body[name=xx]
|
|
438
|
-
* 5. xxx, html xxx, body xxx
|
|
439
|
-
*
|
|
440
|
-
* TODO: BUG
|
|
441
|
-
.test-b {
|
|
442
|
-
border: 1px solid var(--color-a);
|
|
443
|
-
border-bottom-color: var(--color-b);
|
|
444
|
-
}
|
|
445
|
-
*/
|
|
446
|
-
function scopedStyleRule(rule, prefix) {
|
|
447
|
-
const { selectorText, cssText } = rule;
|
|
448
|
-
if (/^((html[\s>~,]+body)|(html|body|:root))$/.test(selectorText)) {
|
|
449
|
-
return cssText.replace(/^((html[\s>~,]+body)|(html|body|:root))/, prefix);
|
|
450
|
-
}
|
|
451
|
-
else if (selectorText === '*') {
|
|
452
|
-
return cssText.replace('*', `${prefix} *`);
|
|
453
|
-
}
|
|
454
|
-
const builtInRootSelectorRE = /(^|\s+)((html[\s>~]+body)|(html|body|:root))(?=[\s>~]+|$)/;
|
|
455
|
-
return cssText.replace(/^[\s\S]+{/, (selectors) => {
|
|
456
|
-
return selectors.replace(/(^|,)([^,]+)/g, (all, $1, $2) => {
|
|
457
|
-
if (builtInRootSelectorRE.test($2)) {
|
|
458
|
-
// body[name=xx]|body.xx|body#xx etc. do not need to handle
|
|
459
|
-
return all.replace(builtInRootSelectorRE, prefix);
|
|
460
|
-
}
|
|
461
|
-
return `${$1} ${prefix} ${$2.replace(/^\s*/, '')}`;
|
|
462
|
-
});
|
|
463
|
-
});
|
|
362
|
+
// common reg
|
|
363
|
+
const rootSelectorREG = /(^|\s+)(html|:root)(?=[\s>~[.#:]+|$)/;
|
|
364
|
+
const bodySelectorREG = /(^|\s+)((html[\s>~]+body)|body)(?=[\s>~[.#:]+|$)/;
|
|
365
|
+
const cssUrlREG = /url\(["']?([^)"']+)["']?\)/gm;
|
|
366
|
+
function parseError(msg, linkpath) {
|
|
367
|
+
msg = linkpath ? `${linkpath}:${msg}` : msg;
|
|
368
|
+
const err = new Error(msg);
|
|
369
|
+
err.reason = msg;
|
|
370
|
+
if (linkpath) {
|
|
371
|
+
err.filename = linkpath;
|
|
372
|
+
}
|
|
373
|
+
throw err;
|
|
464
374
|
}
|
|
465
375
|
/**
|
|
466
|
-
*
|
|
467
|
-
*
|
|
468
|
-
*
|
|
469
|
-
*
|
|
470
|
-
* @param linkpath link resource address, if it is the style converted from link, it will have linkpath
|
|
376
|
+
* Reference resources https://github.com/reworkcss/css
|
|
377
|
+
* CSSParser mainly deals with 3 scenes: styleRule, @, and comment
|
|
378
|
+
* And scopecss deals with 2 scenes: selector & url
|
|
379
|
+
* It can also disable scopecss with inline comments
|
|
471
380
|
*/
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
381
|
+
class CSSParser {
|
|
382
|
+
constructor() {
|
|
383
|
+
this.cssText = ''; // css content
|
|
384
|
+
this.prefix = ''; // prefix as micro-app[name=xxx]
|
|
385
|
+
this.baseURI = ''; // domain name
|
|
386
|
+
this.linkpath = ''; // link resource address, if it is the style converted from link, it will have linkpath
|
|
387
|
+
this.result = ''; // parsed cssText
|
|
388
|
+
this.scopecssDisable = false; // use block comments /* scopecss-disable */ to disable scopecss in your file, and use /* scopecss-enable */ to enable scopecss
|
|
389
|
+
this.scopecssDisableSelectors = []; // disable or enable scopecss for specific selectors
|
|
390
|
+
this.scopecssDisableNextLine = false; // use block comments /* scopecss-disable-next-line */ to disable scopecss on a specific line
|
|
391
|
+
// https://developer.mozilla.org/en-US/docs/Web/API/CSSMediaRule
|
|
392
|
+
this.mediaRule = this.createMatcherForAtRuleWithChildRule(/^@media *([^{]+)/, 'media');
|
|
393
|
+
// https://developer.mozilla.org/en-US/docs/Web/API/CSSSupportsRule
|
|
394
|
+
this.supportsRule = this.createMatcherForAtRuleWithChildRule(/^@supports *([^{]+)/, 'supports');
|
|
395
|
+
this.documentRule = this.createMatcherForAtRuleWithChildRule(/^@([-\w]+)?document *([^{]+)/, 'document');
|
|
396
|
+
this.hostRule = this.createMatcherForAtRuleWithChildRule(/^@host\s*/, 'host');
|
|
397
|
+
// https://developer.mozilla.org/en-US/docs/Web/API/CSSImportRule
|
|
398
|
+
this.importRule = this.createMatcherForNoneBraceAtRule('import');
|
|
399
|
+
// Removed in most browsers
|
|
400
|
+
this.charsetRule = this.createMatcherForNoneBraceAtRule('charset');
|
|
401
|
+
// https://developer.mozilla.org/en-US/docs/Web/API/CSSNamespaceRule
|
|
402
|
+
this.namespaceRule = this.createMatcherForNoneBraceAtRule('namespace');
|
|
403
|
+
}
|
|
404
|
+
exec(cssText, prefix, baseURI, linkpath) {
|
|
405
|
+
this.cssText = cssText;
|
|
406
|
+
this.prefix = prefix;
|
|
407
|
+
this.baseURI = baseURI;
|
|
408
|
+
this.linkpath = linkpath || '';
|
|
409
|
+
this.matchRules();
|
|
410
|
+
return this.result;
|
|
411
|
+
}
|
|
412
|
+
reset() {
|
|
413
|
+
this.cssText = this.prefix = this.baseURI = this.linkpath = this.result = '';
|
|
414
|
+
this.scopecssDisable = this.scopecssDisableNextLine = false;
|
|
415
|
+
this.scopecssDisableSelectors = [];
|
|
416
|
+
}
|
|
417
|
+
// core action for match rules
|
|
418
|
+
matchRules() {
|
|
419
|
+
this.matchLeadingSpaces();
|
|
420
|
+
this.matchComments();
|
|
421
|
+
while (this.cssText.length &&
|
|
422
|
+
this.cssText.charAt(0) !== '}' &&
|
|
423
|
+
(this.matchAtRule() || this.matchStyleRule())) {
|
|
424
|
+
this.matchComments();
|
|
425
|
+
}
|
|
426
|
+
}
|
|
427
|
+
// https://developer.mozilla.org/en-US/docs/Web/API/CSSStyleRule
|
|
428
|
+
matchStyleRule() {
|
|
429
|
+
const selectorList = this.formatSelector();
|
|
430
|
+
// reset scopecssDisableNextLine
|
|
431
|
+
this.scopecssDisableNextLine = false;
|
|
432
|
+
if (!selectorList)
|
|
433
|
+
return parseError('selector missing', this.linkpath);
|
|
434
|
+
this.result += selectorList.join(', ');
|
|
435
|
+
this.matchComments();
|
|
436
|
+
this.styleDeclarations();
|
|
437
|
+
this.matchLeadingSpaces();
|
|
438
|
+
return true;
|
|
439
|
+
}
|
|
440
|
+
// https://developer.mozilla.org/en-US/docs/Web/API/CSSStyleDeclaration
|
|
441
|
+
styleDeclarations() {
|
|
442
|
+
if (!this.matchOpenBrace())
|
|
443
|
+
return parseError("Declaration missing '{'", this.linkpath);
|
|
444
|
+
this.matchComments();
|
|
445
|
+
while (this.styleDeclaration()) {
|
|
446
|
+
this.matchComments();
|
|
447
|
+
}
|
|
448
|
+
if (!this.matchCloseBrace())
|
|
449
|
+
return parseError("Declaration missing '}'", this.linkpath);
|
|
450
|
+
return true;
|
|
451
|
+
}
|
|
452
|
+
// match one styleDeclaration at a time
|
|
453
|
+
styleDeclaration() {
|
|
454
|
+
// css property
|
|
455
|
+
if (!this.commonMatch(/^(\*?[-#\/\*\\\w]+(\[[0-9a-z_-]+\])?)\s*/))
|
|
456
|
+
return false;
|
|
457
|
+
// match :
|
|
458
|
+
if (!this.commonMatch(/^:\s*/))
|
|
459
|
+
return parseError("property missing ':'", this.linkpath);
|
|
460
|
+
// match css value
|
|
461
|
+
const r = this.commonMatch(/^((?:'(?:\\'|.)*?'|"(?:\\"|.)*?"|\([^\)]*?\)|[^};])+)/, true);
|
|
462
|
+
let cssValue = r ? r[0] : '';
|
|
463
|
+
if (!this.scopecssDisableNextLine &&
|
|
464
|
+
(!this.scopecssDisable || this.scopecssDisableSelectors.length)) {
|
|
465
|
+
cssValue = cssValue.replace(cssUrlREG, (all, $1) => {
|
|
466
|
+
if (/^((data|blob):|#)/.test($1) || /^(https?:)?\/\//.test($1)) {
|
|
484
467
|
return all;
|
|
485
468
|
}
|
|
469
|
+
// ./a/b.png ../a/b.png a/b.png
|
|
470
|
+
if (/^((\.\.?\/)|[^/])/.test($1) && this.linkpath) {
|
|
471
|
+
this.baseURI = getLinkFileDir(this.linkpath);
|
|
472
|
+
}
|
|
473
|
+
return `url("${CompletionPath($1, this.baseURI)}")`;
|
|
474
|
+
});
|
|
475
|
+
}
|
|
476
|
+
// reset scopecssDisableNextLine
|
|
477
|
+
this.scopecssDisableNextLine = false;
|
|
478
|
+
this.result += cssValue;
|
|
479
|
+
this.matchLeadingSpaces();
|
|
480
|
+
this.commonMatch(/^[;\s]*/);
|
|
481
|
+
return true;
|
|
482
|
+
}
|
|
483
|
+
formatSelector() {
|
|
484
|
+
const m = this.commonMatch(/^([^{]+)/, true);
|
|
485
|
+
if (!m)
|
|
486
|
+
return false;
|
|
487
|
+
return trim(m[0])
|
|
488
|
+
.replace(/\/\*([^*]|[\r\n]|(\*+([^*/]|[\r\n])))*\*\/+/g, '')
|
|
489
|
+
.replace(/"(?:\\"|[^"])*"|'(?:\\'|[^'])*'/g, (r) => {
|
|
490
|
+
return r.replace(/,/g, '\u200C');
|
|
491
|
+
})
|
|
492
|
+
.split(/\s*(?![^(]*\)),\s*/)
|
|
493
|
+
.map((s) => {
|
|
494
|
+
const selectorText = s.replace(/\u200C/g, ',');
|
|
495
|
+
if (this.scopecssDisableNextLine) {
|
|
496
|
+
return selectorText;
|
|
497
|
+
}
|
|
498
|
+
else if (this.scopecssDisable) {
|
|
499
|
+
if (!this.scopecssDisableSelectors.length ||
|
|
500
|
+
this.scopecssDisableSelectors.includes(selectorText)) {
|
|
501
|
+
return selectorText;
|
|
502
|
+
}
|
|
503
|
+
}
|
|
504
|
+
if (selectorText === '*') {
|
|
505
|
+
return this.prefix + ' *';
|
|
506
|
+
}
|
|
507
|
+
else if (bodySelectorREG.test(selectorText)) {
|
|
508
|
+
return selectorText.replace(bodySelectorREG, this.prefix + ' micro-app-body');
|
|
509
|
+
}
|
|
510
|
+
else if (rootSelectorREG.test(selectorText)) { // ignore root selector
|
|
511
|
+
return selectorText;
|
|
512
|
+
}
|
|
513
|
+
return this.prefix + ' ' + selectorText;
|
|
514
|
+
});
|
|
515
|
+
}
|
|
516
|
+
matchAtRule() {
|
|
517
|
+
if (this.cssText[0] !== '@')
|
|
518
|
+
return false;
|
|
519
|
+
// reset scopecssDisableNextLine
|
|
520
|
+
this.scopecssDisableNextLine = false;
|
|
521
|
+
return this.keyframesRule() ||
|
|
522
|
+
this.mediaRule() ||
|
|
523
|
+
this.custommediaRule() ||
|
|
524
|
+
this.supportsRule() ||
|
|
525
|
+
this.importRule() ||
|
|
526
|
+
this.charsetRule() ||
|
|
527
|
+
this.namespaceRule() ||
|
|
528
|
+
this.documentRule() ||
|
|
529
|
+
this.pageRule() ||
|
|
530
|
+
this.hostRule() ||
|
|
531
|
+
this.fontfaceRule();
|
|
532
|
+
}
|
|
533
|
+
// https://developer.mozilla.org/en-US/docs/Web/API/CSSKeyframesRule
|
|
534
|
+
keyframesRule() {
|
|
535
|
+
if (!this.commonMatch(/^@([-\w]+)?keyframes\s*/))
|
|
536
|
+
return false;
|
|
537
|
+
if (!this.commonMatch(/^([-\w]+)\s*/))
|
|
538
|
+
return parseError('@keyframes missing name', this.linkpath);
|
|
539
|
+
this.matchComments();
|
|
540
|
+
if (!this.matchOpenBrace())
|
|
541
|
+
return parseError("@keyframes missing '{'", this.linkpath);
|
|
542
|
+
this.matchComments();
|
|
543
|
+
while (this.keyframeRule()) {
|
|
544
|
+
this.matchComments();
|
|
545
|
+
}
|
|
546
|
+
if (!this.matchCloseBrace())
|
|
547
|
+
return parseError("@keyframes missing '}'", this.linkpath);
|
|
548
|
+
this.matchLeadingSpaces();
|
|
549
|
+
return true;
|
|
550
|
+
}
|
|
551
|
+
keyframeRule() {
|
|
552
|
+
let r;
|
|
553
|
+
const valList = [];
|
|
554
|
+
while (r = this.commonMatch(/^((\d+\.\d+|\.\d+|\d+)%?|[a-z]+)\s*/)) {
|
|
555
|
+
valList.push(r[1]);
|
|
556
|
+
this.commonMatch(/^,\s*/);
|
|
557
|
+
}
|
|
558
|
+
if (!valList.length)
|
|
559
|
+
return false;
|
|
560
|
+
this.styleDeclarations();
|
|
561
|
+
this.matchLeadingSpaces();
|
|
562
|
+
return true;
|
|
563
|
+
}
|
|
564
|
+
// https://github.com/postcss/postcss-custom-media
|
|
565
|
+
custommediaRule() {
|
|
566
|
+
if (!this.commonMatch(/^@custom-media\s+(--[^\s]+)\s*([^{;]+);/))
|
|
567
|
+
return false;
|
|
568
|
+
this.matchLeadingSpaces();
|
|
569
|
+
return true;
|
|
570
|
+
}
|
|
571
|
+
// https://developer.mozilla.org/en-US/docs/Web/API/CSSPageRule
|
|
572
|
+
pageRule() {
|
|
573
|
+
if (!this.commonMatch(/^@page */))
|
|
574
|
+
return false;
|
|
575
|
+
this.formatSelector();
|
|
576
|
+
// reset scopecssDisableNextLine
|
|
577
|
+
this.scopecssDisableNextLine = false;
|
|
578
|
+
return this.commonHandlerForAtRuleWithSelfRule('page');
|
|
579
|
+
}
|
|
580
|
+
// https://developer.mozilla.org/en-US/docs/Web/API/CSSFontFaceRule
|
|
581
|
+
fontfaceRule() {
|
|
582
|
+
if (!this.commonMatch(/^@font-face\s*/))
|
|
583
|
+
return false;
|
|
584
|
+
return this.commonHandlerForAtRuleWithSelfRule('font-face');
|
|
585
|
+
}
|
|
586
|
+
// common matcher for @media, @supports, @document, @host
|
|
587
|
+
createMatcherForAtRuleWithChildRule(reg, name) {
|
|
588
|
+
return () => {
|
|
589
|
+
if (!this.commonMatch(reg))
|
|
590
|
+
return false;
|
|
591
|
+
if (!this.matchOpenBrace())
|
|
592
|
+
return parseError(`@${name} missing '{'`, this.linkpath);
|
|
593
|
+
this.matchComments();
|
|
594
|
+
this.matchRules();
|
|
595
|
+
if (!this.matchCloseBrace())
|
|
596
|
+
return parseError(`@${name} missing '}'`, this.linkpath);
|
|
597
|
+
this.matchLeadingSpaces();
|
|
598
|
+
return true;
|
|
599
|
+
};
|
|
600
|
+
}
|
|
601
|
+
// common matcher for @import, @charset, @namespace
|
|
602
|
+
createMatcherForNoneBraceAtRule(name) {
|
|
603
|
+
const reg = new RegExp('^@' + name + '\\s*([^;]+);');
|
|
604
|
+
return () => {
|
|
605
|
+
if (!this.commonMatch(reg))
|
|
606
|
+
return false;
|
|
607
|
+
this.matchLeadingSpaces();
|
|
608
|
+
return false;
|
|
609
|
+
};
|
|
610
|
+
}
|
|
611
|
+
// common handler for @font-face, @page
|
|
612
|
+
commonHandlerForAtRuleWithSelfRule(name) {
|
|
613
|
+
if (!this.matchOpenBrace())
|
|
614
|
+
return parseError(`@${name} missing '{'`, this.linkpath);
|
|
615
|
+
this.matchComments();
|
|
616
|
+
while (this.styleDeclaration()) {
|
|
617
|
+
this.matchComments();
|
|
618
|
+
}
|
|
619
|
+
if (!this.matchCloseBrace())
|
|
620
|
+
return parseError(`@${name} missing '}'`, this.linkpath);
|
|
621
|
+
this.matchLeadingSpaces();
|
|
622
|
+
return true;
|
|
623
|
+
}
|
|
624
|
+
// match and slice comments
|
|
625
|
+
matchComments() {
|
|
626
|
+
while (this.matchComment())
|
|
627
|
+
;
|
|
628
|
+
}
|
|
629
|
+
// css comment
|
|
630
|
+
matchComment() {
|
|
631
|
+
if (this.cssText.charAt(0) !== '/' || this.cssText.charAt(1) !== '*')
|
|
632
|
+
return false;
|
|
633
|
+
// reset scopecssDisableNextLine
|
|
634
|
+
this.scopecssDisableNextLine = false;
|
|
635
|
+
let i = 2;
|
|
636
|
+
while (this.cssText.charAt(i) !== '' && (this.cssText.charAt(i) !== '*' || this.cssText.charAt(i + 1) !== '/'))
|
|
637
|
+
++i;
|
|
638
|
+
i += 2;
|
|
639
|
+
if (this.cssText.charAt(i - 1) === '') {
|
|
640
|
+
return parseError('End of comment missing', this.linkpath);
|
|
641
|
+
}
|
|
642
|
+
// get comment content
|
|
643
|
+
let commentText = this.cssText.slice(2, i - 2);
|
|
644
|
+
this.result += `/*${commentText}*/`;
|
|
645
|
+
commentText = trim(commentText.replace(/^\s*!/, ''));
|
|
646
|
+
// set ignore config
|
|
647
|
+
if (commentText === 'scopecss-disable-next-line') {
|
|
648
|
+
this.scopecssDisableNextLine = true;
|
|
649
|
+
}
|
|
650
|
+
else if (/^scopecss-disable/.test(commentText)) {
|
|
651
|
+
if (commentText === 'scopecss-disable') {
|
|
652
|
+
this.scopecssDisable = true;
|
|
486
653
|
}
|
|
487
654
|
else {
|
|
488
|
-
|
|
655
|
+
this.scopecssDisable = true;
|
|
656
|
+
const ignoreRules = commentText.replace('scopecss-disable', '').split(',');
|
|
657
|
+
ignoreRules.forEach((rule) => {
|
|
658
|
+
this.scopecssDisableSelectors.push(trim(rule));
|
|
659
|
+
});
|
|
489
660
|
}
|
|
490
661
|
}
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
662
|
+
else if (commentText === 'scopecss-enable') {
|
|
663
|
+
this.scopecssDisable = false;
|
|
664
|
+
this.scopecssDisableSelectors = [];
|
|
494
665
|
}
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
result += scopedPackRule(rule, prefix, 'supports');
|
|
520
|
-
break;
|
|
521
|
-
default:
|
|
522
|
-
result += rule.cssText;
|
|
523
|
-
break;
|
|
524
|
-
}
|
|
525
|
-
}
|
|
526
|
-
return result.replace(/^\s+/, '');
|
|
666
|
+
this.cssText = this.cssText.slice(i);
|
|
667
|
+
this.matchLeadingSpaces();
|
|
668
|
+
return true;
|
|
669
|
+
}
|
|
670
|
+
commonMatch(reg, skip = false) {
|
|
671
|
+
const matchArray = reg.exec(this.cssText);
|
|
672
|
+
if (!matchArray)
|
|
673
|
+
return;
|
|
674
|
+
const matchStr = matchArray[0];
|
|
675
|
+
this.cssText = this.cssText.slice(matchStr.length);
|
|
676
|
+
if (!skip)
|
|
677
|
+
this.result += matchStr;
|
|
678
|
+
return matchArray;
|
|
679
|
+
}
|
|
680
|
+
matchOpenBrace() {
|
|
681
|
+
return this.commonMatch(/^{\s*/);
|
|
682
|
+
}
|
|
683
|
+
matchCloseBrace() {
|
|
684
|
+
return this.commonMatch(/^}/);
|
|
685
|
+
}
|
|
686
|
+
// match and slice the leading spaces
|
|
687
|
+
matchLeadingSpaces() {
|
|
688
|
+
this.commonMatch(/^\s*/);
|
|
689
|
+
}
|
|
527
690
|
}
|
|
528
691
|
/**
|
|
529
692
|
* common method of bind CSS
|
|
530
693
|
*/
|
|
531
|
-
function commonAction(
|
|
532
|
-
var _a, _b;
|
|
694
|
+
function commonAction(styleElement, appName, prefix, baseURI, linkpath) {
|
|
533
695
|
if (!styleElement.__MICRO_APP_HAS_SCOPED__) {
|
|
534
|
-
const rules = Array.from((_b = (_a = templateStyle.sheet) === null || _a === void 0 ? void 0 : _a.cssRules) !== null && _b !== void 0 ? _b : []);
|
|
535
|
-
let result = scopedHost(scopedRule(rules, prefix), baseURI, originContent, linkpath);
|
|
536
|
-
/**
|
|
537
|
-
* Solve the problem of missing content quotes in some Safari browsers
|
|
538
|
-
* docs: https://developer.mozilla.org/zh-CN/docs/Web/CSS/content
|
|
539
|
-
* If there are still problems, it is recommended to use the attr()
|
|
540
|
-
*/
|
|
541
|
-
if (isSafari()) {
|
|
542
|
-
result = result.replace(/([;{]\s*content:\s*)([^\s"][^";}]*)/gm, (all, $1, $2) => {
|
|
543
|
-
if ($2 === 'none' ||
|
|
544
|
-
/^(url\()|(counter\()|(attr\()|(open-quote)|(close-quote)/.test($2)) {
|
|
545
|
-
return all;
|
|
546
|
-
}
|
|
547
|
-
return `${$1}"${$2}"`;
|
|
548
|
-
});
|
|
549
|
-
}
|
|
550
|
-
styleElement.textContent = result;
|
|
551
696
|
styleElement.__MICRO_APP_HAS_SCOPED__ = true;
|
|
697
|
+
let result = null;
|
|
698
|
+
try {
|
|
699
|
+
result = parser.exec(styleElement.textContent, prefix, baseURI, linkpath);
|
|
700
|
+
parser.reset();
|
|
701
|
+
}
|
|
702
|
+
catch (e) {
|
|
703
|
+
parser.reset();
|
|
704
|
+
logError('CSSParser: An error occurred while parsing CSS', appName, e);
|
|
705
|
+
}
|
|
706
|
+
if (result)
|
|
707
|
+
styleElement.textContent = result;
|
|
552
708
|
}
|
|
553
709
|
}
|
|
710
|
+
let parser;
|
|
554
711
|
/**
|
|
555
712
|
* scopedCSS
|
|
556
713
|
* @param styleElement target style element
|
|
@@ -559,27 +716,18 @@ function commonAction(templateStyle, styleElement, originContent, prefix, baseUR
|
|
|
559
716
|
function scopedCSS(styleElement, app) {
|
|
560
717
|
if (app.scopecss) {
|
|
561
718
|
const prefix = `${microApp.tagName}[name=${app.name}]`;
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
globalEnv.templateStyle = templateStyle = pureCreateElement('style');
|
|
565
|
-
templateStyle.setAttribute('id', 'micro-app-template-style');
|
|
566
|
-
globalEnv.rawDocument.body.appendChild(templateStyle);
|
|
567
|
-
templateStyle.sheet.disabled = true;
|
|
568
|
-
}
|
|
719
|
+
if (!parser)
|
|
720
|
+
parser = new CSSParser();
|
|
569
721
|
if (styleElement.textContent) {
|
|
570
|
-
|
|
571
|
-
commonAction(templateStyle, styleElement, styleElement.textContent, prefix, app.url, styleElement.__MICRO_APP_LINK_PATH__);
|
|
572
|
-
templateStyle.textContent = '';
|
|
722
|
+
commonAction(styleElement, app.name, prefix, app.url, styleElement.__MICRO_APP_LINK_PATH__);
|
|
573
723
|
}
|
|
574
724
|
else {
|
|
575
725
|
const observer = new MutationObserver(function () {
|
|
576
|
-
var _a, _b;
|
|
577
726
|
observer.disconnect();
|
|
578
|
-
// styled-component will
|
|
579
|
-
if (
|
|
580
|
-
styleElement.
|
|
581
|
-
|
|
582
|
-
commonAction(styleElement, styleElement, styleElement.textContent, prefix, app.url, styleElement.__MICRO_APP_LINK_PATH__);
|
|
727
|
+
// styled-component will be ignore
|
|
728
|
+
if (styleElement.textContent && !styleElement.hasAttribute('data-styled')) {
|
|
729
|
+
commonAction(styleElement, app.name, prefix, app.url, styleElement.__MICRO_APP_LINK_PATH__);
|
|
730
|
+
}
|
|
583
731
|
});
|
|
584
732
|
observer.observe(styleElement, { childList: true });
|
|
585
733
|
}
|
|
@@ -718,7 +866,12 @@ function fetchLinkSuccess(url, info, data, microAppHead, app) {
|
|
|
718
866
|
styleLink.textContent = data;
|
|
719
867
|
styleLink.__MICRO_APP_LINK_PATH__ = url;
|
|
720
868
|
styleLink.setAttribute('data-origin-href', url);
|
|
721
|
-
|
|
869
|
+
if (info.placeholder.parentNode) {
|
|
870
|
+
info.placeholder.parentNode.replaceChild(scopedCSS(styleLink, app), info.placeholder);
|
|
871
|
+
}
|
|
872
|
+
else {
|
|
873
|
+
microAppHead.appendChild(scopedCSS(styleLink, app));
|
|
874
|
+
}
|
|
722
875
|
info.placeholder = null;
|
|
723
876
|
info.code = data;
|
|
724
877
|
}
|
|
@@ -759,6 +912,95 @@ function foramtDynamicLink(url, info, app, originLink, replaceStyle) {
|
|
|
759
912
|
});
|
|
760
913
|
}
|
|
761
914
|
|
|
915
|
+
const globalEnv = {};
|
|
916
|
+
/**
|
|
917
|
+
* Note loop nesting
|
|
918
|
+
* Only prototype or unique values can be put here
|
|
919
|
+
*/
|
|
920
|
+
function initGlobalEnv() {
|
|
921
|
+
if (isBrowser) {
|
|
922
|
+
/**
|
|
923
|
+
* save patch raw methods
|
|
924
|
+
* pay attention to this binding
|
|
925
|
+
*/
|
|
926
|
+
const rawSetAttribute = Element.prototype.setAttribute;
|
|
927
|
+
const rawAppendChild = Element.prototype.appendChild;
|
|
928
|
+
const rawInsertBefore = Element.prototype.insertBefore;
|
|
929
|
+
const rawReplaceChild = Element.prototype.replaceChild;
|
|
930
|
+
const rawRemoveChild = Element.prototype.removeChild;
|
|
931
|
+
const rawAppend = Element.prototype.append;
|
|
932
|
+
const rawPrepend = Element.prototype.prepend;
|
|
933
|
+
const rawCloneNode = Element.prototype.cloneNode;
|
|
934
|
+
const rawCreateElement = Document.prototype.createElement;
|
|
935
|
+
const rawCreateElementNS = Document.prototype.createElementNS;
|
|
936
|
+
const rawCreateDocumentFragment = Document.prototype.createDocumentFragment;
|
|
937
|
+
const rawQuerySelector = Document.prototype.querySelector;
|
|
938
|
+
const rawQuerySelectorAll = Document.prototype.querySelectorAll;
|
|
939
|
+
const rawGetElementById = Document.prototype.getElementById;
|
|
940
|
+
const rawGetElementsByClassName = Document.prototype.getElementsByClassName;
|
|
941
|
+
const rawGetElementsByTagName = Document.prototype.getElementsByTagName;
|
|
942
|
+
const rawGetElementsByName = Document.prototype.getElementsByName;
|
|
943
|
+
const ImageProxy = new Proxy(Image, {
|
|
944
|
+
construct(Target, args) {
|
|
945
|
+
const elementImage = new Target(...args);
|
|
946
|
+
elementImage.__MICRO_APP_NAME__ = getCurrentAppName();
|
|
947
|
+
return elementImage;
|
|
948
|
+
},
|
|
949
|
+
});
|
|
950
|
+
const rawWindow = Function('return window')();
|
|
951
|
+
const rawDocument = Function('return document')();
|
|
952
|
+
const supportModuleScript = isSupportModuleScript();
|
|
953
|
+
/**
|
|
954
|
+
* save effect raw methods
|
|
955
|
+
* pay attention to this binding, especially setInterval, setTimeout, clearInterval, clearTimeout
|
|
956
|
+
*/
|
|
957
|
+
const rawWindowAddEventListener = rawWindow.addEventListener;
|
|
958
|
+
const rawWindowRemoveEventListener = rawWindow.removeEventListener;
|
|
959
|
+
const rawSetInterval = rawWindow.setInterval;
|
|
960
|
+
const rawSetTimeout = rawWindow.setTimeout;
|
|
961
|
+
const rawClearInterval = rawWindow.clearInterval;
|
|
962
|
+
const rawClearTimeout = rawWindow.clearTimeout;
|
|
963
|
+
const rawDocumentAddEventListener = rawDocument.addEventListener;
|
|
964
|
+
const rawDocumentRemoveEventListener = rawDocument.removeEventListener;
|
|
965
|
+
// mark current application as base application
|
|
966
|
+
window.__MICRO_APP_BASE_APPLICATION__ = true;
|
|
967
|
+
Object.assign(globalEnv, {
|
|
968
|
+
// source/patch
|
|
969
|
+
rawSetAttribute,
|
|
970
|
+
rawAppendChild,
|
|
971
|
+
rawInsertBefore,
|
|
972
|
+
rawReplaceChild,
|
|
973
|
+
rawRemoveChild,
|
|
974
|
+
rawAppend,
|
|
975
|
+
rawPrepend,
|
|
976
|
+
rawCloneNode,
|
|
977
|
+
rawCreateElement,
|
|
978
|
+
rawCreateElementNS,
|
|
979
|
+
rawCreateDocumentFragment,
|
|
980
|
+
rawQuerySelector,
|
|
981
|
+
rawQuerySelectorAll,
|
|
982
|
+
rawGetElementById,
|
|
983
|
+
rawGetElementsByClassName,
|
|
984
|
+
rawGetElementsByTagName,
|
|
985
|
+
rawGetElementsByName,
|
|
986
|
+
ImageProxy,
|
|
987
|
+
// common global vars
|
|
988
|
+
rawWindow,
|
|
989
|
+
rawDocument,
|
|
990
|
+
supportModuleScript,
|
|
991
|
+
// sandbox/effect
|
|
992
|
+
rawWindowAddEventListener,
|
|
993
|
+
rawWindowRemoveEventListener,
|
|
994
|
+
rawSetInterval,
|
|
995
|
+
rawSetTimeout,
|
|
996
|
+
rawClearInterval,
|
|
997
|
+
rawClearTimeout,
|
|
998
|
+
rawDocumentAddEventListener,
|
|
999
|
+
rawDocumentRemoveEventListener,
|
|
1000
|
+
});
|
|
1001
|
+
}
|
|
1002
|
+
}
|
|
1003
|
+
|
|
762
1004
|
// Global scripts, reuse across apps
|
|
763
1005
|
const globalScripts = new Map();
|
|
764
1006
|
/**
|
|
@@ -909,17 +1151,21 @@ function execScripts(scriptList, app, initedHook) {
|
|
|
909
1151
|
}
|
|
910
1152
|
}
|
|
911
1153
|
if (deferScriptPromise.length) {
|
|
912
|
-
|
|
913
|
-
res.
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
!info.module && initedHook(false);
|
|
918
|
-
});
|
|
919
|
-
initedHook(isUndefined(initedHook.moduleCount));
|
|
920
|
-
}).catch((err) => {
|
|
1154
|
+
promiseStream(deferScriptPromise, (res) => {
|
|
1155
|
+
const info = deferScriptInfo[res.index][1];
|
|
1156
|
+
info.code = info.code || res.data;
|
|
1157
|
+
}, (err) => {
|
|
1158
|
+
initedHook.errorCount = initedHook.errorCount ? ++initedHook.errorCount : 1;
|
|
921
1159
|
logError(err, app.name);
|
|
922
|
-
|
|
1160
|
+
}, () => {
|
|
1161
|
+
deferScriptInfo.forEach(([url, info]) => {
|
|
1162
|
+
if (info.code) {
|
|
1163
|
+
runScript(url, app, info, false, initedHook);
|
|
1164
|
+
!info.module && initedHook(false);
|
|
1165
|
+
}
|
|
1166
|
+
});
|
|
1167
|
+
initedHook(isUndefined(initedHook.moduleCount) ||
|
|
1168
|
+
initedHook.errorCount === deferScriptPromise.length);
|
|
923
1169
|
});
|
|
924
1170
|
}
|
|
925
1171
|
else {
|
|
@@ -1054,7 +1300,7 @@ function bindScope(url, app, code, module) {
|
|
|
1054
1300
|
}
|
|
1055
1301
|
if (app.sandBox && !module) {
|
|
1056
1302
|
globalEnv.rawWindow.__MICRO_APP_PROXY_WINDOW__ = app.sandBox.proxyWindow;
|
|
1057
|
-
return `;(function(
|
|
1303
|
+
return `;(function(proxyWindow){with(proxyWindow.__MICRO_APP_WINDOW__){(function(${globalKeyToBeCached}){;${code}\n}).call(proxyWindow,${globalKeyToBeCached})}})(window.__MICRO_APP_PROXY_WINDOW__);`;
|
|
1058
1304
|
}
|
|
1059
1305
|
return code;
|
|
1060
1306
|
}
|
|
@@ -1473,46 +1719,41 @@ function rebuildDataCenterSnapshot(microAppEventCneter) {
|
|
|
1473
1719
|
}
|
|
1474
1720
|
}
|
|
1475
1721
|
|
|
1476
|
-
|
|
1722
|
+
/* eslint-disable no-return-assign */
|
|
1477
1723
|
function isBoundedFunction(value) {
|
|
1478
|
-
if (
|
|
1479
|
-
return
|
|
1480
|
-
|
|
1481
|
-
// bind function
|
|
1482
|
-
const boundFunction = isBoundFunction(value);
|
|
1483
|
-
boundedMap.set(value, boundFunction);
|
|
1484
|
-
return boundFunction;
|
|
1724
|
+
if (isBoolean(value.__MICRO_APP_ISBOUND_FUNCTION))
|
|
1725
|
+
return value.__MICRO_APP_ISBOUND_FUNCTION;
|
|
1726
|
+
return value.__MICRO_APP_ISBOUND_FUNCTION = isBoundFunction(value);
|
|
1485
1727
|
}
|
|
1486
|
-
const constructorMap = new WeakMap();
|
|
1487
1728
|
function isConstructor(value) {
|
|
1488
|
-
|
|
1489
|
-
|
|
1490
|
-
|
|
1729
|
+
var _a;
|
|
1730
|
+
if (isBoolean(value.__MICRO_APP_ISCONSTRUCTOR))
|
|
1731
|
+
return value.__MICRO_APP_ISCONSTRUCTOR;
|
|
1491
1732
|
const valueStr = value.toString();
|
|
1492
|
-
const result = (value.prototype &&
|
|
1493
|
-
value.prototype.constructor === value &&
|
|
1733
|
+
const result = (((_a = value.prototype) === null || _a === void 0 ? void 0 : _a.constructor) === value &&
|
|
1494
1734
|
Object.getOwnPropertyNames(value.prototype).length > 1) ||
|
|
1495
1735
|
/^function\s+[A-Z]/.test(valueStr) ||
|
|
1496
1736
|
/^class\s+/.test(valueStr);
|
|
1497
|
-
|
|
1498
|
-
return result;
|
|
1737
|
+
return value.__MICRO_APP_ISCONSTRUCTOR = result;
|
|
1499
1738
|
}
|
|
1500
|
-
const rawWindowMethodMap = new WeakMap();
|
|
1501
1739
|
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
|
|
1502
|
-
function
|
|
1503
|
-
if (
|
|
1504
|
-
return
|
|
1505
|
-
|
|
1506
|
-
if (isFunction(value) && !isConstructor(value) && !isBoundedFunction(value)) {
|
|
1740
|
+
function bindFunctionToRawWindow(rawWindow, value) {
|
|
1741
|
+
if (value.__MICRO_APP_BOUND_WINDOW_FUNCTION)
|
|
1742
|
+
return value.__MICRO_APP_BOUND_WINDOW_FUNCTION;
|
|
1743
|
+
if (!isConstructor(value) && !isBoundedFunction(value)) {
|
|
1507
1744
|
const bindRawWindowValue = value.bind(rawWindow);
|
|
1508
1745
|
for (const key in value) {
|
|
1509
1746
|
bindRawWindowValue[key] = value[key];
|
|
1510
1747
|
}
|
|
1511
|
-
if (value.hasOwnProperty('prototype')
|
|
1512
|
-
bindRawWindowValue
|
|
1748
|
+
if (value.hasOwnProperty('prototype')) {
|
|
1749
|
+
rawDefineProperty(bindRawWindowValue, 'prototype', {
|
|
1750
|
+
value: value.prototype,
|
|
1751
|
+
configurable: true,
|
|
1752
|
+
enumerable: false,
|
|
1753
|
+
writable: true,
|
|
1754
|
+
});
|
|
1513
1755
|
}
|
|
1514
|
-
|
|
1515
|
-
return bindRawWindowValue;
|
|
1756
|
+
return value.__MICRO_APP_BOUND_WINDOW_FUNCTION = bindRawWindowValue;
|
|
1516
1757
|
}
|
|
1517
1758
|
return value;
|
|
1518
1759
|
}
|
|
@@ -1536,7 +1777,7 @@ function overwriteDocumentOnClick() {
|
|
|
1536
1777
|
isFunction(f) && f.call(document, e);
|
|
1537
1778
|
});
|
|
1538
1779
|
}
|
|
1539
|
-
|
|
1780
|
+
rawDefineProperty(document, 'onclick', {
|
|
1540
1781
|
configurable: true,
|
|
1541
1782
|
enumerable: true,
|
|
1542
1783
|
get() {
|
|
@@ -1586,7 +1827,7 @@ function effectDocumentEvent() {
|
|
|
1586
1827
|
else {
|
|
1587
1828
|
documentEventListenerMap.set(appName, new Map([[type, new Set([listener])]]));
|
|
1588
1829
|
}
|
|
1589
|
-
listener && (listener.
|
|
1830
|
+
listener && (listener.__MICRO_APP_MARK_OPTIONS__ = options);
|
|
1590
1831
|
}
|
|
1591
1832
|
rawDocumentAddEventListener.call(rawDocument, type, listener, options);
|
|
1592
1833
|
};
|
|
@@ -1615,27 +1856,27 @@ const formatEventList = ['unmount', 'appstate-change'];
|
|
|
1615
1856
|
/**
|
|
1616
1857
|
* Format event name
|
|
1617
1858
|
* @param type event name
|
|
1618
|
-
* @param
|
|
1859
|
+
* @param microAppWindow micro window
|
|
1619
1860
|
*/
|
|
1620
|
-
function formatEventType(type,
|
|
1861
|
+
function formatEventType(type, microAppWindow) {
|
|
1621
1862
|
if (formatEventList.includes(type)) {
|
|
1622
|
-
return `${type}-${
|
|
1863
|
+
return `${type}-${microAppWindow.__MICRO_APP_NAME__}`;
|
|
1623
1864
|
}
|
|
1624
1865
|
return type;
|
|
1625
1866
|
}
|
|
1626
1867
|
/**
|
|
1627
1868
|
* Rewrite side-effect events
|
|
1628
|
-
* @param
|
|
1869
|
+
* @param microAppWindow micro window
|
|
1629
1870
|
*/
|
|
1630
|
-
function effect(
|
|
1631
|
-
const appName =
|
|
1871
|
+
function effect(microAppWindow) {
|
|
1872
|
+
const appName = microAppWindow.__MICRO_APP_NAME__;
|
|
1632
1873
|
const eventListenerMap = new Map();
|
|
1633
1874
|
const intervalIdMap = new Map();
|
|
1634
1875
|
const timeoutIdMap = new Map();
|
|
1635
1876
|
const { rawWindow, rawDocument, rawWindowAddEventListener, rawWindowRemoveEventListener, rawSetInterval, rawSetTimeout, rawClearInterval, rawClearTimeout, rawDocumentRemoveEventListener, } = globalEnv;
|
|
1636
1877
|
// listener may be null, e.g test-passive
|
|
1637
|
-
|
|
1638
|
-
type = formatEventType(type,
|
|
1878
|
+
microAppWindow.addEventListener = function (type, listener, options) {
|
|
1879
|
+
type = formatEventType(type, microAppWindow);
|
|
1639
1880
|
const listenerList = eventListenerMap.get(type);
|
|
1640
1881
|
if (listenerList) {
|
|
1641
1882
|
listenerList.add(listener);
|
|
@@ -1643,32 +1884,32 @@ function effect(microWindow) {
|
|
|
1643
1884
|
else {
|
|
1644
1885
|
eventListenerMap.set(type, new Set([listener]));
|
|
1645
1886
|
}
|
|
1646
|
-
listener && (listener.
|
|
1887
|
+
listener && (listener.__MICRO_APP_MARK_OPTIONS__ = options);
|
|
1647
1888
|
rawWindowAddEventListener.call(rawWindow, type, listener, options);
|
|
1648
1889
|
};
|
|
1649
|
-
|
|
1650
|
-
type = formatEventType(type,
|
|
1890
|
+
microAppWindow.removeEventListener = function (type, listener, options) {
|
|
1891
|
+
type = formatEventType(type, microAppWindow);
|
|
1651
1892
|
const listenerList = eventListenerMap.get(type);
|
|
1652
1893
|
if ((listenerList === null || listenerList === void 0 ? void 0 : listenerList.size) && listenerList.has(listener)) {
|
|
1653
1894
|
listenerList.delete(listener);
|
|
1654
1895
|
}
|
|
1655
1896
|
rawWindowRemoveEventListener.call(rawWindow, type, listener, options);
|
|
1656
1897
|
};
|
|
1657
|
-
|
|
1898
|
+
microAppWindow.setInterval = function (handler, timeout, ...args) {
|
|
1658
1899
|
const intervalId = rawSetInterval.call(rawWindow, handler, timeout, ...args);
|
|
1659
1900
|
intervalIdMap.set(intervalId, { handler, timeout, args });
|
|
1660
1901
|
return intervalId;
|
|
1661
1902
|
};
|
|
1662
|
-
|
|
1903
|
+
microAppWindow.setTimeout = function (handler, timeout, ...args) {
|
|
1663
1904
|
const timeoutId = rawSetTimeout.call(rawWindow, handler, timeout, ...args);
|
|
1664
1905
|
timeoutIdMap.set(timeoutId, { handler, timeout, args });
|
|
1665
1906
|
return timeoutId;
|
|
1666
1907
|
};
|
|
1667
|
-
|
|
1908
|
+
microAppWindow.clearInterval = function (intervalId) {
|
|
1668
1909
|
intervalIdMap.delete(intervalId);
|
|
1669
1910
|
rawClearInterval.call(rawWindow, intervalId);
|
|
1670
1911
|
};
|
|
1671
|
-
|
|
1912
|
+
microAppWindow.clearTimeout = function (timeoutId) {
|
|
1672
1913
|
timeoutIdMap.delete(timeoutId);
|
|
1673
1914
|
rawClearTimeout.call(rawWindow, timeoutId);
|
|
1674
1915
|
};
|
|
@@ -1709,15 +1950,15 @@ function effect(microWindow) {
|
|
|
1709
1950
|
// rebuild window event
|
|
1710
1951
|
umdWindowListenerMap.forEach((listenerList, type) => {
|
|
1711
1952
|
for (const listener of listenerList) {
|
|
1712
|
-
|
|
1953
|
+
microAppWindow.addEventListener(type, listener, listener === null || listener === void 0 ? void 0 : listener.__MICRO_APP_MARK_OPTIONS__);
|
|
1713
1954
|
}
|
|
1714
1955
|
});
|
|
1715
1956
|
// rebuild timer
|
|
1716
1957
|
umdIntervalIdMap.forEach((info) => {
|
|
1717
|
-
|
|
1958
|
+
microAppWindow.setInterval(info.handler, info.timeout, ...info.args);
|
|
1718
1959
|
});
|
|
1719
1960
|
umdTimeoutIdMap.forEach((info) => {
|
|
1720
|
-
|
|
1961
|
+
microAppWindow.setTimeout(info.handler, info.timeout, ...info.args);
|
|
1721
1962
|
});
|
|
1722
1963
|
// rebuild onclick event
|
|
1723
1964
|
umdOnClickHandler && documentClickListMap.set(appName, umdOnClickHandler);
|
|
@@ -1725,7 +1966,7 @@ function effect(microWindow) {
|
|
|
1725
1966
|
setCurrentAppName(appName);
|
|
1726
1967
|
umdDocumentListenerMap.forEach((listenerList, type) => {
|
|
1727
1968
|
for (const listener of listenerList) {
|
|
1728
|
-
document.addEventListener(type, listener, listener === null || listener === void 0 ? void 0 : listener.
|
|
1969
|
+
document.addEventListener(type, listener, listener === null || listener === void 0 ? void 0 : listener.__MICRO_APP_MARK_OPTIONS__);
|
|
1729
1970
|
}
|
|
1730
1971
|
});
|
|
1731
1972
|
setCurrentAppName(null);
|
|
@@ -1773,189 +2014,70 @@ function effect(microWindow) {
|
|
|
1773
2014
|
releaseEffect,
|
|
1774
2015
|
};
|
|
1775
2016
|
}
|
|
1776
|
-
|
|
1777
|
-
const
|
|
1778
|
-
|
|
1779
|
-
|
|
1780
|
-
|
|
1781
|
-
|
|
1782
|
-
|
|
1783
|
-
|
|
2017
|
+
// window.addEventListener('mousedown', (e: Event) => {
|
|
2018
|
+
// const targetNode = e.target
|
|
2019
|
+
// const activeApps = getActiveApps(true)
|
|
2020
|
+
// let isScopeOfMicroApp = false
|
|
2021
|
+
// for (const appName of activeApps) {
|
|
2022
|
+
// const app = appInstanceMap.get(appName)!
|
|
2023
|
+
// if (targetNode instanceof Node && app.container!.contains(targetNode)) {
|
|
2024
|
+
// isScopeOfMicroApp = true
|
|
2025
|
+
// // console.log(111111, appName)
|
|
2026
|
+
// setCurrentAppName(appName)
|
|
2027
|
+
// break
|
|
2028
|
+
// }
|
|
2029
|
+
// }
|
|
2030
|
+
// if (!isScopeOfMicroApp) {
|
|
2031
|
+
// setCurrentAppName(null)
|
|
2032
|
+
// }
|
|
2033
|
+
// }, false)
|
|
2034
|
+
// let isWaitingForMacroReset = false
|
|
2035
|
+
// window.addEventListener('mouseup', () => {
|
|
2036
|
+
// if (!isWaitingForMacroReset && getCurrentAppName()) {
|
|
2037
|
+
// isWaitingForMacroReset = true
|
|
2038
|
+
// setTimeout(() => {
|
|
2039
|
+
// setCurrentAppName(null)
|
|
2040
|
+
// isWaitingForMacroReset = false
|
|
2041
|
+
// })
|
|
2042
|
+
// }
|
|
2043
|
+
// }, false)
|
|
1784
2044
|
|
|
1785
2045
|
// Variables that can escape to rawWindow
|
|
1786
2046
|
const staticEscapeProperties = [
|
|
1787
2047
|
'System',
|
|
1788
2048
|
'__cjsWrapper',
|
|
1789
|
-
'__REACT_ERROR_OVERLAY_GLOBAL_HOOK__',
|
|
1790
2049
|
];
|
|
1791
2050
|
// Variables that can only assigned to rawWindow
|
|
1792
2051
|
const escapeSetterKeyList = [
|
|
1793
2052
|
'location',
|
|
1794
2053
|
];
|
|
1795
|
-
const
|
|
1796
|
-
undefined: true,
|
|
1797
|
-
Array: true,
|
|
1798
|
-
Object: true,
|
|
1799
|
-
String: true,
|
|
1800
|
-
Boolean: true,
|
|
1801
|
-
Math: true,
|
|
1802
|
-
Number: true,
|
|
1803
|
-
Symbol: true,
|
|
1804
|
-
parseFloat: true,
|
|
1805
|
-
Float32Array: true,
|
|
1806
|
-
};
|
|
1807
|
-
/**
|
|
1808
|
-
* macro task to solve the rendering problem of vue3
|
|
1809
|
-
*/
|
|
1810
|
-
let macroTimer;
|
|
1811
|
-
function macroTask(fn) {
|
|
1812
|
-
macroTimer && clearTimeout(macroTimer);
|
|
1813
|
-
macroTimer = setTimeout(fn, 0);
|
|
1814
|
-
}
|
|
2054
|
+
const globalPropertyList = ['window', 'self', 'globalThis'];
|
|
1815
2055
|
class SandBox {
|
|
1816
|
-
constructor(appName, url
|
|
1817
|
-
// Scoped global Properties(Properties that can only get and set in
|
|
2056
|
+
constructor(appName, url) {
|
|
2057
|
+
// Scoped global Properties(Properties that can only get and set in microAppWindow, will not escape to rawWindow)
|
|
1818
2058
|
this.scopeProperties = ['webpackJsonp'];
|
|
1819
2059
|
// Properties that can be escape to rawWindow
|
|
1820
2060
|
this.escapeProperties = [];
|
|
1821
|
-
// Properties newly added to
|
|
2061
|
+
// Properties newly added to microAppWindow
|
|
1822
2062
|
this.injectedKeys = new Set();
|
|
1823
2063
|
// Properties escape to rawWindow, cleared when unmount
|
|
1824
|
-
this.escapeKeys = new Set();
|
|
1825
|
-
// sandbox state
|
|
1826
|
-
this.active = false;
|
|
1827
|
-
this.
|
|
1828
|
-
|
|
1829
|
-
|
|
1830
|
-
|
|
1831
|
-
|
|
1832
|
-
//
|
|
1833
|
-
this.
|
|
1834
|
-
//
|
|
1835
|
-
|
|
1836
|
-
// Rewrite global event listener & timeout
|
|
1837
|
-
Object.assign(this, effect(this.microWindow));
|
|
1838
|
-
this.proxyWindow = new Proxy(this.microWindow, {
|
|
1839
|
-
get: (target, key) => {
|
|
1840
|
-
if (key === Symbol.unscopables)
|
|
1841
|
-
return unscopables;
|
|
1842
|
-
if (['window', 'self', 'globalThis'].includes(key)) {
|
|
1843
|
-
return this.proxyWindow;
|
|
1844
|
-
}
|
|
1845
|
-
if (key === 'top' || key === 'parent') {
|
|
1846
|
-
if (rawWindow === rawWindow.parent) { // not in iframe
|
|
1847
|
-
return this.proxyWindow;
|
|
1848
|
-
}
|
|
1849
|
-
return Reflect.get(rawWindow, key); // iframe
|
|
1850
|
-
}
|
|
1851
|
-
if (key === 'hasOwnProperty')
|
|
1852
|
-
return hasOwnProperty;
|
|
1853
|
-
if (key === 'document' || key === 'eval' || key === 'Image') {
|
|
1854
|
-
if (this.active) {
|
|
1855
|
-
setCurrentAppName(appName);
|
|
1856
|
-
(macro ? macroTask : defer)(() => setCurrentAppName(null));
|
|
1857
|
-
}
|
|
1858
|
-
switch (key) {
|
|
1859
|
-
case 'document':
|
|
1860
|
-
return rawDocument;
|
|
1861
|
-
case 'eval':
|
|
1862
|
-
return eval;
|
|
1863
|
-
case 'Image':
|
|
1864
|
-
return ImageProxy;
|
|
1865
|
-
}
|
|
1866
|
-
}
|
|
1867
|
-
if (Reflect.has(target, key)) {
|
|
1868
|
-
return Reflect.get(target, key);
|
|
1869
|
-
}
|
|
1870
|
-
if (this.scopeProperties.includes(key) ||
|
|
1871
|
-
(isString(key) && /^__MICRO_APP_/.test(key))) {
|
|
1872
|
-
return Reflect.get(target, key);
|
|
1873
|
-
}
|
|
1874
|
-
const rawValue = Reflect.get(rawWindow, key);
|
|
1875
|
-
return bindFunctionToRawWidow(rawWindow, rawValue);
|
|
1876
|
-
},
|
|
1877
|
-
set: (target, key, value) => {
|
|
1878
|
-
if (this.active) {
|
|
1879
|
-
if (escapeSetterKeyList.includes(key)) {
|
|
1880
|
-
Reflect.set(rawWindow, key, value);
|
|
1881
|
-
}
|
|
1882
|
-
else if (!target.hasOwnProperty(key) &&
|
|
1883
|
-
rawWindow.hasOwnProperty(key) &&
|
|
1884
|
-
!this.scopeProperties.includes(key)) {
|
|
1885
|
-
const descriptor = Object.getOwnPropertyDescriptor(rawWindow, key);
|
|
1886
|
-
const { writable, configurable, enumerable } = descriptor;
|
|
1887
|
-
if (writable) {
|
|
1888
|
-
Object.defineProperty(target, key, {
|
|
1889
|
-
configurable,
|
|
1890
|
-
enumerable,
|
|
1891
|
-
writable,
|
|
1892
|
-
value,
|
|
1893
|
-
});
|
|
1894
|
-
this.injectedKeys.add(key);
|
|
1895
|
-
}
|
|
1896
|
-
}
|
|
1897
|
-
else {
|
|
1898
|
-
Reflect.set(target, key, value);
|
|
1899
|
-
this.injectedKeys.add(key);
|
|
1900
|
-
}
|
|
1901
|
-
if ((this.escapeProperties.includes(key) ||
|
|
1902
|
-
(staticEscapeProperties.includes(key) && !Reflect.has(rawWindow, key))) &&
|
|
1903
|
-
!this.scopeProperties.includes(key)) {
|
|
1904
|
-
Reflect.set(rawWindow, key, value);
|
|
1905
|
-
this.escapeKeys.add(key);
|
|
1906
|
-
}
|
|
1907
|
-
}
|
|
1908
|
-
return true;
|
|
1909
|
-
},
|
|
1910
|
-
has: (target, key) => {
|
|
1911
|
-
if (this.scopeProperties.includes(key))
|
|
1912
|
-
return key in target;
|
|
1913
|
-
return key in unscopables || key in target || key in rawWindow;
|
|
1914
|
-
},
|
|
1915
|
-
// Object.getOwnPropertyDescriptor(window, key)
|
|
1916
|
-
// TODO: use set
|
|
1917
|
-
getOwnPropertyDescriptor: (target, key) => {
|
|
1918
|
-
if (target.hasOwnProperty(key)) {
|
|
1919
|
-
descriptorTargetMap.set(key, 'target');
|
|
1920
|
-
return Object.getOwnPropertyDescriptor(target, key);
|
|
1921
|
-
}
|
|
1922
|
-
if (rawWindow.hasOwnProperty(key)) {
|
|
1923
|
-
// like console, alert ...
|
|
1924
|
-
descriptorTargetMap.set(key, 'rawWindow');
|
|
1925
|
-
const descriptor = Object.getOwnPropertyDescriptor(rawWindow, key);
|
|
1926
|
-
if (descriptor && !descriptor.configurable) {
|
|
1927
|
-
descriptor.configurable = true;
|
|
1928
|
-
}
|
|
1929
|
-
return descriptor;
|
|
1930
|
-
}
|
|
1931
|
-
return undefined;
|
|
1932
|
-
},
|
|
1933
|
-
// Object.defineProperty(window, key, Descriptor)
|
|
1934
|
-
defineProperty: (target, key, value) => {
|
|
1935
|
-
const from = descriptorTargetMap.get(key);
|
|
1936
|
-
if (from === 'rawWindow') {
|
|
1937
|
-
return Reflect.defineProperty(rawWindow, key, value);
|
|
1938
|
-
}
|
|
1939
|
-
return Reflect.defineProperty(target, key, value);
|
|
1940
|
-
},
|
|
1941
|
-
// Object.getOwnPropertyNames(window)
|
|
1942
|
-
ownKeys: (target) => {
|
|
1943
|
-
return unique(Reflect.ownKeys(rawWindow).concat(Reflect.ownKeys(target)));
|
|
1944
|
-
},
|
|
1945
|
-
deleteProperty: (target, key) => {
|
|
1946
|
-
if (target.hasOwnProperty(key)) {
|
|
1947
|
-
this.injectedKeys.has(key) && this.injectedKeys.delete(key);
|
|
1948
|
-
this.escapeKeys.has(key) && Reflect.deleteProperty(rawWindow, key);
|
|
1949
|
-
return Reflect.deleteProperty(target, key);
|
|
1950
|
-
}
|
|
1951
|
-
return true;
|
|
1952
|
-
},
|
|
1953
|
-
});
|
|
2064
|
+
this.escapeKeys = new Set();
|
|
2065
|
+
// sandbox state
|
|
2066
|
+
this.active = false;
|
|
2067
|
+
this.microAppWindow = {}; // Proxy target
|
|
2068
|
+
// get scopeProperties and escapeProperties from plugins
|
|
2069
|
+
this.getScopeProperties(appName);
|
|
2070
|
+
// create proxyWindow with Proxy(microAppWindow)
|
|
2071
|
+
this.proxyWindow = this.createProxyWindow();
|
|
2072
|
+
// inject global properties
|
|
2073
|
+
this.initMicroAppWindow(this.microAppWindow, appName, url);
|
|
2074
|
+
// Rewrite global event listener & timeout
|
|
2075
|
+
Object.assign(this, effect(this.microAppWindow));
|
|
1954
2076
|
}
|
|
1955
2077
|
start(baseroute) {
|
|
1956
2078
|
if (!this.active) {
|
|
1957
2079
|
this.active = true;
|
|
1958
|
-
this.
|
|
2080
|
+
this.microAppWindow.__MICRO_APP_BASE_ROUTE__ = this.microAppWindow.__MICRO_APP_BASE_URL__ = baseroute;
|
|
1959
2081
|
// BUG FIX: bable-polyfill@6.x
|
|
1960
2082
|
globalEnv.rawWindow._babelPolyfill && (globalEnv.rawWindow._babelPolyfill = false);
|
|
1961
2083
|
if (++SandBox.activeCount === 1) {
|
|
@@ -1967,10 +2089,10 @@ class SandBox {
|
|
|
1967
2089
|
if (this.active) {
|
|
1968
2090
|
this.active = false;
|
|
1969
2091
|
this.releaseEffect();
|
|
1970
|
-
this.
|
|
1971
|
-
this.
|
|
2092
|
+
this.microAppWindow.microApp.clearDataListener();
|
|
2093
|
+
this.microAppWindow.microApp.clearGlobalDataListener();
|
|
1972
2094
|
this.injectedKeys.forEach((key) => {
|
|
1973
|
-
Reflect.deleteProperty(this.
|
|
2095
|
+
Reflect.deleteProperty(this.microAppWindow, key);
|
|
1974
2096
|
});
|
|
1975
2097
|
this.injectedKeys.clear();
|
|
1976
2098
|
this.escapeKeys.forEach((key) => {
|
|
@@ -1984,12 +2106,12 @@ class SandBox {
|
|
|
1984
2106
|
}
|
|
1985
2107
|
// record umd snapshot before the first execution of umdHookMount
|
|
1986
2108
|
recordUmdSnapshot() {
|
|
1987
|
-
this.
|
|
2109
|
+
this.microAppWindow.__MICRO_APP_UMD_MODE__ = true;
|
|
1988
2110
|
this.recordUmdEffect();
|
|
1989
|
-
recordDataCenterSnapshot(this.
|
|
2111
|
+
recordDataCenterSnapshot(this.microAppWindow.microApp);
|
|
1990
2112
|
this.recordUmdinjectedValues = new Map();
|
|
1991
2113
|
this.injectedKeys.forEach((key) => {
|
|
1992
|
-
this.recordUmdinjectedValues.set(key, Reflect.get(this.
|
|
2114
|
+
this.recordUmdinjectedValues.set(key, Reflect.get(this.microAppWindow, key));
|
|
1993
2115
|
});
|
|
1994
2116
|
}
|
|
1995
2117
|
// rebuild umd snapshot before remount umd app
|
|
@@ -1998,7 +2120,7 @@ class SandBox {
|
|
|
1998
2120
|
Reflect.set(this.proxyWindow, key, value);
|
|
1999
2121
|
});
|
|
2000
2122
|
this.rebuildUmdEffect();
|
|
2001
|
-
rebuildDataCenterSnapshot(this.
|
|
2123
|
+
rebuildDataCenterSnapshot(this.microAppWindow.microApp);
|
|
2002
2124
|
}
|
|
2003
2125
|
/**
|
|
2004
2126
|
* get scopeProperties and escapeProperties from plugins
|
|
@@ -2033,20 +2155,178 @@ class SandBox {
|
|
|
2033
2155
|
}
|
|
2034
2156
|
}
|
|
2035
2157
|
}
|
|
2158
|
+
// create proxyWindow with Proxy(microAppWindow)
|
|
2159
|
+
createProxyWindow() {
|
|
2160
|
+
const rawWindow = globalEnv.rawWindow;
|
|
2161
|
+
const descriptorTargetMap = new Map();
|
|
2162
|
+
// window.xxx will trigger proxy
|
|
2163
|
+
return new Proxy(this.microAppWindow, {
|
|
2164
|
+
get: (target, key) => {
|
|
2165
|
+
if (Reflect.has(target, key) ||
|
|
2166
|
+
(isString(key) && /^__MICRO_APP_/.test(key)) ||
|
|
2167
|
+
this.scopeProperties.includes(key))
|
|
2168
|
+
return Reflect.get(target, key);
|
|
2169
|
+
const rawValue = Reflect.get(rawWindow, key);
|
|
2170
|
+
return isFunction(rawValue) ? bindFunctionToRawWindow(rawWindow, rawValue) : rawValue;
|
|
2171
|
+
},
|
|
2172
|
+
set: (target, key, value) => {
|
|
2173
|
+
if (this.active) {
|
|
2174
|
+
if (escapeSetterKeyList.includes(key)) {
|
|
2175
|
+
Reflect.set(rawWindow, key, value);
|
|
2176
|
+
}
|
|
2177
|
+
else if (
|
|
2178
|
+
// target.hasOwnProperty has been rewritten
|
|
2179
|
+
!rawHasOwnProperty.call(target, key) &&
|
|
2180
|
+
rawHasOwnProperty.call(rawWindow, key) &&
|
|
2181
|
+
!this.scopeProperties.includes(key)) {
|
|
2182
|
+
const descriptor = Object.getOwnPropertyDescriptor(rawWindow, key);
|
|
2183
|
+
const { configurable, enumerable, writable, set } = descriptor;
|
|
2184
|
+
// set value because it can be set
|
|
2185
|
+
rawDefineProperty(target, key, {
|
|
2186
|
+
value,
|
|
2187
|
+
configurable,
|
|
2188
|
+
enumerable,
|
|
2189
|
+
writable: writable !== null && writable !== void 0 ? writable : !!set,
|
|
2190
|
+
});
|
|
2191
|
+
this.injectedKeys.add(key);
|
|
2192
|
+
}
|
|
2193
|
+
else {
|
|
2194
|
+
Reflect.set(target, key, value);
|
|
2195
|
+
this.injectedKeys.add(key);
|
|
2196
|
+
}
|
|
2197
|
+
if ((this.escapeProperties.includes(key) ||
|
|
2198
|
+
(staticEscapeProperties.includes(key) && !Reflect.has(rawWindow, key))) &&
|
|
2199
|
+
!this.scopeProperties.includes(key)) {
|
|
2200
|
+
Reflect.set(rawWindow, key, value);
|
|
2201
|
+
this.escapeKeys.add(key);
|
|
2202
|
+
}
|
|
2203
|
+
}
|
|
2204
|
+
return true;
|
|
2205
|
+
},
|
|
2206
|
+
has: (target, key) => {
|
|
2207
|
+
if (this.scopeProperties.includes(key))
|
|
2208
|
+
return key in target;
|
|
2209
|
+
return key in target || key in rawWindow;
|
|
2210
|
+
},
|
|
2211
|
+
// Object.getOwnPropertyDescriptor(window, key)
|
|
2212
|
+
getOwnPropertyDescriptor: (target, key) => {
|
|
2213
|
+
if (rawHasOwnProperty.call(target, key)) {
|
|
2214
|
+
descriptorTargetMap.set(key, 'target');
|
|
2215
|
+
return Object.getOwnPropertyDescriptor(target, key);
|
|
2216
|
+
}
|
|
2217
|
+
if (rawHasOwnProperty.call(rawWindow, key)) {
|
|
2218
|
+
descriptorTargetMap.set(key, 'rawWindow');
|
|
2219
|
+
const descriptor = Object.getOwnPropertyDescriptor(rawWindow, key);
|
|
2220
|
+
if (descriptor && !descriptor.configurable) {
|
|
2221
|
+
descriptor.configurable = true;
|
|
2222
|
+
}
|
|
2223
|
+
return descriptor;
|
|
2224
|
+
}
|
|
2225
|
+
return undefined;
|
|
2226
|
+
},
|
|
2227
|
+
// Object.defineProperty(window, key, Descriptor)
|
|
2228
|
+
defineProperty: (target, key, value) => {
|
|
2229
|
+
const from = descriptorTargetMap.get(key);
|
|
2230
|
+
if (from === 'rawWindow') {
|
|
2231
|
+
return Reflect.defineProperty(rawWindow, key, value);
|
|
2232
|
+
}
|
|
2233
|
+
return Reflect.defineProperty(target, key, value);
|
|
2234
|
+
},
|
|
2235
|
+
// Object.getOwnPropertyNames(window)
|
|
2236
|
+
ownKeys: (target) => {
|
|
2237
|
+
return unique(Reflect.ownKeys(rawWindow).concat(Reflect.ownKeys(target)));
|
|
2238
|
+
},
|
|
2239
|
+
deleteProperty: (target, key) => {
|
|
2240
|
+
if (rawHasOwnProperty.call(target, key)) {
|
|
2241
|
+
this.injectedKeys.has(key) && this.injectedKeys.delete(key);
|
|
2242
|
+
this.escapeKeys.has(key) && Reflect.deleteProperty(rawWindow, key);
|
|
2243
|
+
return Reflect.deleteProperty(target, key);
|
|
2244
|
+
}
|
|
2245
|
+
return true;
|
|
2246
|
+
},
|
|
2247
|
+
});
|
|
2248
|
+
}
|
|
2036
2249
|
/**
|
|
2037
|
-
* inject global properties to
|
|
2038
|
-
* @param
|
|
2250
|
+
* inject global properties to microAppWindow
|
|
2251
|
+
* @param microAppWindow micro window
|
|
2039
2252
|
* @param appName app name
|
|
2040
2253
|
* @param url app url
|
|
2041
2254
|
*/
|
|
2042
|
-
|
|
2043
|
-
|
|
2044
|
-
|
|
2045
|
-
|
|
2046
|
-
|
|
2047
|
-
|
|
2048
|
-
|
|
2049
|
-
|
|
2255
|
+
initMicroAppWindow(microAppWindow, appName, url) {
|
|
2256
|
+
microAppWindow.__MICRO_APP_ENVIRONMENT__ = true;
|
|
2257
|
+
microAppWindow.__MICRO_APP_NAME__ = appName;
|
|
2258
|
+
microAppWindow.__MICRO_APP_PUBLIC_PATH__ = getEffectivePath(url);
|
|
2259
|
+
microAppWindow.__MICRO_APP_WINDOW__ = microAppWindow;
|
|
2260
|
+
microAppWindow.microApp = new EventCenterForMicroApp(appName);
|
|
2261
|
+
microAppWindow.rawWindow = globalEnv.rawWindow;
|
|
2262
|
+
microAppWindow.rawDocument = globalEnv.rawDocument;
|
|
2263
|
+
microAppWindow.removeDomScope = removeDomScope;
|
|
2264
|
+
microAppWindow.hasOwnProperty = (key) => rawHasOwnProperty.call(microAppWindow, key) || rawHasOwnProperty.call(globalEnv.rawWindow, key);
|
|
2265
|
+
this.setMappingPropertiesWithRawDescriptor(microAppWindow);
|
|
2266
|
+
this.setHijackProperties(microAppWindow, appName);
|
|
2267
|
+
}
|
|
2268
|
+
// properties associated with the native window
|
|
2269
|
+
setMappingPropertiesWithRawDescriptor(microAppWindow) {
|
|
2270
|
+
let topValue, parentValue;
|
|
2271
|
+
const rawWindow = globalEnv.rawWindow;
|
|
2272
|
+
if (rawWindow === rawWindow.parent) { // not in iframe
|
|
2273
|
+
topValue = parentValue = this.proxyWindow;
|
|
2274
|
+
}
|
|
2275
|
+
else { // in iframe
|
|
2276
|
+
topValue = rawWindow.top;
|
|
2277
|
+
parentValue = rawWindow.parent;
|
|
2278
|
+
}
|
|
2279
|
+
rawDefineProperty(microAppWindow, 'top', this.createDescriptorFormicroAppWindow('top', topValue));
|
|
2280
|
+
rawDefineProperty(microAppWindow, 'parent', this.createDescriptorFormicroAppWindow('parent', parentValue));
|
|
2281
|
+
globalPropertyList.forEach((key) => {
|
|
2282
|
+
rawDefineProperty(microAppWindow, key, this.createDescriptorFormicroAppWindow(key, this.proxyWindow));
|
|
2283
|
+
});
|
|
2284
|
+
}
|
|
2285
|
+
createDescriptorFormicroAppWindow(key, value) {
|
|
2286
|
+
const { configurable = true, enumerable = true, writable, set } = Object.getOwnPropertyDescriptor(globalEnv.rawWindow, key) || { writable: true };
|
|
2287
|
+
const descriptor = {
|
|
2288
|
+
value,
|
|
2289
|
+
configurable,
|
|
2290
|
+
enumerable,
|
|
2291
|
+
writable: writable !== null && writable !== void 0 ? writable : !!set
|
|
2292
|
+
};
|
|
2293
|
+
return descriptor;
|
|
2294
|
+
}
|
|
2295
|
+
// set hijack Properties to microAppWindow
|
|
2296
|
+
setHijackProperties(microAppWindow, appName) {
|
|
2297
|
+
let modifiedEval, modifiedImage;
|
|
2298
|
+
rawDefineProperties(microAppWindow, {
|
|
2299
|
+
document: {
|
|
2300
|
+
get() {
|
|
2301
|
+
throttleDeferForSetAppName(appName);
|
|
2302
|
+
return globalEnv.rawDocument;
|
|
2303
|
+
},
|
|
2304
|
+
configurable: false,
|
|
2305
|
+
enumerable: true,
|
|
2306
|
+
},
|
|
2307
|
+
eval: {
|
|
2308
|
+
get() {
|
|
2309
|
+
throttleDeferForSetAppName(appName);
|
|
2310
|
+
return modifiedEval || eval;
|
|
2311
|
+
},
|
|
2312
|
+
set: (value) => {
|
|
2313
|
+
modifiedEval = value;
|
|
2314
|
+
},
|
|
2315
|
+
configurable: true,
|
|
2316
|
+
enumerable: false,
|
|
2317
|
+
},
|
|
2318
|
+
Image: {
|
|
2319
|
+
get() {
|
|
2320
|
+
throttleDeferForSetAppName(appName);
|
|
2321
|
+
return modifiedImage || globalEnv.ImageProxy;
|
|
2322
|
+
},
|
|
2323
|
+
set: (value) => {
|
|
2324
|
+
modifiedImage = value;
|
|
2325
|
+
},
|
|
2326
|
+
configurable: true,
|
|
2327
|
+
enumerable: false,
|
|
2328
|
+
},
|
|
2329
|
+
});
|
|
2050
2330
|
}
|
|
2051
2331
|
}
|
|
2052
2332
|
SandBox.activeCount = 0; // number of active sandbox
|
|
@@ -2115,7 +2395,7 @@ function dispatchCustomEventToMicroApp(eventName, appName, detail = {}) {
|
|
|
2115
2395
|
// micro app instances
|
|
2116
2396
|
const appInstanceMap = new Map();
|
|
2117
2397
|
class CreateApp {
|
|
2118
|
-
constructor({ name, url, ssrUrl, container, inline, scopecss, useSandbox,
|
|
2398
|
+
constructor({ name, url, ssrUrl, container, inline, scopecss, useSandbox, baseroute, }) {
|
|
2119
2399
|
this.state = appStates.NOT_LOADED;
|
|
2120
2400
|
this.keepAliveState = null;
|
|
2121
2401
|
this.keepAliveContainer = null;
|
|
@@ -2126,7 +2406,6 @@ class CreateApp {
|
|
|
2126
2406
|
this.umdMode = false;
|
|
2127
2407
|
this.isPrefetch = false;
|
|
2128
2408
|
this.container = null;
|
|
2129
|
-
this.macro = false;
|
|
2130
2409
|
this.baseroute = '';
|
|
2131
2410
|
this.sandBox = null;
|
|
2132
2411
|
this.container = container !== null && container !== void 0 ? container : null;
|
|
@@ -2138,13 +2417,12 @@ class CreateApp {
|
|
|
2138
2417
|
this.url = url;
|
|
2139
2418
|
this.useSandbox = useSandbox;
|
|
2140
2419
|
this.scopecss = this.useSandbox && scopecss;
|
|
2141
|
-
this.macro = macro !== null && macro !== void 0 ? macro : false;
|
|
2142
2420
|
this.source = {
|
|
2143
2421
|
links: new Map(),
|
|
2144
2422
|
scripts: new Map(),
|
|
2145
2423
|
};
|
|
2146
2424
|
this.loadSourceCode();
|
|
2147
|
-
this.useSandbox && (this.sandBox = new SandBox(name, url
|
|
2425
|
+
this.useSandbox && (this.sandBox = new SandBox(name, url));
|
|
2148
2426
|
}
|
|
2149
2427
|
// Load resources
|
|
2150
2428
|
loadSourceCode() {
|
|
@@ -2312,7 +2590,7 @@ class CreateApp {
|
|
|
2312
2590
|
var _a;
|
|
2313
2591
|
(_a = this.sandBox) === null || _a === void 0 ? void 0 : _a.stop();
|
|
2314
2592
|
if (destroy) {
|
|
2315
|
-
this.
|
|
2593
|
+
this.actionsForCompletelyDestroy();
|
|
2316
2594
|
}
|
|
2317
2595
|
else if (this.umdMode && this.container.childElementCount) {
|
|
2318
2596
|
cloneContainer(this.container, this.source.html, false);
|
|
@@ -2324,7 +2602,7 @@ class CreateApp {
|
|
|
2324
2602
|
unmountcb && unmountcb();
|
|
2325
2603
|
}
|
|
2326
2604
|
// actions for completely destroy
|
|
2327
|
-
|
|
2605
|
+
actionsForCompletelyDestroy() {
|
|
2328
2606
|
if (!this.useSandbox && this.umdMode) {
|
|
2329
2607
|
delete window[this.libraryName];
|
|
2330
2608
|
}
|
|
@@ -2390,92 +2668,6 @@ class CreateApp {
|
|
|
2390
2668
|
return {};
|
|
2391
2669
|
}
|
|
2392
2670
|
}
|
|
2393
|
-
// if app not prefetch & not unmount, then app is active
|
|
2394
|
-
function getActiveApps() {
|
|
2395
|
-
const activeApps = [];
|
|
2396
|
-
appInstanceMap.forEach((app, appName) => {
|
|
2397
|
-
if (appStates.UNMOUNT !== app.getAppState() && !app.isPrefetch) {
|
|
2398
|
-
activeApps.push(appName);
|
|
2399
|
-
}
|
|
2400
|
-
});
|
|
2401
|
-
return activeApps;
|
|
2402
|
-
}
|
|
2403
|
-
// get all registered apps
|
|
2404
|
-
function getAllApps() {
|
|
2405
|
-
return Array.from(appInstanceMap.keys());
|
|
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
|
-
}
|
|
2479
2671
|
|
|
2480
2672
|
// Record element and map element
|
|
2481
2673
|
const dynamicElementInMicroAppMap = new WeakMap();
|
|
@@ -2946,7 +3138,6 @@ function defineElement(tagName) {
|
|
|
2946
3138
|
// inline: whether js runs in inline script mode, default is false
|
|
2947
3139
|
// disableScopecss: whether disable css scoped, default is false
|
|
2948
3140
|
// disableSandbox: whether disable sandbox, default is false
|
|
2949
|
-
// macro: used to solve the async render problem of vue3, default is false
|
|
2950
3141
|
// baseRoute: route prefix, default is ''
|
|
2951
3142
|
// keep-alive: open keep-alive mode
|
|
2952
3143
|
connectedCallback() {
|
|
@@ -3144,7 +3335,7 @@ function defineElement(tagName) {
|
|
|
3144
3335
|
* fix of unmounted umd app with disableSandbox
|
|
3145
3336
|
*/
|
|
3146
3337
|
if (appInstanceMap.has(this.appName)) {
|
|
3147
|
-
appInstanceMap.get(this.appName).
|
|
3338
|
+
appInstanceMap.get(this.appName).actionsForCompletelyDestroy();
|
|
3148
3339
|
}
|
|
3149
3340
|
const instance = new CreateApp({
|
|
3150
3341
|
name: this.appName,
|
|
@@ -3154,7 +3345,6 @@ function defineElement(tagName) {
|
|
|
3154
3345
|
inline: this.getDisposeResult('inline'),
|
|
3155
3346
|
scopecss: !(this.getDisposeResult('disableScopecss') || this.getDisposeResult('shadowDOM')),
|
|
3156
3347
|
useSandbox: !this.getDisposeResult('disableSandbox'),
|
|
3157
|
-
macro: this.getDisposeResult('macro'),
|
|
3158
3348
|
baseroute: this.getBaseRouteCompatible(),
|
|
3159
3349
|
});
|
|
3160
3350
|
appInstanceMap.set(this.appName, instance);
|
|
@@ -3279,13 +3469,12 @@ function filterPreFetchTarget(apps) {
|
|
|
3279
3469
|
* url: string,
|
|
3280
3470
|
* disableScopecss?: boolean,
|
|
3281
3471
|
* disableSandbox?: boolean,
|
|
3282
|
-
* macro?: boolean,
|
|
3283
3472
|
* },
|
|
3284
3473
|
* ...
|
|
3285
3474
|
* ])
|
|
3286
3475
|
* Note:
|
|
3287
3476
|
* 1: preFetch is asynchronous and is performed only when the browser is idle
|
|
3288
|
-
* 2: disableScopecss, disableSandbox
|
|
3477
|
+
* 2: disableScopecss, disableSandbox must be same with micro-app element, if conflict, the one who executes first shall prevail
|
|
3289
3478
|
* @param apps micro apps
|
|
3290
3479
|
*/
|
|
3291
3480
|
function preFetch(apps) {
|
|
@@ -3295,13 +3484,12 @@ function preFetch(apps) {
|
|
|
3295
3484
|
requestIdleCallback(() => {
|
|
3296
3485
|
isFunction(apps) && (apps = apps());
|
|
3297
3486
|
filterPreFetchTarget(apps).forEach((item) => {
|
|
3298
|
-
var _a, _b
|
|
3487
|
+
var _a, _b;
|
|
3299
3488
|
const app = new CreateApp({
|
|
3300
3489
|
name: item.name,
|
|
3301
3490
|
url: item.url,
|
|
3302
3491
|
scopecss: !((_a = item.disableScopecss) !== null && _a !== void 0 ? _a : microApp.disableScopecss),
|
|
3303
3492
|
useSandbox: !((_b = item.disableSandbox) !== null && _b !== void 0 ? _b : microApp.disableSandbox),
|
|
3304
|
-
macro: (_c = item.macro) !== null && _c !== void 0 ? _c : microApp.macro,
|
|
3305
3493
|
});
|
|
3306
3494
|
app.isPrefetch = true;
|
|
3307
3495
|
appInstanceMap.set(item.name, app);
|
|
@@ -3351,6 +3539,99 @@ function getGlobalAssets(assets) {
|
|
|
3351
3539
|
}
|
|
3352
3540
|
}
|
|
3353
3541
|
|
|
3542
|
+
/**
|
|
3543
|
+
* if app not prefetch & not unmount, then app is active
|
|
3544
|
+
* @param excludeHiddenApp exclude hidden keep-alive app
|
|
3545
|
+
* @returns active apps
|
|
3546
|
+
*/
|
|
3547
|
+
function getActiveApps(excludeHiddenApp) {
|
|
3548
|
+
const activeApps = [];
|
|
3549
|
+
appInstanceMap.forEach((app, appName) => {
|
|
3550
|
+
if (appStates.UNMOUNT !== app.getAppState() &&
|
|
3551
|
+
!app.isPrefetch &&
|
|
3552
|
+
(!excludeHiddenApp ||
|
|
3553
|
+
keepAliveStates.KEEP_ALIVE_HIDDEN !== app.getKeepAliveState())) {
|
|
3554
|
+
activeApps.push(appName);
|
|
3555
|
+
}
|
|
3556
|
+
});
|
|
3557
|
+
return activeApps;
|
|
3558
|
+
}
|
|
3559
|
+
// get all registered apps
|
|
3560
|
+
function getAllApps() {
|
|
3561
|
+
return Array.from(appInstanceMap.keys());
|
|
3562
|
+
}
|
|
3563
|
+
/**
|
|
3564
|
+
* unmount app by appname
|
|
3565
|
+
* @param appName
|
|
3566
|
+
* @param options unmountAppParams
|
|
3567
|
+
* @returns Promise<void>
|
|
3568
|
+
*/
|
|
3569
|
+
function unmountApp(appName, options) {
|
|
3570
|
+
const app = appInstanceMap.get(formatAppName(appName));
|
|
3571
|
+
return new Promise((reslove) => {
|
|
3572
|
+
if (app) {
|
|
3573
|
+
if (app.getAppState() === appStates.UNMOUNT || app.isPrefetch) {
|
|
3574
|
+
if (options === null || options === void 0 ? void 0 : options.destroy) {
|
|
3575
|
+
app.actionsForCompletelyDestroy();
|
|
3576
|
+
}
|
|
3577
|
+
reslove();
|
|
3578
|
+
}
|
|
3579
|
+
else if (app.getKeepAliveState() === keepAliveStates.KEEP_ALIVE_HIDDEN) {
|
|
3580
|
+
if (options === null || options === void 0 ? void 0 : options.destroy) {
|
|
3581
|
+
app.unmount(true, reslove);
|
|
3582
|
+
}
|
|
3583
|
+
else if (options === null || options === void 0 ? void 0 : options.clearAliveState) {
|
|
3584
|
+
app.unmount(false, reslove);
|
|
3585
|
+
}
|
|
3586
|
+
else {
|
|
3587
|
+
reslove();
|
|
3588
|
+
}
|
|
3589
|
+
}
|
|
3590
|
+
else {
|
|
3591
|
+
const container = getRootContainer(app.container);
|
|
3592
|
+
const unmountHandler = () => {
|
|
3593
|
+
container.removeEventListener('unmount', unmountHandler);
|
|
3594
|
+
container.removeEventListener('afterhidden', afterhiddenHandler);
|
|
3595
|
+
reslove();
|
|
3596
|
+
};
|
|
3597
|
+
const afterhiddenHandler = () => {
|
|
3598
|
+
container.removeEventListener('unmount', unmountHandler);
|
|
3599
|
+
container.removeEventListener('afterhidden', afterhiddenHandler);
|
|
3600
|
+
reslove();
|
|
3601
|
+
};
|
|
3602
|
+
container.addEventListener('unmount', unmountHandler);
|
|
3603
|
+
container.addEventListener('afterhidden', afterhiddenHandler);
|
|
3604
|
+
if (options === null || options === void 0 ? void 0 : options.destroy) {
|
|
3605
|
+
let destroyAttrValue, destoryAttrValue;
|
|
3606
|
+
container.hasAttribute('destroy') && (destroyAttrValue = container.getAttribute('destroy'));
|
|
3607
|
+
container.hasAttribute('destory') && (destoryAttrValue = container.getAttribute('destory'));
|
|
3608
|
+
container.setAttribute('destroy', 'true');
|
|
3609
|
+
container.parentNode.removeChild(container);
|
|
3610
|
+
container.removeAttribute('destroy');
|
|
3611
|
+
typeof destroyAttrValue === 'string' && container.setAttribute('destroy', destroyAttrValue);
|
|
3612
|
+
typeof destoryAttrValue === 'string' && container.setAttribute('destory', destoryAttrValue);
|
|
3613
|
+
}
|
|
3614
|
+
else if ((options === null || options === void 0 ? void 0 : options.clearAliveState) && container.hasAttribute('keep-alive')) {
|
|
3615
|
+
const keepAliveAttrValue = container.getAttribute('keep-alive');
|
|
3616
|
+
container.removeAttribute('keep-alive');
|
|
3617
|
+
container.parentNode.removeChild(container);
|
|
3618
|
+
container.setAttribute('keep-alive', keepAliveAttrValue);
|
|
3619
|
+
}
|
|
3620
|
+
else {
|
|
3621
|
+
container.parentNode.removeChild(container);
|
|
3622
|
+
}
|
|
3623
|
+
}
|
|
3624
|
+
}
|
|
3625
|
+
else {
|
|
3626
|
+
logWarn(`app ${appName} does not exist`);
|
|
3627
|
+
reslove();
|
|
3628
|
+
}
|
|
3629
|
+
});
|
|
3630
|
+
}
|
|
3631
|
+
// unmount all apps in turn
|
|
3632
|
+
function unmountAllApps(options) {
|
|
3633
|
+
return Array.from(appInstanceMap.keys()).reduce((pre, next) => pre.then(() => unmountApp(next, options)), Promise.resolve());
|
|
3634
|
+
}
|
|
3354
3635
|
class MicroApp extends EventCenterForBaseApp {
|
|
3355
3636
|
constructor() {
|
|
3356
3637
|
super(...arguments);
|
|
@@ -3385,7 +3666,6 @@ class MicroApp extends EventCenterForBaseApp {
|
|
|
3385
3666
|
this.inline = options.inline;
|
|
3386
3667
|
this.disableScopecss = options.disableScopecss;
|
|
3387
3668
|
this.disableSandbox = options.disableSandbox;
|
|
3388
|
-
this.macro = options.macro;
|
|
3389
3669
|
this.ssr = options.ssr;
|
|
3390
3670
|
isFunction(options.fetch) && (this.fetch = options.fetch);
|
|
3391
3671
|
isPlainObject(options.lifeCycles) && (this.lifeCycles = options.lifeCycles);
|
|
@@ -3414,5 +3694,5 @@ class MicroApp extends EventCenterForBaseApp {
|
|
|
3414
3694
|
var microApp = new MicroApp();
|
|
3415
3695
|
|
|
3416
3696
|
export default microApp;
|
|
3417
|
-
export { EventCenterForMicroApp, getActiveApps, getAllApps, preFetch, pureCreateElement, removeDomScope, unmountAllApps, unmountApp, version };
|
|
3697
|
+
export { EventCenterForMicroApp, MicroApp, getActiveApps, getAllApps, preFetch, pureCreateElement, removeDomScope, unmountAllApps, unmountApp, version };
|
|
3418
3698
|
//# sourceMappingURL=index.esm.js.map
|