@micro-zoe/micro-app 1.0.0-rc.8 → 1.0.0-rc.9
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 +10 -0
- package/lib/index.esm.js +144 -47
- 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/lib/index.d.ts
CHANGED
|
@@ -143,6 +143,10 @@ declare module '@micro-zoe/micro-app/libs/utils' {
|
|
|
143
143
|
export function isURL(target: unknown): target is URL;
|
|
144
144
|
export function isElement(target: unknown): target is Element;
|
|
145
145
|
export function isNode(target: unknown): target is Node;
|
|
146
|
+
export function isCanvasElement(target: unknown): target is HTMLAnchorElement;
|
|
147
|
+
export function isAnchorElement(target: unknown): target is HTMLAnchorElement;
|
|
148
|
+
export function isAudioElement(target: unknown): target is HTMLAnchorElement;
|
|
149
|
+
export function isVideoElement(target: unknown): target is HTMLAnchorElement;
|
|
146
150
|
export function isLinkElement(target: unknown): target is HTMLLinkElement;
|
|
147
151
|
export function isStyleElement(target: unknown): target is HTMLStyleElement;
|
|
148
152
|
export function isScriptElement(target: unknown): target is HTMLScriptElement;
|
|
@@ -340,6 +344,12 @@ declare module '@micro-zoe/micro-app/libs/utils' {
|
|
|
340
344
|
* target maybe number, string, array ...
|
|
341
345
|
*/
|
|
342
346
|
export function isEmptyObject(target: unknown): boolean;
|
|
347
|
+
/**
|
|
348
|
+
*
|
|
349
|
+
* @param {string} url input url
|
|
350
|
+
* @returns {boolean} is relative path
|
|
351
|
+
*/
|
|
352
|
+
export const isRelativePath: (url: string) => boolean;
|
|
343
353
|
}
|
|
344
354
|
|
|
345
355
|
declare module '@micro-zoe/micro-app/interact' {
|
package/lib/index.esm.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
const version = '1.0.0-rc.
|
|
1
|
+
const version = '1.0.0-rc.9';
|
|
2
2
|
// do not use isUndefined
|
|
3
3
|
const isBrowser = typeof window !== 'undefined';
|
|
4
4
|
// do not use isUndefined
|
|
@@ -89,6 +89,15 @@ function isNode(target) {
|
|
|
89
89
|
var _a;
|
|
90
90
|
return target instanceof Node || isNumber((_a = target) === null || _a === void 0 ? void 0 : _a.nodeType);
|
|
91
91
|
}
|
|
92
|
+
function isAnchorElement(target) {
|
|
93
|
+
return toTypeString(target) === '[object HTMLAnchorElement]';
|
|
94
|
+
}
|
|
95
|
+
function isAudioElement(target) {
|
|
96
|
+
return toTypeString(target) === '[object HTMLAudioElement]';
|
|
97
|
+
}
|
|
98
|
+
function isVideoElement(target) {
|
|
99
|
+
return toTypeString(target) === '[object HTMLVideoElement]';
|
|
100
|
+
}
|
|
92
101
|
function isLinkElement(target) {
|
|
93
102
|
return toTypeString(target) === '[object HTMLLinkElement]';
|
|
94
103
|
}
|
|
@@ -643,6 +652,12 @@ function formatEventType(type, appName) {
|
|
|
643
652
|
function isEmptyObject(target) {
|
|
644
653
|
return isPlainObject(target) ? !Object.keys(target).length : true;
|
|
645
654
|
}
|
|
655
|
+
/**
|
|
656
|
+
*
|
|
657
|
+
* @param {string} url input url
|
|
658
|
+
* @returns {boolean} is relative path
|
|
659
|
+
*/
|
|
660
|
+
const isRelativePath = (url) => !/^https?:\/\//i.test(url) && !/^\/\//i.test(url);
|
|
646
661
|
|
|
647
662
|
function formatEventInfo(event, element) {
|
|
648
663
|
Object.defineProperties(event, {
|
|
@@ -865,7 +880,7 @@ class CSSParser {
|
|
|
865
880
|
// reset scopecssDisableNextLine
|
|
866
881
|
this.scopecssDisableNextLine = false;
|
|
867
882
|
if (!selectors)
|
|
868
|
-
return
|
|
883
|
+
return this.printError('selector missing', this.linkPath);
|
|
869
884
|
this.recordResult(selectors);
|
|
870
885
|
this.matchComments();
|
|
871
886
|
this.styleDeclarations();
|
|
@@ -910,10 +925,10 @@ class CSSParser {
|
|
|
910
925
|
// https://developer.mozilla.org/en-US/docs/Web/API/CSSStyleDeclaration
|
|
911
926
|
styleDeclarations() {
|
|
912
927
|
if (!this.matchOpenBrace())
|
|
913
|
-
return
|
|
928
|
+
return this.printError("Declaration missing '{'", this.linkPath);
|
|
914
929
|
this.matchAllDeclarations();
|
|
915
930
|
if (!this.matchCloseBrace())
|
|
916
|
-
return
|
|
931
|
+
return this.printError("Declaration missing '}'", this.linkPath);
|
|
917
932
|
return true;
|
|
918
933
|
}
|
|
919
934
|
matchAllDeclarations(nesting = 0) {
|
|
@@ -936,7 +951,7 @@ class CSSParser {
|
|
|
936
951
|
}
|
|
937
952
|
// reset scopecssDisableNextLine
|
|
938
953
|
this.scopecssDisableNextLine = false;
|
|
939
|
-
if (!this.cssText)
|
|
954
|
+
if (!this.cssText.length)
|
|
940
955
|
return;
|
|
941
956
|
// extract comments in declarations
|
|
942
957
|
if (this.cssText.charAt(0) === '/') {
|
|
@@ -990,16 +1005,16 @@ class CSSParser {
|
|
|
990
1005
|
if (!this.commonMatch(/^@([-\w]+)?keyframes\s*/))
|
|
991
1006
|
return false;
|
|
992
1007
|
if (!this.commonMatch(/^[^{]+/))
|
|
993
|
-
return
|
|
1008
|
+
return this.printError('@keyframes missing name', this.linkPath);
|
|
994
1009
|
this.matchComments();
|
|
995
1010
|
if (!this.matchOpenBrace())
|
|
996
|
-
return
|
|
1011
|
+
return this.printError("@keyframes missing '{'", this.linkPath);
|
|
997
1012
|
this.matchComments();
|
|
998
1013
|
while (this.keyframeRule()) {
|
|
999
1014
|
this.matchComments();
|
|
1000
1015
|
}
|
|
1001
1016
|
if (!this.matchCloseBrace())
|
|
1002
|
-
return
|
|
1017
|
+
return this.printError("@keyframes missing '}'", this.linkPath);
|
|
1003
1018
|
this.matchLeadingSpaces();
|
|
1004
1019
|
return true;
|
|
1005
1020
|
}
|
|
@@ -1047,7 +1062,7 @@ class CSSParser {
|
|
|
1047
1062
|
this.matchComments();
|
|
1048
1063
|
this.matchRules();
|
|
1049
1064
|
if (!this.matchCloseBrace())
|
|
1050
|
-
return
|
|
1065
|
+
return this.printError('@layer missing \'}\'', this.linkPath);
|
|
1051
1066
|
this.matchLeadingSpaces();
|
|
1052
1067
|
return true;
|
|
1053
1068
|
}
|
|
@@ -1057,11 +1072,11 @@ class CSSParser {
|
|
|
1057
1072
|
if (!this.commonMatch(reg))
|
|
1058
1073
|
return false;
|
|
1059
1074
|
if (!this.matchOpenBrace())
|
|
1060
|
-
return
|
|
1075
|
+
return this.printError(`${name} missing '{'`, this.linkPath);
|
|
1061
1076
|
this.matchComments();
|
|
1062
1077
|
this.matchRules();
|
|
1063
1078
|
if (!this.matchCloseBrace())
|
|
1064
|
-
return
|
|
1079
|
+
return this.printError(`${name} missing '}'`, this.linkPath);
|
|
1065
1080
|
this.matchLeadingSpaces();
|
|
1066
1081
|
return true;
|
|
1067
1082
|
};
|
|
@@ -1079,10 +1094,10 @@ class CSSParser {
|
|
|
1079
1094
|
// common handler for @font-face, @page
|
|
1080
1095
|
commonHandlerForAtRuleWithSelfRule(name) {
|
|
1081
1096
|
if (!this.matchOpenBrace())
|
|
1082
|
-
return
|
|
1097
|
+
return this.printError(`@${name} missing '{'`, this.linkPath);
|
|
1083
1098
|
this.matchAllDeclarations();
|
|
1084
1099
|
if (!this.matchCloseBrace())
|
|
1085
|
-
return
|
|
1100
|
+
return this.printError(`@${name} missing '}'`, this.linkPath);
|
|
1086
1101
|
this.matchLeadingSpaces();
|
|
1087
1102
|
return true;
|
|
1088
1103
|
}
|
|
@@ -1102,7 +1117,7 @@ class CSSParser {
|
|
|
1102
1117
|
++i;
|
|
1103
1118
|
i += 2;
|
|
1104
1119
|
if (this.cssText.charAt(i - 1) === '') {
|
|
1105
|
-
return
|
|
1120
|
+
return this.printError('End of comment missing', this.linkPath);
|
|
1106
1121
|
}
|
|
1107
1122
|
// get comment content
|
|
1108
1123
|
let commentText = this.cssText.slice(2, i - 2);
|
|
@@ -1162,6 +1177,11 @@ class CSSParser {
|
|
|
1162
1177
|
this.result += strFragment;
|
|
1163
1178
|
}
|
|
1164
1179
|
}
|
|
1180
|
+
printError(msg, linkPath) {
|
|
1181
|
+
if (this.cssText.length) {
|
|
1182
|
+
parseError(msg, linkPath);
|
|
1183
|
+
}
|
|
1184
|
+
}
|
|
1165
1185
|
}
|
|
1166
1186
|
/**
|
|
1167
1187
|
* common method of bind CSS
|
|
@@ -2968,14 +2988,37 @@ function updateElementInfo(node, appName) {
|
|
|
2968
2988
|
* 1. 测试baseURI和ownerDocument在with沙箱中是否正确
|
|
2969
2989
|
* 经过验证with沙箱不能重写ownerDocument,否则react点击事件会触发两次
|
|
2970
2990
|
*/
|
|
2971
|
-
|
|
2991
|
+
const props = {
|
|
2972
2992
|
__MICRO_APP_NAME__: {
|
|
2973
2993
|
configurable: true,
|
|
2974
2994
|
enumerable: true,
|
|
2975
2995
|
writable: true,
|
|
2976
2996
|
value: appName,
|
|
2977
2997
|
},
|
|
2978
|
-
}
|
|
2998
|
+
};
|
|
2999
|
+
if (isAnchorElement(node)) {
|
|
3000
|
+
// a 标签
|
|
3001
|
+
const microApp = AppManager.getInstance().get(appName);
|
|
3002
|
+
if (microApp) {
|
|
3003
|
+
let originalHref = node.href;
|
|
3004
|
+
props.href = {
|
|
3005
|
+
get() {
|
|
3006
|
+
if (isRelativePath(originalHref)) {
|
|
3007
|
+
return `${microApp.url}${originalHref}`;
|
|
3008
|
+
}
|
|
3009
|
+
return originalHref;
|
|
3010
|
+
},
|
|
3011
|
+
set(value) {
|
|
3012
|
+
originalHref = value;
|
|
3013
|
+
}
|
|
3014
|
+
};
|
|
3015
|
+
}
|
|
3016
|
+
}
|
|
3017
|
+
if (isImageElement(node) || isVideoElement(node) || isAudioElement(node)) {
|
|
3018
|
+
// @ts-ignore
|
|
3019
|
+
node.crossOrigin = 'anonymous';
|
|
3020
|
+
}
|
|
3021
|
+
rawDefineProperties(node, props);
|
|
2979
3022
|
/**
|
|
2980
3023
|
* In FireFox, iframe Node.prototype will point to native Node.prototype after insert to document
|
|
2981
3024
|
*
|
|
@@ -5535,7 +5578,7 @@ const proxy2RawDocumentMethods = [
|
|
|
5535
5578
|
* @returns EffectHook
|
|
5536
5579
|
*/
|
|
5537
5580
|
function patchWindow$1(appName, microAppWindow, sandbox) {
|
|
5538
|
-
patchWindowProperty$1(appName, microAppWindow);
|
|
5581
|
+
patchWindowProperty$1(appName, microAppWindow, sandbox);
|
|
5539
5582
|
createProxyWindow$1(microAppWindow, sandbox);
|
|
5540
5583
|
return patchWindowEffect$1(microAppWindow);
|
|
5541
5584
|
}
|
|
@@ -5544,7 +5587,7 @@ function patchWindow$1(appName, microAppWindow, sandbox) {
|
|
|
5544
5587
|
* @param appName app name
|
|
5545
5588
|
* @param microAppWindow child app microWindow
|
|
5546
5589
|
*/
|
|
5547
|
-
function patchWindowProperty$1(appName, microAppWindow) {
|
|
5590
|
+
function patchWindowProperty$1(appName, microAppWindow, sandbox) {
|
|
5548
5591
|
const rawWindow = globalEnv.rawWindow;
|
|
5549
5592
|
escape2RawWindowKeys.forEach((key) => {
|
|
5550
5593
|
microAppWindow[key] = bindFunctionToRawTarget(rawWindow[key], rawWindow);
|
|
@@ -5589,25 +5632,10 @@ function patchWindowProperty$1(appName, microAppWindow) {
|
|
|
5589
5632
|
configurable: true,
|
|
5590
5633
|
enumerable: false,
|
|
5591
5634
|
value(target) {
|
|
5592
|
-
return target
|
|
5635
|
+
return instanceOf(target, rawWindow[key]) || instanceOf(target, microAppWindow[key]);
|
|
5593
5636
|
},
|
|
5594
5637
|
});
|
|
5595
5638
|
}
|
|
5596
|
-
// hijackInstanceOfWindowRegExpKeys.some((reg: RegExp) => {
|
|
5597
|
-
// if (reg.test(key) && key in rawWindow) {
|
|
5598
|
-
// rawDefineProperty(microAppWindow[key], Symbol.hasInstance, {
|
|
5599
|
-
// configurable: true,
|
|
5600
|
-
// enumerable: false,
|
|
5601
|
-
// value: (target: unknown) => {
|
|
5602
|
-
// return target instanceof rawWindow[key]
|
|
5603
|
-
// ? true
|
|
5604
|
-
// : instanceOf(target, microAppWindow[key])
|
|
5605
|
-
// },
|
|
5606
|
-
// })
|
|
5607
|
-
// return true
|
|
5608
|
-
// }
|
|
5609
|
-
// return false
|
|
5610
|
-
// })
|
|
5611
5639
|
return /^on/.test(key) && !SCOPE_WINDOW_ON_EVENT_OF_IFRAME.includes(key);
|
|
5612
5640
|
})
|
|
5613
5641
|
.forEach((eventName) => {
|
|
@@ -5628,6 +5656,23 @@ function patchWindowProperty$1(appName, microAppWindow) {
|
|
|
5628
5656
|
logWarn(e, appName);
|
|
5629
5657
|
}
|
|
5630
5658
|
});
|
|
5659
|
+
/**
|
|
5660
|
+
* In esmodule(vite) proxyWindow will not take effect,
|
|
5661
|
+
* escapeProperties should define to microAppWindow
|
|
5662
|
+
*/
|
|
5663
|
+
sandbox.escapeProperties.forEach((key) => {
|
|
5664
|
+
let rawValue = microAppWindow[key];
|
|
5665
|
+
rawDefineProperty(microAppWindow, key, {
|
|
5666
|
+
enumerable: true,
|
|
5667
|
+
configurable: true,
|
|
5668
|
+
get() {
|
|
5669
|
+
return rawValue !== null && rawValue !== void 0 ? rawValue : bindFunctionToRawTarget(rawWindow[key], rawWindow);
|
|
5670
|
+
},
|
|
5671
|
+
set(value) {
|
|
5672
|
+
rawValue = value;
|
|
5673
|
+
}
|
|
5674
|
+
});
|
|
5675
|
+
});
|
|
5631
5676
|
}
|
|
5632
5677
|
/**
|
|
5633
5678
|
* create proxyWindow with Proxy(microAppWindow)
|
|
@@ -5662,7 +5707,7 @@ function createProxyWindow$1(microAppWindow, sandbox) {
|
|
|
5662
5707
|
* 2. window.key in module app(vite), fall into microAppWindow(iframeWindow), escapeProperties will not take effect
|
|
5663
5708
|
* 3. if (key)... --> fall into microAppWindow(iframeWindow), escapeProperties will not take effect
|
|
5664
5709
|
*/
|
|
5665
|
-
if (includes(sandbox.escapeProperties, key) && !Reflect.
|
|
5710
|
+
if (includes(sandbox.escapeProperties, key) && !Reflect.get(target, key)) {
|
|
5666
5711
|
return bindFunctionToRawTarget(Reflect.get(rawWindow, key), rawWindow);
|
|
5667
5712
|
}
|
|
5668
5713
|
return bindFunctionToRawTarget(Reflect.get(target, key), target);
|
|
@@ -5674,17 +5719,13 @@ function createProxyWindow$1(microAppWindow, sandbox) {
|
|
|
5674
5719
|
if (!Reflect.has(target, key)) {
|
|
5675
5720
|
customProperties.add(key);
|
|
5676
5721
|
}
|
|
5722
|
+
// sandbox.escapeProperties will not set to rawWindow from rc.9
|
|
5677
5723
|
Reflect.set(target, key, value);
|
|
5678
|
-
if (includes(sandbox.escapeProperties, key)) {
|
|
5679
|
-
!Reflect.has(rawWindow, key) && sandbox.escapeKeys.add(key);
|
|
5680
|
-
Reflect.set(rawWindow, key, value);
|
|
5681
|
-
}
|
|
5682
5724
|
return true;
|
|
5683
5725
|
},
|
|
5684
5726
|
has: (target, key) => key in target,
|
|
5685
5727
|
deleteProperty: (target, key) => {
|
|
5686
5728
|
if (Reflect.has(target, key)) {
|
|
5687
|
-
sandbox.escapeKeys.has(key) && Reflect.deleteProperty(rawWindow, key);
|
|
5688
5729
|
return Reflect.deleteProperty(target, key);
|
|
5689
5730
|
}
|
|
5690
5731
|
return true;
|
|
@@ -6378,8 +6419,6 @@ class IframeSandbox {
|
|
|
6378
6419
|
this.active = false;
|
|
6379
6420
|
// Properties that can be escape to rawWindow
|
|
6380
6421
|
this.escapeProperties = [];
|
|
6381
|
-
// Properties escape to rawWindow, cleared when unmount
|
|
6382
|
-
this.escapeKeys = new Set();
|
|
6383
6422
|
// Update the base.href when initial and each redirect
|
|
6384
6423
|
this.updateIframeBase = () => {
|
|
6385
6424
|
var _a;
|
|
@@ -6495,10 +6534,6 @@ class IframeSandbox {
|
|
|
6495
6534
|
/* --- memory router part --- end */
|
|
6496
6535
|
if (!umdMode || destroy) {
|
|
6497
6536
|
this.deleteIframeElement();
|
|
6498
|
-
this.escapeKeys.forEach((key) => {
|
|
6499
|
-
Reflect.deleteProperty(globalEnv.rawWindow, key);
|
|
6500
|
-
});
|
|
6501
|
-
this.escapeKeys.clear();
|
|
6502
6537
|
this.clearHijackUmdHooks();
|
|
6503
6538
|
}
|
|
6504
6539
|
if (--globalEnv.activeSandbox === 0) {
|
|
@@ -7852,7 +7887,7 @@ function patchElementAndDocument() {
|
|
|
7852
7887
|
},
|
|
7853
7888
|
set(code) {
|
|
7854
7889
|
globalEnv.rawInnerHTMLDesc.set.call(this, code);
|
|
7855
|
-
const currentAppName = this.__MICRO_APP_NAME__ || getCurrentAppName();
|
|
7890
|
+
const currentAppName = this.__MICRO_APP_NAME__ || getIframeCurrentAppName() || getCurrentAppName();
|
|
7856
7891
|
Array.from(this.children).forEach((child) => {
|
|
7857
7892
|
if (isElement(child) && currentAppName) {
|
|
7858
7893
|
updateElementInfo(child, currentAppName);
|
|
@@ -8027,6 +8062,68 @@ function rejectMicroAppStyle() {
|
|
|
8027
8062
|
}
|
|
8028
8063
|
}
|
|
8029
8064
|
|
|
8065
|
+
// 重写 Worker 构造函数的类型
|
|
8066
|
+
const originalWorker = window.Worker;
|
|
8067
|
+
function isSameOrigin(url) {
|
|
8068
|
+
if (url instanceof URL && url.protocol === 'blob:') {
|
|
8069
|
+
// 如果 url 是 Blob URL,直接返回 true
|
|
8070
|
+
return true;
|
|
8071
|
+
}
|
|
8072
|
+
// 检查 URL 是否与当前页面在同一个源
|
|
8073
|
+
try {
|
|
8074
|
+
const parsedUrl = new URL(url);
|
|
8075
|
+
return (parsedUrl.protocol === window.location.protocol &&
|
|
8076
|
+
parsedUrl.hostname === window.location.hostname &&
|
|
8077
|
+
parsedUrl.port === window.location.port);
|
|
8078
|
+
}
|
|
8079
|
+
catch (error) {
|
|
8080
|
+
return false;
|
|
8081
|
+
}
|
|
8082
|
+
}
|
|
8083
|
+
function urlFromScript(script) {
|
|
8084
|
+
let blob;
|
|
8085
|
+
try {
|
|
8086
|
+
blob = new Blob([script], {
|
|
8087
|
+
type: 'application/javascript'
|
|
8088
|
+
});
|
|
8089
|
+
}
|
|
8090
|
+
catch (e) {
|
|
8091
|
+
const BlobBuilder =
|
|
8092
|
+
// @ts-ignore
|
|
8093
|
+
window.BlobBuilder ||
|
|
8094
|
+
// @ts-ignore
|
|
8095
|
+
window.WebKitBlobBuilder ||
|
|
8096
|
+
// @ts-ignore
|
|
8097
|
+
window.MozBlobBuilder ||
|
|
8098
|
+
// @ts-ignore
|
|
8099
|
+
window.MSBlobBuilder;
|
|
8100
|
+
const blobBuilder = new BlobBuilder();
|
|
8101
|
+
blobBuilder.append(script);
|
|
8102
|
+
blob = blobBuilder.getBlob('application/javascript');
|
|
8103
|
+
}
|
|
8104
|
+
const URL = window.URL || window.webkitURL;
|
|
8105
|
+
return URL.createObjectURL(blob);
|
|
8106
|
+
}
|
|
8107
|
+
// @ts-ignore
|
|
8108
|
+
const WorkerProxy = new Proxy(originalWorker, {
|
|
8109
|
+
construct(Target, args) {
|
|
8110
|
+
const [scriptURL, options] = args;
|
|
8111
|
+
if (!isSameOrigin(scriptURL)) {
|
|
8112
|
+
// 如果 scriptURL 是跨域的,使用 Blob URL 加载并执行 worker
|
|
8113
|
+
const script = `import "${scriptURL}";`;
|
|
8114
|
+
const workerPath = urlFromScript(script);
|
|
8115
|
+
options.type = 'module';
|
|
8116
|
+
return new Target(workerPath, options);
|
|
8117
|
+
}
|
|
8118
|
+
else {
|
|
8119
|
+
// 如果 scriptURL 是同源的,直接使用原生的 Worker 构造函数
|
|
8120
|
+
return new Target(scriptURL, options);
|
|
8121
|
+
}
|
|
8122
|
+
},
|
|
8123
|
+
});
|
|
8124
|
+
// @ts-ignore
|
|
8125
|
+
window.Worker = WorkerProxy;
|
|
8126
|
+
|
|
8030
8127
|
const globalEnv = {
|
|
8031
8128
|
// active sandbox count
|
|
8032
8129
|
activeSandbox: 0,
|