1
- import {
2
- isComment ,
3
- isDynamicAnchor ,
4
- isEmptyText ,
5
- isHydrating ,
6
- locateEndAnchor ,
7
- } from './hydration'
1
+ import { isDynamicAnchor } from '@vue/runtime-dom'
2
+ import { isComment , isEmptyText , locateEndAnchor } from './hydration'
8
3
9
4
/*! #__NO_SIDE_EFFECTS__ */
10
5
export function createTextNode ( value = '' ) : Text {
@@ -27,9 +22,12 @@ export function child(node: ParentNode): Node {
27
22
}
28
23
29
24
/*! #__NO_SIDE_EFFECTS__ */
30
- export function nthChild ( node : Node , i : number ) : Node {
31
- if ( ! isHydrating ) return node . childNodes [ i ]
25
+ export function _nthChild ( node : Node , i : number ) : Node {
26
+ return node . childNodes [ i ]
27
+ }
32
28
29
+ /*! #__NO_SIDE_EFFECTS__ */
30
+ export function __nthChild ( node : Node , i : number ) : Node {
33
31
let n = node . firstChild !
34
32
for ( let start = 0 ; start < i ; start ++ ) {
35
33
n = next ( n ) as ChildNode
@@ -38,9 +36,12 @@ export function nthChild(node: Node, i: number): Node {
38
36
}
39
37
40
38
/*! #__NO_SIDE_EFFECTS__ */
41
- export function next ( node : Node ) : Node {
42
- if ( ! isHydrating ) return node . nextSibling !
39
+ function _next ( node : Node ) : Node {
40
+ return node . nextSibling !
41
+ }
43
42
43
+ /*! #__NO_SIDE_EFFECTS__ */
44
+ function __next ( node : Node ) : Node {
44
45
// process fragment as a single node
45
46
if ( node && isComment ( node , '[' ) ) {
46
47
node = locateEndAnchor ( node ) !
@@ -53,3 +54,46 @@ export function next(node: Node): Node {
53
54
}
54
55
return n
55
56
}
57
+
58
+ type NextFn = ( node : Node ) => Node
59
+ type NthChildFn = ( node : Node , i : number ) => Node
60
+
61
+ interface DelegatedNextFunction extends NextFn {
62
+ impl : NextFn
63
+ }
64
+ interface DelegatedNthChildFunction extends NthChildFn {
65
+ impl : NthChildFn
66
+ }
67
+
68
+ /*! #__NO_SIDE_EFFECTS__ */
69
+ export const next : DelegatedNextFunction = node => {
70
+ return next . impl ( node )
71
+ }
72
+ next . impl = _next
73
+
74
+ /*! #__NO_SIDE_EFFECTS__ */
75
+ export const nthChild : DelegatedNthChildFunction = ( node , i ) => {
76
+ return nthChild . impl ( node , i )
77
+ }
78
+ nthChild . impl = _nthChild
79
+
80
+ // During hydration, there might be differences between the server-rendered (SSR)
81
+ // HTML and the client-side template.
82
+ // For example, a dynamic node `<!>` in the template might be rendered as a
83
+ // Fragment (`<!--[-->...<!--]-->`) in the SSR output.
84
+ // The content of the Fragment affects the lookup results of the `next` and
85
+ // `nthChild` functions.
86
+ // To ensure the hydration process correctly finds nodes, we need to treat the
87
+ // Fragment as a single node.
88
+ // Therefore, during hydration, we need to temporarily switch the implementations
89
+ // of `next` and `nthChild`. After hydration is complete, their implementations
90
+ // are restored to the original versions.
91
+ export function preHydration ( ) : void {
92
+ next . impl = __next
93
+ nthChild . impl = __nthChild
94
+ }
95
+
96
+ export function postHydration ( ) : void {
97
+ next . impl = _next
98
+ nthChild . impl = _nthChild
99
+ }
0 commit comments