Просмотр исходного кода

refactor(runtime-vapor): replace DelegatedFunction pattern with inline hydration checks (#14574)

edison 1 месяц назад
Родитель
Сommit
75f58caf21
2 измененных файлов с 31 добавлено и 94 удалено
  1. 0 4
      packages/runtime-vapor/src/dom/hydration.ts
  2. 31 90
      packages/runtime-vapor/src/dom/node.ts

+ 0 - 4
packages/runtime-vapor/src/dom/hydration.ts

@@ -15,8 +15,6 @@ import {
   _next,
   createElement,
   createTextNode,
-  disableHydrationNodeLookup,
-  enableHydrationNodeLookup,
   locateChildByLogicalIndex,
   parentNode,
 } from './node'
@@ -66,14 +64,12 @@ function performHydration<T>(
 
     isOptimized = true
   }
-  enableHydrationNodeLookup()
   const prev = setIsHydrating(true)
   setup()
   const res = fn()
   cleanup()
   currentHydrationNode = null
   setIsHydrating(prev)
-  if (!isHydrating) disableHydrationNodeLookup()
   return res
 }
 

+ 31 - 90
packages/runtime-vapor/src/dom/node.ts

@@ -1,5 +1,5 @@
 import type { ChildItem, InsertionParent } from '../insertionState'
-import { isComment, locateEndAnchor } from './hydration'
+import { isComment, isHydrating, locateEndAnchor } from './hydration'
 
 /*@__NO_SIDE_EFFECTS__*/
 export function createElement(tagName: string): HTMLElement {
@@ -26,48 +26,50 @@ export function parentNode(node: Node): ParentNode | null {
   return node.parentNode
 }
 
-const _txt: typeof _child = _child
-
-/**
- * Hydration-specific version of `txt`.
- */
 /*@__NO_SIDE_EFFECTS__*/
-const __txt = (node: ParentNode): Node => {
-  let n = node.firstChild!
-
-  // since SSR doesn't generate blank text nodes,
-  // manually insert a text node as the first child
-  if (!n) {
-    return node.appendChild(createTextNode())
+export function txt(node: ParentNode): Node {
+  if (isHydrating) {
+    // since SSR doesn't generate blank text nodes,
+    // manually insert a text node as the first child
+    let n = _child(node)
+    if (!n) {
+      return node.appendChild(createTextNode())
+    }
+    return n
   }
-
-  return n
+  return _child(node)
 }
 
 /*@__NO_SIDE_EFFECTS__*/
-export function _child(node: InsertionParent): Node {
-  return node.firstChild!
+export function child(node: InsertionParent, logicalIndex?: number): Node {
+  if (isHydrating) {
+    return locateChildByLogicalIndex(node, logicalIndex ?? 0)!
+  }
+  return _child(node)
 }
 
-/**
- * Hydration-specific version of `child`.
- */
 /*@__NO_SIDE_EFFECTS__*/
-export function __child(node: ParentNode, logicalIndex: number = 0): Node {
-  return locateChildByLogicalIndex(node as InsertionParent, logicalIndex)!
+export function nthChild(node: InsertionParent, i: number): Node {
+  if (isHydrating) {
+    return locateChildByLogicalIndex(node, i)!
+  }
+  return node.childNodes[i]
 }
 
 /*@__NO_SIDE_EFFECTS__*/
-export function _nthChild(node: InsertionParent, i: number): Node {
-  return node.childNodes[i]
+export function next(node: Node, logicalIndex?: number): Node {
+  if (isHydrating) {
+    return locateChildByLogicalIndex(
+      node.parentNode! as InsertionParent,
+      logicalIndex!,
+    )!
+  }
+  return _next(node)
 }
 
-/**
- * Hydration-specific version of `nthChild`.
- */
 /*@__NO_SIDE_EFFECTS__*/
-export function __nthChild(node: Node, logicalIndex: number): Node {
-  return locateChildByLogicalIndex(node as InsertionParent, logicalIndex)!
+export function _child(node: InsertionParent): Node {
+  return node.firstChild!
 }
 
 /*@__NO_SIDE_EFFECTS__*/
@@ -75,67 +77,6 @@ export function _next(node: Node): Node {
   return node.nextSibling!
 }
 
-/**
- * Hydration-specific version of `next`.
- */
-/*@__NO_SIDE_EFFECTS__*/
-export function __next(node: Node, logicalIndex: number): Node {
-  return locateChildByLogicalIndex(
-    node.parentNode! as InsertionParent,
-    logicalIndex,
-  )!
-}
-
-type DelegatedFunction<T extends (...args: any[]) => any> = T & {
-  impl: T
-}
-
-/*@__NO_SIDE_EFFECTS__*/
-export const txt: DelegatedFunction<typeof _txt> = (...args) => {
-  return txt.impl(...args)
-}
-txt.impl = _txt
-
-/*@__NO_SIDE_EFFECTS__*/
-export const child: DelegatedFunction<typeof _child> = (...args) => {
-  return child.impl(...args)
-}
-child.impl = _child
-
-/*@__NO_SIDE_EFFECTS__*/
-export const next: DelegatedFunction<typeof _next> = (...args) => {
-  return next.impl(...args)
-}
-next.impl = _next
-
-/*@__NO_SIDE_EFFECTS__*/
-export const nthChild: DelegatedFunction<typeof _nthChild> = (...args) => {
-  return nthChild.impl(...args)
-}
-nthChild.impl = _nthChild
-
-/**
- * Enables hydration-specific node lookup behavior.
- *
- * Temporarily switches the implementations of the exported
- * `txt`, `child`, `next`, and `nthChild` functions to their hydration-specific
- * versions (`__txt`, `__child`, `__next`, `__nthChild`). This allows traversal
- * logic to correctly handle SSR comment anchors during hydration.
- */
-export function enableHydrationNodeLookup(): void {
-  txt.impl = __txt
-  child.impl = __child as typeof _child
-  next.impl = __next as typeof _next
-  nthChild.impl = __nthChild as any as typeof _nthChild
-}
-
-export function disableHydrationNodeLookup(): void {
-  txt.impl = _txt
-  child.impl = _child
-  next.impl = _next
-  nthChild.impl = _nthChild
-}
-
 export function locateChildByLogicalIndex(
   parent: InsertionParent,
   logicalIndex: number,