@wsxjs/wsx-core 0.0.30 → 0.1.0
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/chunk-NEHWERG6.mjs +1424 -0
- package/dist/chunk-PIKDVFOA.mjs +1337 -0
- package/dist/chunk-PNIWQQN6.mjs +1330 -0
- package/dist/chunk-PP54HBAY.mjs +1337 -0
- package/dist/index.js +1720 -1988
- package/dist/index.mjs +170 -345
- package/dist/jsx-runtime.js +110 -154
- package/dist/jsx-runtime.mjs +1 -1
- package/dist/jsx.js +110 -154
- package/dist/jsx.mjs +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +2 -2
- package/src/base-component.ts +8 -309
- package/src/index.ts +1 -0
- package/src/jsx-factory.ts +3 -1
- package/src/light-component.ts +111 -123
- package/src/utils/cache-key.ts +17 -2
- package/src/utils/dom-utils.ts +7 -47
- package/src/utils/element-update.ts +107 -231
- package/src/utils/update-children-helpers.ts +67 -78
- package/src/web-component.ts +108 -96
package/dist/index.mjs
CHANGED
|
@@ -4,49 +4,10 @@ import {
|
|
|
4
4
|
createLogger,
|
|
5
5
|
h,
|
|
6
6
|
parseHTMLToNodes,
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
// src/styles/style-manager.ts
|
|
12
|
-
var StyleManager = class {
|
|
13
|
-
/**
|
|
14
|
-
* Create or get a cached CSSStyleSheet for a component
|
|
15
|
-
*/
|
|
16
|
-
static getStyleSheet(componentName, cssText) {
|
|
17
|
-
if (this.styleSheets.has(componentName)) {
|
|
18
|
-
return this.styleSheets.get(componentName);
|
|
19
|
-
}
|
|
20
|
-
if ("adoptedStyleSheets" in Document.prototype && "CSSStyleSheet" in window) {
|
|
21
|
-
const styleSheet = new CSSStyleSheet();
|
|
22
|
-
styleSheet.replaceSync(cssText);
|
|
23
|
-
this.styleSheets.set(componentName, styleSheet);
|
|
24
|
-
return styleSheet;
|
|
25
|
-
} else {
|
|
26
|
-
throw new Error("Constructable StyleSheets not supported. Use fallback method.");
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
|
-
/**
|
|
30
|
-
* Apply styles to a shadow root using constructable stylesheets
|
|
31
|
-
*/
|
|
32
|
-
static applyStyles(shadowRoot, componentName, cssText) {
|
|
33
|
-
try {
|
|
34
|
-
const styleSheet = this.getStyleSheet(componentName, cssText);
|
|
35
|
-
shadowRoot.adoptedStyleSheets = [styleSheet];
|
|
36
|
-
} catch {
|
|
37
|
-
this.applyStylesFallback(shadowRoot, cssText);
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
/**
|
|
41
|
-
* Fallback method for browsers that don't support constructable stylesheets
|
|
42
|
-
*/
|
|
43
|
-
static applyStylesFallback(shadowRoot, cssText) {
|
|
44
|
-
const style = document.createElement("style");
|
|
45
|
-
style.textContent = cssText;
|
|
46
|
-
shadowRoot.appendChild(style);
|
|
47
|
-
}
|
|
48
|
-
};
|
|
49
|
-
StyleManager.styleSheets = /* @__PURE__ */ new Map();
|
|
7
|
+
shouldPreserveElement,
|
|
8
|
+
updateChildren,
|
|
9
|
+
updateProps
|
|
10
|
+
} from "./chunk-PNIWQQN6.mjs";
|
|
50
11
|
|
|
51
12
|
// src/utils/reactive.ts
|
|
52
13
|
import { createLogger as createLogger2 } from "@wsxjs/wsx-logger";
|
|
@@ -383,21 +344,6 @@ var BaseComponent = class extends HTMLElement {
|
|
|
383
344
|
* @internal
|
|
384
345
|
*/
|
|
385
346
|
this._domCache = new DOMCacheManager();
|
|
386
|
-
/**
|
|
387
|
-
* 当前捕获的焦点状态(用于在 render 时使用捕获的值)
|
|
388
|
-
* @internal - 由 rerender() 方法管理
|
|
389
|
-
*/
|
|
390
|
-
this._pendingFocusState = null;
|
|
391
|
-
/**
|
|
392
|
-
* 防抖定时器,用于延迟重渲染(当用户正在输入时)
|
|
393
|
-
* @internal
|
|
394
|
-
*/
|
|
395
|
-
this._rerenderDebounceTimer = null;
|
|
396
|
-
/**
|
|
397
|
-
* 待处理的重渲染标志(当用户正在输入时,标记需要重渲染但延迟执行)
|
|
398
|
-
* @internal
|
|
399
|
-
*/
|
|
400
|
-
this._pendingRerender = false;
|
|
401
347
|
/**
|
|
402
348
|
* 正在渲染标志(防止在 _rerender() 执行期间再次触发 scheduleRerender())
|
|
403
349
|
* @internal
|
|
@@ -409,29 +355,6 @@ var BaseComponent = class extends HTMLElement {
|
|
|
409
355
|
* @internal
|
|
410
356
|
*/
|
|
411
357
|
this._hasScheduledRender = false;
|
|
412
|
-
/**
|
|
413
|
-
* 处理 blur 事件,在用户停止输入时执行待处理的重渲染
|
|
414
|
-
* @internal
|
|
415
|
-
*/
|
|
416
|
-
this.handleGlobalBlur = (event) => {
|
|
417
|
-
const root = this.getActiveRoot();
|
|
418
|
-
const target = event.target;
|
|
419
|
-
if (target && root.contains(target)) {
|
|
420
|
-
if (this._pendingRerender && this.connected) {
|
|
421
|
-
if (this._rerenderDebounceTimer !== null) {
|
|
422
|
-
clearTimeout(this._rerenderDebounceTimer);
|
|
423
|
-
this._rerenderDebounceTimer = null;
|
|
424
|
-
}
|
|
425
|
-
requestAnimationFrame(() => {
|
|
426
|
-
if (this._pendingRerender && this.connected && !this._isRendering) {
|
|
427
|
-
this._pendingRerender = false;
|
|
428
|
-
this._isRendering = true;
|
|
429
|
-
this._rerender();
|
|
430
|
-
}
|
|
431
|
-
});
|
|
432
|
-
}
|
|
433
|
-
}
|
|
434
|
-
};
|
|
435
358
|
this._isDebugEnabled = config.debug ?? false;
|
|
436
359
|
const host = this;
|
|
437
360
|
const originalStyles = config.styles;
|
|
@@ -506,10 +429,6 @@ var BaseComponent = class extends HTMLElement {
|
|
|
506
429
|
*/
|
|
507
430
|
scheduleRerender() {
|
|
508
431
|
if (!this.connected) {
|
|
509
|
-
if (this._rerenderDebounceTimer !== null) {
|
|
510
|
-
clearTimeout(this._rerenderDebounceTimer);
|
|
511
|
-
this._rerenderDebounceTimer = null;
|
|
512
|
-
}
|
|
513
432
|
return;
|
|
514
433
|
}
|
|
515
434
|
if (this._isRendering) {
|
|
@@ -518,31 +437,6 @@ var BaseComponent = class extends HTMLElement {
|
|
|
518
437
|
if (this._hasScheduledRender) {
|
|
519
438
|
return;
|
|
520
439
|
}
|
|
521
|
-
const root = this.getActiveRoot();
|
|
522
|
-
let activeElement = null;
|
|
523
|
-
if (root instanceof ShadowRoot) {
|
|
524
|
-
activeElement = root.activeElement;
|
|
525
|
-
} else {
|
|
526
|
-
const docActiveElement = document.activeElement;
|
|
527
|
-
if (docActiveElement && root.contains(docActiveElement)) {
|
|
528
|
-
activeElement = docActiveElement;
|
|
529
|
-
}
|
|
530
|
-
}
|
|
531
|
-
if (activeElement) {
|
|
532
|
-
const isInputElement = activeElement instanceof HTMLInputElement && activeElement.type !== "radio" && activeElement.type !== "checkbox" || activeElement instanceof HTMLTextAreaElement || activeElement instanceof HTMLSelectElement || activeElement.hasAttribute("contenteditable");
|
|
533
|
-
const forceRender = activeElement.hasAttribute("data-wsx-force-render");
|
|
534
|
-
if (isInputElement && !forceRender) {
|
|
535
|
-
this._pendingRerender = true;
|
|
536
|
-
if (this._rerenderDebounceTimer !== null) {
|
|
537
|
-
clearTimeout(this._rerenderDebounceTimer);
|
|
538
|
-
this._rerenderDebounceTimer = null;
|
|
539
|
-
}
|
|
540
|
-
return;
|
|
541
|
-
}
|
|
542
|
-
}
|
|
543
|
-
if (this._pendingRerender) {
|
|
544
|
-
this._pendingRerender = false;
|
|
545
|
-
}
|
|
546
440
|
this._hasScheduledRender = true;
|
|
547
441
|
requestAnimationFrame(() => {
|
|
548
442
|
this._hasScheduledRender = false;
|
|
@@ -571,21 +465,12 @@ var BaseComponent = class extends HTMLElement {
|
|
|
571
465
|
* @internal
|
|
572
466
|
*/
|
|
573
467
|
cleanup() {
|
|
574
|
-
if (this._rerenderDebounceTimer !== null) {
|
|
575
|
-
clearTimeout(this._rerenderDebounceTimer);
|
|
576
|
-
this._rerenderDebounceTimer = null;
|
|
577
|
-
}
|
|
578
|
-
const root = this.getActiveRoot();
|
|
579
|
-
root.removeEventListener("blur", this.handleGlobalBlur, true);
|
|
580
|
-
this._pendingRerender = false;
|
|
581
468
|
}
|
|
582
469
|
/**
|
|
583
470
|
* 初始化事件监听器(在组件连接时调用)
|
|
584
471
|
* @internal
|
|
585
472
|
*/
|
|
586
473
|
initializeEventListeners() {
|
|
587
|
-
const root = this.getActiveRoot();
|
|
588
|
-
root.addEventListener("blur", this.handleGlobalBlur, true);
|
|
589
474
|
}
|
|
590
475
|
/**
|
|
591
476
|
* 获取配置值
|
|
@@ -658,119 +543,47 @@ var BaseComponent = class extends HTMLElement {
|
|
|
658
543
|
}
|
|
659
544
|
return this;
|
|
660
545
|
}
|
|
546
|
+
};
|
|
547
|
+
|
|
548
|
+
// src/styles/style-manager.ts
|
|
549
|
+
var StyleManager = class {
|
|
661
550
|
/**
|
|
662
|
-
*
|
|
663
|
-
* @returns 焦点状态,如果没有焦点元素则返回 null
|
|
551
|
+
* Create or get a cached CSSStyleSheet for a component
|
|
664
552
|
*/
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
if (root instanceof ShadowRoot) {
|
|
669
|
-
activeElement = root.activeElement;
|
|
670
|
-
} else {
|
|
671
|
-
const docActiveElement = document.activeElement;
|
|
672
|
-
if (docActiveElement && root.contains(docActiveElement)) {
|
|
673
|
-
activeElement = docActiveElement;
|
|
674
|
-
}
|
|
675
|
-
}
|
|
676
|
-
if (!activeElement || !(activeElement instanceof HTMLElement)) {
|
|
677
|
-
return null;
|
|
678
|
-
}
|
|
679
|
-
const key = activeElement.getAttribute("data-wsx-key");
|
|
680
|
-
if (!key) {
|
|
681
|
-
return null;
|
|
553
|
+
static getStyleSheet(componentName, cssText) {
|
|
554
|
+
if (this.styleSheets.has(componentName)) {
|
|
555
|
+
return this.styleSheets.get(componentName);
|
|
682
556
|
}
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
state2.selectionStart = activeElement.selectionStart ?? void 0;
|
|
691
|
-
state2.selectionEnd = activeElement.selectionEnd ?? void 0;
|
|
692
|
-
if (activeElement instanceof HTMLTextAreaElement) {
|
|
693
|
-
state2.scrollTop = activeElement.scrollTop;
|
|
694
|
-
}
|
|
695
|
-
} else if (activeElement instanceof HTMLSelectElement) {
|
|
696
|
-
state2.elementType = "select";
|
|
697
|
-
state2.selectedIndex = activeElement.selectedIndex;
|
|
698
|
-
} else if (activeElement.hasAttribute("contenteditable")) {
|
|
699
|
-
state2.elementType = "contenteditable";
|
|
700
|
-
const selection = window.getSelection();
|
|
701
|
-
if (selection && selection.rangeCount > 0) {
|
|
702
|
-
const range = selection.getRangeAt(0);
|
|
703
|
-
state2.selectionStart = range.startOffset;
|
|
704
|
-
state2.selectionEnd = range.endOffset;
|
|
705
|
-
}
|
|
557
|
+
if ("adoptedStyleSheets" in Document.prototype && "CSSStyleSheet" in window) {
|
|
558
|
+
const styleSheet = new CSSStyleSheet();
|
|
559
|
+
styleSheet.replaceSync(cssText);
|
|
560
|
+
this.styleSheets.set(componentName, styleSheet);
|
|
561
|
+
return styleSheet;
|
|
562
|
+
} else {
|
|
563
|
+
throw new Error("Constructable StyleSheets not supported. Use fallback method.");
|
|
706
564
|
}
|
|
707
|
-
return state2;
|
|
708
565
|
}
|
|
709
566
|
/**
|
|
710
|
-
*
|
|
711
|
-
* @param state - 之前捕获的焦点状态
|
|
567
|
+
* Apply styles to a shadow root using constructable stylesheets
|
|
712
568
|
*/
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
if (!target) {
|
|
720
|
-
return;
|
|
721
|
-
}
|
|
722
|
-
if (state2.value !== void 0) {
|
|
723
|
-
if (target instanceof HTMLInputElement || target instanceof HTMLTextAreaElement) {
|
|
724
|
-
target.value = state2.value;
|
|
725
|
-
}
|
|
726
|
-
}
|
|
727
|
-
if (state2.selectedIndex !== void 0 && target instanceof HTMLSelectElement) {
|
|
728
|
-
target.selectedIndex = state2.selectedIndex;
|
|
569
|
+
static applyStyles(shadowRoot, componentName, cssText) {
|
|
570
|
+
try {
|
|
571
|
+
const styleSheet = this.getStyleSheet(componentName, cssText);
|
|
572
|
+
shadowRoot.adoptedStyleSheets = [styleSheet];
|
|
573
|
+
} catch {
|
|
574
|
+
this.applyStylesFallback(shadowRoot, cssText);
|
|
729
575
|
}
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
if (currentTarget instanceof HTMLInputElement || currentTarget instanceof HTMLTextAreaElement) {
|
|
739
|
-
if (currentTarget.value !== state2.value) {
|
|
740
|
-
currentTarget.value = state2.value;
|
|
741
|
-
}
|
|
742
|
-
}
|
|
743
|
-
}
|
|
744
|
-
currentTarget.focus({ preventScroll: true });
|
|
745
|
-
if (state2.selectionStart !== void 0) {
|
|
746
|
-
if (currentTarget instanceof HTMLInputElement || currentTarget instanceof HTMLTextAreaElement) {
|
|
747
|
-
const start = state2.selectionStart;
|
|
748
|
-
const end = state2.selectionEnd ?? start;
|
|
749
|
-
currentTarget.setSelectionRange(start, end);
|
|
750
|
-
if (state2.scrollTop !== void 0 && currentTarget instanceof HTMLTextAreaElement) {
|
|
751
|
-
currentTarget.scrollTop = state2.scrollTop;
|
|
752
|
-
}
|
|
753
|
-
} else if (currentTarget.hasAttribute("contenteditable")) {
|
|
754
|
-
const selection = window.getSelection();
|
|
755
|
-
if (selection) {
|
|
756
|
-
const range = document.createRange();
|
|
757
|
-
const textNode = currentTarget.childNodes[0];
|
|
758
|
-
if (textNode && textNode.nodeType === Node.TEXT_NODE) {
|
|
759
|
-
const maxPos = Math.min(
|
|
760
|
-
state2.selectionStart,
|
|
761
|
-
textNode.textContent?.length || 0
|
|
762
|
-
);
|
|
763
|
-
range.setStart(textNode, maxPos);
|
|
764
|
-
range.setEnd(textNode, state2.selectionEnd ?? maxPos);
|
|
765
|
-
selection.removeAllRanges();
|
|
766
|
-
selection.addRange(range);
|
|
767
|
-
}
|
|
768
|
-
}
|
|
769
|
-
}
|
|
770
|
-
}
|
|
771
|
-
});
|
|
576
|
+
}
|
|
577
|
+
/**
|
|
578
|
+
* Fallback method for browsers that don't support constructable stylesheets
|
|
579
|
+
*/
|
|
580
|
+
static applyStylesFallback(shadowRoot, cssText) {
|
|
581
|
+
const style = document.createElement("style");
|
|
582
|
+
style.textContent = cssText;
|
|
583
|
+
shadowRoot.appendChild(style);
|
|
772
584
|
}
|
|
773
585
|
};
|
|
586
|
+
StyleManager.styleSheets = /* @__PURE__ */ new Map();
|
|
774
587
|
|
|
775
588
|
// src/web-component.ts
|
|
776
589
|
import { createLogger as createLogger3 } from "@wsxjs/wsx-logger";
|
|
@@ -855,8 +668,11 @@ var WebComponent = class extends BaseComponent {
|
|
|
855
668
|
}
|
|
856
669
|
/**
|
|
857
670
|
* 内部重渲染实现
|
|
858
|
-
*
|
|
859
|
-
*
|
|
671
|
+
* 使用真实 DOM 协调 (RFC 0058) 替代全量替换
|
|
672
|
+
*
|
|
673
|
+
* 策略:
|
|
674
|
+
* 1. 尝试原地更新 (Reconciliation)
|
|
675
|
+
* 2. 只有在结构完全不匹配时才回退到替更新
|
|
860
676
|
*
|
|
861
677
|
* @override
|
|
862
678
|
*/
|
|
@@ -865,64 +681,67 @@ var WebComponent = class extends BaseComponent {
|
|
|
865
681
|
this._isRendering = false;
|
|
866
682
|
return;
|
|
867
683
|
}
|
|
868
|
-
const
|
|
869
|
-
this._pendingFocusState = focusState;
|
|
870
|
-
const adoptedStyleSheets = this.shadowRoot.adoptedStyleSheets || [];
|
|
871
|
-
const hasActualAdoptedStyles = this.shadowRoot.adoptedStyleSheets && this.shadowRoot.adoptedStyleSheets.length > 0;
|
|
872
|
-
const hasFallbackStyleElement = Array.from(this.shadowRoot.children).some(
|
|
873
|
-
(child) => child instanceof HTMLStyleElement
|
|
874
|
-
);
|
|
684
|
+
const content = RenderContext.runInContext(this, () => this.render());
|
|
875
685
|
try {
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
if (
|
|
879
|
-
|
|
880
|
-
|
|
686
|
+
const allChildren = Array.from(this.shadowRoot.childNodes);
|
|
687
|
+
const oldChildren = allChildren.filter((child) => {
|
|
688
|
+
if (child instanceof HTMLStyleElement) return false;
|
|
689
|
+
if (shouldPreserveElement(child)) return false;
|
|
690
|
+
return true;
|
|
691
|
+
});
|
|
692
|
+
if (oldChildren.length === 1 && oldChildren[0] instanceof HTMLElement && content instanceof HTMLElement && oldChildren[0].tagName === content.tagName) {
|
|
693
|
+
const oldRoot = oldChildren[0];
|
|
694
|
+
const newRoot = content;
|
|
695
|
+
if (oldRoot === newRoot) {
|
|
696
|
+
} else {
|
|
697
|
+
const cacheManager = RenderContext.getDOMCache();
|
|
698
|
+
if (cacheManager) {
|
|
699
|
+
const oldMetadata = cacheManager.getMetadata(oldRoot);
|
|
700
|
+
const newMetadata = cacheManager.getMetadata(newRoot);
|
|
701
|
+
if (oldMetadata && newMetadata) {
|
|
702
|
+
updateProps(
|
|
703
|
+
oldRoot,
|
|
704
|
+
oldMetadata.props,
|
|
705
|
+
newMetadata.props,
|
|
706
|
+
oldRoot.tagName
|
|
707
|
+
);
|
|
708
|
+
updateChildren(
|
|
709
|
+
oldRoot,
|
|
710
|
+
oldMetadata.children,
|
|
711
|
+
newMetadata.children,
|
|
712
|
+
cacheManager
|
|
713
|
+
);
|
|
714
|
+
} else {
|
|
715
|
+
oldRoot.replaceWith(newRoot);
|
|
716
|
+
}
|
|
717
|
+
} else {
|
|
718
|
+
oldRoot.replaceWith(newRoot);
|
|
719
|
+
}
|
|
881
720
|
}
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
if (focusState && focusState.key && focusState.value !== void 0) {
|
|
885
|
-
const target = content.querySelector(
|
|
886
|
-
`[data-wsx-key="${focusState.key}"]`
|
|
721
|
+
const hasStylesOriginal = this.shadowRoot.adoptedStyleSheets && this.shadowRoot.adoptedStyleSheets.length > 0 || Array.from(this.shadowRoot.childNodes).some(
|
|
722
|
+
(c) => c instanceof HTMLStyleElement
|
|
887
723
|
);
|
|
888
|
-
if (
|
|
889
|
-
|
|
890
|
-
|
|
724
|
+
if (!hasStylesOriginal) {
|
|
725
|
+
const stylesToApply = this._autoStyles || this.config.styles;
|
|
726
|
+
if (stylesToApply) {
|
|
727
|
+
const styleName = this.config.styleName || this.constructor.name;
|
|
728
|
+
StyleManager.applyStyles(this.shadowRoot, styleName, stylesToApply);
|
|
891
729
|
}
|
|
892
730
|
}
|
|
893
|
-
}
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
}
|
|
898
|
-
const oldNodes = Array.from(this.shadowRoot.childNodes).filter((child) => {
|
|
899
|
-
if (child === content) {
|
|
900
|
-
return false;
|
|
901
|
-
}
|
|
902
|
-
if (child instanceof HTMLStyleElement) {
|
|
903
|
-
return false;
|
|
904
|
-
}
|
|
905
|
-
if (shouldPreserveElement(child)) {
|
|
906
|
-
return false;
|
|
731
|
+
} else {
|
|
732
|
+
oldChildren.forEach((child) => child.remove());
|
|
733
|
+
if (content.parentNode !== this.shadowRoot) {
|
|
734
|
+
this.shadowRoot.appendChild(content);
|
|
907
735
|
}
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
if (adoptedStyleSheets.length > 0) {
|
|
916
|
-
this.shadowRoot.adoptedStyleSheets = adoptedStyleSheets;
|
|
917
|
-
} else if (!hasStylesAfterDOM && !hasStyleElementAfterDOM) {
|
|
918
|
-
const stylesToApply = this._autoStyles || this.config.styles;
|
|
919
|
-
if (stylesToApply) {
|
|
920
|
-
const styleName = this.config.styleName || this.constructor.name;
|
|
921
|
-
StyleManager.applyStyles(this.shadowRoot, styleName, stylesToApply);
|
|
736
|
+
const hasStylesAfter = this.shadowRoot.adoptedStyleSheets && this.shadowRoot.adoptedStyleSheets.length > 0 || Array.from(this.shadowRoot.children).some((c) => c instanceof HTMLStyleElement);
|
|
737
|
+
if (!hasStylesAfter) {
|
|
738
|
+
const stylesToApply = this._autoStyles || this.config.styles;
|
|
739
|
+
if (stylesToApply) {
|
|
740
|
+
const styleName = this.config.styleName || this.constructor.name;
|
|
741
|
+
StyleManager.applyStyles(this.shadowRoot, styleName, stylesToApply);
|
|
742
|
+
}
|
|
922
743
|
}
|
|
923
744
|
}
|
|
924
|
-
this.restoreFocusState(focusState);
|
|
925
|
-
this._pendingFocusState = null;
|
|
926
745
|
this.onRendered?.();
|
|
927
746
|
this._isRendering = false;
|
|
928
747
|
} catch (error) {
|
|
@@ -993,10 +812,10 @@ var LightComponent = class extends BaseComponent {
|
|
|
993
812
|
this.insertBefore(styleElement, this.firstChild);
|
|
994
813
|
}
|
|
995
814
|
} else {
|
|
996
|
-
const childrenToRemove = Array.from(this.
|
|
997
|
-
(
|
|
815
|
+
const childrenToRemove = Array.from(this.childNodes).filter(
|
|
816
|
+
(node) => node !== styleElement
|
|
998
817
|
);
|
|
999
|
-
childrenToRemove.forEach((
|
|
818
|
+
childrenToRemove.forEach((node) => node.remove());
|
|
1000
819
|
const content = RenderContext.runInContext(this, () => this.render());
|
|
1001
820
|
this.appendChild(content);
|
|
1002
821
|
if (styleElement && styleElement !== this.firstChild) {
|
|
@@ -1058,21 +877,9 @@ var LightComponent = class extends BaseComponent {
|
|
|
1058
877
|
this._isRendering = false;
|
|
1059
878
|
return;
|
|
1060
879
|
}
|
|
1061
|
-
const focusState = this.captureFocusState();
|
|
1062
|
-
this._pendingFocusState = focusState;
|
|
1063
880
|
const jsxChildren = this.getJSXChildren();
|
|
1064
881
|
try {
|
|
1065
882
|
const newContent = RenderContext.runInContext(this, () => this.render());
|
|
1066
|
-
if (focusState && focusState.key && focusState.value !== void 0) {
|
|
1067
|
-
const target = newContent.querySelector(
|
|
1068
|
-
`[data-wsx-key="${focusState.key}"]`
|
|
1069
|
-
);
|
|
1070
|
-
if (target) {
|
|
1071
|
-
if (target instanceof HTMLInputElement || target instanceof HTMLTextAreaElement) {
|
|
1072
|
-
target.value = focusState.value;
|
|
1073
|
-
}
|
|
1074
|
-
}
|
|
1075
|
-
}
|
|
1076
883
|
const stylesToApply = this._autoStyles || this.config.styles;
|
|
1077
884
|
const styleName = this.config.styleName || this.constructor.name;
|
|
1078
885
|
if (stylesToApply) {
|
|
@@ -1088,60 +895,66 @@ var LightComponent = class extends BaseComponent {
|
|
|
1088
895
|
styleElement.textContent = stylesToApply;
|
|
1089
896
|
}
|
|
1090
897
|
}
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
|
|
1108
|
-
|
|
1109
|
-
|
|
1110
|
-
|
|
1111
|
-
|
|
1112
|
-
|
|
1113
|
-
|
|
1114
|
-
|
|
898
|
+
const allShadowChildren = Array.from(this.childNodes);
|
|
899
|
+
const oldChildren = allShadowChildren.filter((child) => {
|
|
900
|
+
if (stylesToApply && child instanceof HTMLStyleElement && child.getAttribute("data-wsx-light-component") === styleName) {
|
|
901
|
+
return false;
|
|
902
|
+
}
|
|
903
|
+
if (jsxChildren.includes(child)) {
|
|
904
|
+
return false;
|
|
905
|
+
}
|
|
906
|
+
if (shouldPreserveElement(child)) {
|
|
907
|
+
return false;
|
|
908
|
+
}
|
|
909
|
+
return true;
|
|
910
|
+
});
|
|
911
|
+
if (oldChildren.length === 1 && newContent instanceof HTMLElement && oldChildren[0] instanceof HTMLElement && oldChildren[0].tagName === newContent.tagName) {
|
|
912
|
+
const oldRoot = oldChildren[0];
|
|
913
|
+
const newRoot = newContent;
|
|
914
|
+
if (oldRoot !== newRoot) {
|
|
915
|
+
const cacheManager = RenderContext.getDOMCache();
|
|
916
|
+
if (cacheManager) {
|
|
917
|
+
const oldMetadata = cacheManager.getMetadata(oldRoot);
|
|
918
|
+
const newMetadata = cacheManager.getMetadata(newRoot);
|
|
919
|
+
if (oldMetadata && newMetadata) {
|
|
920
|
+
updateProps(
|
|
921
|
+
oldRoot,
|
|
922
|
+
oldMetadata.props,
|
|
923
|
+
newMetadata.props,
|
|
924
|
+
oldRoot.tagName
|
|
925
|
+
);
|
|
926
|
+
updateChildren(
|
|
927
|
+
oldRoot,
|
|
928
|
+
oldMetadata.children,
|
|
929
|
+
newMetadata.children,
|
|
930
|
+
cacheManager
|
|
931
|
+
);
|
|
932
|
+
} else {
|
|
933
|
+
oldRoot.replaceWith(newRoot);
|
|
934
|
+
}
|
|
1115
935
|
} else {
|
|
1116
|
-
|
|
1117
|
-
this.appendChild(newContent);
|
|
936
|
+
oldRoot.replaceWith(newRoot);
|
|
1118
937
|
}
|
|
1119
|
-
} else {
|
|
1120
|
-
oldChildren.forEach((child) => child.remove());
|
|
1121
|
-
this.appendChild(newContent);
|
|
1122
938
|
}
|
|
1123
|
-
|
|
1124
|
-
|
|
1125
|
-
|
|
1126
|
-
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
|
|
1132
|
-
|
|
1133
|
-
|
|
1134
|
-
|
|
1135
|
-
|
|
1136
|
-
|
|
939
|
+
} else {
|
|
940
|
+
oldChildren.forEach((child) => child.remove());
|
|
941
|
+
this.appendChild(newContent);
|
|
942
|
+
}
|
|
943
|
+
if (stylesToApply) {
|
|
944
|
+
let styleEl = this.querySelector(
|
|
945
|
+
`style[data-wsx-light-component="${styleName}"]`
|
|
946
|
+
);
|
|
947
|
+
if (!styleEl) {
|
|
948
|
+
styleEl = document.createElement("style");
|
|
949
|
+
styleEl.setAttribute("data-wsx-light-component", styleName);
|
|
950
|
+
styleEl.textContent = stylesToApply;
|
|
951
|
+
this.insertBefore(styleEl, this.firstChild);
|
|
952
|
+
} else if (styleEl !== this.firstChild) {
|
|
953
|
+
this.insertBefore(styleEl, this.firstChild);
|
|
1137
954
|
}
|
|
1138
|
-
|
|
1139
|
-
|
|
1140
|
-
|
|
1141
|
-
this.onRendered?.();
|
|
1142
|
-
this._isRendering = false;
|
|
1143
|
-
});
|
|
1144
|
-
});
|
|
955
|
+
}
|
|
956
|
+
this.onRendered?.();
|
|
957
|
+
this._isRendering = false;
|
|
1145
958
|
} catch (error) {
|
|
1146
959
|
logger4.error(`[${this.constructor.name}] Error in _rerender:`, error);
|
|
1147
960
|
this.renderError(error);
|
|
@@ -1155,9 +968,15 @@ var LightComponent = class extends BaseComponent {
|
|
|
1155
968
|
* 这些 children 不是 render() 返回的内容,应该保留
|
|
1156
969
|
*/
|
|
1157
970
|
getJSXChildren() {
|
|
1158
|
-
const jsxChildren = Array.from(this.
|
|
1159
|
-
(
|
|
1160
|
-
|
|
971
|
+
const jsxChildren = Array.from(this.childNodes).filter((node) => {
|
|
972
|
+
if (node instanceof HTMLElement) {
|
|
973
|
+
return node.getAttribute("data-wsx-jsx-child") === "true";
|
|
974
|
+
}
|
|
975
|
+
if (node.nodeType === Node.TEXT_NODE) {
|
|
976
|
+
return node.__wsxJsxChild === true;
|
|
977
|
+
}
|
|
978
|
+
return false;
|
|
979
|
+
});
|
|
1161
980
|
return jsxChildren;
|
|
1162
981
|
}
|
|
1163
982
|
/**
|
|
@@ -1168,9 +987,14 @@ var LightComponent = class extends BaseComponent {
|
|
|
1168
987
|
const styleElement = this.querySelector(
|
|
1169
988
|
`style[data-wsx-light-component="${styleName}"]`
|
|
1170
989
|
);
|
|
1171
|
-
Array.from(this.
|
|
1172
|
-
if (
|
|
1173
|
-
|
|
990
|
+
Array.from(this.childNodes).forEach((node) => {
|
|
991
|
+
if (node !== styleElement && !(node instanceof HTMLSlotElement)) {
|
|
992
|
+
if (node instanceof HTMLElement) {
|
|
993
|
+
node.setAttribute("data-wsx-jsx-child", "true");
|
|
994
|
+
} else if (node.nodeType === Node.TEXT_NODE) {
|
|
995
|
+
node.__wsxManaged = true;
|
|
996
|
+
node.__wsxJsxChild = true;
|
|
997
|
+
}
|
|
1174
998
|
}
|
|
1175
999
|
});
|
|
1176
1000
|
}
|
|
@@ -1323,6 +1147,7 @@ function state(targetOrContext, propertyKey) {
|
|
|
1323
1147
|
throw new Error(createBabelPluginError(propertyName));
|
|
1324
1148
|
}
|
|
1325
1149
|
export {
|
|
1150
|
+
BaseComponent,
|
|
1326
1151
|
Fragment,
|
|
1327
1152
|
LightComponent,
|
|
1328
1153
|
StyleManager,
|