wip: save

This commit is contained in:
daiwei 2025-07-28 11:49:18 +08:00
parent 5a77532fbf
commit 0bd887055b
2 changed files with 38 additions and 28 deletions

View File

@ -940,7 +940,7 @@ describe('createFor', () => {
) )
}) })
test.todo('remove from beginning and insert at end', async () => { test('remove from beginning and insert at end', async () => {
const arr = ref<number[]>([1, 2, 3]) const arr = ref<number[]>([1, 2, 3])
const { host, html } = render(arr) const { host, html } = render(arr)
expect(host.children.length).toBe(3) expect(host.children.length).toBe(3)
@ -1028,7 +1028,7 @@ describe('createFor', () => {
) )
}) })
test.todo('move to left & replace', async () => { test('move to left & replace', async () => {
const arr = ref<number[]>([1, 2, 3, 4, 5]) const arr = ref<number[]>([1, 2, 3, 4, 5])
const { host, html } = render(arr) const { host, html } = render(arr)
expect(host.children.length).toBe(5) expect(host.children.length).toBe(5)
@ -1044,7 +1044,7 @@ describe('createFor', () => {
) )
}) })
test.todo('move to left and leaves hold', async () => { test('move to left and leaves hold', async () => {
const arr = ref<number[]>([1, 4, 5]) const arr = ref<number[]>([1, 4, 5])
const { host, html } = render(arr) const { host, html } = render(arr)
expect(host.children.length).toBe(3) expect(host.children.length).toBe(3)
@ -1058,24 +1058,21 @@ describe('createFor', () => {
expect(html()).toBe(`<span>4</span><span>6</span><!--for-->`) expect(html()).toBe(`<span>4</span><span>6</span><!--for-->`)
}) })
test.todo( test('moved and set to undefined element ending at the end', async () => {
'moved and set to undefined element ending at the end', const arr = ref<number[]>([2, 4, 5])
async () => { const { host, html } = render(arr)
const arr = ref<number[]>([2, 4, 5]) expect(host.children.length).toBe(3)
const { host, html } = render(arr) expect(html()).toBe(
expect(host.children.length).toBe(3) `<span>2</span><span>4</span><span>5</span><!--for-->`,
expect(html()).toBe( )
`<span>2</span><span>4</span><span>5</span><!--for-->`,
)
arr.value = [4, 5, 3] arr.value = [4, 5, 3]
await nextTick() await nextTick()
expect(host.children.length).toBe(3) expect(host.children.length).toBe(3)
expect(html()).toBe( expect(html()).toBe(
`<span>4</span><span>5</span><span>3</span><!--for-->`, `<span>4</span><span>5</span><span>3</span><!--for-->`,
) )
}, })
)
test('reverse element', async () => { test('reverse element', async () => {
const arr = ref<number[]>([1, 2, 3, 4, 5, 6, 7, 8]) const arr = ref<number[]>([1, 2, 3, 4, 5, 6, 7, 8])
@ -1323,7 +1320,7 @@ describe('createFor', () => {
}).render() }).render()
} }
test.todo('move a key in non-keyed nodes with a size up', async () => { test('move a key in non-keyed nodes with a size up', async () => {
const arr = ref<any[]>([1, 'a', 'b', 'c']) const arr = ref<any[]>([1, 'a', 'b', 'c'])
const { host, html } = define({ const { host, html } = define({
setup() { setup() {

View File

@ -254,6 +254,7 @@ export const createFor = (
previousKeyIndexPairs.length = previousKeyIndexInsertIndex previousKeyIndexPairs.length = previousKeyIndexInsertIndex
const previousKeyIndexMap = new Map(previousKeyIndexPairs) const previousKeyIndexMap = new Map(previousKeyIndexPairs)
const blocksToMove: (() => void)[] = []
const blocksToMount: [ const blocksToMount: [
blockIndex: number, blockIndex: number,
blockItem: ReturnType<typeof getItem>, blockItem: ReturnType<typeof getItem>,
@ -272,13 +273,15 @@ export const createFor = (
const reusedBlock = (newBlocks[blockIndex] = const reusedBlock = (newBlocks[blockIndex] =
oldBlocks[previousIndex]) oldBlocks[previousIndex])
update(reusedBlock, ...blockItem) update(reusedBlock, ...blockItem)
insert( blocksToMove.push(() => {
reusedBlock, insert(
parent!, reusedBlock,
anchorOffset === -1 parent!,
? anchorFallback anchorOffset === -1
: normalizeAnchor(newBlocks[anchorOffset].nodes), ? anchorFallback
) : normalizeAnchor(newBlocks[anchorOffset].nodes),
)
})
previousKeyIndexMap.delete(blockKey) previousKeyIndexMap.delete(blockKey)
} else { } else {
blocksToMount.push([ blocksToMount.push([
@ -341,6 +344,16 @@ export const createFor = (
blockKey, blockKey,
) )
} }
if (blocksToMove.length > 0) {
// update anchorFallback to the last block if any new mounted blocks used it
if (blocksToMount.some(move => move[3] === -1)) {
anchorFallback = normalizeAnchor(
newBlocks[newBlocks.length - 1].nodes,
)
}
blocksToMove.forEach(move => move())
}
} }
} }
} }