Skip to content

Commit

Permalink
Merge pull request #3209 from sveltejs/gh-2086-2
Browse files Browse the repository at this point in the history
Prevent outro callback corruption
  • Loading branch information
Rich-Harris committed Jul 10, 2019
2 parents 1e4c1d1 + 2f08e34 commit 283152f
Show file tree
Hide file tree
Showing 8 changed files with 82 additions and 10 deletions.
22 changes: 12 additions & 10 deletions src/runtime/internal/transitions.ts
Expand Up @@ -28,15 +28,17 @@ let outros;

export function group_outros() {
outros = {
remaining: 0,
callbacks: []
r: 0, // remaining outros
c: [], // callbacks
p: outros // parent group
};
}

export function check_outros() {
if (!outros.remaining) {
run_all(outros.callbacks);
if (!outros.r) {
run_all(outros.c);
}
outros = outros.p;
}

export function transition_in(block, local?: 0 | 1) {
Expand All @@ -51,7 +53,7 @@ export function transition_out(block, local: 0 | 1, detach: 0 | 1, callback) {
if (outroing.has(block)) return;
outroing.add(block);

outros.callbacks.push(() => {
outros.c.push(() => {
outroing.delete(block);
if (callback) {
if (detach) block.d(1);
Expand Down Expand Up @@ -153,7 +155,7 @@ export function create_out_transition(node: Element & ElementCSSInlineStyle, fn:

const group = outros;

group.remaining += 1;
group.r += 1;

function go() {
const {
Expand All @@ -178,10 +180,10 @@ export function create_out_transition(node: Element & ElementCSSInlineStyle, fn:

dispatch(node, false, 'end');

if (!--group.remaining) {
if (!--group.r) {
// this will result in `end()` being called,
// so we don't need to clean up here
run_all(group.callbacks);
run_all(group.c);
}

return false;
Expand Down Expand Up @@ -266,7 +268,7 @@ export function create_bidirectional_transition(node: Element & ElementCSSInline
if (!b) {
// @ts-ignore todo: improve typings
program.group = outros;
outros.remaining += 1;
outros.r += 1;
}

if (running_program) {
Expand Down Expand Up @@ -309,7 +311,7 @@ export function create_bidirectional_transition(node: Element & ElementCSSInline
clear_animation();
} else {
// outro — needs to be coordinated
if (!--running_program.group.remaining) run_all(running_program.group.callbacks);
if (!--running_program.group.r) run_all(running_program.group.c);
}
}

Expand Down
5 changes: 5 additions & 0 deletions test/runtime/samples/each-block-keyed-nested/Child.svelte
@@ -0,0 +1,5 @@
<script>
export let id;
</script>

{id}
16 changes: 16 additions & 0 deletions test/runtime/samples/each-block-keyed-nested/_config.js
@@ -0,0 +1,16 @@
export default {
html: `
1
`,

test({ assert, component, target }) {
component.desks = [
{
id: 1,
teams: []
}
];

assert.htmlEqual(target.innerHTML, '');
}
};
16 changes: 16 additions & 0 deletions test/runtime/samples/each-block-keyed-nested/main.svelte
@@ -0,0 +1,16 @@
<script>
import Child from './Child.svelte';
export let desks = [
{
id: 1,
teams: [{ id: 1 }]
}
];
</script>

{#each desks as desk (desk.id)}
{#each desk.teams as team (team.id)}
<Child id={team.id} />
{/each}
{/each}
@@ -0,0 +1,5 @@
<svelte:head>
<meta name="description" content="A"/>
</svelte:head>

A
@@ -0,0 +1,5 @@
<svelte:head>
<meta name="description" content="B"/>
</svelte:head>

B
15 changes: 15 additions & 0 deletions test/runtime/samples/head-detached-in-dynamic-component/_config.js
@@ -0,0 +1,15 @@
export default {
html: `
A
`,

test({ assert, component, window }) {
component.x = false;

const meta = window.document.querySelectorAll('meta');

assert.equal(meta.length, 1);
assert.equal(meta[0].name, 'description');
assert.equal(meta[0].content, 'B');
}
};
@@ -0,0 +1,8 @@
<script>
import A from './A.svelte';
import B from './B.svelte';
export let x = true;
</script>

<svelte:component this="{x ? A : B}"/>

0 comments on commit 283152f

Please sign in to comment.