diff --git a/.github/workflows/node.js.yml b/.github/workflows/node.js.yml index 9acc6de3f..cb004fcf5 100644 --- a/.github/workflows/node.js.yml +++ b/.github/workflows/node.js.yml @@ -16,7 +16,7 @@ jobs: strategy: matrix: - node-version: [18.x] + node-version: [20.x] # See supported Node.js release schedule at https://nodejs.org/en/about/releases/ steps: diff --git a/LICENSE.md b/LICENSE.md new file mode 100644 index 000000000..0598ad131 --- /dev/null +++ b/LICENSE.md @@ -0,0 +1,9 @@ +MIT License + +Copyright (c) 2023 [these people](https://github.com/sveltejs/learn.svelte.dev/graphs/contributors) + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/content/tutorial/01-svelte/01-introduction/03-dynamic-attributes/README.md b/content/tutorial/01-svelte/01-introduction/03-dynamic-attributes/README.md index e03524b1a..6c325239f 100644 --- a/content/tutorial/01-svelte/01-introduction/03-dynamic-attributes/README.md +++ b/content/tutorial/01-svelte/01-introduction/03-dynamic-attributes/README.md @@ -32,5 +32,5 @@ It's not uncommon to have an attribute where the name and value are the same, li ```svelte /// file: App.svelte -A man dances. +{name} dances. ``` diff --git a/content/tutorial/01-svelte/02-reactivity/04-updating-arrays-and-objects/README.md b/content/tutorial/01-svelte/02-reactivity/04-updating-arrays-and-objects/README.md index 74e3a581f..49e0654ab 100644 --- a/content/tutorial/01-svelte/02-reactivity/04-updating-arrays-and-objects/README.md +++ b/content/tutorial/01-svelte/02-reactivity/04-updating-arrays-and-objects/README.md @@ -38,8 +38,9 @@ A simple rule of thumb: the name of the updated variable must appear on the left ```js /// no-file +const obj = { foo: { bar: 1 } }; const foo = obj.foo; -foo.bar = 'baz'; +foo.bar = 2; ``` ...won't trigger reactivity on `obj.foo.bar`, unless you follow it up with `obj = obj`. diff --git a/content/tutorial/01-svelte/04-logic/05-keyed-each-blocks/README.md b/content/tutorial/01-svelte/04-logic/05-keyed-each-blocks/README.md index 9f8688a0e..a87e34367 100644 --- a/content/tutorial/01-svelte/04-logic/05-keyed-each-blocks/README.md +++ b/content/tutorial/01-svelte/04-logic/05-keyed-each-blocks/README.md @@ -2,13 +2,18 @@ title: Keyed each blocks --- -By default, when you modify the value of an `each` block, it will add and remove items at the _end_ of the block, and update any values that have changed. That might not be what you want. +By default, when you modify the value of an `each` block, it will add and remove DOM nodes at the _end_ of the block, and update any values that have changed. That might not be what you want. -It's easier to show why than to explain. Click the 'Remove first thing' button a few times, and notice what happens: it does not remove the first `` component, but rather the _last_ DOM node. Then it updates the `name` value in the remaining DOM nodes, but not the emoji, which is fixed when each `` is created. +It's easier to show why than to explain. The `` component sets the emoji as a constant on initialization, but the name is passed in via a prop. + +Click the 'Remove first thing' button a few times, and notice what happens: + +1. It removes the last component. +2. It then updates the `name` value in the remaining DOM nodes, but not the emoji, which is fixed when each `` is created. Instead, we'd like to remove only the first `` component and its DOM node, and leave the others unaffected. -To do that, we specify a unique identifier (or "key") for the `each` block: +To do that, we specify a unique identifier (or "key") for each iteration of the `each` block: ```svelte /// file: App.svelte @@ -17,6 +22,6 @@ To do that, we specify a unique identifier (or "key") for the `each` block: {/each} ``` -Here, `(thing.id)` is the _key_, which tells Svelte how to figure out which DOM node to change when the component updates. +Here, `(thing.id)` is the _key_, which tells Svelte how to figure out what to update when the values (`name` in this example) change. > You can use any object as the key, as Svelte uses a `Map` internally — in other words you could do `(thing)` instead of `(thing.id)`. Using a string or number is generally safer, however, since it means identity persists without referential equality, for example when updating with fresh data from an API server. diff --git a/content/tutorial/01-svelte/05-events/02-inline-handlers/README.md b/content/tutorial/01-svelte/05-events/02-inline-handlers/README.md index 7b59d9e56..b0aa0f9bf 100644 --- a/content/tutorial/01-svelte/05-events/02-inline-handlers/README.md +++ b/content/tutorial/01-svelte/05-events/02-inline-handlers/README.md @@ -20,7 +20,7 @@ You can also declare event handlers inline: m = { x: e.clientX, y: e.clientY }; }+++} > - The mouse position is {m.x} x {m.y} + The pointer is at {m.x} x {m.y} ``` diff --git a/content/tutorial/01-svelte/05-events/06-dom-event-forwarding/app-a/src/lib/App.svelte b/content/tutorial/01-svelte/05-events/06-dom-event-forwarding/app-a/src/lib/App.svelte index b47a06f1e..33d318c91 100644 --- a/content/tutorial/01-svelte/05-events/06-dom-event-forwarding/app-a/src/lib/App.svelte +++ b/content/tutorial/01-svelte/05-events/06-dom-event-forwarding/app-a/src/lib/App.svelte @@ -6,6 +6,7 @@ audio.src = horn; function handleClick() { + audio.load(); audio.play(); } diff --git a/content/tutorial/01-svelte/06-bindings/03-checkbox-inputs/README.md b/content/tutorial/01-svelte/06-bindings/03-checkbox-inputs/README.md index 8df2be7c2..dc79573de 100644 --- a/content/tutorial/01-svelte/06-bindings/03-checkbox-inputs/README.md +++ b/content/tutorial/01-svelte/06-bindings/03-checkbox-inputs/README.md @@ -6,5 +6,5 @@ Checkboxes are used for toggling between states. Instead of binding to `input.va ```svelte /// file: App.svelte - + ``` diff --git a/content/tutorial/01-svelte/07-lifecycle/01-onmount/README.md b/content/tutorial/01-svelte/07-lifecycle/01-onmount/README.md index e4dfde99a..4195b5c69 100644 --- a/content/tutorial/01-svelte/07-lifecycle/01-onmount/README.md +++ b/content/tutorial/01-svelte/07-lifecycle/01-onmount/README.md @@ -4,7 +4,7 @@ title: onMount Every component has a _lifecycle_ that starts when it is created, and ends when it is destroyed. There are a handful of functions that allow you to run code at key moments during that lifecycle. The one you'll use most frequently is `onMount`, which runs after the component is first rendered to the DOM. -In this exercise, we have a `` that we'd like to animate, using the `paint` function in `gradient.js`. Begin by importing the function from `svelte`: +In this exercise, we have a `` that we'd like to animate, using the `paint` function in `gradient.js`. Begin by importing the `onMount` function from `svelte`: ```svelte /// file: App.svelte @@ -14,7 +14,7 @@ In this exercise, we have a `` that we'd like to animate, using the `pai ``` -Then, add a function that runs when the component mounts: +Then, add a callback that runs when the component mounts: ```svelte /// file: App.svelte @@ -41,7 +41,7 @@ So far so good — you should see gently undulating colours in the shape of the ```js /// file: App.svelte onMount(() => { - const canvas = document.querySelector('canvas') + const canvas = document.querySelector('canvas'); const context = canvas.getContext('2d'); +++let frame =+++ requestAnimationFrame(function loop(t) { diff --git a/content/tutorial/01-svelte/07-lifecycle/01-onmount/app-a/src/lib/App.svelte b/content/tutorial/01-svelte/07-lifecycle/01-onmount/app-a/src/lib/App.svelte index 39b42393d..b36b80ce0 100644 --- a/content/tutorial/01-svelte/07-lifecycle/01-onmount/app-a/src/lib/App.svelte +++ b/content/tutorial/01-svelte/07-lifecycle/01-onmount/app-a/src/lib/App.svelte @@ -5,7 +5,7 @@ +> - \ No newline at end of file + diff --git a/content/tutorial/02-advanced-svelte/05-bindings/03-media-elements/app-b/src/lib/AudioPlayer.svelte b/content/tutorial/02-advanced-svelte/05-bindings/03-media-elements/app-b/src/lib/AudioPlayer.svelte index aa995d34a..fcfbc28ce 100644 --- a/content/tutorial/02-advanced-svelte/05-bindings/03-media-elements/app-b/src/lib/AudioPlayer.svelte +++ b/content/tutorial/02-advanced-svelte/05-bindings/03-media-elements/app-b/src/lib/AudioPlayer.svelte @@ -23,17 +23,17 @@ bind:currentTime={time} bind:duration bind:paused - preload="none" + preload="metadata" on:ended={() => { time = 0; }} - /> + >
@@ -69,7 +69,7 @@ }); }} > -
+
{duration ? format(duration) : '--:--'}
diff --git a/content/tutorial/02-advanced-svelte/05-bindings/05-bind-this/app-a/src/lib/App.svelte b/content/tutorial/02-advanced-svelte/05-bindings/05-bind-this/app-a/src/lib/App.svelte index de10e6465..582abc630 100644 --- a/content/tutorial/02-advanced-svelte/05-bindings/05-bind-this/app-a/src/lib/App.svelte +++ b/content/tutorial/02-advanced-svelte/05-bindings/05-bind-this/app-a/src/lib/App.svelte @@ -20,7 +20,7 @@ +> ``` @@ -55,4 +55,4 @@ Any parent element (such as `
`) can set the value of `--color The values can be dynamic, like any other attribute. -This feature works by wrapping each component in a `
`, where needed, and applying the custom properties to it. \ No newline at end of file +This feature works by wrapping each component in a `
`, where needed, and applying the custom properties to it. diff --git a/content/tutorial/02-advanced-svelte/06-classes-and-styles/04-component-styles/app-a/src/lib/Box.svelte b/content/tutorial/02-advanced-svelte/06-classes-and-styles/04-component-styles/app-a/src/lib/Box.svelte index 5b700e91d..87eee2f31 100644 --- a/content/tutorial/02-advanced-svelte/06-classes-and-styles/04-component-styles/app-a/src/lib/Box.svelte +++ b/content/tutorial/02-advanced-svelte/06-classes-and-styles/04-component-styles/app-a/src/lib/Box.svelte @@ -1,4 +1,4 @@ -
+
\ No newline at end of file + diff --git a/content/tutorial/02-advanced-svelte/06-classes-and-styles/04-component-styles/app-b/src/lib/Box.svelte b/content/tutorial/02-advanced-svelte/06-classes-and-styles/04-component-styles/app-b/src/lib/Box.svelte index ab5da5e35..c91e97bf7 100644 --- a/content/tutorial/02-advanced-svelte/06-classes-and-styles/04-component-styles/app-b/src/lib/Box.svelte +++ b/content/tutorial/02-advanced-svelte/06-classes-and-styles/04-component-styles/app-b/src/lib/Box.svelte @@ -1,4 +1,4 @@ -
+
\ No newline at end of file + diff --git a/content/tutorial/02-advanced-svelte/07-composition/01-slots/README.md b/content/tutorial/02-advanced-svelte/07-composition/01-slots/README.md index fbf7bb8ba..1f9fe948c 100644 --- a/content/tutorial/02-advanced-svelte/07-composition/01-slots/README.md +++ b/content/tutorial/02-advanced-svelte/07-composition/01-slots/README.md @@ -15,8 +15,8 @@ Just like elements can have children... ```svelte /// file: Card.svelte -
- ++++++ +
+ ++++++
``` diff --git a/content/tutorial/02-advanced-svelte/07-composition/01-slots/app-a/src/lib/paper.svg b/content/tutorial/02-advanced-svelte/07-composition/01-slots/app-a/src/lib/paper.svg index f8f704fdf..5dba50c15 100644 --- a/content/tutorial/02-advanced-svelte/07-composition/01-slots/app-a/src/lib/paper.svg +++ b/content/tutorial/02-advanced-svelte/07-composition/01-slots/app-a/src/lib/paper.svg @@ -6,5 +6,5 @@ - - \ No newline at end of file + + diff --git a/content/tutorial/02-advanced-svelte/07-composition/02-named-slots/README.md b/content/tutorial/02-advanced-svelte/07-composition/02-named-slots/README.md index 7918e0423..901e987ce 100644 --- a/content/tutorial/02-advanced-svelte/07-composition/02-named-slots/README.md +++ b/content/tutorial/02-advanced-svelte/07-composition/02-named-slots/README.md @@ -4,20 +4,20 @@ title: Named slots The previous example contained a _default slot_, which renders the direct children of a component. Sometimes you will need more control over placement. In those cases, we can use _named slots_. -Inside the `` component, we've got `` and others for `company` and `address`. Let's add the corresponding named slots in `Card.svelte`: +Inside `App.svelte`, we're rendering a `` component that contains `` and others for `company` and `address`. Let's add the corresponding named slots in `Card.svelte`: ```svelte /// file: Card.svelte
+++
- - + +
+++ - - + + +++
- +
+++
``` @@ -47,7 +47,7 @@ Alternatively, we could use the `:global` modifier inside `Card.svelte` to targe ```svelte /// file: Card.svelte -``` \ No newline at end of file +``` diff --git a/content/tutorial/02-advanced-svelte/07-composition/02-named-slots/app-a/src/lib/App.svelte b/content/tutorial/02-advanced-svelte/07-composition/02-named-slots/app-a/src/lib/App.svelte index 594151af4..a9bde36e5 100644 --- a/content/tutorial/02-advanced-svelte/07-composition/02-named-slots/app-a/src/lib/App.svelte +++ b/content/tutorial/02-advanced-svelte/07-composition/02-named-slots/app-a/src/lib/App.svelte @@ -14,7 +14,7 @@ Mergers and Aquisitions
- 358 Exchange Place, New York, N.Y. 100099 fax 212 555 6390 telex 10 4534 + 358 Exchange Place, New York, N.Y. 10099 fax 212 555 6390 telex 10 4534
diff --git a/content/tutorial/02-advanced-svelte/07-composition/02-named-slots/app-a/src/lib/paper.svg b/content/tutorial/02-advanced-svelte/07-composition/02-named-slots/app-a/src/lib/paper.svg index f8f704fdf..5dba50c15 100644 --- a/content/tutorial/02-advanced-svelte/07-composition/02-named-slots/app-a/src/lib/paper.svg +++ b/content/tutorial/02-advanced-svelte/07-composition/02-named-slots/app-a/src/lib/paper.svg @@ -6,5 +6,5 @@ - - \ No newline at end of file + + diff --git a/content/tutorial/02-advanced-svelte/07-composition/02-named-slots/app-b/src/lib/App.svelte b/content/tutorial/02-advanced-svelte/07-composition/02-named-slots/app-b/src/lib/App.svelte index 2613efd08..6ddf52dcc 100644 --- a/content/tutorial/02-advanced-svelte/07-composition/02-named-slots/app-b/src/lib/App.svelte +++ b/content/tutorial/02-advanced-svelte/07-composition/02-named-slots/app-b/src/lib/App.svelte @@ -14,7 +14,7 @@ Mergers and Aquisitions
- 358 Exchange Place, New York, N.Y. 100099 fax 212 555 6390 telex 10 4534 + 358 Exchange Place, New York, N.Y. 10099 fax 212 555 6390 telex 10 4534
diff --git a/content/tutorial/02-advanced-svelte/07-composition/03-slot-fallbacks/app-a/src/lib/App.svelte b/content/tutorial/02-advanced-svelte/07-composition/03-slot-fallbacks/app-a/src/lib/App.svelte index 5bb5882ca..b7b99912f 100644 --- a/content/tutorial/02-advanced-svelte/07-composition/03-slot-fallbacks/app-a/src/lib/App.svelte +++ b/content/tutorial/02-advanced-svelte/07-composition/03-slot-fallbacks/app-a/src/lib/App.svelte @@ -14,7 +14,7 @@ Mergers and Aquisitions - 358 Exchange Place, New York, N.Y. 100099 fax 212 555 6390 telex 10 4534 + 358 Exchange Place, New York, N.Y. 10099 fax 212 555 6390 telex 10 4534 diff --git a/content/tutorial/02-advanced-svelte/07-composition/03-slot-fallbacks/app-a/src/lib/paper.svg b/content/tutorial/02-advanced-svelte/07-composition/03-slot-fallbacks/app-a/src/lib/paper.svg index f8f704fdf..5dba50c15 100644 --- a/content/tutorial/02-advanced-svelte/07-composition/03-slot-fallbacks/app-a/src/lib/paper.svg +++ b/content/tutorial/02-advanced-svelte/07-composition/03-slot-fallbacks/app-a/src/lib/paper.svg @@ -6,5 +6,5 @@ - - \ No newline at end of file + + diff --git a/content/tutorial/02-advanced-svelte/07-composition/04-slot-props/README.md b/content/tutorial/02-advanced-svelte/07-composition/04-slot-props/README.md index 896528c17..c8dbd89a4 100644 --- a/content/tutorial/02-advanced-svelte/07-composition/04-slot-props/README.md +++ b/content/tutorial/02-advanced-svelte/07-composition/04-slot-props/README.md @@ -12,7 +12,7 @@ Open `FilterableList.svelte`. The `` is being rendered for each filtered i /// file: FilterableList.svelte
{#each data.filter(matches) as item} - + {/each}
``` diff --git a/content/tutorial/02-advanced-svelte/07-composition/04-slot-props/app-a/src/lib/App.svelte b/content/tutorial/02-advanced-svelte/07-composition/04-slot-props/app-a/src/lib/App.svelte index 9757ff15d..1a7c9c9d5 100644 --- a/content/tutorial/02-advanced-svelte/07-composition/04-slot-props/app-a/src/lib/App.svelte +++ b/content/tutorial/02-advanced-svelte/07-composition/04-slot-props/app-a/src/lib/App.svelte @@ -10,7 +10,7 @@ field="name" >
- + name hex rgb @@ -18,7 +18,7 @@
- + {row.name} {row.hex} {row.rgb} diff --git a/content/tutorial/02-advanced-svelte/07-composition/04-slot-props/app-b/src/lib/App.svelte b/content/tutorial/02-advanced-svelte/07-composition/04-slot-props/app-b/src/lib/App.svelte index a21b37016..34c173fff 100644 --- a/content/tutorial/02-advanced-svelte/07-composition/04-slot-props/app-b/src/lib/App.svelte +++ b/content/tutorial/02-advanced-svelte/07-composition/04-slot-props/app-b/src/lib/App.svelte @@ -9,7 +9,7 @@ let:item={row} >
- + name hex rgb @@ -17,7 +17,7 @@
- + {row.name} {row.hex} {row.rgb} diff --git a/content/tutorial/02-advanced-svelte/07-composition/05-optional-slots/README.md b/content/tutorial/02-advanced-svelte/07-composition/05-optional-slots/README.md index 7f1d3d859..c9c219f69 100644 --- a/content/tutorial/02-advanced-svelte/07-composition/05-optional-slots/README.md +++ b/content/tutorial/02-advanced-svelte/07-composition/05-optional-slots/README.md @@ -7,7 +7,7 @@ In some cases, you may want to control parts of your component based on whether ```svelte /// file: App.svelte ---
- + name hex rgb @@ -31,7 +31,7 @@ We can fix that by using the special `$$slots` variable in `FilterableList.svelt /// file: FilterableList.svelte +++{#if $$slots.header}+++
- +
+++{/if}+++ ``` diff --git a/content/tutorial/02-advanced-svelte/07-composition/05-optional-slots/app-b/src/lib/App.svelte b/content/tutorial/02-advanced-svelte/07-composition/05-optional-slots/app-b/src/lib/App.svelte index de5be5138..0dde93327 100644 --- a/content/tutorial/02-advanced-svelte/07-composition/05-optional-slots/app-b/src/lib/App.svelte +++ b/content/tutorial/02-advanced-svelte/07-composition/05-optional-slots/app-b/src/lib/App.svelte @@ -9,7 +9,7 @@ let:item={row} >
- + {row.name} {row.hex} {row.rgb} diff --git a/content/tutorial/02-advanced-svelte/08-context/01-context-api/README.md b/content/tutorial/02-advanced-svelte/08-context/01-context-api/README.md index d88c5b015..208cf5798 100644 --- a/content/tutorial/02-advanced-svelte/08-context/01-context-api/README.md +++ b/content/tutorial/02-advanced-svelte/08-context/01-context-api/README.md @@ -86,5 +86,5 @@ import { getContext } from 'svelte'; const { count } = getContext('my-context'); -$: console.log({ count }); +$: console.log({ count: $count }); ``` diff --git a/content/tutorial/02-advanced-svelte/09-special-elements/01-svelte-self/README.md b/content/tutorial/02-advanced-svelte/09-special-elements/01-svelte-self/README.md index c117ad4ce..ea4e6a572 100644 --- a/content/tutorial/02-advanced-svelte/09-special-elements/01-svelte-self/README.md +++ b/content/tutorial/02-advanced-svelte/09-special-elements/01-svelte-self/README.md @@ -20,8 +20,8 @@ It's useful for things like this folder tree view, where folders can contain _ot ```svelte /// file: Folder.svelte {#if file.files} - ++++++ + ++++++ {:else} - + {/if} ``` diff --git a/content/tutorial/02-advanced-svelte/09-special-elements/02-svelte-component/README.md b/content/tutorial/02-advanced-svelte/09-special-elements/02-svelte-component/README.md index 0b31b2f81..bc16deb01 100644 --- a/content/tutorial/02-advanced-svelte/09-special-elements/02-svelte-component/README.md +++ b/content/tutorial/02-advanced-svelte/09-special-elements/02-svelte-component/README.md @@ -27,7 +27,7 @@ We _could_ do this with a sequence of `if` blocks... {/each} -++++++ +++++++ ``` The `this` value can be any component constructor, or a falsy value — if it's falsy, no component is rendered. diff --git a/content/tutorial/02-advanced-svelte/09-special-elements/09-svelte-options/README.md b/content/tutorial/02-advanced-svelte/09-special-elements/09-svelte-options/README.md index 145ed9407..6514e388c 100644 --- a/content/tutorial/02-advanced-svelte/09-special-elements/09-svelte-options/README.md +++ b/content/tutorial/02-advanced-svelte/09-special-elements/09-svelte-options/README.md @@ -26,6 +26,6 @@ The options that can be set here are: - `accessors={true}` — adds getters and setters for the component's props - `accessors={false}` — the default - `namespace="..."` — the namespace where this component will be used, most commonly `"svg"` -- `tag="..."` — the name to use when compiling this component as a custom element +- `customElement="..."` — the name to use when compiling this component as a custom element Consult the [API reference](https://svelte.dev/docs) for more information on these options. diff --git a/content/tutorial/02-advanced-svelte/10-module-context/01-sharing-code/app-a/src/lib/AudioPlayer.svelte b/content/tutorial/02-advanced-svelte/10-module-context/01-sharing-code/app-a/src/lib/AudioPlayer.svelte index 1cc7d1737..85be476d6 100644 --- a/content/tutorial/02-advanced-svelte/10-module-context/01-sharing-code/app-a/src/lib/AudioPlayer.svelte +++ b/content/tutorial/02-advanced-svelte/10-module-context/01-sharing-code/app-a/src/lib/AudioPlayer.svelte @@ -26,13 +26,13 @@ on:ended={() => { time = 0; }} - /> + >
@@ -68,7 +68,7 @@ }); }} > -
+
{duration ? format(duration) : '--:--'}
diff --git a/content/tutorial/02-advanced-svelte/10-module-context/01-sharing-code/app-b/src/lib/AudioPlayer.svelte b/content/tutorial/02-advanced-svelte/10-module-context/01-sharing-code/app-b/src/lib/AudioPlayer.svelte index acafe1bbc..ffdb485d8 100644 --- a/content/tutorial/02-advanced-svelte/10-module-context/01-sharing-code/app-b/src/lib/AudioPlayer.svelte +++ b/content/tutorial/02-advanced-svelte/10-module-context/01-sharing-code/app-b/src/lib/AudioPlayer.svelte @@ -38,13 +38,13 @@ on:ended={() => { time = 0; }} - /> + >
@@ -80,7 +80,7 @@ }); }} > -
+
{duration ? format(duration) : '--:--'}
diff --git a/content/tutorial/02-advanced-svelte/10-module-context/02-module-exports/README.md b/content/tutorial/02-advanced-svelte/10-module-context/02-module-exports/README.md index 520567dbb..70def8228 100644 --- a/content/tutorial/02-advanced-svelte/10-module-context/02-module-exports/README.md +++ b/content/tutorial/02-advanced-svelte/10-module-context/02-module-exports/README.md @@ -21,6 +21,7 @@ We can now import `stopAll` in `App.svelte`... /// file: App.svelte ``` diff --git a/content/tutorial/02-advanced-svelte/10-module-context/02-module-exports/app-b/src/lib/AudioPlayer.svelte b/content/tutorial/02-advanced-svelte/10-module-context/02-module-exports/app-b/src/lib/AudioPlayer.svelte index 0eaa4a16e..323286b79 100644 --- a/content/tutorial/02-advanced-svelte/10-module-context/02-module-exports/app-b/src/lib/AudioPlayer.svelte +++ b/content/tutorial/02-advanced-svelte/10-module-context/02-module-exports/app-b/src/lib/AudioPlayer.svelte @@ -42,13 +42,13 @@ on:ended={() => { time = 0; }} - /> + >
@@ -84,7 +84,7 @@ }); }} > -
+
{duration ? format(duration) : '--:--'}
diff --git a/content/tutorial/02-advanced-svelte/common/src/routes/+error.svelte b/content/tutorial/02-advanced-svelte/common/src/routes/+error.svelte index 930ccfd10..fb5551052 100644 --- a/content/tutorial/02-advanced-svelte/common/src/routes/+error.svelte +++ b/content/tutorial/02-advanced-svelte/common/src/routes/+error.svelte @@ -11,7 +11,7 @@ code {$page.status}

