Merge branch 'master' into pr/5269

pull/5269/head
Conduitry 5 years ago
commit e6eac2456f

@ -8,10 +8,13 @@ the issue. One way we prioritize issues is by the number of :+1: reactions on
their descriptions. Please DO NOT add `+1` or :+1: comments.
### Feature requests and proposals
We're excited to hear how we can make Svelte better. Please add as much detail
as you can on your use case.
as you can on your use case. To propose an implementation of a large feature or
change, please create an [RFC](https://github.com/sveltejs/rfcs).
### Bugs
If you're filing an issue about a bug please include as much information
as you can including the following.

@ -7,6 +7,11 @@ assignees: ''
---
<!--
If you'd like to propose an implementation for a large new feature or change then please create an RFC:
https://github.com/sveltejs/rfcs
-->
**Is your feature request related to a problem? Please describe.**
A clear and concise description of what the problem is. For example: I'm always frustrated when [...]

@ -1,8 +1,7 @@
### Before submitting the PR, please make sure you do the following
- [ ] It's really useful if your PR relates to an outstanding issue, so please reference it in your PR, or create an explanatory one for discussion. In many cases, features are absent for a reason.
- [ ] This message body should clearly illustrate what problems it solves. If there are related issues, remember to reference them.
- [ ] Ideally, include a test that fails without this PR but passes with it. PRs will only be merged once they pass CI. (Remember to `npm run lint`!)
- [ ] It's really useful if your PR references an issue where it is discussed ahead of time. In many cases, features are absent for a reason. For large changes, please create an RFC: https://github.com/sveltejs/rfcs
- [ ] This message body should clearly illustrate what problems it solves.
- [ ] Ideally, include a test that fails without this PR but passes with it.
### Tests
- [ ] Run the tests with `npm test` or `yarn test`)
- [ ] Run the tests with `npm test` and lint the project with `npm run lint`

@ -0,0 +1,14 @@
module.exports = {
file: [
'test/test.ts'
],
require: [
'sucrase/register'
]
};
// add coverage options when running 'npx c8 mocha'
if (process.env.NODE_V8_COVERAGE) {
module.exports.fullTrace = true;
module.exports.require.push('source-map-support/register');
}

