@micro-zoe/micro-app 0.8.1 → 0.8.5
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.md +1 -1
- package/README.zh-cn.md +1 -1
- package/lib/index.d.ts +1 -0
- package/lib/index.esm.js +185 -162
- package/lib/index.esm.js.map +1 -1
- package/lib/index.min.js +1 -1
- package/lib/index.min.js.map +1 -1
- package/lib/index.umd.js +1 -1
- package/lib/index.umd.js.map +1 -1
- package/package.json +1 -1
- package/typings/global.d.ts +3 -2
package/README.md
CHANGED
|
@@ -152,7 +152,7 @@ For more commands, see [DEVELP](https://github.com/micro-zoe/micro-app/blob/mast
|
|
|
152
152
|
</details>
|
|
153
153
|
|
|
154
154
|
# Contributors
|
|
155
|
-
<a href="https://github.com/micro-zoe/micro-app/graphs/contributors"><img src="
|
|
155
|
+
<a href="https://github.com/micro-zoe/micro-app/graphs/contributors"><img src="https://micro-zoe.com/contributors.svg?height=55&people=11" /></a>
|
|
156
156
|
<!-- opencollective is inaccurate -->
|
|
157
157
|
<!-- <a href="https://github.com/micro-zoe/micro-app/graphs/contributors"><img src="https://opencollective.com/micro-app/contributors.svg?width=890&button=false" /></a> -->
|
|
158
158
|
|
package/README.zh-cn.md
CHANGED
|
@@ -153,7 +153,7 @@ yarn start # 访问 http://localhost:3000
|
|
|
153
153
|
</details>
|
|
154
154
|
|
|
155
155
|
# 贡献者们
|
|
156
|
-
<a href="https://github.com/micro-zoe/micro-app/graphs/contributors"><img src="
|
|
156
|
+
<a href="https://github.com/micro-zoe/micro-app/graphs/contributors"><img src="https://micro-zoe.com/contributors.svg?height=55&people=11" /></a>
|
|
157
157
|
<!-- opencollective is inaccurate -->
|
|
158
158
|
<!-- <a href="https://github.com/micro-zoe/micro-app/graphs/contributors"><img src="https://opencollective.com/micro-app/contributors.svg?width=890&button=false" /></a> -->
|
|
159
159
|
|
package/lib/index.d.ts
CHANGED
package/lib/index.esm.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
const version = '0.8.
|
|
1
|
+
const version = '0.8.5';
|
|
2
2
|
// do not use isUndefined
|
|
3
3
|
const isBrowser = typeof window !== 'undefined';
|
|
4
4
|
// do not use isUndefined
|
|
@@ -224,7 +224,7 @@ const requestIdleCallback = globalThis.requestIdleCallback ||
|
|
|
224
224
|
return Math.max(0, 50 - (Date.now() - lastTime));
|
|
225
225
|
},
|
|
226
226
|
});
|
|
227
|
-
},
|
|
227
|
+
}, 50);
|
|
228
228
|
};
|
|
229
229
|
/**
|
|
230
230
|
* Record the currently running app.name
|
|
@@ -303,6 +303,9 @@ function getRootContainer(target) {
|
|
|
303
303
|
function trim(str) {
|
|
304
304
|
return str ? str.replace(/^\s+|\s+$/g, '') : '';
|
|
305
305
|
}
|
|
306
|
+
function isFireFox() {
|
|
307
|
+
return navigator.userAgent.indexOf('Firefox') > -1;
|
|
308
|
+
}
|
|
306
309
|
|
|
307
310
|
var ObservedAttrName;
|
|
308
311
|
(function (ObservedAttrName) {
|
|
@@ -359,9 +362,8 @@ function fetchSource(url, appName = null, options = {}) {
|
|
|
359
362
|
// common reg
|
|
360
363
|
const rootSelectorREG = /(^|\s+)(html|:root)(?=[\s>~[.#:]+|$)/;
|
|
361
364
|
const bodySelectorREG = /(^|\s+)((html[\s>~]+body)|body)(?=[\s>~[.#:]+|$)/;
|
|
362
|
-
const cssUrlREG = /url\(["']?([^)"']+)["']?\)/gm;
|
|
363
365
|
function parseError(msg, linkPath) {
|
|
364
|
-
msg = linkPath ? `${linkPath}
|
|
366
|
+
msg = linkPath ? `${linkPath} ${msg}` : msg;
|
|
365
367
|
const err = new Error(msg);
|
|
366
368
|
err.reason = msg;
|
|
367
369
|
if (linkPath) {
|
|
@@ -370,7 +372,7 @@ function parseError(msg, linkPath) {
|
|
|
370
372
|
throw err;
|
|
371
373
|
}
|
|
372
374
|
/**
|
|
373
|
-
* Reference
|
|
375
|
+
* Reference https://github.com/reworkcss/css
|
|
374
376
|
* CSSParser mainly deals with 3 scenes: styleRule, @, and comment
|
|
375
377
|
* And scopecss deals with 2 scenes: selector & url
|
|
376
378
|
* And can also disable scopecss with inline comments
|
|
@@ -404,7 +406,7 @@ class CSSParser {
|
|
|
404
406
|
this.baseURI = baseURI;
|
|
405
407
|
this.linkPath = linkPath || '';
|
|
406
408
|
this.matchRules();
|
|
407
|
-
return this.result;
|
|
409
|
+
return isFireFox() ? decodeURIComponent(this.result) : this.result;
|
|
408
410
|
}
|
|
409
411
|
reset() {
|
|
410
412
|
this.cssText = this.prefix = this.baseURI = this.linkPath = this.result = '';
|
|
@@ -423,92 +425,76 @@ class CSSParser {
|
|
|
423
425
|
}
|
|
424
426
|
// https://developer.mozilla.org/en-US/docs/Web/API/CSSStyleRule
|
|
425
427
|
matchStyleRule() {
|
|
426
|
-
const
|
|
428
|
+
const selectors = this.formatSelector(true);
|
|
427
429
|
// reset scopecssDisableNextLine
|
|
428
430
|
this.scopecssDisableNextLine = false;
|
|
429
|
-
if (!
|
|
431
|
+
if (!selectors)
|
|
430
432
|
return parseError('selector missing', this.linkPath);
|
|
431
|
-
this.
|
|
433
|
+
this.recordResult(selectors);
|
|
432
434
|
this.matchComments();
|
|
433
435
|
this.styleDeclarations();
|
|
434
436
|
this.matchLeadingSpaces();
|
|
435
437
|
return true;
|
|
436
438
|
}
|
|
439
|
+
formatSelector(skip) {
|
|
440
|
+
const m = this.commonMatch(/^([^{]+)/, skip);
|
|
441
|
+
if (!m)
|
|
442
|
+
return false;
|
|
443
|
+
return m[0].replace(/(^|,[\n\s]*)([^,]+)/g, (_, separator, selector) => {
|
|
444
|
+
selector = trim(selector);
|
|
445
|
+
if (!(this.scopecssDisableNextLine ||
|
|
446
|
+
(this.scopecssDisable && (!this.scopecssDisableSelectors.length ||
|
|
447
|
+
this.scopecssDisableSelectors.includes(selector))) ||
|
|
448
|
+
rootSelectorREG.test(selector))) {
|
|
449
|
+
if (bodySelectorREG.test(selector)) {
|
|
450
|
+
selector = selector.replace(bodySelectorREG, this.prefix + ' micro-app-body');
|
|
451
|
+
}
|
|
452
|
+
else {
|
|
453
|
+
selector = this.prefix + ' ' + selector;
|
|
454
|
+
}
|
|
455
|
+
}
|
|
456
|
+
return separator + selector;
|
|
457
|
+
});
|
|
458
|
+
}
|
|
437
459
|
// https://developer.mozilla.org/en-US/docs/Web/API/CSSStyleDeclaration
|
|
438
460
|
styleDeclarations() {
|
|
439
461
|
if (!this.matchOpenBrace())
|
|
440
462
|
return parseError("Declaration missing '{'", this.linkPath);
|
|
441
|
-
this.
|
|
442
|
-
while (this.styleDeclaration()) {
|
|
443
|
-
this.matchComments();
|
|
444
|
-
}
|
|
463
|
+
this.matchAllDeclarations();
|
|
445
464
|
if (!this.matchCloseBrace())
|
|
446
465
|
return parseError("Declaration missing '}'", this.linkPath);
|
|
447
466
|
return true;
|
|
448
467
|
}
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
// ./a/b.png ../a/b.png a/b.png
|
|
467
|
-
if (/^((\.\.?\/)|[^/])/.test($1) && this.linkPath) {
|
|
468
|
-
this.baseURI = getLinkFileDir(this.linkPath);
|
|
469
|
-
}
|
|
470
|
-
return `url("${CompletionPath($1, this.baseURI)}")`;
|
|
471
|
-
});
|
|
468
|
+
matchAllDeclarations() {
|
|
469
|
+
let cssValue = this.commonMatch(/^(?:url\(["']?(?:[^)"'}]+)["']?\)|[^}/])*/, true)[0];
|
|
470
|
+
if (cssValue) {
|
|
471
|
+
if (!this.scopecssDisableNextLine &&
|
|
472
|
+
(!this.scopecssDisable || this.scopecssDisableSelectors.length)) {
|
|
473
|
+
cssValue = cssValue.replace(/url\(["']?([^)"']+)["']?\)/gm, (all, $1) => {
|
|
474
|
+
if (/^((data|blob):|#)/.test($1) || /^(https?:)?\/\//.test($1)) {
|
|
475
|
+
return all;
|
|
476
|
+
}
|
|
477
|
+
// ./a/b.png ../a/b.png a/b.png
|
|
478
|
+
if (/^((\.\.?\/)|[^/])/.test($1) && this.linkPath) {
|
|
479
|
+
this.baseURI = getLinkFileDir(this.linkPath);
|
|
480
|
+
}
|
|
481
|
+
return `url("${CompletionPath($1, this.baseURI)}")`;
|
|
482
|
+
});
|
|
483
|
+
}
|
|
484
|
+
this.recordResult(cssValue);
|
|
472
485
|
}
|
|
473
486
|
// reset scopecssDisableNextLine
|
|
474
487
|
this.scopecssDisableNextLine = false;
|
|
475
|
-
this.
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
return
|
|
485
|
-
.replace(/\/\*([^*]|[\r\n]|(\*+([^*/]|[\r\n])))*\*\/+/g, '')
|
|
486
|
-
.replace(/"(?:\\"|[^"])*"|'(?:\\'|[^'])*'/g, (r) => {
|
|
487
|
-
return r.replace(/,/g, '\u200C');
|
|
488
|
-
})
|
|
489
|
-
.split(/\s*(?![^(]*\)),\s*/)
|
|
490
|
-
.map((s) => {
|
|
491
|
-
const selectorText = s.replace(/\u200C/g, ',');
|
|
492
|
-
if (this.scopecssDisableNextLine) {
|
|
493
|
-
return selectorText;
|
|
494
|
-
}
|
|
495
|
-
else if (this.scopecssDisable) {
|
|
496
|
-
if (!this.scopecssDisableSelectors.length ||
|
|
497
|
-
this.scopecssDisableSelectors.includes(selectorText)) {
|
|
498
|
-
return selectorText;
|
|
499
|
-
}
|
|
500
|
-
}
|
|
501
|
-
if (selectorText === '*') {
|
|
502
|
-
return this.prefix + ' *';
|
|
503
|
-
}
|
|
504
|
-
else if (bodySelectorREG.test(selectorText)) {
|
|
505
|
-
return selectorText.replace(bodySelectorREG, this.prefix + ' micro-app-body');
|
|
506
|
-
}
|
|
507
|
-
else if (rootSelectorREG.test(selectorText)) { // ignore root selector
|
|
508
|
-
return selectorText;
|
|
509
|
-
}
|
|
510
|
-
return this.prefix + ' ' + selectorText;
|
|
511
|
-
});
|
|
488
|
+
if (!this.cssText || this.cssText.charAt(0) === '}')
|
|
489
|
+
return;
|
|
490
|
+
// extract comments in declarations
|
|
491
|
+
if (this.cssText.charAt(0) === '/' && this.cssText.charAt(1) === '*') {
|
|
492
|
+
this.matchComments();
|
|
493
|
+
}
|
|
494
|
+
else {
|
|
495
|
+
this.commonMatch(/\/+/);
|
|
496
|
+
}
|
|
497
|
+
return this.matchAllDeclarations();
|
|
512
498
|
}
|
|
513
499
|
matchAtRule() {
|
|
514
500
|
if (this.cssText[0] !== '@')
|
|
@@ -569,7 +555,7 @@ class CSSParser {
|
|
|
569
555
|
pageRule() {
|
|
570
556
|
if (!this.commonMatch(/^@page */))
|
|
571
557
|
return false;
|
|
572
|
-
this.formatSelector();
|
|
558
|
+
this.formatSelector(false);
|
|
573
559
|
// reset scopecssDisableNextLine
|
|
574
560
|
this.scopecssDisableNextLine = false;
|
|
575
561
|
return this.commonHandlerForAtRuleWithSelfRule('page');
|
|
@@ -602,17 +588,14 @@ class CSSParser {
|
|
|
602
588
|
if (!this.commonMatch(reg))
|
|
603
589
|
return false;
|
|
604
590
|
this.matchLeadingSpaces();
|
|
605
|
-
return
|
|
591
|
+
return true;
|
|
606
592
|
};
|
|
607
593
|
}
|
|
608
594
|
// common handler for @font-face, @page
|
|
609
595
|
commonHandlerForAtRuleWithSelfRule(name) {
|
|
610
596
|
if (!this.matchOpenBrace())
|
|
611
597
|
return parseError(`@${name} missing '{'`, this.linkPath);
|
|
612
|
-
this.
|
|
613
|
-
while (this.styleDeclaration()) {
|
|
614
|
-
this.matchComments();
|
|
615
|
-
}
|
|
598
|
+
this.matchAllDeclarations();
|
|
616
599
|
if (!this.matchCloseBrace())
|
|
617
600
|
return parseError(`@${name} missing '}'`, this.linkPath);
|
|
618
601
|
this.matchLeadingSpaces();
|
|
@@ -638,7 +621,7 @@ class CSSParser {
|
|
|
638
621
|
}
|
|
639
622
|
// get comment content
|
|
640
623
|
let commentText = this.cssText.slice(2, i - 2);
|
|
641
|
-
this.
|
|
624
|
+
this.recordResult(`/*${commentText}*/`);
|
|
642
625
|
commentText = trim(commentText.replace(/^\s*!/, ''));
|
|
643
626
|
// set ignore config
|
|
644
627
|
if (commentText === 'scopecss-disable-next-line') {
|
|
@@ -671,7 +654,7 @@ class CSSParser {
|
|
|
671
654
|
const matchStr = matchArray[0];
|
|
672
655
|
this.cssText = this.cssText.slice(matchStr.length);
|
|
673
656
|
if (!skip)
|
|
674
|
-
this.
|
|
657
|
+
this.recordResult(matchStr);
|
|
675
658
|
return matchArray;
|
|
676
659
|
}
|
|
677
660
|
matchOpenBrace() {
|
|
@@ -684,6 +667,16 @@ class CSSParser {
|
|
|
684
667
|
matchLeadingSpaces() {
|
|
685
668
|
this.commonMatch(/^\s*/);
|
|
686
669
|
}
|
|
670
|
+
// splice string
|
|
671
|
+
recordResult(strFragment) {
|
|
672
|
+
// Firefox is slow when string contain special characters, see https://github.com/micro-zoe/micro-app/issues/256
|
|
673
|
+
if (isFireFox()) {
|
|
674
|
+
this.result += encodeURIComponent(strFragment);
|
|
675
|
+
}
|
|
676
|
+
else {
|
|
677
|
+
this.result += strFragment;
|
|
678
|
+
}
|
|
679
|
+
}
|
|
687
680
|
}
|
|
688
681
|
/**
|
|
689
682
|
* common method of bind CSS
|
|
@@ -698,7 +691,7 @@ function commonAction(styleElement, appName, prefix, baseURI, linkPath) {
|
|
|
698
691
|
}
|
|
699
692
|
catch (e) {
|
|
700
693
|
parser.reset();
|
|
701
|
-
logError('
|
|
694
|
+
logError('An error occurred while parsing CSS:\n', appName, e);
|
|
702
695
|
}
|
|
703
696
|
if (result)
|
|
704
697
|
styleElement.textContent = result;
|
|
@@ -834,11 +827,9 @@ function extractLinkFromHtml(link, parent, app, isDynamic = false) {
|
|
|
834
827
|
*/
|
|
835
828
|
function fetchLinksFromHtml(wrapElement, app, microAppHead) {
|
|
836
829
|
const linkEntries = Array.from(app.source.links.entries());
|
|
837
|
-
const fetchLinkPromise = []
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
globalLinkCode ? fetchLinkPromise.push(globalLinkCode) : fetchLinkPromise.push(fetchSource(url, app.name));
|
|
841
|
-
}
|
|
830
|
+
const fetchLinkPromise = linkEntries.map(([url]) => {
|
|
831
|
+
return globalLinks.has(url) ? globalLinks.get(url) : fetchSource(url, app.name);
|
|
832
|
+
});
|
|
842
833
|
promiseStream(fetchLinkPromise, (res) => {
|
|
843
834
|
fetchLinkSuccess(linkEntries[res.index][0], linkEntries[res.index][1], res.data, microAppHead, app);
|
|
844
835
|
}, (err) => {
|
|
@@ -1115,6 +1106,27 @@ function patchElementPrototypeMethods() {
|
|
|
1115
1106
|
this.__MICRO_APP_NAME__ && (clonedNode.__MICRO_APP_NAME__ = this.__MICRO_APP_NAME__);
|
|
1116
1107
|
return clonedNode;
|
|
1117
1108
|
};
|
|
1109
|
+
// patch getBoundingClientRect
|
|
1110
|
+
// TODO: scenes test
|
|
1111
|
+
// Element.prototype.getBoundingClientRect = function getBoundingClientRect () {
|
|
1112
|
+
// const rawRect: DOMRect = globalEnv.rawGetBoundingClientRect.call(this)
|
|
1113
|
+
// if (this.__MICRO_APP_NAME__) {
|
|
1114
|
+
// const app = appInstanceMap.get(this.__MICRO_APP_NAME__)
|
|
1115
|
+
// if (!app?.container) {
|
|
1116
|
+
// return rawRect
|
|
1117
|
+
// }
|
|
1118
|
+
// const appBody = app.container.querySelector('micro-app-body')
|
|
1119
|
+
// const appBodyRect: DOMRect = globalEnv.rawGetBoundingClientRect.call(appBody)
|
|
1120
|
+
// const computedRect: DOMRect = new DOMRect(
|
|
1121
|
+
// rawRect.x - appBodyRect.x,
|
|
1122
|
+
// rawRect.y - appBodyRect.y,
|
|
1123
|
+
// rawRect.width,
|
|
1124
|
+
// rawRect.height,
|
|
1125
|
+
// )
|
|
1126
|
+
// return computedRect
|
|
1127
|
+
// }
|
|
1128
|
+
// return rawRect
|
|
1129
|
+
// }
|
|
1118
1130
|
}
|
|
1119
1131
|
/**
|
|
1120
1132
|
* Mark the newly created element in the micro application
|
|
@@ -1281,6 +1293,7 @@ function releasePatches() {
|
|
|
1281
1293
|
Element.prototype.append = globalEnv.rawAppend;
|
|
1282
1294
|
Element.prototype.prepend = globalEnv.rawPrepend;
|
|
1283
1295
|
Element.prototype.cloneNode = globalEnv.rawCloneNode;
|
|
1296
|
+
// Element.prototype.getBoundingClientRect = globalEnv.rawGetBoundingClientRect
|
|
1284
1297
|
}
|
|
1285
1298
|
// Set the style of micro-app-head and micro-app-body
|
|
1286
1299
|
let hasRejectMicroAppStyle = false;
|
|
@@ -1334,6 +1347,7 @@ function initGlobalEnv() {
|
|
|
1334
1347
|
const rawAppend = Element.prototype.append;
|
|
1335
1348
|
const rawPrepend = Element.prototype.prepend;
|
|
1336
1349
|
const rawCloneNode = Element.prototype.cloneNode;
|
|
1350
|
+
// const rawGetBoundingClientRect = Element.prototype.getBoundingClientRect
|
|
1337
1351
|
const rawCreateElement = Document.prototype.createElement;
|
|
1338
1352
|
const rawCreateElementNS = Document.prototype.createElementNS;
|
|
1339
1353
|
const rawCreateDocumentFragment = Document.prototype.createDocumentFragment;
|
|
@@ -1377,6 +1391,7 @@ function initGlobalEnv() {
|
|
|
1377
1391
|
rawAppend,
|
|
1378
1392
|
rawPrepend,
|
|
1379
1393
|
rawCloneNode,
|
|
1394
|
+
// rawGetBoundingClientRect,
|
|
1380
1395
|
rawCreateElement,
|
|
1381
1396
|
rawCreateElementNS,
|
|
1382
1397
|
rawCreateDocumentFragment,
|
|
@@ -1497,7 +1512,7 @@ function fetchScriptsFromHtml(wrapElement, app) {
|
|
|
1497
1512
|
if (globalScriptText) {
|
|
1498
1513
|
info.code = globalScriptText;
|
|
1499
1514
|
}
|
|
1500
|
-
else if (!info.defer && !info.async) {
|
|
1515
|
+
else if ((!info.defer && !info.async) || app.isPrefetch) {
|
|
1501
1516
|
fetchScriptPromise.push(fetchSource(url, app.name));
|
|
1502
1517
|
fetchScriptPromiseInfo.push([url, info]);
|
|
1503
1518
|
}
|
|
@@ -1590,7 +1605,7 @@ function execScripts(scriptList, app, initHook) {
|
|
|
1590
1605
|
function runScript(url, app, info, isDynamic, callback) {
|
|
1591
1606
|
var _a;
|
|
1592
1607
|
try {
|
|
1593
|
-
const code = bindScope(url, app, info.code, info
|
|
1608
|
+
const code = bindScope(url, app, info.code, info);
|
|
1594
1609
|
if (app.inline || info.module) {
|
|
1595
1610
|
const scriptElement = pureCreateElement('script');
|
|
1596
1611
|
runCode2InlineScript(url, code, info.module, scriptElement, callback);
|
|
@@ -1643,7 +1658,7 @@ function runDynamicRemoteScript(url, info, app, originScript) {
|
|
|
1643
1658
|
app.source.scripts.set(url, info);
|
|
1644
1659
|
info.isGlobal && globalScripts.set(url, code);
|
|
1645
1660
|
try {
|
|
1646
|
-
code = bindScope(url, app, code, info
|
|
1661
|
+
code = bindScope(url, app, code, info);
|
|
1647
1662
|
if (app.inline || info.module) {
|
|
1648
1663
|
runCode2InlineScript(url, code, info.module, replaceElement, dispatchScriptOnLoadEvent);
|
|
1649
1664
|
}
|
|
@@ -1699,13 +1714,13 @@ function runCode2Function(code, info) {
|
|
|
1699
1714
|
* @param url script address
|
|
1700
1715
|
* @param app app
|
|
1701
1716
|
* @param code code
|
|
1702
|
-
* @param
|
|
1717
|
+
* @param info source script info
|
|
1703
1718
|
*/
|
|
1704
|
-
function bindScope(url, app, code,
|
|
1719
|
+
function bindScope(url, app, code, info) {
|
|
1705
1720
|
if (isPlainObject(microApp.plugins)) {
|
|
1706
|
-
code = usePlugins(url, code, app.name, microApp.plugins);
|
|
1721
|
+
code = usePlugins(url, code, app.name, microApp.plugins, info);
|
|
1707
1722
|
}
|
|
1708
|
-
if (app.sandBox && !module) {
|
|
1723
|
+
if (app.sandBox && !info.module) {
|
|
1709
1724
|
globalEnv.rawWindow.__MICRO_APP_PROXY_WINDOW__ = app.sandBox.proxyWindow;
|
|
1710
1725
|
return `;(function(proxyWindow){with(proxyWindow.__MICRO_APP_WINDOW__){(function(${globalKeyToBeCached}){;${code}\n}).call(proxyWindow,${globalKeyToBeCached})}})(window.__MICRO_APP_PROXY_WINDOW__);`;
|
|
1711
1726
|
}
|
|
@@ -1717,19 +1732,20 @@ function bindScope(url, app, code, module) {
|
|
|
1717
1732
|
* @param code code
|
|
1718
1733
|
* @param appName app name
|
|
1719
1734
|
* @param plugins plugin list
|
|
1735
|
+
* @param info source script info
|
|
1720
1736
|
*/
|
|
1721
|
-
function usePlugins(url, code, appName, plugins) {
|
|
1737
|
+
function usePlugins(url, code, appName, plugins, info) {
|
|
1722
1738
|
var _a;
|
|
1723
|
-
const newCode = processCode(plugins.global, code, url);
|
|
1724
|
-
return processCode((_a = plugins.modules) === null || _a === void 0 ? void 0 : _a[appName], newCode, url);
|
|
1739
|
+
const newCode = processCode(plugins.global, code, url, info);
|
|
1740
|
+
return processCode((_a = plugins.modules) === null || _a === void 0 ? void 0 : _a[appName], newCode, url, info);
|
|
1725
1741
|
}
|
|
1726
|
-
function processCode(configs, code, url) {
|
|
1742
|
+
function processCode(configs, code, url, info) {
|
|
1727
1743
|
if (!isArray(configs)) {
|
|
1728
1744
|
return code;
|
|
1729
1745
|
}
|
|
1730
1746
|
return configs.reduce((preCode, config) => {
|
|
1731
1747
|
if (isPlainObject(config) && isFunction(config.loader)) {
|
|
1732
|
-
return config.loader(preCode, url, config.options);
|
|
1748
|
+
return config.loader(preCode, url, config.options, info);
|
|
1733
1749
|
}
|
|
1734
1750
|
return preCode;
|
|
1735
1751
|
}, code);
|
|
@@ -2432,8 +2448,11 @@ const escapeSetterKeyList = [
|
|
|
2432
2448
|
const globalPropertyList = ['window', 'self', 'globalThis'];
|
|
2433
2449
|
class SandBox {
|
|
2434
2450
|
constructor(appName, url) {
|
|
2435
|
-
|
|
2436
|
-
|
|
2451
|
+
/**
|
|
2452
|
+
* Scoped global Properties(Properties that can only get and set in microAppWindow, will not escape to rawWindow)
|
|
2453
|
+
* https://github.com/micro-zoe/micro-app/issues/234
|
|
2454
|
+
*/
|
|
2455
|
+
this.scopeProperties = ['webpackJsonp', 'Vue'];
|
|
2437
2456
|
// Properties that can be escape to rawWindow
|
|
2438
2457
|
this.escapeProperties = [];
|
|
2439
2458
|
// Properties newly added to microAppWindow
|
|
@@ -2631,10 +2650,12 @@ class SandBox {
|
|
|
2631
2650
|
microAppWindow.__MICRO_APP_NAME__ = appName;
|
|
2632
2651
|
microAppWindow.__MICRO_APP_PUBLIC_PATH__ = getEffectivePath(url);
|
|
2633
2652
|
microAppWindow.__MICRO_APP_WINDOW__ = microAppWindow;
|
|
2634
|
-
microAppWindow.microApp = new EventCenterForMicroApp(appName)
|
|
2653
|
+
microAppWindow.microApp = Object.assign(new EventCenterForMicroApp(appName), {
|
|
2654
|
+
removeDomScope,
|
|
2655
|
+
pureCreateElement,
|
|
2656
|
+
});
|
|
2635
2657
|
microAppWindow.rawWindow = globalEnv.rawWindow;
|
|
2636
2658
|
microAppWindow.rawDocument = globalEnv.rawDocument;
|
|
2637
|
-
microAppWindow.removeDomScope = removeDomScope;
|
|
2638
2659
|
microAppWindow.hasOwnProperty = (key) => rawHasOwnProperty.call(microAppWindow, key) || rawHasOwnProperty.call(globalEnv.rawWindow, key);
|
|
2639
2660
|
this.setMappingPropertiesWithRawDescriptor(microAppWindow);
|
|
2640
2661
|
this.setHijackProperties(microAppWindow, appName);
|
|
@@ -2779,6 +2800,7 @@ class CreateApp {
|
|
|
2779
2800
|
this.libraryName = null;
|
|
2780
2801
|
this.umdMode = false;
|
|
2781
2802
|
this.isPrefetch = false;
|
|
2803
|
+
this.prefetchResolve = null;
|
|
2782
2804
|
this.container = null;
|
|
2783
2805
|
this.baseroute = '';
|
|
2784
2806
|
this.sandBox = null;
|
|
@@ -2807,12 +2829,17 @@ class CreateApp {
|
|
|
2807
2829
|
* When resource is loaded, mount app if it is not prefetch or unmount
|
|
2808
2830
|
*/
|
|
2809
2831
|
onLoad(html) {
|
|
2832
|
+
var _a;
|
|
2810
2833
|
if (++this.loadSourceLevel === 2) {
|
|
2811
2834
|
this.source.html = html;
|
|
2812
|
-
if (this.isPrefetch
|
|
2813
|
-
|
|
2814
|
-
|
|
2815
|
-
|
|
2835
|
+
if (this.isPrefetch) {
|
|
2836
|
+
(_a = this.prefetchResolve) === null || _a === void 0 ? void 0 : _a.call(this);
|
|
2837
|
+
this.prefetchResolve = null;
|
|
2838
|
+
}
|
|
2839
|
+
else if (appStates.UNMOUNT !== this.state) {
|
|
2840
|
+
this.state = appStates.LOAD_SOURCE_FINISHED;
|
|
2841
|
+
this.mount();
|
|
2842
|
+
}
|
|
2816
2843
|
}
|
|
2817
2844
|
}
|
|
2818
2845
|
/**
|
|
@@ -2821,6 +2848,10 @@ class CreateApp {
|
|
|
2821
2848
|
*/
|
|
2822
2849
|
onLoadError(e) {
|
|
2823
2850
|
this.loadSourceLevel = -1;
|
|
2851
|
+
if (this.prefetchResolve) {
|
|
2852
|
+
this.prefetchResolve();
|
|
2853
|
+
this.prefetchResolve = null;
|
|
2854
|
+
}
|
|
2824
2855
|
if (appStates.UNMOUNT !== this.state) {
|
|
2825
2856
|
this.onerror(e);
|
|
2826
2857
|
this.state = appStates.LOAD_SOURCE_ERROR;
|
|
@@ -3406,21 +3437,6 @@ function defineElement(tagName) {
|
|
|
3406
3437
|
window.customElements.define(tagName, MicroAppElement);
|
|
3407
3438
|
}
|
|
3408
3439
|
|
|
3409
|
-
function filterPreFetchTarget(apps) {
|
|
3410
|
-
const validApps = [];
|
|
3411
|
-
if (isArray(apps)) {
|
|
3412
|
-
apps.forEach((item) => {
|
|
3413
|
-
if (isPlainObject(item)) {
|
|
3414
|
-
item.name = formatAppName(item.name);
|
|
3415
|
-
item.url = formatAppURL(item.url, item.name);
|
|
3416
|
-
if (item.name && item.url && !appInstanceMap.has(item.name)) {
|
|
3417
|
-
validApps.push(item);
|
|
3418
|
-
}
|
|
3419
|
-
}
|
|
3420
|
-
});
|
|
3421
|
-
}
|
|
3422
|
-
return validApps;
|
|
3423
|
-
}
|
|
3424
3440
|
/**
|
|
3425
3441
|
* preFetch([
|
|
3426
3442
|
* {
|
|
@@ -3442,16 +3458,37 @@ function preFetch(apps) {
|
|
|
3442
3458
|
}
|
|
3443
3459
|
requestIdleCallback(() => {
|
|
3444
3460
|
isFunction(apps) && (apps = apps());
|
|
3445
|
-
|
|
3461
|
+
if (isArray(apps)) {
|
|
3462
|
+
apps.reduce((pre, next) => pre.then(() => preFetchInSerial(next)), Promise.resolve());
|
|
3463
|
+
}
|
|
3464
|
+
});
|
|
3465
|
+
}
|
|
3466
|
+
// sequential preload app
|
|
3467
|
+
function preFetchInSerial(prefetchApp) {
|
|
3468
|
+
return new Promise((resolve) => {
|
|
3469
|
+
requestIdleCallback(() => {
|
|
3446
3470
|
var _a, _b;
|
|
3447
|
-
|
|
3448
|
-
name
|
|
3449
|
-
url
|
|
3450
|
-
|
|
3451
|
-
|
|
3452
|
-
|
|
3453
|
-
|
|
3454
|
-
|
|
3471
|
+
if (isPlainObject(prefetchApp) && navigator.onLine) {
|
|
3472
|
+
prefetchApp.name = formatAppName(prefetchApp.name);
|
|
3473
|
+
prefetchApp.url = formatAppURL(prefetchApp.url, prefetchApp.name);
|
|
3474
|
+
if (prefetchApp.name && prefetchApp.url && !appInstanceMap.has(prefetchApp.name)) {
|
|
3475
|
+
const app = new CreateApp({
|
|
3476
|
+
name: prefetchApp.name,
|
|
3477
|
+
url: prefetchApp.url,
|
|
3478
|
+
scopecss: !((_a = prefetchApp.disableScopecss) !== null && _a !== void 0 ? _a : microApp.disableScopecss),
|
|
3479
|
+
useSandbox: !((_b = prefetchApp.disableSandbox) !== null && _b !== void 0 ? _b : microApp.disableSandbox),
|
|
3480
|
+
});
|
|
3481
|
+
app.isPrefetch = true;
|
|
3482
|
+
app.prefetchResolve = resolve;
|
|
3483
|
+
appInstanceMap.set(prefetchApp.name, app);
|
|
3484
|
+
}
|
|
3485
|
+
else {
|
|
3486
|
+
resolve();
|
|
3487
|
+
}
|
|
3488
|
+
}
|
|
3489
|
+
else {
|
|
3490
|
+
resolve();
|
|
3491
|
+
}
|
|
3455
3492
|
});
|
|
3456
3493
|
});
|
|
3457
3494
|
}
|
|
@@ -3462,38 +3499,24 @@ function preFetch(apps) {
|
|
|
3462
3499
|
function getGlobalAssets(assets) {
|
|
3463
3500
|
if (isPlainObject(assets)) {
|
|
3464
3501
|
requestIdleCallback(() => {
|
|
3465
|
-
|
|
3466
|
-
|
|
3467
|
-
|
|
3468
|
-
|
|
3469
|
-
|
|
3470
|
-
|
|
3471
|
-
|
|
3472
|
-
|
|
3473
|
-
|
|
3474
|
-
|
|
3475
|
-
|
|
3476
|
-
|
|
3477
|
-
|
|
3478
|
-
|
|
3479
|
-
|
|
3480
|
-
}
|
|
3481
|
-
if (isArray(assets.css)) {
|
|
3482
|
-
const effectiveCss = assets.css.filter((path) => isString(path) && path.includes('.css') && !globalLinks.has(path));
|
|
3483
|
-
const fetchCssPromise = [];
|
|
3484
|
-
effectiveCss.forEach((path) => {
|
|
3485
|
-
fetchCssPromise.push(fetchSource(path));
|
|
3486
|
-
});
|
|
3487
|
-
// fetch css with stream
|
|
3488
|
-
promiseStream(fetchCssPromise, (res) => {
|
|
3489
|
-
const path = effectiveCss[res.index];
|
|
3490
|
-
if (!globalLinks.has(path)) {
|
|
3491
|
-
globalLinks.set(path, res.data);
|
|
3492
|
-
}
|
|
3493
|
-
}, (err) => {
|
|
3494
|
-
logError(err);
|
|
3495
|
-
});
|
|
3502
|
+
fetchGlobalResources(assets.js, 'js', globalScripts);
|
|
3503
|
+
fetchGlobalResources(assets.css, 'css', globalLinks);
|
|
3504
|
+
});
|
|
3505
|
+
}
|
|
3506
|
+
}
|
|
3507
|
+
// TODO: requestIdleCallback for every file
|
|
3508
|
+
function fetchGlobalResources(resources, suffix, cache) {
|
|
3509
|
+
if (isArray(resources)) {
|
|
3510
|
+
const effectiveResource = resources.filter((path) => isString(path) && path.includes(`.${suffix}`) && !cache.has(path));
|
|
3511
|
+
const fetchResourcePromise = effectiveResource.map((path) => fetchSource(path));
|
|
3512
|
+
// fetch resource with stream
|
|
3513
|
+
promiseStream(fetchResourcePromise, (res) => {
|
|
3514
|
+
const path = effectiveResource[res.index];
|
|
3515
|
+
if (!cache.has(path)) {
|
|
3516
|
+
cache.set(path, res.data);
|
|
3496
3517
|
}
|
|
3518
|
+
}, (err) => {
|
|
3519
|
+
logError(err);
|
|
3497
3520
|
});
|
|
3498
3521
|
}
|
|
3499
3522
|
}
|