Merge pull request #1569 from sveltejs/gh-1568

outro when <svelte:component> switches -
pull/1570/merge
Rich Harris 7 years ago committed by GitHub
commit b86b9322c2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -303,11 +303,13 @@ export default class Compiler {
}, },
}); });
if (name === 'transitionManager') { if (name === 'transitionManager' || name === 'outros') {
// special case // 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') { } else if (name === 'escaped' || name === 'missingComponent') {
// vars are an awkward special case... would be nice to avoid this // vars are an awkward special case... would be nice to avoid this
const alias = this.alias(name); const alias = this.alias(name);

@ -1,6 +1,4 @@
import deindent from '../../utils/deindent'; import deindent from '../../utils/deindent';
import flattenReference from '../../utils/flattenReference';
import validCalleeObjects from '../../utils/validCalleeObjects';
import stringifyProps from '../../utils/stringifyProps'; import stringifyProps from '../../utils/stringifyProps';
import CodeBuilder from '../../utils/CodeBuilder'; import CodeBuilder from '../../utils/CodeBuilder';
import getTailSnippet from '../../utils/getTailSnippet'; import getTailSnippet from '../../utils/getTailSnippet';
@ -10,7 +8,6 @@ import { escape, escapeTemplate, stringify } from '../../utils/stringify';
import Node from './shared/Node'; import Node from './shared/Node';
import Block from '../dom/Block'; import Block from '../dom/Block';
import Attribute from './Attribute'; import Attribute from './Attribute';
import usesThisOrArguments from '../../validate/js/utils/usesThisOrArguments';
import mapChildren from './shared/mapChildren'; import mapChildren from './shared/mapChildren';
import Binding from './Binding'; import Binding from './Binding';
import EventHandler from './EventHandler'; import EventHandler from './EventHandler';
@ -344,9 +341,7 @@ export default class Component extends Node {
const switch_value = block.getUniqueName('switch_value'); const switch_value = block.getUniqueName('switch_value');
const switch_props = block.getUniqueName('switch_props'); const switch_props = block.getUniqueName('switch_props');
const { dependencies, snippet } = this.expression; const { snippet } = this.expression;
const anchor = this.getOrCreateAnchor(block, parentNode, parentNodes);
block.builders.init.addBlock(deindent` block.builders.init.addBlock(deindent`
var ${switch_value} = ${snippet}; 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); const updateMountNode = this.getUpdateMountNode(anchor);
if (updates.length) { if (updates.length) {
@ -402,7 +398,16 @@ export default class Component extends Node {
block.builders.update.addBlock(deindent` block.builders.update.addBlock(deindent`
if (${switch_value} !== (${switch_value} = ${snippet})) { 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}) { if (${switch_value}) {
${name} = new ${switch_value}(${switch_props}(ctx)); ${name} = new ${switch_value}(${switch_props}(ctx));

@ -324,7 +324,7 @@ export default class EachBlock extends Node {
block.builders.update.addBlock(deindent` block.builders.update.addBlock(deindent`
const ${this.each_block_value} = ${snippet}; 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();`} ${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}); ${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();`} ${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) { if (this.block.hasOutros) {
destroy = deindent` destroy = deindent`
@transitionManager.groupOutros(); @groupOutros();
for (; #i < ${iterations}.length; #i += 1) ${outroBlock}(#i, 1); for (; #i < ${iterations}.length; #i += 1) ${outroBlock}(#i, 1);
`; `;
} else { } else {

@ -301,7 +301,7 @@ export default class IfBlock extends Node {
const updateMountNode = this.getUpdateMountNode(anchor); const updateMountNode = this.getUpdateMountNode(anchor);
const destroyOldBlock = deindent` const destroyOldBlock = deindent`
@transitionManager.groupOutros(); @groupOutros();
${name}.o(function() { ${name}.o(function() {
${if_blocks}[${previous_block_index}].d(1); ${if_blocks}[${previous_block_index}].d(1);
${if_blocks}[${previous_block_index}] = null; ${if_blocks}[${previous_block_index}] = null;
@ -423,7 +423,7 @@ export default class IfBlock extends Node {
// as that will typically result in glitching // as that will typically result in glitching
const exit = branch.hasOutroMethod const exit = branch.hasOutroMethod
? deindent` ? deindent`
@transitionManager.groupOutros(); @groupOutros();
${name}.o(function() { ${name}.o(function() {
${name}.d(1); ${name}.d(1);
${name} = null; ${name} = null;

@ -27,7 +27,7 @@ fs.readdirSync(__dirname).forEach(file => {
? declaration.declarations[0].init ? declaration.declarations[0].init
: declaration; : declaration;
declarations[name] = source.slice(value.start, value.end); declarations[name] = value ? source.slice(value.start, value.end) : 'null';
}); });
}); });

@ -1,5 +1,5 @@
import { assign, isPromise } from './utils.js'; import { assign, isPromise } from './utils.js';
import { transitionManager } from './transitions.js'; import { groupOutros } from './transitions.js';
export function handlePromise(promise, info) { export function handlePromise(promise, info) {
var token = info.token = {}; var token = info.token = {};
@ -16,7 +16,7 @@ export function handlePromise(promise, info) {
if (info.blocks) { if (info.blocks) {
info.blocks.forEach((block, i) => { info.blocks.forEach((block, i) => {
if (i !== index && block) { if (i !== index && block) {
transitionManager.groupOutros(); groupOutros();
block.o(() => { block.o(() => {
block.d(1); block.d(1);
info.blocks[i] = null; info.blocks[i] = null;

@ -72,8 +72,8 @@ export function wrapTransition(component, node, fn, params, intro) {
} }
if (!b) { if (!b) {
program.group = transitionManager.outros; program.group = outros;
transitionManager.outros.remaining += 1; outros.remaining += 1;
} }
if (obj.delay) { 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 = { export var transitionManager = {
running: false, running: false,
transitions: [], transitions: [],
@ -236,13 +246,6 @@ export var transitionManager = {
.join(', '); .join(', ');
}, },
groupOutros() {
this.outros = {
remaining: 0,
callbacks: []
};
},
wait() { wait() {
if (!transitionManager.promise) { if (!transitionManager.promise) {
transitionManager.promise = Promise.resolve(); transitionManager.promise = Promise.resolve();

@ -125,13 +125,6 @@ var transitionManager = {
.join(', '); .join(', ');
}, },
groupOutros() {
this.outros = {
remaining: 0,
callbacks: []
};
},
wait() { wait() {
if (!transitionManager.promise) { if (!transitionManager.promise) {
transitionManager.promise = Promise.resolve(); transitionManager.promise = Promise.resolve();

@ -0,0 +1,16 @@
<div transition:a>a</div>
<script>
export default {
transitions: {
a(node, params) {
return {
duration: 100,
tick: t => {
node.a = t;
}
};
}
}
};
</script>

@ -0,0 +1,16 @@
<div transition:b>b</div>
<script>
export default {
transitions: {
b(node, params) {
return {
duration: 100,
tick: t => {
node.b = t;
}
};
}
}
};
</script>

@ -0,0 +1,37 @@
export default {
nestedTransitions: true,
skipIntroByDefault: true,
data: {
x: true,
},
html: `
<div>a</div>
`,
test (assert, component, target, window, raf) {
component.set({ x: false });
assert.htmlEqual(target.innerHTML, `
<div>a</div>
<div>b</div>
`);
const [a, b] = target.querySelectorAll('div');
raf.tick(25);
assert.equal(a.a, 0.75);
assert.equal(b.b, 0.25);
raf.tick(100);
assert.equal(a.a, 0);
assert.equal(b.b, 1);
assert.htmlEqual(target.innerHTML, `
<div>b</div>
`);
}
};

@ -0,0 +1,12 @@
<svelte:component this="{x ? A : B}"/>
<script>
import A from './A.html';
import B from './B.html';
export default {
data() {
return { A, B };
}
};
</script>
Loading…
Cancel
Save