-
Notifications
You must be signed in to change notification settings - Fork 595
/
main.ts
71 lines (65 loc) · 1.93 KB
/
main.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
import { ComponentType, h, options, render } from "preact";
import { assetHashingHook } from "./utils.ts";
function createRootFragment(
parent: Element,
replaceNode: Node | Node[],
) {
replaceNode = ([] as Node[]).concat(replaceNode);
const s = replaceNode[replaceNode.length - 1].nextSibling;
function insert(c: Node, r: Node) {
parent.insertBefore(c, r || s);
}
// @ts-ignore this is fine
return parent.__k = {
nodeType: 1,
parentNode: parent,
firstChild: replaceNode[0],
childNodes: replaceNode,
insertBefore: insert,
appendChild: insert,
removeChild: function (c: Node) {
parent.removeChild(c);
},
};
}
// deno-lint-ignore no-explicit-any
export function revive(islands: Record<string, ComponentType>, props: any[]) {
function walk(node: Node | null) {
const tag = node!.nodeType === 8 &&
((node as Comment).data.match(/^\s*frsh-(.*)\s*$/) || [])[1];
let endNode: Node | null = null;
if (tag) {
const startNode = node!;
const children = [];
const parent = node!.parentNode;
// collect all children of the island
while ((node = node!.nextSibling) && node.nodeType !== 8) {
children.push(node);
}
startNode.parentNode!.removeChild(startNode); // remove start tag node
const [id, n] = tag.split(":");
render(
h(islands[id], props[Number(n)]),
createRootFragment(
parent! as HTMLElement,
children,
// deno-lint-ignore no-explicit-any
) as any as HTMLElement,
);
endNode = node;
}
const sib = node!.nextSibling;
const fc = node!.firstChild;
if (endNode) {
endNode.parentNode?.removeChild(endNode); // remove end tag node
}
if (sib) walk(sib);
if (fc) walk(fc);
}
walk(document.body);
}
const originalHook = options.vnode;
options.vnode = (vnode) => {
assetHashingHook(vnode);
if (originalHook) originalHook(vnode);
};