diff --git a/src/compile/nodes/AwaitBlock.ts b/src/compile/nodes/AwaitBlock.ts index 882a27885f..4897adcd59 100644 --- a/src/compile/nodes/AwaitBlock.ts +++ b/src/compile/nodes/AwaitBlock.ts @@ -172,12 +172,13 @@ export default class AwaitBlock extends Node { } if (this.pending.block.hasOutroMethod && this.compiler.options.nestedTransitions) { + const countdown = block.getUniqueName('countdown'); block.builders.outro.addBlock(deindent` - #outrocallback = @callAfter(#outrocallback, 3); + const ${countdown} = @callAfter(#outrocallback, 3); for (let #i = 0; #i < 3; #i += 1) { const block = ${info}.blocks[#i]; - if (block) block.o(#outrocallback); - else #outrocallback(); + if (block) block.o(${countdown}); + else ${countdown}(); } `); } diff --git a/src/compile/nodes/EachBlock.ts b/src/compile/nodes/EachBlock.ts index 720161971d..adf23d85c9 100644 --- a/src/compile/nodes/EachBlock.ts +++ b/src/compile/nodes/EachBlock.ts @@ -331,9 +331,10 @@ export default class EachBlock extends Node { `); if (this.compiler.options.nestedTransitions) { + const countdown = block.getUniqueName('countdown'); block.builders.outro.addBlock(deindent` - #outrocallback = @callAfter(#outrocallback, ${blocks}.length); - for (#i = 0; #i < ${blocks}.length; #i += 1) ${blocks}[#i].o(#outrocallback); + const ${countdown} = @callAfter(#outrocallback, ${blocks}.length); + for (#i = 0; #i < ${blocks}.length; #i += 1) ${blocks}[#i].o(${countdown}); `); } @@ -393,14 +394,16 @@ export default class EachBlock extends Node { allDependencies.add(dependency); }); - const outro = this.block.hasOutros && block.getUniqueName('outro') - if (outro) { + const outroBlock = this.block.hasOutros && block.getUniqueName('outroBlock') + if (outroBlock) { block.builders.init.addBlock(deindent` - function ${outro}(i, detach, fn) { + function ${outroBlock}(i, detach, fn) { if (${iterations}[i]) { ${iterations}[i].o(() => { - ${iterations}[i].d(detach); - if (detach) ${iterations}[i] = null; + if (detach) { + ${iterations}[i].d(detach); + ${iterations}[i] = null; + } if (fn) fn(); }); } @@ -447,7 +450,7 @@ export default class EachBlock extends Node { if (this.block.hasOutros) { destroy = deindent` @transitionManager.groupOutros(); - for (; #i < ${iterations}.length; #i += 1) ${outro}(#i, 1); + for (; #i < ${iterations}.length; #i += 1) ${outroBlock}(#i, 1); `; } else { destroy = deindent` @@ -473,10 +476,11 @@ export default class EachBlock extends Node { `); } - if (outro && this.compiler.options.nestedTransitions) { + if (outroBlock && this.compiler.options.nestedTransitions) { + const countdown = block.getUniqueName('countdown'); block.builders.outro.addBlock(deindent` - #outrocallback = @callAfter(#outrocallback, #i); - for (let #i = 0; #i < ${iterations}.length; #i += 1) ${outro}(#i, 0, #outrocallback);` + const ${countdown} = @callAfter(#outrocallback, ${iterations}.length); + for (let #i = 0; #i < ${iterations}.length; #i += 1) ${outroBlock}(#i, 0, ${countdown});` ); } diff --git a/src/compile/nodes/IfBlock.ts b/src/compile/nodes/IfBlock.ts index 3ecab77f43..ee5cb41a83 100644 --- a/src/compile/nodes/IfBlock.ts +++ b/src/compile/nodes/IfBlock.ts @@ -147,9 +147,10 @@ export default class IfBlock extends Node { this.buildSimple(block, parentNode, parentNodes, branches[0], dynamic, vars); if (hasOutros && this.compiler.options.nestedTransitions) { - block.builders.outro.addLine( - `if (${name}) ${name}.o(#outrocallback);` - ); + block.builders.outro.addBlock(deindent` + if (${name}) ${name}.o(#outrocallback); + else #outrocallback(); + `); } } diff --git a/test/runtime/samples/nested-transition-detach-each/_config.js b/test/runtime/samples/nested-transition-detach-each/_config.js new file mode 100644 index 0000000000..523be65e97 --- /dev/null +++ b/test/runtime/samples/nested-transition-detach-each/_config.js @@ -0,0 +1,41 @@ +export default { + data: { + visible: false, + rows: [1, 2, 3], + cols: ['a', 'b', 'c'] + }, + + html: ``, + + compileOptions: { + dev: true + }, + nestedTransitions: true, + skipIntroByDefault: true, + + test(assert, component, target, window, raf) { + component.set({ visible: true }); + assert.htmlEqual(target.innerHTML, ` +
+
1, a
+
1, b
+
1, c
+
+
+
2, a
+
2, b
+
2, c
+
+
+
3, a
+
3, b
+
3, c
+
+ `); + + component.set({ visible: false }); + raf.tick(0); + raf.tick(100); + assert.htmlEqual(target.innerHTML, ``); + }, +}; diff --git a/test/runtime/samples/nested-transition-detach-each/main.html b/test/runtime/samples/nested-transition-detach-each/main.html new file mode 100644 index 0000000000..c81fc3eb78 --- /dev/null +++ b/test/runtime/samples/nested-transition-detach-each/main.html @@ -0,0 +1,22 @@ +{#if visible} + {#each rows as row} +
+ {#each cols as col} +
{row}, {col}
+ {/each} +
+ {/each} +{/if} + + \ No newline at end of file diff --git a/test/runtime/samples/nested-transition-detach-if-false/Folder.html b/test/runtime/samples/nested-transition-detach-if-false/Folder.html new file mode 100644 index 0000000000..cd3448a3f2 --- /dev/null +++ b/test/runtime/samples/nested-transition-detach-if-false/Folder.html @@ -0,0 +1,44 @@ +
  • + {dir} + + {#if open} + + {/if} +
  • + + \ No newline at end of file diff --git a/test/runtime/samples/nested-transition-detach-if-false/_config.js b/test/runtime/samples/nested-transition-detach-if-false/_config.js new file mode 100644 index 0000000000..1e26a54787 --- /dev/null +++ b/test/runtime/samples/nested-transition-detach-if-false/_config.js @@ -0,0 +1,26 @@ +export default { + html: ` +
  • + a + +
  • + `, + + nestedTransitions: true, + + test(assert, component, target, window, raf) { + component.refs.folder.set({ open: false }); + assert.htmlEqual(target.innerHTML, ` +
  • + a +
  • + `); + }, +}; diff --git a/test/runtime/samples/nested-transition-detach-if-false/main.html b/test/runtime/samples/nested-transition-detach-if-false/main.html new file mode 100644 index 0000000000..cf14773c9c --- /dev/null +++ b/test/runtime/samples/nested-transition-detach-if-false/main.html @@ -0,0 +1,9 @@ + + + \ No newline at end of file