diff --git a/src/compile/Compiler.ts b/src/compile/Compiler.ts index 4a4239bbae..bb2ffd1d5e 100644 --- a/src/compile/Compiler.ts +++ b/src/compile/Compiler.ts @@ -303,11 +303,13 @@ export default class Compiler { }, }); - if (name === 'transitionManager') { + if (name === 'transitionManager' || name === 'outros') { // special case - const global = `_svelteTransitionManager`; + const global = name === 'outros' + ? `_svelteOutros` + : `_svelteTransitionManager`; - inlineHelpers += `\n\nvar ${this.alias('transitionManager')} = window.${global} || (window.${global} = ${code});\n\n`; + inlineHelpers += `\n\nvar ${this.alias(name)} = window.${global} || (window.${global} = ${code});\n\n`; } else if (name === 'escaped' || name === 'missingComponent') { // vars are an awkward special case... would be nice to avoid this const alias = this.alias(name); diff --git a/src/compile/nodes/Component.ts b/src/compile/nodes/Component.ts index 736b2306ea..ebe396b709 100644 --- a/src/compile/nodes/Component.ts +++ b/src/compile/nodes/Component.ts @@ -1,6 +1,4 @@ import deindent from '../../utils/deindent'; -import flattenReference from '../../utils/flattenReference'; -import validCalleeObjects from '../../utils/validCalleeObjects'; import stringifyProps from '../../utils/stringifyProps'; import CodeBuilder from '../../utils/CodeBuilder'; import getTailSnippet from '../../utils/getTailSnippet'; @@ -10,7 +8,6 @@ import { escape, escapeTemplate, stringify } from '../../utils/stringify'; import Node from './shared/Node'; import Block from '../dom/Block'; import Attribute from './Attribute'; -import usesThisOrArguments from '../../validate/js/utils/usesThisOrArguments'; import mapChildren from './shared/mapChildren'; import Binding from './Binding'; import EventHandler from './EventHandler'; @@ -344,9 +341,7 @@ export default class Component extends Node { const switch_value = block.getUniqueName('switch_value'); const switch_props = block.getUniqueName('switch_props'); - const { dependencies, snippet } = this.expression; - - const anchor = this.getOrCreateAnchor(block, parentNode, parentNodes); + const { snippet } = this.expression; block.builders.init.addBlock(deindent` var ${switch_value} = ${snippet}; @@ -392,6 +387,7 @@ export default class Component extends Node { } `); + const anchor = this.getOrCreateAnchor(block, parentNode, parentNodes); const updateMountNode = this.getUpdateMountNode(anchor); if (updates.length) { @@ -402,7 +398,16 @@ export default class Component extends Node { block.builders.update.addBlock(deindent` if (${switch_value} !== (${switch_value} = ${snippet})) { - if (${name}) ${name}.destroy(); + if (${name}) { + ${this.compiler.options.nestedTransitions + ? deindent` + @groupOutros(); + const old_component = ${name}; + old_component._fragment.o(() => { + old_component.destroy(); + });` + : `${name}.destroy();`} + } if (${switch_value}) { ${name} = new ${switch_value}(${switch_props}(ctx)); diff --git a/src/compile/nodes/EachBlock.ts b/src/compile/nodes/EachBlock.ts index adf23d85c9..a29877367e 100644 --- a/src/compile/nodes/EachBlock.ts +++ b/src/compile/nodes/EachBlock.ts @@ -324,7 +324,7 @@ export default class EachBlock extends Node { block.builders.update.addBlock(deindent` const ${this.each_block_value} = ${snippet}; - ${this.block.hasOutros && `@transitionManager.groupOutros();`} + ${this.block.hasOutros && `@groupOutros();`} ${this.block.hasAnimation && `for (let #i = 0; #i < ${blocks}.length; #i += 1) ${blocks}[#i].r();`} ${blocks} = @updateKeyedEach(${blocks}, #component, changed, ${get_key}, ${dynamic ? '1' : '0'}, ctx, ${this.each_block_value}, ${lookup}, ${updateMountNode}, ${destroy}, ${create_each_block}, "${mountOrIntro}", ${anchor}, ${this.get_each_context}); ${this.block.hasAnimation && `for (let #i = 0; #i < ${blocks}.length; #i += 1) ${blocks}[#i].a();`} @@ -449,7 +449,7 @@ export default class EachBlock extends Node { if (this.block.hasOutros) { destroy = deindent` - @transitionManager.groupOutros(); + @groupOutros(); for (; #i < ${iterations}.length; #i += 1) ${outroBlock}(#i, 1); `; } else { diff --git a/src/compile/nodes/IfBlock.ts b/src/compile/nodes/IfBlock.ts index ee5cb41a83..730128fc71 100644 --- a/src/compile/nodes/IfBlock.ts +++ b/src/compile/nodes/IfBlock.ts @@ -301,7 +301,7 @@ export default class IfBlock extends Node { const updateMountNode = this.getUpdateMountNode(anchor); const destroyOldBlock = deindent` - @transitionManager.groupOutros(); + @groupOutros(); ${name}.o(function() { ${if_blocks}[${previous_block_index}].d(1); ${if_blocks}[${previous_block_index}] = null; @@ -423,7 +423,7 @@ export default class IfBlock extends Node { // as that will typically result in glitching const exit = branch.hasOutroMethod ? deindent` - @transitionManager.groupOutros(); + @groupOutros(); ${name}.o(function() { ${name}.d(1); ${name} = null; diff --git a/src/shared/_build.js b/src/shared/_build.js index d62a5602e3..79d9f56774 100644 --- a/src/shared/_build.js +++ b/src/shared/_build.js @@ -27,7 +27,7 @@ fs.readdirSync(__dirname).forEach(file => { ? declaration.declarations[0].init : declaration; - declarations[name] = source.slice(value.start, value.end); + declarations[name] = value ? source.slice(value.start, value.end) : 'null'; }); }); diff --git a/src/shared/await-block.js b/src/shared/await-block.js index f5aceaf163..ed4b2ccf26 100644 --- a/src/shared/await-block.js +++ b/src/shared/await-block.js @@ -1,5 +1,5 @@ import { assign, isPromise } from './utils.js'; -import { transitionManager } from './transitions.js'; +import { groupOutros } from './transitions.js'; export function handlePromise(promise, info) { var token = info.token = {}; @@ -16,7 +16,7 @@ export function handlePromise(promise, info) { if (info.blocks) { info.blocks.forEach((block, i) => { if (i !== index && block) { - transitionManager.groupOutros(); + groupOutros(); block.o(() => { block.d(1); info.blocks[i] = null; diff --git a/src/shared/transitions.js b/src/shared/transitions.js index 5f33c27dff..33903e9cbd 100644 --- a/src/shared/transitions.js +++ b/src/shared/transitions.js @@ -72,8 +72,8 @@ export function wrapTransition(component, node, fn, params, intro) { } if (!b) { - program.group = transitionManager.outros; - transitionManager.outros.remaining += 1; + program.group = outros; + outros.remaining += 1; } if (obj.delay) { @@ -165,6 +165,16 @@ export function wrapTransition(component, node, fn, params, intro) { }; } +export let outros = { + remaining: 0, + callbacks: [] +}; + +export function groupOutros() { + outros.remaining = 0; + outros.callbacks = []; +} + export var transitionManager = { running: false, transitions: [], @@ -236,13 +246,6 @@ export var transitionManager = { .join(', '); }, - groupOutros() { - this.outros = { - remaining: 0, - callbacks: [] - }; - }, - wait() { if (!transitionManager.promise) { transitionManager.promise = Promise.resolve(); 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 9989c77978..b1ecb4ce56 100644 --- a/test/js/samples/each-block-keyed-animated/expected-bundle.js +++ b/test/js/samples/each-block-keyed-animated/expected-bundle.js @@ -125,13 +125,6 @@ var transitionManager = { .join(', '); }, - groupOutros() { - this.outros = { - remaining: 0, - callbacks: [] - }; - }, - wait() { if (!transitionManager.promise) { transitionManager.promise = Promise.resolve(); diff --git a/test/runtime/samples/transition-js-dynamic-component/A.html b/test/runtime/samples/transition-js-dynamic-component/A.html new file mode 100644 index 0000000000..7671fb5c58 --- /dev/null +++ b/test/runtime/samples/transition-js-dynamic-component/A.html @@ -0,0 +1,16 @@ +