diff --git a/src/compile/dom/Block.ts b/src/compile/dom/Block.ts index 69a6736fcd..a0330c888c 100644 --- a/src/compile/dom/Block.ts +++ b/src/compile/dom/Block.ts @@ -258,11 +258,15 @@ export default class Block { }, `); } else { - properties.addBlock(deindent` - ${dev ? 'i: function intro' : 'i'}(#target, anchor) { - this.m(#target, anchor); - }, - `); + if (this.builders.mount.isEmpty()) { + properties.addBlock(`i: @noop,`); + } else { + properties.addBlock(deindent` + ${dev ? 'i: function intro' : 'i'}(#target, anchor) { + this.m(#target, anchor); + }, + `); + } } if (hasOutros) { diff --git a/src/compile/nodes/AwaitBlock.ts b/src/compile/nodes/AwaitBlock.ts index 0d74dc608b..097aea3d0d 100644 --- a/src/compile/nodes/AwaitBlock.ts +++ b/src/compile/nodes/AwaitBlock.ts @@ -76,6 +76,8 @@ export default class AwaitBlock extends Node { this.pending.block.hasOutroMethod = hasOutros; this.then.block.hasOutroMethod = hasOutros; this.catch.block.hasOutroMethod = hasOutros; + + if (hasOutros) block.addOutro(); } build( @@ -169,6 +171,17 @@ export default class AwaitBlock extends Node { `); } + if (this.pending.block.hasOutroMethod) { + block.builders.outro.addBlock(deindent` + #outrocallback = @callAfter(#outrocallback, 3); + for (let #i = 0; #i < 3; #i += 1) { + const block = ${info}.blocks[#i]; + if (block) block.o(#outrocallback); + else #outrocallback(); + } + `); + } + block.builders.destroy.addBlock(deindent` ${info}.block.d(${parentNode ? '' : 'detach'}); ${info} = null; diff --git a/src/compile/nodes/EachBlock.ts b/src/compile/nodes/EachBlock.ts index e55ecd8119..7af6bfbec3 100644 --- a/src/compile/nodes/EachBlock.ts +++ b/src/compile/nodes/EachBlock.ts @@ -322,17 +322,8 @@ export default class EachBlock extends Node { `); block.builders.outro.addBlock(deindent` - const keys = Object.keys(${lookup}).filter(key => ${lookup}[key]); - #outrocallback = @callAfter(#outrocallback, keys.length); - - function outro(key) { - ${lookup}[key].o(() => { - ${lookup}[key] = null; - #outrocallback(); - }); - } - - for (let #i = 0; #i < keys.length; #i += 1) outro(keys[#i]); + #outrocallback = @callAfter(#outrocallback, ${blocks}.length); + for (#i = 0; #i < ${blocks}.length; #i += 1) ${blocks}[#i].o(#outrocallback); `) block.builders.destroy.addBlock(deindent` diff --git a/test/runtime/samples/transition-js-nested-await/_config.js b/test/runtime/samples/transition-js-nested-await/_config.js new file mode 100644 index 0000000000..d688c55cf1 --- /dev/null +++ b/test/runtime/samples/transition-js-nested-await/_config.js @@ -0,0 +1,37 @@ +let fulfil; + +const promise = new Promise(f => { + fulfil = f; +}); + +export default { + skipIntroByDefault: true, + nestedTransitions: true, + + data: { + x: false, + promise + }, + + test(assert, component, target, window, raf) { + component.set({ x: true }); + fulfil(); + + return promise.then(() => { + const div = target.querySelector('div'); + assert.equal(div.foo, 0); + + raf.tick(100); + assert.equal(div.foo, 1); + + component.set({ x: false }); + assert.htmlEqual(target.innerHTML, '
'); + + raf.tick(150); + assert.equal(div.foo, 0.5); + + raf.tick(200); + assert.htmlEqual(target.innerHTML, ''); + }); + } +}; diff --git a/test/runtime/samples/transition-js-nested-await/main.html b/test/runtime/samples/transition-js-nested-await/main.html new file mode 100644 index 0000000000..039051a8bd --- /dev/null +++ b/test/runtime/samples/transition-js-nested-await/main.html @@ -0,0 +1,20 @@ +{#if x} + {#await promise then value} +
+ {/await} +{/if} + + \ No newline at end of file