daiwei 1 rok temu
rodzic
commit
7a842ab6cb

+ 9 - 4
packages/compiler-ssr/src/ssrCodegenTransform.ts

@@ -302,8 +302,8 @@ function processChildrenDynamicInfo(
     const child = filteredChildren[i]
     if (
       isStaticChildNode(child) ||
-      // v-if has an anchor, which can be used to distinguish the boundary
-      child.type === NodeTypes.IF
+      // fragment has it's own anchor, which can be used to distinguish the boundary
+      isFragmentChild(child)
     ) {
       continue
     }
@@ -359,10 +359,10 @@ function processChildrenDynamicInfo(
 }
 
 /**
- * Check if a node should be processed as dynamic.
+ * Check if a node should be processed as dynamic child.
  * This is primarily used in Vapor mode hydration to wrap dynamic parts
  * with markers (`<!--[[-->` and `<!--]]-->`).
- * The purpose is to distinguish the boundaries of nodes during hydration
+ * The purpose is to distinguish the boundaries of nodes during vapor hydration
  *
  * 1. two consecutive dynamic nodes should only wrap the second one
  * <element>
@@ -416,3 +416,8 @@ function shouldProcessChildAsDynamic(
 
   return false
 }
+
+function isFragmentChild(child: TemplateChildNode): boolean {
+  const { type } = child
+  return type === NodeTypes.IF || type === NodeTypes.FOR
+}

+ 3 - 3
packages/runtime-core/src/hydration.ts

@@ -26,13 +26,13 @@ import {
   includeBooleanAttr,
   isBooleanAttr,
   isDynamicAnchor,
-  isDynamicFragmentEndAnchor,
   isKnownHtmlAttr,
   isKnownSvgAttr,
   isOn,
   isRenderableAttrValue,
   isReservedProp,
   isString,
+  isVaporFragmentEndAnchor,
   normalizeClass,
   normalizeStyle,
   stringifyStyle,
@@ -126,7 +126,7 @@ export function createHydrationFunctions(
     // skip if:
     // - dynamic anchors (`<!--[[-->`, `<!--][-->`)
     // - dynamic fragment end anchors (e.g. `<!--if-->`, `<!--for-->`)
-    if (n && (isDynamicAnchor(n) || isDynamicFragmentEndAnchor(n))) {
+    if (n && (isDynamicAnchor(n) || isVaporFragmentEndAnchor(n))) {
       n = next(n)
     }
     return n
@@ -158,7 +158,7 @@ export function createHydrationFunctions(
     slotScopeIds: string[] | null,
     optimized = false,
   ): Node | null => {
-    if (isDynamicAnchor(node) || isDynamicFragmentEndAnchor(node)) {
+    if (isDynamicAnchor(node) || isVaporFragmentEndAnchor(node)) {
       node = nextSibling(node)!
     }
     optimized = optimized || !!vnode.dynamicChildren

Plik diff jest za duży
+ 528 - 519
packages/runtime-vapor/__tests__/hydration.spec.ts


+ 6 - 2
packages/runtime-vapor/src/apiCreateFor.ts

@@ -16,7 +16,11 @@ import {
   isObject,
   isString,
 } from '@vue/shared'
-import { createComment, createTextNode, nextSiblingAnchor } from './dom/node'
+import {
+  createComment,
+  createTextNode,
+  nextVaporFragmentAnchor,
+} from './dom/node'
 import {
   type Block,
   VaporFragment,
@@ -97,7 +101,7 @@ export const createFor = (
   let parent: ParentNode | undefined | null
   const parentAnchor = isHydrating
     ? // Use fragment end anchor if available, otherwise use the specific for anchor.
-      nextSiblingAnchor(
+      nextVaporFragmentAnchor(
         currentHydrationNode!,
         isComment(currentHydrationNode!, '[') ? ']' : FOR_ANCHOR_LABEL,
       )!

+ 8 - 4
packages/runtime-vapor/src/block.ts

@@ -1,11 +1,15 @@
-import { isArray, isDynamicFragmentEndAnchor } from '@vue/shared'
+import { isArray, isVaporFragmentEndAnchor } from '@vue/shared'
 import {
   type VaporComponentInstance,
   isVaporComponent,
   mountComponent,
   unmountComponent,
 } from './component'
-import { createComment, createTextNode, nextSiblingAnchor } from './dom/node'
+import {
+  createComment,
+  createTextNode,
+  nextVaporFragmentAnchor,
+} from './dom/node'
 import { EffectScope, pauseTracking, resetTracking } from '@vue/reactivity'
 import {
   currentHydrationNode,
@@ -95,8 +99,8 @@ export class DynamicFragment extends VaporFragment {
       this.anchor = currentHydrationNode
     } else {
       // find next sibling dynamic fragment end anchor
-      const anchor = nextSiblingAnchor(currentHydrationNode!, label)!
-      if (anchor && isDynamicFragmentEndAnchor(anchor)) {
+      const anchor = nextVaporFragmentAnchor(currentHydrationNode!, label)!
+      if (anchor && isVaporFragmentEndAnchor(anchor)) {
         this.anchor = anchor
       } else if (__DEV__) {
         // TODO warning

+ 5 - 28
packages/runtime-vapor/src/dom/hydration.ts

@@ -11,7 +11,7 @@ import {
   enableHydrationNodeLookup,
   next,
 } from './node'
-import { isDynamicFragmentEndAnchor } from '@vue/shared'
+import { isVaporFragmentEndAnchor } from '@vue/shared'
 
 export let isHydrating = false
 export let currentHydrationNode: Node | null = null
@@ -83,7 +83,7 @@ function adoptTemplateImpl(node: Node, template: string): Node | null {
   return node
 }
 
-function locateHydrationNodeImpl(isFragment?: boolean) {
+function locateHydrationNodeImpl(hasFragmentAnchor?: boolean) {
   let node: Node | null
   // prepend / firstChild
   if (insertionAnchor === 0) {
@@ -94,10 +94,9 @@ function locateHydrationNodeImpl(isFragment?: boolean) {
   } else {
     node = insertionParent ? insertionParent.lastChild : currentHydrationNode
 
-    // if the last child is a comment, it is the anchor for the fragment
-    // so it need to find the previous node
-    if (isFragment && node && isDynamicFragmentEndAnchor(node)) {
-      let previous = node.previousSibling //prev(node)
+    // if the last child is a vapor fragment end anchor, find the previous one
+    if (hasFragmentAnchor && node && isVaporFragmentEndAnchor(node)) {
+      let previous = node.previousSibling
       if (previous) node = previous
     }
 
@@ -166,25 +165,3 @@ export function locateEndAnchor(
   }
   return null
 }
-
-export function locateStartAnchor(
-  node: Node | null,
-  open = '[',
-  close = ']',
-): Node | null {
-  let match = 0
-  while (node) {
-    if (node.nodeType === 8) {
-      if ((node as Comment).data === close) match++
-      if ((node as Comment).data === open) {
-        if (match === 0) {
-          return node
-        } else {
-          match--
-        }
-      }
-    }
-    node = node.previousSibling
-  }
-  return null
-}

+ 5 - 34
packages/runtime-vapor/src/dom/node.ts

@@ -1,14 +1,9 @@
-import {
-  isComment,
-  isEmptyText,
-  locateEndAnchor,
-  locateStartAnchor,
-} from './hydration'
+import { isComment, isEmptyText, locateEndAnchor } from './hydration'
 import {
   DYNAMIC_END_ANCHOR_LABEL,
   DYNAMIC_START_ANCHOR_LABEL,
   isDynamicAnchor,
-  isDynamicFragmentEndAnchor,
+  isVaporFragmentEndAnchor,
 } from '@vue/shared'
 
 /*! #__NO_SIDE_EFFECTS__ */
@@ -104,30 +99,6 @@ export function disableHydrationNodeLookup(): void {
   nthChild.impl = _nthChild
 }
 
-/*! #__NO_SIDE_EFFECTS__ */
-// TODO check if this is still needed
-export function prev(node: Node): Node | null {
-  // process dynamic node (<!--[[-->...<!--]]-->) as a single one
-  if (isComment(node, DYNAMIC_END_ANCHOR_LABEL)) {
-    node = locateStartAnchor(
-      node,
-      DYNAMIC_START_ANCHOR_LABEL,
-      DYNAMIC_END_ANCHOR_LABEL,
-    )!
-  }
-
-  // process fragment node (<!--[-->...<!--]-->) as a single one
-  else if (isComment(node, ']')) {
-    node = locateStartAnchor(node)!
-  }
-
-  let n = node.previousSibling
-  while (n && isNonHydrationNode(n)) {
-    n = n.previousSibling
-  }
-  return n
-}
-
 function isNonHydrationNode(node: Node) {
   return (
     // empty text nodes, no need to hydrate
@@ -136,12 +107,12 @@ function isNonHydrationNode(node: Node) {
     isDynamicAnchor(node) ||
     // fragment end anchor (`<!--]-->`)
     isComment(node, ']') ||
-    // dynamic fragment end anchors
-    isDynamicFragmentEndAnchor(node)
+    // vapor fragment end anchors
+    isVaporFragmentEndAnchor(node)
   )
 }
 
-export function nextSiblingAnchor(
+export function nextVaporFragmentAnchor(
   node: Node,
   anchorLabel: string,
 ): Comment | null {

+ 5 - 7
packages/shared/src/domAnchors.ts

@@ -1,12 +1,10 @@
 export const DYNAMIC_START_ANCHOR_LABEL = '[['
 export const DYNAMIC_END_ANCHOR_LABEL = ']]'
 
-export const IF_ANCHOR_LABEL: string = __DEV__ ? 'if' : '$'
-export const DYNAMIC_COMPONENT_ANCHOR_LABEL: string = __DEV__
-  ? 'dynamic-component'
-  : '$2'
-export const FOR_ANCHOR_LABEL: string = __DEV__ ? 'for' : '$3'
-export const SLOT_ANCHOR_LABEL: string = __DEV__ ? 'slot' : '$4'
+export const IF_ANCHOR_LABEL: string = 'if'
+export const DYNAMIC_COMPONENT_ANCHOR_LABEL: string = 'dynamic-component'
+export const FOR_ANCHOR_LABEL: string = 'for'
+export const SLOT_ANCHOR_LABEL: string = 'slot'
 
 export function isDynamicAnchor(node: Node): node is Comment {
   if (node.nodeType !== 8) return false
@@ -17,7 +15,7 @@ export function isDynamicAnchor(node: Node): node is Comment {
   )
 }
 
-export function isDynamicFragmentEndAnchor(node: Node): node is Comment {
+export function isVaporFragmentEndAnchor(node: Node): node is Comment {
   if (node.nodeType !== 8) return false
 
   const data = (node as Comment).data

Niektóre pliki nie zostały wyświetlone z powodu dużej ilości zmienionych plików