diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 14824ecdfa..ff0ec4f633 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -5,10 +5,9 @@ jobs: runs-on: ${{ matrix.os }} strategy: matrix: - node-version: [8, 10, 12] + node-version: [8, 10, 12, 14] os: [ubuntu-latest, windows-latest, macOS-latest] steps: - - run: git config --global core.autocrlf false - uses: actions/checkout@v1 - uses: actions/setup-node@v1 with: @@ -24,7 +23,10 @@ jobs: - uses: actions/setup-node@v1 - run: 'npm i && npm run lint' Unit: - runs-on: ubuntu-latest + runs-on: ${{ matrix.os }} + strategy: + matrix: + os: [ubuntu-latest, windows-latest, macOS-latest] steps: - uses: actions/checkout@v1 - uses: actions/setup-node@v1 diff --git a/.gitignore b/.gitignore index 7a14244929..f7fac04eba 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,7 @@ .idea .DS_Store .nyc_output +.vscode node_modules *.map /src/compiler/compile/internal_exports.ts diff --git a/CHANGELOG.md b/CHANGELOG.md index f1564848b5..73bc68d72f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,76 @@ # Svelte changelog +## 3.23.0 + +* Update `` to `undefined` ([#3569](https://github.com/sveltejs/svelte/issues/3569)) +* Fix setting `` updates ([#4631](https://github.com/sveltejs/svelte/issues/4631), [#4687](https://github.com/sveltejs/svelte/issues/4687)) +* Prevent illegal attribute names ([#4648](https://github.com/sveltejs/svelte/issues/4648)) +* Fix `{#if}` block directly within `` ([#4703](https://github.com/sveltejs/svelte/issues/4703)) + +## 3.20.1 + +* Fix compiler regression with slots ([#4562](https://github.com/sveltejs/svelte/issues/4562)) + +## 3.20.0 + +* Allow destructuring in `{#await}` blocks ([#1851](https://github.com/sveltejs/svelte/issues/1851)) +* Allow `` to be used in a slot ([#2798](https://github.com/sveltejs/svelte/issues/2798)) +* Expose object of unknown props in `$$restProps` ([#2930](https://github.com/sveltejs/svelte/issues/2930)) +* Prevent passing named slots other than from the top level within a component ([#3385](https://github.com/sveltejs/svelte/issues/3385)) +* Allow transitions and animations to work within iframes ([#3624](https://github.com/sveltejs/svelte/issues/3624)) +* Fix initialising slot fallbacks when unnecessary ([#3763](https://github.com/sveltejs/svelte/issues/3763)) +* Disallow binding directly to `const` variables ([#4479](https://github.com/sveltejs/svelte/issues/4479)) +* Fix re-attaching event handlers on keyed `{#each}` blocks ([#4491](https://github.com/sveltejs/svelte/issues/4491)) +* Fix updating keyed `{#each}` blocks with `{:else}` ([#4536](https://github.com/sveltejs/svelte/issues/4536), [#4549](https://github.com/sveltejs/svelte/issues/4549)) +* Fix hydration of top-level content ([#4542](https://github.com/sveltejs/svelte/issues/4542)) + ## 3.19.2 * In `dev` mode, display a runtime warning when a component is passed an unexpected slot ([#1020](https://github.com/sveltejs/svelte/issues/1020), [#1447](https://github.com/sveltejs/svelte/issues/1447)) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index f7df9770db..c3eff81da3 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -93,7 +93,7 @@ Test samples are kept in `/test/xxx/samples` folder. #### Running tests -1. To run test, run `npm run test` +1. To run test, run `npm run test`. 1. To run test for a specific feature, you can use the `-g` (aka `--grep`) option. For example, to only run test involving transitions, run `npm run test -- -g transition`. ##### Running solo test @@ -130,7 +130,7 @@ The core Svelte team will be monitoring for pull requests. Do help us by making ### Code conventions -- `snake_case` for internal variable names and methods +- `snake_case` for internal variable names and methods. - `camelCase` for public variable names and methods. ## License diff --git a/README.md b/README.md index fa725804a9..e2e4fcd532 100644 --- a/README.md +++ b/README.md @@ -34,11 +34,6 @@ npm install > Do not use Yarn to install the dependencies, as the specific package versions in `package-lock.json` are used to build and test Svelte. -> Many tests depend on newlines being preserved as ``. On Windows, you can ensure this by cloning with: -> ```bash -> git -c core.autocrlf=false clone https://github.com/sveltejs/svelte.git -> ``` - To build the compiler, and all the other modules included in the package: ```bash @@ -77,6 +72,9 @@ npm install && npm run update npm run dev ``` +### Is svelte.dev down? + +Probably not, but it's possible. If you can't seem to access any `.dev` sites, check out [this SuperUser question and answer](https://superuser.com/q/1413402). ## License diff --git a/banner.png b/banner.png deleted file mode 100644 index 0d117c3c09..0000000000 Binary files a/banner.png and /dev/null differ diff --git a/package-lock.json b/package-lock.json index 014348f37e..cd9a83e04b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "svelte", - "version": "3.19.2", + "version": "3.23.0", "lockfileVersion": 1, "requires": true, "dependencies": { @@ -280,9 +280,9 @@ "dev": true }, "acorn": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.1.0.tgz", - "integrity": "sha512-kL5CuoXA/dgxlBbVrflsflzQ3PAas7RYZB52NOm/6839iVYJgKMJ3cQJD+t2i5+qFa8h3MDpEOJiS64E8JLnSQ==", + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.1.1.tgz", + "integrity": "sha512-add7dgA5ppRPxCFJoAGfMDi7PIBXq1RtGo7BhbLaxwrXPOmw8gq48Y9ozT01hUKy9byMjlR20EJhu5zlkErEkg==", "dev": true }, "acorn-globals": { @@ -296,9 +296,9 @@ }, "dependencies": { "acorn": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.3.0.tgz", - "integrity": "sha512-/czfa8BwS88b9gWQVhc8eknunSA2DoJpJyTQkhheIf5E48u1N0R4q/YxxsAeqRrmK9TQ/uYfgLDfZo91UlANIA==", + "version": "6.4.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.4.1.tgz", + "integrity": "sha512-ZVA9k326Nwrj3Cj9jlh3wGFutC2ZornPNARZwsNYqQYgN0EsV2d53w5RN/co65Ohn4sUAUtb1rSUAOD6XN9idA==", "dev": true } } @@ -492,6 +492,12 @@ "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", "dev": true }, + "buffer-crc32": { + "version": "0.2.13", + "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", + "integrity": "sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI=", + "dev": true + }, "buffer-from": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", @@ -1352,15 +1358,15 @@ } }, "extract-zip": { - "version": "1.6.7", - "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-1.6.7.tgz", - "integrity": "sha1-qEC0uK9kAyZMjbV/Txp0Mz74H+k=", + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-1.7.0.tgz", + "integrity": "sha512-xoh5G1W/PB0/27lXgMQyIhP5DSY/LhoCsOyZgb+6iMmRtCwVBo55uKaMoEYrDCKQhWvqEip5ZPKAc6eFNyf/MA==", "dev": true, "requires": { - "concat-stream": "1.6.2", - "debug": "2.6.9", - "mkdirp": "0.5.1", - "yauzl": "2.4.1" + "concat-stream": "^1.6.2", + "debug": "^2.6.9", + "mkdirp": "^0.5.4", + "yauzl": "^2.10.0" }, "dependencies": { "debug": { @@ -1405,9 +1411,9 @@ "dev": true }, "fd-slicer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.0.1.tgz", - "integrity": "sha1-i1vL2ewyfFBBv5qwI/1nUPEXfmU=", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz", + "integrity": "sha1-JcfInLH5B3+IkbvmHY85Dq4lbx4=", "dev": true, "requires": { "pend": "~1.2.0" @@ -1598,26 +1604,6 @@ "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==", "dev": true }, - "handlebars": { - "version": "4.5.3", - "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.5.3.tgz", - "integrity": "sha512-3yPecJoJHK/4c6aZhSvxOyG4vJKDshV36VHp0iVCDVh7o9w2vwi3NSnL2MMPj3YdduqaBcu7cGbggJQM0br9xA==", - "dev": true, - "requires": { - "neo-async": "^2.6.0", - "optimist": "^0.6.1", - "source-map": "^0.6.1", - "uglify-js": "^3.1.4" - }, - "dependencies": { - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - } - } - }, "har-schema": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", @@ -1676,6 +1662,12 @@ "whatwg-encoding": "^1.0.1" } }, + "html-escaper": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", + "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", + "dev": true + }, "http-proxy-agent": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz", @@ -1984,12 +1976,12 @@ } }, "istanbul-reports": { - "version": "2.2.6", - "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-2.2.6.tgz", - "integrity": "sha512-SKi4rnMyLBKe0Jy2uUdx28h8oG7ph2PPuQPvIAh31d+Ci+lSiEu4C+h3oBPuJ9+mPKhOyW0M8gY4U5NM1WLeXA==", + "version": "2.2.7", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-2.2.7.tgz", + "integrity": "sha512-uu1F/L1o5Y6LzPVSVZXNOoD/KXpJue9aeLRd0sM9uMXfZvzomB0WxVamWb5ue8kA2vVWEmW7EG+A5n3f1kqHKg==", "dev": true, "requires": { - "handlebars": "^4.1.2" + "html-escaper": "^2.0.0" } }, "js-tokens": { @@ -2049,9 +2041,9 @@ }, "dependencies": { "acorn": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.3.0.tgz", - "integrity": "sha512-/czfa8BwS88b9gWQVhc8eknunSA2DoJpJyTQkhheIf5E48u1N0R4q/YxxsAeqRrmK9TQ/uYfgLDfZo91UlANIA==", + "version": "6.4.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.4.1.tgz", + "integrity": "sha512-ZVA9k326Nwrj3Cj9jlh3wGFutC2ZornPNARZwsNYqQYgN0EsV2d53w5RN/co65Ohn4sUAUtb1rSUAOD6XN9idA==", "dev": true }, "ws": { @@ -2301,26 +2293,18 @@ } }, "minimist": { - "version": "0.0.10", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.10.tgz", - "integrity": "sha1-3j+YVD2/lggr5IrRoMfNqDYwHc8=", + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", + "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", "dev": true }, "mkdirp": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", - "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", + "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", "dev": true, "requires": { - "minimist": "0.0.8" - }, - "dependencies": { - "minimist": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", - "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", - "dev": true - } + "minimist": "^1.2.5" } }, "mocha": { @@ -2397,6 +2381,21 @@ "path-is-absolute": "^1.0.0" } }, + "minimist": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", + "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", + "dev": true + }, + "mkdirp": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", + "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", + "dev": true, + "requires": { + "minimist": "0.0.8" + } + }, "ms": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", @@ -2534,12 +2533,6 @@ "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", "dev": true }, - "neo-async": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.1.tgz", - "integrity": "sha512-iyam8fBuCUpWeKPGpaNMetEocMt364qkCsfL9JuhjXX6dRnguRVOfk2GZaDpPjcOKiiXCPINZC1GczQ7iTq3Zw==", - "dev": true - }, "nice-try": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", @@ -2687,16 +2680,6 @@ } } }, - "optimist": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/optimist/-/optimist-0.6.1.tgz", - "integrity": "sha1-2j6nRob6IaGaERwybpDrFaAZZoY=", - "dev": true, - "requires": { - "minimist": "~0.0.1", - "wordwrap": "~0.0.2" - } - }, "optionator": { "version": "0.8.2", "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.2.tgz", @@ -3047,9 +3030,9 @@ } }, "readable-stream": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", - "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", + "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", "dev": true, "requires": { "core-util-is": "~1.0.0", @@ -3672,26 +3655,6 @@ "integrity": "sha512-ACzBtm/PhXBDId6a6sDJfroT2pOWt/oOnk4/dElG5G33ZL776N3Y6/6bKZJBFpd+b05F3Ct9qDjMeJmRWtE2/g==", "dev": true }, - "uglify-js": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.6.0.tgz", - "integrity": "sha512-W+jrUHJr3DXKhrsS7NUVxn3zqMOFn0hL/Ei6v0anCIMoKC93TjcflTagwIHLW7SfMFfiQuktQyFVCFHGUE0+yg==", - "dev": true, - "optional": true, - "requires": { - "commander": "~2.20.0", - "source-map": "~0.6.1" - }, - "dependencies": { - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true, - "optional": true - } - } - }, "uri-js": { "version": "4.2.2", "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz", @@ -3860,12 +3823,6 @@ } } }, - "wordwrap": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.3.tgz", - "integrity": "sha1-o9XabNXAvAAI03I0u68b7WMFkQc=", - "dev": true - }, "wrap-ansi": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", @@ -4112,12 +4069,13 @@ } }, "yauzl": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.4.1.tgz", - "integrity": "sha1-lSj0QtqxsihOWLQ3m7GU4i4MQAU=", + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz", + "integrity": "sha1-x+sXyT4RLLEIb6bY5R+wZnt5pfk=", "dev": true, "requires": { - "fd-slicer": "~1.0.1" + "buffer-crc32": "~0.2.3", + "fd-slicer": "~1.1.0" } } } diff --git a/package.json b/package.json index 009e5143a9..90cee0a5d5 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "svelte", - "version": "3.19.2", + "version": "3.23.0", "description": "Cybernetically enhanced web apps", "module": "index.mjs", "main": "index", diff --git a/site/content/docs/00-introduction.md b/site/content/docs/00-introduction.md index 15fdffbde2..2ca82a8698 100644 --- a/site/content/docs/00-introduction.md +++ b/site/content/docs/00-introduction.md @@ -6,4 +6,6 @@ This page contains detailed API reference documentation. It's intended to be a r If that's not you (yet), you may prefer to visit the [interactive tutorial](tutorial) or the [examples](examples) before consulting this reference. -Don't be shy about asking for help in the [Discord chatroom](chat). \ No newline at end of file +Don't be shy about asking for help in the [Discord chatroom](chat). + +Using an older version of Svelte? Have a look at the [v2 docs](https://v2.svelte.dev). \ No newline at end of file diff --git a/site/content/docs/01-component-format.md b/site/content/docs/01-component-format.md index 07a59c69f8..8eac5d3c50 100644 --- a/site/content/docs/01-component-format.md +++ b/site/content/docs/01-component-format.md @@ -8,7 +8,7 @@ Components are the building blocks of Svelte applications. They are written into All three sections — script, styles and markup — are optional. -```html +```sv @@ -30,7 +30,7 @@ A ` @@ -26,7 +26,7 @@ A lowercase tag, like `
`, denotes a regular HTML element. A capitalised tag By default, attributes work exactly like their HTML counterparts. -```html +```sv
@@ -36,7 +36,7 @@ By default, attributes work exactly like their HTML counterparts. As in HTML, values may be unquoted. -```html +```sv ``` @@ -44,7 +44,7 @@ As in HTML, values may be unquoted. Attribute values can contain JavaScript expressions. -```html +```sv page {p} ``` @@ -52,7 +52,7 @@ Attribute values can contain JavaScript expressions. Or they can *be* JavaScript expressions. -```html +```sv ``` @@ -71,7 +71,7 @@ All other attributes are included unless their value is [nullish](https://develo An expression might include characters that would cause syntax highlighting to fail in regular HTML, so quoting the value is permitted. The quotes do not affect how the value is parsed: -```html +```sv ``` @@ -79,7 +79,7 @@ An expression might include characters that would cause syntax highlighting to f When the attribute name and value match (`name={name}`), they can be replaced with `{name}`. -```html +```sv @@ -91,7 +91,7 @@ By convention, values passed to components are referred to as *properties* or *p As with elements, `name={name}` can be replaced with the `{name}` shorthand. -```html +```sv ``` @@ -101,7 +101,7 @@ As with elements, `name={name}` can be replaced with the `{name}` shorthand. An element or component can have multiple spread attributes, interspersed with regular ones. -```html +```sv ``` @@ -109,10 +109,22 @@ An element or component can have multiple spread attributes, interspersed with r *`$$props`* references all props that are passed to a component – including ones that are not declared with `export`. It is useful in rare cases, but not generally recommended, as it is difficult for Svelte to optimise. -```html +```sv ``` +--- + +*`$$restProps`* contains only the props which are *not* declared with `export`. It can be used to pass down other unknown attributes to an element in a component. + +```html + +``` + + +> The `value` attribute of an `input` element or its children `option` elements must not be set with spread attributes when using `bind:group` or `bind:checked`. Svelte needs to be able to see the element's `value` directly in the markup in these cases so that it can link it to the bound variable. + +--- ### Text expressions @@ -124,7 +136,7 @@ An element or component can have multiple spread attributes, interspersed with r Text can also contain JavaScript expressions: -```html +```sv

Hello {name}!

{a} + {b} = {a + b}.

``` @@ -136,7 +148,7 @@ Text can also contain JavaScript expressions: You can use HTML comments inside components. -```html +```sv

Hello world

``` @@ -145,7 +157,7 @@ You can use HTML comments inside components. Comments beginning with `svelte-ignore` disable warnings for the next block of markup. Usually these are accessibility warnings; make sure that you're disabling them for a good reason. -```html +```sv ``` @@ -167,7 +179,7 @@ Comments beginning with `svelte-ignore` disable warnings for the next block of m Content that is conditionally rendered can be wrapped in an if block. -```html +```sv {#if answer === 42}

what was the question?

{/if} @@ -177,7 +189,7 @@ Content that is conditionally rendered can be wrapped in an if block. Additional conditions can be added with `{:else if expression}`, optionally ending in an `{:else}` clause. -```html +```sv {#if porridge.temperature > 100}

too hot!

{:else if 80 > porridge.temperature} @@ -197,6 +209,9 @@ Additional conditions can be added with `{:else if expression}`, optionally endi {#each expression as name, index}...{/each} ``` ```sv +{#each expression as name (key)}...{/each} +``` +```sv {#each expression as name, index (key)}...{/each} ``` ```sv @@ -207,7 +222,7 @@ Additional conditions can be added with `{:else if expression}`, optionally endi Iterating over lists of values can be done with an each block. -```html +```sv

Shopping list

    {#each items as item} @@ -222,7 +237,7 @@ You can use each blocks to iterate over any array or array-like value — that i An each block can also specify an *index*, equivalent to the second argument in an `array.map(...)` callback: -```html +```sv {#each items as item, i}
  • {i + 1}: {item.name} x {item.qty}
  • {/each} @@ -232,7 +247,12 @@ An each block can also specify an *index*, equivalent to the second argument in If a *key* expression is provided — which must uniquely identify each list item — Svelte will use it to diff the list when data changes, rather than adding or removing items at the end. The key can be any object, but strings and numbers are recommended since they allow identity to persist when the objects themselves change. -```html +```sv +{#each items as item (item.id)} +
  • {item.name} x {item.qty}
  • +{/each} + + {#each items as item, i (item.id)}
  • {i + 1}: {item.name} x {item.qty}
  • {/each} @@ -242,7 +262,7 @@ If a *key* expression is provided — which must uniquely identify each list ite You can freely use destructuring and rest patterns in each blocks. -```html +```sv {#each items as { id, name, qty }, i (id)}
  • {i + 1}: {name} x {qty}
  • {/each} @@ -260,7 +280,7 @@ You can freely use destructuring and rest patterns in each blocks. An each block can also have an `{:else}` clause, which is rendered if the list is empty. -```html +```sv {#each todos as todo}

    {todo.text}

    {:else} @@ -285,7 +305,7 @@ An each block can also have an `{:else}` clause, which is rendered if the list i Await blocks allow you to branch on the three possible states of a Promise — pending, fulfilled or rejected. -```html +```sv {#await promise}

    waiting for the promise to resolve...

    @@ -302,7 +322,7 @@ Await blocks allow you to branch on the three possible states of a Promise — p The `catch` block can be omitted if you don't need to render anything when the promise rejects (or no error is possible). -```html +```sv {#await promise}

    waiting for the promise to resolve...

    @@ -316,7 +336,7 @@ The `catch` block can be omitted if you don't need to render anything when the p If you don't care about the pending state, you can also omit the initial block. -```html +```sv {#await promise then value}

    The value is {value}

    {/await} @@ -337,7 +357,7 @@ The expression should be valid standalone HTML — `{@html "
    "}content{@html > Svelte does not sanitize expressions before injecting HTML. If the data comes from an untrusted source, you must sanitize it, or you are exposing your users to an XSS vulnerability. -```html +```sv

    {post.title}

    {@html post.content} @@ -360,7 +380,7 @@ The `{@debug ...}` tag offers an alternative to `console.log(...)`. It logs the It accepts a comma-separated list of variable names (not arbitrary expressions). -```html +```sv @@ -1331,7 +1354,7 @@ The `` element renders a component dynamically, using the comp If `this` is falsy, no component is rendered. -```html +```sv ``` @@ -1349,7 +1372,7 @@ If `this` is falsy, no component is rendered. The `` element allows you to add event listeners to the `window` object without worrying about removing them when the component is destroyed, or checking for the existence of `window` when server-side rendering. -```html +```sv @@ -582,7 +584,7 @@ Animates a `blur` filter alongside an element's opacity. * `opacity` (`number`, default 0) - the opacity value to animate out to and in from * `amount` (`number`, default 5) - the size of the blur in pixels -```html +```sv @@ -621,7 +623,7 @@ Animates the x and y positions and the opacity of an element. `in` transitions a You can see the `fly` transition in action in the [transition tutorial](tutorial/adding-parameters-to-transitions). -```html +```sv - \ No newline at end of file + diff --git a/site/content/tutorial/07-lifecycle/04-tick/app-b/App.svelte b/site/content/tutorial/07-lifecycle/04-tick/app-b/App.svelte index c9cb6de420..477b5ffb79 100644 --- a/site/content/tutorial/07-lifecycle/04-tick/app-b/App.svelte +++ b/site/content/tutorial/07-lifecycle/04-tick/app-b/App.svelte @@ -4,7 +4,7 @@ let text = `Select some text and hit the tab key to toggle uppercase`; async function handleKeydown(event) { - if (event.which !== 9) return; + if (event.key !== 'Tab') return; event.preventDefault(); @@ -34,4 +34,4 @@ } - \ No newline at end of file + diff --git a/site/content/tutorial/07-lifecycle/04-tick/text.md b/site/content/tutorial/07-lifecycle/04-tick/text.md index b58b024ad6..8f5603a361 100644 --- a/site/content/tutorial/07-lifecycle/04-tick/text.md +++ b/site/content/tutorial/07-lifecycle/04-tick/text.md @@ -4,7 +4,7 @@ title: tick The `tick` function is unlike other lifecycle functions in that you can call it any time, not just when the component first initialises. It returns a promise that resolves as soon as any pending state changes have been applied to the DOM (or immediately, if there are no pending state changes). -When you invalidate component state in Svelte, it doesn't update the DOM immediately. Instead, it waits until the next *microtask* to see if there are any other changes that need to be applied, including in other components. Doing so avoids unnecessary work and allows the browser to batch things more effectively. +When you update component state in Svelte, it doesn't update the DOM immediately. Instead, it waits until the next *microtask* to see if there are any other changes that need to be applied, including in other components. Doing so avoids unnecessary work and allows the browser to batch things more effectively. You can see that behaviour in this example. Select a range of text and hit the tab key. Because the `