@wsxjs/wsx-core 0.0.26 → 0.0.28

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/jsx.js CHANGED
@@ -85,6 +85,17 @@ function flattenChildren(children, skipHTMLDetection = false, depth = 0) {
85
85
  } else {
86
86
  result.push(child);
87
87
  }
88
+ } else if (child instanceof DocumentFragment) {
89
+ const fragmentChildren = Array.from(child.childNodes);
90
+ for (const fragChild of fragmentChildren) {
91
+ if (fragChild instanceof HTMLElement || fragChild instanceof SVGElement) {
92
+ result.push(fragChild);
93
+ } else if (fragChild.nodeType === Node.TEXT_NODE) {
94
+ result.push(fragChild.textContent || "");
95
+ } else if (fragChild instanceof DocumentFragment) {
96
+ result.push(...flattenChildren([fragChild], skipHTMLDetection, depth + 1));
97
+ }
98
+ }
88
99
  } else {
89
100
  result.push(child);
90
101
  }
@@ -185,7 +196,7 @@ function isCreatedByH(element) {
185
196
  }
186
197
  function shouldPreserveElement(element) {
187
198
  if (!(element instanceof HTMLElement || element instanceof SVGElement)) {
188
- return true;
199
+ return false;
189
200
  }
190
201
  if (!isCreatedByH(element)) {
191
202
  return true;
@@ -549,7 +560,7 @@ function setSmartProperty(element, key, value, tag) {
549
560
 
550
561
  // src/utils/element-creation.ts
551
562
  function applySingleProp(element, key, value, tag, isSVG) {
552
- if (value === null || value === void 0 || value === false) {
563
+ if (value === null || value === void 0) {
553
564
  return;
554
565
  }
555
566
  if (key === "ref" && typeof value === "function") {
@@ -578,6 +589,31 @@ function applySingleProp(element, key, value, tag, isSVG) {
578
589
  if (typeof value === "boolean") {
579
590
  if (value) {
580
591
  element.setAttribute(key, "");
592
+ if (element instanceof HTMLInputElement) {
593
+ if (key === "checked") {
594
+ element.checked = true;
595
+ } else if (key === "disabled") {
596
+ element.disabled = true;
597
+ } else if (key === "readonly") {
598
+ element.readOnly = true;
599
+ }
600
+ } else if (element instanceof HTMLOptionElement && key === "selected") {
601
+ element.selected = true;
602
+ }
603
+ } else {
604
+ const attributeName = isSVG ? getSVGAttributeName(key) : key;
605
+ element.removeAttribute(attributeName);
606
+ if (element instanceof HTMLInputElement) {
607
+ if (key === "checked") {
608
+ element.checked = false;
609
+ } else if (key === "disabled") {
610
+ element.disabled = false;
611
+ } else if (key === "readonly") {
612
+ element.readOnly = false;
613
+ }
614
+ } else if (element instanceof HTMLOptionElement && key === "selected") {
615
+ element.selected = false;
616
+ }
581
617
  }
582
618
  return;
583
619
  }
@@ -611,7 +647,9 @@ function appendChildrenToElement(element, children) {
611
647
  return;
612
648
  }
613
649
  if (typeof child === "string" || typeof child === "number") {
614
- element.appendChild(document.createTextNode(String(child)));
650
+ const textNode = document.createTextNode(String(child));
651
+ textNode.__wsxManaged = true;
652
+ element.appendChild(textNode);
615
653
  } else if (child instanceof HTMLElement || child instanceof SVGElement) {
616
654
  element.appendChild(child);
617
655
  } else if (child instanceof DocumentFragment) {
@@ -631,6 +669,9 @@ function collectPreservedElements(element) {
631
669
  const preserved = [];
632
670
  for (let i = 0; i < element.childNodes.length; i++) {
633
671
  const child = element.childNodes[i];
672
+ if (child.nodeType === Node.TEXT_NODE) {
673
+ continue;
674
+ }
634
675
  if (shouldPreserveElement(child)) {
635
676
  preserved.push(child);
636
677
  }
@@ -664,38 +705,40 @@ function findElementNode(oldChild, parent) {
664
705
  }
665
706
  return null;
666
707
  }
667
- function findTextNode(parent, domIndex) {
668
- while (domIndex.value < parent.childNodes.length) {
669
- const node = parent.childNodes[domIndex.value];
670
- if (node.nodeType === Node.TEXT_NODE && node.parentNode === parent) {
671
- const textNode = node;
672
- domIndex.value++;
673
- return textNode;
708
+ function findTextNode(parent, domIndex, processedNodes) {
709
+ for (let i = domIndex.value; i < parent.childNodes.length; i++) {
710
+ const node = parent.childNodes[i];
711
+ if (node.nodeType === Node.TEXT_NODE && node.__wsxManaged === true && !processedNodes.has(node)) {
712
+ domIndex.value = i + 1;
713
+ return node;
674
714
  }
675
- domIndex.value++;
676
715
  }
677
716
  return null;
678
717
  }
679
- function updateOrCreateTextNode(parent, oldNode, newText) {
718
+ function updateOrCreateTextNode(parent, oldNode, newText, insertBeforeNode) {
719
+ if (shouldPreserveElement(parent)) {
720
+ if (oldNode && oldNode.nodeType === Node.TEXT_NODE) {
721
+ return oldNode;
722
+ }
723
+ return document.createTextNode(newText);
724
+ }
680
725
  if (oldNode && oldNode.nodeType === Node.TEXT_NODE) {
681
726
  if (oldNode.textContent !== newText) {
682
727
  oldNode.textContent = newText;
683
728
  }
684
- return oldNode;
685
- } else {
686
- if (!oldNode) {
687
- for (let i = 0; i < parent.childNodes.length; i++) {
688
- const node = parent.childNodes[i];
689
- if (node.nodeType === Node.TEXT_NODE && node.parentNode === parent && node.textContent === newText) {
690
- return node;
691
- }
729
+ if (insertBeforeNode !== void 0) {
730
+ if (oldNode !== insertBeforeNode && oldNode.nextSibling !== insertBeforeNode) {
731
+ parent.insertBefore(oldNode, insertBeforeNode);
692
732
  }
693
733
  }
734
+ return oldNode;
735
+ } else {
694
736
  const newTextNode = document.createTextNode(newText);
737
+ newTextNode.__wsxManaged = true;
695
738
  if (oldNode && !shouldPreserveElement(oldNode)) {
696
739
  parent.replaceChild(newTextNode, oldNode);
697
740
  } else {
698
- parent.insertBefore(newTextNode, oldNode || null);
741
+ parent.insertBefore(newTextNode, insertBeforeNode ?? null);
699
742
  }
700
743
  return newTextNode;
701
744
  }
@@ -705,53 +748,13 @@ function removeNodeIfNotPreserved(parent, node) {
705
748
  parent.removeChild(node);
706
749
  }
707
750
  }
708
- function replaceOrInsertElement(parent, newChild, oldNode) {
709
- const targetNextSibling = oldNode && shouldPreserveElement(oldNode) ? oldNode : oldNode?.nextSibling || null;
710
- replaceOrInsertElementAtPosition(parent, newChild, oldNode, targetNextSibling);
711
- }
712
- function replaceOrInsertElementAtPosition(parent, newChild, oldNode, targetNextSibling) {
713
- if (newChild.parentNode && newChild.parentNode !== parent) {
714
- newChild.parentNode.removeChild(newChild);
715
- }
716
- const isInCorrectPosition = newChild.parentNode === parent && newChild.nextSibling === targetNextSibling;
717
- if (isInCorrectPosition) {
718
- return;
719
- }
720
- if (newChild.parentNode === parent) {
721
- parent.insertBefore(newChild, targetNextSibling);
722
- return;
723
- }
724
- if (oldNode && oldNode.parentNode === parent && !shouldPreserveElement(oldNode)) {
725
- if (oldNode !== newChild) {
726
- parent.replaceChild(newChild, oldNode);
727
- }
728
- } else {
729
- if (newChild.parentNode === parent) {
730
- return;
731
- }
732
- const newChildCacheKey = getElementCacheKey(newChild);
733
- if (!newChildCacheKey) {
734
- const newChildContent = newChild.textContent || "";
735
- const newChildTag = newChild.tagName.toLowerCase();
736
- for (let i = 0; i < parent.childNodes.length; i++) {
737
- const existingNode = parent.childNodes[i];
738
- if (existingNode instanceof HTMLElement || existingNode instanceof SVGElement) {
739
- const existingCacheKey = getElementCacheKey(existingNode);
740
- if (!existingCacheKey && existingNode.tagName.toLowerCase() === newChildTag && existingNode.textContent === newChildContent && existingNode !== newChild) {
741
- return;
742
- }
743
- }
744
- }
745
- }
746
- parent.insertBefore(newChild, targetNextSibling);
747
- }
748
- }
749
751
  function appendNewChild(parent, child, processedNodes) {
750
752
  if (child === null || child === void 0 || child === false) {
751
753
  return;
752
754
  }
753
755
  if (typeof child === "string" || typeof child === "number") {
754
756
  const newTextNode = document.createTextNode(String(child));
757
+ newTextNode.__wsxManaged = true;
755
758
  parent.appendChild(newTextNode);
756
759
  if (processedNodes) {
757
760
  processedNodes.add(newTextNode);
@@ -768,6 +771,11 @@ function appendNewChild(parent, child, processedNodes) {
768
771
  processedNodes.add(child);
769
772
  }
770
773
  } else if (child instanceof DocumentFragment) {
774
+ if (processedNodes) {
775
+ for (let i = 0; i < child.childNodes.length; i++) {
776
+ processedNodes.add(child.childNodes[i]);
777
+ }
778
+ }
771
779
  parent.appendChild(child);
772
780
  }
773
781
  }
@@ -788,21 +796,32 @@ function buildNewChildrenMaps(flatNew) {
788
796
  return { elementSet, cacheKeyMap };
789
797
  }
790
798
  function shouldRemoveNode(node, elementSet, cacheKeyMap, processedNodes) {
799
+ if (node.nodeType === Node.TEXT_NODE) {
800
+ if (node.__wsxManaged === true) {
801
+ if (processedNodes && processedNodes.has(node)) {
802
+ return false;
803
+ }
804
+ return true;
805
+ }
806
+ const parent = node.parentNode;
807
+ if (parent && (parent instanceof HTMLElement || parent instanceof SVGElement)) {
808
+ if (shouldPreserveElement(parent)) {
809
+ return false;
810
+ }
811
+ }
812
+ return true;
813
+ } else {
814
+ if (shouldPreserveElement(node)) {
815
+ return false;
816
+ }
817
+ }
818
+ const isProcessed = processedNodes && processedNodes.has(node);
791
819
  if (shouldPreserveElement(node)) {
792
820
  return false;
793
821
  }
794
- if (node.nodeType === Node.TEXT_NODE && processedNodes && processedNodes.has(node)) {
822
+ if (node.nodeType === Node.TEXT_NODE && isProcessed) {
795
823
  return false;
796
824
  }
797
- if (node.nodeType === Node.TEXT_NODE && processedNodes) {
798
- let parent = node.parentNode;
799
- while (parent) {
800
- if (processedNodes.has(parent) && parent.parentNode) {
801
- return false;
802
- }
803
- parent = parent.parentNode;
804
- }
805
- }
806
825
  if (node instanceof HTMLElement || node instanceof SVGElement || node instanceof DocumentFragment) {
807
826
  if (elementSet.has(node)) {
808
827
  return false;
@@ -844,7 +863,8 @@ function collectNodesToRemove(parent, elementSet, cacheKeyMap, processedNodes) {
844
863
  const nodesToRemove = [];
845
864
  for (let i = 0; i < parent.childNodes.length; i++) {
846
865
  const node = parent.childNodes[i];
847
- if (shouldRemoveNode(node, elementSet, cacheKeyMap, processedNodes)) {
866
+ const removed = shouldRemoveNode(node, elementSet, cacheKeyMap, processedNodes);
867
+ if (removed) {
848
868
  nodesToRemove.push(node);
849
869
  }
850
870
  }
@@ -933,7 +953,7 @@ function removeProp(element, key, oldValue, tag) {
933
953
  }
934
954
  }
935
955
  function applySingleProp2(element, key, value, tag, isSVG) {
936
- if (value === null || value === void 0 || value === false) {
956
+ if (value === null || value === void 0) {
937
957
  return;
938
958
  }
939
959
  if (key === "ref" && typeof value === "function") {
@@ -966,6 +986,31 @@ function applySingleProp2(element, key, value, tag, isSVG) {
966
986
  if (typeof value === "boolean") {
967
987
  if (value) {
968
988
  element.setAttribute(key, "");
989
+ if (element instanceof HTMLInputElement) {
990
+ if (key === "checked") {
991
+ element.checked = true;
992
+ } else if (key === "disabled") {
993
+ element.disabled = true;
994
+ } else if (key === "readonly") {
995
+ element.readOnly = true;
996
+ }
997
+ } else if (element instanceof HTMLOptionElement && key === "selected") {
998
+ element.selected = true;
999
+ }
1000
+ } else {
1001
+ const attributeName = isSVG ? getSVGAttributeName(key) : key;
1002
+ element.removeAttribute(attributeName);
1003
+ if (element instanceof HTMLInputElement) {
1004
+ if (key === "checked") {
1005
+ element.checked = false;
1006
+ } else if (key === "disabled") {
1007
+ element.disabled = false;
1008
+ } else if (key === "readonly") {
1009
+ element.readOnly = false;
1010
+ }
1011
+ } else if (element instanceof HTMLOptionElement && key === "selected") {
1012
+ element.selected = false;
1013
+ }
969
1014
  }
970
1015
  return;
971
1016
  }
@@ -1021,6 +1066,7 @@ function updateChildren(element, oldChildren, newChildren, _cacheManager) {
1021
1066
  const preservedElements = collectPreservedElements(element);
1022
1067
  const minLength = Math.min(flatOld.length, flatNew.length);
1023
1068
  const domIndex = { value: 0 };
1069
+ const insertionIndex = { value: 0 };
1024
1070
  const processedNodes = /* @__PURE__ */ new Set();
1025
1071
  for (let i = 0; i < minLength; i++) {
1026
1072
  const oldChild = flatOld[i];
@@ -1035,40 +1081,54 @@ function updateChildren(element, oldChildren, newChildren, _cacheManager) {
1035
1081
  }
1036
1082
  }
1037
1083
  } else if (typeof oldChild === "string" || typeof oldChild === "number") {
1038
- oldNode = findTextNode(element, domIndex);
1039
- if (!oldNode && element.childNodes.length > 0) {
1040
- const oldText = String(oldChild);
1041
- for (let j = domIndex.value; j < element.childNodes.length; j++) {
1042
- const node = element.childNodes[j];
1043
- if (node.nodeType === Node.TEXT_NODE && node.parentNode === element && node.textContent === oldText) {
1044
- oldNode = node;
1045
- domIndex.value = j + 1;
1046
- break;
1084
+ if (shouldPreserveElement(element)) {
1085
+ oldNode = null;
1086
+ } else {
1087
+ oldNode = findTextNode(element, domIndex, processedNodes);
1088
+ if (oldNode) {
1089
+ const nodeIndex = Array.from(element.childNodes).indexOf(oldNode);
1090
+ if (nodeIndex !== -1 && nodeIndex >= domIndex.value) {
1091
+ domIndex.value = nodeIndex + 1;
1047
1092
  }
1048
1093
  }
1049
1094
  }
1050
1095
  }
1051
1096
  if (typeof oldChild === "string" || typeof oldChild === "number") {
1052
1097
  if (typeof newChild === "string" || typeof newChild === "number") {
1053
- const oldText = String(oldChild);
1054
1098
  const newText = String(newChild);
1055
- const needsUpdate = oldText !== newText || oldNode && oldNode.nodeType === Node.TEXT_NODE && oldNode.textContent !== newText;
1056
- if (needsUpdate) {
1057
- const updatedNode = updateOrCreateTextNode(element, oldNode, newText);
1058
- if (updatedNode && !processedNodes.has(updatedNode)) {
1059
- processedNodes.add(updatedNode);
1060
- }
1061
- } else {
1062
- if (oldNode && oldNode.parentNode === element) {
1063
- processedNodes.add(oldNode);
1064
- }
1099
+ if (shouldPreserveElement(element)) {
1100
+ continue;
1101
+ }
1102
+ const insertBeforeNode = insertionIndex.value < element.childNodes.length ? element.childNodes[insertionIndex.value] : null;
1103
+ const updatedNode = updateOrCreateTextNode(
1104
+ element,
1105
+ oldNode,
1106
+ newText,
1107
+ insertBeforeNode
1108
+ );
1109
+ if (updatedNode) {
1110
+ processedNodes.add(updatedNode);
1111
+ insertionIndex.value++;
1065
1112
  }
1066
1113
  } else {
1067
- removeNodeIfNotPreserved(element, oldNode);
1114
+ const targetNode = insertionIndex.value < element.childNodes.length ? element.childNodes[insertionIndex.value] : null;
1068
1115
  if (newChild instanceof HTMLElement || newChild instanceof SVGElement) {
1069
- replaceOrInsertElement(element, newChild, oldNode);
1116
+ if (oldNode && oldNode === targetNode && oldNode.parentNode === element) {
1117
+ element.replaceChild(newChild, oldNode);
1118
+ } else {
1119
+ element.insertBefore(newChild, targetNode);
1120
+ removeNodeIfNotPreserved(element, oldNode);
1121
+ }
1122
+ processedNodes.add(newChild);
1123
+ insertionIndex.value++;
1070
1124
  } else if (newChild instanceof DocumentFragment) {
1071
- element.insertBefore(newChild, oldNode || null);
1125
+ if (processedNodes) {
1126
+ for (let i2 = 0; i2 < newChild.childNodes.length; i2++) {
1127
+ processedNodes.add(newChild.childNodes[i2]);
1128
+ }
1129
+ }
1130
+ element.insertBefore(newChild, targetNode);
1131
+ removeNodeIfNotPreserved(element, oldNode);
1072
1132
  }
1073
1133
  }
1074
1134
  } else if (oldChild instanceof HTMLElement || oldChild instanceof SVGElement) {
@@ -1076,49 +1136,37 @@ function updateChildren(element, oldChildren, newChildren, _cacheManager) {
1076
1136
  continue;
1077
1137
  }
1078
1138
  if (newChild instanceof HTMLElement || newChild instanceof SVGElement) {
1079
- let targetNextSibling = null;
1080
- let foundPreviousElement = false;
1081
- for (let j = i - 1; j >= 0; j--) {
1082
- const prevChild = flatNew[j];
1083
- if (prevChild instanceof HTMLElement || prevChild instanceof SVGElement) {
1084
- if (prevChild.parentNode === element) {
1085
- targetNextSibling = prevChild.nextSibling;
1086
- foundPreviousElement = true;
1087
- break;
1088
- }
1139
+ const insertBeforeNode = insertionIndex.value < element.childNodes.length ? element.childNodes[insertionIndex.value] : null;
1140
+ if (newChild === oldNode) {
1141
+ if (newChild.nextSibling !== insertBeforeNode) {
1142
+ element.insertBefore(newChild, insertBeforeNode);
1089
1143
  }
1090
- }
1091
- if (!foundPreviousElement) {
1092
- const firstChild = Array.from(element.childNodes).find(
1093
- (node) => !shouldPreserveElement(node) && !processedNodes.has(node)
1094
- );
1095
- targetNextSibling = firstChild || null;
1096
- }
1097
- const isInCorrectPosition = newChild.parentNode === element && newChild.nextSibling === targetNextSibling;
1098
- if (newChild === oldChild && isInCorrectPosition) {
1099
- if (oldNode) processedNodes.add(oldNode);
1100
- processedNodes.add(newChild);
1101
- continue;
1102
- }
1103
- const referenceNode = oldNode && oldNode.parentNode === element ? oldNode : null;
1104
- replaceOrInsertElementAtPosition(
1105
- element,
1106
- newChild,
1107
- referenceNode,
1108
- targetNextSibling
1109
- );
1110
- if (oldNode && oldNode !== newChild) {
1111
- processedNodes.delete(oldNode);
1144
+ } else {
1145
+ element.insertBefore(newChild, insertBeforeNode);
1112
1146
  }
1113
1147
  processedNodes.add(newChild);
1148
+ insertionIndex.value++;
1114
1149
  } else {
1115
- removeNodeIfNotPreserved(element, oldNode);
1150
+ const targetNode = insertionIndex.value < element.childNodes.length ? element.childNodes[insertionIndex.value] : null;
1116
1151
  if (typeof newChild === "string" || typeof newChild === "number") {
1117
1152
  const newTextNode = document.createTextNode(String(newChild));
1118
- element.insertBefore(newTextNode, oldNode?.nextSibling || null);
1153
+ newTextNode.__wsxManaged = true;
1154
+ if (oldNode && oldNode === targetNode && oldNode.parentNode === element) {
1155
+ element.replaceChild(newTextNode, oldNode);
1156
+ } else {
1157
+ element.insertBefore(newTextNode, targetNode);
1158
+ removeNodeIfNotPreserved(element, oldNode);
1159
+ }
1119
1160
  processedNodes.add(newTextNode);
1161
+ insertionIndex.value++;
1120
1162
  } else if (newChild instanceof DocumentFragment) {
1121
- element.insertBefore(newChild, oldNode?.nextSibling || null);
1163
+ if (processedNodes) {
1164
+ for (let i2 = 0; i2 < newChild.childNodes.length; i2++) {
1165
+ processedNodes.add(newChild.childNodes[i2]);
1166
+ }
1167
+ }
1168
+ element.insertBefore(newChild, targetNode);
1169
+ removeNodeIfNotPreserved(element, oldNode);
1122
1170
  }
1123
1171
  }
1124
1172
  }
@@ -1240,7 +1288,9 @@ function Fragment(_props, children) {
1240
1288
  return;
1241
1289
  }
1242
1290
  if (typeof child === "string" || typeof child === "number") {
1243
- fragment.appendChild(document.createTextNode(String(child)));
1291
+ const textNode = document.createTextNode(String(child));
1292
+ textNode.__wsxManaged = true;
1293
+ fragment.appendChild(textNode);
1244
1294
  } else if (child instanceof HTMLElement || child instanceof SVGElement) {
1245
1295
  fragment.appendChild(child);
1246
1296
  } else if (child instanceof DocumentFragment) {
package/dist/jsx.mjs CHANGED
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  Fragment,
3
3
  h
4
- } from "./chunk-5Q2VEEUH.mjs";
4
+ } from "./chunk-34PNC5CJ.mjs";
5
5
  export {
6
6
  Fragment,
7
7
  h