@sigil-dev/runtime 0.9.5 → 0.9.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/index.ts +72 -1
- package/package.json +1 -1
package/index.ts
CHANGED
|
@@ -699,7 +699,10 @@ export function hydrateKeyedList<T>(
|
|
|
699
699
|
return { anchor, keyMap };
|
|
700
700
|
}
|
|
701
701
|
|
|
702
|
-
export function insert(
|
|
702
|
+
export function insert(
|
|
703
|
+
parent: Element | DocumentFragment,
|
|
704
|
+
value: unknown,
|
|
705
|
+
): void {
|
|
703
706
|
if (value === false || value === null || value === undefined) return;
|
|
704
707
|
if (typeof value === "function") {
|
|
705
708
|
insert(parent, value());
|
|
@@ -716,6 +719,74 @@ export function insert(parent: Element, value: unknown): void {
|
|
|
716
719
|
parent.append(String(value));
|
|
717
720
|
}
|
|
718
721
|
|
|
722
|
+
/**
|
|
723
|
+
* Hydrate a `<!--g-->…<!--/g-->` slot.
|
|
724
|
+
*
|
|
725
|
+
* Consumes the delimiter pair and the SSR content between them from `nodes`,
|
|
726
|
+
* then runs `value` against that content as its hydration pool. Component
|
|
727
|
+
* children are compiled to thunks precisely so this call — not the caller's
|
|
728
|
+
* pool — decides what they claim: `<Wrap><Item/></Wrap>` puts `Item`'s SSR
|
|
729
|
+
* markup inside `Wrap`'s root, which the caller cannot see.
|
|
730
|
+
*
|
|
731
|
+
* SSR left no slot (SPA navigation renders into empty elements): fall back to
|
|
732
|
+
* a fresh `insert`.
|
|
733
|
+
*/
|
|
734
|
+
export function hydrateSlot(
|
|
735
|
+
nodes: ChildNode[],
|
|
736
|
+
parent: Element | DocumentFragment,
|
|
737
|
+
value: unknown,
|
|
738
|
+
): void {
|
|
739
|
+
let open = -1;
|
|
740
|
+
for (let i = 0; i < nodes.length; i++) {
|
|
741
|
+
const node = nodes[i];
|
|
742
|
+
if (node instanceof Comment && node.data === "g") {
|
|
743
|
+
open = i;
|
|
744
|
+
break;
|
|
745
|
+
}
|
|
746
|
+
}
|
|
747
|
+
if (open === -1) {
|
|
748
|
+
insert(parent, value);
|
|
749
|
+
return;
|
|
750
|
+
}
|
|
751
|
+
let close = open + 1;
|
|
752
|
+
while (close < nodes.length) {
|
|
753
|
+
const node = nodes[close];
|
|
754
|
+
if (node instanceof Comment && node.data === "/g") break;
|
|
755
|
+
close++;
|
|
756
|
+
}
|
|
757
|
+
const inner = nodes.slice(open + 1, close);
|
|
758
|
+
// Drop the whole run so later siblings can't claim slot content.
|
|
759
|
+
nodes.splice(open, close - open + 1);
|
|
760
|
+
pushHydrationNodes(inner);
|
|
761
|
+
try {
|
|
762
|
+
attachHydrated(parent, value);
|
|
763
|
+
} finally {
|
|
764
|
+
popHydrationNodes();
|
|
765
|
+
}
|
|
766
|
+
}
|
|
767
|
+
|
|
768
|
+
/**
|
|
769
|
+
* Realize a slot value that already has SSR markup in the DOM: run thunks,
|
|
770
|
+
* skip primitives (their text is already rendered), and append only nodes
|
|
771
|
+
* that hydration created fresh instead of claiming.
|
|
772
|
+
*/
|
|
773
|
+
function attachHydrated(
|
|
774
|
+
parent: Element | DocumentFragment,
|
|
775
|
+
value: unknown,
|
|
776
|
+
): void {
|
|
777
|
+
if (typeof value === "function") {
|
|
778
|
+
attachHydrated(parent, (value as () => unknown)());
|
|
779
|
+
return;
|
|
780
|
+
}
|
|
781
|
+
if (Array.isArray(value)) {
|
|
782
|
+
for (const item of value) attachHydrated(parent, item);
|
|
783
|
+
return;
|
|
784
|
+
}
|
|
785
|
+
if (value instanceof Node && value.parentNode !== parent) {
|
|
786
|
+
parent.appendChild(value);
|
|
787
|
+
}
|
|
788
|
+
}
|
|
789
|
+
|
|
719
790
|
/**
|
|
720
791
|
* Apply a use: directive to an element.
|
|
721
792
|
* The directive function receives (element, params) and may return a cleanup function.
|