aaa
Rich Harris 8 months ago
parent 18b902344c
commit 364f45a08e

@ -326,7 +326,10 @@ function open(parser) {
start,
end: -1,
expression,
fragment: create_fragment()
fragment: create_fragment(),
metadata: {
expression: create_expression_metadata()
}
});
parser.stack.push(block);

@ -16,5 +16,10 @@ export function KeyBlock(node, context) {
mark_subtree_dynamic(context.path);
context.next();
context.visit(node.expression, {
...context.state,
expression: node.metadata.expression
});
context.visit(node.fragment);
}

@ -13,7 +13,32 @@ export function KeyBlock(node, context) {
const key = /** @type {Expression} */ (context.visit(node.expression));
const body = /** @type {Expression} */ (context.visit(node.fragment));
context.state.init.push(
b.stmt(b.call('$.key', context.state.node, b.thunk(key), b.arrow([b.id('$$anchor')], body)))
);
if (node.metadata.expression.is_async) {
context.state.init.push(
b.stmt(
b.call(
'$.async',
context.state.node,
b.array([b.thunk(key, true)]),
b.arrow(
[context.state.node, b.id('$$key')],
b.block([
b.stmt(
b.call(
'$.key',
context.state.node,
b.thunk(b.call('$.get', b.id('$$key'))),
b.arrow([b.id('$$anchor')], body)
)
)
])
)
)
)
);
} else {
context.state.init.push(
b.stmt(b.call('$.key', context.state.node, b.thunk(key), b.arrow([b.id('$$anchor')], body)))
);
}
}

@ -434,6 +434,7 @@ export namespace AST {
test: Expression;
consequent: Fragment;
alternate: Fragment | null;
/** @internal */
metadata: {
expression: ExpressionMetadata;
};
@ -457,6 +458,10 @@ export namespace AST {
type: 'KeyBlock';
expression: Expression;
fragment: Fragment;
/** @internal */
metadata: {
expression: ExpressionMetadata;
};
}
export interface SnippetBlock extends BaseNode {

@ -0,0 +1,51 @@
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(1);
await Promise.resolve();
await Promise.resolve();
await Promise.resolve();
await tick();
assert.htmlEqual(target.innerHTML, '<h1>hello</h1>');
const h1 = target.querySelector('h1');
d = deferred();
component.promise = d.promise;
await tick();
assert.htmlEqual(target.innerHTML, '<p>pending</p>');
d.resolve(1);
await Promise.resolve();
await tick();
assert.htmlEqual(target.innerHTML, '<h1>hello</h1>');
assert.equal(target.querySelector('h1'), h1);
d = deferred();
component.promise = d.promise;
await tick();
assert.htmlEqual(target.innerHTML, '<p>pending</p>');
d.resolve(2);
await Promise.resolve();
await tick();
assert.htmlEqual(target.innerHTML, '<h1>hello</h1>');
assert.notEqual(target.querySelector('h1'), h1);
}
});

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