mirror of https://github.com/sveltejs/svelte
commit
9b010742fa
@ -0,0 +1,5 @@
|
|||||||
|
---
|
||||||
|
'svelte': patch
|
||||||
|
---
|
||||||
|
|
||||||
|
A transition's parameters are now evaluated when the transition is initialized.
|
||||||
@ -0,0 +1,5 @@
|
|||||||
|
---
|
||||||
|
'svelte': patch
|
||||||
|
---
|
||||||
|
|
||||||
|
fix: deeply unstate objects passed to inspect
|
||||||
@ -0,0 +1,5 @@
|
|||||||
|
---
|
||||||
|
'svelte': patch
|
||||||
|
---
|
||||||
|
|
||||||
|
fix: handle delegated events of elements moved outside the container
|
||||||
@ -0,0 +1,5 @@
|
|||||||
|
---
|
||||||
|
'svelte': patch
|
||||||
|
---
|
||||||
|
|
||||||
|
feat: add `$state.frozen` rune
|
||||||
@ -0,0 +1,5 @@
|
|||||||
|
---
|
||||||
|
'svelte': patch
|
||||||
|
---
|
||||||
|
|
||||||
|
fix: improve script `lang` attribute detection
|
||||||
@ -0,0 +1,5 @@
|
|||||||
|
---
|
||||||
|
'svelte': patch
|
||||||
|
---
|
||||||
|
|
||||||
|
Fix issue with assigning prop values as defaults of other props
|
||||||
@ -0,0 +1,5 @@
|
|||||||
|
---
|
||||||
|
'svelte': patch
|
||||||
|
---
|
||||||
|
|
||||||
|
fix: support TypeScript's `satisfies` operator
|
||||||
@ -0,0 +1,5 @@
|
|||||||
|
---
|
||||||
|
'svelte': patch
|
||||||
|
---
|
||||||
|
|
||||||
|
Fix interopability between backticks and templates
|
||||||
@ -0,0 +1,5 @@
|
|||||||
|
---
|
||||||
|
'svelte': patch
|
||||||
|
---
|
||||||
|
|
||||||
|
fix: improve pseudo class parsing
|
||||||
@ -0,0 +1,5 @@
|
|||||||
|
---
|
||||||
|
'svelte': patch
|
||||||
|
---
|
||||||
|
|
||||||
|
fix: provide `unstate` in server environment
|
||||||
@ -0,0 +1,5 @@
|
|||||||
|
---
|
||||||
|
'svelte': patch
|
||||||
|
---
|
||||||
|
|
||||||
|
fix: add types for popover attributes and events
|
||||||
@ -0,0 +1,5 @@
|
|||||||
|
---
|
||||||
|
'svelte': patch
|
||||||
|
---
|
||||||
|
|
||||||
|
fix: skip generating $.proxy() calls for unary and binary expressions
|
||||||
@ -0,0 +1,5 @@
|
|||||||
|
---
|
||||||
|
'svelte': patch
|
||||||
|
---
|
||||||
|
|
||||||
|
fix: support hydrating around `<noscript>`
|
||||||
@ -0,0 +1,5 @@
|
|||||||
|
---
|
||||||
|
'svelte': patch
|
||||||
|
---
|
||||||
|
|
||||||
|
fix: allow pseudo classes after `:global(..)`
|
||||||
@ -0,0 +1,5 @@
|
|||||||
|
---
|
||||||
|
'svelte': patch
|
||||||
|
---
|
||||||
|
|
||||||
|
fix: bail-out event handler referencing each index
|
||||||
@ -0,0 +1,5 @@
|
|||||||
|
---
|
||||||
|
'svelte': patch
|
||||||
|
---
|
||||||
|
|
||||||
|
fix: parse `:nth-of-type(xn+y)` correctly
|
||||||
@ -0,0 +1,5 @@
|
|||||||
|
---
|
||||||
|
'svelte': patch
|
||||||
|
---
|
||||||
|
|
||||||
|
fix: ensure if block is executed in correct order
|
||||||
@ -0,0 +1,7 @@
|
|||||||
|
/**
|
||||||
|
* @param {string} str
|
||||||
|
* @returns {string}
|
||||||
|
*/
|
||||||
|
export function sanitize_template_string(str) {
|
||||||
|
return str.replace(/(`|\${|\\)/g, '\\$1');
|
||||||
|
}
|
||||||
@ -0,0 +1,2 @@
|
|||||||
|
<!--ssr:0--><noscript>JavaScript is required for this site.</noscript>
|
||||||
|
<h1>Hello!</h1><p>Count: 0</p><!--ssr:0-->
|
||||||
@ -0,0 +1,9 @@
|
|||||||
|
<script>
|
||||||
|
import { onMount } from "svelte";
|
||||||
|
let count = 0;
|
||||||
|
onMount(() => count++);
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<noscript>JavaScript is required for this site.</noscript>
|
||||||
|
|
||||||
|
<h1>Hello!</h1><p>Count: {count}</p>
|
||||||
@ -0,0 +1,4 @@
|
|||||||
|
<!--should not error out-->
|
||||||
|
<script lang="ts">
|
||||||
|
let count: number;
|
||||||
|
</script>
|
||||||
@ -0,0 +1,132 @@
|
|||||||
|
{
|
||||||
|
"css": null,
|
||||||
|
"js": [],
|
||||||
|
"start": 0,
|
||||||
|
"end": 27,
|
||||||
|
"type": "Root",
|
||||||
|
"fragment": {
|
||||||
|
"type": "Fragment",
|
||||||
|
"nodes": [
|
||||||
|
{
|
||||||
|
"type": "Comment",
|
||||||
|
"start": 0,
|
||||||
|
"end": 27,
|
||||||
|
"data": "should not error out",
|
||||||
|
"ignores": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "Text",
|
||||||
|
"start": 27,
|
||||||
|
"end": 28,
|
||||||
|
"raw": "\n",
|
||||||
|
"data": "\n"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"transparent": false
|
||||||
|
},
|
||||||
|
"options": null,
|
||||||
|
"instance": {
|
||||||
|
"type": "Script",
|
||||||
|
"start": 28,
|
||||||
|
"end": 76,
|
||||||
|
"context": "default",
|
||||||
|
"content": {
|
||||||
|
"type": "Program",
|
||||||
|
"start": 46,
|
||||||
|
"end": 67,
|
||||||
|
"loc": {
|
||||||
|
"start": {
|
||||||
|
"line": 1,
|
||||||
|
"column": 0
|
||||||
|
},
|
||||||
|
"end": {
|
||||||
|
"line": 4,
|
||||||
|
"column": 0
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"body": [
|
||||||
|
{
|
||||||
|
"type": "VariableDeclaration",
|
||||||
|
"start": 48,
|
||||||
|
"end": 66,
|
||||||
|
"loc": {
|
||||||
|
"start": {
|
||||||
|
"line": 3,
|
||||||
|
"column": 1
|
||||||
|
},
|
||||||
|
"end": {
|
||||||
|
"line": 3,
|
||||||
|
"column": 19
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"declarations": [
|
||||||
|
{
|
||||||
|
"type": "VariableDeclarator",
|
||||||
|
"start": 52,
|
||||||
|
"end": 65,
|
||||||
|
"loc": {
|
||||||
|
"start": {
|
||||||
|
"line": 3,
|
||||||
|
"column": 5
|
||||||
|
},
|
||||||
|
"end": {
|
||||||
|
"line": 3,
|
||||||
|
"column": 18
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"id": {
|
||||||
|
"type": "Identifier",
|
||||||
|
"start": 52,
|
||||||
|
"end": 18,
|
||||||
|
"loc": {
|
||||||
|
"start": {
|
||||||
|
"line": 3,
|
||||||
|
"column": 5
|
||||||
|
},
|
||||||
|
"end": {
|
||||||
|
"line": 3,
|
||||||
|
"column": 18
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"name": "count",
|
||||||
|
"typeAnnotation": {
|
||||||
|
"type": "TSTypeAnnotation",
|
||||||
|
"start": 57,
|
||||||
|
"end": 65,
|
||||||
|
"loc": {
|
||||||
|
"start": {
|
||||||
|
"line": 3,
|
||||||
|
"column": 10
|
||||||
|
},
|
||||||
|
"end": {
|
||||||
|
"line": 3,
|
||||||
|
"column": 18
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"typeAnnotation": {
|
||||||
|
"type": "TSNumberKeyword",
|
||||||
|
"start": 59,
|
||||||
|
"end": 65,
|
||||||
|
"loc": {
|
||||||
|
"start": {
|
||||||
|
"line": 3,
|
||||||
|
"column": 12
|
||||||
|
},
|
||||||
|
"end": {
|
||||||
|
"line": 3,
|
||||||
|
"column": 18
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"init": null
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"kind": "let"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"sourceType": "module"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,18 @@
|
|||||||
|
<style>
|
||||||
|
/* test that all these are parsed correctly */
|
||||||
|
::view-transition-old(x-y) {
|
||||||
|
color: red;
|
||||||
|
}
|
||||||
|
:global(::view-transition-old(x-y)) {
|
||||||
|
color: red;
|
||||||
|
}
|
||||||
|
::highlight(rainbow-color-1) {
|
||||||
|
color: red;
|
||||||
|
}
|
||||||
|
custom-element::part(foo) {
|
||||||
|
color: red;
|
||||||
|
}
|
||||||
|
::slotted(.content) {
|
||||||
|
color: red;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@ -0,0 +1,246 @@
|
|||||||
|
{
|
||||||
|
"css": {
|
||||||
|
"type": "Style",
|
||||||
|
"start": 0,
|
||||||
|
"end": 313,
|
||||||
|
"attributes": [],
|
||||||
|
"children": [
|
||||||
|
{
|
||||||
|
"type": "Rule",
|
||||||
|
"prelude": {
|
||||||
|
"type": "SelectorList",
|
||||||
|
"start": 60,
|
||||||
|
"end": 86,
|
||||||
|
"children": [
|
||||||
|
{
|
||||||
|
"type": "Selector",
|
||||||
|
"start": 60,
|
||||||
|
"end": 86,
|
||||||
|
"children": [
|
||||||
|
{
|
||||||
|
"type": "PseudoElementSelector",
|
||||||
|
"name": "view-transition-old",
|
||||||
|
"start": 60,
|
||||||
|
"end": 81
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"block": {
|
||||||
|
"type": "Block",
|
||||||
|
"start": 88,
|
||||||
|
"end": 109,
|
||||||
|
"children": [
|
||||||
|
{
|
||||||
|
"type": "Declaration",
|
||||||
|
"start": 92,
|
||||||
|
"end": 102,
|
||||||
|
"property": "color",
|
||||||
|
"value": "red"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"start": 60,
|
||||||
|
"end": 109
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "Rule",
|
||||||
|
"prelude": {
|
||||||
|
"type": "SelectorList",
|
||||||
|
"start": 111,
|
||||||
|
"end": 146,
|
||||||
|
"children": [
|
||||||
|
{
|
||||||
|
"type": "Selector",
|
||||||
|
"start": 111,
|
||||||
|
"end": 146,
|
||||||
|
"children": [
|
||||||
|
{
|
||||||
|
"type": "PseudoClassSelector",
|
||||||
|
"name": "global",
|
||||||
|
"args": {
|
||||||
|
"type": "SelectorList",
|
||||||
|
"start": 119,
|
||||||
|
"end": 145,
|
||||||
|
"children": [
|
||||||
|
{
|
||||||
|
"type": "Selector",
|
||||||
|
"start": 119,
|
||||||
|
"end": 145,
|
||||||
|
"children": [
|
||||||
|
{
|
||||||
|
"type": "PseudoElementSelector",
|
||||||
|
"name": "view-transition-old",
|
||||||
|
"start": 119,
|
||||||
|
"end": 140
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"start": 111,
|
||||||
|
"end": 146
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"block": {
|
||||||
|
"type": "Block",
|
||||||
|
"start": 148,
|
||||||
|
"end": 169,
|
||||||
|
"children": [
|
||||||
|
{
|
||||||
|
"type": "Declaration",
|
||||||
|
"start": 152,
|
||||||
|
"end": 162,
|
||||||
|
"property": "color",
|
||||||
|
"value": "red"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"start": 111,
|
||||||
|
"end": 169
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "Rule",
|
||||||
|
"prelude": {
|
||||||
|
"type": "SelectorList",
|
||||||
|
"start": 171,
|
||||||
|
"end": 199,
|
||||||
|
"children": [
|
||||||
|
{
|
||||||
|
"type": "Selector",
|
||||||
|
"start": 171,
|
||||||
|
"end": 199,
|
||||||
|
"children": [
|
||||||
|
{
|
||||||
|
"type": "PseudoElementSelector",
|
||||||
|
"name": "highlight",
|
||||||
|
"start": 171,
|
||||||
|
"end": 182
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"block": {
|
||||||
|
"type": "Block",
|
||||||
|
"start": 200,
|
||||||
|
"end": 218,
|
||||||
|
"children": [
|
||||||
|
{
|
||||||
|
"type": "Declaration",
|
||||||
|
"start": 204,
|
||||||
|
"end": 214,
|
||||||
|
"property": "color",
|
||||||
|
"value": "red"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"start": 171,
|
||||||
|
"end": 218
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "Rule",
|
||||||
|
"prelude": {
|
||||||
|
"type": "SelectorList",
|
||||||
|
"start": 220,
|
||||||
|
"end": 245,
|
||||||
|
"children": [
|
||||||
|
{
|
||||||
|
"type": "Selector",
|
||||||
|
"start": 220,
|
||||||
|
"end": 245,
|
||||||
|
"children": [
|
||||||
|
{
|
||||||
|
"type": "TypeSelector",
|
||||||
|
"name": "custom-element",
|
||||||
|
"start": 220,
|
||||||
|
"end": 234
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "PseudoElementSelector",
|
||||||
|
"name": "part",
|
||||||
|
"start": 234,
|
||||||
|
"end": 240
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"block": {
|
||||||
|
"type": "Block",
|
||||||
|
"start": 246,
|
||||||
|
"end": 264,
|
||||||
|
"children": [
|
||||||
|
{
|
||||||
|
"type": "Declaration",
|
||||||
|
"start": 250,
|
||||||
|
"end": 260,
|
||||||
|
"property": "color",
|
||||||
|
"value": "red"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"start": 220,
|
||||||
|
"end": 264
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "Rule",
|
||||||
|
"prelude": {
|
||||||
|
"type": "SelectorList",
|
||||||
|
"start": 266,
|
||||||
|
"end": 285,
|
||||||
|
"children": [
|
||||||
|
{
|
||||||
|
"type": "Selector",
|
||||||
|
"start": 266,
|
||||||
|
"end": 285,
|
||||||
|
"children": [
|
||||||
|
{
|
||||||
|
"type": "PseudoElementSelector",
|
||||||
|
"name": "slotted",
|
||||||
|
"start": 266,
|
||||||
|
"end": 275
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"block": {
|
||||||
|
"type": "Block",
|
||||||
|
"start": 286,
|
||||||
|
"end": 304,
|
||||||
|
"children": [
|
||||||
|
{
|
||||||
|
"type": "Declaration",
|
||||||
|
"start": 290,
|
||||||
|
"end": 300,
|
||||||
|
"property": "color",
|
||||||
|
"value": "red"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"start": 266,
|
||||||
|
"end": 304
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"content": {
|
||||||
|
"start": 7,
|
||||||
|
"end": 305,
|
||||||
|
"styles": "\n /* test that all these are parsed correctly */\n\t::view-transition-old(x-y) {\n\t\tcolor: red;\n }\n\t:global(::view-transition-old(x-y)) {\n\t\tcolor: red;\n }\n\t::highlight(rainbow-color-1) {\n\t\tcolor: red;\n\t}\n\tcustom-element::part(foo) {\n\t\tcolor: red;\n\t}\n\t::slotted(.content) {\n\t\tcolor: red;\n\t}\n"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"js": [],
|
||||||
|
"start": null,
|
||||||
|
"end": null,
|
||||||
|
"type": "Root",
|
||||||
|
"fragment": {
|
||||||
|
"type": "Fragment",
|
||||||
|
"nodes": [],
|
||||||
|
"transparent": false
|
||||||
|
},
|
||||||
|
"options": null
|
||||||
|
}
|
||||||
@ -0,0 +1,44 @@
|
|||||||
|
import { test } from '../../test';
|
||||||
|
|
||||||
|
export default test({
|
||||||
|
html: `
|
||||||
|
<p>1</p>
|
||||||
|
<p>2</p>
|
||||||
|
<p>3</p>
|
||||||
|
<p>4</p>
|
||||||
|
<p>5</p>
|
||||||
|
<p>6</p>
|
||||||
|
|
||||||
|
<h1>Bag'ol stores</h1>
|
||||||
|
<p>6</p>
|
||||||
|
<p></p>
|
||||||
|
<p></p>
|
||||||
|
|
||||||
|
<button>Click me!</button>
|
||||||
|
`,
|
||||||
|
|
||||||
|
async test({ assert, target, window }) {
|
||||||
|
const button = target.querySelector('button');
|
||||||
|
const clickEvent = new window.Event('click', { bubbles: true });
|
||||||
|
await button?.dispatchEvent(clickEvent);
|
||||||
|
|
||||||
|
assert.htmlEqual(
|
||||||
|
target.innerHTML,
|
||||||
|
`
|
||||||
|
<p>7</p>
|
||||||
|
<p>8</p>
|
||||||
|
<p>9</p>
|
||||||
|
<p>10</p>
|
||||||
|
<p>11</p>
|
||||||
|
<p>12</p>
|
||||||
|
|
||||||
|
<h1>Bag'ol stores</h1>
|
||||||
|
<p>12</p>
|
||||||
|
<p>14</p>
|
||||||
|
<p>15</p>
|
||||||
|
|
||||||
|
<button>Click me!</button>
|
||||||
|
`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
||||||
@ -0,0 +1,42 @@
|
|||||||
|
<script>
|
||||||
|
import { get, writable } from 'svelte/store'
|
||||||
|
|
||||||
|
let bagOlStores = writable([1, 2, 3, writable(4), writable(5), writable(6)]);
|
||||||
|
|
||||||
|
let firstNonStore, secondNonStore, thirdNonStore, firstStore, secondStore, thirdStore;
|
||||||
|
([firstNonStore, secondNonStore, thirdNonStore, firstStore, secondStore, thirdStore] = $bagOlStores);
|
||||||
|
|
||||||
|
function changeStores() {
|
||||||
|
$bagOlStores = ([
|
||||||
|
firstNonStore,
|
||||||
|
secondNonStore,
|
||||||
|
thirdNonStore,
|
||||||
|
firstStore,
|
||||||
|
$secondStore,
|
||||||
|
thirdStore
|
||||||
|
] = [
|
||||||
|
7,
|
||||||
|
8,
|
||||||
|
9,
|
||||||
|
writable(10),
|
||||||
|
11,
|
||||||
|
writable(12),
|
||||||
|
writable(14),
|
||||||
|
writable(15)
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<p>{firstNonStore}</p>
|
||||||
|
<p>{secondNonStore}</p>
|
||||||
|
<p>{thirdNonStore}</p>
|
||||||
|
<p>{$firstStore}</p>
|
||||||
|
<p>{$secondStore}</p>
|
||||||
|
<p>{$thirdStore}</p>
|
||||||
|
|
||||||
|
<h1>Bag'ol stores</h1>
|
||||||
|
<p>{get($bagOlStores[5])}</p>
|
||||||
|
<p>{get($bagOlStores[6])}</p>
|
||||||
|
<p>{get($bagOlStores[7])}</p>
|
||||||
|
|
||||||
|
<button on:click={changeStores}>Click me!</button>
|
||||||
@ -0,0 +1,44 @@
|
|||||||
|
import { test } from '../../test';
|
||||||
|
|
||||||
|
export default test({
|
||||||
|
html: `
|
||||||
|
<p>1</p>
|
||||||
|
<p>2</p>
|
||||||
|
<p>3</p>
|
||||||
|
<p>4</p>
|
||||||
|
<p>5</p>
|
||||||
|
<p>6</p>
|
||||||
|
|
||||||
|
<h1>Bag'ol stores</h1>
|
||||||
|
<p>4</p>
|
||||||
|
<p>5</p>
|
||||||
|
<p>6</p>
|
||||||
|
|
||||||
|
<button>Click me!</button>
|
||||||
|
`,
|
||||||
|
|
||||||
|
async test({ assert, target, window }) {
|
||||||
|
const button = target.querySelector('button');
|
||||||
|
const clickEvent = new window.Event('click', { bubbles: true });
|
||||||
|
await button?.dispatchEvent(clickEvent);
|
||||||
|
|
||||||
|
assert.htmlEqual(
|
||||||
|
target.innerHTML,
|
||||||
|
`
|
||||||
|
<p>7</p>
|
||||||
|
<p>8</p>
|
||||||
|
<p>9</p>
|
||||||
|
<p>10</p>
|
||||||
|
<p>11</p>
|
||||||
|
<p>12</p>
|
||||||
|
|
||||||
|
<h1>Bag'ol stores</h1>
|
||||||
|
<p>14</p>
|
||||||
|
<p>13</p>
|
||||||
|
<p>12</p>
|
||||||
|
|
||||||
|
<button>Click me!</button>
|
||||||
|
`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
||||||
@ -0,0 +1,48 @@
|
|||||||
|
<script>
|
||||||
|
import { get, writable } from 'svelte/store'
|
||||||
|
|
||||||
|
let bagOlStores = writable({
|
||||||
|
firstNonStore: 1,
|
||||||
|
secondNonStore: 2,
|
||||||
|
thirdNonStore: 3,
|
||||||
|
firstStore: writable(4),
|
||||||
|
secondStore: writable(5),
|
||||||
|
thirdStore: writable(6)
|
||||||
|
});
|
||||||
|
|
||||||
|
let { firstNonStore, secondNonStore, thirdNonStore, firstStore, secondStore, thirdStore } = $bagOlStores;
|
||||||
|
|
||||||
|
function changeStores() {
|
||||||
|
$bagOlStores = ({
|
||||||
|
thirdStore,
|
||||||
|
$secondStore,
|
||||||
|
$firstStore,
|
||||||
|
firstNonStore,
|
||||||
|
secondNonStore,
|
||||||
|
thirdNonStore,
|
||||||
|
} = {
|
||||||
|
firstNonStore: 7,
|
||||||
|
secondNonStore: 8,
|
||||||
|
thirdNonStore: 9,
|
||||||
|
$firstStore: 10,
|
||||||
|
$secondStore: 11,
|
||||||
|
firstStore: writable(14),
|
||||||
|
secondStore: writable(13),
|
||||||
|
thirdStore: writable(12)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<p>{firstNonStore}</p>
|
||||||
|
<p>{secondNonStore}</p>
|
||||||
|
<p>{thirdNonStore}</p>
|
||||||
|
<p>{$firstStore}</p>
|
||||||
|
<p>{$secondStore}</p>
|
||||||
|
<p>{$thirdStore}</p>
|
||||||
|
|
||||||
|
<h1>Bag'ol stores</h1>
|
||||||
|
<p>{get($bagOlStores.firstStore)}</p>
|
||||||
|
<p>{get($bagOlStores.secondStore)}</p>
|
||||||
|
<p>{get($bagOlStores.thirdStore)}</p>
|
||||||
|
|
||||||
|
<button on:click={changeStores}>Click me!</button>
|
||||||
@ -0,0 +1,9 @@
|
|||||||
|
<script>
|
||||||
|
let z = 8;
|
||||||
|
let { a, b = a, c = b * b, d = z * b + c } = $props();
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<p>{a}</p>
|
||||||
|
<p>{b}</p>
|
||||||
|
<p>{c}</p>
|
||||||
|
<p>{d}</p>
|
||||||
@ -0,0 +1,5 @@
|
|||||||
|
import { test } from '../../test';
|
||||||
|
|
||||||
|
export default test({
|
||||||
|
html: `<p>5</p><p>5</p><p>25</p><p>65</p>`
|
||||||
|
});
|
||||||
@ -0,0 +1,5 @@
|
|||||||
|
<script>
|
||||||
|
import Test from './Test.svelte'
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<Test a={5} />
|
||||||
@ -0,0 +1,5 @@
|
|||||||
|
import { test } from '../../test';
|
||||||
|
|
||||||
|
export default test({
|
||||||
|
html: '<div>/ $clicks: 0 `tim$es` \\</div><div>$dollars `backticks` pyramid /\\</div>'
|
||||||
|
});
|
||||||
@ -0,0 +1,6 @@
|
|||||||
|
<div>
|
||||||
|
/ $clicks: {0} `tim${"e"}s` \
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
$dollars `backticks` pyramid /\
|
||||||
|
</div>
|
||||||
@ -0,0 +1,9 @@
|
|||||||
|
<script>
|
||||||
|
const { item } = $props();
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
{#if item}
|
||||||
|
{item.length}
|
||||||
|
{/if}
|
||||||
|
</div>
|
||||||
@ -0,0 +1,26 @@
|
|||||||
|
import { flushSync } from 'svelte';
|
||||||
|
import { test } from '../../test';
|
||||||
|
|
||||||
|
export default test({
|
||||||
|
async test({ assert, target, component }) {
|
||||||
|
const [b1, b2] = target.querySelectorAll('button');
|
||||||
|
assert.htmlEqual(
|
||||||
|
target.innerHTML,
|
||||||
|
'<div>5</div><div>5</div><div>3</div><button>set null</button><button>set object</button'
|
||||||
|
);
|
||||||
|
flushSync(() => {
|
||||||
|
b2.click();
|
||||||
|
});
|
||||||
|
assert.htmlEqual(
|
||||||
|
target.innerHTML,
|
||||||
|
'<div>5</div><div>5</div><div>3</div><button>set null</button><button>set object</button'
|
||||||
|
);
|
||||||
|
flushSync(() => {
|
||||||
|
b1.click();
|
||||||
|
});
|
||||||
|
assert.htmlEqual(
|
||||||
|
target.innerHTML,
|
||||||
|
'<div>5</div><div></div><div>3</div><button>set null</button><button>set object</button'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
||||||
@ -0,0 +1,12 @@
|
|||||||
|
<script>
|
||||||
|
import Component from './Component.svelte';
|
||||||
|
|
||||||
|
let items = $state(['hello', 'world', 'bye']);
|
||||||
|
</script>
|
||||||
|
|
||||||
|
{#each items as item}
|
||||||
|
<Component {item} />
|
||||||
|
{/each}
|
||||||
|
|
||||||
|
<button onclick={() => (items[1] = null)}> set null </button>
|
||||||
|
<button onclick={() => (items[1] = 'hello')}> set object </button>
|
||||||
@ -0,0 +1,22 @@
|
|||||||
|
import { test } from '../../test';
|
||||||
|
import { log } from './log.js';
|
||||||
|
|
||||||
|
export default test({
|
||||||
|
html: `<button>0</button>`,
|
||||||
|
|
||||||
|
before_test() {
|
||||||
|
log.length = 0;
|
||||||
|
},
|
||||||
|
|
||||||
|
async test({ assert, target }) {
|
||||||
|
const btn = target.querySelector('button');
|
||||||
|
|
||||||
|
await btn?.click();
|
||||||
|
assert.htmlEqual(target.innerHTML, `<button>0</button>`);
|
||||||
|
|
||||||
|
await btn?.click();
|
||||||
|
assert.htmlEqual(target.innerHTML, `<button>0</button>`);
|
||||||
|
|
||||||
|
assert.deepEqual(log, ['read only', 'read only']);
|
||||||
|
}
|
||||||
|
});
|
||||||
@ -0,0 +1,2 @@
|
|||||||
|
/** @type {any[]} */
|
||||||
|
export const log = [];
|
||||||
@ -0,0 +1,16 @@
|
|||||||
|
<script>
|
||||||
|
import { log } from './log.js';
|
||||||
|
|
||||||
|
class Counter {
|
||||||
|
count = $state.frozen({ a: 0 });
|
||||||
|
}
|
||||||
|
const counter = new Counter();
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<button on:click={() => {
|
||||||
|
try {
|
||||||
|
counter.count.a++
|
||||||
|
} catch (e) {
|
||||||
|
log.push('read only')
|
||||||
|
}
|
||||||
|
}}>{counter.count.a}</button>
|
||||||
@ -0,0 +1,15 @@
|
|||||||
|
import { test } from '../../test';
|
||||||
|
|
||||||
|
export default test({
|
||||||
|
html: `<button>0</button>`,
|
||||||
|
|
||||||
|
async test({ assert, target }) {
|
||||||
|
const btn = target.querySelector('button');
|
||||||
|
|
||||||
|
await btn?.click();
|
||||||
|
assert.htmlEqual(target.innerHTML, `<button>1</button>`);
|
||||||
|
|
||||||
|
await btn?.click();
|
||||||
|
assert.htmlEqual(target.innerHTML, `<button>2</button>`);
|
||||||
|
}
|
||||||
|
});
|
||||||
@ -0,0 +1,8 @@
|
|||||||
|
<script>
|
||||||
|
class Counter {
|
||||||
|
count = $state.frozen(0);
|
||||||
|
}
|
||||||
|
const counter = new Counter();
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<button on:click={() => counter.count++}>{counter.count}</button>
|
||||||
@ -0,0 +1,22 @@
|
|||||||
|
import { test } from '../../test';
|
||||||
|
import { log } from './log.js';
|
||||||
|
|
||||||
|
export default test({
|
||||||
|
html: `<button>0</button>`,
|
||||||
|
|
||||||
|
before_test() {
|
||||||
|
log.length = 0;
|
||||||
|
},
|
||||||
|
|
||||||
|
async test({ assert, target }) {
|
||||||
|
const btn = target.querySelector('button');
|
||||||
|
|
||||||
|
await btn?.click();
|
||||||
|
assert.htmlEqual(target.innerHTML, `<button>0</button>`);
|
||||||
|
|
||||||
|
await btn?.click();
|
||||||
|
assert.htmlEqual(target.innerHTML, `<button>0</button>`);
|
||||||
|
|
||||||
|
assert.deepEqual(log, ['read only', 'read only']);
|
||||||
|
}
|
||||||
|
});
|
||||||
@ -0,0 +1,2 @@
|
|||||||
|
/** @type {any[]} */
|
||||||
|
export const log = [];
|
||||||
@ -0,0 +1,27 @@
|
|||||||
|
<script>
|
||||||
|
import { log } from './log.js';
|
||||||
|
|
||||||
|
class Counter {
|
||||||
|
#count = $state.frozen();
|
||||||
|
|
||||||
|
constructor(initial_count) {
|
||||||
|
this.#count = { a: initial_count };
|
||||||
|
}
|
||||||
|
|
||||||
|
get count() {
|
||||||
|
return this.#count;
|
||||||
|
}
|
||||||
|
set count(val) {
|
||||||
|
this.#count = val;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const counter = new Counter(0);
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<button on:click={() => {
|
||||||
|
try {
|
||||||
|
counter.count.a++
|
||||||
|
} catch (e) {
|
||||||
|
log.push('read only')
|
||||||
|
}
|
||||||
|
}}>{counter.count.a}</button>
|
||||||
@ -0,0 +1,15 @@
|
|||||||
|
import { test } from '../../test';
|
||||||
|
|
||||||
|
export default test({
|
||||||
|
html: `<button>0</button>`,
|
||||||
|
|
||||||
|
async test({ assert, target }) {
|
||||||
|
const btn = target.querySelector('button');
|
||||||
|
|
||||||
|
await btn?.click();
|
||||||
|
assert.htmlEqual(target.innerHTML, `<button>1</button>`);
|
||||||
|
|
||||||
|
await btn?.click();
|
||||||
|
assert.htmlEqual(target.innerHTML, `<button>2</button>`);
|
||||||
|
}
|
||||||
|
});
|
||||||
@ -0,0 +1,19 @@
|
|||||||
|
<script>
|
||||||
|
class Counter {
|
||||||
|
#count = $state.frozen(0);
|
||||||
|
|
||||||
|
constructor(initial_count) {
|
||||||
|
this.#count = initial_count;
|
||||||
|
}
|
||||||
|
|
||||||
|
get count() {
|
||||||
|
return this.#count;
|
||||||
|
}
|
||||||
|
set count(val) {
|
||||||
|
this.#count = val;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const counter = new Counter(0);
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<button on:click={() => counter.count++}>{counter.count}</button>
|
||||||
@ -0,0 +1,23 @@
|
|||||||
|
import { test } from '../../test';
|
||||||
|
|
||||||
|
// Tests that event delegation still works when the element with the event listener is moved outside the container
|
||||||
|
export default test({
|
||||||
|
async test({ assert, target }) {
|
||||||
|
const btn1 = target.parentElement?.querySelector('button');
|
||||||
|
const btn2 = target.querySelector('button');
|
||||||
|
|
||||||
|
btn1?.click();
|
||||||
|
await Promise.resolve();
|
||||||
|
assert.htmlEqual(
|
||||||
|
target.parentElement?.innerHTML ?? '',
|
||||||
|
'<main><div><button>clicks: 1</button></div></main><button>clicks: 1</button>'
|
||||||
|
);
|
||||||
|
|
||||||
|
btn2?.click();
|
||||||
|
await Promise.resolve();
|
||||||
|
assert.htmlEqual(
|
||||||
|
target.parentElement?.innerHTML ?? '',
|
||||||
|
'<main><div><button>clicks: 2</button></div></main><button>clicks: 2</button>'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
||||||
@ -0,0 +1,12 @@
|
|||||||
|
<script>
|
||||||
|
let count = $state(0);
|
||||||
|
let el;
|
||||||
|
$effect(() => {
|
||||||
|
document.getElementsByTagName('body')[0].appendChild(el);
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<button bind:this={el} onclick={() => count++}>clicks: {count}</button>
|
||||||
|
<button onclick={() => count++}>clicks: {count}</button>
|
||||||
|
</div>
|
||||||
@ -0,0 +1,40 @@
|
|||||||
|
import { test } from '../../test';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @type {any[]}
|
||||||
|
*/
|
||||||
|
let log;
|
||||||
|
/**
|
||||||
|
* @type {typeof console.log}}
|
||||||
|
*/
|
||||||
|
let original_log;
|
||||||
|
|
||||||
|
export default test({
|
||||||
|
compileOptions: {
|
||||||
|
dev: true
|
||||||
|
},
|
||||||
|
before_test() {
|
||||||
|
log = [];
|
||||||
|
original_log = console.log;
|
||||||
|
console.log = (...v) => {
|
||||||
|
log.push(...v);
|
||||||
|
};
|
||||||
|
},
|
||||||
|
after_test() {
|
||||||
|
console.log = original_log;
|
||||||
|
},
|
||||||
|
async test({ assert, target }) {
|
||||||
|
const [b1] = target.querySelectorAll('button');
|
||||||
|
b1.click();
|
||||||
|
await Promise.resolve();
|
||||||
|
|
||||||
|
assert.deepEqual(log, [
|
||||||
|
'init',
|
||||||
|
{ x: { count: 0 } },
|
||||||
|
[{ count: 0 }],
|
||||||
|
'update',
|
||||||
|
{ x: { count: 1 } },
|
||||||
|
[{ count: 1 }]
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
});
|
||||||
@ -0,0 +1,7 @@
|
|||||||
|
<script>
|
||||||
|
let x = $state({count: 0});
|
||||||
|
|
||||||
|
$inspect({x}, [x]);
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<button on:click={() => x.count++}>{x.count}</button>
|
||||||
@ -0,0 +1,38 @@
|
|||||||
|
import { test } from '../../test';
|
||||||
|
|
||||||
|
export default test({
|
||||||
|
html: `
|
||||||
|
<button>Update</button>
|
||||||
|
|
||||||
|
<p>0</p>
|
||||||
|
<p>b</p>
|
||||||
|
<p>true</p>
|
||||||
|
<p>0</p>
|
||||||
|
<p>10</p>
|
||||||
|
<p>12</p>
|
||||||
|
<p>15</p>
|
||||||
|
<p>16</p>
|
||||||
|
`,
|
||||||
|
|
||||||
|
async test({ assert, target, window }) {
|
||||||
|
const button = target.querySelector('button');
|
||||||
|
const clickEvent = new window.Event('click', { bubbles: true });
|
||||||
|
await button?.dispatchEvent(clickEvent);
|
||||||
|
|
||||||
|
assert.htmlEqual(
|
||||||
|
target.innerHTML,
|
||||||
|
`
|
||||||
|
<button>Update</button>
|
||||||
|
|
||||||
|
<p>5</p>
|
||||||
|
<p>d</p>
|
||||||
|
<p>false</p>
|
||||||
|
<p>3</p>
|
||||||
|
<p>100</p>
|
||||||
|
<p>120</p>
|
||||||
|
<p>25</p>
|
||||||
|
<p>26</p>
|
||||||
|
`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
||||||
@ -0,0 +1,23 @@
|
|||||||
|
<script>
|
||||||
|
let a = $state(0);
|
||||||
|
let b = $state("b");
|
||||||
|
let c = $state(true);
|
||||||
|
let d = $state([]);
|
||||||
|
let e = $state({ x: 10, y: 12 });
|
||||||
|
let f = $state({ w: 15, v: 16 });
|
||||||
|
|
||||||
|
function change() {
|
||||||
|
({ d, e, g: [f.w, f.v] } = { d: ([a, b, c] = [5, "d", false]), e: { x: 100, y: 120 }, g: [25, 26] });
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<button on:click={change}>Update</button>
|
||||||
|
|
||||||
|
<p>{a}</p>
|
||||||
|
<p>{b}</p>
|
||||||
|
<p>{c}</p>
|
||||||
|
<p>{d.length}</p>
|
||||||
|
<p>{e.x}</p>
|
||||||
|
<p>{e.y}</p>
|
||||||
|
<p>{f.w}</p>
|
||||||
|
<p>{f.v}</p>
|
||||||
@ -0,0 +1,11 @@
|
|||||||
|
import { test } from '../../test';
|
||||||
|
|
||||||
|
export default test({
|
||||||
|
async test({ assert, target }) {
|
||||||
|
const [b1] = target.querySelectorAll('button');
|
||||||
|
b1.click();
|
||||||
|
await Promise.resolve();
|
||||||
|
|
||||||
|
assert.htmlEqual(target.innerHTML, `<button>0, 1</button>`);
|
||||||
|
}
|
||||||
|
});
|
||||||
@ -0,0 +1,11 @@
|
|||||||
|
<script>
|
||||||
|
let items = $state.frozen([0]);
|
||||||
|
|
||||||
|
const addItem = () => {
|
||||||
|
items = [...items, items.length];
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<button on:click={addItem}>
|
||||||
|
{items.join(', ')}
|
||||||
|
</button>
|
||||||
@ -0,0 +1,17 @@
|
|||||||
|
import { test } from '../../test';
|
||||||
|
import { log } from './log.js';
|
||||||
|
|
||||||
|
export default test({
|
||||||
|
before_test() {
|
||||||
|
log.length = 0;
|
||||||
|
},
|
||||||
|
|
||||||
|
async test({ assert, target }) {
|
||||||
|
const [b1, b2] = target.querySelectorAll('button');
|
||||||
|
b1.click();
|
||||||
|
b2.click();
|
||||||
|
await Promise.resolve();
|
||||||
|
|
||||||
|
assert.deepEqual(log, [0, 1]);
|
||||||
|
}
|
||||||
|
});
|
||||||
@ -0,0 +1,2 @@
|
|||||||
|
/** @type {any[]} */
|
||||||
|
export const log = [];
|
||||||
@ -0,0 +1,13 @@
|
|||||||
|
<script>
|
||||||
|
import { log } from './log.js';
|
||||||
|
|
||||||
|
let x = $state.frozen(0);
|
||||||
|
let y = $state.frozen(0);
|
||||||
|
|
||||||
|
$effect(() => {
|
||||||
|
log.push(x);
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<button on:click={() => x++}>{x}</button>
|
||||||
|
<button on:click={() => y++}>{y}</button>
|
||||||
@ -0,0 +1,12 @@
|
|||||||
|
import { test } from '../../test';
|
||||||
|
|
||||||
|
export default test({
|
||||||
|
test({ assert, component, target }) {
|
||||||
|
const div = /** @type {HTMLDivElement & { foo?: number }} */ (target.querySelector('div'));
|
||||||
|
|
||||||
|
assert.equal(div.foo, undefined);
|
||||||
|
component.foo = 2;
|
||||||
|
component.visible = false;
|
||||||
|
assert.equal(div.foo, 2);
|
||||||
|
}
|
||||||
|
});
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in new issue