Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 4a6e016

Browse files
committed
fix(runtime-vapor): preserve fallback carrier order with fragment anchors
1 parent c1df71d commit 4a6e016

2 files changed

Lines changed: 38 additions & 7 deletions

File tree

‎packages/runtime-vapor/__tests__/componentSlots.spec.ts‎

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ import {
3636
import { makeRender } from './_utils'
3737
import type { DynamicSlot } from '../src/componentSlots'
3838
import { setElementText, setText } from '../src/dom/prop'
39-
import { isValidBlock } from '../src/block'
39+
import { type Block, isValidBlock } from '../src/block'
4040
import { hydrateNode, setCurrentHydrationNode } from '../src/dom/hydration'
4141
import {
4242
DynamicFragment,
@@ -533,6 +533,40 @@ describe('component: slots', () => {
533533
expect(container.innerHTML).toBe('abxy!<!--slot-->')
534534
})
535535

536+
test('slot fallback controller re-syncs carrier order when fallback ends with a fragment anchor', async () => {
537+
const container = document.createElement('div')
538+
const carrierA = document.createTextNode('x')
539+
const carrierB = document.createTextNode('y')
540+
const marker = document.createTextNode('!')
541+
const slotAnchor = document.createComment('slot')
542+
const trailingFragment = new DynamicFragment('if', false, false)
543+
trailingFragment.update(() => document.createTextNode('b'))
544+
const fallback = new VaporFragment<Block>([
545+
document.createTextNode('a'),
546+
trailingFragment,
547+
])
548+
const controller = new SlotFallbackController({
549+
getParentBoundary: () => null,
550+
getLocalFallback: () => () => fallback,
551+
getContent: () => [carrierA, carrierB],
552+
getParentNode: () => container,
553+
getAnchor: () => slotAnchor,
554+
runWithRenderCtx: fn => fn(),
555+
isContentValid: () => false,
556+
onValidityChange: vi.fn(),
557+
})
558+
559+
container.append(carrierA, marker, carrierB, slotAnchor)
560+
controller.recheck()
561+
562+
expect(container.innerHTML).toBe('ab<!--if-->x!y<!--slot-->')
563+
564+
controller.syncActiveFallback()
565+
await nextTick()
566+
567+
expect(container.innerHTML).toBe('ab<!--if-->xy!<!--slot-->')
568+
})
569+
536570
test('slot fallback controller defaults to idle when isBusy is omitted', () => {
537571
const fallback = document.createTextNode('fallback')
538572
const controller = new SlotFallbackController({

‎packages/runtime-vapor/src/fragment.ts‎

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -982,12 +982,9 @@ export class SlotFallbackController {
982982
}
983983

984984
const carrierNodes = collectBlockNodes(this.host.getContent(), [], true)
985-
const lastNode = block.nodes[block.nodes.length - 1]
986-
if (
987-
!carrierNodes.length ||
988-
!(lastNode instanceof Node) ||
989-
lastNode instanceof Comment
990-
) {
985+
const fallbackNodes = collectBlockNodes(block, [], true)
986+
const lastNode = fallbackNodes[fallbackNodes.length - 1]
987+
if (!carrierNodes.length || !lastNode) {
991988
return
992989
}
993990

0 commit comments

Comments
 (0)