mirror of https://github.com/sveltejs/svelte
commit
ee30cc9214
@ -1,5 +0,0 @@
|
||||
---
|
||||
'svelte': patch
|
||||
---
|
||||
|
||||
fix: `append_styles` in an effect to make them available on mount
|
@ -1,5 +0,0 @@
|
||||
---
|
||||
'svelte': patch
|
||||
---
|
||||
|
||||
chore: remove `parser.template_untrimmed`
|
@ -1,5 +0,0 @@
|
||||
---
|
||||
'svelte': patch
|
||||
---
|
||||
|
||||
fix: always inject styles when compiling as a custom element
|
@ -0,0 +1,10 @@
|
||||
/** @import { AST } from '#compiler' */
|
||||
/** @import { Context } from '../types.js' */
|
||||
|
||||
/**
|
||||
* @param {AST.Fragment} node
|
||||
* @param {Context} context
|
||||
*/
|
||||
export function Fragment(node, context) {
|
||||
context.next({ ...context.state, fragment: node });
|
||||
}
|
@ -0,0 +1,20 @@
|
||||
/** @import { Expression, ForOfStatement, Pattern, Statement, VariableDeclaration } from 'estree' */
|
||||
/** @import { ComponentContext } from '../types' */
|
||||
import * as b from '#compiler/builders';
|
||||
import { dev, is_ignored } from '../../../../state.js';
|
||||
|
||||
/**
|
||||
* @param {ForOfStatement} node
|
||||
* @param {ComponentContext} context
|
||||
*/
|
||||
export function ForOfStatement(node, context) {
|
||||
if (node.await && dev && !is_ignored(node, 'await_reactivity_loss')) {
|
||||
const left = /** @type {VariableDeclaration | Pattern} */ (context.visit(node.left));
|
||||
const argument = /** @type {Expression} */ (context.visit(node.right));
|
||||
const body = /** @type {Statement} */ (context.visit(node.body));
|
||||
const right = b.call('$.for_await_track_reactivity_loss', argument);
|
||||
return b.for_of(left, right, body, true);
|
||||
}
|
||||
|
||||
context.next();
|
||||
}
|
@ -0,0 +1,10 @@
|
||||
import { test } from '../../test';
|
||||
|
||||
export default test({
|
||||
error: {
|
||||
code: 'snippet_invalid_export',
|
||||
message:
|
||||
'An exported snippet can only reference things declared in a `<script module>`, or other exportable snippets',
|
||||
position: [26, 29]
|
||||
}
|
||||
});
|
@ -0,0 +1,11 @@
|
||||
<script module>
|
||||
export { foo }
|
||||
</script>
|
||||
|
||||
<script>
|
||||
let x = 42;
|
||||
</script>
|
||||
|
||||
{#snippet foo()}
|
||||
{x}
|
||||
{/snippet}
|
@ -0,0 +1 @@
|
||||
<p>nested</p>
|
@ -0,0 +1,8 @@
|
||||
import { test } from '../../test';
|
||||
|
||||
export default test({
|
||||
errors: [
|
||||
'Failed to hydrate: ',
|
||||
new DOMException("Node can't be inserted in a #text parent.", 'HierarchyRequestError')
|
||||
]
|
||||
});
|
@ -0,0 +1 @@
|
||||
<main><p>nested</p><!----></main>
|
@ -0,0 +1,2 @@
|
||||
<!--[-->
|
||||
<main><p>nested</p><!----></main><!--]-->
|
@ -0,0 +1,7 @@
|
||||
<script>
|
||||
import Nested from './Nested.svelte';
|
||||
</script>
|
||||
|
||||
<main>
|
||||
<Nested />
|
||||
</main>
|
@ -0,0 +1,19 @@
|
||||
import { flushSync } from 'svelte';
|
||||
import { test } from '../../test';
|
||||
|
||||
export default test({
|
||||
test({ target, assert }) {
|
||||
const input = target.querySelector('input');
|
||||
const button = target.querySelector('button');
|
||||
|
||||
assert.equal(input?.step, 'any');
|
||||
|
||||
button?.click();
|
||||
flushSync();
|
||||
assert.equal(input?.step, '10');
|
||||
|
||||
button?.click();
|
||||
flushSync();
|
||||
assert.equal(input?.step, 'any');
|
||||
}
|
||||
});
|
@ -0,0 +1,6 @@
|
||||
<script>
|
||||
let step = "any";
|
||||
</script>
|
||||
|
||||
<input type="range" {...{step}} />
|
||||
<button onclick={() => step = step === "any" ? 10 : "any"}>change step</button>
|
@ -0,0 +1,12 @@
|
||||
import { ok, test } from '../../test';
|
||||
import { flushSync } from 'svelte';
|
||||
|
||||
export default test({
|
||||
async test({ assert, target, errors }) {
|
||||
const btn = target.querySelector('button');
|
||||
flushSync(() => {
|
||||
btn?.click();
|
||||
});
|
||||
assert.deepEqual(errors, []);
|
||||
}
|
||||
});
|
@ -0,0 +1,24 @@
|
||||
<script lang="ts">
|
||||
import { getAbortSignal } from "svelte";
|
||||
|
||||
let aborted = $state(0);
|
||||
|
||||
let count = $state(0);
|
||||
|
||||
let der = $derived.by(()=>{
|
||||
const signal = getAbortSignal();
|
||||
|
||||
signal.addEventListener("abort", () => {
|
||||
try{
|
||||
aborted++;
|
||||
}catch(e){
|
||||
console.error(e);
|
||||
}
|
||||
});
|
||||
return count;
|
||||
})
|
||||
</script>
|
||||
|
||||
{der}
|
||||
|
||||
<button onclick={() => count++}></button>
|
@ -0,0 +1,43 @@
|
||||
import { tick } from 'svelte';
|
||||
import { test } from '../../test';
|
||||
|
||||
export default test({
|
||||
async test({ assert, target }) {
|
||||
const [reset, one, two, reject] = target.querySelectorAll('button');
|
||||
|
||||
await tick();
|
||||
assert.htmlEqual(
|
||||
target.innerHTML,
|
||||
'<button>reset</button><button>one</button><button>two</button><button>reject</button> waiting'
|
||||
);
|
||||
|
||||
one.click();
|
||||
await tick();
|
||||
assert.htmlEqual(
|
||||
target.innerHTML,
|
||||
'<button>reset</button><button>one</button><button>two</button><button>reject</button> one_res'
|
||||
);
|
||||
|
||||
reset.click();
|
||||
await tick();
|
||||
assert.htmlEqual(
|
||||
target.innerHTML,
|
||||
'<button>reset</button><button>one</button><button>two</button><button>reject</button> waiting'
|
||||
);
|
||||
|
||||
two.click();
|
||||
await tick();
|
||||
assert.htmlEqual(
|
||||
target.innerHTML,
|
||||
'<button>reset</button><button>one</button><button>two</button><button>reject</button> two_res'
|
||||
);
|
||||
|
||||
reset.click();
|
||||
reject.click();
|
||||
await tick();
|
||||
assert.htmlEqual(
|
||||
target.innerHTML,
|
||||
'<button>reset</button><button>one</button><button>two</button><button>reject</button> reject_catch'
|
||||
);
|
||||
}
|
||||
});
|
@ -0,0 +1,22 @@
|
||||
<script>
|
||||
let deferred = $state(Promise.withResolvers());
|
||||
</script>
|
||||
|
||||
<button onclick={() => deferred = Promise.withResolvers()}>reset</button>
|
||||
<button onclick={() => deferred.resolve("one")}>one</button>
|
||||
<button onclick={() => deferred.resolve("two")}>two</button>
|
||||
<button onclick={() => deferred.reject("reject")}>reject</button>
|
||||
|
||||
<svelte:boundary>
|
||||
{#await await deferred.promise + "_res"}
|
||||
waiting
|
||||
{:then res}
|
||||
{res}
|
||||
{:catch err}
|
||||
{err}_catch
|
||||
{/await}
|
||||
|
||||
{#snippet pending()}
|
||||
<p>pending</p>
|
||||
{/snippet}
|
||||
</svelte:boundary>
|
@ -0,0 +1,12 @@
|
||||
import { tick } from 'svelte';
|
||||
import { test } from '../../test';
|
||||
|
||||
export default test({
|
||||
html: `<h1>Loading...</h1>`,
|
||||
|
||||
async test({ assert, target }) {
|
||||
await tick();
|
||||
|
||||
assert.htmlEqual(target.innerHTML, `<h1>Hello, world!</h1>`);
|
||||
}
|
||||
});
|
@ -0,0 +1,16 @@
|
||||
<script>
|
||||
let name = $state('world');
|
||||
</script>
|
||||
|
||||
<svelte:boundary>
|
||||
{#snippet pending()}
|
||||
<h1>Loading...</h1>
|
||||
{/snippet}
|
||||
|
||||
{#snippet greet()}
|
||||
{@const greeting = await `Hello, ${name}!`}
|
||||
<h1>{greeting}</h1>
|
||||
{/snippet}
|
||||
|
||||
{@render greet()}
|
||||
</svelte:boundary>
|
@ -0,0 +1,24 @@
|
||||
import { tick } from 'svelte';
|
||||
import { test } from '../../test';
|
||||
|
||||
export default test({
|
||||
compileOptions: {
|
||||
dev: true
|
||||
},
|
||||
|
||||
html: `<button>a</button><button>b</button><p>pending</p>`,
|
||||
|
||||
async test({ assert, target, warnings }) {
|
||||
await tick();
|
||||
assert.htmlEqual(target.innerHTML, '<button>a</button><button>b</button><h1>3</h1>');
|
||||
|
||||
assert.equal(
|
||||
warnings[0],
|
||||
'Detected reactivity loss when reading `values[1]`. This happens when state is read in an async function after an earlier `await`'
|
||||
);
|
||||
|
||||
assert.equal(warnings[1].name, 'TracedAtError');
|
||||
|
||||
assert.equal(warnings.length, 2);
|
||||
}
|
||||
});
|
@ -0,0 +1,24 @@
|
||||
<script>
|
||||
let values = $state([1, 2]);
|
||||
|
||||
async function get_total() {
|
||||
let total = 0;
|
||||
|
||||
for await (const n of values) {
|
||||
total += n;
|
||||
}
|
||||
|
||||
return total;
|
||||
}
|
||||
</script>
|
||||
|
||||
<button onclick={() => values[0]++}>a</button>
|
||||
<button onclick={() => values[1]++}>b</button>
|
||||
|
||||
<svelte:boundary>
|
||||
<h1>{await get_total()}</h1>
|
||||
|
||||
{#snippet pending()}
|
||||
<p>pending</p>
|
||||
{/snippet}
|
||||
</svelte:boundary>
|
@ -0,0 +1,7 @@
|
||||
<script>
|
||||
let { data } = $props();
|
||||
</script>
|
||||
|
||||
{#each data.obj.arr as i}
|
||||
<p>{i}</p>
|
||||
{/each}
|
@ -0,0 +1 @@
|
||||
<p>Comp 2</p>
|
@ -0,0 +1,11 @@
|
||||
import { flushSync } from 'svelte';
|
||||
import { test } from '../../test';
|
||||
|
||||
export default test({
|
||||
async test({ assert, target }) {
|
||||
const [btn] = target.querySelectorAll('button');
|
||||
btn.click();
|
||||
flushSync();
|
||||
assert.htmlEqual(target.innerHTML, `<button>Change</button> <p>Comp 2</p>`);
|
||||
}
|
||||
});
|
@ -0,0 +1,16 @@
|
||||
<script>
|
||||
import Comp_1 from './Comp-1.svelte';
|
||||
import Comp_2 from './Comp-2.svelte';
|
||||
|
||||
let Comp = $state.raw(Comp_1);
|
||||
let data = $state.raw({ obj: { arr: [1, 2, 3] } });
|
||||
|
||||
function change() {
|
||||
Comp = Comp_2;
|
||||
data = {};
|
||||
}
|
||||
</script>
|
||||
|
||||
<button onclick={change}>Change</button>
|
||||
|
||||
<Comp {data} />
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in new issue