Skip to content

Commit ee8c5be

Browse files
committed
refactor: block anchors
1 parent e52d2ab commit ee8c5be

File tree

9 files changed

+349
-376
lines changed

9 files changed

+349
-376
lines changed

packages/compiler-core/src/ast.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -163,7 +163,7 @@ export interface ComponentNode extends BaseElementNode {
163163
| MemoExpression // when cached by v-memo
164164
| undefined
165165
ssrCodegenNode?: CallExpression
166-
anchor?: string
166+
needAnchor?: boolean
167167
}
168168

169169
export interface SlotOutletNode extends BaseElementNode {
@@ -173,14 +173,14 @@ export interface SlotOutletNode extends BaseElementNode {
173173
| CacheExpression // when cached by v-once
174174
| undefined
175175
ssrCodegenNode?: CallExpression
176-
anchor?: string
176+
needAnchor?: boolean
177177
}
178178

179179
export interface TemplateNode extends BaseElementNode {
180180
tagType: ElementTypes.TEMPLATE
181181
// TemplateNode is a container type that always gets compiled away
182182
codegenNode: undefined
183-
anchor?: string
183+
needAnchor?: boolean
184184
}
185185

186186
export interface TextNode extends Node {
@@ -290,7 +290,7 @@ export interface IfNode extends Node {
290290
type: NodeTypes.IF
291291
branches: IfBranchNode[]
292292
codegenNode?: IfConditionalExpression | CacheExpression // <div v-if v-once>
293-
anchor?: string
293+
needAnchor?: boolean
294294
}
295295

296296
export interface IfBranchNode extends Node {
@@ -310,7 +310,7 @@ export interface ForNode extends Node {
310310
parseResult: ForParseResult
311311
children: TemplateChildNode[]
312312
codegenNode?: ForCodegenNode
313-
anchor?: string
313+
needAnchor?: boolean
314314
}
315315

316316
export interface ForParseResult {

packages/compiler-ssr/__tests__/ssrVaporAnchors.spes.ts

Lines changed: 85 additions & 85 deletions
Large diffs are not rendered by default.

packages/compiler-ssr/src/ssrCodegenTransform.ts

Lines changed: 25 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,8 @@ import {
2525
processExpression,
2626
} from '@vue/compiler-dom'
2727
import {
28-
BLOCK_APPEND_ANCHOR_LABEL,
29-
BLOCK_INSERTION_ANCHOR_LABEL,
30-
BLOCK_PREPEND_ANCHOR_LABEL,
28+
BLOCK_ANCHOR_END_LABEL,
29+
BLOCK_ANCHOR_START_LABEL,
3130
escapeHtml,
3231
isString,
3332
} from '@vue/shared'
@@ -188,14 +187,19 @@ export function processChildren(
188187
ssrProcessElement(child, context)
189188
break
190189
case ElementTypes.COMPONENT:
191-
if (child.anchor) context.pushStringPart(`<!--[${child.anchor}-->`)
190+
if (child.needAnchor)
191+
context.pushStringPart(`<!--${BLOCK_ANCHOR_START_LABEL}-->`)
192192
ssrProcessComponent(child, context, parent)
193-
if (child.anchor) context.pushStringPart(`<!--${child.anchor}]-->`)
193+
if (child.needAnchor)
194+
context.pushStringPart(`<!--${BLOCK_ANCHOR_END_LABEL}-->`)
195+
194196
break
195197
case ElementTypes.SLOT:
196-
if (child.anchor) context.pushStringPart(`<!--[${child.anchor}-->`)
198+
if (child.needAnchor)
199+
context.pushStringPart(`<!--${BLOCK_ANCHOR_START_LABEL}-->`)
197200
ssrProcessSlotOutlet(child, context)
198-
if (child.anchor) context.pushStringPart(`<!--${child.anchor}]-->`)
201+
if (child.needAnchor)
202+
context.pushStringPart(`<!--${BLOCK_ANCHOR_END_LABEL}-->`)
199203
break
200204
case ElementTypes.TEMPLATE:
201205
// TODO
@@ -230,14 +234,18 @@ export function processChildren(
230234
)
231235
break
232236
case NodeTypes.IF:
233-
if (child.anchor) context.pushStringPart(`<!--[${child.anchor}-->`)
237+
if (child.needAnchor)
238+
context.pushStringPart(`<!--${BLOCK_ANCHOR_START_LABEL}-->`)
234239
ssrProcessIf(child, context, disableNestedFragments, disableComment)
235-
if (child.anchor) context.pushStringPart(`<!--${child.anchor}]-->`)
240+
if (child.needAnchor)
241+
context.pushStringPart(`<!--${BLOCK_ANCHOR_END_LABEL}-->`)
236242
break
237243
case NodeTypes.FOR:
238-
if (child.anchor) context.pushStringPart(`<!--[${child.anchor}-->`)
244+
if (child.needAnchor)
245+
context.pushStringPart(`<!--${BLOCK_ANCHOR_START_LABEL}-->`)
239246
ssrProcessFor(child, context, disableNestedFragments)
240-
if (child.anchor) context.pushStringPart(`<!--${child.anchor}]-->`)
247+
if (child.needAnchor)
248+
context.pushStringPart(`<!--${BLOCK_ANCHOR_END_LABEL}-->`)
241249
break
242250
case NodeTypes.IF_BRANCH:
243251
// no-op - handled by ssrProcessIf
@@ -276,7 +284,7 @@ export function processChildrenAsStatement(
276284
}
277285

278286
export function processBlockNodeAnchor(children: TemplateChildNode[]): void {
279-
let prevBlocks: (TemplateChildNode & { anchor?: string })[] = []
287+
let prevBlocks: (TemplateChildNode & { needAnchor?: boolean })[] = []
280288
let hasStaticNode = false
281289
let blockCount = 0
282290
for (const child of children) {
@@ -288,15 +296,11 @@ export function processBlockNodeAnchor(children: TemplateChildNode[]): void {
288296
if (isStaticNode(child)) {
289297
if (prevBlocks.length) {
290298
if (hasStaticNode) {
291-
// insertion anchor
292-
prevBlocks.forEach(
293-
child => (child.anchor = BLOCK_INSERTION_ANCHOR_LABEL),
294-
)
299+
// insert
300+
prevBlocks.forEach(child => (child.needAnchor = true))
295301
} else {
296302
// prepend
297-
prevBlocks.forEach(
298-
child => (child.anchor = BLOCK_PREPEND_ANCHOR_LABEL),
299-
)
303+
prevBlocks.forEach(child => (child.needAnchor = true))
300304
}
301305
prevBlocks = []
302306
}
@@ -307,8 +311,8 @@ export function processBlockNodeAnchor(children: TemplateChildNode[]): void {
307311
// When there is only one block node, no anchor is needed,
308312
// firstChild is used as the hydration node
309313
if (prevBlocks.length && !(blockCount === 1 && !hasStaticNode)) {
310-
// append anchor
311-
prevBlocks.forEach(child => (child.anchor = BLOCK_APPEND_ANCHOR_LABEL))
314+
// append
315+
prevBlocks.forEach(child => (child.needAnchor = true))
312316
}
313317
}
314318

packages/compiler-ssr/src/transforms/ssrTransformComponent.ts

Lines changed: 27 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ import {
77
DOMDirectiveTransforms,
88
DOMNodeTransforms,
99
type DirectiveNode,
10-
type ElementNode,
1110
ElementTypes,
1211
type ExpressionNode,
1312
type ForNode,
@@ -63,6 +62,8 @@ import {
6362
ssrTransformTransitionGroup,
6463
} from './ssrTransformTransitionGroup'
6564
import {
65+
BLOCK_ANCHOR_END_LABEL,
66+
BLOCK_ANCHOR_START_LABEL,
6667
DYNAMIC_COMPONENT_ANCHOR_LABEL,
6768
FOR_ANCHOR_LABEL,
6869
IF_ANCHOR_LABEL,
@@ -417,14 +418,14 @@ function injectVaporAnchors(
417418
}
418419

419420
const { tagType, props } = child
420-
let insertionAnchor: string | undefined
421+
let needBlockAnchor: boolean | undefined
421422

422423
if (
423424
tagType === ElementTypes.COMPONENT ||
424425
tagType === ElementTypes.SLOT ||
425426
tagType === ElementTypes.TEMPLATE
426427
) {
427-
insertionAnchor = child.anchor
428+
needBlockAnchor = child.needAnchor
428429
} else if (tagType === ElementTypes.ELEMENT) {
429430
let hasIf = false
430431
let hasFor = false
@@ -439,11 +440,11 @@ function injectVaporAnchors(
439440
}
440441

441442
if (hasIf) {
442-
insertionAnchor = (child as any as IfNode).anchor
443+
needBlockAnchor = (child as any as IfNode).needAnchor
443444
const lastBranchIndex = findLastIfBranchIndex(children, i)
444445
if (lastBranchIndex > i) {
445446
injectIfAnchors(
446-
insertionAnchor,
447+
needBlockAnchor,
447448
newChildren,
448449
i,
449450
lastBranchIndex,
@@ -453,22 +454,22 @@ function injectVaporAnchors(
453454
continue
454455
}
455456
} else if (hasFor) {
456-
insertionAnchor = (child as any as ForNode).anchor
457+
needBlockAnchor = (child as any as ForNode).needAnchor
457458
}
458459
}
459460

460-
if (insertionAnchor) {
461-
newChildren.push(createAnchor(`[${insertionAnchor}`))
461+
if (needBlockAnchor) {
462+
newChildren.push(createAnchor(BLOCK_ANCHOR_START_LABEL))
462463
}
463464

464465
newChildren.push(child)
465466

466-
// inject block anchor
467-
const blockAnchorLabel = resolveBlockAnchorLabel(child)
468-
if (blockAnchorLabel) newChildren.push(createAnchor(blockAnchorLabel))
467+
// inject fragment anchor
468+
const fragmentAnchorLabel = resolveFragmentAnchorLabel(child)
469+
if (fragmentAnchorLabel) newChildren.push(createAnchor(fragmentAnchorLabel))
469470

470-
if (insertionAnchor) {
471-
newChildren.push(createAnchor(`${insertionAnchor}]`))
471+
if (needBlockAnchor) {
472+
newChildren.push(createAnchor(BLOCK_ANCHOR_END_LABEL))
472473
}
473474

474475
child.children = injectVaporAnchors(child.children, child)
@@ -478,19 +479,19 @@ function injectVaporAnchors(
478479
}
479480

480481
function injectIfAnchors(
481-
insertionAnchor: string | undefined,
482+
needBlockAnchor: boolean | undefined,
482483
newChildren: TemplateChildNode[],
483484
i: number,
484485
lastBranchIndex: number,
485486
children: TemplateChildNode[],
486487
) {
487-
if (insertionAnchor) {
488-
newChildren.push(createAnchor(`[${insertionAnchor}`))
488+
if (needBlockAnchor) {
489+
newChildren.push(createAnchor(BLOCK_ANCHOR_START_LABEL))
489490
}
490491

491492
for (let j = i; j <= lastBranchIndex; j++) {
492493
const node = children[j] as PlainElementNode
493-
const blockAnchorLabel = resolveBlockAnchorLabel(node)
494+
const fragmentAnchorLabel = resolveFragmentAnchorLabel(node)
494495
let isElse = false
495496

496497
const conditionalProps: typeof node.props = []
@@ -523,17 +524,17 @@ function injectIfAnchors(
523524
}
524525
newChildren.push(wrapperNode)
525526

526-
if (blockAnchorLabel) {
527+
if (fragmentAnchorLabel) {
527528
const repeatCount = j - i - (isElse ? 1 : 0) + 1
528529
wrapperNode.children.push(
529-
createAnchor(`<!--${blockAnchorLabel}-->`.repeat(repeatCount)),
530+
createAnchor(`<!--${fragmentAnchorLabel}-->`.repeat(repeatCount)),
530531
)
531532
}
532533
node.children = injectVaporAnchors(node.children, node)
533534
}
534535

535-
if (insertionAnchor) {
536-
newChildren.push(createAnchor(`${insertionAnchor}]`))
536+
if (needBlockAnchor) {
537+
newChildren.push(createAnchor(BLOCK_ANCHOR_END_LABEL))
537538
}
538539
}
539540

@@ -584,7 +585,11 @@ function findLastIfBranchIndex(
584585
return lastIndex
585586
}
586587

587-
function resolveBlockAnchorLabel(child: ElementNode): string | undefined {
588+
function resolveFragmentAnchorLabel(
589+
child: TemplateChildNode,
590+
): string | undefined {
591+
if (child.type !== NodeTypes.ELEMENT) return
592+
588593
if (child.tagType === ElementTypes.COMPONENT && child.tag === 'component') {
589594
return DYNAMIC_COMPONENT_ANCHOR_LABEL
590595
} else if (child.tagType === ElementTypes.SLOT) {

0 commit comments

Comments
 (0)