Skip to content

Commit ed348c6

Browse files
committed
if blocks
1 parent c34e44f commit ed348c6

File tree

6 files changed

+90
-5
lines changed

6 files changed

+90
-5
lines changed

packages/svelte/src/compiler/phases/1-parse/state/tag.js

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,10 @@ function open(parser) {
6060
end: -1,
6161
test: read_expression(parser),
6262
consequent: create_fragment(),
63-
alternate: null
63+
alternate: null,
64+
metadata: {
65+
expression: create_expression_metadata()
66+
}
6467
});
6568

6669
parser.allow_whitespace();
@@ -441,7 +444,10 @@ function next(parser) {
441444
elseif: true,
442445
test: expression,
443446
consequent: create_fragment(),
444-
alternate: null
447+
alternate: null,
448+
metadata: {
449+
expression: create_expression_metadata()
450+
}
445451
});
446452

447453
parser.stack.push(child);

packages/svelte/src/compiler/phases/2-analyze/visitors/IfBlock.js

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,5 +17,11 @@ export function IfBlock(node, context) {
1717

1818
mark_subtree_dynamic(context.path);
1919

20-
context.next();
20+
context.visit(node.test, {
21+
...context.state,
22+
expression: node.metadata.expression
23+
});
24+
25+
context.visit(node.consequent);
26+
if (node.alternate) context.visit(node.alternate);
2127
}

packages/svelte/src/compiler/phases/3-transform/client/visitors/IfBlock.js

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,14 +24,19 @@ export function IfBlock(node, context) {
2424
statements.push(b.var(b.id(alternate_id), b.arrow([b.id('$$anchor')], alternate)));
2525
}
2626

27+
const { is_async } = node.metadata.expression;
28+
29+
const expression = /** @type {Expression} */ (context.visit(node.test));
30+
const test = is_async ? b.call('$.get', b.id('$$condition')) : expression;
31+
2732
/** @type {Expression[]} */
2833
const args = [
2934
context.state.node,
3035
b.arrow(
3136
[b.id('$$render')],
3237
b.block([
3338
b.if(
34-
/** @type {Expression} */ (context.visit(node.test)),
39+
test,
3540
b.stmt(b.call(b.id('$$render'), b.id(consequent_id))),
3641
alternate_id
3742
? b.stmt(
@@ -74,5 +79,18 @@ export function IfBlock(node, context) {
7479

7580
statements.push(b.stmt(b.call('$.if', ...args)));
7681

77-
context.state.init.push(b.block(statements));
82+
if (is_async) {
83+
context.state.init.push(
84+
b.stmt(
85+
b.call(
86+
'$.async',
87+
context.state.node,
88+
b.array([b.thunk(expression, true)]),
89+
b.arrow([context.state.node, b.id('$$condition')], b.block(statements))
90+
)
91+
)
92+
);
93+
} else {
94+
context.state.init.push(b.block(statements));
95+
}
7896
}

packages/svelte/src/compiler/types/template.d.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -434,6 +434,9 @@ export namespace AST {
434434
test: Expression;
435435
consequent: Fragment;
436436
alternate: Fragment | null;
437+
metadata: {
438+
expression: ExpressionMetadata;
439+
};
437440
}
438441

439442
/** An `{#await ...}` block */
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
import { tick } from 'svelte';
2+
import { deferred } from '../../../../src/internal/shared/utils.js';
3+
import { test } from '../../test';
4+
5+
/** @type {ReturnType<typeof deferred>} */
6+
let d;
7+
8+
export default test({
9+
html: `<p>pending</p>`,
10+
11+
get props() {
12+
d = deferred();
13+
14+
return {
15+
promise: d.promise
16+
};
17+
},
18+
19+
async test({ assert, target, component }) {
20+
d.resolve(true);
21+
await Promise.resolve();
22+
await Promise.resolve();
23+
await Promise.resolve();
24+
await tick();
25+
assert.htmlEqual(target.innerHTML, '<h1>yes</h1>');
26+
27+
d = deferred();
28+
component.promise = d.promise;
29+
await tick();
30+
assert.htmlEqual(target.innerHTML, '<p>pending</p>');
31+
32+
d.resolve(false);
33+
await Promise.resolve();
34+
await tick();
35+
assert.htmlEqual(target.innerHTML, '<h1>no</h1>');
36+
}
37+
});
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
<script>
2+
let { promise } = $props();
3+
</script>
4+
5+
<svelte:boundary>
6+
{#if await promise}
7+
<h1>yes</h1>
8+
{:else}
9+
<h1>no</h1>
10+
{/if}
11+
12+
{#snippet pending()}
13+
<p>pending</p>
14+
{/snippet}
15+
</svelte:boundary>

0 commit comments

Comments
 (0)