thunderous 2.3.4 → 2.3.6
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.cjs +87 -94
- package/dist/index.js +87 -94
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
@@ -87,11 +87,15 @@ var createSignal = (initVal, options) => {
|
|
87
87
|
if (!isBatchingUpdates) {
|
88
88
|
isBatchingUpdates = true;
|
89
89
|
queueMicrotask(() => {
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
90
|
+
while (updateQueue.size > 0) {
|
91
|
+
const updates = Array.from(updateQueue);
|
92
|
+
updateQueue.clear();
|
93
|
+
for (const fn of updates) {
|
94
|
+
try {
|
95
|
+
fn();
|
96
|
+
} catch (error) {
|
97
|
+
console.error("Error in subscriber:", { error, oldValue, newValue, fn });
|
98
|
+
}
|
95
99
|
}
|
96
100
|
}
|
97
101
|
if (options?.debugMode === true || setterOptions?.debugMode === true) {
|
@@ -106,7 +110,6 @@ var createSignal = (initVal, options) => {
|
|
106
110
|
}
|
107
111
|
console.log("Signal set:", { oldValue, newValue, subscribers, label });
|
108
112
|
}
|
109
|
-
updateQueue.clear();
|
110
113
|
isBatchingUpdates = false;
|
111
114
|
});
|
112
115
|
}
|
@@ -448,9 +451,7 @@ var evaluateBindings = (element, fragment) => {
|
|
448
451
|
child.replaceWith(childFragment);
|
449
452
|
}
|
450
453
|
} else if (child instanceof Element) {
|
451
|
-
const
|
452
|
-
const attrSetQueue = [];
|
453
|
-
for (const attr of child.attributes) {
|
454
|
+
for (const attr of [...child.attributes]) {
|
454
455
|
const attrName = attr.name;
|
455
456
|
if (SIGNAL_BINDING_REGEX.test(attr.value)) {
|
456
457
|
const textList = attr.value.split(SIGNAL_BINDING_REGEX);
|
@@ -470,12 +471,12 @@ var evaluateBindings = (element, fragment) => {
|
|
470
471
|
}
|
471
472
|
}
|
472
473
|
if (hasNull && newText === "null" || attrName.startsWith("prop:")) {
|
473
|
-
|
474
|
+
child.removeAttribute(attrName);
|
474
475
|
} else {
|
475
|
-
|
476
|
+
child.setAttribute(attrName, newText);
|
476
477
|
}
|
477
478
|
if (attrName.startsWith("prop:")) {
|
478
|
-
|
479
|
+
child.removeAttribute(attrName);
|
479
480
|
const propName = attrName.replace("prop:", "");
|
480
481
|
const newValue = hasNull && newText === "null" ? null : newText;
|
481
482
|
if (!(propName in child)) logPropertyWarning(propName, child);
|
@@ -502,27 +503,21 @@ var evaluateBindings = (element, fragment) => {
|
|
502
503
|
}
|
503
504
|
}
|
504
505
|
if (uniqueKey !== "" && !attrName.startsWith("prop:")) {
|
505
|
-
|
506
|
+
child.setAttribute(attrName, `this.__customCallbackFns.get('${uniqueKey}')(event)`);
|
506
507
|
} else if (attrName.startsWith("prop:")) {
|
507
|
-
|
508
|
+
child.removeAttribute(attrName);
|
508
509
|
const propName = attrName.replace("prop:", "");
|
509
510
|
if (!(propName in child)) logPropertyWarning(propName, child);
|
510
511
|
child[propName] = child.__customCallbackFns.get(uniqueKey);
|
511
512
|
}
|
512
513
|
});
|
513
514
|
} else if (attrName.startsWith("prop:")) {
|
514
|
-
|
515
|
+
child.removeAttribute(attrName);
|
515
516
|
const propName = attrName.replace("prop:", "");
|
516
517
|
if (!(propName in child)) logPropertyWarning(propName, child);
|
517
518
|
child[propName] = attr.value;
|
518
519
|
}
|
519
520
|
}
|
520
|
-
for (const attrName of attrRemoveQueue) {
|
521
|
-
child.removeAttribute(attrName);
|
522
|
-
}
|
523
|
-
for (const [name, value] of attrSetQueue) {
|
524
|
-
child.setAttribute(name, value);
|
525
|
-
}
|
526
521
|
evaluateBindings(child, fragment);
|
527
522
|
}
|
528
523
|
}
|
@@ -592,6 +587,7 @@ var css = (strings, ...values) => {
|
|
592
587
|
};
|
593
588
|
|
594
589
|
// src/custom-element.ts
|
590
|
+
var ANY_BINDING_REGEX = /(\{\{.+:.+\}\})/;
|
595
591
|
var customElement = (render, options) => {
|
596
592
|
const _options = { ...DEFAULT_RENDER_OPTIONS, ...options };
|
597
593
|
const {
|
@@ -686,6 +682,46 @@ var customElement = (render, options) => {
|
|
686
682
|
}
|
687
683
|
}
|
688
684
|
});
|
685
|
+
#getPropSignal = ((prop, { allowUndefined = false } = {}) => {
|
686
|
+
if (!(prop in this.#propSignals)) this.#propSignals[prop] = createSignal();
|
687
|
+
const [_getter, _setter] = this.#propSignals[prop];
|
688
|
+
let setFromProp = false;
|
689
|
+
const setter = (newValue) => {
|
690
|
+
if (!setFromProp) this[prop] = newValue;
|
691
|
+
_setter(newValue);
|
692
|
+
};
|
693
|
+
const getter = () => {
|
694
|
+
const value = _getter();
|
695
|
+
if (value === void 0 && !allowUndefined) {
|
696
|
+
const error = new Error(
|
697
|
+
`Error accessing property: "${prop}"
|
698
|
+
You must set an initial value before calling a property signal's getter.
|
699
|
+
`
|
700
|
+
);
|
701
|
+
console.error(error);
|
702
|
+
throw error;
|
703
|
+
}
|
704
|
+
return value;
|
705
|
+
};
|
706
|
+
getter.getter = true;
|
707
|
+
const descriptor = Object.getOwnPropertyDescriptor(this, prop);
|
708
|
+
if (descriptor === void 0) {
|
709
|
+
Object.defineProperty(this, prop, {
|
710
|
+
get: getter,
|
711
|
+
set: (newValue) => {
|
712
|
+
setFromProp = true;
|
713
|
+
_setter(newValue);
|
714
|
+
setFromProp = false;
|
715
|
+
}
|
716
|
+
});
|
717
|
+
}
|
718
|
+
const publicSignal = [getter, setter];
|
719
|
+
publicSignal.init = (value) => {
|
720
|
+
_setter(value);
|
721
|
+
return [getter, setter];
|
722
|
+
};
|
723
|
+
return publicSignal;
|
724
|
+
}).bind(this);
|
689
725
|
#render() {
|
690
726
|
const root = this.#shadowRoot ?? this;
|
691
727
|
renderState.currentShadowRoot = this.#shadowRoot;
|
@@ -729,43 +765,7 @@ var customElement = (render, options) => {
|
|
729
765
|
}
|
730
766
|
),
|
731
767
|
propSignals: new Proxy({}, {
|
732
|
-
get: (_, prop) =>
|
733
|
-
if (!(prop in this.#propSignals)) this.#propSignals[prop] = createSignal();
|
734
|
-
const [_getter, _setter] = this.#propSignals[prop];
|
735
|
-
let setFromProp = false;
|
736
|
-
const setter = (newValue) => {
|
737
|
-
if (!setFromProp) this[prop] = newValue;
|
738
|
-
_setter(newValue);
|
739
|
-
};
|
740
|
-
const getter = () => {
|
741
|
-
const value = _getter();
|
742
|
-
if (value === void 0) {
|
743
|
-
const error = new Error(
|
744
|
-
`Error accessing property: "${prop}"
|
745
|
-
You must set an initial value before calling a property signal's getter.
|
746
|
-
`
|
747
|
-
);
|
748
|
-
console.error(error);
|
749
|
-
throw error;
|
750
|
-
}
|
751
|
-
return value;
|
752
|
-
};
|
753
|
-
getter.getter = true;
|
754
|
-
Object.defineProperty(this, prop, {
|
755
|
-
get: getter,
|
756
|
-
set: (newValue) => {
|
757
|
-
setFromProp = true;
|
758
|
-
_setter(newValue);
|
759
|
-
setFromProp = false;
|
760
|
-
}
|
761
|
-
});
|
762
|
-
const publicSignal = [getter, setter];
|
763
|
-
publicSignal.init = (value) => {
|
764
|
-
_setter(value);
|
765
|
-
return [getter, setter];
|
766
|
-
};
|
767
|
-
return publicSignal;
|
768
|
-
},
|
768
|
+
get: (_, prop) => this.#getPropSignal(prop),
|
769
769
|
set: () => {
|
770
770
|
console.error("Signals must be assigned via setters.");
|
771
771
|
return false;
|
@@ -822,6 +822,27 @@ You must set an initial value before calling a property signal's getter.
|
|
822
822
|
constructor() {
|
823
823
|
try {
|
824
824
|
super();
|
825
|
+
if (!Object.prototype.hasOwnProperty.call(this, "__customCallbackFns")) {
|
826
|
+
this.__customCallbackFns = /* @__PURE__ */ new Map();
|
827
|
+
}
|
828
|
+
for (const attr of this.attributes) {
|
829
|
+
this.#attrSignals[attr.name] = createSignal(attr.value);
|
830
|
+
}
|
831
|
+
for (const [attrName, attr] of this.#attributesAsPropertiesMap) {
|
832
|
+
if (!(attrName in this.#attrSignals)) this.#attrSignals[attrName] = createSignal(null);
|
833
|
+
const propName = attr.prop;
|
834
|
+
const [getter] = this.#getPropSignal(propName, { allowUndefined: true });
|
835
|
+
createEffect(() => {
|
836
|
+
const value = getter();
|
837
|
+
if (value === void 0) return;
|
838
|
+
if (value !== null) {
|
839
|
+
this.setAttribute(attrName, String(value));
|
840
|
+
} else {
|
841
|
+
this.removeAttribute(attrName);
|
842
|
+
}
|
843
|
+
});
|
844
|
+
}
|
845
|
+
this.#render();
|
825
846
|
} catch (error) {
|
826
847
|
const _error = new Error(
|
827
848
|
"Error instantiating element:\nThis usually occurs if you have errors in the function body of your component. Check prior logs for possible causes.\n",
|
@@ -830,41 +851,6 @@ You must set an initial value before calling a property signal's getter.
|
|
830
851
|
console.error(_error);
|
831
852
|
throw _error;
|
832
853
|
}
|
833
|
-
if (!Object.prototype.hasOwnProperty.call(this, "__customCallbackFns")) {
|
834
|
-
this.__customCallbackFns = /* @__PURE__ */ new Map();
|
835
|
-
}
|
836
|
-
for (const [attrName, attr] of this.#attributesAsPropertiesMap) {
|
837
|
-
this.#attrSignals[attrName] = createSignal(null);
|
838
|
-
Object.defineProperty(this, attr.prop, {
|
839
|
-
get: () => {
|
840
|
-
if (!(attrName in this.#attrSignals)) this.#attrSignals[attrName] = createSignal(null);
|
841
|
-
const [getter] = this.#attrSignals[attrName];
|
842
|
-
const raw = getter();
|
843
|
-
const rawOnly = raw !== null && attr.value === null;
|
844
|
-
const value = rawOnly ? attr.coerce(raw) : attr.value;
|
845
|
-
return value === null ? null : value;
|
846
|
-
},
|
847
|
-
set: (newValue) => {
|
848
|
-
const oldValue = attr.value;
|
849
|
-
attr.value = newValue;
|
850
|
-
if (!(attrName in this.#attrSignals)) this.#attrSignals[attrName] = createSignal(null);
|
851
|
-
const [, attrSetter] = this.#attrSignals[attrName];
|
852
|
-
const [, propSetter] = this.#propSignals[attrName];
|
853
|
-
const attrValue = newValue === null ? null : String(newValue);
|
854
|
-
if (String(oldValue) === attrValue) return;
|
855
|
-
attrSetter(attrValue);
|
856
|
-
propSetter(newValue);
|
857
|
-
if (attrValue === null) this.removeAttribute(attrName);
|
858
|
-
else this.setAttribute(attrName, attrValue);
|
859
|
-
},
|
860
|
-
configurable: true,
|
861
|
-
enumerable: true
|
862
|
-
});
|
863
|
-
}
|
864
|
-
for (const attr of this.attributes) {
|
865
|
-
this.#attrSignals[attr.name] = createSignal(attr.value);
|
866
|
-
}
|
867
|
-
this.#render();
|
868
854
|
}
|
869
855
|
connectedCallback() {
|
870
856
|
if (this.#observer !== null) {
|
@@ -882,12 +868,19 @@ You must set an initial value before calling a property signal's getter.
|
|
882
868
|
fn();
|
883
869
|
}
|
884
870
|
}
|
871
|
+
#attributesBusy = false;
|
885
872
|
attributeChangedCallback(name, oldValue, newValue) {
|
873
|
+
if (this.#attributesBusy || ANY_BINDING_REGEX.test(newValue ?? "")) return;
|
886
874
|
const [, attrSetter] = this.#attrSignals[name] ?? [];
|
887
875
|
attrSetter?.(newValue);
|
888
876
|
const prop = this.#attributesAsPropertiesMap.get(name);
|
889
877
|
if (prop !== void 0) {
|
890
|
-
|
878
|
+
const propName = prop.prop;
|
879
|
+
this.#attributesBusy = true;
|
880
|
+
const [, propSetter] = this.#getPropSignal(propName);
|
881
|
+
const propValue = newValue === null ? null : prop.coerce(newValue);
|
882
|
+
propSetter(propValue);
|
883
|
+
this.#attributesBusy = false;
|
891
884
|
}
|
892
885
|
for (const fn of this.#attributeChangedFns) {
|
893
886
|
fn(name, oldValue, newValue);
|
package/dist/index.js
CHANGED
@@ -52,11 +52,15 @@ var createSignal = (initVal, options) => {
|
|
52
52
|
if (!isBatchingUpdates) {
|
53
53
|
isBatchingUpdates = true;
|
54
54
|
queueMicrotask(() => {
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
55
|
+
while (updateQueue.size > 0) {
|
56
|
+
const updates = Array.from(updateQueue);
|
57
|
+
updateQueue.clear();
|
58
|
+
for (const fn of updates) {
|
59
|
+
try {
|
60
|
+
fn();
|
61
|
+
} catch (error) {
|
62
|
+
console.error("Error in subscriber:", { error, oldValue, newValue, fn });
|
63
|
+
}
|
60
64
|
}
|
61
65
|
}
|
62
66
|
if (options?.debugMode === true || setterOptions?.debugMode === true) {
|
@@ -71,7 +75,6 @@ var createSignal = (initVal, options) => {
|
|
71
75
|
}
|
72
76
|
console.log("Signal set:", { oldValue, newValue, subscribers, label });
|
73
77
|
}
|
74
|
-
updateQueue.clear();
|
75
78
|
isBatchingUpdates = false;
|
76
79
|
});
|
77
80
|
}
|
@@ -413,9 +416,7 @@ var evaluateBindings = (element, fragment) => {
|
|
413
416
|
child.replaceWith(childFragment);
|
414
417
|
}
|
415
418
|
} else if (child instanceof Element) {
|
416
|
-
const
|
417
|
-
const attrSetQueue = [];
|
418
|
-
for (const attr of child.attributes) {
|
419
|
+
for (const attr of [...child.attributes]) {
|
419
420
|
const attrName = attr.name;
|
420
421
|
if (SIGNAL_BINDING_REGEX.test(attr.value)) {
|
421
422
|
const textList = attr.value.split(SIGNAL_BINDING_REGEX);
|
@@ -435,12 +436,12 @@ var evaluateBindings = (element, fragment) => {
|
|
435
436
|
}
|
436
437
|
}
|
437
438
|
if (hasNull && newText === "null" || attrName.startsWith("prop:")) {
|
438
|
-
|
439
|
+
child.removeAttribute(attrName);
|
439
440
|
} else {
|
440
|
-
|
441
|
+
child.setAttribute(attrName, newText);
|
441
442
|
}
|
442
443
|
if (attrName.startsWith("prop:")) {
|
443
|
-
|
444
|
+
child.removeAttribute(attrName);
|
444
445
|
const propName = attrName.replace("prop:", "");
|
445
446
|
const newValue = hasNull && newText === "null" ? null : newText;
|
446
447
|
if (!(propName in child)) logPropertyWarning(propName, child);
|
@@ -467,27 +468,21 @@ var evaluateBindings = (element, fragment) => {
|
|
467
468
|
}
|
468
469
|
}
|
469
470
|
if (uniqueKey !== "" && !attrName.startsWith("prop:")) {
|
470
|
-
|
471
|
+
child.setAttribute(attrName, `this.__customCallbackFns.get('${uniqueKey}')(event)`);
|
471
472
|
} else if (attrName.startsWith("prop:")) {
|
472
|
-
|
473
|
+
child.removeAttribute(attrName);
|
473
474
|
const propName = attrName.replace("prop:", "");
|
474
475
|
if (!(propName in child)) logPropertyWarning(propName, child);
|
475
476
|
child[propName] = child.__customCallbackFns.get(uniqueKey);
|
476
477
|
}
|
477
478
|
});
|
478
479
|
} else if (attrName.startsWith("prop:")) {
|
479
|
-
|
480
|
+
child.removeAttribute(attrName);
|
480
481
|
const propName = attrName.replace("prop:", "");
|
481
482
|
if (!(propName in child)) logPropertyWarning(propName, child);
|
482
483
|
child[propName] = attr.value;
|
483
484
|
}
|
484
485
|
}
|
485
|
-
for (const attrName of attrRemoveQueue) {
|
486
|
-
child.removeAttribute(attrName);
|
487
|
-
}
|
488
|
-
for (const [name, value] of attrSetQueue) {
|
489
|
-
child.setAttribute(name, value);
|
490
|
-
}
|
491
486
|
evaluateBindings(child, fragment);
|
492
487
|
}
|
493
488
|
}
|
@@ -557,6 +552,7 @@ var css = (strings, ...values) => {
|
|
557
552
|
};
|
558
553
|
|
559
554
|
// src/custom-element.ts
|
555
|
+
var ANY_BINDING_REGEX = /(\{\{.+:.+\}\})/;
|
560
556
|
var customElement = (render, options) => {
|
561
557
|
const _options = { ...DEFAULT_RENDER_OPTIONS, ...options };
|
562
558
|
const {
|
@@ -651,6 +647,46 @@ var customElement = (render, options) => {
|
|
651
647
|
}
|
652
648
|
}
|
653
649
|
});
|
650
|
+
#getPropSignal = ((prop, { allowUndefined = false } = {}) => {
|
651
|
+
if (!(prop in this.#propSignals)) this.#propSignals[prop] = createSignal();
|
652
|
+
const [_getter, _setter] = this.#propSignals[prop];
|
653
|
+
let setFromProp = false;
|
654
|
+
const setter = (newValue) => {
|
655
|
+
if (!setFromProp) this[prop] = newValue;
|
656
|
+
_setter(newValue);
|
657
|
+
};
|
658
|
+
const getter = () => {
|
659
|
+
const value = _getter();
|
660
|
+
if (value === void 0 && !allowUndefined) {
|
661
|
+
const error = new Error(
|
662
|
+
`Error accessing property: "${prop}"
|
663
|
+
You must set an initial value before calling a property signal's getter.
|
664
|
+
`
|
665
|
+
);
|
666
|
+
console.error(error);
|
667
|
+
throw error;
|
668
|
+
}
|
669
|
+
return value;
|
670
|
+
};
|
671
|
+
getter.getter = true;
|
672
|
+
const descriptor = Object.getOwnPropertyDescriptor(this, prop);
|
673
|
+
if (descriptor === void 0) {
|
674
|
+
Object.defineProperty(this, prop, {
|
675
|
+
get: getter,
|
676
|
+
set: (newValue) => {
|
677
|
+
setFromProp = true;
|
678
|
+
_setter(newValue);
|
679
|
+
setFromProp = false;
|
680
|
+
}
|
681
|
+
});
|
682
|
+
}
|
683
|
+
const publicSignal = [getter, setter];
|
684
|
+
publicSignal.init = (value) => {
|
685
|
+
_setter(value);
|
686
|
+
return [getter, setter];
|
687
|
+
};
|
688
|
+
return publicSignal;
|
689
|
+
}).bind(this);
|
654
690
|
#render() {
|
655
691
|
const root = this.#shadowRoot ?? this;
|
656
692
|
renderState.currentShadowRoot = this.#shadowRoot;
|
@@ -694,43 +730,7 @@ var customElement = (render, options) => {
|
|
694
730
|
}
|
695
731
|
),
|
696
732
|
propSignals: new Proxy({}, {
|
697
|
-
get: (_, prop) =>
|
698
|
-
if (!(prop in this.#propSignals)) this.#propSignals[prop] = createSignal();
|
699
|
-
const [_getter, _setter] = this.#propSignals[prop];
|
700
|
-
let setFromProp = false;
|
701
|
-
const setter = (newValue) => {
|
702
|
-
if (!setFromProp) this[prop] = newValue;
|
703
|
-
_setter(newValue);
|
704
|
-
};
|
705
|
-
const getter = () => {
|
706
|
-
const value = _getter();
|
707
|
-
if (value === void 0) {
|
708
|
-
const error = new Error(
|
709
|
-
`Error accessing property: "${prop}"
|
710
|
-
You must set an initial value before calling a property signal's getter.
|
711
|
-
`
|
712
|
-
);
|
713
|
-
console.error(error);
|
714
|
-
throw error;
|
715
|
-
}
|
716
|
-
return value;
|
717
|
-
};
|
718
|
-
getter.getter = true;
|
719
|
-
Object.defineProperty(this, prop, {
|
720
|
-
get: getter,
|
721
|
-
set: (newValue) => {
|
722
|
-
setFromProp = true;
|
723
|
-
_setter(newValue);
|
724
|
-
setFromProp = false;
|
725
|
-
}
|
726
|
-
});
|
727
|
-
const publicSignal = [getter, setter];
|
728
|
-
publicSignal.init = (value) => {
|
729
|
-
_setter(value);
|
730
|
-
return [getter, setter];
|
731
|
-
};
|
732
|
-
return publicSignal;
|
733
|
-
},
|
733
|
+
get: (_, prop) => this.#getPropSignal(prop),
|
734
734
|
set: () => {
|
735
735
|
console.error("Signals must be assigned via setters.");
|
736
736
|
return false;
|
@@ -787,6 +787,27 @@ You must set an initial value before calling a property signal's getter.
|
|
787
787
|
constructor() {
|
788
788
|
try {
|
789
789
|
super();
|
790
|
+
if (!Object.prototype.hasOwnProperty.call(this, "__customCallbackFns")) {
|
791
|
+
this.__customCallbackFns = /* @__PURE__ */ new Map();
|
792
|
+
}
|
793
|
+
for (const attr of this.attributes) {
|
794
|
+
this.#attrSignals[attr.name] = createSignal(attr.value);
|
795
|
+
}
|
796
|
+
for (const [attrName, attr] of this.#attributesAsPropertiesMap) {
|
797
|
+
if (!(attrName in this.#attrSignals)) this.#attrSignals[attrName] = createSignal(null);
|
798
|
+
const propName = attr.prop;
|
799
|
+
const [getter] = this.#getPropSignal(propName, { allowUndefined: true });
|
800
|
+
createEffect(() => {
|
801
|
+
const value = getter();
|
802
|
+
if (value === void 0) return;
|
803
|
+
if (value !== null) {
|
804
|
+
this.setAttribute(attrName, String(value));
|
805
|
+
} else {
|
806
|
+
this.removeAttribute(attrName);
|
807
|
+
}
|
808
|
+
});
|
809
|
+
}
|
810
|
+
this.#render();
|
790
811
|
} catch (error) {
|
791
812
|
const _error = new Error(
|
792
813
|
"Error instantiating element:\nThis usually occurs if you have errors in the function body of your component. Check prior logs for possible causes.\n",
|
@@ -795,41 +816,6 @@ You must set an initial value before calling a property signal's getter.
|
|
795
816
|
console.error(_error);
|
796
817
|
throw _error;
|
797
818
|
}
|
798
|
-
if (!Object.prototype.hasOwnProperty.call(this, "__customCallbackFns")) {
|
799
|
-
this.__customCallbackFns = /* @__PURE__ */ new Map();
|
800
|
-
}
|
801
|
-
for (const [attrName, attr] of this.#attributesAsPropertiesMap) {
|
802
|
-
this.#attrSignals[attrName] = createSignal(null);
|
803
|
-
Object.defineProperty(this, attr.prop, {
|
804
|
-
get: () => {
|
805
|
-
if (!(attrName in this.#attrSignals)) this.#attrSignals[attrName] = createSignal(null);
|
806
|
-
const [getter] = this.#attrSignals[attrName];
|
807
|
-
const raw = getter();
|
808
|
-
const rawOnly = raw !== null && attr.value === null;
|
809
|
-
const value = rawOnly ? attr.coerce(raw) : attr.value;
|
810
|
-
return value === null ? null : value;
|
811
|
-
},
|
812
|
-
set: (newValue) => {
|
813
|
-
const oldValue = attr.value;
|
814
|
-
attr.value = newValue;
|
815
|
-
if (!(attrName in this.#attrSignals)) this.#attrSignals[attrName] = createSignal(null);
|
816
|
-
const [, attrSetter] = this.#attrSignals[attrName];
|
817
|
-
const [, propSetter] = this.#propSignals[attrName];
|
818
|
-
const attrValue = newValue === null ? null : String(newValue);
|
819
|
-
if (String(oldValue) === attrValue) return;
|
820
|
-
attrSetter(attrValue);
|
821
|
-
propSetter(newValue);
|
822
|
-
if (attrValue === null) this.removeAttribute(attrName);
|
823
|
-
else this.setAttribute(attrName, attrValue);
|
824
|
-
},
|
825
|
-
configurable: true,
|
826
|
-
enumerable: true
|
827
|
-
});
|
828
|
-
}
|
829
|
-
for (const attr of this.attributes) {
|
830
|
-
this.#attrSignals[attr.name] = createSignal(attr.value);
|
831
|
-
}
|
832
|
-
this.#render();
|
833
819
|
}
|
834
820
|
connectedCallback() {
|
835
821
|
if (this.#observer !== null) {
|
@@ -847,12 +833,19 @@ You must set an initial value before calling a property signal's getter.
|
|
847
833
|
fn();
|
848
834
|
}
|
849
835
|
}
|
836
|
+
#attributesBusy = false;
|
850
837
|
attributeChangedCallback(name, oldValue, newValue) {
|
838
|
+
if (this.#attributesBusy || ANY_BINDING_REGEX.test(newValue ?? "")) return;
|
851
839
|
const [, attrSetter] = this.#attrSignals[name] ?? [];
|
852
840
|
attrSetter?.(newValue);
|
853
841
|
const prop = this.#attributesAsPropertiesMap.get(name);
|
854
842
|
if (prop !== void 0) {
|
855
|
-
|
843
|
+
const propName = prop.prop;
|
844
|
+
this.#attributesBusy = true;
|
845
|
+
const [, propSetter] = this.#getPropSignal(propName);
|
846
|
+
const propValue = newValue === null ? null : prop.coerce(newValue);
|
847
|
+
propSetter(propValue);
|
848
|
+
this.#attributesBusy = false;
|
856
849
|
}
|
857
850
|
for (const fn of this.#attributeChangedFns) {
|
858
851
|
fn(name, oldValue, newValue);
|