aaa
Rich Harris 8 months ago
parent c34e44f781
commit ed348c6cab

@ -60,7 +60,10 @@ function open(parser) {
end: -1, end: -1,
test: read_expression(parser), test: read_expression(parser),
consequent: create_fragment(), consequent: create_fragment(),
alternate: null alternate: null,
metadata: {
expression: create_expression_metadata()
}
}); });
parser.allow_whitespace(); parser.allow_whitespace();
@ -441,7 +444,10 @@ function next(parser) {
elseif: true, elseif: true,
test: expression, test: expression,
consequent: create_fragment(), consequent: create_fragment(),
alternate: null alternate: null,
metadata: {
expression: create_expression_metadata()
}
}); });
parser.stack.push(child); parser.stack.push(child);

@ -17,5 +17,11 @@ export function IfBlock(node, context) {
mark_subtree_dynamic(context.path); mark_subtree_dynamic(context.path);
context.next(); context.visit(node.test, {
...context.state,
expression: node.metadata.expression
});
context.visit(node.consequent);
if (node.alternate) context.visit(node.alternate);
} }

@ -24,6 +24,11 @@ export function IfBlock(node, context) {
statements.push(b.var(b.id(alternate_id), b.arrow([b.id('$$anchor')], alternate))); statements.push(b.var(b.id(alternate_id), b.arrow([b.id('$$anchor')], alternate)));
} }
const { is_async } = node.metadata.expression;
const expression = /** @type {Expression} */ (context.visit(node.test));
const test = is_async ? b.call('$.get', b.id('$$condition')) : expression;
/** @type {Expression[]} */ /** @type {Expression[]} */
const args = [ const args = [
context.state.node, context.state.node,
@ -31,7 +36,7 @@ export function IfBlock(node, context) {
[b.id('$$render')], [b.id('$$render')],
b.block([ b.block([
b.if( b.if(
/** @type {Expression} */ (context.visit(node.test)), test,
b.stmt(b.call(b.id('$$render'), b.id(consequent_id))), b.stmt(b.call(b.id('$$render'), b.id(consequent_id))),
alternate_id alternate_id
? b.stmt( ? b.stmt(
@ -74,5 +79,18 @@ export function IfBlock(node, context) {
statements.push(b.stmt(b.call('$.if', ...args))); statements.push(b.stmt(b.call('$.if', ...args)));
if (is_async) {
context.state.init.push(
b.stmt(
b.call(
'$.async',
context.state.node,
b.array([b.thunk(expression, true)]),
b.arrow([context.state.node, b.id('$$condition')], b.block(statements))
)
)
);
} else {
context.state.init.push(b.block(statements)); context.state.init.push(b.block(statements));
}
} }

@ -434,6 +434,9 @@ export namespace AST {
test: Expression; test: Expression;
consequent: Fragment; consequent: Fragment;
alternate: Fragment | null; alternate: Fragment | null;
metadata: {
expression: ExpressionMetadata;
};
} }
/** An `{#await ...}` block */ /** An `{#await ...}` block */

@ -0,0 +1,37 @@
import { tick } from 'svelte';
import { deferred } from '../../../../src/internal/shared/utils.js';
import { test } from '../../test';
/** @type {ReturnType<typeof deferred>} */
let d;
export default test({
html: `<p>pending</p>`,
get props() {
d = deferred();
return {
promise: d.promise
};
},
async test({ assert, target, component }) {
d.resolve(true);
await Promise.resolve();
await Promise.resolve();
await Promise.resolve();
await tick();
assert.htmlEqual(target.innerHTML, '<h1>yes</h1>');
d = deferred();
component.promise = d.promise;
await tick();
assert.htmlEqual(target.innerHTML, '<p>pending</p>');
d.resolve(false);
await Promise.resolve();
await tick();
assert.htmlEqual(target.innerHTML, '<h1>no</h1>');
}
});

@ -0,0 +1,15 @@
<script>
let { promise } = $props();
</script>
<svelte:boundary>
{#if await promise}
<h1>yes</h1>
{:else}
<h1>no</h1>
{/if}
{#snippet pending()}
<p>pending</p>
{/snippet}
</svelte:boundary>
Loading…
Cancel
Save