@@ -6,12 +6,11 @@ import {
66 setInsertionState ,
77} from '../insertionState'
88import {
9- _child ,
109 disableHydrationNodeLookup ,
1110 enableHydrationNodeLookup ,
1211 next ,
1312} from './node'
14- import { isDynamicAnchor , isVaporFragmentEndAnchor } from '@vue/shared'
13+ import { isVaporAnchors , isVaporFragmentAnchor } from '@vue/shared'
1514
1615export let isHydrating = false
1716export let currentHydrationNode : Node | null = null
@@ -33,7 +32,6 @@ function performHydration<T>(
3332
3433 // optimize anchor cache lookup
3534 ; ( Comment . prototype as any ) . $fs = undefined
36- ; ( Node . prototype as any ) . $nc = undefined
3735 isOptimized = true
3836 }
3937 enableHydrationNodeLookup ( )
@@ -101,24 +99,29 @@ function adoptTemplateImpl(node: Node, template: string): Node | null {
10199 return node
102100}
103101
102+ const hydrationPositionMap = new WeakMap < ParentNode , Node > ( )
103+
104104function locateHydrationNodeImpl ( hasFragmentAnchor ?: boolean ) {
105105 let node : Node | null
106106 // prepend / firstChild
107107 if ( insertionAnchor === 0 ) {
108- node = _child ( insertionParent ! )
108+ node = insertionParent ! . firstChild
109109 } else if ( insertionAnchor ) {
110- // for dynamic children, use insertionAnchor as the node
110+ // `insertionAnchor` is a Node, it is the DOM node to hydrate
111+ // Template: `...<span/><!----><span/>...`// `insertionAnchor` is the placeholder
112+ // SSR Output: `...<span/>Content<span/>...`// `insertionAnchor` is the actual node
111113 node = insertionAnchor
112114 } else {
113115 node = insertionParent
114- ? insertionParent . $nc || insertionParent . lastChild
116+ ? hydrationPositionMap . get ( insertionParent ) || insertionParent . lastChild
115117 : currentHydrationNode
116118
117- // if the last child is a vapor fragment end anchor, find the previous one
118- if ( hasFragmentAnchor && node && isVaporFragmentEndAnchor ( node ) ) {
119+ // if node is a vapor fragment anchor, find the previous one
120+ if ( hasFragmentAnchor && node && isVaporFragmentAnchor ( node ) ) {
119121 node = node . previousSibling
120122 if ( __DEV__ && ! node ) {
121- // TODO warning, should not happen
123+ // this should not happen
124+ throw new Error ( `vapor fragment anchor previous node was not found.` )
122125 }
123126 }
124127
@@ -153,7 +156,8 @@ function locateHydrationNodeImpl(hasFragmentAnchor?: boolean) {
153156 }
154157
155158 if ( insertionParent && node ) {
156- insertionParent . $nc = node ! . previousSibling
159+ const prev = node . previousSibling
160+ if ( prev ) hydrationPositionMap . set ( insertionParent , prev )
157161 }
158162 }
159163
@@ -166,10 +170,6 @@ function locateHydrationNodeImpl(hasFragmentAnchor?: boolean) {
166170 currentHydrationNode = node
167171}
168172
169- export function isEmptyText ( node : Node ) : node is Text {
170- return node . nodeType === 3 && ! ( node as Text ) . data . trim ( )
171- }
172-
173173export function locateEndAnchor (
174174 node : Node | null ,
175175 open = '[' ,
@@ -194,26 +194,26 @@ export function locateEndAnchor(
194194
195195export function isNonHydrationNode ( node : Node ) : boolean {
196196 return (
197- // empty text nodes
198- isEmptyText ( node ) ||
199- // dynamic node anchors (<!--[[-->, <!--]]-->)
200- isDynamicAnchor ( node ) ||
201- // fragment end anchor (`<!--]-->`)
197+ // empty text node
198+ isEmptyTextNode ( node ) ||
199+ // vdom fragment end anchor (`<!--]-->`)
202200 isComment ( node , ']' ) ||
203- // vapor fragment end anchors
204- isVaporFragmentEndAnchor ( node )
201+ // vapor mode specific anchors
202+ isVaporAnchors ( node )
205203 )
206204}
207205
208- export function findVaporFragmentAnchor (
206+ export function locateVaporFragmentAnchor (
209207 node : Node ,
210208 anchorLabel : string ,
211- ) : Comment | null {
209+ ) : Comment | undefined {
212210 let n = node . nextSibling
213211 while ( n ) {
214212 if ( isComment ( n , anchorLabel ) ) return n
215213 n = n . nextSibling
216214 }
215+ }
217216
218- return null
217+ export function isEmptyTextNode ( node : Node ) : node is Text {
218+ return node . nodeType === 3 && ! ( node as Text ) . data . trim ( )
219219}
0 commit comments