diff --git a/src/compile/nodes/Element.ts b/src/compile/nodes/Element.ts index 6c174f0272..12cffbbebf 100644 --- a/src/compile/nodes/Element.ts +++ b/src/compile/nodes/Element.ts @@ -712,6 +712,8 @@ export default class Element extends Node { ${name} = null; }); `); + + block.builders.destroy.addConditional('detach', `if (${name}) ${name}.abort();`); } else { const introName = intro && block.getUniqueName(`${this.var}_intro`); const outroName = outro && block.getUniqueName(`${this.var}_outro`); @@ -726,8 +728,8 @@ export default class Element extends Node { if (outro) { block.builders.intro.addBlock(deindent` - if (${introName}) ${introName}.abort(); - if (${outroName}) ${outroName}.abort(); + if (${introName}) ${introName}.abort(1); + if (${outroName}) ${outroName}.abort(1); `); } @@ -748,7 +750,7 @@ export default class Element extends Node { const fn = `%transitions-${outro.name}`; block.builders.intro.addBlock(deindent` - if (${outroName}) ${outroName}.abort(); + if (${outroName}) ${outroName}.abort(1); `); // TODO hide elements that have outro'd (unless they belong to a still-outroing @@ -757,6 +759,8 @@ export default class Element extends Node { ${outroName} = @wrapTransition(#component, ${this.var}, ${fn}, ${snippet}, false); ${outroName}.run(0, #outrocallback); `); + + block.builders.destroy.addConditional('detach', `if (${outroName}) ${outroName}.abort();`); } } } diff --git a/src/shared/transitions.js b/src/shared/transitions.js index 33903e9cbd..87635927c7 100644 --- a/src/shared/transitions.js +++ b/src/shared/transitions.js @@ -148,9 +148,9 @@ export function wrapTransition(component, node, fn, params, intro) { this.running = !!this.pending; }, - abort() { + abort(reset) { if (this.program) { - if (obj.tick) obj.tick(1, 0); + if (reset && obj.tick) obj.tick(1, 0); if (obj.css) transitionManager.deleteRule(node, this.program.name); this.program = this.pending = null; this.running = false; diff --git a/test/runtime/samples/transition-js-destroyed-before-end/_config.js b/test/runtime/samples/transition-js-destroyed-before-end/_config.js new file mode 100644 index 0000000000..d079c44641 --- /dev/null +++ b/test/runtime/samples/transition-js-destroyed-before-end/_config.js @@ -0,0 +1,19 @@ +export default { + skipIntroByDefault: true, + + data: { + visible: true + }, + + test(assert, component, target, window, raf) { + component.set({ visible: false }); + const div = target.querySelector('div'); + + raf.tick(50); + assert.equal(div.foo, 0.5); + + component.destroy(); + + raf.tick(100); + }, +}; diff --git a/test/runtime/samples/transition-js-destroyed-before-end/main.html b/test/runtime/samples/transition-js-destroyed-before-end/main.html new file mode 100644 index 0000000000..e6e0ee0c63 --- /dev/null +++ b/test/runtime/samples/transition-js-destroyed-before-end/main.html @@ -0,0 +1,18 @@ +{#if visible} +
destroy me
+{/if} + + \ No newline at end of file