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 406f2a591a..73bc68d72f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,9 +1,101 @@ # Svelte changelog -## Unreleased +## 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)) +* In `vars` array, correctly indicate whether `module` variables are `mutated` or `reassigned` ([#3215](https://github.com/sveltejs/svelte/issues/3215)) +* Fix spread props not updating in certain situations ([#3521](https://github.com/sveltejs/svelte/issues/3521), [#4480](https://github.com/sveltejs/svelte/issues/4480)) +* Use the fallback content for slots if they are passed only whitespace ([#4092](https://github.com/sveltejs/svelte/issues/4092)) +* Fix bitmask overflow for `{#if}` blocks ([#4263](https://github.com/sveltejs/svelte/issues/4263)) +* In `dev` mode, check for unknown props even if the component has no writable props ([#4323](https://github.com/sveltejs/svelte/issues/4323)) +* Exclude global variables from `$capture_state` ([#4463](https://github.com/sveltejs/svelte/issues/4463)) +* Fix bitmask overflow for slots ([#4481](https://github.com/sveltejs/svelte/issues/4481)) + +## 3.19.1 + +* Do not treat modifications to `$$props` as updates to a store called `$props` ([#4368](https://github.com/sveltejs/svelte/issues/4368)) +* Deconflict `value` parameter name used in contextual bindings ([#4445](https://github.com/sveltejs/svelte/issues/4445)) +* Fix dev mode validation of `{#each}` blocks using strings ([#4450](https://github.com/sveltejs/svelte/issues/4450)) + +## 3.19.0 * Fix indirect bindings involving elements with spreads ([#3680](https://github.com/sveltejs/svelte/issues/3680)) +* `$capture_state`/`$inject_state` now act on the component's entire state, rather than its props ([#3822](https://github.com/sveltejs/svelte/pull/3822)) +* Warn when using `` and `Foo` is dynamic ([#4331](https://github.com/sveltejs/svelte/issues/4331)) +* Display compilation warnings in `svelte/register` in dev mode ([#4364](https://github.com/sveltejs/svelte/issues/4364)) * Fix unneeded updating of keyed each blocks ([#4373](https://github.com/sveltejs/svelte/issues/4373)) +* Throw runtime error in dev mode for non-array-like values in `{#each}` blocks ([#4408](https://github.com/sveltejs/svelte/issues/4408)) ## 3.18.2 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 e05154bd7c..e2e4fcd532 100644 --- a/README.md +++ b/README.md @@ -7,11 +7,6 @@ npm version - - build status - - license @@ -37,10 +32,7 @@ cd svelte npm install ``` -> 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 -> ``` +> Do not use Yarn to install the dependencies, as the specific package versions in `package-lock.json` are used to build and test Svelte. To build the compiler, and all the other modules included in the package: @@ -80,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 8f0b7469f8..cd9a83e04b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "svelte", - "version": "3.18.2", + "version": "3.23.0", "lockfileVersion": 1, "requires": true, "dependencies": { @@ -137,6 +137,12 @@ } } }, + "@tootallnate/once": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-1.0.0.tgz", + "integrity": "sha512-KYyTT/T6ALPkIRd2Ge080X/BsXvy9O0hcWTtMWkPvwAwF99+vn6Dv4GzrFT/Nn1LePr+FFDbRXXlqmsy9lw2zA==", + "dev": true + }, "@types/eslint-visitor-keys": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/@types/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz", @@ -274,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": { @@ -290,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 } } @@ -486,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", @@ -609,16 +621,16 @@ } }, "codecov": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/codecov/-/codecov-3.5.0.tgz", - "integrity": "sha512-/OsWOfIHaQIr7aeZ4pY0UC1PZT6kimoKFOFYFNb6wxo3iw12nRrh+mNGH72rnXxNsq6SGfesVPizm/6Q3XqcFQ==", + "version": "3.6.5", + "resolved": "https://registry.npmjs.org/codecov/-/codecov-3.6.5.tgz", + "integrity": "sha512-v48WuDMUug6JXwmmfsMzhCHRnhUf8O3duqXvltaYJKrO1OekZWpB/eH6iIoaxMl8Qli0+u3OxptdsBOYiD7VAQ==", "dev": true, "requires": { - "argv": "^0.0.2", - "ignore-walk": "^3.0.1", - "js-yaml": "^3.13.1", - "teeny-request": "^3.11.3", - "urlgrey": "^0.4.4" + "argv": "0.0.2", + "ignore-walk": "3.0.3", + "js-yaml": "3.13.1", + "teeny-request": "6.0.1", + "urlgrey": "0.4.4" } }, "color-convert": { @@ -1346,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": { @@ -1399,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" @@ -1592,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", @@ -1670,6 +1662,43 @@ "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", + "integrity": "sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg==", + "dev": true, + "requires": { + "@tootallnate/once": "1", + "agent-base": "6", + "debug": "4" + }, + "dependencies": { + "agent-base": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.0.tgz", + "integrity": "sha512-j1Q7cSCqN+AwrmDd+pzgqc0/NpC655x2bUf5ZjRIO77DcNBFmh+OgRNzF6OKdCC9RSCb19fGd99+bhXFdkRNqw==", + "dev": true, + "requires": { + "debug": "4" + } + }, + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + } + } + }, "http-signature": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", @@ -1707,9 +1736,9 @@ "dev": true }, "ignore-walk": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/ignore-walk/-/ignore-walk-3.0.1.tgz", - "integrity": "sha512-DTVlMx3IYPe0/JJcYP7Gxg7ttZZu3IInhuEhbchuqneY9wWe5Ojy2mXLBaQFUQmo0AW2r3qG7m1mg86js+gnlQ==", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/ignore-walk/-/ignore-walk-3.0.3.tgz", + "integrity": "sha512-m7o6xuOaT1aqheYHKf8W6J5pYH85ZI9w077erOzLje3JsB1gkafkAhHHY19dqjulgIZHFm32Cp5uNZgcQqdJKw==", "dev": true, "requires": { "minimatch": "^3.0.4" @@ -1947,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": { @@ -2012,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": { @@ -2264,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": { @@ -2360,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", @@ -2497,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", @@ -2650,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", @@ -3010,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", @@ -3362,6 +3382,15 @@ "integrity": "sha1-NbCYdbT/SfJqd35QmzCQoyJr8ks=", "dev": true }, + "stream-events": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/stream-events/-/stream-events-1.0.5.tgz", + "integrity": "sha512-E1GUzBSgvct8Jsb3v2X15pjzN1tYebtbLaMg+eBOUOAxgbLoSbT2NS91ckc5lJD1KfLjId+jXJRgo0qnV5Nerg==", + "dev": true, + "requires": { + "stubs": "^3.0.0" + } + }, "string-width": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", @@ -3409,6 +3438,12 @@ "integrity": "sha512-VTyMAUfdm047mwKl+u79WIdrZxtFtn+nBxHeb844XBQ9uMNTuTHdx2hc5RiAJYqwTj3wc/xe5HLSdJSkJ+WfZw==", "dev": true }, + "stubs": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/stubs/-/stubs-3.0.0.tgz", + "integrity": "sha1-6NK6H6nJBXAwPAMLaQD31fiavls=", + "dev": true + }, "sucrase": { "version": "3.10.1", "resolved": "https://registry.npmjs.org/sucrase/-/sucrase-3.10.1.tgz", @@ -3449,14 +3484,43 @@ } }, "teeny-request": { - "version": "3.11.3", - "resolved": "https://registry.npmjs.org/teeny-request/-/teeny-request-3.11.3.tgz", - "integrity": "sha512-CKncqSF7sH6p4rzCgkb/z/Pcos5efl0DmolzvlqRQUNcpRIruOhY9+T1FsIlyEbfWd7MsFpodROOwHYh2BaXzw==", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/teeny-request/-/teeny-request-6.0.1.tgz", + "integrity": "sha512-TAK0c9a00ELOqLrZ49cFxvPVogMUFaWY8dUsQc/0CuQPGF+BOxOQzXfE413BAk2kLomwNplvdtMpeaeGWmoc2g==", "dev": true, "requires": { - "https-proxy-agent": "^2.2.1", + "http-proxy-agent": "^4.0.0", + "https-proxy-agent": "^4.0.0", "node-fetch": "^2.2.0", + "stream-events": "^1.0.5", "uuid": "^3.3.2" + }, + "dependencies": { + "agent-base": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-5.1.1.tgz", + "integrity": "sha512-TMeqbNl2fMW0nMjTEPOwe3J/PRFP4vqeoNuQMG0HlMrtm5QxKqdvAkZ1pRBQ/ulIyDD5Yq0nJ7YbdD8ey0TO3g==", + "dev": true + }, + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "https-proxy-agent": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-4.0.0.tgz", + "integrity": "sha512-zoDhWrkR3of1l9QAL8/scJZyLu8j/gBkcwcaQOZh7Gyh/+uJQzGVETdgT30akuwkpL8HTRfssqI3BZuV18teDg==", + "dev": true, + "requires": { + "agent-base": "5", + "debug": "4" + } + } } }, "test-exclude": { @@ -3591,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", @@ -3779,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", @@ -4031,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 6000e9d1c4..90cee0a5d5 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "svelte", - "version": "3.18.2", + "version": "3.23.0", "description": "Cybernetically enhanced web apps", "module": "index.mjs", "main": "index", diff --git a/register.js b/register.js index 3278c1cbf5..25f8aa4309 100644 --- a/register.js +++ b/register.js @@ -36,7 +36,15 @@ function registerExtension(extension) { format: 'cjs' }); - const { js } = compile(fs.readFileSync(filename, 'utf-8'), options); + const { js, warnings } = compile(fs.readFileSync(filename, 'utf-8'), options); + + if (options.dev) { + warnings.forEach(warning => { + console.warn(`\nSvelte Warning in ${warning.filename}:`); + console.warn(warning.message); + console.warn(warning.frame); + }) + } return module._compile(js.code, filename); }; diff --git a/site/content/blog/2019-04-16-svelte-for-new-developers.md b/site/content/blog/2019-04-16-svelte-for-new-developers.md index fc8e993e88..796a6c11ab 100644 --- a/site/content/blog/2019-04-16-svelte-for-new-developers.md +++ b/site/content/blog/2019-04-16-svelte-for-new-developers.md @@ -18,7 +18,7 @@ You'll be using the *command line*, also known as the terminal. On Windows, you The command line is a way to interact with your computer (or another computer! but that's a topic for another time) with more power and control than the GUI (graphical user interface) that most people use day-to-day. -Once on the command line, you can navigate the filesystem using `ls` to list the contents of your current directory, and `cd` to change the current directory. For example, if you had a `Development` directory of your projects inside your home directory, you would type +Once on the command line, you can navigate the filesystem using `ls` (`dir` on Windows) to list the contents of your current directory, and `cd` to change the current directory. For example, if you had a `Development` directory of your projects inside your home directory, you would type ```bash cd Development @@ -34,7 +34,7 @@ cd svelte-projects A full introduction to the command line is out of the scope of this guide, but here are a few more useful commands: * `cd ..` — navigates to the parent of the current directory -* `cat my-file.txt` — on Mac/Linux, lists the contents of `my-file.txt` +* `cat my-file.txt` — on Mac/Linux (`type my-file.txt` on Windows), lists the contents of `my-file.txt` * `open .` (or `start .` on Windows) — opens the current directory in Finder or File Explorer 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 026a2da5b3..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 ` ``` @@ -57,7 +57,7 @@ In development mode (see the [compiler options](docs#svelte_compile)), a warning If you export a `const`, `class` or `function`, it is readonly from outside the component. Function *expressions* are valid props, however. -```html +```sv @@ -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,15 +52,26 @@ Attribute values can contain JavaScript expressions. Or they can *be* JavaScript expressions. -```html +```sv ``` --- -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: +Boolean attributes are included on the element if their value is [truthy](https://developer.mozilla.org/en-US/docs/Glossary/Truthy) and excluded if it's [falsy](https://developer.mozilla.org/en-US/docs/Glossary/Falsy). + +All other attributes are included unless their value is [nullish](https://developer.mozilla.org/en-US/docs/Glossary/Nullish) (`null` or `undefined`). ```html + +
This div has no title attribute
+``` + +--- + +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: + +```sv ``` @@ -68,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 @@ -80,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 ``` @@ -90,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 ``` @@ -98,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 @@ -113,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}.

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

Hello world

``` @@ -134,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 ``` @@ -156,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} @@ -166,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} @@ -186,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 @@ -196,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} @@ -211,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} @@ -221,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} @@ -231,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} @@ -249,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} @@ -274,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...

    @@ -291,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...

    @@ -305,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} @@ -326,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} @@ -349,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 @@ -1320,7 +1354,7 @@ The `` element renders a component dynamically, using the comp If `this` is falsy, no component is rendered. -```html +```sv ``` @@ -1338,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 + \ No newline at end of file diff --git a/site/content/examples/04-events/05-dom-event-forwarding/CustomButton.svelte b/site/content/examples/04-events/05-dom-event-forwarding/CustomButton.svelte new file mode 100644 index 0000000000..f521c1f471 --- /dev/null +++ b/site/content/examples/04-events/05-dom-event-forwarding/CustomButton.svelte @@ -0,0 +1,22 @@ + + + \ No newline at end of file diff --git a/site/content/examples/04-events/05-dom-event-forwarding/FancyButton.svelte b/site/content/examples/04-events/05-dom-event-forwarding/FancyButton.svelte deleted file mode 100644 index 68dcc68636..0000000000 --- a/site/content/examples/04-events/05-dom-event-forwarding/FancyButton.svelte +++ /dev/null @@ -1,15 +0,0 @@ - - - \ No newline at end of file diff --git a/site/content/examples/05-bindings/08-media-elements/App.svelte b/site/content/examples/05-bindings/08-media-elements/App.svelte index 469e9e12eb..7a071dbe49 100644 --- a/site/content/examples/05-bindings/08-media-elements/App.svelte +++ b/site/content/examples/05-bindings/08-media-elements/App.svelte @@ -109,8 +109,8 @@
    \ No newline at end of file +
    diff --git a/site/content/examples/06-lifecycle/03-tick/App.svelte b/site/content/examples/06-lifecycle/03-tick/App.svelte index c9cb6de420..477b5ffb79 100644 --- a/site/content/examples/06-lifecycle/03-tick/App.svelte +++ b/site/content/examples/06-lifecycle/03-tick/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/examples/09-transitions/04-custom-js-transitions/App.svelte b/site/content/examples/09-transitions/04-custom-js-transitions/App.svelte index 3b3fb94d1c..396c793639 100644 --- a/site/content/examples/09-transitions/04-custom-js-transitions/App.svelte +++ b/site/content/examples/09-transitions/04-custom-js-transitions/App.svelte @@ -4,7 +4,7 @@ function typewriter(node, { speed = 50 }) { const valid = ( node.childNodes.length === 1 && - node.childNodes[0].nodeType === 3 + node.childNodes[0].nodeType === Node.TEXT_NODE ); if (!valid) { @@ -33,4 +33,4 @@

    The quick brown fox jumps over the lazy dog

    -{/if} \ No newline at end of file +{/if} diff --git a/site/content/examples/10-animations/00-animate/App.svelte b/site/content/examples/10-animations/00-animate/App.svelte index 279821491b..a90d0ecfb5 100644 --- a/site/content/examples/10-animations/00-animate/App.svelte +++ b/site/content/examples/10-animations/00-animate/App.svelte @@ -112,7 +112,7 @@
    diff --git a/site/content/examples/21-miscellaneous/01-hacker-news/Item.svelte b/site/content/examples/21-miscellaneous/01-hacker-news/Item.svelte index e9cd617e96..608d04e497 100644 --- a/site/content/examples/21-miscellaneous/01-hacker-news/Item.svelte +++ b/site/content/examples/21-miscellaneous/01-hacker-news/Item.svelte @@ -3,6 +3,8 @@ export let item; export let returnTo; + + $: url = !item.domain ? `https://news.ycombinator.com/${item.url}` : item.url; + + \ No newline at end of file diff --git a/site/content/tutorial/05-events/06-dom-event-forwarding/app-a/FancyButton.svelte b/site/content/tutorial/05-events/06-dom-event-forwarding/app-a/FancyButton.svelte deleted file mode 100644 index b75f19a1f2..0000000000 --- a/site/content/tutorial/05-events/06-dom-event-forwarding/app-a/FancyButton.svelte +++ /dev/null @@ -1,15 +0,0 @@ - - - \ No newline at end of file diff --git a/site/content/tutorial/05-events/06-dom-event-forwarding/app-b/App.svelte b/site/content/tutorial/05-events/06-dom-event-forwarding/app-b/App.svelte index 1429cae207..e75c78106a 100644 --- a/site/content/tutorial/05-events/06-dom-event-forwarding/app-b/App.svelte +++ b/site/content/tutorial/05-events/06-dom-event-forwarding/app-b/App.svelte @@ -1,9 +1,9 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/site/content/tutorial/05-events/06-dom-event-forwarding/app-b/CustomButton.svelte b/site/content/tutorial/05-events/06-dom-event-forwarding/app-b/CustomButton.svelte new file mode 100644 index 0000000000..f521c1f471 --- /dev/null +++ b/site/content/tutorial/05-events/06-dom-event-forwarding/app-b/CustomButton.svelte @@ -0,0 +1,22 @@ + + + \ No newline at end of file diff --git a/site/content/tutorial/05-events/06-dom-event-forwarding/app-b/FancyButton.svelte b/site/content/tutorial/05-events/06-dom-event-forwarding/app-b/FancyButton.svelte deleted file mode 100644 index 68dcc68636..0000000000 --- a/site/content/tutorial/05-events/06-dom-event-forwarding/app-b/FancyButton.svelte +++ /dev/null @@ -1,15 +0,0 @@ - - - \ No newline at end of file diff --git a/site/content/tutorial/05-events/06-dom-event-forwarding/text.md b/site/content/tutorial/05-events/06-dom-event-forwarding/text.md index 0959e1d98b..be9ae77f89 100644 --- a/site/content/tutorial/05-events/06-dom-event-forwarding/text.md +++ b/site/content/tutorial/05-events/06-dom-event-forwarding/text.md @@ -4,7 +4,7 @@ title: DOM event forwarding Event forwarding works for DOM events too. -We want to get notified of clicks on our `` — to do that, we just need to forward `click` events on the `
    -
    \ No newline at end of file +
diff --git a/site/content/tutorial/07-lifecycle/03-update/app-b/App.svelte b/site/content/tutorial/07-lifecycle/03-update/app-b/App.svelte index bdf42e28a9..97caca99d5 100644 --- a/site/content/tutorial/07-lifecycle/03-update/app-b/App.svelte +++ b/site/content/tutorial/07-lifecycle/03-update/app-b/App.svelte @@ -20,7 +20,7 @@ ]; function handleKeydown(event) { - if (event.which === 13) { + if (event.key === 'Enter') { const text = event.target.value; if (!text) return; @@ -104,4 +104,4 @@ - \ No newline at end of file + diff --git a/site/content/tutorial/07-lifecycle/04-tick/app-a/App.svelte b/site/content/tutorial/07-lifecycle/04-tick/app-a/App.svelte index 3386ff93df..97edefa935 100644 --- a/site/content/tutorial/07-lifecycle/04-tick/app-a/App.svelte +++ b/site/content/tutorial/07-lifecycle/04-tick/app-a/App.svelte @@ -2,7 +2,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(); @@ -32,4 +32,4 @@ } - \ 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 `