@blueking/bk-weweb 0.0.6 → 0.0.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/dist/collect-source.js +202 -198
- package/dist/collect-source.js.map +1 -1
- package/dist/index.esm.js +292 -196
- package/dist/index.esm.js.map +1 -1
- package/dist/index.min.js +1 -1
- package/dist/index.min.js.map +1 -1
- package/dist/index.umd.js +1 -1
- package/dist/index.umd.js.map +1 -1
- package/package.json +1 -1
- package/typings/base-app/collect-source.d.ts +1 -1
- package/typings/base-app/element.d.ts +2 -0
- package/typings/cache/app-cache.d.ts +1 -0
- package/typings/context/cache.d.ts +6 -0
- package/typings/context/window.d.ts +0 -5
- package/typings/entry/entry.d.ts +2 -2
- package/typings/entry/script.d.ts +1 -0
- package/typings/entry/style.d.ts +2 -0
- package/typings/index.d.ts +1 -1
- package/typings/typings/global.d.ts +0 -3
- package/typings/typings/index.d.ts +1 -0
- package/typings/typings/source.d.ts +2 -0
- package/typings/utils/common.d.ts +2 -12
- package/typings/utils/custom.d.ts +3 -0
- package/typings/utils/element.d.ts +1 -1
- package/typings/utils/index.d.ts +1 -1
- package/typings/utils/load-source.d.ts +1 -1
package/dist/collect-source.js
CHANGED
|
@@ -12,73 +12,6 @@ var AppState;
|
|
|
12
12
|
AppState["UNMOUNT"] = "UNMOUNT";
|
|
13
13
|
})(AppState || (AppState = {}));
|
|
14
14
|
|
|
15
|
-
// is function
|
|
16
|
-
function isFunction(target) {
|
|
17
|
-
return typeof target === 'function';
|
|
18
|
-
}
|
|
19
|
-
// Promise.then might be synchronized in Zone.js context, we need to use setTimeout instead to mock next tick.
|
|
20
|
-
const nextTask = typeof window.Zone === 'function' ? setTimeout : cb => Promise.resolve().then(cb);
|
|
21
|
-
function addUrlProtocol(url) {
|
|
22
|
-
return url.startsWith('//') ? `${location.protocol}${url}` : url;
|
|
23
|
-
}
|
|
24
|
-
// Get valid address, such as https://xxx/xx/xx.html to https://xxx/xx/
|
|
25
|
-
function getUrlDir(url) {
|
|
26
|
-
const { origin, pathname } = new URL(url);
|
|
27
|
-
if (/\.(\w+)$/.test(pathname)) {
|
|
28
|
-
const fullPath = `${origin}${pathname}`;
|
|
29
|
-
const pathArr = fullPath.split('/');
|
|
30
|
-
pathArr.pop();
|
|
31
|
-
return `${pathArr.join('/')}/`;
|
|
32
|
-
}
|
|
33
|
-
return `${origin}${pathname}/`.replace(/\/\/$/, '/');
|
|
34
|
-
}
|
|
35
|
-
// 补齐url地址
|
|
36
|
-
function fillUpPath(path, baseURI) {
|
|
37
|
-
if (!path || /^((((ht|f)tps?)|file):)?\/\//.test(path) || /^(data|blob):/.test(path))
|
|
38
|
-
return path;
|
|
39
|
-
return new URL(path, getUrlDir(addUrlProtocol(baseURI))).toString();
|
|
40
|
-
}
|
|
41
|
-
// 获取url目录
|
|
42
|
-
function getFileDir(linkpath) {
|
|
43
|
-
const pathArr = linkpath.split('/');
|
|
44
|
-
pathArr.pop();
|
|
45
|
-
return addUrlProtocol(`${pathArr.join('/')}/`);
|
|
46
|
-
}
|
|
47
|
-
// is ie11
|
|
48
|
-
const isIE11 = typeof navigator !== 'undefined' && navigator.userAgent.indexOf('Trident') !== -1;
|
|
49
|
-
// 随机url
|
|
50
|
-
function randomUrl() {
|
|
51
|
-
return `inline-${random(16)}`;
|
|
52
|
-
}
|
|
53
|
-
// Array deduplication
|
|
54
|
-
function arrayUnique(array) {
|
|
55
|
-
return Array.from(new Set(array));
|
|
56
|
-
}
|
|
57
|
-
// is safari browser
|
|
58
|
-
function isSafari() {
|
|
59
|
-
return /Safari/.test(navigator.userAgent);
|
|
60
|
-
}
|
|
61
|
-
// Create pure elements
|
|
62
|
-
function createElement$1(tagName, options) {
|
|
63
|
-
const element = document.createElement(tagName, options);
|
|
64
|
-
if (element.__BK_WEWEB_APP_KEY__)
|
|
65
|
-
delete element.__BK_WEWEB_APP_KEY__;
|
|
66
|
-
return element;
|
|
67
|
-
}
|
|
68
|
-
// bodyle element
|
|
69
|
-
function isBodyElement(key) {
|
|
70
|
-
return /^(body|head|html)$/i.test(key);
|
|
71
|
-
}
|
|
72
|
-
// create random string
|
|
73
|
-
const random = (n, str = 'abcdefghijklmnopqrstuvwxyz0123456789') => {
|
|
74
|
-
// 生成n位长度的字符串
|
|
75
|
-
let result = '';
|
|
76
|
-
for (let i = 0; i < n; i++) {
|
|
77
|
-
result += str[parseInt((Math.random() * str.length).toString(), 10)];
|
|
78
|
-
}
|
|
79
|
-
return result;
|
|
80
|
-
};
|
|
81
|
-
|
|
82
15
|
let currentRunningApp = null;
|
|
83
16
|
function getCurrentRunningApp() {
|
|
84
17
|
return currentRunningApp;
|
|
@@ -86,8 +19,6 @@ function getCurrentRunningApp() {
|
|
|
86
19
|
function setCurrentRunningApp(appInstance) {
|
|
87
20
|
currentRunningApp = appInstance;
|
|
88
21
|
}
|
|
89
|
-
const documentClickListMap = new Map();
|
|
90
|
-
const documentEventListenerMap = new Map();
|
|
91
22
|
const script = document.createElement('script');
|
|
92
23
|
const isSupportModuleScript = 'noModule' in script;
|
|
93
24
|
const SCOPED_CSS_STYLE_ID = 'SCOPED_CSS_STYLE_ID';
|
|
@@ -99,6 +30,7 @@ const disabledStyleDom = templateStyle;
|
|
|
99
30
|
|
|
100
31
|
const { document: document$1 } = window;
|
|
101
32
|
const { createElement, querySelector, querySelectorAll, getElementById, getElementsByClassName, getElementsByTagName, getElementsByName, } = Document.prototype;
|
|
33
|
+
const SPECIAL_ELEMENT_TAG = ['body', 'html', 'head'];
|
|
102
34
|
function rewriteDocumentPrototypeMethods() {
|
|
103
35
|
Document.prototype.createElement = function (tagName, options) {
|
|
104
36
|
const element = createElement.call(this, tagName, options);
|
|
@@ -118,14 +50,14 @@ function rewriteDocumentPrototypeMethods() {
|
|
|
118
50
|
};
|
|
119
51
|
function querySelectorNew(selectors) {
|
|
120
52
|
const app = getCurrentRunningApp();
|
|
121
|
-
if (!app || !selectors ||
|
|
53
|
+
if (!app || !selectors || SPECIAL_ELEMENT_TAG.includes(selectors) || document$1 !== this) {
|
|
122
54
|
return querySelector.call(this, selectors);
|
|
123
55
|
}
|
|
124
56
|
return app?.container?.querySelector(selectors) ?? null;
|
|
125
57
|
}
|
|
126
58
|
function querySelectorAllNew(selectors) {
|
|
127
59
|
const app = getCurrentRunningApp();
|
|
128
|
-
if (!app || !selectors ||
|
|
60
|
+
if (!app || !selectors || SPECIAL_ELEMENT_TAG.includes(selectors) || document$1 !== this) {
|
|
129
61
|
return querySelectorAll.call(this, selectors);
|
|
130
62
|
}
|
|
131
63
|
return app?.container?.querySelectorAll(selectors) ?? [];
|
|
@@ -158,7 +90,7 @@ function rewriteDocumentPrototypeMethods() {
|
|
|
158
90
|
Document.prototype.getElementsByTagName = function (key) {
|
|
159
91
|
const app = getCurrentRunningApp();
|
|
160
92
|
if (!app
|
|
161
|
-
||
|
|
93
|
+
|| SPECIAL_ELEMENT_TAG.includes(key)
|
|
162
94
|
|| (!app?.showSourceCode && key.toLocaleLowerCase() === 'script')) {
|
|
163
95
|
return getElementsByTagName.call(this, key);
|
|
164
96
|
}
|
|
@@ -191,6 +123,31 @@ function resetDocumentPrototypeMethods() {
|
|
|
191
123
|
Document.prototype.getElementsByName = getElementsByName;
|
|
192
124
|
}
|
|
193
125
|
|
|
126
|
+
const nextTask = cb => Promise.resolve().then(cb);
|
|
127
|
+
function addUrlProtocol(url) {
|
|
128
|
+
return url.startsWith('//') ? `${location.protocol}${url}` : url;
|
|
129
|
+
}
|
|
130
|
+
// 补齐url地址
|
|
131
|
+
function fillUpPath(path, baseURI) {
|
|
132
|
+
if (!path || /^((((ht|f)tps?)|file):)?\/\//.test(path) || /^(data|blob):/.test(path))
|
|
133
|
+
return path;
|
|
134
|
+
const { origin, pathname } = new URL(addUrlProtocol(baseURI));
|
|
135
|
+
return new URL(path, `${origin}${pathname}`.replace(/\.(\w+)$/, '/')).toString();
|
|
136
|
+
}
|
|
137
|
+
// 随机url
|
|
138
|
+
function randomUrl() {
|
|
139
|
+
return `inline-${random(16)}`;
|
|
140
|
+
}
|
|
141
|
+
// create random string
|
|
142
|
+
const random = (n, str = 'abcdefghijklmnopqrstuvwxyz0123456789') => {
|
|
143
|
+
// 生成n位长度的字符串
|
|
144
|
+
let result = '';
|
|
145
|
+
for (let i = 0; i < n; i++) {
|
|
146
|
+
result += str[parseInt((Math.random() * str.length).toString(), 10)];
|
|
147
|
+
}
|
|
148
|
+
return result;
|
|
149
|
+
};
|
|
150
|
+
|
|
194
151
|
const CSS_ATTRIBUTE_KEY = 'id';
|
|
195
152
|
var CSS_RULE_TYPE;
|
|
196
153
|
(function (CSS_RULE_TYPE) {
|
|
@@ -263,7 +220,7 @@ const commonFakeWindowKeyMap = {
|
|
|
263
220
|
__bk_zIndex_manager: true,
|
|
264
221
|
};
|
|
265
222
|
|
|
266
|
-
function
|
|
223
|
+
function createEventSource(event, element) {
|
|
267
224
|
Object.defineProperties(event, {
|
|
268
225
|
currentTarget: {
|
|
269
226
|
get() {
|
|
@@ -284,23 +241,17 @@ function eventHandler(event, element) {
|
|
|
284
241
|
}
|
|
285
242
|
function dispatchLinkOrScriptLoad(element) {
|
|
286
243
|
const event = new CustomEvent('load');
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
element.onload(event)
|
|
290
|
-
|
|
291
|
-
else {
|
|
292
|
-
element.dispatchEvent(event);
|
|
293
|
-
}
|
|
244
|
+
createEventSource(event, element);
|
|
245
|
+
typeof element.onload === 'function'
|
|
246
|
+
? element.onload(event)
|
|
247
|
+
: element.dispatchEvent(event);
|
|
294
248
|
}
|
|
295
249
|
function dispatchLinkOrScriptError(element) {
|
|
296
250
|
const event = new CustomEvent('error');
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
element.onerror(event)
|
|
300
|
-
|
|
301
|
-
else {
|
|
302
|
-
element.dispatchEvent(event);
|
|
303
|
-
}
|
|
251
|
+
createEventSource(event, element);
|
|
252
|
+
typeof element.onerror === 'function'
|
|
253
|
+
? element.onerror(event)
|
|
254
|
+
: element.dispatchEvent(event);
|
|
304
255
|
}
|
|
305
256
|
|
|
306
257
|
/* eslint-disable no-param-reassign */
|
|
@@ -342,7 +293,7 @@ class Style {
|
|
|
342
293
|
}
|
|
343
294
|
async excuteCode(app) {
|
|
344
295
|
app.registerRunningApp();
|
|
345
|
-
let styleElement =
|
|
296
|
+
let styleElement = this.createStyleElement();
|
|
346
297
|
styleElement.setAttribute('type', 'text/css');
|
|
347
298
|
styleElement.textContent = this.code;
|
|
348
299
|
try {
|
|
@@ -356,6 +307,18 @@ class Style {
|
|
|
356
307
|
}
|
|
357
308
|
return styleElement;
|
|
358
309
|
}
|
|
310
|
+
// 主应用已生效的样式 不再应用在子应用
|
|
311
|
+
linkedBaseStyle(styleElement, app) {
|
|
312
|
+
if (!(app.container instanceof ShadowRoot)
|
|
313
|
+
&& styleElement.textContent
|
|
314
|
+
&& appCache.getBaseAppStyle(styleElement.textContent)) {
|
|
315
|
+
styleElement.textContent = '';
|
|
316
|
+
styleElement.innerHTML = '';
|
|
317
|
+
styleElement.setAttribute('linked-from-base', 'true');
|
|
318
|
+
return true;
|
|
319
|
+
}
|
|
320
|
+
return false;
|
|
321
|
+
}
|
|
359
322
|
scopedStyleCSS(app, styleElement) {
|
|
360
323
|
const needKeepAlive = !!app.keepAlive && !(app.container instanceof ShadowRoot);
|
|
361
324
|
setMarkElement(styleElement, app, needKeepAlive);
|
|
@@ -364,6 +327,8 @@ class Style {
|
|
|
364
327
|
styleElement.textContent = '';
|
|
365
328
|
styleElement.innerHTML = '';
|
|
366
329
|
}
|
|
330
|
+
if (this.linkedBaseStyle(styleElement, app))
|
|
331
|
+
return styleElement;
|
|
367
332
|
disabledStyleDom.textContent = this.code;
|
|
368
333
|
this.commonScoped(disabledStyleDom, styleElement, app);
|
|
369
334
|
disabledStyleDom.textContent = '';
|
|
@@ -373,7 +338,9 @@ class Style {
|
|
|
373
338
|
if (!(styleElement.textContent || styleElement.sheet?.cssRules?.length))
|
|
374
339
|
return;
|
|
375
340
|
observer.disconnect();
|
|
376
|
-
this.
|
|
341
|
+
if (!this.linkedBaseStyle(styleElement, app)) {
|
|
342
|
+
this.commonScoped(styleElement, styleElement, app);
|
|
343
|
+
}
|
|
377
344
|
});
|
|
378
345
|
observer.observe(styleElement, { attributes: false, childList: true, subtree: true, characterData: true });
|
|
379
346
|
}
|
|
@@ -381,7 +348,7 @@ class Style {
|
|
|
381
348
|
return styleElement;
|
|
382
349
|
}
|
|
383
350
|
scopedLinkCSS(app, linkElement) {
|
|
384
|
-
const styleElement =
|
|
351
|
+
const styleElement = this.createStyleElement();
|
|
385
352
|
styleElement.setAttribute('type', 'text/css');
|
|
386
353
|
const needKeepAlive = !!app.keepAlive && !(app.container instanceof ShadowRoot);
|
|
387
354
|
setMarkElement(styleElement, app, needKeepAlive);
|
|
@@ -432,7 +399,7 @@ class Style {
|
|
|
432
399
|
const cssPrefix = `#${app.name}`;
|
|
433
400
|
const scopedCss = this.scopeRule(rules, cssPrefix);
|
|
434
401
|
let cssText = this.resetUrlHost(scopedCss, app.url, this.url);
|
|
435
|
-
if (
|
|
402
|
+
if (/Safari/.test(navigator.userAgent)) {
|
|
436
403
|
cssText = cssText.replace(/([;{]\s*content:\s*)([^\s"][^";}]*)/gm, (all, $1, $2) => {
|
|
437
404
|
if ($2 === 'none' || /^(url\()|(counter\()|(attr\()|(open-quote)|(close-quote)/.test($2)) {
|
|
438
405
|
return all;
|
|
@@ -479,7 +446,9 @@ class Style {
|
|
|
479
446
|
return text;
|
|
480
447
|
}
|
|
481
448
|
if (/^((\.\.?\/)|[^/])/.test($1) && linkpath) {
|
|
482
|
-
|
|
449
|
+
const pathArr = linkpath.split('/');
|
|
450
|
+
pathArr.pop();
|
|
451
|
+
baseURI = addUrlProtocol(`${pathArr.join('/')}/`);
|
|
483
452
|
}
|
|
484
453
|
return `url("${fillUpPath($1, baseURI)}")`;
|
|
485
454
|
});
|
|
@@ -500,6 +469,12 @@ class Style {
|
|
|
500
469
|
return `${$1} ${prefix} ${$2.replace(/^\s*/, '')}`;
|
|
501
470
|
}));
|
|
502
471
|
}
|
|
472
|
+
createStyleElement() {
|
|
473
|
+
const styleElement = document.createElement('style');
|
|
474
|
+
if (styleElement.__BK_WEWEB_APP_KEY__)
|
|
475
|
+
delete styleElement.__BK_WEWEB_APP_KEY__;
|
|
476
|
+
return styleElement;
|
|
477
|
+
}
|
|
503
478
|
}
|
|
504
479
|
async function excuteAppStyles(app, container) {
|
|
505
480
|
const styleList = Array.from(app.source.styles.values());
|
|
@@ -513,7 +488,7 @@ async function excuteAppStyles(app, container) {
|
|
|
513
488
|
document.head.append(...styleElementList);
|
|
514
489
|
}
|
|
515
490
|
else {
|
|
516
|
-
parentElemnt?.
|
|
491
|
+
parentElemnt?.append(...styleElementList);
|
|
517
492
|
}
|
|
518
493
|
});
|
|
519
494
|
}
|
|
@@ -524,6 +499,29 @@ function resetNewElement(parent, child, app) {
|
|
|
524
499
|
if (child.hasAttribute('exclude')) {
|
|
525
500
|
return document.createComment('【bk-weweb】style with exclude attribute is ignored');
|
|
526
501
|
}
|
|
502
|
+
if (child.textContent) {
|
|
503
|
+
// 父级应用样式已生效情况下 即可忽略子应用对应样式 webcomponent的隔离下优化不生效
|
|
504
|
+
if (!(app.container instanceof ShadowRoot)
|
|
505
|
+
&& appCache.getBaseAppStyle(child.textContent)) {
|
|
506
|
+
return document.createComment('【bk-weweb】style is effective in base app');
|
|
507
|
+
}
|
|
508
|
+
}
|
|
509
|
+
// else {
|
|
510
|
+
// const observer = new MutationObserver(() => {
|
|
511
|
+
// if (child.textContent) {
|
|
512
|
+
// observer.disconnect();
|
|
513
|
+
// if (!(app.container instanceof ShadowRoot)
|
|
514
|
+
// && appCache.getBaseAppStyle(child.textContent)) {
|
|
515
|
+
// debugger;
|
|
516
|
+
// console.info('--------------');
|
|
517
|
+
// child.sheet!.disabled = true;
|
|
518
|
+
// child.setAttribute('aaaaaaaaaaaa', '------');
|
|
519
|
+
// parent.removeChild(child);
|
|
520
|
+
// }
|
|
521
|
+
// }
|
|
522
|
+
// });
|
|
523
|
+
// observer.observe(child, { attributeFilter: ['src'], childList: true, subtree: false });
|
|
524
|
+
// }
|
|
527
525
|
if (!child.hasAttribute('ignore')) {
|
|
528
526
|
const styleInstance = new Style({
|
|
529
527
|
code: child.textContent || '',
|
|
@@ -637,7 +635,7 @@ function elementInsertHandler(parent, newChild, passiveChild, rawMethod) {
|
|
|
637
635
|
return rawMethod.call(parent, newChild, passiveChild);
|
|
638
636
|
}
|
|
639
637
|
function setMarkElement(element, app, keepAlive) {
|
|
640
|
-
if (keepAlive) {
|
|
638
|
+
if (keepAlive && app) {
|
|
641
639
|
element.__KEEP_ALIVE__ = app.appCacheKey;
|
|
642
640
|
element.setAttribute('data-from', app.name);
|
|
643
641
|
element.setAttribute('data-keep-alive', 'true');
|
|
@@ -731,7 +729,7 @@ function bindFunctionToRawWindow(rawWindow, value) {
|
|
|
731
729
|
if (rawWindowMethodMap.has(value)) {
|
|
732
730
|
return rawWindowMethodMap.get(value);
|
|
733
731
|
}
|
|
734
|
-
if (
|
|
732
|
+
if (typeof value === 'function' && !isConstructor(value)) {
|
|
735
733
|
const bindRawWindowValue = value.bind(rawWindow);
|
|
736
734
|
Object.keys(value).forEach(key => (bindRawWindowValue[key] = value[key]));
|
|
737
735
|
// eslint-disable-next-line no-prototype-builtins
|
|
@@ -744,50 +742,49 @@ function bindFunctionToRawWindow(rawWindow, value) {
|
|
|
744
742
|
return value;
|
|
745
743
|
}
|
|
746
744
|
|
|
747
|
-
/* eslint-disable no-param-reassign */
|
|
748
745
|
// rewrite document and body event listener
|
|
749
746
|
function rewriteDocumentAndBodyEvent() {
|
|
750
747
|
const { addEventListener, removeEventListener } = window.document;
|
|
751
748
|
const { addEventListener: bodyAddEventListener, removeEventListener: bodyRemoveEventListener } = window.document.body;
|
|
749
|
+
const documentListenerMap = new Map();
|
|
752
750
|
document.addEventListener = function (type, listener, options) {
|
|
753
751
|
const app = getCurrentRunningApp();
|
|
754
|
-
if (app) {
|
|
755
|
-
const
|
|
756
|
-
|
|
757
|
-
const appListenerList = appListenersMap.get(type);
|
|
758
|
-
if (appListenerList) {
|
|
759
|
-
appListenerList.add(listener);
|
|
760
|
-
}
|
|
761
|
-
else {
|
|
762
|
-
appListenersMap.set(type, new Set([listener]));
|
|
763
|
-
}
|
|
764
|
-
}
|
|
765
|
-
else {
|
|
766
|
-
documentEventListenerMap.set(app.appCacheKey, new Map([[type, new Set([listener])]]));
|
|
767
|
-
}
|
|
752
|
+
if (app?.keepAlive) {
|
|
753
|
+
const listeners = documentListenerMap.get(type) || [];
|
|
754
|
+
documentListenerMap.set(type, [...listeners, listener]);
|
|
768
755
|
}
|
|
769
|
-
addEventListener.call(app?.container instanceof ShadowRoot
|
|
756
|
+
addEventListener.call(app?.container instanceof ShadowRoot
|
|
757
|
+
? app.container
|
|
758
|
+
: this, type, listener, options);
|
|
770
759
|
};
|
|
771
760
|
document.body.addEventListener = document.addEventListener;
|
|
772
761
|
document.removeEventListener = function (type, listener, options) {
|
|
773
762
|
const app = getCurrentRunningApp();
|
|
774
|
-
if (app) {
|
|
775
|
-
const
|
|
776
|
-
if (
|
|
777
|
-
|
|
778
|
-
if (appListenerList?.size && appListenerList.has(listener)) {
|
|
779
|
-
appListenerList.delete(listener);
|
|
780
|
-
}
|
|
763
|
+
if (app?.keepAlive) {
|
|
764
|
+
const listeners = documentListenerMap.get(type) || [];
|
|
765
|
+
if (listeners.length && listeners.some(l => l === listener)) {
|
|
766
|
+
listeners.splice(listeners.indexOf(listener), 1);
|
|
781
767
|
}
|
|
782
768
|
}
|
|
783
|
-
removeEventListener.call(app?.container instanceof ShadowRoot
|
|
769
|
+
removeEventListener.call(app?.container instanceof ShadowRoot
|
|
770
|
+
? app.container
|
|
771
|
+
: this, type, listener, options);
|
|
784
772
|
};
|
|
785
773
|
document.body.removeEventListener = document.removeEventListener;
|
|
786
774
|
function resetDocumentAndBodyEvent() {
|
|
775
|
+
const app = getCurrentRunningApp();
|
|
776
|
+
if (app?.keepAlive && documentListenerMap.values()) {
|
|
777
|
+
Array.from(documentListenerMap.entries()).forEach(([type, listeners]) => {
|
|
778
|
+
listeners?.forEach((listener) => {
|
|
779
|
+
document.removeEventListener.call(document, type, listener);
|
|
780
|
+
});
|
|
781
|
+
});
|
|
782
|
+
}
|
|
787
783
|
document.addEventListener = addEventListener;
|
|
788
784
|
document.body.addEventListener = bodyAddEventListener;
|
|
789
785
|
document.removeEventListener = removeEventListener;
|
|
790
786
|
document.body.removeEventListener = bodyRemoveEventListener;
|
|
787
|
+
documentListenerMap.clear();
|
|
791
788
|
}
|
|
792
789
|
return {
|
|
793
790
|
resetDocumentAndBodyEvent,
|
|
@@ -795,85 +792,45 @@ function rewriteDocumentAndBodyEvent() {
|
|
|
795
792
|
}
|
|
796
793
|
// rewrite window funtion like settimeout setinterval ...
|
|
797
794
|
function rewriteWindowFunction(fakeWindow) {
|
|
798
|
-
const app = getCurrentRunningApp();
|
|
799
795
|
const eventListenerMap = new Map();
|
|
800
|
-
const
|
|
801
|
-
const timeoutIdMap = new Map();
|
|
796
|
+
const intervalIdList = [];
|
|
802
797
|
const rawWindow = window;
|
|
803
|
-
const
|
|
804
|
-
const { addEventListener, removeEventListener, setInterval, setTimeout, clearInterval, clearTimeout } = window;
|
|
805
|
-
const { removeEventListener: documentRemoveEventListener } = window.document;
|
|
806
|
-
// listener may be null, e.g test-passive
|
|
798
|
+
const { addEventListener, removeEventListener, setInterval, clearInterval } = window;
|
|
807
799
|
fakeWindow.addEventListener = function (type, listener, options) {
|
|
808
|
-
|
|
809
|
-
if (listenerList) {
|
|
810
|
-
listenerList.add(listener);
|
|
811
|
-
}
|
|
812
|
-
else {
|
|
813
|
-
eventListenerMap.set(type, new Set([listener]));
|
|
814
|
-
}
|
|
800
|
+
eventListenerMap.set(type, [...(eventListenerMap.get(type) || []), listener]);
|
|
815
801
|
addEventListener.call(rawWindow, type, listener, options);
|
|
816
802
|
};
|
|
817
803
|
fakeWindow.removeEventListener = function (type, listener, options) {
|
|
818
804
|
const listenerList = eventListenerMap.get(type);
|
|
819
|
-
if (listenerList?.
|
|
820
|
-
listenerList.
|
|
805
|
+
if (listenerList?.length && listenerList.indexOf(listener)) {
|
|
806
|
+
listenerList.splice(listenerList.indexOf(listener), 1);
|
|
821
807
|
}
|
|
822
808
|
removeEventListener.call(rawWindow, type, listener, options);
|
|
823
809
|
};
|
|
824
810
|
fakeWindow.setInterval = function (handler, timeout, ...args) {
|
|
825
811
|
const intervalId = setInterval.call(rawWindow, handler, timeout, ...args);
|
|
826
|
-
|
|
812
|
+
intervalIdList.push(intervalId);
|
|
827
813
|
return intervalId;
|
|
828
814
|
};
|
|
829
|
-
fakeWindow.setTimeout = function (handler, timeout, ...args) {
|
|
830
|
-
const timeoutId = setTimeout.call(rawWindow, handler, timeout, ...args);
|
|
831
|
-
timeoutIdMap.set(timeoutId, { handler, timeout, args });
|
|
832
|
-
return timeoutId;
|
|
833
|
-
};
|
|
834
815
|
fakeWindow.clearInterval = function (intervalId) {
|
|
835
|
-
|
|
816
|
+
const index = intervalIdList.indexOf(intervalId);
|
|
817
|
+
index > -1 && intervalIdList.splice(intervalIdList.indexOf(intervalId), 1);
|
|
836
818
|
clearInterval.call(rawWindow, intervalId);
|
|
837
819
|
};
|
|
838
|
-
fakeWindow.clearTimeout = function (timeoutId) {
|
|
839
|
-
timeoutIdMap.delete(timeoutId);
|
|
840
|
-
clearTimeout.call(rawWindow, timeoutId);
|
|
841
|
-
};
|
|
842
820
|
// reset all event listener & interval & timeout when unmount app
|
|
843
821
|
const resetWindowFunction = () => {
|
|
844
822
|
// clear window events listener
|
|
845
823
|
if (eventListenerMap.size) {
|
|
846
824
|
eventListenerMap.forEach((listenerList, type) => {
|
|
847
|
-
|
|
848
|
-
removeEventListener.call(rawWindow, type, listener);
|
|
849
|
-
}
|
|
825
|
+
listenerList.forEach(listener => removeEventListener.call(rawWindow, type, listener));
|
|
850
826
|
});
|
|
851
827
|
eventListenerMap.clear();
|
|
852
828
|
}
|
|
853
829
|
// clear settimeout timers
|
|
854
|
-
if (
|
|
855
|
-
|
|
830
|
+
if (intervalIdList.length) {
|
|
831
|
+
intervalIdList.forEach((intervalId) => {
|
|
856
832
|
clearInterval.call(rawWindow, intervalId);
|
|
857
833
|
});
|
|
858
|
-
intervalIdMap.clear();
|
|
859
|
-
}
|
|
860
|
-
if (timeoutIdMap.size) {
|
|
861
|
-
timeoutIdMap.forEach((_, timeoutId) => {
|
|
862
|
-
clearTimeout.call(rawWindow, timeoutId);
|
|
863
|
-
});
|
|
864
|
-
timeoutIdMap.clear();
|
|
865
|
-
}
|
|
866
|
-
if (app) {
|
|
867
|
-
documentClickListMap.delete(app.appCacheKey);
|
|
868
|
-
const documentAppListenersMap = documentEventListenerMap.get(app.appCacheKey);
|
|
869
|
-
if (documentAppListenersMap) {
|
|
870
|
-
documentAppListenersMap.forEach((listenerList, type) => {
|
|
871
|
-
for (const listener of listenerList) {
|
|
872
|
-
documentRemoveEventListener.call(rawDocument, type, listener);
|
|
873
|
-
}
|
|
874
|
-
});
|
|
875
|
-
documentAppListenersMap.clear();
|
|
876
|
-
}
|
|
877
834
|
}
|
|
878
835
|
};
|
|
879
836
|
return {
|
|
@@ -1005,8 +962,8 @@ class SandBox {
|
|
|
1005
962
|
return Reflect.defineProperty(target, key, value);
|
|
1006
963
|
},
|
|
1007
964
|
// Object.getOwnPropertyNames(window)
|
|
1008
|
-
ownKeys: (target) =>
|
|
1009
|
-
.concat(Reflect.ownKeys(target))),
|
|
965
|
+
ownKeys: (target) => Array.from(new Set(Reflect.ownKeys(rawWindow)
|
|
966
|
+
.concat(Reflect.ownKeys(target)))),
|
|
1010
967
|
deleteProperty: (target, key) => {
|
|
1011
968
|
if (target.hasOwnProperty(key)) {
|
|
1012
969
|
this.injectedKeySet.has(key) && this.injectedKeySet.delete(key);
|
|
@@ -1386,6 +1343,10 @@ class IframeApp {
|
|
|
1386
1343
|
}
|
|
1387
1344
|
// todo set some global start props
|
|
1388
1345
|
start(option) {
|
|
1346
|
+
// 是否收集主应用资源
|
|
1347
|
+
if (option?.collectBaseSource) {
|
|
1348
|
+
collectBaseSource();
|
|
1349
|
+
}
|
|
1389
1350
|
if (typeof option?.fetchSource === 'function') {
|
|
1390
1351
|
this.fetchSource = option.fetchSource;
|
|
1391
1352
|
}
|
|
@@ -1433,6 +1394,9 @@ class Script {
|
|
|
1433
1394
|
this.fromHtml = fromHtml ?? false;
|
|
1434
1395
|
this.initial = initial ?? false;
|
|
1435
1396
|
}
|
|
1397
|
+
setCode(code) {
|
|
1398
|
+
this.code = code;
|
|
1399
|
+
}
|
|
1436
1400
|
async getCode(app) {
|
|
1437
1401
|
if (this.code.length || !this.url) {
|
|
1438
1402
|
return this.code;
|
|
@@ -1458,12 +1422,15 @@ class Script {
|
|
|
1458
1422
|
if (!this.code)
|
|
1459
1423
|
await this.getCode(app);
|
|
1460
1424
|
if (app instanceof MicroInstanceModel) {
|
|
1461
|
-
|
|
1425
|
+
const golbalWindow = app.scopeJs ? app.sandBox?.proxyWindow || window : window;
|
|
1426
|
+
noteGlobalProps(golbalWindow);
|
|
1462
1427
|
}
|
|
1463
1428
|
let scopedCode = this.code;
|
|
1464
1429
|
scopedCode = this.transformCode(app);
|
|
1465
1430
|
if (app.showSourceCode || this.isModule) {
|
|
1466
|
-
const scriptElement = createElement
|
|
1431
|
+
const scriptElement = document.createElement('script');
|
|
1432
|
+
if (scriptElement.__BK_WEWEB_APP_KEY__)
|
|
1433
|
+
delete scriptElement.__BK_WEWEB_APP_KEY__;
|
|
1467
1434
|
app.registerRunningApp();
|
|
1468
1435
|
this.executeSourceScript(scriptElement, scopedCode);
|
|
1469
1436
|
if (needRelaceScriptElement)
|
|
@@ -1479,8 +1446,15 @@ class Script {
|
|
|
1479
1446
|
return document.createComment('【bk-weweb】dynamic script');
|
|
1480
1447
|
}
|
|
1481
1448
|
if (app instanceof MicroInstanceModel) {
|
|
1482
|
-
const
|
|
1483
|
-
exportProp
|
|
1449
|
+
const golbalWindow = app.scopeJs ? app.sandBox?.proxyWindow || window : window;
|
|
1450
|
+
const exportProp = getGlobalProp(golbalWindow);
|
|
1451
|
+
if (exportProp) {
|
|
1452
|
+
this.exportInstance = (golbalWindow)[exportProp];
|
|
1453
|
+
// window 下需清除全局副作用
|
|
1454
|
+
if (!app.scopeJs) {
|
|
1455
|
+
delete (golbalWindow)[exportProp];
|
|
1456
|
+
}
|
|
1457
|
+
}
|
|
1484
1458
|
}
|
|
1485
1459
|
}
|
|
1486
1460
|
catch (e) {
|
|
@@ -1538,7 +1512,8 @@ class Script {
|
|
|
1538
1512
|
function shouldSkipProperty(global, p) {
|
|
1539
1513
|
return (!global.hasOwnProperty(p)
|
|
1540
1514
|
|| (!isNaN(p) && p < global.length)
|
|
1541
|
-
|| (
|
|
1515
|
+
|| (typeof navigator !== 'undefined' && navigator.userAgent.indexOf('Trident') !== -1
|
|
1516
|
+
&& global[p] && typeof window !== 'undefined' && global[p].parent === window));
|
|
1542
1517
|
}
|
|
1543
1518
|
// 获取instance js source code 执行后 绑定的export 实例
|
|
1544
1519
|
function getGlobalProp(global, useFirstGlobalProp) {
|
|
@@ -1792,7 +1767,9 @@ class EntrySource {
|
|
|
1792
1767
|
}
|
|
1793
1768
|
}
|
|
1794
1769
|
this.rawHtml = htmlStr;
|
|
1795
|
-
const wrapElement = createElement
|
|
1770
|
+
const wrapElement = document.createElement('div');
|
|
1771
|
+
if (wrapElement.__BK_WEWEB_APP_KEY__)
|
|
1772
|
+
delete wrapElement.__BK_WEWEB_APP_KEY__;
|
|
1796
1773
|
wrapElement.innerHTML = htmlStr.replace(/<\/?head>/gim, '').replace(/<\/?body>/i, '');
|
|
1797
1774
|
this.collectScriptAndStyle(wrapElement, app);
|
|
1798
1775
|
await excuteAppStyles(app, wrapElement);
|
|
@@ -1936,7 +1913,7 @@ class EntrySource {
|
|
|
1936
1913
|
return { replace: script };
|
|
1937
1914
|
}
|
|
1938
1915
|
setScript(url, script) {
|
|
1939
|
-
this.scripts.set(url, new Script(script));
|
|
1916
|
+
this.scripts.set(url, script instanceof Script ? script : new Script(script));
|
|
1940
1917
|
}
|
|
1941
1918
|
getScript(url) {
|
|
1942
1919
|
return this.scripts.get(url);
|
|
@@ -1944,8 +1921,8 @@ class EntrySource {
|
|
|
1944
1921
|
setStyle(url, style) {
|
|
1945
1922
|
this.styles.set(url, style);
|
|
1946
1923
|
}
|
|
1947
|
-
getStyle(
|
|
1948
|
-
return this.styles.get(
|
|
1924
|
+
getStyle(urlOrCode) {
|
|
1925
|
+
return this.styles.get(urlOrCode) || Array.from(this.styles.values()).find(style => style.code === urlOrCode);
|
|
1949
1926
|
}
|
|
1950
1927
|
}
|
|
1951
1928
|
|
|
@@ -2008,6 +1985,9 @@ class AppCache {
|
|
|
2008
1985
|
setBaseAppStyle(url, style) {
|
|
2009
1986
|
this.baseSource.setStyle(url, style);
|
|
2010
1987
|
}
|
|
1988
|
+
getBaseAppStyle(urlOrCode) {
|
|
1989
|
+
return this.baseSource.getStyle(urlOrCode);
|
|
1990
|
+
}
|
|
2011
1991
|
setBaseAppScript(url, script) {
|
|
2012
1992
|
this.baseSource.setScript(url, script);
|
|
2013
1993
|
}
|
|
@@ -2021,7 +2001,8 @@ window.__getAppOrInstance__ = function (id) {
|
|
|
2021
2001
|
};
|
|
2022
2002
|
|
|
2023
2003
|
function getStyleSource(url, style, originLink) {
|
|
2024
|
-
const replaceStyle = createElement
|
|
2004
|
+
const replaceStyle = document.createElement('style');
|
|
2005
|
+
setMarkElement(replaceStyle);
|
|
2025
2006
|
fetchSource(url)
|
|
2026
2007
|
.then((data) => {
|
|
2027
2008
|
style.code = data;
|
|
@@ -2036,12 +2017,13 @@ function getStyleSource(url, style, originLink) {
|
|
|
2036
2017
|
return replaceStyle;
|
|
2037
2018
|
}
|
|
2038
2019
|
function getScriptSource(url, script, originScript) {
|
|
2039
|
-
const
|
|
2020
|
+
const replaceScript = document.createElement('script');
|
|
2021
|
+
setMarkElement(replaceScript);
|
|
2040
2022
|
fetchSource(url)
|
|
2041
2023
|
.then((code) => {
|
|
2042
|
-
script.code
|
|
2024
|
+
script.setCode(code);
|
|
2043
2025
|
try {
|
|
2044
|
-
|
|
2026
|
+
replaceScript.textContent = code;
|
|
2045
2027
|
if (!url.startsWith('inline-')) {
|
|
2046
2028
|
originScript.setAttribute('origin-src', url);
|
|
2047
2029
|
}
|
|
@@ -2055,15 +2037,15 @@ function getScriptSource(url, script, originScript) {
|
|
|
2055
2037
|
console.error(err);
|
|
2056
2038
|
dispatchLinkOrScriptError(originScript);
|
|
2057
2039
|
});
|
|
2058
|
-
return
|
|
2040
|
+
return replaceScript;
|
|
2059
2041
|
}
|
|
2060
|
-
function
|
|
2042
|
+
function createNewNode(child) {
|
|
2061
2043
|
if (child instanceof HTMLLinkElement) {
|
|
2062
2044
|
const rel = child.getAttribute('rel');
|
|
2063
2045
|
let href = child.getAttribute('href');
|
|
2064
2046
|
if (rel === 'stylesheet' && href) {
|
|
2065
|
-
href = fillUpPath(href, location.
|
|
2066
|
-
const replaceStyle = createElement
|
|
2047
|
+
href = fillUpPath(href, location.origin);
|
|
2048
|
+
const replaceStyle = document.createElement('style');
|
|
2067
2049
|
const styleInstance = new Style({
|
|
2068
2050
|
code: '',
|
|
2069
2051
|
url: href,
|
|
@@ -2076,7 +2058,7 @@ function rewriteNewNode(child) {
|
|
|
2076
2058
|
if (child instanceof HTMLScriptElement) {
|
|
2077
2059
|
let src = child.getAttribute('src');
|
|
2078
2060
|
if (src && child.type !== 'module') {
|
|
2079
|
-
src = fillUpPath(src, location.
|
|
2061
|
+
src = fillUpPath(src, location.origin);
|
|
2080
2062
|
const script = new Script({
|
|
2081
2063
|
code: '',
|
|
2082
2064
|
async: child.hasAttribute('async'),
|
|
@@ -2091,26 +2073,48 @@ function rewriteNewNode(child) {
|
|
|
2091
2073
|
}
|
|
2092
2074
|
return child;
|
|
2093
2075
|
}
|
|
2094
|
-
function
|
|
2095
|
-
|
|
2096
|
-
|
|
2076
|
+
function isLinkOrScript(node) {
|
|
2077
|
+
return node instanceof HTMLLinkElement || node instanceof HTMLScriptElement;
|
|
2078
|
+
}
|
|
2079
|
+
function baseElementInertHandle(parent, newChild, passiveChild, rawMethod) {
|
|
2080
|
+
if (isLinkOrScript(newChild)) {
|
|
2081
|
+
const targetChild = createNewNode(newChild);
|
|
2097
2082
|
return rawMethod.call(parent, targetChild, passiveChild);
|
|
2098
2083
|
}
|
|
2099
2084
|
return rawMethod.call(parent, newChild, passiveChild);
|
|
2100
2085
|
}
|
|
2086
|
+
function baseElementAppendHandle(parent, newChild, rawMethod) {
|
|
2087
|
+
if (isLinkOrScript(newChild)) {
|
|
2088
|
+
const targetChild = createNewNode(newChild);
|
|
2089
|
+
return rawMethod.call(parent, targetChild);
|
|
2090
|
+
}
|
|
2091
|
+
return rawMethod.call(parent, newChild);
|
|
2092
|
+
}
|
|
2101
2093
|
|
|
2102
|
-
|
|
2094
|
+
function collectBaseSource() {
|
|
2103
2095
|
const rawBodyAppendChild = HTMLBodyElement.prototype.appendChild;
|
|
2104
2096
|
const rawHeadAppendChild = HTMLHeadElement.prototype.appendChild;
|
|
2105
2097
|
const rawHeadInsertBefore = HTMLHeadElement.prototype.appendChild;
|
|
2106
2098
|
HTMLBodyElement.prototype.appendChild = function (newChild) {
|
|
2107
|
-
return
|
|
2099
|
+
return baseElementAppendHandle(this, newChild, rawBodyAppendChild);
|
|
2108
2100
|
};
|
|
2109
2101
|
HTMLHeadElement.prototype.appendChild = function (newChild) {
|
|
2110
|
-
return
|
|
2102
|
+
return baseElementAppendHandle(this, newChild, rawHeadAppendChild);
|
|
2111
2103
|
};
|
|
2112
2104
|
HTMLHeadElement.prototype.insertBefore = function (newChild, refChild) {
|
|
2113
|
-
return
|
|
2105
|
+
return baseElementInertHandle(this, newChild, refChild, rawHeadInsertBefore);
|
|
2114
2106
|
};
|
|
2115
|
-
|
|
2107
|
+
window.addEventListener('load', () => {
|
|
2108
|
+
const nodeList = document.head.querySelectorAll('style');
|
|
2109
|
+
nodeList.forEach((node) => {
|
|
2110
|
+
node.textContent && appCache.setBaseAppStyle(randomUrl(), new Style({
|
|
2111
|
+
code: node.textContent,
|
|
2112
|
+
url: '',
|
|
2113
|
+
fromHtml: false,
|
|
2114
|
+
}));
|
|
2115
|
+
});
|
|
2116
|
+
});
|
|
2117
|
+
}
|
|
2118
|
+
|
|
2119
|
+
export { collectBaseSource };
|
|
2116
2120
|
//# sourceMappingURL=collect-source.js.map
|