diff --git a/src/compile/dom/Block.ts b/src/compile/dom/Block.ts index ca3984b5d7..b0879e9d70 100644 --- a/src/compile/dom/Block.ts +++ b/src/compile/dom/Block.ts @@ -177,6 +177,10 @@ export default class Block { this.builders.mount.addLine(`#current = true;`); } + if (!this.builders.mount.isEmpty() && this.builders.outro.isEmpty()) { + this.builders.outro.addLine(`#outrocallback();`); + } + if (!this.builders.outro.isEmpty()) { this.builders.outro.addLine(`#current = false;`); } diff --git a/src/shared/keyed-each.js b/src/shared/keyed-each.js index d3afde60fb..591da14b17 100644 --- a/src/shared/keyed-each.js +++ b/src/shared/keyed-each.js @@ -1,3 +1,5 @@ +import { noop } from './utils.js'; + export function destroyBlock(block, lookup) { block.d(1); lookup[block.key] = null; @@ -47,7 +49,8 @@ export function updateKeyedEach(old_blocks, component, changed, get_key, dynamic var will_move = {}; var did_move = {}; - function insert(block) { + function insert(block, removeFirst) { + if (removeFirst && block.o) block.o(noop); block[intro_method](node, next); lookup[block.key] = block; next = block.first; @@ -74,7 +77,7 @@ export function updateKeyedEach(old_blocks, component, changed, get_key, dynamic } else if (!lookup[new_key] || will_move[new_key]) { - insert(new_block); + insert(new_block, !!lookup[new_key]); } else if (did_move[old_key]) { @@ -82,7 +85,7 @@ export function updateKeyedEach(old_blocks, component, changed, get_key, dynamic } else if (deltas[new_key] > deltas[old_key]) { did_move[new_key] = true; - insert(new_block); + insert(new_block, true); } else { will_move[old_key] = true; diff --git a/test/js/samples/each-block-keyed-animated/expected-bundle.js b/test/js/samples/each-block-keyed-animated/expected-bundle.js index a7f5e22800..ec3d717d9b 100644 --- a/test/js/samples/each-block-keyed-animated/expected-bundle.js +++ b/test/js/samples/each-block-keyed-animated/expected-bundle.js @@ -291,7 +291,8 @@ function updateKeyedEach(old_blocks, component, changed, get_key, dynamic, ctx, var will_move = {}; var did_move = {}; - function insert(block) { + function insert(block, removeFirst) { + if (removeFirst && block.o) block.o(noop); block[intro_method](node, next); lookup[block.key] = block; next = block.first; @@ -318,7 +319,7 @@ function updateKeyedEach(old_blocks, component, changed, get_key, dynamic, ctx, } else if (!lookup[new_key] || will_move[new_key]) { - insert(new_block); + insert(new_block, !!lookup[new_key]); } else if (did_move[old_key]) { @@ -326,7 +327,7 @@ function updateKeyedEach(old_blocks, component, changed, get_key, dynamic, ctx, } else if (deltas[new_key] > deltas[old_key]) { did_move[new_key] = true; - insert(new_block); + insert(new_block, true); } else { will_move[old_key] = true; diff --git a/test/js/samples/each-block-keyed/expected-bundle.js b/test/js/samples/each-block-keyed/expected-bundle.js index 3643c1c059..ec3aff8e03 100644 --- a/test/js/samples/each-block-keyed/expected-bundle.js +++ b/test/js/samples/each-block-keyed/expected-bundle.js @@ -71,7 +71,8 @@ function updateKeyedEach(old_blocks, component, changed, get_key, dynamic, ctx, var will_move = {}; var did_move = {}; - function insert(block) { + function insert(block, removeFirst) { + if (removeFirst && block.o) block.o(noop); block[intro_method](node, next); lookup[block.key] = block; next = block.first; @@ -98,7 +99,7 @@ function updateKeyedEach(old_blocks, component, changed, get_key, dynamic, ctx, } else if (!lookup[new_key] || will_move[new_key]) { - insert(new_block); + insert(new_block, !!lookup[new_key]); } else if (did_move[old_key]) { @@ -106,7 +107,7 @@ function updateKeyedEach(old_blocks, component, changed, get_key, dynamic, ctx, } else if (deltas[new_key] > deltas[old_key]) { did_move[new_key] = true; - insert(new_block); + insert(new_block, true); } else { will_move[old_key] = true; diff --git a/test/runtime/samples/each-block-keyed-component/Todo.html b/test/runtime/samples/each-block-keyed-component/Todo.html new file mode 100644 index 0000000000..18a6961518 --- /dev/null +++ b/test/runtime/samples/each-block-keyed-component/Todo.html @@ -0,0 +1 @@ +
1: one
+2: two
+3: three
+ `, + + nestedTransitions: true, + + test(assert, component, target) { + const { todos } = component.get(); + + const [p1, p2, p3] = target.querySelectorAll('p'); + + component.set({ + todos: todos.reverse() + }); + + assert.htmlEqual(target.innerHTML, ` +1: three
+2: two
+3: one
+ `); + + const [p4, p5, p6] = target.querySelectorAll('p'); + + assert.equal(p1, p6); + assert.equal(p2, p5); + assert.equal(p3, p4); + + component.destroy(); + } +}; diff --git a/test/runtime/samples/each-block-keyed-component/main.html b/test/runtime/samples/each-block-keyed-component/main.html new file mode 100644 index 0000000000..29686daa4a --- /dev/null +++ b/test/runtime/samples/each-block-keyed-component/main.html @@ -0,0 +1,10 @@ +{#each todos as todo, i (todo.id)} +