@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.
@@ -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 || isBodyElement(selectors) || document$1 !== this) {
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 || isBodyElement(selectors) || document$1 !== this) {
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
- || isBodyElement(key)
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 eventHandler(event, element) {
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
- eventHandler(event, element);
288
- if (isFunction(element.onload)) {
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
- eventHandler(event, element);
298
- if (isFunction(element.onerror)) {
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 = createElement$1('style');
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.commonScoped(styleElement, styleElement, app);
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 = createElement$1('style');
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 (isSafari()) {
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
- baseURI = getFileDir(linkpath);
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?.prepend(...styleElementList);
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 (isFunction(value) && !isConstructor(value)) {
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 appListenersMap = documentEventListenerMap.get(app.appCacheKey);
756
- if (appListenersMap) {
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 ? app.container : this, type, listener, options);
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 appListenersMap = documentEventListenerMap.get(app.appCacheKey);
776
- if (appListenersMap) {
777
- const appListenerList = appListenersMap.get(type);
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 ? app.container : this, type, listener, options);
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 intervalIdMap = new Map();
801
- const timeoutIdMap = new Map();
796
+ const intervalIdList = [];
802
797
  const rawWindow = window;
803
- const rawDocument = window.document;
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
- const listenerList = eventListenerMap.get(type);
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?.size && listenerList.has(listener)) {
820
- listenerList.delete(listener);
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
- intervalIdMap.set(intervalId, { handler, timeout, args });
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
- intervalIdMap.delete(intervalId);
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
- for (const listener of listenerList) {
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 (intervalIdMap.size) {
855
- intervalIdMap.forEach((_, intervalId) => {
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) => arrayUnique(Reflect.ownKeys(rawWindow)
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
- noteGlobalProps(app.sandBox?.proxyWindow || window);
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$1('script');
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 exportProp = getGlobalProp(app.sandBox?.proxyWindow || window);
1483
- exportProp && (this.exportInstance = (app.sandBox?.proxyWindow || window)[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
- || (isIE11 && global[p] && typeof window !== 'undefined' && global[p].parent === window));
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$1('div');
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(url) {
1948
- return this.styles.get(url);
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$1('style');
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 replaceElement = createElement$1('script');
2020
+ const replaceScript = document.createElement('script');
2021
+ setMarkElement(replaceScript);
2040
2022
  fetchSource(url)
2041
2023
  .then((code) => {
2042
- script.code = code;
2024
+ script.setCode(code);
2043
2025
  try {
2044
- replaceElement.textContent = code;
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 replaceElement;
2040
+ return replaceScript;
2059
2041
  }
2060
- function rewriteNewNode(child) {
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.href);
2066
- const replaceStyle = createElement$1('style');
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.href);
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 baseElementHandle(parent, newChild, passiveChild, rawMethod, baseSource) {
2095
- if (baseSource) {
2096
- const targetChild = rewriteNewNode(newChild);
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
- (function () {
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 baseElementHandle(this, newChild, null, rawBodyAppendChild, true);
2099
+ return baseElementAppendHandle(this, newChild, rawBodyAppendChild);
2108
2100
  };
2109
2101
  HTMLHeadElement.prototype.appendChild = function (newChild) {
2110
- return baseElementHandle(this, newChild, null, rawHeadAppendChild, true);
2102
+ return baseElementAppendHandle(this, newChild, rawHeadAppendChild);
2111
2103
  };
2112
2104
  HTMLHeadElement.prototype.insertBefore = function (newChild, refChild) {
2113
- return baseElementHandle(this, newChild, refChild, rawHeadInsertBefore, true);
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