@blueking/bk-weweb 0.0.35-beta.1 → 0.0.35-beta.2

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/index.esm.js CHANGED
@@ -119,10 +119,11 @@ var WewebMode = /* @__PURE__ */ ((WewebMode2) => {
119
119
  // src/typings/sandbox.ts
120
120
  var WINDOW_WHITE_LIST = [
121
121
  "System",
122
- // SystemJS
122
+ // SystemJS 模块加载器
123
123
  "__cjsWrapper",
124
- // SystemJS CommonJS wrapper
125
- false ? "__REACT_DEVTOOLS_GLOBAL_HOOK__" : ""
124
+ // SystemJS CommonJS 包装器
125
+ // 开发环境下允许 React DevTools
126
+ ...false ? ["__REACT_DEVTOOLS_GLOBAL_HOOK__"] : []
126
127
  ];
127
128
  var BK_WEWEB_INJECT_KEY_LIST = [
128
129
  "__POWERED_BY_BK_WEWEB__",
@@ -137,18 +138,25 @@ var COMMON_MICRO_APP_WINDOW_KEY_MAP = {
137
138
  i18n: true
138
139
  };
139
140
  var DEV_MICRO_APP_WINDOW_KEY_MAP = false ? {
141
+ // 开发环境标识
140
142
  __DEV__: true,
143
+ // Vue DevTools 相关
141
144
  __VUE_DEVTOOLS_GLOBAL_HOOK__: true,
142
145
  __VUE_DEVTOOLS_HOOK_REPLAY__: true,
143
146
  __VUE_DEVTOOLS_PLUGINS__: true,
147
+ // Vue I18n 相关
144
148
  __VUE_I18N_FULL_INSTALL__: true,
145
149
  __VUE_I18N_LEGACY_API__: true,
150
+ // Vue 配置相关
146
151
  __VUE_OPTIONS_API__: true,
152
+ // Core-js 相关
147
153
  "__core-js_shared__": true,
154
+ // Webpack 相关
148
155
  webpackChunkapm: true,
149
156
  webpackChunkpc: true,
150
157
  webpackChunktrace: true,
151
158
  webpackJsonp: true,
159
+ // 包含通用配置
152
160
  ...COMMON_MICRO_APP_WINDOW_KEY_MAP
153
161
  } : COMMON_MICRO_APP_WINDOW_KEY_MAP;
154
162
 
@@ -198,10 +206,10 @@ var isJsonpUrl = (url) => {
198
206
  };
199
207
 
200
208
  // src/context/document.ts
201
- var SPECIAL_ELEMENT_TAG = ["body", "html", "head"];
202
- var createProxyDocument = (rawDocument, app) => {
203
- const fakeDocument = {};
204
- function shadowRootInsertAdjacentHTML(where, domString) {
209
+ var SPECIAL_ELEMENT_TAGS = ["body", "html", "head"];
210
+ var APP_KEY_PROPERTY = "__BK_WEWEB_APP_KEY__";
211
+ function createShadowRootInsertAdjacentHTML(app) {
212
+ return function shadowRootInsertAdjacentHTML(where, domString) {
205
213
  const temporaryContainer = document.createElement("div");
206
214
  temporaryContainer.innerHTML = domString;
207
215
  const elements = Array.from(temporaryContainer.childNodes);
@@ -228,16 +236,18 @@ var createProxyDocument = (rawDocument, app) => {
228
236
  }
229
237
  break;
230
238
  }
231
- }
232
- const proxyBody = new Proxy(
239
+ };
240
+ }
241
+ function createProxyBody(rawDocument, app) {
242
+ return new Proxy(
233
243
  {},
234
244
  {
235
245
  get(_, key) {
236
246
  if (app.container instanceof ShadowRoot) {
237
247
  if (key === "insertAdjacentHTML") {
238
- return shadowRootInsertAdjacentHTML.bind(app.container);
248
+ return createShadowRootInsertAdjacentHTML(app);
239
249
  }
240
- const value2 = app.container[key];
250
+ const value2 = Reflect.get(app.container, key);
241
251
  if (typeof value2 === "function") {
242
252
  return value2.bind(app.container);
243
253
  }
@@ -250,7 +260,7 @@ var createProxyDocument = (rawDocument, app) => {
250
260
  },
251
261
  set(_, key, value) {
252
262
  if (app.container instanceof ShadowRoot) {
253
- app.container[key] = value;
263
+ Reflect.set(app.container, key, value);
254
264
  return true;
255
265
  }
256
266
  Reflect.set(rawDocument.body, key, value);
@@ -258,60 +268,102 @@ var createProxyDocument = (rawDocument, app) => {
258
268
  }
259
269
  }
260
270
  );
261
- function createElement(tagName, options) {
271
+ }
272
+ function createElementWithAppKey(rawDocument, app) {
273
+ return function createElement(tagName, options) {
262
274
  const element = rawDocument.createElement(tagName, options);
263
- element.__BK_WEWEB_APP_KEY__ = app.appCacheKey;
275
+ element[APP_KEY_PROPERTY] = app.appCacheKey;
264
276
  return element;
277
+ };
278
+ }
279
+ function isSpecialElementTag(selector) {
280
+ return SPECIAL_ELEMENT_TAGS.includes(selector);
281
+ }
282
+ function safeQuerySelector(container, selector) {
283
+ try {
284
+ return container?.querySelector(selector) ?? null;
285
+ } catch {
286
+ return null;
287
+ }
288
+ }
289
+ function safeQuerySelectorAll(container, selector) {
290
+ try {
291
+ return container?.querySelectorAll(selector) ?? [];
292
+ } catch {
293
+ return [];
265
294
  }
266
- function querySelectorNew(selectors) {
295
+ }
296
+ function createProxyQuerySelector(rawDocument, app, proxyBody) {
297
+ return function querySelectorNew(selectors) {
267
298
  if (selectors === proxyBody) {
268
299
  return app.container instanceof ShadowRoot ? app.container : rawDocument.body;
269
300
  }
270
- if (SPECIAL_ELEMENT_TAG.includes(selectors)) {
301
+ if (isSpecialElementTag(selectors)) {
271
302
  if (app?.container instanceof ShadowRoot) {
272
303
  return app?.container;
273
304
  }
274
305
  return rawDocument.querySelector.call(this, selectors);
275
306
  }
276
- try {
277
- return app?.container?.querySelector(selectors) ?? null;
278
- } catch {
279
- return null;
280
- }
281
- }
282
- function querySelectorAllNew(selectors) {
283
- if (SPECIAL_ELEMENT_TAG.includes(selectors)) {
307
+ return safeQuerySelector(app?.container, selectors);
308
+ };
309
+ }
310
+ function createProxyQuerySelectorAll(rawDocument, app) {
311
+ return function querySelectorAllNew(selectors) {
312
+ if (isSpecialElementTag(selectors)) {
284
313
  if (app?.container instanceof ShadowRoot) {
285
- return app?.container;
314
+ return [app?.container];
286
315
  }
287
- return rawDocument.querySelector(selectors);
316
+ const result = rawDocument.querySelector(selectors);
317
+ return result ? [result] : [];
288
318
  }
289
- return app?.container?.querySelectorAll(selectors) ?? [];
290
- }
291
- function getElementByIdNew(key) {
292
- return querySelectorNew.call(rawDocument, `#${key}`);
293
- }
294
- function getElementsByClassName(key) {
295
- return querySelectorAllNew(`.${key}`);
296
- }
297
- function getElementsByTagName(key) {
298
- if (SPECIAL_ELEMENT_TAG.includes(key) || !app?.showSourceCode && key.toLocaleLowerCase() === "script") {
299
- return rawDocument.getElementsByTagName(key);
319
+ return safeQuerySelectorAll(app?.container, selectors);
320
+ };
321
+ }
322
+ function createProxyGetElementById(rawDocument, querySelector) {
323
+ return function getElementByIdNew(id) {
324
+ return querySelector.call(rawDocument, `#${id}`);
325
+ };
326
+ }
327
+ function createProxyGetElementsByClassName(querySelectorAll) {
328
+ return function getElementsByClassName(className) {
329
+ return querySelectorAll(`.${className}`);
330
+ };
331
+ }
332
+ function createProxyGetElementsByTagName(rawDocument, app, querySelectorAll) {
333
+ return function getElementsByTagName(tagName) {
334
+ if (isSpecialElementTag(tagName) || !app?.showSourceCode && tagName.toLowerCase() === "script") {
335
+ return rawDocument.getElementsByTagName(tagName);
300
336
  }
301
- return querySelectorAllNew(key);
302
- }
303
- function getElementsByNameNew(key) {
304
- return querySelectorAllNew(`[name=${key}]`);
305
- }
306
- const methodMap = {
337
+ return querySelectorAll(tagName);
338
+ };
339
+ }
340
+ function createProxyGetElementsByName(querySelectorAll) {
341
+ return function getElementsByNameNew(name) {
342
+ return querySelectorAll(`[name="${name}"]`);
343
+ };
344
+ }
345
+ function createProxyMethodMap(rawDocument, app, proxyBody) {
346
+ const createElement = createElementWithAppKey(rawDocument, app);
347
+ const querySelector = createProxyQuerySelector(rawDocument, app, proxyBody);
348
+ const querySelectorAll = createProxyQuerySelectorAll(rawDocument, app);
349
+ const getElementById = createProxyGetElementById(rawDocument, querySelector);
350
+ const getElementsByClassName = createProxyGetElementsByClassName(querySelectorAll);
351
+ const getElementsByTagName = createProxyGetElementsByTagName(rawDocument, app, querySelectorAll);
352
+ const getElementsByName = createProxyGetElementsByName(querySelectorAll);
353
+ return {
307
354
  createElement: createElement.bind(rawDocument),
308
- querySelector: querySelectorNew.bind(rawDocument),
309
- querySelectorAll: querySelectorAllNew.bind(rawDocument),
310
- getElementById: getElementByIdNew.bind(rawDocument),
355
+ querySelector: querySelector.bind(rawDocument),
356
+ querySelectorAll: querySelectorAll.bind(rawDocument),
357
+ getElementById: getElementById.bind(rawDocument),
311
358
  getElementsByClassName: getElementsByClassName.bind(rawDocument),
312
359
  getElementsByTagName: getElementsByTagName.bind(rawDocument),
313
- getElementsByName: getElementsByNameNew.bind(rawDocument)
360
+ getElementsByName: getElementsByName.bind(rawDocument)
314
361
  };
362
+ }
363
+ var createProxyDocument = (rawDocument, app) => {
364
+ const fakeDocument = {};
365
+ const proxyBody = createProxyBody(rawDocument, app);
366
+ const methodMap = createProxyMethodMap(rawDocument, app, proxyBody);
315
367
  return new Proxy(fakeDocument, {
316
368
  get(_, key) {
317
369
  if (key === "body") {
@@ -473,6 +525,11 @@ function rewriteWindowFunction(fakeWindow) {
473
525
 
474
526
  // src/context/sandbox.ts
475
527
  var SandBox = class {
528
+ /**
529
+ * 构造函数
530
+ * @description 初始化沙箱环境,创建代理对象和隔离机制
531
+ * @param app - 关联的微应用实例
532
+ */
476
533
  constructor(app) {
477
534
  this.app = app;
478
535
  const windowDescriptorSet = /* @__PURE__ */ new Set();
@@ -488,63 +545,30 @@ var SandBox = class {
488
545
  this.fakeWindow = fakeWindow;
489
546
  const { resetWindowFunction } = rewriteWindowFunction(this.fakeWindow);
490
547
  this.resetWindowFunction = resetWindowFunction;
491
- this.windowSymbolKey = `__${(app.name || app.appCacheKey).replace(/(-|,|:|~|'|")/gim, "_")}_${random(
492
- 10
493
- )}__`;
548
+ const appIdentifier = (app.name || app.appCacheKey).replace(/[-,:~'"]/g, "_");
549
+ this.windowSymbolKey = `__${appIdentifier}_${random(10)}__`;
494
550
  this.proxyWindow = new Proxy(this.fakeWindow, {
495
- // 定义属性
496
551
  defineProperty: (target, key, value) => {
497
552
  if (windowDescriptorSet.has(key)) {
498
553
  return Reflect.defineProperty(rawWindow, key, value);
499
554
  }
500
555
  return Reflect.defineProperty(target, key, value);
501
556
  },
502
- // 删除属性
503
557
  deleteProperty: (target, key) => {
504
558
  if (Object.hasOwn(target, key)) {
505
- this.sameRawWindowKeySet.has(key) && this.sameRawWindowKeySet.delete(key);
506
- this.inRawWindowKeySet.has(key) && Reflect.deleteProperty(rawWindow, key);
559
+ if (this.sameRawWindowKeySet.has(key)) {
560
+ this.sameRawWindowKeySet.delete(key);
561
+ }
562
+ if (this.inRawWindowKeySet.has(key)) {
563
+ Reflect.deleteProperty(rawWindow, key);
564
+ }
507
565
  return Reflect.deleteProperty(target, key);
508
566
  }
509
567
  return true;
510
568
  },
511
- // 获取属性
512
569
  get: (target, key) => {
513
- if (key === Symbol.unscopables || windowNativeFuncMap.has(key)) return rawWindow[key];
514
- if (DEV_MICRO_APP_WINDOW_KEY_MAP[key]) return this.fakeWindow[key];
515
- if (WINDOW_ALIAS_LIST.includes(key)) return this.proxyWindow;
516
- if (key === "document") {
517
- app.registerRunningApp();
518
- return this.rawDocument;
519
- }
520
- if (key === "eval") {
521
- app.registerRunningApp();
522
- return eval;
523
- }
524
- if (BK_WEWEB_LOCATION_KEY_LIST.includes(key) && this.app instanceof MicroAppModel && this.app.iframe && this.app.scopeLocation) {
525
- return this.app.iframe.contentWindow?.[key];
526
- }
527
- if (key === "hasOwnProperty")
528
- return (key2) => Object.hasOwn(this.fakeWindow, key2) || Object.hasOwn(rawWindow, key2);
529
- if (key === "top" || key === "parent") {
530
- if (rawWindow === rawWindow.parent) {
531
- return this.proxyWindow;
532
- }
533
- return Reflect.get(rawWindow, key);
534
- }
535
- if (key === "getComputedStyle") {
536
- return (element, pseudoElt) => {
537
- if (element instanceof Element) {
538
- return rawWindow.getComputedStyle(element, pseudoElt);
539
- }
540
- return rawWindow.getComputedStyle(document.body, pseudoElt);
541
- };
542
- }
543
- if (Reflect.has(target, key) || BK_WEWEB_INJECT_KEY_LIST.includes(key)) return Reflect.get(target, key);
544
- const rawValue = Reflect.get(rawWindow, key);
545
- return bindFunctionToRawWindow(rawWindow, rawValue);
570
+ return this.handleProxyGet(target, key, rawWindow);
546
571
  },
547
- // 获取属性描述符
548
572
  getOwnPropertyDescriptor: (target, key) => {
549
573
  if (Object.hasOwn(target, key)) {
550
574
  return Object.getOwnPropertyDescriptor(target, key);
@@ -559,69 +583,197 @@ var SandBox = class {
559
583
  }
560
584
  return void 0;
561
585
  },
562
- // 检查属性是否存在
563
586
  has: (target, key) => windowNativeFuncMap.has(key) || key in target || key in rawWindow,
564
- // 获取所有属性名
565
587
  ownKeys: (target) => Array.from(new Set(Reflect.ownKeys(rawWindow).concat(Reflect.ownKeys(target)))),
566
- // 设置属性
567
588
  set: (target, key, value) => {
568
- if (this.active) {
569
- if (BK_WEWEB_LOCATION_KEY_LIST.includes(key) && this.app instanceof MicroAppModel && this.app.iframe && this.app.scopeLocation) {
570
- return Reflect.set(this.app.iframe.contentWindow, key, value);
571
- }
572
- if (key === "location") {
573
- Reflect.set(rawWindow, key, value);
574
- } else if (!Object.hasOwn(target, key) && Object.hasOwn(rawWindow, key) && !BK_WEWEB_INJECT_KEY_LIST.includes(key)) {
575
- const descriptor = Object.getOwnPropertyDescriptor(rawWindow, key);
576
- const { configurable, enumerable, writable } = descriptor;
577
- if (writable) {
578
- Object.defineProperty(target, key, {
579
- configurable,
580
- enumerable,
581
- value,
582
- writable
583
- });
584
- this.sameRawWindowKeySet.add(key);
585
- }
586
- } else {
587
- Reflect.set(target, key, value);
588
- this.sameRawWindowKeySet.add(key);
589
- }
590
- if (WINDOW_WHITE_LIST.includes(key) && !Reflect.has(rawWindow, key) && !BK_WEWEB_INJECT_KEY_LIST.includes(key)) {
591
- Reflect.set(rawWindow, key, value);
592
- this.inRawWindowKeySet.add(key);
593
- }
594
- }
595
- return true;
589
+ return this.handleProxySet(target, key, value, rawWindow);
596
590
  }
597
591
  });
598
592
  rawWindow[this.windowSymbolKey] = this.proxyWindow;
599
593
  }
600
- // 沙箱激活状态
594
+ /** 沙箱激活状态标识 */
601
595
  active = false;
602
- // 记录在原始window上新增的属性
596
+ /** 记录在原始 window 上新增的属性键集合 */
603
597
  inRawWindowKeySet = /* @__PURE__ */ new Set();
604
- // 重置文档和body事件的函数
598
+ /** 重置文档和 body 事件的函数 */
605
599
  resetDocumentAndBodyEvent;
606
- // 重置window函数的方法
600
+ /** 重置 window 函数的方法 */
607
601
  resetWindowFunction;
608
- // 记录与原始window相同的属性
602
+ /** 记录与原始 window 相同的属性键集合 */
609
603
  sameRawWindowKeySet = /* @__PURE__ */ new Set();
610
- // 伪造的window对象
604
+ /** 伪造的 window 对象 */
611
605
  fakeWindow;
612
- // 代理的document对象
606
+ /** 代理的 document 对象 */
613
607
  proxyDocument;
614
- // 代理的window对象
608
+ /** 代理的 window 对象 */
615
609
  proxyWindow;
616
- // 原始document对象
610
+ /** 原始 document 对象 */
617
611
  rawDocument;
618
- // 原始window对象
612
+ /** 原始 window 对象 */
619
613
  rawWindow;
620
- // window上的唯一标识key
614
+ /** window 上的唯一标识键 */
621
615
  windowSymbolKey;
616
+ /**
617
+ * 处理代理对象的 get 操作
618
+ * @description 统一处理代理对象属性获取的复杂逻辑
619
+ * @param target - 目标对象
620
+ * @param key - 属性键
621
+ * @param rawWindow - 原始 window 对象
622
+ * @returns unknown - 属性值
623
+ * @private
624
+ */
625
+ handleProxyGet(target, key, rawWindow) {
626
+ if (key === Symbol.unscopables || windowNativeFuncMap.has(key)) {
627
+ return rawWindow[key];
628
+ }
629
+ if (DEV_MICRO_APP_WINDOW_KEY_MAP[key]) {
630
+ return this.fakeWindow[key];
631
+ }
632
+ if (WINDOW_ALIAS_LIST.includes(key)) {
633
+ return this.proxyWindow;
634
+ }
635
+ if (key === "document") {
636
+ this.app.registerRunningApp();
637
+ return this.rawDocument;
638
+ }
639
+ if (key === "eval") {
640
+ this.app.registerRunningApp();
641
+ return eval;
642
+ }
643
+ if (this.shouldUseIframeLocation(key)) {
644
+ if (this.app instanceof MicroAppModel && this.app.iframe?.contentWindow) {
645
+ return this.app.iframe.contentWindow[key];
646
+ }
647
+ return void 0;
648
+ }
649
+ if (key === "hasOwnProperty") {
650
+ return (checkKey) => Object.hasOwn(this.fakeWindow, checkKey) || Object.hasOwn(rawWindow, checkKey);
651
+ }
652
+ if (key === "top" || key === "parent") {
653
+ if (rawWindow === rawWindow.parent) {
654
+ return this.proxyWindow;
655
+ }
656
+ return Reflect.get(rawWindow, key);
657
+ }
658
+ if (key === "getComputedStyle") {
659
+ return this.createGetComputedStyleProxy(rawWindow);
660
+ }
661
+ if (Reflect.has(target, key) || BK_WEWEB_INJECT_KEY_LIST.includes(key)) {
662
+ return Reflect.get(target, key);
663
+ }
664
+ const rawValue = Reflect.get(rawWindow, key);
665
+ return bindFunctionToRawWindow(rawWindow, rawValue);
666
+ }
667
+ /**
668
+ * 处理代理对象的 set 操作
669
+ * @description 统一处理代理对象属性设置的复杂逻辑
670
+ * @param target - 目标对象
671
+ * @param key - 属性键
672
+ * @param value - 属性值
673
+ * @param rawWindow - 原始 window 对象
674
+ * @returns boolean - 设置是否成功
675
+ * @private
676
+ */
677
+ handleProxySet(target, key, value, rawWindow) {
678
+ if (!this.active) {
679
+ return true;
680
+ }
681
+ if (this.shouldUseIframeLocation(key)) {
682
+ const iframe = this.app instanceof MicroAppModel ? this.app.iframe : null;
683
+ return iframe?.contentWindow ? Reflect.set(iframe.contentWindow, key, value) : true;
684
+ }
685
+ if (key === "location") {
686
+ Reflect.set(rawWindow, key, value);
687
+ } else if (this.shouldSetOnTarget(target, key, rawWindow)) {
688
+ this.setPropertyOnTarget(target, key, value, rawWindow);
689
+ } else {
690
+ Reflect.set(target, key, value);
691
+ this.sameRawWindowKeySet.add(key);
692
+ }
693
+ this.handleWhiteListProperty(key, value, rawWindow);
694
+ return true;
695
+ }
696
+ /**
697
+ * 判断是否应该使用 iframe 的 location
698
+ * @description 检查是否在 iframe 模式下访问 location 相关属性
699
+ * @param key - 属性键
700
+ * @returns boolean - 是否使用 iframe location
701
+ * @private
702
+ */
703
+ shouldUseIframeLocation(key) {
704
+ return !!(BK_WEWEB_LOCATION_KEY_LIST.includes(key) && this.app instanceof MicroAppModel && this.app.iframe && this.app.scopeLocation);
705
+ }
706
+ /**
707
+ * 创建 getComputedStyle 方法的代理
708
+ * @description 为 getComputedStyle 方法创建安全的代理实现
709
+ * @param rawWindow - 原始 window 对象
710
+ * @returns Function - 代理后的 getComputedStyle 方法
711
+ * @private
712
+ */
713
+ createGetComputedStyleProxy(rawWindow) {
714
+ return (element, pseudoElt) => {
715
+ if (element instanceof Element) {
716
+ return rawWindow.getComputedStyle(element, pseudoElt);
717
+ }
718
+ return rawWindow.getComputedStyle(document.body, pseudoElt);
719
+ };
720
+ }
721
+ /**
722
+ * 判断是否应该在目标对象上设置属性
723
+ * @description 检查属性设置的逻辑条件
724
+ * @param target - 目标对象
725
+ * @param key - 属性键
726
+ * @param rawWindow - 原始 window 对象
727
+ * @returns boolean - 是否在目标对象上设置
728
+ * @private
729
+ */
730
+ shouldSetOnTarget(target, key, rawWindow) {
731
+ return !Object.hasOwn(target, key) && Object.hasOwn(rawWindow, key) && !BK_WEWEB_INJECT_KEY_LIST.includes(key);
732
+ }
733
+ /**
734
+ * 在目标对象上设置属性
735
+ * @description 安全地在目标对象上设置属性,保持描述符特性
736
+ * @param target - 目标对象
737
+ * @param key - 属性键
738
+ * @param value - 属性值
739
+ * @param rawWindow - 原始 window 对象
740
+ * @private
741
+ */
742
+ setPropertyOnTarget(target, key, value, rawWindow) {
743
+ const descriptor = Object.getOwnPropertyDescriptor(rawWindow, key);
744
+ if (!descriptor) {
745
+ return;
746
+ }
747
+ const { configurable, enumerable, writable } = descriptor;
748
+ if (writable) {
749
+ Object.defineProperty(target, key, {
750
+ configurable,
751
+ enumerable,
752
+ value,
753
+ writable
754
+ });
755
+ this.sameRawWindowKeySet.add(key);
756
+ }
757
+ }
758
+ /**
759
+ * 处理白名单属性
760
+ * @description 处理需要在原始 window 上设置的白名单属性
761
+ * @param key - 属性键
762
+ * @param value - 属性值
763
+ * @param rawWindow - 原始 window 对象
764
+ * @private
765
+ */
766
+ handleWhiteListProperty(key, value, rawWindow) {
767
+ if (WINDOW_WHITE_LIST.includes(key) && !Reflect.has(rawWindow, key) && !BK_WEWEB_INJECT_KEY_LIST.includes(key)) {
768
+ Reflect.set(rawWindow, key, value);
769
+ this.inRawWindowKeySet.add(key);
770
+ }
771
+ }
622
772
  /**
623
773
  * 激活沙箱
624
- * @param data 传递给沙箱的数据
774
+ * @description 启动沙箱环境,初始化代理对象和事件处理
775
+ * @param data - 传递给沙箱的数据(可选)
776
+ * @returns void
625
777
  */
626
778
  activated(data) {
627
779
  if (!this.active) {
@@ -633,7 +785,9 @@ var SandBox = class {
633
785
  }
634
786
  }
635
787
  /**
636
- * 停用沙箱,清理所有副作用
788
+ * 停用沙箱
789
+ * @description 关闭沙箱环境,清理所有副作用和修改
790
+ * @returns void
637
791
  */
638
792
  deactivated() {
639
793
  if (!this.active) return;
@@ -2320,37 +2474,79 @@ var EntrySource = class {
2320
2474
 
2321
2475
  // src/cache/app-cache.ts
2322
2476
  var AppCache = class {
2323
- // todo 主应用共享资源包
2477
+ /** 基础资源源,用于主应用共享资源包 */
2324
2478
  baseSource;
2479
+ /** 应用实例缓存映射表 */
2325
2480
  cache;
2481
+ /**
2482
+ * 构造函数
2483
+ * @description 初始化应用缓存管理器
2484
+ */
2326
2485
  constructor() {
2327
2486
  this.cache = /* @__PURE__ */ new Map();
2328
2487
  this.baseSource = new EntrySource(location.href);
2329
2488
  }
2330
- // 删除缓存
2331
- deleteApp(url) {
2332
- this.cache.delete(url);
2489
+ /**
2490
+ * 设置应用实例到缓存
2491
+ * @description 将应用实例添加到缓存中,使用应用的缓存键作为标识
2492
+ * @param app - 要缓存的应用实例
2493
+ * @returns void
2494
+ */
2495
+ setApp(app) {
2496
+ this.cache.set(app.appCacheKey, app);
2333
2497
  }
2334
- // 获取缓存app
2498
+ /**
2499
+ * 获取缓存的应用实例
2500
+ * @description 根据名称或ID获取已缓存的应用实例
2501
+ * @param name - 应用名称或ID,为空时返回 undefined
2502
+ * @returns BaseModel | undefined - 应用实例或 undefined
2503
+ */
2335
2504
  getApp(name) {
2336
2505
  if (!name) return void 0;
2337
2506
  const app = this.cache.get(name);
2338
2507
  if (app) return app;
2339
2508
  return Array.from(this.cache.values()).find((item) => item.name === name);
2340
2509
  }
2341
- // 获取缓存app
2342
- getBaseAppStyle(urlOrCode) {
2343
- return this.baseSource.getStyle(urlOrCode);
2510
+ /**
2511
+ * 删除缓存的应用实例
2512
+ * @description 从缓存中移除指定URL的应用实例
2513
+ * @param url - 要删除的应用URL标识
2514
+ * @returns void
2515
+ */
2516
+ deleteApp(url) {
2517
+ this.cache.delete(url);
2344
2518
  }
2519
+ /**
2520
+ * 获取缓存的HTML内容
2521
+ * @description 根据URL获取已缓存的HTML内容
2522
+ * @param url - 应用的URL
2523
+ * @returns string - HTML内容,未找到时返回空字符串
2524
+ */
2345
2525
  getCacheHtml(url) {
2346
2526
  const list = Array.from(this.cache.values());
2347
2527
  const app = list.find((item) => item.url === url);
2348
2528
  if (app) return app.source?.rawHtml || "";
2349
2529
  return "";
2350
2530
  }
2531
+ /**
2532
+ * 设置基础应用脚本
2533
+ * @description 将脚本添加到基础资源源中,供多个应用共享
2534
+ * @param url - 脚本的URL
2535
+ * @param script - 脚本实例
2536
+ * @returns void
2537
+ */
2538
+ setBaseAppScript(url, script) {
2539
+ this.baseSource.setScript(url, script);
2540
+ }
2541
+ /**
2542
+ * 获取缓存的脚本资源
2543
+ * @description 从基础资源源或应用缓存中获取脚本资源
2544
+ * @param url - 脚本的URL
2545
+ * @returns Script | undefined - 脚本实例或 undefined
2546
+ */
2351
2547
  getCacheScript(url) {
2352
2548
  let script = this.baseSource.getScript(url);
2353
- if (script) return;
2549
+ if (script) return script;
2354
2550
  const list = Array.from(this.cache.values());
2355
2551
  list.some((app) => {
2356
2552
  script = app.source?.getScript(url);
@@ -2358,9 +2554,34 @@ var AppCache = class {
2358
2554
  });
2359
2555
  return script;
2360
2556
  }
2557
+ /**
2558
+ * 设置基础应用样式
2559
+ * @description 将样式添加到基础资源源中,供多个应用共享
2560
+ * @param url - 样式的URL
2561
+ * @param style - 样式实例
2562
+ * @returns void
2563
+ */
2564
+ setBaseAppStyle(url, style) {
2565
+ this.baseSource.setStyle(url, style);
2566
+ }
2567
+ /**
2568
+ * 获取基础应用样式
2569
+ * @description 从基础资源源中获取样式资源
2570
+ * @param urlOrCode - 样式的URL或代码
2571
+ * @returns Style | undefined - 样式实例或 undefined
2572
+ */
2573
+ getBaseAppStyle(urlOrCode) {
2574
+ return this.baseSource.getStyle(urlOrCode);
2575
+ }
2576
+ /**
2577
+ * 获取缓存的样式资源
2578
+ * @description 从基础资源源或应用缓存中获取样式资源
2579
+ * @param url - 样式的URL
2580
+ * @returns Style | undefined - 样式实例或 undefined
2581
+ */
2361
2582
  getCacheStyle(url) {
2362
2583
  let style = this.baseSource.getStyle(url);
2363
- if (style) return;
2584
+ if (style) return style;
2364
2585
  const list = Array.from(this.cache.values());
2365
2586
  list.some((app) => {
2366
2587
  style = app.source?.getStyle(url);
@@ -2368,15 +2589,11 @@ var AppCache = class {
2368
2589
  });
2369
2590
  return style;
2370
2591
  }
2371
- setApp(app) {
2372
- this.cache.set(app.appCacheKey, app);
2373
- }
2374
- setBaseAppScript(url, script) {
2375
- this.baseSource.setScript(url, script);
2376
- }
2377
- setBaseAppStyle(url, style) {
2378
- this.baseSource.setStyle(url, style);
2379
- }
2592
+ /**
2593
+ * 检查是否存在活跃的应用
2594
+ * @description 判断当前是否有处于非卸载状态的应用实例
2595
+ * @returns boolean - 存在活跃应用时返回 true
2596
+ */
2380
2597
  get hasActiveApp() {
2381
2598
  return Array.from(this.cache.values()).some((app) => app.status !== AppState.UNMOUNT);
2382
2599
  }
@@ -2396,8 +2613,8 @@ function getStyleSource(url, style, originLink) {
2396
2613
  appCache.setBaseAppStyle(url, style);
2397
2614
  replaceStyle.textContent = data;
2398
2615
  dispatchLinkOrScriptLoad(originLink);
2399
- }).catch((err) => {
2400
- console.error(err);
2616
+ }).catch((error) => {
2617
+ console.error("Failed to load style resource:", error);
2401
2618
  dispatchLinkOrScriptError(originLink);
2402
2619
  });
2403
2620
  return replaceStyle;
@@ -2412,59 +2629,67 @@ function getScriptSource(url, script, originScript) {
2412
2629
  if (!url.startsWith("inline-")) {
2413
2630
  originScript.setAttribute("origin-src", url);
2414
2631
  }
2415
- } catch (e) {
2416
- console.error(e, url);
2632
+ } catch (error) {
2633
+ console.error("Failed to set script content:", error, url);
2417
2634
  }
2418
2635
  dispatchLinkOrScriptLoad(originScript);
2419
- }).catch((err) => {
2420
- console.error(err);
2636
+ }).catch((error) => {
2637
+ console.error("Failed to load script resource:", error);
2421
2638
  dispatchLinkOrScriptError(originScript);
2422
2639
  });
2423
2640
  return replaceScript;
2424
2641
  }
2642
+ function processLinkElement(linkElement) {
2643
+ const rel = linkElement.getAttribute("rel");
2644
+ let href = linkElement.getAttribute("href");
2645
+ if (rel === "stylesheet" && href) {
2646
+ href = fillUpPath(href, location.origin);
2647
+ const replaceStyle = document.createElement("style");
2648
+ const styleInstance = new Style({
2649
+ code: "",
2650
+ fromHtml: false,
2651
+ url: href
2652
+ });
2653
+ getStyleSource(href, styleInstance, linkElement);
2654
+ return replaceStyle;
2655
+ }
2656
+ return linkElement;
2657
+ }
2658
+ function processScriptElement(scriptElement) {
2659
+ let src = scriptElement.getAttribute("src");
2660
+ if (src && scriptElement.type !== "module") {
2661
+ src = fillUpPath(src, location.origin);
2662
+ const script = new Script({
2663
+ async: scriptElement.hasAttribute("async"),
2664
+ code: "",
2665
+ defer: scriptElement.defer || scriptElement.type === "module",
2666
+ fromHtml: false,
2667
+ isModule: false
2668
+ });
2669
+ appCache.setBaseAppScript(src, script);
2670
+ const replaceElement = getScriptSource(src, script, scriptElement);
2671
+ return replaceElement || scriptElement;
2672
+ }
2673
+ return scriptElement;
2674
+ }
2425
2675
  function createNewNode(child) {
2426
2676
  if (child instanceof HTMLLinkElement) {
2427
- const rel = child.getAttribute("rel");
2428
- let href = child.getAttribute("href");
2429
- if (rel === "stylesheet" && href) {
2430
- href = fillUpPath(href, location.origin);
2431
- const replaceStyle = document.createElement("style");
2432
- const styleInstance = new Style({
2433
- code: "",
2434
- fromHtml: false,
2435
- url: href
2436
- });
2437
- getStyleSource(href, styleInstance, child);
2438
- return replaceStyle;
2439
- }
2677
+ return processLinkElement(child);
2440
2678
  }
2441
2679
  if (child instanceof HTMLScriptElement) {
2442
- let src = child.getAttribute("src");
2443
- if (src && child.type !== "module") {
2444
- src = fillUpPath(src, location.origin);
2445
- const script = new Script({
2446
- async: child.hasAttribute("async"),
2447
- code: "",
2448
- defer: child.defer || child.type === "module",
2449
- fromHtml: false,
2450
- isModule: false
2451
- });
2452
- appCache.setBaseAppScript(src, script);
2453
- const replaceElement = getScriptSource(src, script, child);
2454
- return replaceElement || child;
2455
- }
2680
+ return processScriptElement(child);
2456
2681
  }
2457
2682
  return child;
2458
2683
  }
2459
2684
  function isLinkOrScript(node) {
2460
2685
  return node instanceof HTMLLinkElement || node instanceof HTMLScriptElement;
2461
2686
  }
2462
- function baseElementInertHandle(parent, newChild, passiveChild, rawMethod) {
2687
+ function baseElementInertHandle(parent, newChild, referenceChild, rawMethod) {
2463
2688
  if (isLinkOrScript(newChild)) {
2464
2689
  const targetChild = createNewNode(newChild);
2465
- return rawMethod.call(parent, targetChild, passiveChild);
2690
+ return rawMethod.call(parent, targetChild, referenceChild);
2466
2691
  }
2467
- return rawMethod.call(parent, newChild, passiveChild);
2692
+ return rawMethod.call(parent, newChild, referenceChild);
2468
2693
  }
2469
2694
  function baseElementAppendHandle(parent, newChild, rawMethod) {
2470
2695
  if (isLinkOrScript(newChild)) {
@@ -2475,10 +2700,15 @@ function baseElementAppendHandle(parent, newChild, rawMethod) {
2475
2700
  }
2476
2701
 
2477
2702
  // src/base-app/collect-source.ts
2478
- function collectBaseSource() {
2479
- const rawBodyAppendChild = HTMLBodyElement.prototype.appendChild;
2480
- const rawHeadAppendChild = HTMLHeadElement.prototype.appendChild;
2481
- const rawHeadInsertBefore = HTMLHeadElement.prototype.appendChild;
2703
+ function cacheOriginalDOMMethods() {
2704
+ return {
2705
+ rawBodyAppendChild: HTMLBodyElement.prototype.appendChild,
2706
+ rawHeadAppendChild: HTMLHeadElement.prototype.appendChild,
2707
+ rawHeadInsertBefore: HTMLHeadElement.prototype.insertBefore
2708
+ };
2709
+ }
2710
+ function overrideDOMMethods(originalMethods) {
2711
+ const { rawBodyAppendChild, rawHeadAppendChild, rawHeadInsertBefore } = originalMethods;
2482
2712
  HTMLBodyElement.prototype.appendChild = function(newChild) {
2483
2713
  return baseElementAppendHandle(this, newChild, rawBodyAppendChild);
2484
2714
  };
@@ -2488,22 +2718,39 @@ function collectBaseSource() {
2488
2718
  HTMLHeadElement.prototype.insertBefore = function(newChild, refChild) {
2489
2719
  return baseElementInertHandle(this, newChild, refChild, rawHeadInsertBefore);
2490
2720
  };
2491
- window.addEventListener("load", () => {
2492
- const nodeList = document.head.querySelectorAll("style");
2493
- for (const node of Array.from(nodeList)) {
2494
- node.textContent && appCache.setBaseAppStyle(
2495
- randomUrl(),
2496
- new Style({
2497
- code: node.textContent,
2721
+ }
2722
+ function collectExistingStyles() {
2723
+ const styleNodes = document.head.querySelectorAll("style");
2724
+ for (const styleNode of Array.from(styleNodes)) {
2725
+ const textContent = styleNode.textContent;
2726
+ if (textContent) {
2727
+ try {
2728
+ const style = new Style({
2729
+ code: textContent,
2498
2730
  fromHtml: false,
2499
2731
  url: ""
2500
- })
2501
- );
2732
+ });
2733
+ appCache.setBaseAppStyle(randomUrl(), style);
2734
+ } catch (error) {
2735
+ console.warn("Failed to collect style element:", error);
2736
+ }
2502
2737
  }
2503
- });
2738
+ }
2739
+ }
2740
+ function setupLoadEventListener() {
2741
+ window.addEventListener("load", collectExistingStyles);
2742
+ }
2743
+ function collectBaseSource() {
2744
+ const originalMethods = cacheOriginalDOMMethods();
2745
+ overrideDOMMethods(originalMethods);
2746
+ setupLoadEventListener();
2504
2747
  }
2505
2748
 
2506
2749
  // src/context/element.ts
2750
+ var RESOURCE_ATTRIBUTES = ["src", "srcset"];
2751
+ var LINK_ATTRIBUTES = ["href"];
2752
+ var RESOURCE_TAG_NAMES = ["IMG", "SCRIPT"];
2753
+ var LINK_TAG_NAMES = ["LINK"];
2507
2754
  var { setAttribute } = Element.prototype;
2508
2755
  var {
2509
2756
  append,
@@ -2518,47 +2765,84 @@ var {
2518
2765
  } = HTMLHeadElement.prototype;
2519
2766
  var rawHead = document.head;
2520
2767
  var hasRewrite = false;
2521
- function rewriteBodyAndHeaderMethods() {
2522
- if (hasRewrite) return;
2523
- hasRewrite = true;
2524
- Element.prototype.setAttribute = function(key, value) {
2525
- const tagName = this.tagName.toLocaleUpperCase();
2526
- if ((["src", "srcset"].includes(key) && ["IMG", "SCRIPT"].includes(tagName) || key === "href" && ["LINK"].includes(tagName)) && this.__BK_WEWEB_APP_KEY__ && appCache.getApp(this.__BK_WEWEB_APP_KEY__ || "")) {
2527
- setAttribute.call(this, key, fillUpPath(value, appCache.getApp(this.__BK_WEWEB_APP_KEY__).url));
2528
- } else {
2529
- setAttribute.call(this, key, value);
2768
+ function shouldProcessResourcePath(key, tagName) {
2769
+ const upperTagName = tagName.toUpperCase();
2770
+ return RESOURCE_ATTRIBUTES.includes(key) && RESOURCE_TAG_NAMES.includes(upperTagName) || LINK_ATTRIBUTES.includes(key) && LINK_TAG_NAMES.includes(upperTagName);
2771
+ }
2772
+ function getElementApp(element) {
2773
+ if (!element.__BK_WEWEB_APP_KEY__) {
2774
+ return null;
2775
+ }
2776
+ return appCache.getApp(element.__BK_WEWEB_APP_KEY__);
2777
+ }
2778
+ function createOverriddenSetAttribute() {
2779
+ return function(key, value) {
2780
+ const tagName = this.tagName.toUpperCase();
2781
+ if (shouldProcessResourcePath(key, tagName) && this.__BK_WEWEB_APP_KEY__) {
2782
+ const app = getElementApp(this);
2783
+ if (app) {
2784
+ setAttribute.call(this, key, fillUpPath(value, app.url));
2785
+ return;
2786
+ }
2530
2787
  }
2788
+ setAttribute.call(this, key, value);
2531
2789
  };
2532
- HTMLBodyElement.prototype.appendChild = function appendChildNew(newChild) {
2533
- if (newChild.__KEEP_ALIVE__ && isSpecialElement(newChild)) return headAppendChild.call(rawHead, newChild);
2790
+ }
2791
+ function handleKeepAliveElement(newChild) {
2792
+ if (newChild.__KEEP_ALIVE__ && isSpecialElement(newChild)) {
2793
+ return headAppendChild.call(rawHead, newChild);
2794
+ }
2795
+ return null;
2796
+ }
2797
+ function createOverriddenAppendChild() {
2798
+ return function(newChild) {
2799
+ const keepAliveResult = handleKeepAliveElement(newChild);
2800
+ if (keepAliveResult) {
2801
+ return keepAliveResult;
2802
+ }
2534
2803
  return elementAppendHandler(this, newChild, bodyAppendChild2);
2535
2804
  };
2536
- HTMLBodyElement.prototype.append = function(...nodes) {
2805
+ }
2806
+ function createOverriddenAppend() {
2807
+ return function(...nodes) {
2537
2808
  nodes.forEach((node) => {
2538
- if (node.__KEEP_ALIVE__ && isSpecialElement(node)) {
2539
- return headAppendChild.call(rawHead, node);
2809
+ const keepAliveResult = handleKeepAliveElement(node);
2810
+ if (keepAliveResult) {
2811
+ return;
2540
2812
  }
2541
2813
  elementAppendHandler(this, node, bodyAppendChild2);
2542
2814
  });
2543
2815
  };
2544
- HTMLHeadElement.prototype.appendChild = HTMLBodyElement.prototype.appendChild;
2545
- HTMLHeadElement.prototype.insertBefore = function(newChild, refChild) {
2546
- return elementInsertHandler(this, newChild, refChild, headInsertBefore);
2547
- };
2548
- HTMLBodyElement.prototype.insertBefore = function(newChild, refChild) {
2816
+ }
2817
+ function createOverriddenInsertBefore() {
2818
+ return function(newChild, refChild) {
2549
2819
  return elementInsertHandler(this, newChild, refChild, headInsertBefore);
2550
2820
  };
2551
- HTMLBodyElement.prototype.removeChild = function removeChildNew(oldChild) {
2552
- const app = appCache.getApp(oldChild.__BK_WEWEB_APP_KEY__);
2821
+ }
2822
+ function createOverriddenRemoveChild() {
2823
+ return function(oldChild) {
2824
+ const app = oldChild.__BK_WEWEB_APP_KEY__ ? appCache.getApp(oldChild.__BK_WEWEB_APP_KEY__) : null;
2553
2825
  if (app?.container?.contains(oldChild)) {
2554
- const node = bodyRemoveChild.call(app.container, oldChild);
2555
- return node;
2826
+ return bodyRemoveChild.call(app.container, oldChild);
2556
2827
  }
2557
2828
  if (this.contains(oldChild)) {
2558
2829
  return bodyRemoveChild.call(this, oldChild);
2559
2830
  }
2560
2831
  return oldChild;
2561
2832
  };
2833
+ }
2834
+ function rewriteBodyAndHeaderMethods() {
2835
+ if (hasRewrite) {
2836
+ return;
2837
+ }
2838
+ hasRewrite = true;
2839
+ Element.prototype.setAttribute = createOverriddenSetAttribute();
2840
+ HTMLBodyElement.prototype.appendChild = createOverriddenAppendChild();
2841
+ HTMLBodyElement.prototype.append = createOverriddenAppend();
2842
+ HTMLBodyElement.prototype.insertBefore = createOverriddenInsertBefore();
2843
+ HTMLBodyElement.prototype.removeChild = createOverriddenRemoveChild();
2844
+ HTMLHeadElement.prototype.appendChild = HTMLBodyElement.prototype.appendChild;
2845
+ HTMLHeadElement.prototype.insertBefore = createOverriddenInsertBefore();
2562
2846
  HTMLHeadElement.prototype.removeChild = HTMLBodyElement.prototype.removeChild;
2563
2847
  }
2564
2848
  function resetBodyAndHeaderMethods() {
@@ -2587,8 +2871,8 @@ function activated(appKey, container, callback) {
2587
2871
  beforeLoad();
2588
2872
  app.activated(container, callback);
2589
2873
  });
2590
- } else {
2591
- app && nextTask(() => {
2874
+ } else if (app) {
2875
+ nextTask(() => {
2592
2876
  beforeLoad();
2593
2877
  app.mount(container, callback);
2594
2878
  });
@@ -2596,9 +2880,10 @@ function activated(appKey, container, callback) {
2596
2880
  }
2597
2881
 
2598
2882
  // src/lifecycle/deactivated.ts
2883
+ var DEACTIVATABLE_STATES = [AppState.ACTIVATED, AppState.MOUNTED];
2599
2884
  function deactivated(appKey) {
2600
2885
  const app = appCache.getApp(appKey);
2601
- if (app && [AppState.ACTIVATED, AppState.MOUNTED].some((status) => status === app.status)) {
2886
+ if (app && DEACTIVATABLE_STATES.some((status) => status === app.status)) {
2602
2887
  app.keepAlive ? app.deactivated() : app.unmount();
2603
2888
  }
2604
2889
  if (!appCache.hasActiveApp) {
@@ -2607,9 +2892,12 @@ function deactivated(appKey) {
2607
2892
  }
2608
2893
 
2609
2894
  // src/lifecycle/load.ts
2895
+ var STATUS_CHECK_INTERVAL = 300;
2610
2896
  async function load(props) {
2611
2897
  beforeLoad();
2612
- if (props.mode === "js" /* INSTANCE */) return await loadInstance(props);
2898
+ if (props.mode === "js" /* INSTANCE */) {
2899
+ return await loadInstance(props);
2900
+ }
2613
2901
  return await loadApp(props);
2614
2902
  }
2615
2903
  async function loadApp(props) {
@@ -2638,7 +2926,7 @@ function loadInstance(props) {
2638
2926
  resolve(instance);
2639
2927
  clearInterval(timer);
2640
2928
  }
2641
- }, 300);
2929
+ }, STATUS_CHECK_INTERVAL);
2642
2930
  return;
2643
2931
  }
2644
2932
  resolve(instance);
@@ -2658,14 +2946,35 @@ function unmount(appKey) {
2658
2946
 
2659
2947
  // src/component/web-component.ts
2660
2948
  var BkWewebElement = class extends HTMLElement {
2949
+ /** 应用 URL 缓存 */
2661
2950
  appUrl = "";
2951
+ /** 组件连接状态标识 */
2662
2952
  connected = false;
2953
+ /**
2954
+ * 观察的属性列表
2955
+ * @description 定义需要监听变化的属性名称列表
2956
+ * @returns string[] - 属性名称数组
2957
+ */
2663
2958
  static get observedAttributes() {
2664
2959
  return ["url" /* url */];
2665
2960
  }
2961
+ /**
2962
+ * 获取布尔类型属性值
2963
+ * @description 解析布尔类型的自定义属性,支持驼峰和短横线命名
2964
+ * @param name - 属性名称
2965
+ * @returns boolean | undefined - 属性值或 undefined
2966
+ * @private
2967
+ */
2666
2968
  getBooleanAttr(name) {
2667
- return this.hasAttribute(name) || this.hasAttribute(name.replace(/([A-Z])/g, "-$1").toLocaleLowerCase()) ? this.getAttribute(name) !== "false" : void 0;
2969
+ const hasAttr = this.hasAttribute(name) || this.hasAttribute(name.replace(/([A-Z])/g, "-$1").toLocaleLowerCase());
2970
+ return hasAttr ? this.getAttribute(name) !== "false" : void 0;
2668
2971
  }
2972
+ /**
2973
+ * 处理属性变化的内部逻辑
2974
+ * @description 当属性发生变化时执行的处理逻辑
2975
+ * @returns Promise<void>
2976
+ * @private
2977
+ */
2669
2978
  async handleAttributeChanged() {
2670
2979
  if (!this.appKey) return;
2671
2980
  if (this.getBooleanAttr("setShodowDom" /* setShodowDom */)) {
@@ -2678,12 +2987,27 @@ var BkWewebElement = class extends HTMLElement {
2678
2987
  }
2679
2988
  await load(this.appProps);
2680
2989
  }
2990
+ /**
2991
+ * 属性变化回调
2992
+ * @description 当观察的属性发生变化时触发
2993
+ * @param attr - 变化的属性名
2994
+ * @param _oldVal - 旧值(未使用)
2995
+ * @param newVal - 新值
2996
+ * @returns void
2997
+ */
2681
2998
  attributeChangedCallback(attr, _oldVal, newVal) {
2682
2999
  if (attr !== "url" /* url */ || this[attr] === newVal || !this.connected) return;
2683
3000
  this.appUrl = newVal;
2684
3001
  const cacheApp = appCache.getApp(this.appKey);
2685
- (this.connected || cacheApp) && this.handleAttributeChanged();
3002
+ if (this.connected || cacheApp) {
3003
+ this.handleAttributeChanged();
3004
+ }
2686
3005
  }
3006
+ /**
3007
+ * 组件连接到 DOM 时的回调
3008
+ * @description 当自定义元素被插入到 DOM 时触发
3009
+ * @returns Promise<void>
3010
+ */
2687
3011
  async connectedCallback() {
2688
3012
  if (this.getBooleanAttr("setShodowDom" /* setShodowDom */) && !this.shadowRoot) {
2689
3013
  this.attachShadow({ delegatesFocus: false, mode: "open" });
@@ -2692,12 +3016,24 @@ var BkWewebElement = class extends HTMLElement {
2692
3016
  activated(this.appKey, this.shadowRoot ?? this);
2693
3017
  this.connected = true;
2694
3018
  }
3019
+ /**
3020
+ * 组件从 DOM 断开时的回调
3021
+ * @description 当自定义元素从 DOM 中移除时触发
3022
+ * @returns void
3023
+ */
2695
3024
  disconnectedCallback() {
2696
3025
  this.connected = false;
2697
3026
  if (this.appProps.keepAlive) {
2698
3027
  deactivated(this.appKey);
2699
- } else unmount(this.appKey);
3028
+ } else {
3029
+ unmount(this.appKey);
3030
+ }
2700
3031
  }
3032
+ /**
3033
+ * 获取应用数据
3034
+ * @description 解析 data 属性中的 JSON 数据
3035
+ * @returns Record<string, unknown> - 应用数据对象
3036
+ */
2701
3037
  get appData() {
2702
3038
  if (this.hasAttribute("data" /* data */)) {
2703
3039
  try {
@@ -2707,35 +3043,44 @@ var BkWewebElement = class extends HTMLElement {
2707
3043
  }
2708
3044
  return {};
2709
3045
  }
2710
- // 考虑到js模式下 需要js bundle的复用性 需用户设置id属性 如果单实例下则可以不用配置
3046
+ /**
3047
+ * 获取应用标识符
3048
+ * @description 优先使用 id 属性,其次使用 url 属性作为应用标识
3049
+ * 考虑到 JS 模式下需要 JS bundle 的复用性,需用户设置 id 属性
3050
+ * 如果是单实例应用则可以不用配置 id
3051
+ * @returns string | null - 应用标识符或 null
3052
+ */
2711
3053
  get appKey() {
2712
3054
  return this.getAttribute("id" /* id */) || this.getAttribute("url" /* url */);
2713
3055
  }
3056
+ /**
3057
+ * 获取应用配置属性
3058
+ * @description 根据模式返回相应的应用配置对象
3059
+ * @returns IAppModelProps | IJsModelProps - 应用配置对象
3060
+ */
2714
3061
  get appProps() {
3062
+ const commonProps = {
3063
+ container: this.shadowRoot ?? this,
3064
+ data: this.appData,
3065
+ id: this.appKey,
3066
+ keepAlive: this.getBooleanAttr("keepAlive" /* keepAlive */),
3067
+ showSourceCode: this.getBooleanAttr("showSourceCode" /* showSourceCode */),
3068
+ url: this.getAttribute("url" /* url */)
3069
+ };
2715
3070
  if (this.getAttribute("mode") === "js" /* INSTANCE */) {
2716
3071
  return {
2717
- container: this.shadowRoot ?? this,
2718
- data: this.appData,
2719
- id: this.appKey,
2720
- keepAlive: this.getBooleanAttr("keepAlive" /* keepAlive */),
3072
+ ...commonProps,
2721
3073
  mode: "js" /* INSTANCE */,
2722
3074
  scopeCss: this.getBooleanAttr("scopeCss" /* scopeCss */) && !this.getBooleanAttr("setShodowDom" /* setShodowDom */),
2723
- scopeJs: this.getBooleanAttr("scopeJs" /* scopeJs */),
2724
- showSourceCode: this.getBooleanAttr("showSourceCode" /* showSourceCode */),
2725
- url: this.getAttribute("url" /* url */)
3075
+ scopeJs: this.getBooleanAttr("scopeJs" /* scopeJs */)
2726
3076
  };
2727
3077
  }
2728
3078
  return {
2729
- container: this.shadowRoot ?? this,
2730
- data: this.appData,
2731
- id: this.appKey,
2732
- keepAlive: this.getBooleanAttr("keepAlive" /* keepAlive */),
3079
+ ...commonProps,
2733
3080
  mode: "app" /* APP */,
2734
3081
  scopeCss: !this.getBooleanAttr("setShodowDom" /* setShodowDom */),
2735
3082
  scopeJs: !this.getBooleanAttr("scopeJs" /* scopeJs */),
2736
- scopeLocation: this.getBooleanAttr("scopeLocation" /* scopeLocation */),
2737
- showSourceCode: this.getBooleanAttr("showSourceCode" /* showSourceCode */),
2738
- url: this.getAttribute("url" /* url */)
3083
+ scopeLocation: this.getBooleanAttr("scopeLocation" /* scopeLocation */)
2739
3084
  };
2740
3085
  }
2741
3086
  };
@@ -2743,10 +3088,12 @@ var BkWewebElement = class extends HTMLElement {
2743
3088
  // src/lifecycle/mount.ts
2744
3089
  function mount(appKey, container, callback) {
2745
3090
  const app = appCache.getApp(appKey);
2746
- app && nextTask(() => {
2747
- beforeLoad();
2748
- app.mount(container, callback);
2749
- });
3091
+ if (app) {
3092
+ nextTask(() => {
3093
+ beforeLoad();
3094
+ app.mount(container, callback);
3095
+ });
3096
+ }
2750
3097
  }
2751
3098
 
2752
3099
  // src/lifecycle/unload.ts