@ -2,9 +2,64 @@
## Unreleased
* Support `<slot slot="...">` ([#2079](https://github.com/sveltejs/svelte/issues/2079))
* Add `EventSource` to known globals ([#5463](https://github.com/sveltejs/svelte/issues/5463))
* Fix compiler exception with `~`/`+` combinators and `{...spread}` attributes ([#5465](https://github.com/sveltejs/svelte/issues/5465))
## 3.28.0
* Add `{#key}` block for keying arbitrary content on an expression ([#1469](https://github.com/sveltejs/svelte/issues/1469))
## 3.27.0
* Add `|nonpassive` event modifier, explicitly passing `passive: false` ([#2068](https://github.com/sveltejs/svelte/issues/2068))
* Scope CSS selectors with `~` and `+` combinators ([#3104](https://github.com/sveltejs/svelte/issues/3104))
* Fix keyed `{#each}` not reacting to key changing ([#5444](https://github.com/sveltejs/svelte/issues/5444))
* Fix destructuring into store values ([#5449](https://github.com/sveltejs/svelte/issues/5449))
* Fix erroneous `missing-declaration` warning with `use:obj.method` ([#5451](https://github.com/sveltejs/svelte/issues/5451))
## 3.26.0
* Support `use:obj.method` as actions ([#3935](https://github.com/sveltejs/svelte/issues/3935))
* Support `_` as numeric separator ([#5407](https://github.com/sveltejs/svelte/issues/5407))
* Fix assignments to properties on store values ([#5412](https://github.com/sveltejs/svelte/issues/5412))
* Add special style scoping handling of `[open]` selectors on `<details>` elements ([#5421](https://github.com/sveltejs/svelte/issues/5421))
* Support `import.meta` in template expressions ([#5422](https://github.com/sveltejs/svelte/issues/5422))
## 3.25.1
* Fix specificity of certain styles involving a child selector ([#4795](https://github.com/sveltejs/svelte/issues/4795))
* Fix transitions that are parameterised with stores ([#5244](https://github.com/sveltejs/svelte/issues/5244))
* Fix scoping of styles involving child selector and `*` ([#5370](https://github.com/sveltejs/svelte/issues/5370))
* Fix destructuring which reassigns stores ([#5388](https://github.com/sveltejs/svelte/issues/5388))
* Fix `{#await}`s with no `{:catch}` getting stuck unresolved if the promise rejects ([#5401](https://github.com/sveltejs/svelte/issues/5401))
## 3.25.0
* Use `null` rather than `undefined` for coerced bound value of `<input type="number">` ([#1701](https://github.com/sveltejs/svelte/issues/1701))
* Expose object of which slots have received content in `$$slots` ([#2106](https://github.com/sveltejs/svelte/issues/2106))
* Correctly disallow using lifecycle hooks after synchronous component initialisation ([#4259](https://github.com/sveltejs/svelte/issues/4259), [#4899](https://github.com/sveltejs/svelte/issues/4899))
* Re-throw an unhandled rejection when an `{#await}` block with no `{:catch}` gets a rejection ([#5129](https://github.com/sveltejs/svelte/issues/5129))
* Add types to `createEventDispatcher` ([#5211](https://github.com/sveltejs/svelte/issues/5211))
* In SSR mode, do not automatically declare variables for reactive assignments to member expressions ([#5247](https://github.com/sveltejs/svelte/issues/5247))
* Include selector in message of `unused-css-selector` warning ([#5252](https://github.com/sveltejs/svelte/issues/5252))
* Fix using `<Namespaced.Component/>`s in child `{#await}`/`{#each}` contexts ([#5255](https://github.com/sveltejs/svelte/issues/5255))
* Fix using `<svelte:component>` in `{:catch}` ([#5259](https://github.com/sveltejs/svelte/issues/5259))
* Fix setting one-way bound `<input>` `value` to `undefined` when it has spread attributes ([#5270](https://github.com/sveltejs/svelte/issues/5270))
* Fix deep two-way bindings inside an `{#each}` involving a store ([#5286](https://github.com/sveltejs/svelte/issues/5286))
* Use valid XHTML for elements that are optimised and inserted with `.innerHTML` ([#5315](https://github.com/sveltejs/svelte/issues/5315))
* Fix reactivity of `$$props` in slot fallback content ([#5367](https://github.com/sveltejs/svelte/issues/5367))
## 3.24.1
* Prevent duplicate invalidation with certain two-way component bindings ([#3180](https://github.com/sveltejs/svelte/issues/3180), [#5117](https://github.com/sveltejs/svelte/issues/5117), [#5144](https://github.com/sveltejs/svelte/issues/5144))
* Fix reactivity when passing `$$props` to a `<slot>` ([#3364](https://github.com/sveltejs/svelte/issues/3364))
* Fix transitions on `{#each}` `{:else}` ([#4970](https://github.com/sveltejs/svelte/issues/4970))
* Fix unneeded invalidation of `$$props` and `$$restProps` ([#4993](https://github.com/sveltejs/svelte/issues/4993), [#5118](https://github.com/sveltejs/svelte/issues/5118))
* Provide better compiler error message when mismatched tags are due to autoclosing of tags ([#5049](https://github.com/sveltejs/svelte/issues/5049))
* Add `a11y-label-has-associated-control` warning ([#5074](https://github.com/sveltejs/svelte/pull/5074))
* Add `a11y-media-has-caption` warning ([#5075](https://github.com/sveltejs/svelte/pull/5075))
* Fix `bind:group` when using contextual reference ([#5174](https://github.com/sveltejs/svelte/issues/5174))
## 3.24.0

@ -43,13 +43,16 @@ When [opening a new issue](https://github.com/sveltejs/svelte/issues/new/choose)
- **One issue, one bug:** Please report a single bug per issue.
- **Provide reproduction steps:** List all the steps necessary to reproduce the issue. The person reading your bug report should be able to follow these steps to reproduce your issue with minimal effort. If possible, use the [REPL](https://svelte.dev/repl) to create your reproduction.
## RFCs
If you'd like to propose an implementation for a large new feature or change then please [create an RFC](https://github.com/sveltejs/rfcs) to discuss it up front.
## Installation
1. Ensure you have [npm](https://www.npmjs.com/get-npm) installed.
1. After cloning the repository, run `npm install` in the root of the repository.
1. To start a development server, run `npm run dev`.
## Pull requests
### Your first pull request

@ -20,6 +20,15 @@ Svelte is a new way to build web applications. It's a compiler that takes your d
Learn more at the [Svelte website](https://svelte.dev), or stop by the [Discord chatroom](https://svelte.dev/chat).
## Supporting Svelte
Svelte is an MIT-licensed open source project with its ongoing development made possible entirely by the support of awesome volunteers. If you'd like to support their efforts, please consider:
- [Becoming a backer on Open Collective](https://opencollective.com/svelte).
Funds donated via Open Collective will be used for compensating expenses related to Svelte's development such as hosting costs. If sufficient donations are received, funds may also be used to support Svelte's development more directly.
## Development
Pull requests are encouraged and always welcome. [Pick an issue](https://github.com/sveltejs/svelte/issues?q=is%3Aissue+is%3Aopen+sort%3Aupdated-desc) and help us out!

@ -1,4 +0,0 @@
--require source-map-support/register
--full-trace
--recursive
test/test.js

@ -1 +0,0 @@
test/test.js

496
package-lock.json generated

@ -1,6 +1,6 @@
{
"name": "svelte",
"version": "3.24.0",
"version": "3.28.0",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
@ -144,8 +144,8 @@
}
},
"@sveltejs/eslint-config": {
"version": "github:sveltejs/eslint-config#e8a9b27cd3f7aa66388474412b1a5c11c5a44ade",
"from": "github:sveltejs/eslint-config#v0.0.1",
"version": "github:sveltejs/eslint-config#848ce6464a9ae9c2f3a3095474701dfe9ab851df",
"from": "github:sveltejs/eslint-config#v5.0.0",
"dev": true
},
"@tootallnate/once": {
@ -197,9 +197,9 @@
"dev": true
},
"@types/mocha": {
"version": "5.2.7",
"resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-5.2.7.tgz",
"integrity": "sha512-NYrtPht0wGzhwe9+/idPaBB+TqkY9AhTvOLMkThm0IoEfLaiVQZwBwyJ5puCkO3AUCWrmcoePjp2mbFocKy4SQ==",
"version": "7.0.2",
"resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-7.0.2.tgz",
"integrity": "sha512-ZvO2tAcjmMi8V/5Z3JsyofMe3hasRcaw88cto5etSVMwVQfeivGAlEYmaQgceUSVYFofVjT+ioHsATjdWcFt1w==",
"dev": true
},
"@types/node": {
@ -315,9 +315,9 @@
"dev": true
},
"acorn": {
"version": "7.3.1",
"resolved": "https://registry.npmjs.org/acorn/-/acorn-7.3.1.tgz",
"integrity": "sha512-tLc0wSnatxAQHVHUapaHdz72pi9KUyHjq5KyHjGg9Y8Ifdc79pTh2XvI6I1/chZbnM7QtNKzh66ooDogPZSleA==",
"version": "7.4.0",
"resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.0.tgz",
"integrity": "sha512-+G7P8jJmCHr+S+cLfQxygbWhXy+8YTVGzAkpEbcLo2mLoL7tij/VG41QSHACSf5QgYRhMZYHuNc6drJaO0Da+w==",
"dev": true
},
"acorn-globals": {
@ -422,6 +422,16 @@
"integrity": "sha1-q8av7tzqUugJzcA3au0845Y10X8=",
"dev": true
},
"anymatch": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.1.tgz",
"integrity": "sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg==",
"dev": true,
"requires": {
"normalize-path": "^3.0.0",
"picomatch": "^2.0.4"
}
},
"argparse": {
"version": "1.0.10",
"resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz",
@ -630,6 +640,12 @@
"tweetnacl": "^0.14.3"
}
},
"binary-extensions": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.1.0.tgz",
"integrity": "sha512-1Yj8h9Q+QDF5FzhMs/c9+6UntbD5MkRfRwac8DoEm9ZfUBZ7tZ55YcGVAzEe4bXsdQHEk+s9S5wsOKVdZrw0tQ==",
"dev": true
},
"brace-expansion": {
"version": "1.1.11",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
@ -640,6 +656,15 @@
"concat-map": "0.0.1"
}
},
"braces": {
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz",
"integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==",
"dev": true,
"requires": {
"fill-range": "^7.0.1"
}
},
"browser-process-hrtime": {
"version": "0.1.3",
"resolved": "https://registry.npmjs.org/browser-process-hrtime/-/browser-process-hrtime-0.1.3.tgz",
@ -736,6 +761,22 @@
"integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==",
"dev": true
},
"chokidar": {
"version": "3.3.0",
"resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.3.0.tgz",
"integrity": "sha512-dGmKLDdT3Gdl7fBUe8XK+gAtGmzy5Fn0XkkWQuYxGIgWVPPse2CxFA5mtrlD0TOHaHjEUqkWNyP1XdHoJES/4A==",
"dev": true,
"requires": {
"anymatch": "~3.1.1",
"braces": "~3.0.2",
"fsevents": "~2.1.1",
"glob-parent": "~5.1.0",
"is-binary-path": "~2.1.0",
"is-glob": "~4.0.1",
"normalize-path": "~3.0.0",
"readdirp": "~3.2.0"
}
},
"cli-cursor": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz",
@ -762,12 +803,6 @@
"wrap-ansi": "^5.1.0"
}
},
"code-point-at": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz",
"integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=",
"dev": true
},
"code-red": {
"version": "0.1.3",
"resolved": "https://registry.npmjs.org/code-red/-/code-red-0.1.3.tgz",
@ -1020,23 +1055,36 @@
}
},
"es-abstract": {
"version": "1.13.0",
"resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.13.0.tgz",
"integrity": "sha512-vDZfg/ykNxQVwup/8E1BZhVzFfBxs9NqMzGcvIJrqg5k2/5Za2bWo40dK2J1pgLngZ7c+Shh8lwYtLGyrwPutg==",
"version": "1.17.6",
"resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.6.tgz",
"integrity": "sha512-Fr89bON3WFyUi5EvAeI48QTWX0AyekGgLA8H+c+7fbfCkJwRWRMLd8CQedNEyJuoYYhmtEqY92pgte1FAhBlhw==",
"dev": true,
"requires": {
"es-to-primitive": "^1.2.0",
"es-to-primitive": "^1.2.1",
"function-bind": "^1.1.1",
"has": "^1.0.3",
"is-callable": "^1.1.4",
"is-regex": "^1.0.4",
"object-keys": "^1.0.12"
"has-symbols": "^1.0.1",
"is-callable": "^1.2.0",
"is-regex": "^1.1.0",
"object-inspect": "^1.7.0",
"object-keys": "^1.1.1",
"object.assign": "^4.1.0",
"string.prototype.trimend": "^1.0.1",
"string.prototype.trimstart": "^1.0.1"
},
"dependencies": {
"has-symbols": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.1.tgz",
"integrity": "sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==",
"dev": true
}
}
},
"es-to-primitive": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.0.tgz",
"integrity": "sha512-qZryBOJjV//LaxLTV6UC//WewneB3LcXOL9NP++ozKVXsIIIpm/2c13UDiD9Jp2eThsecw9m3jPqDwTyobcdbg==",
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz",
"integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==",
"dev": true,
"requires": {
"is-callable": "^1.1.4",
@ -1722,6 +1770,15 @@
"flat-cache": "^2.0.1"
}
},
"fill-range": {
"version": "7.0.1",
"resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
"integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==",
"dev": true,
"requires": {
"to-regex-range": "^5.0.1"
}
},
"find-up": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz",
@ -1790,6 +1847,13 @@
"integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=",
"dev": true
},
"fsevents": {
"version": "2.1.3",
"resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.3.tgz",
"integrity": "sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ==",
"dev": true,
"optional": true
},
"function-bind": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
@ -2204,16 +2268,25 @@
"integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=",
"dev": true
},
"is-binary-path": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz",
"integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==",
"dev": true,
"requires": {
"binary-extensions": "^2.0.0"
}
},
"is-buffer": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.3.tgz",
"integrity": "sha512-U15Q7MXTuZlrbymiz95PJpZxu8IlipAp4dtS3wOdgPXx3mqBnslrWU14kxfHB+Py/+2PVKSr37dMAgM2A4uArw==",
"version": "2.0.4",
"resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.4.tgz",
"integrity": "sha512-Kq1rokWXOPXWuaMAqZiJW4XxsmD9zGx9q4aePabbn3qCRGedtH7Cm+zV8WETitMfu1wdh+Rvd6w5egwSngUX2A==",
"dev": true
},
"is-callable": {
"version": "1.1.4",
"resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.4.tgz",
"integrity": "sha512-r5p9sxJjYnArLjObpjA4xu5EKI3CuKHkJXMhT7kwbpUyIFD1n5PMAsoPvWnvtZiNz7LjkYDRZhd7FlI0eMijEA==",
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.1.tgz",
"integrity": "sha512-wliAfSzx6V+6WfMOmus1xy0XvSgf/dlStkvTfq7F0g4bOIW0PSUbnyse3NhDwdyYS1ozfUtAAySqTws3z9Eqgg==",
"dev": true
},
"is-date-object": {
@ -2249,6 +2322,12 @@
"integrity": "sha1-Mlj7afeMFNW4FdZkM2tM/7ZEFZE=",
"dev": true
},
"is-number": {
"version": "7.0.0",
"resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
"integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
"dev": true
},
"is-reference": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/is-reference/-/is-reference-1.2.1.tgz",
@ -2259,12 +2338,20 @@
}
},
"is-regex": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.4.tgz",
"integrity": "sha1-VRdIm1RwkbCTDglWVM7SXul+lJE=",
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.1.tgz",
"integrity": "sha512-1+QkEcxiLlB7VEyFtyBg94e08OAsvq7FUBgApTq/w2ymCLyKJgDPsybBENVtA7XCQEgEXxKPonG+mvYRxh/LIg==",
"dev": true,
"requires": {
"has": "^1.0.1"
"has-symbols": "^1.0.1"
},
"dependencies": {
"has-symbols": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.1.tgz",
"integrity": "sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==",
"dev": true
}
}
},
"is-stream": {
@ -2539,12 +2626,12 @@
"dev": true
},
"log-symbols": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-2.2.0.tgz",
"integrity": "sha512-VeIAFslyIerEJLXHziedo2basKbMKtTw3vfn5IzG0XTjhAVEJyNHnL2p7vc+wBDSdQuUpNw3M2u6xb9QsAY5Eg==",
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-3.0.0.tgz",
"integrity": "sha512-dSkNGuI7iG3mfvDzUuYZyvk5dD9ocYCYzNU6CYDE6+Xqd+gwme6Z00NS3dUh8mq/73HaEtT7m6W+yUPtU6BZnQ==",
"dev": true,
"requires": {
"chalk": "^2.0.1"
"chalk": "^2.4.2"
}
},
"lru-cache": {
@ -2662,13 +2749,14 @@
}
},
"mocha": {
"version": "6.2.0",
"resolved": "https://registry.npmjs.org/mocha/-/mocha-6.2.0.tgz",
"integrity": "sha512-qwfFgY+7EKAAUAdv7VYMZQknI7YJSGesxHyhn6qD52DV8UcSZs5XwCifcZGMVIE4a5fbmhvbotxC0DLQ0oKohQ==",
"version": "7.2.0",
"resolved": "https://registry.npmjs.org/mocha/-/mocha-7.2.0.tgz",
"integrity": "sha512-O9CIypScywTVpNaRrCAgoUnJgozpIofjKUYmJhiCIJMiuYnLI6otcb1/kpW9/n/tJODHGZ7i8aLQoDVsMtOKQQ==",
"dev": true,
"requires": {
"ansi-colors": "3.2.3",
"browser-stdout": "1.3.1",
"chokidar": "3.3.0",
"debug": "3.2.6",
"diff": "3.5.0",
"escape-string-regexp": "1.0.5",
@ -2677,50 +2765,21 @@
"growl": "1.10.5",
"he": "1.2.0",
"js-yaml": "3.13.1",
"log-symbols": "2.2.0",
"log-symbols": "3.0.0",
"minimatch": "3.0.4",
"mkdirp": "0.5.1",
"mkdirp": "0.5.5",
"ms": "2.1.1",
"node-environment-flags": "1.0.5",
"node-environment-flags": "1.0.6",
"object.assign": "4.1.0",
"strip-json-comments": "2.0.1",
"supports-color": "6.0.0",
"which": "1.3.1",
"wide-align": "1.1.3",
"yargs": "13.2.2",
"yargs-parser": "13.0.0",
"yargs-unparser": "1.5.0"
"yargs": "13.3.2",
"yargs-parser": "13.1.2",
"yargs-unparser": "1.6.0"
},
"dependencies": {
"ansi-regex": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz",
"integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=",
"dev": true
},
"cliui": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/cliui/-/cliui-4.1.0.tgz",
"integrity": "sha512-4FG+RSG9DL7uEwRUZXZn3SS34DiDPfzP0VOiEwtUWlE+AR2EIg+hSyvrIgUUfhdgR/UkAeW2QHgeP+hWrXs7jQ==",
"dev": true,
"requires": {
"string-width": "^2.1.1",
"strip-ansi": "^4.0.0",
"wrap-ansi": "^2.0.0"
},
"dependencies": {
"string-width": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz",
"integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==",
"dev": true,
"requires": {
"is-fullwidth-code-point": "^2.0.0",
"strip-ansi": "^4.0.0"
}
}
}
},
"glob": {
"version": "7.1.3",
"resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz",
@ -2735,36 +2794,12 @@
"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",
"integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==",
"dev": true
},
"strip-ansi": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz",
"integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=",
"dev": true,
"requires": {
"ansi-regex": "^3.0.0"
}
},
"strip-json-comments": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz",
@ -2780,76 +2815,28 @@
"has-flag": "^3.0.0"
}
},
"wrap-ansi": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz",
"integrity": "sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=",
"dev": true,
"requires": {
"string-width": "^1.0.1",
"strip-ansi": "^3.0.1"
},
"dependencies": {
"ansi-regex": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz",
"integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=",
"dev": true
},
"is-fullwidth-code-point": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz",
"integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=",
"dev": true,
"requires": {
"number-is-nan": "^1.0.0"
}
},
"string-width": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz",
"integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=",
"dev": true,
"requires": {
"code-point-at": "^1.0.0",
"is-fullwidth-code-point": "^1.0.0",
"strip-ansi": "^3.0.0"
}
},
"strip-ansi": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
"integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=",
"dev": true,
"requires": {
"ansi-regex": "^2.0.0"
}
}
}
},
"yargs": {
"version": "13.2.2",
"resolved": "https://registry.npmjs.org/yargs/-/yargs-13.2.2.tgz",
"integrity": "sha512-WyEoxgyTD3w5XRpAQNYUB9ycVH/PQrToaTXdYXRdOXvEy1l19br+VJsc0vcO8PTGg5ro/l/GY7F/JMEBmI0BxA==",
"version": "13.3.2",
"resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz",
"integrity": "sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==",
"dev": true,
"requires": {
"cliui": "^4.0.0",
"cliui": "^5.0.0",
"find-up": "^3.0.0",
"get-caller-file": "^2.0.1",
"os-locale": "^3.1.0",
"require-directory": "^2.1.1",
"require-main-filename": "^2.0.0",
"set-blocking": "^2.0.0",
"string-width": "^3.0.0",
"which-module": "^2.0.0",
"y18n": "^4.0.0",
"yargs-parser": "^13.0.0"
"yargs-parser": "^13.1.2"
}
},
"yargs-parser": {
"version": "13.0.0",
"resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.0.0.tgz",
"integrity": "sha512-w2LXjoL8oRdRQN+hOyppuXs+V/fVAYtpcrRxZuF7Kt/Oc+Jr2uAcVntaUTNT6w5ihoWfFDpNY8CPx1QskxZ/pw==",
"version": "13.1.2",
"resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz",
"integrity": "sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==",
"dev": true,
"requires": {
"camelcase": "^5.0.0",
@ -2894,9 +2881,9 @@
"dev": true
},
"node-environment-flags": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/node-environment-flags/-/node-environment-flags-1.0.5.tgz",
"integrity": "sha512-VNYPRfGfmZLx0Ye20jWzHUjyTW/c+6Wq+iLhDzUI4XmhrDd9l/FozXV3F2xOaXjvp0co0+v1YSR3CMP6g+VvLQ==",
"version": "1.0.6",
"resolved": "https://registry.npmjs.org/node-environment-flags/-/node-environment-flags-1.0.6.tgz",
"integrity": "sha512-5Evy2epuL+6TM0lCQGpFIj6KwiEsGh1SrHUhTbNX+sLbBtjidPZFAnVK9y5yU1+h//RitLbRHTIMyxQPtxMdHw==",
"dev": true,
"requires": {
"object.getownpropertydescriptors": "^2.0.3",
@ -2904,17 +2891,17 @@
},
"dependencies": {
"semver": {
"version": "5.7.0",
"resolved": "https://registry.npmjs.org/semver/-/semver-5.7.0.tgz",
"integrity": "sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA==",
"version": "5.7.1",
"resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
"integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==",
"dev": true
}
}
},
"node-fetch": {
"version": "2.6.0",
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.0.tgz",
"integrity": "sha512-8dG4H5ujfvFiqDmVu9fQ5bOHUC15JMjMY/Zumv26oOvvVJjM67KF8koCWIabKQ1GJIa9r2mMZscBq/TbdOcmNA==",
"version": "2.6.1",
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.1.tgz",
"integrity": "sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw==",
"dev": true
},
"node-modules-regexp": {
@ -2935,6 +2922,12 @@
"validate-npm-package-license": "^3.0.1"
}
},
"normalize-path": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
"integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==",
"dev": true
},
"npm-run-path": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz",
@ -2944,12 +2937,6 @@
"path-key": "^2.0.0"
}
},
"number-is-nan": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz",
"integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=",
"dev": true
},
"nwsapi": {
"version": "2.1.4",
"resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.1.4.tgz",
@ -2993,13 +2980,13 @@
}
},
"object.getownpropertydescriptors": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.0.3.tgz",
"integrity": "sha1-h1jIRvW0B62rDyNuCYbxSwUcqhY=",
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.0.tgz",
"integrity": "sha512-Z53Oah9A3TdLoblT7VKJaTDdXdT+lQO+cNpKVnya5JDe9uLvzu1YyY1yFDFrcxrlRgWrEFH0jJtD/IbuwjcEVg==",
"dev": true,
"requires": {
"define-properties": "^1.1.2",
"es-abstract": "^1.5.1"
"define-properties": "^1.1.3",
"es-abstract": "^1.17.0-next.1"
}
},
"object.values": {
@ -3253,6 +3240,12 @@
"is-reference": "^1.1.4"
}
},
"picomatch": {
"version": "2.2.2",
"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.2.tgz",
"integrity": "sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg==",
"dev": true
},
"pify": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz",
@ -3466,6 +3459,15 @@
"util-deprecate": "~1.0.1"
}
},
"readdirp": {
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.2.0.tgz",
"integrity": "sha512-crk4Qu3pmXwgxdSgGhgA/eXiJAPQiX4GMOZZMXnqKxHX7TaoL+3gQVo/WeuAiogr07DpnfjIMpXXa+PAIvwPGQ==",
"dev": true,
"requires": {
"picomatch": "^2.0.4"
}
},
"regexpp": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.1.0.tgz",
@ -4257,6 +4259,15 @@
"os-tmpdir": "~1.0.2"
}
},
"to-regex-range": {
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
"integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
"dev": true,
"requires": {
"is-number": "^7.0.0"
}
},
"tough-cookie": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-3.0.1.tgz",
@ -4616,135 +4627,38 @@
}
},
"yargs-unparser": {
"version": "1.5.0",
"resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-1.5.0.tgz",
"integrity": "sha512-HK25qidFTCVuj/D1VfNiEndpLIeJN78aqgR23nL3y4N0U/91cOAzqfHlF8n2BvoNDcZmJKin3ddNSvOxSr8flw==",
"version": "1.6.0",
"resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-1.6.0.tgz",
"integrity": "sha512-W9tKgmSn0DpSatfri0nx52Joq5hVXgeLiqR/5G0sZNDoLZFOr/xjBUDcShCOGNsBnEMNo1KAMBkTej1Hm62HTw==",
"dev": true,
"requires": {
"flat": "^4.1.0",
"lodash": "^4.17.11",
"yargs": "^12.0.5"
"lodash": "^4.17.15",
"yargs": "^13.3.0"
},
"dependencies": {
"ansi-regex": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz",
"integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=",
"dev": true
},
"cliui": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/cliui/-/cliui-4.1.0.tgz",
"integrity": "sha512-4FG+RSG9DL7uEwRUZXZn3SS34DiDPfzP0VOiEwtUWlE+AR2EIg+hSyvrIgUUfhdgR/UkAeW2QHgeP+hWrXs7jQ==",
"dev": true,
"requires": {
"string-width": "^2.1.1",
"strip-ansi": "^4.0.0",
"wrap-ansi": "^2.0.0"
}
},
"get-caller-file": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.3.tgz",
"integrity": "sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w==",
"dev": true
},
"require-main-filename": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-1.0.1.tgz",
"integrity": "sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE=",
"dev": true
},
"string-width": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz",
"integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==",
"dev": true,
"requires": {
"is-fullwidth-code-point": "^2.0.0",
"strip-ansi": "^4.0.0"
}
},
"strip-ansi": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz",
"integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=",
"dev": true,
"requires": {
"ansi-regex": "^3.0.0"
}
},
"wrap-ansi": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz",
"integrity": "sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=",
"dev": true,
"requires": {
"string-width": "^1.0.1",
"strip-ansi": "^3.0.1"
},
"dependencies": {
"ansi-regex": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz",
"integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=",
"dev": true
},
"is-fullwidth-code-point": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz",
"integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=",
"dev": true,
"requires": {
"number-is-nan": "^1.0.0"
}
},
"string-width": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz",
"integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=",
"dev": true,
"requires": {
"code-point-at": "^1.0.0",
"is-fullwidth-code-point": "^1.0.0",
"strip-ansi": "^3.0.0"
}
},
"strip-ansi": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
"integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=",
"dev": true,
"requires": {
"ansi-regex": "^2.0.0"
}
}
}
},
"yargs": {
"version": "12.0.5",
"resolved": "https://registry.npmjs.org/yargs/-/yargs-12.0.5.tgz",
"integrity": "sha512-Lhz8TLaYnxq/2ObqHDql8dX8CJi97oHxrjUcYtzKbbykPtVW9WB+poxI+NM2UIzsMgNCZTIf0AQwsjK5yMAqZw==",
"version": "13.3.2",
"resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz",
"integrity": "sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==",
"dev": true,
"requires": {
"cliui": "^4.0.0",
"decamelize": "^1.2.0",
"cliui": "^5.0.0",
"find-up": "^3.0.0",
"get-caller-file": "^1.0.1",
"os-locale": "^3.0.0",
"get-caller-file": "^2.0.1",
"require-directory": "^2.1.1",
"require-main-filename": "^1.0.1",
"require-main-filename": "^2.0.0",
"set-blocking": "^2.0.0",
"string-width": "^2.0.0",
"string-width": "^3.0.0",
"which-module": "^2.0.0",
"y18n": "^3.2.1 || ^4.0.0",
"yargs-parser": "^11.1.1"
"y18n": "^4.0.0",
"yargs-parser": "^13.1.2"
}
},
"yargs-parser": {
"version": "11.1.1",
"resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-11.1.1.tgz",
"integrity": "sha512-C6kB/WJDiaxONLJQnF8ccx9SEeoTTLek8RVbaOIsrAUS8VrBEXfmeSnCZxygc+XC2sNMBIwOOnfcxiynjHsVSQ==",
"version": "13.1.2",
"resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz",
"integrity": "sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==",
"dev": true,
"requires": {
"camelcase": "^5.0.0",

@ -1,6 +1,6 @@
{
"name": "svelte",
"version": "3.24.0",
"version": "3.28.0",
"description": "Cybernetically enhanced web apps",
"module": "index.mjs",
"main": "index",
@ -23,10 +23,10 @@
},
"types": "types/runtime/index.d.ts",
"scripts": {
"test": "mocha --opts mocha.opts",
"test": "mocha",
"test:unit": "mocha --require sucrase/register --recursive src/**/__test__.ts",
"quicktest": "mocha --opts mocha.opts",
"precoverage": "c8 mocha --opts mocha.coverage.opts",
"quicktest": "mocha",
"precoverage": "c8 mocha",
"coverage": "c8 report --reporter=text-lcov > coverage.lcov && c8 report --reporter=html",
"codecov": "codecov",
"precodecov": "npm run coverage",
@ -63,12 +63,12 @@
"@rollup/plugin-sucrase": "^3.0.0",
"@rollup/plugin-typescript": "^2.0.1",
"@rollup/plugin-virtual": "^2.0.0",
"@sveltejs/eslint-config": "github:sveltejs/eslint-config#v0.0.1",
"@types/mocha": "^5.2.7",
"@sveltejs/eslint-config": "github:sveltejs/eslint-config#v5.0.0",
"@types/mocha": "^7.0.0",
"@types/node": "^8.10.53",
"@typescript-eslint/eslint-plugin": "^3.0.2",
"@typescript-eslint/parser": "^3.0.2",
"acorn": "^7.3.1",
"acorn": "^7.4.0",
"agadoo": "^1.1.0",
"c8": "^5.0.1",
"code-red": "^0.1.3",
@ -83,7 +83,7 @@
"kleur": "^3.0.3",
"locate-character": "^2.0.5",
"magic-string": "^0.25.3",
"mocha": "^6.2.0",
"mocha": "^7.0.0",
"periscopic": "^2.0.1",
"puppeteer": "^2.1.1",
"rollup": "^1.27.14",

@ -99,12 +99,20 @@ export default [
json(),
ts_plugin
],
output: {
file: 'compiler.js',
format: is_publish ? 'umd' : 'cjs',
name: 'svelte',
sourcemap: true,
},
output: [
{
file: 'compiler.js',
format: is_publish ? 'umd' : 'cjs',
name: 'svelte',
sourcemap: true,
},
{
file: 'compiler.mjs',
format: 'esm',
name: 'svelte',
sourcemap: true,
}
],
external: is_publish
? []
: id => id === 'acorn' || id === 'magic-string' || id.startsWith('css-tree')

@ -9,7 +9,7 @@ sapper:
@echo "\n~> updating template & contributors list"
@npm run update
@echo "\n~> building Sapper app"
@npm run sapper
@npm run build
docker:

@ -47,7 +47,7 @@ In order for the REPL's GitHub integration to work properly when running locally
## Building the site
To build the website, run `npm run sapper`. The output can be found in `__sapper__/build`.
To build the website, run `npm run build`. The output can be found in `__sapper__/build`.
## Testing

@ -5,7 +5,7 @@ author: Rich Harris
authorURL: https://twitter.com/Rich_Harris
---
> Quickstart for the impatient: [the Sapper docs](https://sapper.svelte.technology), and the [starter template](https://github.com/sveltejs/sapper-template)
> Quickstart for the impatient: [the Sapper docs](https://sapper.svelte.dev), and the [starter template](https://github.com/sveltejs/sapper-template)
If you had to list the characteristics of the perfect Node.js web application framework, you'd probably come up with something like this:
@ -47,9 +47,9 @@ What happens if we use the new model as a starting point?
## Introducing Sapper
<aside><p>The <a href="https://sapper.svelte.technology/docs#why-the-name-">name comes from</a> the term for combat engineers, and is also short for Svelte app maker</p></aside>
<aside><p>The <a href="https://sapper.svelte.dev/docs#Why_the_name">name comes from</a> the term for combat engineers, and is also short for Svelte app maker</p></aside>
[Sapper](https://sapper.svelte.technology) is the answer to that question. **Sapper is a Next.js-style framework that aims to meet the eleven criteria at the top of this article while dramatically reducing the amount of code that gets sent to the browser.** It's implemented as Express-compatible middleware, meaning it's easy to understand and customise.
[Sapper](https://sapper.svelte.dev) is the answer to that question. **Sapper is a Next.js-style framework that aims to meet the eleven criteria at the top of this article while dramatically reducing the amount of code that gets sent to the browser.** It's implemented as Express-compatible middleware, meaning it's easy to understand and customise.
The same 'hello world' app that took 204kb with React and Next weighs just 7kb with Sapper. That number is likely to fall further in the future as we explore the space of optimisation possibilities, such as not shipping any JavaScript *at all* for pages that aren't interactive, beyond the tiny Sapper runtime that handles client-side routing.

@ -30,7 +30,9 @@ To treat `*.svelte` files as HTML, open *__Edit → Config...__* and add the fol
## Vim/Neovim
To treat all `*.svelte` files as HTML, add the following line to your `init.vim`:
You can use the [coc-svelte extension](https://github.com/coc-extensions/coc-svelte) which utilises the official language-server.
As an alternative you can treat all `*.svelte` files as HTML. Add the following line to your `init.vim`:
```
au! BufNewFile,BufRead *.svelte set ft=html
@ -50,13 +52,7 @@ To set the filetype for a single file, use a [modeline](https://vim.fandom.com/w
## Visual Studio Code
To treat `*.svelte` files as HTML, add the following lines to your `settings.json` file:
```cson
"files.associations": {
"*.svelte": "html"
}
```
We recommend using the official [Svelte for VS Code extension](https://marketplace.visualstudio.com/items?itemName=svelte.svelte-vscode).
## JetBrains WebStorm

@ -51,7 +51,7 @@ Once installed, you'll have access to three new commands:
## Installing a text editor
To write code, you need a good editor. The most popular choice is [Visual Studio Code](https://code.visualstudio.com/) or VSCode, and justifiably so — it's well-designed and fully-featured, and has a wealth of extensions ([including one for Svelte](https://marketplace.visualstudio.com/items?itemName=JamesBirtles.svelte-vscode), which provides syntax highlighting and diagnostic messages when you're writing components).
To write code, you need a good editor. The most popular choice is [Visual Studio Code](https://code.visualstudio.com/) or VSCode, and justifiably so — it's well-designed and fully-featured, and has a wealth of extensions ([including one for Svelte](https://marketplace.visualstudio.com/items?itemName=svelte.svelte-vscode), which provides syntax highlighting and diagnostic messages when you're writing components).
## Creating a project

@ -107,7 +107,7 @@ Your `include`/`exclude` may differ per project — these are defaults that shou
Any editor [using an LSP](https://langserver.org/#implementations-client) can be supported. The [VS Code](https://marketplace.visualstudio.com/items?itemName=svelte.svelte-vscode) extension has been our primary focus, but there is work in progress [on Atom](https://github.com/sveltejs/language-tools/pull/160), and Vim via [coc-svelte](https://github.com/coc-extensions/coc-svelte) has been updated with the latest LSP.
These editor extensions will improve your coding experience even if you only use JavaScript. The editor won't offer errors, but it will offer inference and refactoring tools. You can [add `// @check-js`](https://www.staging-typescript.org/docs/handbook/intro-to-js-ts.html) to the top of a `<script>` tag using JavaScript to get better error messages with no infra changes.
These editor extensions will improve your coding experience even if you only use JavaScript. The editor won't offer errors, but it will offer inference and refactoring tools. You can [add `// @ts-check`](https://www.staging-typescript.org/docs/handbook/intro-to-js-ts.html) to the top of a `<script>` tag using JavaScript to get better error messages with no infra changes.
To switch a `<script>` to use TypeScript, use `<script lang="ts">` and that should be it. Hopefully you won't be seeing an ocean of red squiggles.
@ -134,7 +134,7 @@ error Command failed with exit code 1.
## What about TypeScript in Sapper projects?
Watch this space!
TypeScript support was added to Sapper in 0.28, so if you're using an older version be sure to [upgrade](https://sapper.svelte.dev/migrating#0_27_to_0_28).
## How can I contribute?

@ -107,7 +107,7 @@ 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.
*`$$props`* references all props that are passed to a component, including ones that are not declared with `export`. It is not generally recommended, as it is difficult for Svelte to optimise. But it can be useful in rare cases for example, when you don't know at compile time what props might be passed to a component.
```sv
<Widget {...$$props}/>
@ -115,7 +115,7 @@ An element or component can have multiple spread attributes, interspersed with r
---
*`$$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.
*`$$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. It shares the same optimisation problems as *`$$props`*, and is likewise not recommended.
```html
<input {...$$restProps}>
@ -342,6 +342,33 @@ If you don't care about the pending state, you can also omit the initial block.
{/await}
```
### {#key ...}
```sv
{#key expression}...{/key}
```
Key blocks destroy and recreate their contents when the value of an expression changes.
---
This is useful if you want an element to play its transition whenever a value changes.
```sv
{#key value}
<div transition:fade>{value}</div>
{/key}
```
---
When used around components, this will cause them to be reinstantiated and reinitialised.
```sv
{#key value}
<Component />
{/key}
```
### {@html ...}
@ -471,6 +498,7 @@ The following modifiers are available:
* `preventDefault` — calls `event.preventDefault()` before running the handler
* `stopPropagation` — calls `event.stopPropagation()`, preventing the event reaching the next element
* `passive` — improves scrolling performance on touch/wheel events (Svelte will add it automatically where it's safe to do so)
* `nonpassive` — explicitly set `passive: false`
* `capture` — fires the handler during the *capture* phase instead of the *bubbling* phase
* `once` — remove the handler after the first time it runs
* `self` — only trigger handler if event.target is the element itself
@ -544,6 +572,21 @@ Numeric input values are coerced; even though `input.value` is a string as far a
<input type="range" bind:value={num}>
```
---
On `<input>` elements with `type="file"`, you can use `bind:files` to get the [`FileList` of selected files](https://developer.mozilla.org/en-US/docs/Web/API/FileList).
```sv
<label for="avatar">Upload a picture:</label>
<input
accept="image/png, image/jpeg"
bind:files
id="avatar"
name="avatar"
type="file"
/>
```
##### Binding `<select>` value

@ -0,0 +1,37 @@
<script>
let files;
$: if (files) {
// Note that `files` is of type `FileList`, not an Array:
// https://developer.mozilla.org/en-US/docs/Web/API/FileList
console.log(files);
for (const file of files) {
console.log(`${file.name}: ${file.size} bytes`);
}
}
</script>
<label for="avatar">Upload a picture:</label>
<input
accept="image/png, image/jpeg"
bind:files
id="avatar"
name="avatar"
type="file"
/>
<label for="many">Upload multiple files of any type:</label>
<input
bind:files
id="many"
multiple
type="file"
/>
{#if files}
<h2>Selected files:</h2>
{#each Array.from(files) as file}
<p>{file.name} ({file.size} bytes) </p>
{/each}
{/if}

@ -2,6 +2,6 @@
question: I'm new to Svelte. Where should I start?
---
We think the best way to get started is playing through the interactive [Tutorial](https://svelte.dev/tutorial). Each step there is mainly focused on one specific aspect and is easy to follow. You'll be editing and running real Svelte components right in your browser.
We think the best way to get started is playing through the interactive [Tutorial](tutorial). Each step there is mainly focused on one specific aspect and is easy to follow. You'll be editing and running real Svelte components right in your browser.
Five to ten minutes should be enough to get you up and running. An hour and a half should get you through the entire tutorial.

@ -2,9 +2,13 @@
question: Are there any video courses?
---
There are no official ones, but here are a couple of third-part ones that we know of.
Rich Harris, the creator of Svelte, taught a course:
- [Egghead](https://egghead.io/playlists/getting-started-with-svelte-3-05a8541a)
- [Udemy](https://www.udemy.com/sveltejs-the-complete-guide/)
- [Frontend Masters](https://frontendmasters.com/courses/svelte/)
There are also a number of third-party courses:
- [Egghead](https://egghead.io/browse/frameworks/svelte)
- [Udemy](https://www.udemy.com/courses/search/?q=sveltejs+svelte)
Note that Udemy very frequently has discounts over 90%.

@ -0,0 +1,9 @@
---
question: Are there any books?
---
There are a few books:
- [Svelte Handbook](https://flaviocopes.com/page/download-svelte-handbook/) by Flavio Copes
- [Svelte 3 Up and Running](https://www.amazon.com/dp/B08D6T6BKS/) by Alessandro Segala
- [Svelte and Sapper in Action](https://www.manning.com/books/svelte-and-sapper-in-action) by R. Mark Volkmann

@ -10,3 +10,11 @@ To declare the type of a reactive variable in a Svelte template, you should use
let x: number;
$: x = count + 1;
```
To import a type or interface make sure to use [TypeScript's `type` modifier](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-8.html#type-only-imports-and-export):
```
import type { SomeInterface } from './SomeFile';
```
You must use the `type` modifier because `svelte-preprocess` doesn't know whether an import is a type or a value — it only transpiles one file at a time without knowledge of the other files and therefore can't safely erase imports which only contain types without this modifier present.

@ -13,7 +13,7 @@ First, you'll need to integrate Svelte with a build tool. There are officially m
Don't worry if you're relatively new to web development and haven't used these tools before. We've prepared a simple step-by-step guide, [Svelte for new developers](blog/svelte-for-new-developers), which walks you through the process.
You'll also want to configure your text editor to treat `.svelte` files the same as `.html` for the sake of syntax highlighting. [Read this guide to learn how](blog/setting-up-your-editor).
You'll also want to configure your text editor. If you're using VS Code, install the [Svelte extension](https://marketplace.visualstudio.com/items?itemName=svelte.svelte-vscode), otherwise follow [this guide](blog/setting-up-your-editor) to configure your text editor to treat `.svelte` files the same as `.html` for the sake of syntax highlighting.
Then, once you've got your project set up, using Svelte components is easy. The compiler turns each component into a regular JavaScript class — just import it and instantiate with `new`:

@ -2,10 +2,10 @@
title: Spread props
---
If you have an object of properties, you can 'spread' them on to a component instead of specifying each one:
If you have an object of properties, you can 'spread' them onto a component instead of specifying each one:
```html
<Info {...pkg}/>
```
> Conversely, if you need to reference all the props that were passed into a component, including ones that weren't declared with `export`, you can do so by accessing `$$props` directly. It's not generally recommended, as it's difficult for Svelte to optimise, but it's useful in rare cases.
> Conversely, if you need to reference all the props that were passed into a component, including ones that weren't declared with `export`, you can do so by accessing `$$props` directly. It's not generally recommended, as it's difficult for Svelte to optimise, but it's useful in rare cases.

@ -21,6 +21,7 @@ The full list of modifiers:
* `preventDefault` — calls `event.preventDefault()` before running the handler. Useful for client-side form handling, for example.
* `stopPropagation` — calls `event.stopPropagation()`, preventing the event reaching the next element
* `passive` — improves scrolling performance on touch/wheel events (Svelte will add it automatically where it's safe to do so)
* `nonpassive` — explicitly set `passive: false`
* `capture` — fires the handler during the *capture* phase instead of the *bubbling* phase ([MDN docs](https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Building_blocks/Events#Event_bubbling_and_capture))
* `once` — remove the handler after the first time it runs
* `self` — only trigger handler if event.target is the element itself

@ -7,23 +7,23 @@
display: block;
}
.active {
.selected {
background-color: #ff3e00;
color: white;
}
</style>
<button
class="{current === 'foo' ? 'active' : ''}"
class="{current === 'foo' ? 'selected' : ''}"
on:click="{() => current = 'foo'}"
>foo</button>
<button
class="{current === 'bar' ? 'active' : ''}"
class="{current === 'bar' ? 'selected' : ''}"
on:click="{() => current = 'bar'}"
>bar</button>
<button
class="{current === 'baz' ? 'active' : ''}"
class="{current === 'baz' ? 'selected' : ''}"
on:click="{() => current = 'baz'}"
>baz</button>

@ -7,23 +7,23 @@
display: block;
}
.active {
.selected {
background-color: #ff3e00;
color: white;
}
</style>
<button
class:active="{current === 'foo'}"
class:selected="{current === 'foo'}"
on:click="{() => current = 'foo'}"
>foo</button>
<button
class:active="{current === 'bar'}"
class:selected="{current === 'bar'}"
on:click="{() => current = 'bar'}"
>bar</button>
<button
class:active="{current === 'baz'}"
class:selected="{current === 'baz'}"
on:click="{() => current = 'baz'}"
>baz</button>

@ -6,7 +6,7 @@ Like any other attribute, you can specify classes with a JavaScript attribute, s
```html
<button
class="{current === 'foo' ? 'active' : ''}"
class="{current === 'foo' ? 'selected' : ''}"
on:click="{() => current = 'foo'}"
>foo</button>
```
@ -15,9 +15,9 @@ This is such a common pattern in UI development that Svelte includes a special d
```html
<button
class:active="{current === 'foo'}"
class:selected="{current === 'foo'}"
on:click="{() => current = 'foo'}"
>foo</button>
```
The `active` class is added to the element whenever the value of the expression is truthy, and removed when it's falsy.
The `selected` class is added to the element whenever the value of the expression is truthy, and removed when it's falsy.

@ -14,7 +14,7 @@ It's useful for things like this folder tree view, where folders can contain *ot
{/if}
```
...but that's impossible, because a file can't import itself. Instead, we use `<svelte:self>`:
...but that's impossible, because a module can't import itself. Instead, we use `<svelte:self>`:
```html
{#if file.type === 'folder'}
@ -22,4 +22,4 @@ It's useful for things like this folder tree view, where folders can contain *ot
{:else}
<File {...file}/>
{/if}
```
```

@ -315,6 +315,12 @@
"@babel/types": "^7.4.4"
}
},
"@babel/helper-validator-identifier": {
"version": "7.10.4",
"resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.10.4.tgz",
"integrity": "sha512-3U9y+43hz7ZM+rzG24Qe2mufW5KhvFg/NhnNph+i9mgCtdTCtMJuI1TMkrIUiK7Ix4PYlRF9I5dhqaLYA/ADXw==",
"dev": true
},
"@babel/helper-wrap-function": {
"version": "7.2.0",
"resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.2.0.tgz",
@ -1270,6 +1276,168 @@
"resolved": "https://registry.npmjs.org/@polka/url/-/url-1.0.0-next.9.tgz",
"integrity": "sha512-VZqSaulg2kVQYMulmuZcvapPwH5/y81YHANiFIKz1GNZoG/F4o1JSeLlrvXJ8tC+RPUjxdrebfT3Qn+bnMi0bA=="
},
"@rollup/plugin-babel": {
"version": "5.2.0",
"resolved": "https://registry.npmjs.org/@rollup/plugin-babel/-/plugin-babel-5.2.0.tgz",
"integrity": "sha512-CPABsajaKjINgBQ3it+yMnfVO3ibsrMBxRzbUOUw2cL1hsZJ7aogU8mgglQm3S2hHJgjnAmxPz0Rq7DVdmHsTw==",
"dev": true,
"requires": {
"@babel/helper-module-imports": "^7.10.4",
"@rollup/pluginutils": "^3.1.0"
},
"dependencies": {
"@babel/helper-module-imports": {
"version": "7.10.4",
"resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.10.4.tgz",
"integrity": "sha512-nEQJHqYavI217oD9+s5MUBzk6x1IlvoS9WTPfgG43CbMEeStE0v+r+TucWdx8KFGowPGvyOkDT9+7DHedIDnVw==",
"dev": true,
"requires": {
"@babel/types": "^7.10.4"
}
},
"@babel/types": {
"version": "7.11.5",
"resolved": "https://registry.npmjs.org/@babel/types/-/types-7.11.5.tgz",
"integrity": "sha512-bvM7Qz6eKnJVFIn+1LPtjlBFPVN5jNDc1XmN15vWe7Q3DPBufWWsLiIvUu7xW87uTG6QoggpIDnUgLQvPheU+Q==",
"dev": true,
"requires": {
"@babel/helper-validator-identifier": "^7.10.4",
"lodash": "^4.17.19",
"to-fast-properties": "^2.0.0"
}
}
}
},
"@rollup/plugin-commonjs": {
"version": "15.0.0",
"resolved": "https://registry.npmjs.org/@rollup/plugin-commonjs/-/plugin-commonjs-15.0.0.tgz",
"integrity": "sha512-8uAdikHqVyrT32w1zB9VhW6uGwGjhKgnDNP4pQJsjdnyF4FgCj6/bmv24c7v2CuKhq32CcyCwRzMPEElaKkn0w==",
"dev": true,
"requires": {
"@rollup/pluginutils": "^3.1.0",
"commondir": "^1.0.1",
"estree-walker": "^2.0.1",
"glob": "^7.1.6",
"is-reference": "^1.2.1",
"magic-string": "^0.25.7",
"resolve": "^1.17.0"
},
"dependencies": {
"estree-walker": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.1.tgz",
"integrity": "sha512-tF0hv+Yi2Ot1cwj9eYHtxC0jB9bmjacjQs6ZBTj82H8JwUywFuc+7E83NWfNMwHXZc11mjfFcVXPe9gEP4B8dg==",
"dev": true
},
"glob": {
"version": "7.1.6",
"resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz",
"integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==",
"dev": true,
"requires": {
"fs.realpath": "^1.0.0",
"inflight": "^1.0.4",
"inherits": "2",
"minimatch": "^3.0.4",
"once": "^1.3.0",
"path-is-absolute": "^1.0.0"
}
},
"is-reference": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/is-reference/-/is-reference-1.2.1.tgz",
"integrity": "sha512-U82MsXXiFIrjCK4otLT+o2NA2Cd2g5MLoOVXUZjIOhLurrRxpEXzI8O0KZHr3IjLvlAH1kTPYSuqer5T9ZVBKQ==",
"dev": true,
"requires": {
"@types/estree": "*"
}
},
"magic-string": {
"version": "0.25.7",
"resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.25.7.tgz",
"integrity": "sha512-4CrMT5DOHTDk4HYDlzmwu4FVCcIYI8gauveasrdCu2IKIFOJ3f0v/8MDGJCDL9oD2ppz/Av1b0Nj345H9M+XIA==",
"dev": true,
"requires": {
"sourcemap-codec": "^1.4.4"
}
},
"resolve": {
"version": "1.17.0",
"resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz",
"integrity": "sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==",
"dev": true,
"requires": {
"path-parse": "^1.0.6"
}
}
}
},
"@rollup/plugin-json": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/@rollup/plugin-json/-/plugin-json-4.1.0.tgz",
"integrity": "sha512-yfLbTdNS6amI/2OpmbiBoW12vngr5NW2jCJVZSBEz+H5KfUJZ2M7sDjk0U6GOOdCWFVScShte29o9NezJ53TPw==",
"dev": true,
"requires": {
"@rollup/pluginutils": "^3.0.8"
}
},
"@rollup/plugin-node-resolve": {
"version": "9.0.0",
"resolved": "https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-9.0.0.tgz",
"integrity": "sha512-gPz+utFHLRrd41WMP13Jq5mqqzHL3OXrfj3/MkSyB6UBIcuNt9j60GCbarzMzdf1VHFpOxfQh/ez7wyadLMqkg==",
"dev": true,
"requires": {
"@rollup/pluginutils": "^3.1.0",
"@types/resolve": "1.17.1",
"builtin-modules": "^3.1.0",
"deepmerge": "^4.2.2",
"is-module": "^1.0.0",
"resolve": "^1.17.0"
},
"dependencies": {
"resolve": {
"version": "1.17.0",
"resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz",
"integrity": "sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==",
"dev": true,
"requires": {
"path-parse": "^1.0.6"
}
}
}
},
"@rollup/plugin-replace": {
"version": "2.3.3",
"resolved": "https://registry.npmjs.org/@rollup/plugin-replace/-/plugin-replace-2.3.3.tgz",
"integrity": "sha512-XPmVXZ7IlaoWaJLkSCDaa0Y6uVo5XQYHhiMFzOd5qSv5rE+t/UJToPIOE56flKIxBFQI27ONsxb7dqHnwSsjKQ==",
"dev": true,
"requires": {
"@rollup/pluginutils": "^3.0.8",
"magic-string": "^0.25.5"
},
"dependencies": {
"magic-string": {
"version": "0.25.7",
"resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.25.7.tgz",
"integrity": "sha512-4CrMT5DOHTDk4HYDlzmwu4FVCcIYI8gauveasrdCu2IKIFOJ3f0v/8MDGJCDL9oD2ppz/Av1b0Nj345H9M+XIA==",
"dev": true,
"requires": {
"sourcemap-codec": "^1.4.4"
}
}
}
},
"@rollup/pluginutils": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-3.1.0.tgz",
"integrity": "sha512-GksZ6pr6TpIjHm8h9lSQ8pi8BE9VeubNT0OMJ3B5uZJ8pz73NPiqOtCog/x2/QzM1ENChPKxMDhiQuRHsqc+lg==",
"dev": true,
"requires": {
"@types/estree": "0.0.39",
"estree-walker": "^1.0.1",
"picomatch": "^2.2.2"
}
},
"@sindresorhus/slugify": {
"version": "0.9.1",
"resolved": "https://registry.npmjs.org/@sindresorhus/slugify/-/slugify-0.9.1.tgz",
@ -1281,9 +1449,9 @@
}
},
"@sveltejs/site-kit": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/@sveltejs/site-kit/-/site-kit-1.2.1.tgz",
"integrity": "sha512-5AhOCBcproHF5UbmuOIB9CiyAmG6BXOr2G4EjeeDz/tyo9myfnRKIgJSy26q8Zlw6TOlwxhzcAgvL5sgZF+IsA==",
"version": "1.2.5",
"resolved": "https://registry.npmjs.org/@sveltejs/site-kit/-/site-kit-1.2.5.tgz",
"integrity": "sha512-fA1YWW4tYOxPRVocx+jF4S2LGamku8xeKx/+J5aY7ZCbwuo/c4VF+T0K7WuQRI8U6Dw3pJqdiCra+xH4TnCGRw==",
"dev": true,
"requires": {
"@sindresorhus/slugify": "^0.9.1",
@ -1291,9 +1459,9 @@
}
},
"@sveltejs/svelte-repl": {
"version": "0.2.0",
"resolved": "https://registry.npmjs.org/@sveltejs/svelte-repl/-/svelte-repl-0.2.0.tgz",
"integrity": "sha512-2vLQnOVrsmn2d2K4a6urGm8OulGGSPhZCGNySSb1H8nOPsgKrdcTt5qoaxNYXgcyVp55Yow2SvXYXsyJKd4KEQ==",
"version": "0.2.1",
"resolved": "https://registry.npmjs.org/@sveltejs/svelte-repl/-/svelte-repl-0.2.1.tgz",
"integrity": "sha512-ShNjMdsEAzGLu2PoogJEuWcV47E+1CsO8dNJ2wZcs7xyPsvuswp6KV1jFsBQmWZ+jLqtnRhlo6w2Mf43XOS/Dg==",
"dev": true,
"requires": {
"codemirror": "^5.49.2",
@ -1356,20 +1524,14 @@
}
},
"@types/resolve": {
"version": "0.0.8",
"resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-0.0.8.tgz",
"integrity": "sha512-auApPaJf3NPfe18hSoJkp8EbZzer2ISk7o8mCC3M9he/a04+gbMF97NkpD2S8riMGvm4BMRI59/SZQSaLTKpsQ==",
"version": "1.17.1",
"resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-1.17.1.tgz",
"integrity": "sha512-yy7HuzQhj0dhGpD8RLXSZWEkLsV9ibvxvi6EiJ3bkqLAO1RGo0WbkWQiwpRlSFymTJRz0d3k5LM3kkx8ArDbLw==",
"dev": true,
"requires": {
"@types/node": "*"
}
},
"acorn": {
"version": "7.1.1",
"resolved": "https://registry.npmjs.org/acorn/-/acorn-7.1.1.tgz",
"integrity": "sha512-add7dgA5ppRPxCFJoAGfMDi7PIBXq1RtGo7BhbLaxwrXPOmw8gq48Y9ozT01hUKy9byMjlR20EJhu5zlkErEkg==",
"dev": true
},
"ansi-colors": {
"version": "3.2.3",
"resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-3.2.3.tgz",
@ -1556,9 +1718,9 @@
"dev": true
},
"clean-css": {
"version": "4.2.1",
"resolved": "https://registry.npmjs.org/clean-css/-/clean-css-4.2.1.tgz",
"integrity": "sha512-4ZxI6dy4lrY6FHzfiy1aEOXgu4LIsW2MhwG0VBKdcoGoH/XLFgaHSdLTGr4O8Be6A8r3MOphEiI8Gc1n0ecf3g==",
"version": "4.2.3",
"resolved": "https://registry.npmjs.org/clean-css/-/clean-css-4.2.3.tgz",
"integrity": "sha512-VcMWDN54ZN/DS+g58HYL5/n4Zrqe8vHJpGA8KdgUXFU4fuP/aHNw8eld9SyEIyabIMJX/0RaY/fplOo5hYLSFA==",
"dev": true,
"requires": {
"source-map": "~0.6.0"
@ -1573,9 +1735,9 @@
}
},
"clipboard": {
"version": "2.0.4",
"resolved": "https://registry.npmjs.org/clipboard/-/clipboard-2.0.4.tgz",
"integrity": "sha512-Vw26VSLRpJfBofiVaFb/I8PVfdI1OxKcYShe6fm0sP/DtmiWQNCjhM/okTvdCo0G+lMMm1rMYbk4IK4x1X+kgQ==",
"version": "2.0.6",
"resolved": "https://registry.npmjs.org/clipboard/-/clipboard-2.0.6.tgz",
"integrity": "sha512-g5zbiixBRk/wyKakSwCKd7vQXDjFnAMGHoEyBogG/bw9kTD9GvdAvaoRR1ALcEzt3pVKxZR0pViekPMIS0QyGg==",
"optional": true,
"requires": {
"good-listener": "^1.2.2",
@ -1601,9 +1763,9 @@
"dev": true
},
"codemirror": {
"version": "5.55.0",
"resolved": "https://registry.npmjs.org/codemirror/-/codemirror-5.55.0.tgz",
"integrity": "sha512-TumikSANlwiGkdF/Blnu/rqovZ0Y3Jh8yy9TqrPbSM0xxSucq3RgnpVDQ+mD9q6JERJEIT2FMuF/fBGfkhIR/g==",
"version": "5.57.0",
"resolved": "https://registry.npmjs.org/codemirror/-/codemirror-5.57.0.tgz",
"integrity": "sha512-WGc6UL7Hqt+8a6ZAsj/f1ApQl3NPvHY/UQSzG6fB6l4BjExgVdhFaxd7mRTw1UCiYe/6q86zHP+kfvBQcZGvUg==",
"dev": true
},
"color-convert": {
@ -1622,9 +1784,15 @@
"dev": true
},
"commander": {
"version": "2.20.0",
"resolved": "https://registry.npmjs.org/commander/-/commander-2.20.0.tgz",
"integrity": "sha512-7j2y+40w61zy6YC2iRNpUe/NwhNyoXrYpHMrSunaMG64nRnaf96zO/KMQR4OyN/UnE5KLyEBnKHd4aG3rskjpQ==",
"version": "2.20.3",
"resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz",
"integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==",
"dev": true
},
"commondir": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz",
"integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=",
"dev": true
},
"concat-map": {
@ -1693,12 +1861,6 @@
}
}
},
"core-util-is": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz",
"integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=",
"dev": true
},
"cross-spawn": {
"version": "6.0.5",
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz",
@ -1727,6 +1889,12 @@
"integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=",
"dev": true
},
"deepmerge": {
"version": "4.2.2",
"resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.2.2.tgz",
"integrity": "sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==",
"dev": true
},
"define-properties": {
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz",
@ -1865,9 +2033,9 @@
"dev": true
},
"estree-walker": {
"version": "0.6.1",
"resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-0.6.1.tgz",
"integrity": "sha512-SqmZANLWS0mnatqbSfRP5g8OXZC12Fgg1IwNtLsyHDzJizORW4khDfjPqJZsemPWBB2uqykUah5YpQ6epsqC/w==",
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-1.0.1.tgz",
"integrity": "sha512-1fMXF3YP4pZZVozF8j/ZLfvnR8NSIljt56UhbZ5PeeDmmGHpgpdwQt7ITlGvYaQukCvuBRMLEiKiYC+oeIg4cg==",
"dev": true
},
"esutils": {
@ -1950,6 +2118,13 @@
"integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=",
"dev": true
},
"fsevents": {
"version": "2.1.3",
"resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.3.tgz",
"integrity": "sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ==",
"dev": true,
"optional": true
},
"function-bind": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
@ -2178,15 +2353,6 @@
"integrity": "sha1-Mlj7afeMFNW4FdZkM2tM/7ZEFZE=",
"dev": true
},
"is-reference": {
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/is-reference/-/is-reference-1.1.3.tgz",
"integrity": "sha512-W1iHHv/oyBb2pPxkBxtaewxa1BC58Pn5J0hogyCdefwUIvb6R+TGbAcIa4qPNYLqLhb3EnOgUf2MQkkF76BcKw==",
"dev": true,
"requires": {
"@types/estree": "0.0.39"
}
},
"is-regex": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.4.tgz",
@ -2211,12 +2377,6 @@
"has-symbols": "^1.0.0"
}
},
"isarray": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
"integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=",
"dev": true
},
"isexe": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
@ -2224,22 +2384,29 @@
"dev": true
},
"jest-worker": {
"version": "24.6.0",
"resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-24.6.0.tgz",
"integrity": "sha512-jDwgW5W9qGNvpI1tNnvajh0a5IE/PuGLFmHk6aR/BZFz8tSgGw17GsDPXAJ6p91IvYDjOw8GpFbvvZGAK+DPQQ==",
"version": "26.3.0",
"resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-26.3.0.tgz",
"integrity": "sha512-Vmpn2F6IASefL+DVBhPzI2J9/GJUsqzomdeN+P+dK8/jKxbh8R3BtFnx3FIta7wYlPU62cpJMJQo4kuOowcMnw==",
"dev": true,
"requires": {
"merge-stream": "^1.0.1",
"supports-color": "^6.1.0"
"@types/node": "*",
"merge-stream": "^2.0.0",
"supports-color": "^7.0.0"
},
"dependencies": {
"has-flag": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
"integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
"dev": true
},
"supports-color": {
"version": "6.1.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz",
"integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==",
"version": "7.2.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
"integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
"dev": true,
"requires": {
"has-flag": "^3.0.0"
"has-flag": "^4.0.0"
}
}
}
@ -2474,15 +2641,6 @@
"integrity": "sha1-miyr0bno4K6ZOkv31YdcOcQujqw=",
"dev": true
},
"magic-string": {
"version": "0.25.2",
"resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.25.2.tgz",
"integrity": "sha512-iLs9mPjh9IuTtRsqqhNGYcZXGei0Nh/A4xirrsqW7c+QhKVFL2vm7U09ru6cHRD22azaP/wMDgI+HCqbETMTtg==",
"dev": true,
"requires": {
"sourcemap-codec": "^1.4.4"
}
},
"map-age-cleaner": {
"version": "0.1.3",
"resolved": "https://registry.npmjs.org/map-age-cleaner/-/map-age-cleaner-0.1.3.tgz",
@ -2493,9 +2651,9 @@
}
},
"marked": {
"version": "0.7.0",
"resolved": "https://registry.npmjs.org/marked/-/marked-0.7.0.tgz",
"integrity": "sha512-c+yYdCZJQrsRjTPhUx7VKkApw9bwDkNbHUKo1ovgcfDjb2kc8rLuRbIFyXL5WOEUwzSSKo3IXpph2K6DqB/KZg=="
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/marked/-/marked-1.1.1.tgz",
"integrity": "sha512-mJzT8D2yPxoPh7h0UXkB+dBj4FykPJ2OIfxAWeIHrvoHDkFxukV/29QxoFQoPM6RLEwhIFdJpmKBlqVM3s2ZIw=="
},
"mem": {
"version": "4.3.0",
@ -2515,18 +2673,15 @@
"dev": true
},
"merge-stream": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-1.0.1.tgz",
"integrity": "sha1-QEEgLVCKNCugAXQAjfDCUbjBNeE=",
"dev": true,
"requires": {
"readable-stream": "^2.0.1"
}
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz",
"integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==",
"dev": true
},
"mime": {
"version": "2.4.4",
"resolved": "https://registry.npmjs.org/mime/-/mime-2.4.4.tgz",
"integrity": "sha512-LRxmNwziLPT828z+4YkNzloCFC2YM4wrB99k+AV5ZbEyfGNWfG8SO1FUXLmLDBSo89NrJZ4DIWeLjy1CHGhMGA=="
"version": "2.4.6",
"resolved": "https://registry.npmjs.org/mime/-/mime-2.4.6.tgz",
"integrity": "sha512-RZKhC3EmpBchfTGBVb8fb+RL2cWyw/32lshnsETttkBAyAUXSGHxbEJWWRXc751DrIxG1q04b8QwMbAwkRPpUA=="
},
"mimic-fn": {
"version": "2.1.0",
@ -2702,9 +2857,9 @@
}
},
"node-fetch": {
"version": "2.6.0",
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.0.tgz",
"integrity": "sha512-8dG4H5ujfvFiqDmVu9fQ5bOHUC15JMjMY/Zumv26oOvvVJjM67KF8koCWIabKQ1GJIa9r2mMZscBq/TbdOcmNA==",
"version": "2.6.1",
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.1.tgz",
"integrity": "sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw==",
"dev": true
},
"node-pg-migrate": {
@ -3105,6 +3260,12 @@
"integrity": "sha512-CzFr90qM24ju5f88quFC/6qohjC144rehe5n6DH900lgXmUe86+xCKc10ev56gRKC4/BkHUoG4uSiQgBiIXwDA==",
"dev": true
},
"picomatch": {
"version": "2.2.2",
"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.2.tgz",
"integrity": "sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg==",
"dev": true
},
"pidtree": {
"version": "0.3.0",
"resolved": "https://registry.npmjs.org/pidtree/-/pidtree-0.3.0.tgz",
@ -3170,9 +3331,9 @@
"integrity": "sha512-plS7uY0WWiTBwWZs9KM3M88ZxHWKbrbMUDf52CPum6BqAxiLmKROmaTnmhXtv0krQ0l0HRLcFS8JDwOFyPt/OQ=="
},
"prismjs": {
"version": "1.17.1",
"resolved": "https://registry.npmjs.org/prismjs/-/prismjs-1.17.1.tgz",
"integrity": "sha512-PrEDJAFdUGbOP6xK/UsfkC5ghJsPJviKgnQOoxaDbBjwc8op68Quupwt1DeAFoG8GImPhiKXAvvsH7wDSLsu1Q==",
"version": "1.21.0",
"resolved": "https://registry.npmjs.org/prismjs/-/prismjs-1.21.0.tgz",
"integrity": "sha512-uGdSIu1nk3kej2iZsLyDoJ7e9bnPzIgY0naW/HdknGj61zScaprVEVGHrPoXqI+M9sP0NDnTK2jpkvmldpuqDw==",
"requires": {
"clipboard": "^2.0.0"
}
@ -3189,12 +3350,6 @@
"integrity": "sha1-FjjYqONML0QKkduVq5rrZ3/Bhc8=",
"dev": true
},
"process-nextick-args": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz",
"integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==",
"dev": true
},
"pump": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz",
@ -3205,6 +3360,15 @@
"once": "^1.3.1"
}
},
"randombytes": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz",
"integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==",
"dev": true,
"requires": {
"safe-buffer": "^5.1.0"
}
},
"read-pkg": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz",
@ -3216,21 +3380,6 @@
"path-type": "^3.0.0"
}
},
"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==",
"dev": true,
"requires": {
"core-util-is": "~1.0.0",
"inherits": "~2.0.3",
"isarray": "~1.0.0",
"process-nextick-args": "~2.0.0",
"safe-buffer": "~5.1.1",
"string_decoder": "~1.1.1",
"util-deprecate": "~1.0.1"
}
},
"rechoir": {
"version": "0.6.2",
"resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz",
@ -3361,121 +3510,74 @@
}
},
"rollup": {
"version": "1.21.2",
"resolved": "https://registry.npmjs.org/rollup/-/rollup-1.21.2.tgz",
"integrity": "sha512-sCAHlcQ/PExU5t/kRwkEWHdhGmQrZ2IgdQzbjPVNfhWbKHMMZGYqkASVTpQqRPLtQKg15xzEscc+BnIK/TE7/Q==",
"dev": true,
"requires": {
"@types/estree": "0.0.39",
"@types/node": "^12.7.4",
"acorn": "^7.0.0"
},
"dependencies": {
"@types/node": {
"version": "12.7.4",
"resolved": "https://registry.npmjs.org/@types/node/-/node-12.7.4.tgz",
"integrity": "sha512-W0+n1Y+gK/8G2P/piTkBBN38Qc5Q1ZSO6B5H3QmPCUewaiXOo2GCAWZ4ElZCcNhjJuBSUSLGFUJnmlCn5+nxOQ==",
"dev": true
}
}
},
"rollup-plugin-babel": {
"version": "4.3.3",
"resolved": "https://registry.npmjs.org/rollup-plugin-babel/-/rollup-plugin-babel-4.3.3.tgz",
"integrity": "sha512-tKzWOCmIJD/6aKNz0H1GMM+lW1q9KyFubbWzGiOG540zxPPifnEAHTZwjo0g991Y+DyOZcLqBgqOdqazYE5fkw==",
"dev": true,
"requires": {
"@babel/helper-module-imports": "^7.0.0",
"rollup-pluginutils": "^2.8.1"
}
},
"rollup-plugin-commonjs": {
"version": "10.1.0",
"resolved": "https://registry.npmjs.org/rollup-plugin-commonjs/-/rollup-plugin-commonjs-10.1.0.tgz",
"integrity": "sha512-jlXbjZSQg8EIeAAvepNwhJj++qJWNJw1Cl0YnOqKtP5Djx+fFGkp3WRh+W0ASCaFG5w1jhmzDxgu3SJuVxPF4Q==",
"version": "2.26.10",
"resolved": "https://registry.npmjs.org/rollup/-/rollup-2.26.10.tgz",
"integrity": "sha512-dUnjCWOA0h9qNX6qtcHidyatz8FAFZxVxt1dbcGtKdlJkpSxGK3G9+DLCYvtZr9v94D129ij9zUhG+xbRoqepw==",
"dev": true,
"requires": {
"estree-walker": "^0.6.1",
"is-reference": "^1.1.2",
"magic-string": "^0.25.2",
"resolve": "^1.11.0",
"rollup-pluginutils": "^2.8.1"
"fsevents": "~2.1.2"
}
},
"rollup-plugin-json": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/rollup-plugin-json/-/rollup-plugin-json-4.0.0.tgz",
"integrity": "sha512-hgb8N7Cgfw5SZAkb3jf0QXii6QX/FOkiIq2M7BAQIEydjHvTyxXHQiIzZaTFgx1GK0cRCHOCBHIyEkkLdWKxow==",
"rollup-plugin-svelte": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/rollup-plugin-svelte/-/rollup-plugin-svelte-6.0.0.tgz",
"integrity": "sha512-y9qtWa+iNYwXdOZqaEqz3i6k3gzofC9JXzv+WVKDOt0DLiJxJaSrlKKf4YkKG91RzTK5Lo+0fW8in9QH/DxEhA==",
"dev": true,
"requires": {
"rollup-pluginutils": "^2.5.0"
"require-relative": "^0.8.7",
"rollup-pluginutils": "^2.8.2",
"sourcemap-codec": "^1.4.8"
}
},
"rollup-plugin-node-resolve": {
"version": "5.2.0",
"resolved": "https://registry.npmjs.org/rollup-plugin-node-resolve/-/rollup-plugin-node-resolve-5.2.0.tgz",
"integrity": "sha512-jUlyaDXts7TW2CqQ4GaO5VJ4PwwaV8VUGA7+km3n6k6xtOEacf61u0VXwN80phY/evMcaS+9eIeJ9MOyDxt5Zw==",
"rollup-plugin-terser": {
"version": "7.0.1",
"resolved": "https://registry.npmjs.org/rollup-plugin-terser/-/rollup-plugin-terser-7.0.1.tgz",
"integrity": "sha512-HL0dgzSxBYG/Ly9i/E5Sc+PuKKZ0zBzk11VmLCfdUtpqH4yYqkLclPkTqRy85FU9246yetImOClaQ/ufnj08vg==",
"dev": true,
"requires": {
"@types/resolve": "0.0.8",
"builtin-modules": "^3.1.0",
"is-module": "^1.0.0",
"resolve": "^1.11.1",
"rollup-pluginutils": "^2.8.1"
"@babel/code-frame": "^7.10.4",
"jest-worker": "^26.2.1",
"serialize-javascript": "^4.0.0",
"terser": "^5.0.0"
},
"dependencies": {
"resolve": {
"version": "1.11.1",
"resolved": "https://registry.npmjs.org/resolve/-/resolve-1.11.1.tgz",
"integrity": "sha512-vIpgF6wfuJOZI7KKKSP+HmiKggadPQAdsp5HiC1mvqnfp0gF1vdwgBWZIdrVft9pgqoMFQN+R7BSWZiBxx+BBw==",
"@babel/code-frame": {
"version": "7.10.4",
"resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.10.4.tgz",
"integrity": "sha512-vG6SvB6oYEhvgisZNFRmRCUkLz11c7rp+tbNTynGqc6mS1d5ATd/sGyV6W0KZZnXRKMTzZDRgQT3Ou9jhpAfUg==",
"dev": true,
"requires": {
"path-parse": "^1.0.6"
"@babel/highlight": "^7.10.4"
}
},
"@babel/highlight": {
"version": "7.10.4",
"resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.10.4.tgz",
"integrity": "sha512-i6rgnR/YgPEQzZZnbTHHuZdlE8qyoBNalD6F+q4vAFlcMEcqmkoG+mPqJYJCo63qPf74+Y1UZsl3l6f7/RIkmA==",
"dev": true,
"requires": {
"@babel/helper-validator-identifier": "^7.10.4",
"chalk": "^2.0.0",
"js-tokens": "^4.0.0"
}
}
}
},
"rollup-plugin-replace": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/rollup-plugin-replace/-/rollup-plugin-replace-2.2.0.tgz",
"integrity": "sha512-/5bxtUPkDHyBJAKketb4NfaeZjL5yLZdeUihSfbF2PQMz+rSTEb8ARKoOl3UBT4m7/X+QOXJo3sLTcq+yMMYTA==",
"dev": true,
"requires": {
"magic-string": "^0.25.2",
"rollup-pluginutils": "^2.6.0"
}
},
"rollup-plugin-svelte": {
"version": "5.1.0",
"resolved": "https://registry.npmjs.org/rollup-plugin-svelte/-/rollup-plugin-svelte-5.1.0.tgz",
"integrity": "sha512-4MRZG29dAWDpoxEs5uIHzDnYafQEOLaKIJAuDYUtFIzEm1F1IGSTlFyjd8/qk4wltlHdu6V7YfZY53+CKryhMg==",
"dev": true,
"requires": {
"require-relative": "^0.8.7",
"rollup-pluginutils": "^2.3.3",
"sourcemap-codec": "^1.4.4"
}
},
"rollup-plugin-terser": {
"version": "5.1.1",
"resolved": "https://registry.npmjs.org/rollup-plugin-terser/-/rollup-plugin-terser-5.1.1.tgz",
"integrity": "sha512-McIMCDEY8EU6Y839C09UopeRR56wXHGdvKKjlfiZG/GrP6wvZQ62u2ko/Xh1MNH2M9WDL+obAAHySljIZYCuPQ==",
"dev": true,
"requires": {
"@babel/code-frame": "^7.0.0",
"jest-worker": "^24.6.0",
"rollup-pluginutils": "^2.8.1",
"serialize-javascript": "^1.7.0",
"terser": "^4.1.0"
}
},
"rollup-pluginutils": {
"version": "2.8.1",
"resolved": "https://registry.npmjs.org/rollup-pluginutils/-/rollup-pluginutils-2.8.1.tgz",
"integrity": "sha512-J5oAoysWar6GuZo0s+3bZ6sVZAC0pfqKz68De7ZgDi5z63jOVZn1uJL/+z1jeKHNbGII8kAyHF5q8LnxSX5lQg==",
"version": "2.8.2",
"resolved": "https://registry.npmjs.org/rollup-pluginutils/-/rollup-pluginutils-2.8.2.tgz",
"integrity": "sha512-EEp9NhnUkwY8aif6bxgovPHMoMoNr2FulJziTndpt5H9RdwC47GSGuII9XxpSdzVGM0GWrNPHV6ie1LTNJPaLQ==",
"dev": true,
"requires": {
"estree-walker": "^0.6.1"
},
"dependencies": {
"estree-walker": {
"version": "0.6.1",
"resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-0.6.1.tgz",
"integrity": "sha512-SqmZANLWS0mnatqbSfRP5g8OXZC12Fgg1IwNtLsyHDzJizORW4khDfjPqJZsemPWBB2uqykUah5YpQ6epsqC/w==",
"dev": true
}
}
},
"safe-buffer": {
@ -3495,9 +3597,9 @@
}
},
"sapper": {
"version": "0.27.11",
"resolved": "https://registry.npmjs.org/sapper/-/sapper-0.27.11.tgz",
"integrity": "sha512-5EaPZhlc8OnyN3UCI6dRSM1Gz5sxyzLZG/1z5nMvZhg9Ng+rSvEvJx/rW/tSHcnQPa8or7+YcbfvQHKS5oPHiw==",
"version": "0.27.16",
"resolved": "https://registry.npmjs.org/sapper/-/sapper-0.27.16.tgz",
"integrity": "sha512-q8dohkbhga6xO+0a8h84odFyoilQ0D0vJtF8NHra/DQmSeN2R2MXUfwhw3EyvLms3T1x8H3v+qw642Qf5JXA9g==",
"dev": true,
"requires": {
"html-minifier": "^4.0.0",
@ -3505,14 +3607,6 @@
"shimport": "^1.0.1",
"sourcemap-codec": "^1.4.6",
"string-hash": "^1.1.3"
},
"dependencies": {
"sourcemap-codec": {
"version": "1.4.6",
"resolved": "https://registry.npmjs.org/sourcemap-codec/-/sourcemap-codec-1.4.6.tgz",
"integrity": "sha512-1ZooVLYFxC448piVLBbtOxFcXwnymH9oUF8nRd3CuYDVvkRBxRl6pB4Mtas5a4drtL+E8LDgFkQNcgIw6tc8Hg==",
"dev": true
}
}
},
"sax": {
@ -3533,10 +3627,13 @@
"integrity": "sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA=="
},
"serialize-javascript": {
"version": "1.7.0",
"resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-1.7.0.tgz",
"integrity": "sha512-ke8UG8ulpFOxO8f8gRYabHQe/ZntKlcig2Mp+8+URDP1D8vJZ0KUt7LYo07q25Z/+JVSgpr/cui9PIp5H6/+nA==",
"dev": true
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-4.0.0.tgz",
"integrity": "sha512-GaNA54380uFefWghODBWEGisLZFj00nS5ACs6yHa9nLqlLpVLO8ChDGeKRjZnV4Nh4n0Qi7nhYZD/9fCPzEqkw==",
"dev": true,
"requires": {
"randombytes": "^2.1.0"
}
},
"set-blocking": {
"version": "2.0.0",
@ -3595,9 +3692,9 @@
"dev": true
},
"sirv": {
"version": "1.0.0-next.2",
"resolved": "https://registry.npmjs.org/sirv/-/sirv-1.0.0-next.2.tgz",
"integrity": "sha512-hWp0todr4jSb1BFBiANRmqYRXzX02l36/X4tyHPYKqMZ+e1hrDZKUjIIXrAOBRWlAE/G5cGImUciMrUcU8DeOg==",
"version": "1.0.6",
"resolved": "https://registry.npmjs.org/sirv/-/sirv-1.0.6.tgz",
"integrity": "sha512-LRGu7Op4Xl9hhigOy2kcB53zAYTjNDdpooey49dIU0cMdpOv9ithVf7nstk3jvs8EhMiT/VORoyazZYGgw4vnA==",
"requires": {
"@polka/url": "^1.0.0-next.9",
"mime": "^2.3.1",
@ -3611,9 +3708,9 @@
"dev": true
},
"source-map-support": {
"version": "0.5.12",
"resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.12.tgz",
"integrity": "sha512-4h2Pbvyy15EE02G+JOZpUCmqWJuqrs+sEkzewTm++BPi7Hvn/HwcqLAcNxYAyI0x13CpPPn+kMjl+hplXMHITQ==",
"version": "0.5.19",
"resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.19.tgz",
"integrity": "sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw==",
"dev": true,
"requires": {
"buffer-from": "^1.0.0",
@ -3629,9 +3726,9 @@
}
},
"sourcemap-codec": {
"version": "1.4.4",
"resolved": "https://registry.npmjs.org/sourcemap-codec/-/sourcemap-codec-1.4.4.tgz",
"integrity": "sha512-CYAPYdBu34781kLHkaW3m6b/uUSyMOC2R61gcYMWooeuaGtjof86ZA/8T+qVPPt7np1085CR9hmMGrySwEc8Xg==",
"version": "1.4.8",
"resolved": "https://registry.npmjs.org/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz",
"integrity": "sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==",
"dev": true
},
"spdx-correct": {
@ -3718,15 +3815,6 @@
"function-bind": "^1.1.1"
}
},
"string_decoder": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
"integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
"dev": true,
"requires": {
"safe-buffer": "~5.1.0"
}
},
"strip-ansi": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz",
@ -3791,9 +3879,9 @@
}
},
"terser": {
"version": "4.1.2",
"resolved": "https://registry.npmjs.org/terser/-/terser-4.1.2.tgz",
"integrity": "sha512-jvNoEQSPXJdssFwqPSgWjsOrb+ELoE+ILpHPKXC83tIxOlh2U75F1KuB2luLD/3a6/7K3Vw5pDn+hvu0C4AzSw==",
"version": "5.3.0",
"resolved": "https://registry.npmjs.org/terser/-/terser-5.3.0.tgz",
"integrity": "sha512-XTT3D3AwxC54KywJijmY2mxZ8nJiEjBHVYzq8l9OaYuRFWeQNBwvipuzzYEP4e+/AVcd1hqG/CqgsdIRyT45Fg==",
"dev": true,
"requires": {
"commander": "^2.20.0",
@ -3839,9 +3927,9 @@
"dev": true
},
"totalist": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/totalist/-/totalist-1.0.1.tgz",
"integrity": "sha512-HuAt9bWDCdLkebrIQr+i63NgQSvjeD2VTNUIEBqof/4pG4Gb6omuBOMUX0vF371cbfImXQzmb4Ue/0c9MUWGew=="
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/totalist/-/totalist-1.1.0.tgz",
"integrity": "sha512-gduQwd1rOdDMGxFG1gEvhV88Oirdo2p+KjoYFU7k2g+i7n6AFFbDQ5kMPUsW0pNbfQsB/cwXvT1i4Bue0s9g5g=="
},
"trim-right": {
"version": "1.0.1",
@ -3858,22 +3946,10 @@
}
},
"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,
"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
}
}
"version": "3.10.4",
"resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.10.4.tgz",
"integrity": "sha512-kBFT3U4Dcj4/pJ52vfjCSfyLyvG9VYYuGYPmrPvAxRw/i7xHiT4VvCev+uiEMcEEiu6UNB6KgWmGtSUYIWScbw==",
"dev": true
},
"unicode-canonical-property-names-ecmascript": {
"version": "1.0.4",
@ -3918,12 +3994,6 @@
"pako": "^1.0.5"
}
},
"util-deprecate": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
"integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=",
"dev": true
},
"util.promisify": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/util.promisify/-/util.promisify-1.0.0.tgz",

@ -4,9 +4,9 @@
"description": "Docs and examples for Svelte",
"scripts": {
"dev": "npm run copy-workers && sapper dev",
"copy-workers": "rm -rf static/workers && cp -r node_modules/@sveltejs/svelte-repl/workers static",
"copy-workers": "node scripts/copy-workers.js",
"migrate": "node-pg-migrate -r dotenv/config",
"sapper": "npm run copy-workers && sapper build --legacy",
"build": "npm run copy-workers && sapper build --legacy",
"update": "node scripts/update_template.js && node scripts/get-contributors.js && node scripts/update_whos_using.js",
"start": "node __sapper__/build",
"test": "mocha -r esm test/**",
@ -21,12 +21,12 @@
"flru": "^1.0.2",
"httpie": "^1.1.2",
"jsonwebtoken": "^8.5.1",
"marked": "^0.7.0",
"marked": "^1.0.0",
"pg": "^7.12.1",
"polka": "^1.0.0-next.9",
"prism-svelte": "^0.4.3",
"prismjs": "^1.17.1",
"sirv": "^1.0.0-next.2",
"prismjs": "^1.21.0",
"sirv": "^1.0.0",
"yootils": "0.0.16"
},
"devDependencies": {
@ -35,26 +35,26 @@
"@babel/plugin-transform-runtime": "^7.6.0",
"@babel/preset-env": "^7.6.0",
"@babel/runtime": "^7.6.0",
"@rollup/plugin-babel": "^5.0.0",
"@rollup/plugin-commonjs": "^15.0.0",
"@rollup/plugin-json": "^4.1.0",
"@rollup/plugin-node-resolve": "^9.0.0",
"@rollup/plugin-replace": "^2.2.0",
"@sindresorhus/slugify": "^0.9.1",
"@sveltejs/site-kit": "^1.2.1",
"@sveltejs/svelte-repl": "^0.2.0",
"@sveltejs/site-kit": "^1.2.5",
"@sveltejs/svelte-repl": "^0.2.1",
"degit": "^2.1.4",
"dotenv": "^8.1.0",
"esm": "^3.2.25",
"jimp": "^0.8.0",
"mocha": "^6.2.0",
"node-fetch": "^2.6.0",
"node-fetch": "^2.6.1",
"node-pg-migrate": "^3.22.0",
"npm-run-all": "^4.1.5",
"rollup": "^1.21.2",
"rollup-plugin-babel": "^4.3.3",
"rollup-plugin-commonjs": "^10.1.0",
"rollup-plugin-json": "^4.0.0",
"rollup-plugin-node-resolve": "^5.2.0",
"rollup-plugin-replace": "^2.2.0",
"rollup-plugin-svelte": "^5.1.0",
"rollup-plugin-terser": "^5.1.1",
"sapper": "^0.27.11",
"rollup": "^2.26.10",
"rollup-plugin-svelte": "^6.0.0",
"rollup-plugin-terser": "^7.0.0",
"sapper": "^0.27.16",
"shelljs": "^0.8.3",
"svelte": "^3.12.0"
},

@ -1,10 +1,10 @@
import 'dotenv/config';
import resolve from 'rollup-plugin-node-resolve';
import replace from 'rollup-plugin-replace';
import commonjs from 'rollup-plugin-commonjs';
import babel from '@rollup/plugin-babel';
import commonjs from '@rollup/plugin-commonjs';
import json from '@rollup/plugin-json';
import replace from '@rollup/plugin-replace';
import resolve from '@rollup/plugin-node-resolve';
import svelte from 'rollup-plugin-svelte';
import babel from 'rollup-plugin-babel';
import json from 'rollup-plugin-json';
import { terser } from 'rollup-plugin-terser';
import config from 'sapper/config/rollup.js';
import pkg from './package.json';
@ -44,7 +44,7 @@ export default {
legacy && babel({
extensions: ['.js', '.mjs', '.html', '.svelte'],
runtimeHelpers: true,
babelHelpers: 'runtime',
exclude: ['node_modules/@babel/**'],
presets: [
['@babel/preset-env', {
@ -63,6 +63,8 @@ export default {
module: true
})
],
preserveEntrySignatures: false,
onwarn
},
@ -91,6 +93,8 @@ export default {
require('module').builtinModules || Object.keys(process.binding('natives'))
)
],
preserveEntrySignatures: 'strict',
onwarn
},
@ -105,6 +109,9 @@ export default {
}),
commonjs(),
!dev && terser()
]
],
preserveEntrySignatures: false,
onwarn
}
};

@ -0,0 +1,4 @@
const sh = require('shelljs');
sh.rm('-rf', 'static/workers');
sh.cp('-r', 'node_modules/@sveltejs/svelte-repl/workers', 'static');

@ -5,8 +5,8 @@
<style>
.input-output-toggle {
display: grid;
position: absolute;
user-select: none;
flex: 0;
grid-template-columns: 1fr 40px 1fr;
grid-gap: 0.5em;
align-items: center;

@ -89,6 +89,8 @@
left: 0;
width: 100%;
height: 100%;
display: flex;
flex-direction: column;
background-color: var(--back);
overflow: hidden;
box-sizing: border-box;
@ -98,6 +100,7 @@
.viewport {
width: 100%;
height: 100%;
flex: 1;
}
.mobile .viewport {

@ -8,6 +8,18 @@ function formatPubdate(str) {
return `${d} ${months[+m]} ${y} 12:00 +0000`;
}
function escapeHTML(html) {
const chars = {
'"' : 'quot',
"'": '#39',
'&': 'amp',
'<' : 'lt',
'>' : 'gt'
};
return html.replace(/["'&<>]/g, c => `&${chars[c]};`);
}
const rss = `
<?xml version="1.0" encoding="UTF-8" ?>
<rss version="2.0">
@ -23,9 +35,9 @@ const rss = `
</image>
${get_posts().filter(post => !post.metadata.draft).map(post => `
<item>
<title>${post.metadata.title}</title>
<title>${escapeHTML(post.metadata.title)}</title>
<link>https://svelte.dev/blog/${post.slug}</link>
<description>${post.metadata.description}</description>
<description>${escapeHTML(post.metadata.description)}</description>
<pubDate>${formatPubdate(post.metadata.pubdate)}</pubDate>
</item>
`).join('')}

@ -228,6 +228,7 @@ export default app;` });
background-color: var(--second);
color: white;
white-space: nowrap;
flex: 0;
}
.icon {

@ -125,6 +125,8 @@
padding: var(--app-controls-h) 0 0 0;
/* margin: 0 calc(var(--side-nav) * -1); */
box-sizing: border-box;
display: flex;
flex-direction: column;
}
.viewport {
@ -136,6 +138,7 @@
width: 200%;
height: calc(100% - 42px);
transition: transform 0.3s;
flex: 1;
}
.mobile .offset {

@ -27,6 +27,8 @@
overflow: hidden;
box-sizing: border-box;
--pane-controls-h: 4.2rem;
display: flex;
flex-direction: column;
}
</style>

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

@ -8,7 +8,7 @@ import {
create_scopes,
extract_names,
Scope,
extract_identifiers,
extract_identifiers
} from './utils/scope';
import Stylesheet from './css/Stylesheet';
import { test } from '../config';
@ -29,6 +29,7 @@ import add_to_set from './utils/add_to_set';
import check_graph_for_cycles from './utils/check_graph_for_cycles';
import { print, x, b } from 'code-red';
import { is_reserved_keyword } from './utils/reserved_keywords';
import Element from './nodes/Element';
interface ComponentOptions {
namespace?: string;
@ -85,6 +86,7 @@ export default class Component {
file: string;
locate: (c: number) => { line: number; column: number };
elements: Element[] = [];
stylesheet: Stylesheet;
aliases: Map<string, Identifier> = new Map();
@ -155,7 +157,7 @@ export default class Component {
) || { start: 0, end: 0 };
this.warn(svelteOptions, {
code: 'custom-element-no-tag',
message: `No custom element 'tag' option was specified. To automatically register a custom element, specify a name with a hyphen in it, e.g. <svelte:options tag="my-thing"/>. To hide this warning, use <svelte:options tag={null}/>`,
message: `No custom element 'tag' option was specified. To automatically register a custom element, specify a name with a hyphen in it, e.g. <svelte:options tag="my-thing"/>. To hide this warning, use <svelte:options tag={null}/>`
});
}
this.tag = this.component_options.tag || compile_options.tag;
@ -171,8 +173,8 @@ export default class Component {
this.walk_instance_js_post_template();
this.elements.forEach(element => this.stylesheet.apply(element));
if (!compile_options.customElement) this.stylesheet.reify();
this.stylesheet.warn_on_unused_selectors(this);
}
@ -190,7 +192,7 @@ export default class Component {
this.add_var({
name,
injected: true,
referenced: true,
referenced: true
});
} else if (name[0] === '$') {
this.add_var({
@ -198,7 +200,7 @@ export default class Component {
injected: true,
referenced: true,
mutated: true,
writable: true,
writable: true
});
const subscribable_name = name.slice(1);
@ -221,6 +223,10 @@ export default class Component {
return this.aliases.get(name);
}
apply_stylesheet(element: Element) {
this.elements.push(element);
}
global(name: string) {
const alias = this.alias(name);
this.globals.set(name, alias);
@ -289,7 +295,7 @@ export default class Component {
}
const imported_helpers = Array.from(this.helpers, ([name, alias]) => ({
name,
alias,
alias
}));
create_module(
@ -305,7 +311,7 @@ export default class Component {
.filter(variable => variable.module && variable.export_name)
.map(variable => ({
name: variable.name,
as: variable.export_name,
as: variable.export_name
}))
);
@ -342,9 +348,9 @@ export default class Component {
reassigned: v.reassigned || false,
referenced: v.referenced || false,
writable: v.writable || false,
referenced_from_script: v.referenced_from_script || false,
referenced_from_script: v.referenced_from_script || false
})),
stats: this.stats.render(),
stats: this.stats.render()
};
}
@ -409,7 +415,7 @@ export default class Component {
source: this.source,
start: pos.start,
end: pos.end,
filename: this.compile_options.filename,
filename: this.compile_options.filename
});
}
@ -441,7 +447,7 @@ export default class Component {
pos: pos.start,
filename: this.compile_options.filename,
toString: () =>
`${warning.message} (${start.line}:${start.column})\n${frame}`,
`${warning.message} (${start.line}:${start.column})\n${frame}`
});
}
@ -453,7 +459,7 @@ export default class Component {
if (node.type === 'ExportDefaultDeclaration') {
this.error(node, {
code: `default-export`,
message: `A component cannot have a default export`,
message: `A component cannot have a default export`
});
}
@ -461,7 +467,7 @@ export default class Component {
if (node.source) {
this.error(node, {
code: `not-implemented`,
message: `A component currently cannot have an export ... from`,
message: `A component currently cannot have an export ... from`
});
}
if (node.declaration) {
@ -531,10 +537,10 @@ export default class Component {
if (node.type === 'LabeledStatement' && node.label.name === '$') {
component.warn(node as any, {
code: 'module-script-reactive-declaration',
message: '$: has no effect in a module script',
message: '$: has no effect in a module script'
});
}
},
}
});
const { scope, globals } = create_scopes(script.content);
@ -544,7 +550,7 @@ export default class Component {
if (name[0] === '$') {
this.error(node as any, {
code: 'illegal-declaration',
message: `The $ prefix is reserved, and cannot be used for variable and import names`,
message: `The $ prefix is reserved, and cannot be used for variable and import names`
});
}
@ -562,7 +568,7 @@ export default class Component {
if (name[0] === '$') {
this.error(node as any, {
code: 'illegal-subscription',
message: `Cannot reference store value inside <script context="module">`,
message: `Cannot reference store value inside <script context="module">`
});
} else {
this.add_var({
@ -623,7 +629,7 @@ export default class Component {
if (name[0] === '$') {
this.error(node as any, {
code: 'illegal-declaration',
message: `The $ prefix is reserved, and cannot be used for variable and import names`,
message: `The $ prefix is reserved, and cannot be used for variable and import names`
});
}
@ -647,12 +653,12 @@ export default class Component {
injected: true,
writable: true,
reassigned: true,
initialised: true,
initialised: true
});
} else if (is_reserved_keyword(name)) {
this.add_var({
name,
injected: true,
injected: true
});
} else if (name[0] === '$') {
if (name === '$' || name[1] === '$') {
@ -666,7 +672,7 @@ export default class Component {
name,
injected: true,
mutated: true,
writable: true,
writable: true
});
this.add_reference(name.slice(1));
@ -764,7 +770,7 @@ export default class Component {
if (map.has(node)) {
scope = scope.parent;
}
},
}
});
for (const [parent, prop, index] of to_remove) {
@ -832,7 +838,7 @@ export default class Component {
if (map.has(node)) {
scope = scope.parent;
}
},
}
});
}
@ -844,7 +850,7 @@ export default class Component {
) {
this.warn(node as any, {
code: 'non-top-level-reactive-declaration',
message: '$: has no effect outside of the top-level',
message: '$: has no effect outside of the top-level'
});
}
@ -881,7 +887,7 @@ export default class Component {
if (node.body.type !== 'BlockStatement') {
node.body = {
type: 'BlockStatement',
body: [node.body],
body: [node.body]
};
}
node.body.body.push(inside[0]);
@ -890,8 +896,8 @@ export default class Component {
type: 'BlockStatement',
body: [
before[0],
node,
],
node
]
};
}
return null;
@ -927,7 +933,7 @@ export default class Component {
// TODO is this still true post-#3539?
component.error(declarator as any, {
code: 'destructured-prop',
message: `Cannot declare props in destructured declaration`,
message: `Cannot declare props in destructured declaration`
});
}
@ -947,12 +953,6 @@ export default class Component {
const variable = component.var_lookup.get(name);
if (variable.export_name && variable.writable) {
const insert = variable.subscribable
? get_insert(variable)
: null;
parent[key].splice(index + 1, 0, insert);
declarator.id = {
type: 'ObjectPattern',
properties: [{
@ -973,7 +973,9 @@ export default class Component {
};
declarator.init = x`$$props`;
} else if (variable.subscribable) {
}
if (variable.subscribable && declarator.init) {
const insert = get_insert(variable);
parent[key].splice(index + 1, 0, ...insert);
}
@ -990,7 +992,7 @@ export default class Component {
if (node.type === 'ExportNamedDeclaration' && node.declaration) {
(parent as Program).body[index] = node.declaration;
}
},
}
});
}
@ -1004,7 +1006,7 @@ export default class Component {
hoistable_nodes,
var_lookup,
injected_reactive_declaration_vars,
imports,
imports
} = this;
const top_level_function_declarations = new Map();
@ -1136,7 +1138,7 @@ export default class Component {
if (map.has(node)) {
scope = scope.parent;
}
},
}
});
checked.add(fn_declaration);
@ -1229,7 +1231,7 @@ export default class Component {
if (map.has(node)) {
scope = scope.parent;
}
},
}
});
const { expression } = node.body as ExpressionStatement;
@ -1239,7 +1241,7 @@ export default class Component {
assignees,
dependencies,
node,
declaration,
declaration
});
}
});
@ -1320,7 +1322,7 @@ export default class Component {
this.warn(node, {
code: 'missing-declaration',
message,
message
});
}
@ -1343,7 +1345,7 @@ function process_component_options(component: Component, nodes) {
'accessors' in component.compile_options
? component.compile_options.accessors
: !!component.compile_options.customElement,
preserveWhitespace: !!component.compile_options.preserveWhitespace,
preserveWhitespace: !!component.compile_options.preserveWhitespace
};
const node = nodes.find(node => node.name === 'svelte:options');
@ -1384,7 +1386,7 @@ function process_component_options(component: Component, nodes) {
if (tag && !/^[a-zA-Z][a-zA-Z0-9]*-[a-zA-Z0-9-]+$/.test(tag)) {
component.error(attribute, {
code: `invalid-tag-property`,
message: `tag name must be two or more words joined by the '-' character`,
message: `tag name must be two or more words joined by the '-' character`
});
}
@ -1412,12 +1414,12 @@ function process_component_options(component: Component, nodes) {
if (match) {
component.error(attribute, {
code: `invalid-namespace-property`,
message: `Invalid namespace '${ns}' (did you mean '${match}'?)`,
message: `Invalid namespace '${ns}' (did you mean '${match}'?)`
});
} else {
component.error(attribute, {
code: `invalid-namespace-property`,
message: `Invalid namespace '${ns}'`,
message: `Invalid namespace '${ns}'`
});
}
}
@ -1443,13 +1445,13 @@ function process_component_options(component: Component, nodes) {
default:
component.error(attribute, {
code: `invalid-options-attribute`,
message: `<svelte:options> unknown attribute`,
message: `<svelte:options> unknown attribute`
});
}
} else {
component.error(attribute, {
code: `invalid-options-attribute`,
message: `<svelte:options> can only have static 'tag', 'namespace', 'accessors', 'immutable' and 'preserveWhitespace' attributes`,
message: `<svelte:options> can only have static 'tag', 'namespace', 'accessors', 'immutable' and 'preserveWhitespace' attributes`
});
}
});

@ -4,12 +4,24 @@ import { gather_possible_values, UNKNOWN } from './gather_possible_values';
import { CssNode } from './interfaces';
import Component from '../Component';
import Element from '../nodes/Element';
import { INode } from '../nodes/interfaces';
import EachBlock from '../nodes/EachBlock';
import IfBlock from '../nodes/IfBlock';
import AwaitBlock from '../nodes/AwaitBlock';
enum BlockAppliesToNode {
NotPossible,
Possible,
UnknownSelectorType
}
enum NodeExist {
Probably = 1,
Definitely = 2,
}
const whitelist_attribute_selector = new Map([
['details', new Set(['open'])]
]);
export default class Selector {
node: CssNode;
@ -35,10 +47,10 @@ export default class Selector {
this.used = this.local_blocks.length === 0;
}
apply(node: Element, stack: Element[]) {
apply(node: Element) {
const to_encapsulate: any[] = [];
apply_selector(this.local_blocks.slice(), node, stack.slice(), to_encapsulate);
apply_selector(this.local_blocks.slice(), node, to_encapsulate);
if (to_encapsulate.length > 0) {
to_encapsulate.forEach(({ node, block }) => {
@ -65,9 +77,8 @@ export default class Selector {
transform(code: MagicString, attr: string, max_amount_class_specificity_increased: number) {
const amount_class_specificity_to_increase = max_amount_class_specificity_increased - this.blocks.filter(block => block.should_encapsulate).length;
attr = attr.repeat(amount_class_specificity_to_increase + 1);
function encapsulate_block(block: Block) {
function encapsulate_block(block: Block, attr: string) {
let i = block.selectors.length;
while (i--) {
@ -89,15 +100,14 @@ export default class Selector {
}
}
this.blocks.forEach((block) => {
this.blocks.forEach((block, index) => {
if (block.global) {
const selector = block.selectors[0];
const first = selector.children[0];
const last = selector.children[selector.children.length - 1];
code.remove(selector.start, first.start).remove(last.end, selector.end);
}
if (block.should_encapsulate) encapsulate_block(block);
if (block.should_encapsulate) encapsulate_block(block, index === this.blocks.length - 1 ? attr.repeat(amount_class_specificity_to_increase + 1) : attr);
});
}
@ -147,12 +157,12 @@ export default class Selector {
}
}
function apply_selector(blocks: Block[], node: Element, stack: Element[], to_encapsulate: any[]): boolean {
function apply_selector(blocks: Block[], node: Element, to_encapsulate: any[]): boolean {
const block = blocks.pop();
if (!block) return false;
if (!node) {
return blocks.every(block => block.global);
return block.global && blocks.every(block => block.global);
}
switch (block_might_apply_to_node(block, node)) {
@ -160,7 +170,7 @@ function apply_selector(blocks: Block[], node: Element, stack: Element[], to_enc
return false;
case BlockAppliesToNode.UnknownSelectorType:
// bail. TODO figure out what these could be
// bail. TODO figure out what these could be
to_encapsulate.push({ node, block });
return true;
}
@ -172,9 +182,10 @@ function apply_selector(blocks: Block[], node: Element, stack: Element[], to_enc
continue;
}
for (const stack_node of stack) {
if (block_might_apply_to_node(ancestor_block, stack_node) !== BlockAppliesToNode.NotPossible) {
to_encapsulate.push({ node: stack_node, block: ancestor_block });
let parent = node;
while (parent = get_element_parent(parent)) {
if (block_might_apply_to_node(ancestor_block, parent) !== BlockAppliesToNode.NotPossible) {
to_encapsulate.push({ node: parent, block: ancestor_block });
}
}
@ -191,12 +202,22 @@ function apply_selector(blocks: Block[], node: Element, stack: Element[], to_enc
return false;
} else if (block.combinator.name === '>') {
if (apply_selector(blocks, stack.pop(), stack, to_encapsulate)) {
if (apply_selector(blocks, get_element_parent(node), to_encapsulate)) {
to_encapsulate.push({ node, block });
return true;
}
return false;
} else if (block.combinator.name === '+' || block.combinator.name === '~') {
const siblings = get_possible_element_siblings(node, block.combinator.name === '+');
let has_match = false;
for (const possible_sibling of siblings.keys()) {
if (apply_selector(blocks.slice(), possible_sibling, to_encapsulate)) {
to_encapsulate.push({ node, block });
has_match = true;
}
}
return has_match;
}
// TODO other combinators
@ -208,7 +229,7 @@ function apply_selector(blocks: Block[], node: Element, stack: Element[], to_enc
return true;
}
function block_might_apply_to_node(block, node): BlockAppliesToNode {
function block_might_apply_to_node(block: Block, node: Element): BlockAppliesToNode {
let i = block.selectors.length;
while (i--) {
@ -234,7 +255,11 @@ function block_might_apply_to_node(block, node): BlockAppliesToNode {
}
else if (selector.type === 'AttributeSelector') {
if (!attribute_matches(node, selector.name.name, selector.value && unquote(selector.value), selector.matcher, selector.flags)) return BlockAppliesToNode.NotPossible;
if (
!(whitelist_attribute_selector.has(node.name.toLowerCase()) && whitelist_attribute_selector.get(node.name.toLowerCase()).has(selector.name.name.toLowerCase())) &&
!attribute_matches(node, selector.name.name, selector.value && unquote(selector.value), selector.matcher, selector.flags)) {
return BlockAppliesToNode.NotPossible;
}
}
else if (selector.type === 'TypeSelector') {
@ -370,6 +395,158 @@ function unquote(value: CssNode) {
return str;
}
function get_element_parent(node: Element): Element | null {
let parent: INode = node;
while ((parent = parent.parent) && parent.type !== 'Element');
return parent as Element | null;
}
function get_possible_element_siblings(node: INode, adjacent_only: boolean): Map<Element, NodeExist> {
const result: Map<Element, NodeExist> = new Map();
let prev: INode = node;
while (prev = prev.prev) {
if (prev.type === 'Element') {
if (!prev.attributes.find(attr => attr.type === 'Attribute' && attr.name.toLowerCase() === 'slot')) {
result.set(prev, NodeExist.Definitely);
}
if (adjacent_only) {
break;
}
} else if (prev.type === 'EachBlock' || prev.type === 'IfBlock' || prev.type === 'AwaitBlock') {
const possible_last_child = get_possible_last_child(prev, adjacent_only);
add_to_map(possible_last_child, result);
if (adjacent_only && has_definite_elements(possible_last_child)) {
return result;
}
}
}
if (!prev || !adjacent_only) {
let parent: INode = node;
let skip_each_for_last_child = node.type === 'ElseBlock';
while ((parent = parent.parent) && (parent.type === 'EachBlock' || parent.type === 'IfBlock' || parent.type === 'ElseBlock' || parent.type === 'AwaitBlock')) {
const possible_siblings = get_possible_element_siblings(parent, adjacent_only);
add_to_map(possible_siblings, result);
if (parent.type === 'EachBlock') {
// first child of each block can select the last child of each block as previous sibling
if (skip_each_for_last_child) {
skip_each_for_last_child = false;
} else {
add_to_map(get_possible_last_child(parent, adjacent_only), result);
}
} else if (parent.type === 'ElseBlock') {
skip_each_for_last_child = true;
parent = parent.parent;
}
if (adjacent_only && has_definite_elements(possible_siblings)) {
break;
}
}
}
return result;
}
function get_possible_last_child(block: EachBlock | IfBlock | AwaitBlock, adjacent_only: boolean): Map<Element, NodeExist> {
const result: Map<Element, NodeExist> = new Map();
if (block.type === 'EachBlock') {
const each_result: Map<Element, NodeExist> = loop_child(block.children, adjacent_only);
const else_result: Map<Element, NodeExist> = block.else ? loop_child(block.else.children, adjacent_only) : new Map();
const not_exhaustive = !has_definite_elements(else_result);
if (not_exhaustive) {
mark_as_probably(each_result);
mark_as_probably(else_result);
}
add_to_map(each_result, result);
add_to_map(else_result, result);
} else if (block.type === 'IfBlock') {
const if_result: Map<Element, NodeExist> = loop_child(block.children, adjacent_only);
const else_result: Map<Element, NodeExist> = block.else ? loop_child(block.else.children, adjacent_only) : new Map();
const not_exhaustive = !has_definite_elements(if_result) || !has_definite_elements(else_result);
if (not_exhaustive) {
mark_as_probably(if_result);
mark_as_probably(else_result);
}
add_to_map(if_result, result);
add_to_map(else_result, result);
} else if (block.type === 'AwaitBlock') {
const pending_result: Map<Element, NodeExist> = block.pending ? loop_child(block.pending.children, adjacent_only) : new Map();
const then_result: Map<Element, NodeExist> = block.then ? loop_child(block.then.children, adjacent_only) : new Map();
const catch_result: Map<Element, NodeExist> = block.catch ? loop_child(block.catch.children, adjacent_only) : new Map();
const not_exhaustive = !has_definite_elements(pending_result) || !has_definite_elements(then_result) || !has_definite_elements(catch_result);
if (not_exhaustive) {
mark_as_probably(pending_result);
mark_as_probably(then_result);
mark_as_probably(catch_result);
}
add_to_map(pending_result, result);
add_to_map(then_result, result);
add_to_map(catch_result, result);
}
return result;
}
function has_definite_elements(result: Map<Element, NodeExist>): boolean {
if (result.size === 0) return false;
for (const exist of result.values()) {
if (exist === NodeExist.Definitely) {
return true;
}
}
return false;
}
function add_to_map(from: Map<Element, NodeExist>, to: Map<Element, NodeExist>) {
from.forEach((exist, element) => {
to.set(element, higher_existance(exist, to.get(element)));
});
}
function higher_existance(exist1: NodeExist | null, exist2: NodeExist | null): NodeExist {
if (exist1 === undefined || exist2 === undefined) return exist1 || exist2;
return exist1 > exist2 ? exist1 : exist2;
}
function mark_as_probably(result: Map<Element, NodeExist>) {
for (const key of result.keys()) {
result.set(key, NodeExist.Probably);
}
}
function loop_child(children: INode[], adjacent_only: boolean) {
const result: Map<Element, NodeExist> = new Map();
for (let i = children.length - 1; i >= 0; i--) {
const child = children[i];
if (child.type === 'Element') {
result.set(child, NodeExist.Definitely);
if (adjacent_only) {
break;
}
} else if (child.type === 'EachBlock' || child.type === 'IfBlock' || child.type === 'AwaitBlock') {
const child_result = get_possible_last_child(child, adjacent_only);
add_to_map(child_result, result);
if (adjacent_only && has_definite_elements(child_result)) {
break;
}
}
}
return result;
}
class Block {
global: boolean;
combinator: CssNode;

@ -2,7 +2,7 @@ import MagicString from 'magic-string';
import { walk } from 'estree-walker';
import Selector from './Selector';
import Element from '../nodes/Element';
import { Ast, TemplateNode } from '../../interfaces';
import { Ast } from '../../interfaces';
import Component from '../Component';
import { CssNode } from './interfaces';
import hash from "../utils/hash";
@ -51,8 +51,8 @@ class Rule {
this.declarations = node.block.children.map((node: CssNode) => new Declaration(node));
}
apply(node: Element, stack: Element[]) {
this.selectors.forEach(selector => selector.apply(node, stack)); // TODO move the logic in here?
apply(node: Element) {
this.selectors.forEach(selector => selector.apply(node)); // TODO move the logic in here?
}
is_used(dev: boolean) {
@ -162,10 +162,10 @@ class Atrule {
this.declarations = [];
}
apply(node: Element, stack: Element[]) {
apply(node: Element) {
if (this.node.name === 'media' || this.node.name === 'supports') {
this.children.forEach(child => {
child.apply(node, stack);
child.apply(node);
});
}
@ -364,15 +364,9 @@ export default class Stylesheet {
apply(node: Element) {
if (!this.has_styles) return;
const stack: Element[] = [];
let parent: TemplateNode = node;
while (parent = parent.parent) {
if (parent.type === 'Element') stack.unshift(parent as Element);
}
for (let i = 0; i < this.children.length; i += 1) {
const child = this.children[i];
child.apply(node, stack);
child.apply(node);
}
}
@ -435,7 +429,7 @@ export default class Stylesheet {
child.warn_on_unused_selector((selector: Selector) => {
component.warn(selector.node, {
code: `css-unused-selector`,
message: `Unused CSS selector`
message: `Unused CSS selector "${this.source.slice(selector.node.start, selector.node.end)}"`
});
});
});

@ -51,7 +51,7 @@ function validate_options(options: CompileOptions, warnings: Warning[]) {
code: `options-lowercase-name`,
message,
filename,
toString: () => message,
toString: () => message
});
}
@ -61,7 +61,7 @@ function validate_options(options: CompileOptions, warnings: Warning[]) {
code: `options-loop-guard-timeout`,
message,
filename,
toString: () => message,
toString: () => message
});
}
}

@ -11,10 +11,11 @@ export default class Action extends Node {
constructor(component: Component, parent, scope, info) {
super(component, parent, scope, info);
component.warn_if_undefined(info.name, info, scope);
const object = info.name.split('.')[0];
component.warn_if_undefined(object, info, scope);
this.name = info.name;
component.add_reference(info.name.split('.')[0]);
component.add_reference(object);
this.expression = info.expression
? new Expression(component, this, scope, info.expression)

@ -41,7 +41,8 @@ export default class Binding extends Node {
this.raw_expression = JSON.parse(JSON.stringify(info.expression));
const { name } = get_object(this.expression.node);
this.is_contextual = scope.names.has(name);
this.is_contextual = Array.from(this.expression.references).some(name => scope.names.has(name));
// make sure we track this as a mutable ref
if (scope.is_let(name)) {
@ -49,7 +50,7 @@ export default class Binding extends Node {
code: 'invalid-binding',
message: 'Cannot bind to a variable declared with the let: directive'
});
} else if (this.is_contextual) {
} else if (scope.names.has(name)) {
if (scope.is_await(name)) {
component.error(this, {
code: 'invalid-binding',
@ -75,7 +76,7 @@ export default class Binding extends Node {
if (info.expression.type === 'Identifier' && !variable.writable) component.error(this.expression.node, {
code: 'invalid-binding',
message: 'Cannot bind to a variable which is not writable',
message: 'Cannot bind to a variable which is not writable'
});
}

@ -16,6 +16,7 @@ import list from '../../utils/list';
import Let from './Let';
import TemplateScope from './shared/TemplateScope';
import { INode } from './interfaces';
import Component from '../Component';
const svg = /^(?:altGlyph|altGlyphDef|altGlyphItem|animate|animateColor|animateMotion|animateTransform|circle|clipPath|color-profile|cursor|defs|desc|discard|ellipse|feBlend|feColorMatrix|feComponentTransfer|feComposite|feConvolveMatrix|feDiffuseLighting|feDisplacementMap|feDistantLight|feDropShadow|feFlood|feFuncA|feFuncB|feFuncG|feFuncR|feGaussianBlur|feImage|feMerge|feMergeNode|feMorphology|feOffset|fePointLight|feSpecularLighting|feSpotLight|feTile|feTurbulence|filter|font|font-face|font-face-format|font-face-name|font-face-src|font-face-uri|foreignObject|g|glyph|glyphRef|hatch|hatchpath|hkern|image|line|linearGradient|marker|mask|mesh|meshgradient|meshpatch|meshrow|metadata|missing-glyph|mpath|path|pattern|polygon|polyline|radialGradient|rect|set|solidcolor|stop|svg|switch|symbol|text|textPath|tref|tspan|unknown|use|view|vkern)$/;
@ -61,6 +62,17 @@ const a11y_no_onchange = new Set([
'option'
]);
const a11y_labelable = new Set([
"button",
"input",
"keygen",
"meter",
"output",
"progress",
"select",
"textarea"
]);
const invisible_elements = new Set(['meta', 'html', 'script', 'style']);
const valid_modifiers = new Set([
@ -69,6 +81,7 @@ const valid_modifiers = new Set([
'capture',
'once',
'passive',
'nonpassive',
'self'
]);
@ -112,7 +125,7 @@ export default class Element extends Node {
namespace: string;
needs_manual_style_scoping: boolean;
constructor(component, parent, scope, info: any) {
constructor(component: Component, parent, scope, info: any) {
super(component, parent, scope, info);
this.name = info.name;
@ -173,7 +186,7 @@ export default class Element extends Node {
case 'Attribute':
case 'Spread':
// special case
// special case
if (node.name === 'xmlns') this.namespace = node.value[0].data;
this.attributes.push(new Attribute(component, this, scope, node));
@ -224,7 +237,7 @@ export default class Element extends Node {
this.validate();
component.stylesheet.apply(this);
component.apply_stylesheet(this);
}
validate() {
@ -388,7 +401,7 @@ export default class Element extends Node {
if (/(^[0-9-.])|[\^$@%&#?!|()[\]{}^*+~;]/.test(name)) {
component.error(attribute, {
code: `illegal-attribute`,
message: `'${name}' is not a valid attribute name`,
message: `'${name}' is not a valid attribute name`
});
}
@ -412,7 +425,7 @@ export default class Element extends Node {
if (!(parent.type === 'InlineComponent' || within_custom_element(parent))) {
component.error(attribute, {
code: `invalid-slotted-content`,
message: `Element with a slot='...' attribute must be a child of a component or a descendant of a custom element`,
message: `Element with a slot='...' attribute must be a child of a component or a descendant of a custom element`
});
}
}
@ -507,6 +520,35 @@ export default class Element extends Node {
}
}
if (this.name === 'label') {
const has_input_child = this.children.some(i => (i instanceof Element && a11y_labelable.has(i.name) ));
if (!attribute_map.has('for') && !has_input_child) {
component.warn(this, {
code: `a11y-label-has-associated-control`,
message: `A11y: A form label must be associated with a control.`
});
}
}
if (this.is_media_node()) {
if (attribute_map.has('muted')) {
return;
}
let has_caption;
const track = this.children.find((i: Element) => i.name === 'track');
if (track) {
has_caption = track.attributes.find(a => a.name === 'kind' && a.get_static_value() === 'captions');
}
if (!has_caption) {
component.warn(this, {
code: `a11y-media-has-caption`,
message: `A11y: Media elements must have a <track kind="captions">`
});
}
}
if (a11y_no_onchange.has(this.name)) {
if (handlers_map.has('change') && !handlers_map.has('blur')) {
component.warn(this, {
@ -730,6 +772,13 @@ export default class Element extends Node {
});
}
if (handler.modifiers.has('passive') && handler.modifiers.has('nonpassive')) {
component.error(handler, {
code: 'invalid-event-modifier',
message: `The 'passive' and 'nonpassive' modifiers cannot be used together`
});
}
handler.modifiers.forEach(modifier => {
if (!valid_modifiers.has(modifier)) {
component.error(handler, {
@ -764,7 +813,7 @@ export default class Element extends Node {
}
});
if (passive_events.has(handler.name) && handler.can_make_passive && !handler.modifiers.has('preventDefault')) {
if (passive_events.has(handler.name) && handler.can_make_passive && !handler.modifiers.has('preventDefault') && !handler.modifiers.has('nonpassive')) {
// touch/wheel events should be passive by default
handler.modifiers.add('passive');
}

@ -0,0 +1,19 @@
import Expression from "./shared/Expression";
import map_children from "./shared/map_children";
import AbstractBlock from "./shared/AbstractBlock";
export default class KeyBlock extends AbstractBlock {
type: "KeyBlock";
expression: Expression;
constructor(component, parent, scope, info) {
super(component, parent, scope, info);
this.expression = new Expression(component, this, scope, info.expression);
this.children = map_children(component, this, scope, info.children);
this.warn_if_empty_block();
}
}

@ -12,7 +12,7 @@ const elements_without_text = new Set([
'dl',
'optgroup',
'select',
'video',
'video'
]);
export default class Text extends Node {

@ -34,7 +34,7 @@ export default class Transition extends Node {
}
this.expression = info.expression
? new Expression(component, this, scope, info.expression, true)
? new Expression(component, this, scope, info.expression)
: null;
}
}

@ -18,6 +18,7 @@ import Fragment from './Fragment';
import Head from './Head';
import IfBlock from './IfBlock';
import InlineComponent from './InlineComponent';
import KeyBlock from './KeyBlock';
import Let from './Let';
import MustacheTag from './MustacheTag';
import Options from './Options';
@ -50,6 +51,7 @@ export type INode = Action
| Head
| IfBlock
| InlineComponent
| KeyBlock
| Let
| MustacheTag
| Options

@ -24,7 +24,7 @@ export default class Expression {
component: Component;
owner: Owner;
node: any;
references: Set<string>;
references: Set<string> = new Set();
dependencies: Set<string> = new Set();
contextual_dependencies: Set<string> = new Set();
@ -50,7 +50,7 @@ export default class Expression {
this.template_scope = template_scope;
this.owner = owner;
const { dependencies, contextual_dependencies } = this;
const { dependencies, contextual_dependencies, references } = this;
let { map, scope } = create_scopes(info);
this.scope = scope;
@ -64,6 +64,8 @@ export default class Expression {
enter(node: any, parent: any, key: string) {
// don't manipulate shorthand props twice
if (key === 'value' && parent.shorthand) return;
// don't manipulate `import.meta`, `new.target`
if (node.type === 'MetaProperty') return this.skip();
if (map.has(node)) {
scope = map.get(node);
@ -75,6 +77,7 @@ export default class Expression {
if (is_reference(node, parent)) {
const { name, nodes } = flatten_reference(node);
references.add(name);
if (scope.has(name)) return;

@ -6,6 +6,7 @@ import Element from '../Element';
import Head from '../Head';
import IfBlock from '../IfBlock';
import InlineComponent from '../InlineComponent';
import KeyBlock from '../KeyBlock';
import MustacheTag from '../MustacheTag';
import Options from '../Options';
import RawMustacheTag from '../RawMustacheTag';
@ -28,6 +29,7 @@ function get_constructor(type) {
case 'Head': return Head;
case 'IfBlock': return IfBlock;
case 'InlineComponent': return InlineComponent;
case 'KeyBlock': return KeyBlock;
case 'MustacheTag': return MustacheTag;
case 'Options': return Options;
case 'RawMustacheTag': return RawMustacheTag;

@ -4,6 +4,15 @@ import { b, x } from 'code-red';
import { Node, Identifier, ArrayPattern } from 'estree';
import { is_head } from './wrappers/shared/is_head';
export interface Bindings {
object: Identifier;
property: Identifier;
snippet: Node;
store: string;
tail: Node;
modifier: (node: Node) => Node;
}
export interface BlockOptions {
parent?: Block;
name: Identifier;
@ -11,14 +20,7 @@ export interface BlockOptions {
renderer?: Renderer;
comment?: string;
key?: Identifier;
bindings?: Map<string, {
object: Identifier;
property: Identifier;
snippet: Node;
store: string;
tail: Node;
modifier: (node: Node) => Node;
}>;
bindings?: Map<string, Bindings>;
dependencies?: Set<string>;
}
@ -36,14 +38,7 @@ export default class Block {
dependencies: Set<string> = new Set();
bindings: Map<string, {
object: Identifier;
property: Identifier;
snippet: Node;
store: string;
tail: Node;
modifier: (node: Node) => Node;
}>;
bindings: Map<string, Bindings>;
chunks: {
declarations: Array<Node | Node[]>;
@ -106,7 +101,7 @@ export default class Block {
intro: [],
update: [],
outro: [],
destroy: [],
destroy: []
};
this.has_animation = false;

@ -60,7 +60,7 @@ export default class Renderer {
if (component.slots.size > 0) {
this.add_to_context('$$scope');
this.add_to_context('$$slots');
this.add_to_context('#slots');
}
if (this.binding_groups.size > 0) {
@ -76,7 +76,7 @@ export default class Renderer {
bindings: new Map(),
dependencies: new Set(),
dependencies: new Set()
});
this.block.has_update_method = true;
@ -160,19 +160,20 @@ export default class Renderer {
member.is_contextual = true;
} else {
member.is_non_contextual = true;
const variable = this.component.var_lookup.get(name);
member.variable = variable;
member.variable = this.component.var_lookup.get(name);
}
return member;
}
invalidate(name: string, value?) {
invalidate(name: string, value?, main_execution_context: boolean = false) {
const variable = this.component.var_lookup.get(name);
const member = this.context_lookup.get(name);
if (variable && (variable.subscribable && (variable.reassigned || variable.export_name))) {
return x`${`$$subscribe_${name}`}($$invalidate(${member.index}, ${value || name}))`;
return main_execution_context
? x`${`$$subscribe_${name}`}(${value || name})`
: x`${`$$subscribe_${name}`}($$invalidate(${member.index}, ${value || name}))`;
}
if (name[0] === '$' && name[1] !== '$') {

@ -70,6 +70,15 @@ export default function dom(
);
}
const uses_slots = component.var_lookup.has('$$slots');
let compute_slots;
if (uses_slots) {
compute_slots = b`
const $$slots = @compute_slots(#slots);
`;
}
const uses_props = component.var_lookup.has('$$props');
const uses_rest = component.var_lookup.has('$$restProps');
const $$props = uses_props || uses_rest ? `$$new_props` : `$$props`;
@ -293,8 +302,7 @@ export default function dom(
const variable = component.var_lookup.get(prop.name);
if (variable.hoistable) return false;
if (prop.name[0] === '$') return false;
return true;
return prop.name[0] !== '$';
});
const reactive_stores = component.vars.filter(variable => variable.name[0] === '$' && variable.name[1] !== '$');
@ -409,13 +417,14 @@ export default function dom(
${resubscribable_reactive_store_unsubscribers}
${component.slots.size || component.compile_options.dev || uses_slots ? b`let { $$slots: #slots = {}, $$scope } = $$props;` : null}
${component.compile_options.dev && b`@validate_slots('${component.tag}', #slots, [${[...component.slots.keys()].map(key => `'${key}'`).join(',')}]);`}
${compute_slots}
${instance_javascript}
${unknown_props_check}
${component.slots.size || component.compile_options.dev ? b`let { $$slots = {}, $$scope } = $$props;` : null}
${component.compile_options.dev && b`@validate_slots('${component.tag}', $$slots, [${[...component.slots.keys()].map(key => `'${key}'`).join(',')}]);`}
${renderer.binding_groups.size > 0 && b`const $$binding_groups = [${[...renderer.binding_groups.keys()].map(_ => x`[]`)}];`}
${component.partly_hoisted}

@ -31,48 +31,51 @@ export function invalidate(renderer: Renderer, scope: Scope, node: Node, names:
function get_invalidated(variable: Var, node?: Expression) {
if (main_execution_context && !variable.subscribable && variable.name[0] !== '$') {
return node || x`${variable.name}`;
return node;
}
return renderer.invalidate(variable.name);
return renderer.invalidate(variable.name, undefined, main_execution_context);
}
if (head) {
component.has_reactive_assignments = true;
if (node.type === 'AssignmentExpression' && node.operator === '=' && nodes_match(node.left, node.right) && tail.length === 0) {
return get_invalidated(head, node);
} else {
const is_store_value = head.name[0] === '$' && head.name[1] !== '$';
const extra_args = tail.map(variable => get_invalidated(variable));
const pass_value = (
extra_args.length > 0 ||
(node.type === 'AssignmentExpression' && node.left.type !== 'Identifier') ||
(node.type === 'UpdateExpression' && (!node.prefix || node.argument.type !== 'Identifier'))
);
if (!head) {
return node;
}
if (pass_value) {
extra_args.unshift({
type: 'Identifier',
name: head.name
});
}
component.has_reactive_assignments = true;
let invalidate = is_store_value
? x`@set_store_value(${head.name.slice(1)}, ${node}, ${extra_args})`
: !main_execution_context
? x`$$invalidate(${renderer.context_lookup.get(head.name).index}, ${node}, ${extra_args})`
: node;
if (node.type === 'AssignmentExpression' && node.operator === '=' && nodes_match(node.left, node.right) && tail.length === 0) {
return get_invalidated(head, node);
}
if (head.subscribable && head.reassigned) {
const subscribe = `$$subscribe_${head.name}`;
invalidate = x`${subscribe}(${invalidate})`;
}
const is_store_value = head.name[0] === '$' && head.name[1] !== '$';
const extra_args = tail.map(variable => get_invalidated(variable)).filter(Boolean);
return invalidate;
if (is_store_value) {
return x`@set_store_value(${head.name.slice(1)}, ${node}, ${head.name}, ${extra_args})`;
}
let invalidate;
if (!main_execution_context) {
const pass_value = (
extra_args.length > 0 ||
(node.type === 'AssignmentExpression' && node.left.type !== 'Identifier') ||
(node.type === 'UpdateExpression' && (!node.prefix || node.argument.type !== 'Identifier'))
);
if (pass_value) {
extra_args.unshift({
type: 'Identifier',
name: head.name
});
}
invalidate = x`$$invalidate(${renderer.context_lookup.get(head.name).index}, ${node}, ${extra_args})`;
} else {
// skip `$$invalidate` if it is in the main execution context
invalidate = extra_args.length ? [node, ...extra_args] : node;
}
if (head.subscribable && head.reassigned) {
const subscribe = `$$subscribe_${head.name}`;
invalidate = x`${subscribe}(${invalidate})`;
}
return node;
return invalidate;
}

@ -188,6 +188,7 @@ export default class AwaitBlockWrapper extends Wrapper {
ctx: #ctx,
current: null,
token: null,
hasCatch: ${this.catch.node.start !== null ? 'true' : 'false'},
pending: ${this.pending.block.name},
then: ${this.then.block.name},
catch: ${this.catch.block.name},
@ -231,6 +232,15 @@ export default class AwaitBlockWrapper extends Wrapper {
const dependencies = this.node.expression.dynamic_dependencies();
let update_child_context;
if (this.then.value && this.catch.value) {
update_child_context = b`#child_ctx[${this.then.value_index}] = #child_ctx[${this.catch.value_index}] = ${info}.resolved;`;
} else if (this.then.value) {
update_child_context = b`#child_ctx[${this.then.value_index}] = ${info}.resolved;`;
} else if (this.catch.value) {
update_child_context = b`#child_ctx[${this.catch.value_index}] = ${info}.resolved;`;
}
if (dependencies.length > 0) {
const condition = x`
${block.renderer.dirty(dependencies)} &&
@ -247,7 +257,7 @@ export default class AwaitBlockWrapper extends Wrapper {
} else {
const #child_ctx = #ctx.slice();
${this.then.value && b`#child_ctx[${this.then.value_index}] = ${info}.resolved;`}
${update_child_context}
${info}.block.p(#child_ctx, #dirty);
}
`);
@ -261,7 +271,7 @@ export default class AwaitBlockWrapper extends Wrapper {
block.chunks.update.push(b`
{
const #child_ctx = #ctx.slice();
${this.then.value && b`#child_ctx[${this.then.value_index}] = ${info}.resolved;`}
${update_child_context}
${info}.block.p(#child_ctx, #dirty);
}
`);

@ -7,6 +7,7 @@ import FragmentWrapper from './Fragment';
import { b, x } from 'code-red';
import ElseBlock from '../../nodes/ElseBlock';
import { Identifier, Node } from 'estree';
import get_object from '../../utils/get_object';
export class ElseBlockWrapper extends Wrapper {
node: ElseBlock;
@ -139,11 +140,8 @@ export default class EachBlockWrapper extends Wrapper {
view_length: fixed_length === null ? x`${iterations}.length` : fixed_length
};
const store =
node.expression.node.type === 'Identifier' &&
node.expression.node.name[0] === '$'
? node.expression.node.name.slice(1)
: null;
const object = get_object(node.expression.node);
const store = object.type === 'Identifier' && object.name[0] === '$' ? object.name.slice(1) : null;
node.contexts.forEach(prop => {
this.block.bindings.set(prop.key.name, {
@ -241,6 +239,11 @@ export default class EachBlockWrapper extends Wrapper {
this.node.expression.dynamic_dependencies().forEach((dependency: string) => {
all_dependencies.add(dependency);
});
if (this.node.key) {
this.node.key.dynamic_dependencies().forEach((dependency: string) => {
all_dependencies.add(dependency);
});
}
this.dependencies = all_dependencies;
if (this.node.key) {
@ -298,6 +301,19 @@ export default class EachBlockWrapper extends Wrapper {
}
`);
const has_transitions = !!(this.else.block.has_intro_method || this.else.block.has_outro_method);
const destroy_block_else = this.else.block.has_outro_method
? b`
@group_outros();
@transition_out(${each_block_else}, 1, 1, () => {
${each_block_else} = null;
});
@check_outros();`
: b`
${each_block_else}.d(1);
${each_block_else} = null;`;
if (this.else.block.has_update_method) {
this.updates.push(b`
if (!${this.vars.data_length} && ${each_block_else}) {
@ -305,22 +321,22 @@ export default class EachBlockWrapper extends Wrapper {
} else if (!${this.vars.data_length}) {
${each_block_else} = ${this.else.block.name}(#ctx);
${each_block_else}.c();
${has_transitions && b`@transition_in(${each_block_else}, 1);`}
${each_block_else}.m(${update_mount_node}, ${update_anchor_node});
} else if (${each_block_else}) {
${each_block_else}.d(1);
${each_block_else} = null;
${destroy_block_else};
}
`);
} else {
this.updates.push(b`
if (${this.vars.data_length}) {
if (${each_block_else}) {
${each_block_else}.d(1);
${each_block_else} = null;
${destroy_block_else};
}
} else if (!${each_block_else}) {
${each_block_else} = ${this.else.block.name}(#ctx);
${each_block_else}.c();
${has_transitions && b`@transition_in(${each_block_else}, 1);`}
${each_block_else}.m(${update_mount_node}, ${update_anchor_node});
}
`);

@ -307,8 +307,8 @@ const attribute_lookup = {
'optgroup',
'option',
'select',
'textarea',
],
'textarea'
]
},
formnovalidate: { property_name: 'formNoValidate', applies_to: ['button', 'input'] },
hidden: {},
@ -335,9 +335,9 @@ const attribute_lookup = {
'progress',
'param',
'select',
'textarea',
],
},
'textarea'
]
}
};
Object.keys(attribute_lookup).forEach(name => {

@ -302,7 +302,7 @@ function get_binding_group(renderer: Renderer, value: Binding, block: Block) {
},
is_context: contexts.length > 0,
contexts,
index,
index
});
}
@ -355,7 +355,7 @@ function get_event_handler(
uses_context: binding.node.is_contextual || binding.node.expression.uses_context, // TODO this is messy
mutation,
contextual_dependencies,
lhs,
lhs
};
}

@ -45,11 +45,17 @@ export default class EventHandlerWrapper {
const args = [];
const opts = ['passive', 'once', 'capture'].filter(mod => this.node.modifiers.has(mod));
const opts = ['nonpassive', 'passive', 'once', 'capture'].filter(mod => this.node.modifiers.has(mod));
if (opts.length) {
args.push((opts.length === 1 && opts[0] === 'capture')
? TRUE
: x`{ ${opts.map(opt => p`${opt}: true`)} }`);
if (opts.length === 1 && opts[0] === 'capture') {
args.push(TRUE);
} else {
args.push(x`{ ${ opts.map(opt =>
opt === 'nonpassive'
? p`passive: false`
: p`${opt}: true`
) } }`);
}
} else if (block.renderer.options.dev) {
args.push(FALSE);
}

@ -0,0 +1,61 @@
import ElementWrapper from './index';
import SlotWrapper from '../Slot';
import Block from '../../Block';
import { sanitize } from '../../../../utils/names';
import InlineComponentWrapper from '../InlineComponent';
import create_debugging_comment from '../shared/create_debugging_comment';
import { get_slot_definition } from '../shared/get_slot_definition';
export default function create_slot_block(attribute, element: ElementWrapper | SlotWrapper, block: Block) {
const owner = find_slot_owner(element.parent);
if (owner && owner.node.type === 'InlineComponent') {
const name = attribute.get_static_value() as string;
if (!((owner as unknown) as InlineComponentWrapper).slots.has(name)) {
const child_block = block.child({
comment: create_debugging_comment(element.node, element.renderer.component),
name: element.renderer.component.get_unique_name(
`create_${sanitize(name)}_slot`
),
type: 'slot'
});
const { scope, lets } = element.node;
const seen = new Set(lets.map(l => l.name.name));
((owner as unknown) as InlineComponentWrapper).node.lets.forEach(l => {
if (!seen.has(l.name.name)) lets.push(l);
});
((owner as unknown) as InlineComponentWrapper).slots.set(
name,
get_slot_definition(child_block, scope, lets)
);
element.renderer.blocks.push(child_block);
}
element.slot_block = ((owner as unknown) as InlineComponentWrapper).slots.get(
name
).block;
return element.slot_block;
}
return block;
}
function find_slot_owner(owner) {
while (owner) {
if (owner.node.type === 'InlineComponent') {
break;
}
if (owner.node.type === 'Element' && /-/.test(owner.node.name)) {
break;
}
owner = owner.parent;
}
return owner;
}

@ -2,7 +2,7 @@ import Renderer from '../../Renderer';
import Element from '../../../nodes/Element';
import Wrapper from '../shared/Wrapper';
import Block from '../../Block';
import { is_void, sanitize } from '../../../../utils/names';
import { is_void } from '../../../../utils/names';
import FragmentWrapper from '../Fragment';
import { escape_html, string_literal } from '../../../utils/stringify';
import TextWrapper from '../Text';
@ -14,12 +14,9 @@ import StyleAttributeWrapper from './StyleAttribute';
import SpreadAttributeWrapper from './SpreadAttribute';
import { dimensions } from '../../../../utils/patterns';
import Binding from './Binding';
import InlineComponentWrapper from '../InlineComponent';
import add_to_set from '../../../utils/add_to_set';
import { add_event_handler } from '../shared/add_event_handlers';
import { add_action } from '../shared/add_actions';
import create_debugging_comment from '../shared/create_debugging_comment';
import { get_slot_definition } from '../shared/get_slot_definition';
import bind_this from '../shared/bind_this';
import { is_head } from '../shared/is_head';
import { Identifier } from 'estree';
@ -28,6 +25,7 @@ import { extract_names } from 'periscopic';
import Action from '../../../nodes/Action';
import MustacheTagWrapper from '../MustacheTag';
import RawMustacheTagWrapper from '../RawMustacheTag';
import create_slot_block from './create_slot_block';
interface BindingGroup {
events: string[];
@ -132,7 +130,7 @@ const events = [
event_names: ['toggle'],
filter: (node: Element, _name: string) =>
node.name === 'details'
},
}
];
export default class ElementWrapper extends Wrapper {
@ -177,47 +175,7 @@ export default class ElementWrapper extends Wrapper {
this.attributes = this.node.attributes.map(attribute => {
if (attribute.name === 'slot') {
// TODO make separate subclass for this?
let owner = this.parent;
while (owner) {
if (owner.node.type === 'InlineComponent') {
break;
}
if (owner.node.type === 'Element' && /-/.test(owner.node.name)) {
break;
}
owner = owner.parent;
}
if (owner && owner.node.type === 'InlineComponent') {
const name = attribute.get_static_value() as string;
if (!(owner as unknown as InlineComponentWrapper).slots.has(name)) {
const child_block = block.child({
comment: create_debugging_comment(node, this.renderer.component),
name: this.renderer.component.get_unique_name(`create_${sanitize(name)}_slot`),
type: 'slot'
});
const { scope, lets } = this.node;
const seen = new Set(lets.map(l => l.name.name));
(owner as unknown as InlineComponentWrapper).node.lets.forEach(l => {
if (!seen.has(l.name.name)) lets.push(l);
});
(owner as unknown as InlineComponentWrapper).slots.set(
name,
get_slot_definition(child_block, scope, lets)
);
this.renderer.blocks.push(child_block);
}
this.slot_block = (owner as unknown as InlineComponentWrapper).slots.get(name).block;
block = this.slot_block;
}
block = create_slot_block(attribute, this, block);
}
if (attribute.name === 'style') {
return new StyleAttributeWrapper(this, block, attribute);
@ -725,6 +683,18 @@ export default class ElementWrapper extends Wrapper {
block.chunks.update.push(b`
if (${block.renderer.dirty(Array.from(dependencies))} && ${data}.multiple) @select_options(${this.var}, ${data}.value);
`);
} else if (this.node.name === 'input' && this.attributes.find(attr => attr.node.name === 'value')) {
const type = this.node.get_static_attribute_value('type');
if (type === null || type === "" || type === "text" || type === "email" || type === "password") {
block.chunks.mount.push(b`
${this.var}.value = ${data}.value;
`);
block.chunks.update.push(b`
if ('value' in ${data}) {
${this.var}.value = ${data}.value;
}
`);
}
}
}
@ -856,6 +826,10 @@ export default class ElementWrapper extends Wrapper {
block.chunks.destroy.push(b`if (detaching && ${outro_name}) ${outro_name}.end();`);
}
}
if ((intro && intro.expression && intro.expression.dependencies.size) || (outro && outro.expression && outro.expression.dependencies.size)) {
block.maintain_context = true;
}
}
add_animation(block: Block) {
@ -985,12 +959,14 @@ function to_html(wrappers: Array<ElementWrapper | TextWrapper | MustacheTagWrapp
state.quasi.value.raw += `"`;
});
state.quasi.value.raw += '>';
if (!wrapper.void) {
state.quasi.value.raw += '>';
to_html(wrapper.fragment.nodes as Array<ElementWrapper | TextWrapper>, block, literal, state);
state.quasi.value.raw += `</${wrapper.node.name}>`;
} else {
state.quasi.value.raw += '/>';
}
}
});

@ -6,6 +6,7 @@ import EachBlock from './EachBlock';
import Element from './Element/index';
import Head from './Head';
import IfBlock from './IfBlock';
import KeyBlock from './KeyBlock';
import InlineComponent from './InlineComponent/index';
import MustacheTag from './MustacheTag';
import RawMustacheTag from './RawMustacheTag';
@ -30,6 +31,7 @@ const wrappers = {
Head,
IfBlock,
InlineComponent,
KeyBlock,
MustacheTag,
Options: null,
RawMustacheTag,

@ -603,7 +603,7 @@ export default class IfBlockWrapper extends Wrapper {
// as -1
operator: val.operator,
prefix: val.prefix,
argument: val.argument,
argument: val.argument
};
}
}

@ -17,6 +17,7 @@ import { Node, Identifier, ObjectExpression } from 'estree';
import EventHandler from '../Element/EventHandler';
import { extract_names } from 'periscopic';
import mark_each_block_bindings from '../shared/mark_each_block_bindings';
import { string_to_member_expression } from '../../../utils/string_to_member_expression';
export default class InlineComponentWrapper extends Wrapper {
var: Identifier;
@ -111,7 +112,7 @@ export default class InlineComponentWrapper extends Wrapper {
if (variable.reassigned || variable.export_name || variable.is_reactive_dependency) {
this.renderer.component.warn(this.node, {
code: 'reactive-component',
message: `<${name}/> will not be reactive if ${name} changes. Use <svelte:component this={${name}}/> if you want this reactivity.`,
message: `<${name}/> will not be reactive if ${name} changes. Use <svelte:component this={${name}}/> if you want this reactivity.`
});
}
}
@ -484,7 +485,7 @@ export default class InlineComponentWrapper extends Wrapper {
} else {
const expression = this.node.name === 'svelte:self'
? component.name
: this.renderer.reference(this.node.name);
: this.renderer.reference(string_to_member_expression(this.node.name));
block.chunks.init.push(b`
${(this.node.attributes.length > 0 || this.node.bindings.length > 0) && b`

@ -0,0 +1,136 @@
import Wrapper from "./shared/Wrapper";
import Renderer from "../Renderer";
import Block from "../Block";
import EachBlock from "../../nodes/EachBlock";
import KeyBlock from "../../nodes/KeyBlock";
import create_debugging_comment from "./shared/create_debugging_comment";
import FragmentWrapper from "./Fragment";
import { b, x } from "code-red";
import { Identifier } from "estree";
export default class KeyBlockWrapper extends Wrapper {
node: KeyBlock;
fragment: FragmentWrapper;
block: Block;
dependencies: string[];
var: Identifier = { type: "Identifier", name: "key_block" };
constructor(
renderer: Renderer,
block: Block,
parent: Wrapper,
node: EachBlock,
strip_whitespace: boolean,
next_sibling: Wrapper
) {
super(renderer, block, parent, node);
this.cannot_use_innerhtml();
this.not_static_content();
this.dependencies = node.expression.dynamic_dependencies();
if (this.dependencies.length) {
block = block.child({
comment: create_debugging_comment(node, renderer.component),
name: renderer.component.get_unique_name("create_key_block"),
type: "key"
});
renderer.blocks.push(block);
}
this.block = block;
this.fragment = new FragmentWrapper(
renderer,
this.block,
node.children,
parent,
strip_whitespace,
next_sibling
);
}
render(block: Block, parent_node: Identifier, parent_nodes: Identifier) {
if (this.dependencies.length === 0) {
this.render_static_key(block, parent_node, parent_nodes);
} else {
this.render_dynamic_key(block, parent_node, parent_nodes);
}
}
render_static_key(_block: Block, parent_node: Identifier, parent_nodes: Identifier) {
this.fragment.render(this.block, parent_node, parent_nodes);
}
render_dynamic_key(block: Block, parent_node: Identifier, parent_nodes: Identifier) {
this.fragment.render(
this.block,
null,
(x`#nodes` as unknown) as Identifier
);
const has_transitions = !!(
this.block.has_intro_method || this.block.has_outro_method
);
const dynamic = this.block.has_update_method;
const previous_key = block.get_unique_name('previous_key');
const snippet = this.node.expression.manipulate(block);
block.add_variable(previous_key, snippet);
const not_equal = this.renderer.component.component_options.immutable ? x`@not_equal` : x`@safe_not_equal`;
const condition = x`${this.renderer.dirty(this.dependencies)} && ${not_equal}(${previous_key}, ${previous_key} = ${snippet})`;
block.chunks.init.push(b`
let ${this.var} = ${this.block.name}(#ctx);
`);
block.chunks.create.push(b`${this.var}.c();`);
if (this.renderer.options.hydratable) {
block.chunks.claim.push(b`${this.var}.l(${parent_nodes});`);
}
block.chunks.mount.push(
b`${this.var}.m(${parent_node || "#target"}, ${
parent_node ? "null" : "#anchor"
});`
);
const anchor = this.get_or_create_anchor(block, parent_node, parent_nodes);
const body = b`
${
has_transitions
? b`
@group_outros();
@transition_out(${this.var}, 1, 1, @noop);
@check_outros();
`
: b`${this.var}.d(1);`
}
${this.var} = ${this.block.name}(#ctx);
${this.var}.c();
${has_transitions && b`@transition_in(${this.var})`}
${this.var}.m(${this.get_update_mount_node(anchor)}, ${anchor});
`;
if (dynamic) {
block.chunks.update.push(b`
if (${condition}) {
${body}
} else {
${this.var}.p(#ctx, #dirty);
}
`);
} else {
block.chunks.update.push(b`
if (${condition}) {
${body}
}
`);
}
if (has_transitions) {
block.chunks.intro.push(b`@transition_in(${this.var})`);
block.chunks.outro.push(b`@transition_out(${this.var})`);
}
block.chunks.destroy.push(b`${this.var}.d(detaching)`);
}
}

@ -12,11 +12,13 @@ import Expression from '../../nodes/shared/Expression';
import is_dynamic from './shared/is_dynamic';
import { Identifier, ObjectExpression } from 'estree';
import create_debugging_comment from './shared/create_debugging_comment';
import create_slot_block from './Element/create_slot_block';
export default class SlotWrapper extends Wrapper {
node: Slot;
fragment: FragmentWrapper;
fallback: Block | null = null;
slot_block: Block;
var: Identifier = { type: 'Identifier', name: 'slot' };
dependencies: Set<string> = new Set(['$$scope']);
@ -42,6 +44,10 @@ export default class SlotWrapper extends Wrapper {
renderer.blocks.push(this.fallback);
}
if (this.node.values.has('slot')) {
block = create_slot_block(this.node.values.get('slot'), this, block);
}
this.fragment = new FragmentWrapper(
renderer,
this.fallback,
@ -71,6 +77,10 @@ export default class SlotWrapper extends Wrapper {
const { slot_name } = this.node;
if (this.slot_block) {
block = this.slot_block;
}
let get_slot_changes_fn;
let get_slot_context_fn;
@ -125,7 +135,7 @@ export default class SlotWrapper extends Wrapper {
const slot_or_fallback = has_fallback ? block.get_unique_name(`${sanitize(slot_name)}_slot_or_fallback`) : slot;
block.chunks.init.push(b`
const ${slot_definition} = ${renderer.reference('$$slots')}.${slot_name};
const ${slot_definition} = ${renderer.reference('#slots')}.${slot_name};
const ${slot} = @create_slot(${slot_definition}, #ctx, ${renderer.reference('$$scope')}, ${get_slot_context_fn});
${has_fallback ? b`const ${slot_or_fallback} = ${slot} || ${this.fallback.name}(#ctx);` : null}
`);

@ -16,7 +16,7 @@ const associated_events = {
outerHeight: 'resize',
scrollX: 'scroll',
scrollY: 'scroll',
scrollY: 'scroll'
};
const properties = {
@ -29,7 +29,7 @@ const readonly = new Set([
'innerHeight',
'outerWidth',
'outerHeight',
'online',
'online'
]);
export default class WindowWrapper extends Wrapper {

@ -26,11 +26,19 @@ export function add_action(block: Block, target: string, action: Action) {
block.add_variable(id);
const fn = block.renderer.reference(action.name);
const [obj, ...properties] = action.name.split('.');
block.event_listeners.push(
x`@action_destroyer(${id} = ${fn}.call(null, ${target}, ${snippet}))`
);
const fn = block.renderer.reference(obj);
if (properties.length) {
block.event_listeners.push(
x`@action_destroyer(${id} = ${fn}.${properties.join('.')}(${target}, ${snippet}))`
);
} else {
block.event_listeners.push(
x`@action_destroyer(${id} = ${fn}.call(null, ${target}, ${snippet}))`
);
}
if (dependencies && dependencies.length > 0) {
let condition = x`${id} && @is_function(${id}.update)`;

@ -34,13 +34,13 @@ export function get_slot_definition(block: Block, scope: TemplateScope, lets: Le
type: 'Property',
kind: 'init',
key: l.name,
value,
value
});
});
const changes_input = {
type: 'ObjectPattern',
properties,
properties
};
const names: Set<string> = new Set();

@ -1,9 +1,11 @@
import { Var } from '../../../../interfaces';
import { is_reserved_keyword } from '../../../utils/reserved_keywords';
export default function is_dynamic(variable: Var) {
if (variable) {
if (variable.mutated || variable.reassigned) return true; // dynamic internal state
if (!variable.module && variable.writable && variable.export_name) return true; // writable props
if (is_reserved_keyword(variable.name)) return true;
}
return false;

@ -2,7 +2,6 @@ import EachBlock from "../../../nodes/EachBlock";
import InlineComponentWrapper from "../InlineComponent";
import ElementWrapper from "../Element";
import Binding from "../../../nodes/Binding";
import get_object from "../../../utils/get_object";
export default function mark_each_block_bindings(
parent: ElementWrapper | InlineComponentWrapper,
@ -10,9 +9,12 @@ export default function mark_each_block_bindings(
) {
// we need to ensure that the each block creates a context including
// the list and the index, if they're not otherwise referenced
const object = get_object(binding.expression.node).name;
const each_block = parent.node.scope.get_owner(object);
(each_block as EachBlock).has_binding = true;
binding.expression.references.forEach(name => {
const each_block = parent.node.scope.get_owner(name);
if (each_block) {
(each_block as EachBlock).has_binding = true;
}
});
if (binding.name === "group") {
// for `<input bind:group={} >`, we make sure that all the each blocks creates context with `index`

@ -7,6 +7,7 @@ import Head from './handlers/Head';
import HtmlTag from './handlers/HtmlTag';
import IfBlock from './handlers/IfBlock';
import InlineComponent from './handlers/InlineComponent';
import KeyBlock from './handlers/KeyBlock';
import Slot from './handlers/Slot';
import Tag from './handlers/Tag';
import Text from './handlers/Text';
@ -30,6 +31,7 @@ const handlers: Record<string, Handler> = {
Head,
IfBlock,
InlineComponent,
KeyBlock,
MustacheTag: Tag, // TODO MustacheTag is an anachronism
Options: noop,
RawMustacheTag: HtmlTag,

@ -0,0 +1,6 @@
import KeyBlock from '../../nodes/KeyBlock';
import Renderer, { RenderOptions } from '../Renderer';
export default function(node: KeyBlock, renderer: Renderer, options: RenderOptions) {
renderer.render(node.children, options);
}

@ -2,17 +2,39 @@ import Renderer, { RenderOptions } from '../Renderer';
import Slot from '../../nodes/Slot';
import { x } from 'code-red';
import get_slot_data from '../../utils/get_slot_data';
import { get_slot_scope } from './shared/get_slot_scope';
export default function(node: Slot, renderer: Renderer, options: RenderOptions) {
export default function(node: Slot, renderer: Renderer, options: RenderOptions & {
slot_scopes: Map<any, any>;
}) {
const slot_data = get_slot_data(node.values);
const slot = node.get_static_attribute_value('slot');
const nearest_inline_component = node.find_nearest(/InlineComponent/);
if (slot && nearest_inline_component) {
renderer.push();
}
renderer.push();
renderer.render(node.children, options);
const result = renderer.pop();
renderer.add_expression(x`
$$slots.${node.slot_name}
? $$slots.${node.slot_name}(${slot_data})
#slots.${node.slot_name}
? #slots.${node.slot_name}(${slot_data})
: ${result}
`);
if (slot && nearest_inline_component) {
const lets = node.lets;
const seen = new Set(lets.map(l => l.name.name));
nearest_inline_component.lets.forEach(l => {
if (!seen.has(l.name.name)) lets.push(l);
});
options.slot_scopes.set(slot, {
input: get_slot_scope(node.lets),
output: renderer.pop()
});
}
}

@ -5,8 +5,7 @@ import { string_literal } from '../utils/stringify';
import Renderer from './Renderer';
import { INode as TemplateNode } from '../nodes/interfaces'; // TODO
import Text from '../nodes/Text';
import { extract_names } from '../utils/scope';
import { LabeledStatement, Statement, ExpressionStatement, AssignmentExpression, Node } from 'estree';
import { LabeledStatement, Statement, Node } from 'estree';
export default function ssr(
component: Component,
@ -35,6 +34,9 @@ export default function ssr(
const props = component.vars.filter(variable => !variable.module && variable.export_name);
const rest = uses_rest ? b`let $$restProps = @compute_rest_props($$props, [${props.map(prop => `"${prop.export_name}"`).join(',')}]);` : null;
const uses_slots = component.var_lookup.has('$$slots');
const slots = uses_slots ? b`let $$slots = @compute_slots(#slots);` : null;
const reactive_stores = component.vars.filter(variable => variable.name[0] === '$' && variable.name[1] !== '$');
const reactive_store_values = reactive_stores
.map(({ name }) => {
@ -72,37 +74,17 @@ export default function ssr(
})
: [];
const injected = Array.from(component.injected_reactive_declaration_vars).filter(name => {
const variable = component.var_lookup.get(name);
return variable.injected;
});
const reactive_declarations = component.reactive_declarations.map(d => {
const body: Statement = (d.node as LabeledStatement).body;
let statement = b`${body}`;
if (d.declaration) {
const declared = extract_names(d.declaration);
const injected = declared.filter(name => {
return name[0] !== '$' && component.var_lookup.get(name).injected;
});
const self_dependencies = injected.filter(name => d.dependencies.has(name));
if (injected.length) {
// in some cases we need to do `let foo; [expression]`, in
// others we can do `let [expression]`
const separate = (
self_dependencies.length > 0 ||
declared.length > injected.length
);
const { left, right } = (body as ExpressionStatement).expression as AssignmentExpression;
statement = separate
? b`
${injected.map(name => b`let ${name};`)}
${statement}`
: b`
let ${left} = ${right}`;
}
} else { // TODO do not add label if it's not referenced
if (!d.declaration) { // TODO do not add label if it's not referenced
statement = b`$: { ${statement} }`;
}
@ -119,6 +101,8 @@ export default function ssr(
${reactive_store_values}
${injected.map(name => b`let ${name};`)}
${reactive_declarations}
$$rendered = ${literal};
@ -129,12 +113,15 @@ export default function ssr(
: b`
${reactive_store_values}
${injected.map(name => b`let ${name};`)}
${reactive_declarations}
return ${literal};`;
const blocks = [
rest,
slots,
...reactive_stores.map(({ name }) => {
const store_name = name.slice(1);
const store = component.var_lookup.get(store_name);
@ -161,7 +148,7 @@ export default function ssr(
${component.fully_hoisted}
const ${name} = @create_ssr_component(($$result, $$props, $$bindings, $$slots) => {
const ${name} = @create_ssr_component(($$result, $$props, $$bindings, #slots) => {
${blocks}
});
`;

@ -1,4 +1,4 @@
export const reserved_keywords = new Set(["$$props", "$$restProps"]);
export const reserved_keywords = new Set(["$$props", "$$restProps", "$$slots"]);
export function is_reserved_keyword(name) {
return reserved_keywords.has(name);

@ -0,0 +1,17 @@
import { MemberExpression, Identifier } from "estree";
export function string_to_member_expression(name: string) {
const parts = name.split(".");
let node: MemberExpression | Identifier = {
type: "Identifier",
name: parts[0]
};
for (let i = 1; i < parts.length; i++) {
node = {
type: "MemberExpression",
object: node,
property: { type: "Identifier", name: parts[i] }
} as MemberExpression;
}
return node;
}

@ -16,7 +16,7 @@ const escaped = {
"'": '&#39;',
'&': '&amp;',
'<': '&lt;',
'>': '&gt;',
'>': '&gt;'
};
export function escape_html(html) {

@ -108,7 +108,7 @@ export interface CompileOptions {
format?: ModuleFormat;
name?: string;
filename?: string;
generate?: string | false;
generate?: 'dom' | 'ssr' | false;
outputFilename?: string;
cssOutputFilename?: string;
@ -166,4 +166,4 @@ export interface Var {
export interface CssResult {
code: string;
map: SourceMap;
}
}

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save