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
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);

@ -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));

@ -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 {

@ -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;

@ -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';
});
});

@ -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;

@ -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();

@ -125,13 +125,6 @@ var transitionManager = {
.join(', ');
},
groupOutros() {
this.outros = {
remaining: 0,
callbacks: []
};
},
wait() {
if (!transitionManager.promise) {
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