diff --git a/content/tutorial/03-sveltekit/02-routing/02-layouts/README.md b/content/tutorial/03-sveltekit/02-routing/02-layouts/README.md index e7812fead..79898d168 100644 --- a/content/tutorial/03-sveltekit/02-routing/02-layouts/README.md +++ b/content/tutorial/03-sveltekit/02-routing/02-layouts/README.md @@ -14,7 +14,7 @@ src/routes/ └ +page.svelte ``` -...and move the duplicated content from the `+page.svelte` files into the new `+layout.svelte` file. The `` element is where the page content will be rendered: +...and move the duplicated content from the `+page.svelte` files into the new `+layout.svelte` file. The `` element is where the page content will be rendered: ```svelte /// file: src/routes/+layout.svelte @@ -23,7 +23,7 @@ src/routes/ about - + ``` A `+layout.svelte` file applies to every child route, including the sibling `+page.svelte` (if it exists). You can nest layouts to arbitrary depth. diff --git a/content/tutorial/03-sveltekit/03-loading-data/01-page-data/README.md b/content/tutorial/03-sveltekit/03-loading-data/01-page-data/README.md index f23ff32c3..8d9b4049b 100644 --- a/content/tutorial/03-sveltekit/03-loading-data/01-page-data/README.md +++ b/content/tutorial/03-sveltekit/03-loading-data/01-page-data/README.md @@ -7,7 +7,7 @@ At its core, SvelteKit's job boils down to three things: 1. **Routing** — figure out which route matches an incoming request 2. **Loading** — get the data needed by the route -3. **Rendering** - generate some HTML (on the server) or update the DOM (in the browser) +3. **Rendering** — generate some HTML (on the server) or update the DOM (in the browser) We've seen how routing and rendering work. Let's talk about the middle part — loading. diff --git a/content/tutorial/03-sveltekit/03-loading-data/02-layout-data/README.md b/content/tutorial/03-sveltekit/03-loading-data/02-layout-data/README.md index 3b25ecf82..a96aab1ad 100644 --- a/content/tutorial/03-sveltekit/03-loading-data/02-layout-data/README.md +++ b/content/tutorial/03-sveltekit/03-loading-data/02-layout-data/README.md @@ -19,7 +19,7 @@ Now, add a sidebar in the layout for the post page:
- +
+++
+
diff --git a/src/routes/tutorial/[slug]/Output.svelte b/src/routes/tutorial/[slug]/Output.svelte index 0f2526e36..629a2cf5b 100644 --- a/src/routes/tutorial/[slug]/Output.svelte +++ b/src/routes/tutorial/[slug]/Output.svelte @@ -1,7 +1,7 @@ -
{ - if (sessionStorage[copy_enabled]) return; - - /** @type {HTMLElement | null} */ - let node = /** @type {HTMLElement} */ (e.target); +
+
{ + if (sessionStorage[copy_enabled]) return; - while (node && node !== e.currentTarget) { - if (node.nodeName === 'PRE') { - show_modal = true; + /** @type {HTMLElement | null} */ + let node = /** @type {HTMLElement} */ (e.target); - e.preventDefault(); - return; - } + while (node && node !== e.currentTarget) { + if (node.nodeName === 'PRE') { + show_modal = true; - node = /** @type {HTMLElement | null} */ (node.parentNode); - } - }} -> - -
{ - const node = /** @type {HTMLElement} */ (e.target); - - if (node.nodeName === 'CODE') { - const { file } = node.dataset; - if (file) { - dispatch('select', { file }); + e.preventDefault(); + return; } - } - if (node.nodeName === 'SPAN' && node.classList.contains('filename')) { - const file = exercise.scope.prefix + node.textContent; - dispatch('select', { file }); + node = /** @type {HTMLElement | null} */ (node.parentNode); } }} > - {@html exercise.html} + + +
{ + const node = /** @type {HTMLElement} */ (e.target); + + if (node.nodeName === 'CODE') { + const { file } = node.dataset; + if (file) { + dispatch('select', { file }); + } + } + + if (node.nodeName === 'SPAN' && node.classList.contains('filename')) { + const file = exercise.scope.prefix + node.textContent; + dispatch('select', { file }); + } + }} + > + {@html exercise.html} +
+ + {#if exercise.next} +

Next: {exercise.next.title}

+ {/if}
- {#if exercise.next} -

Next: {exercise.next.title}

- {/if} -
- - + +
{#if show_modal} (show_modal = false)}> @@ -113,9 +107,16 @@ {/if} \ No newline at end of file + diff --git a/src/routes/tutorial/[slug]/state.js b/src/routes/tutorial/[slug]/state.js index 629a4d863..e321c3892 100644 --- a/src/routes/tutorial/[slug]/state.js +++ b/src/routes/tutorial/[slug]/state.js @@ -6,19 +6,6 @@ import * as adapter from './adapter.js'; * @typedef {import('svelte/store').Writable} Writable */ -// TODO would be nice if svelte exported this type (maybe it does already?) -/** - * @typedef {{ - * code: string; - * start: { line: number, column: number, character: number }; - * end: { line: number, column: number, character: number }; - * pos: number; - * filename: string; - * frame: string; - * message: string; - * }} CompilerWarning - */ - /** @type {Writable} */ export const files = writable([]); @@ -98,4 +85,4 @@ export function create_directories(name, files) { } return directories; -} \ No newline at end of file +} diff --git a/static/robots.txt b/static/robots.txt new file mode 100644 index 000000000..eb0536286 --- /dev/null +++ b/static/robots.txt @@ -0,0 +1,2 @@ +User-agent: * +Disallow: diff --git a/svelte.config.js b/svelte.config.js index 83e7b17cb..3b4551d49 100644 --- a/svelte.config.js +++ b/svelte.config.js @@ -6,17 +6,13 @@ const config = { kit: { adapter: adapter({ runtime: 'edge' }), + prerender: { + concurrency: 4 + }, + version: { name: child_process.execSync('git rev-parse HEAD').toString().trim() } - }, - - vitePlugin: { - experimental: { - inspector: { - holdMode: true - } - } } }; diff --git a/tests/env_file.spec.ts b/tests/env_file.spec.ts index 7177e40cf..7a546b29c 100644 --- a/tests/env_file.spec.ts +++ b/tests/env_file.spec.ts @@ -1,7 +1,18 @@ -import { expect, test } from '@playwright/test'; +import { expect, test, type Page } from '@playwright/test'; const iframe_selector = 'iframe[src*="webcontainer.io/"]'; +async function disableAnimations(page: Page) { + await page.addStyleTag({ + content: ` + *, *::before, *::after { + animation-duration: 0s !important; + transition-duration: 0s !important; + } + ` + }); +} + test.describe.configure({ mode: 'parallel' }); test('.env file: no timeout error occurs when switching a tutorials without a .env file to one with it', async ({ @@ -11,15 +22,18 @@ test('.env file: no timeout error occurs when switching a tutorials without a .e await page.goto('/tutorial/welcome-to-svelte'); + // disable animations to prevent flakiness + await disableAnimations(page); + const iframe_locator = page.frameLocator(iframe_selector); // wait for the iframe to load await iframe_locator.getByText('Welcome!').waitFor(); // switch to another tutorial with a .env file - await page.click('header > h1', { delay: 200 }); - await page.locator('button', { hasText: 'Part 4: Advanced SvelteKit' }).click({ delay: 200 }); - await page.locator('button', { hasText: 'Environment variables' }).click({ delay: 200 }); + await page.click('header > button > h1', { delay: 200 }); + await page.getByRole('button', { name: 'Part 4: Advanced SvelteKit' }).click({ delay: 200 }); + await page.getByRole('button', { name: 'Environment variables' }).click({ delay: 200 }); await page.locator('a', { hasText: '$env/static/private' }).click({ delay: 200 }); // wait for the iframe to load @@ -41,15 +55,18 @@ test('.env file: environment variables are available when switching a tutorial w await page.goto('/tutorial/welcome-to-svelte'); + // disable animations to prevent flakiness + await disableAnimations(page); + const iframe_locator = page.frameLocator(iframe_selector); // wait for the iframe to load await iframe_locator.getByText('Welcome!').waitFor(); // switch to another tutorial with a .env file - await page.click('header > h1', { delay: 200 }); - await page.locator('button', { hasText: 'Part 4: Advanced SvelteKit' }).click({ delay: 200 }); - await page.locator('button', { hasText: 'Environment variables' }).click({ delay: 200 }); + await page.click('header > button > h1', { delay: 200 }); + await page.getByRole('button', { name: 'Part 4: Advanced SvelteKit' }).click({ delay: 200 }); + await page.getByRole('button', { name: 'Environment variables' }).click({ delay: 200 }); await page.locator('a', { hasText: '$env/dynamic/private' }).click({ delay: 200 }); // wait for the iframe to load diff --git a/vercel.json b/vercel.json new file mode 100644 index 000000000..fb6340954 --- /dev/null +++ b/vercel.json @@ -0,0 +1,22 @@ +{ + "$schema": "https://openapi.vercel.sh/vercel.json", + "headers": [ + { + "source": "_app/immutable/workers/(.*)", + "headers": [ + { + "key": "cross-origin-opener-policy", + "value": "same-origin" + }, + { + "key": "cross-origin-embedder-policy", + "value": "require-corp" + }, + { + "key": "cross-origin-resource-policy", + "value": "cross-origin" + } + ] + } + ] +} diff --git a/vite.config.js b/vite.config.js index 1a3c3386d..bf5e4e7dc 100644 --- a/vite.config.js +++ b/vite.config.js @@ -1,14 +1,23 @@ -import path from 'path'; import { sveltekit } from '@sveltejs/kit/vite'; +import browserslist from 'browserslist'; +import { browserslistToTargets } from 'lightningcss'; +import path from 'node:path'; /** @type {import('vite').UserConfig} */ export default { + logLevel: 'info', + + css: { + transformer: 'lightningcss', + lightningcss: { + targets: browserslistToTargets(browserslist(['>0.2%', 'not dead'])) + } + }, build: { - target: 'esnext' + target: 'esnext', + cssMinify: 'lightningcss' }, - logLevel: 'info', - plugins: [ // apply cross-origin isolation headers when previewing locally { @@ -28,10 +37,16 @@ export default { server: { fs: { - allow: [path.resolve('.apps')] + allow: [path.resolve('.apps')], + strict: false }, watch: { ignored: ['**/.apps/**'] + }, + headers: { + 'cross-origin-opener-policy': 'same-origin', + 'cross-origin-embedder-policy': 'require-corp', + 'cross-origin-resource-policy': 'cross-origin' } },