-
Notifications
You must be signed in to change notification settings - Fork 57
Expand file tree
/
Copy pathhydrate.js
More file actions
52 lines (48 loc) · 1.67 KB
/
hydrate.js
File metadata and controls
52 lines (48 loc) · 1.67 KB
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
import { isFalse } from '../shared/nodes'
import { anchorableElement } from './anchorableNode'
import client from './client'
import { ref } from './ref'
let pool = []
function hydrateBody(selector, node) {
if (node?.attributes?.html) {
anchorableElement(selector)
}
node.element = selector
ref(node.attributes, selector)
for (const element of selector.childNodes) {
if ((element.tagName === 'TEXTAREA' || element.tagName === 'textarea') && element.childNodes.length === 0) {
element.appendChild(document.createTextNode(''))
} else if (element.COMMENT_NODE === 8 && element.textContent === '#') {
pool.push(element.remove())
}
}
if (!node.children) return
const limit = node.children.length
for (let i = limit - 1; i > -1; i--) {
if (node.type !== 'head' && typeof selector?.childNodes?.[i] === 'undefined') {
console.error(
`${node.type.toUpperCase()} expected tag ${node.children[
i
].type.toUpperCase()} to be child at index ${i} but instead found undefined. This error usually happens because of an invalid HTML hierarchy or changes in comparisons after serialization.`,
selector,
)
throw new Error('Virtual DOM does not match the DOM.')
}
hydrateBody(selector.childNodes[i], node.children[i])
}
}
function hydrateHead() {
for (const node of client.nextHead) {
if (isFalse(node)) {
node.element = pool.pop() || document.createComment('')
client.head.append(node.element)
} else {
node.element = document.getElementById(node.attributes.id)
}
}
pool = null
}
export default function hydrate(selector, node) {
hydrateBody(selector, node)
hydrateHead()
}