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'
83
94/*! #__NO_SIDE_EFFECTS__ */
105export function createTextNode ( value = '' ) : Text {
@@ -27,9 +22,12 @@ export function child(node: ParentNode): Node {
2722}
2823
2924/*! #__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+ }
3228
29+ /*! #__NO_SIDE_EFFECTS__ */
30+ export function __nthChild ( node : Node , i : number ) : Node {
3331 let n = node . firstChild !
3432 for ( let start = 0 ; start < i ; start ++ ) {
3533 n = next ( n ) as ChildNode
@@ -38,9 +36,12 @@ export function nthChild(node: Node, i: number): Node {
3836}
3937
4038/*! #__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+ }
4342
43+ /*! #__NO_SIDE_EFFECTS__ */
44+ function __next ( node : Node ) : Node {
4445 // process fragment as a single node
4546 if ( node && isComment ( node , '[' ) ) {
4647 node = locateEndAnchor ( node ) !
@@ -53,3 +54,46 @@ export function next(node: Node): Node {
5354 }
5455 return n
5556}
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