Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Prevent outro callback corruption #3209

Merged
merged 3 commits into from
Jul 10, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
22 changes: 12 additions & 10 deletions src/runtime/internal/transitions.ts
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
@@ -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
Original file line number Diff line number Diff line change
@@ -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
Original file line number Diff line number Diff line change
@@ -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}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<svelte:head>
<meta name="description" content="A"/>
</svelte:head>

A
Original file line number Diff line number Diff line change
@@ -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
Original file line number Diff line number Diff line change
@@ -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');
}
};
Original file line number Diff line number Diff line change
@@ -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}"/>