Merge branch 'master' into pr/5075

pull/5075/head
Conduitry 5 years ago
commit a42870fcbd

@ -3,6 +3,7 @@ on: [push, pull_request]
jobs:
Tests:
runs-on: ${{ matrix.os }}
timeout-minutes: 10
strategy:
matrix:
node-version: [8, 10, 12, 14]
@ -18,12 +19,14 @@ jobs:
CI: true
Lint:
runs-on: ubuntu-latest
timeout-minutes: 2
steps:
- uses: actions/checkout@v1
- uses: actions/setup-node@v1
- run: 'npm i && npm run lint'
Unit:
runs-on: ${{ matrix.os }}
timeout-minutes: 5
strategy:
matrix:
os: [ubuntu-latest, windows-latest, macOS-latest]

@ -2,14 +2,31 @@
## Unreleased
* Fix placement of `{@html}` when used at the root of a slot or the root of a component ([#5012](https://github.com/sveltejs/svelte/issues/5012))
* 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))
* Fix `bind:group` when using contextual reference ([#5174](https://github.com/sveltejs/svelte/issues/5174))
## 3.24.0
* Support nullish coalescing (`??`) and optional chaining (`?.`) operators ([#1972](https://github.com/sveltejs/svelte/issues/1972))
* Support `import.meta` ([#4379](https://github.com/sveltejs/svelte/issues/4379))
* Fix only setting `<input>` values when they're changed when there are spread attributes ([#4418](https://github.com/sveltejs/svelte/issues/4418))
* Fix placement of `{@html}` when used at the root of a slot, at the root of a component, or in `<svelte:head>` ([#5012](https://github.com/sveltejs/svelte/issues/5012), [#5071](https://github.com/sveltejs/svelte/pull/5071))
* Fix certain handling of two-way bound `contenteditable` elements ([#5018](https://github.com/sveltejs/svelte/issues/5018))
* Fix handling of `import`ed value that is used as a store and is also mutated ([#5019](https://github.com/sveltejs/svelte/issues/5019))
* Do not display `a11y-missing-content` warning on elements with `contenteditable` bindings ([#5020](https://github.com/sveltejs/svelte/issues/5020))
* Fix handling of `this` in inline function expressions in the template ([#5033](https://github.com/sveltejs/svelte/issues/5033))
* Fix collapsing HTML with static content ([#5040](https://github.com/sveltejs/svelte/issues/5040))
* Prevent use of `$store` at compile time when top-level `store` has been shadowed ([#5048](https://github.com/sveltejs/svelte/issues/5048))
* Update `<select>` with one-way `value` binding when the available `<option>`s change ([#5051](https://github.com/sveltejs/svelte/issues/5051))
* Fix published `tweened` types so the `.set()` and `.update()` options are optional ([#5062](https://github.com/sveltejs/svelte/issues/5062))
* Fix contextual `bind:this` inside `{#each}` block ([#5067](https://github.com/sveltejs/svelte/issues/5067))
* Preprocess self-closing `<script>` and `<style>` tags ([#5080](https://github.com/sveltejs/svelte/issues/5080))
* Fix types for animation- and transition-related param objects so each param is optional ([#5083](https://github.com/sveltejs/svelte/pull/5083))
## 3.23.2

36
package-lock.json generated

@ -1,6 +1,6 @@
{
"name": "svelte",
"version": "3.23.2",
"version": "3.24.0",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
@ -167,9 +167,9 @@
"dev": true
},
"@types/estree": {
"version": "0.0.39",
"resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.39.tgz",
"integrity": "sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw==",
"version": "0.0.45",
"resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.45.tgz",
"integrity": "sha512-jnqIUKDUqJbDIUxm0Uj7bnlMnRm1T/eZ9N+AVMqhPgzrba2GhGG5o/jCTwmdPK709nEZsGoMzXEDUjcXHa3W0g==",
"dev": true
},
"@types/is-windows": {
@ -315,9 +315,9 @@
"dev": true
},
"acorn": {
"version": "7.1.1",
"resolved": "https://registry.npmjs.org/acorn/-/acorn-7.1.1.tgz",
"integrity": "sha512-add7dgA5ppRPxCFJoAGfMDi7PIBXq1RtGo7BhbLaxwrXPOmw8gq48Y9ozT01hUKy9byMjlR20EJhu5zlkErEkg==",
"version": "7.3.1",
"resolved": "https://registry.npmjs.org/acorn/-/acorn-7.3.1.tgz",
"integrity": "sha512-tLc0wSnatxAQHVHUapaHdz72pi9KUyHjq5KyHjGg9Y8Ifdc79pTh2XvI6I1/chZbnM7QtNKzh66ooDogPZSleA==",
"dev": true
},
"acorn-globals": {
@ -769,12 +769,12 @@
"dev": true
},
"code-red": {
"version": "0.1.2",
"resolved": "https://registry.npmjs.org/code-red/-/code-red-0.1.2.tgz",
"integrity": "sha512-GFNCdH1eTXpmZGzG+/w0L60gO35Kf803UPmAIDlD1220EUk+AtfQuvxnyeRzxIa7FXte0aANnQgySGdoU67I3Q==",
"version": "0.1.3",
"resolved": "https://registry.npmjs.org/code-red/-/code-red-0.1.3.tgz",
"integrity": "sha512-3n9i1Jv0om4+2Aq7pCL8M5xRgc2wTXsblsYUxXJDpgBZ3wJP1zbcNzu4XgUqrG0rjc1to2yh+3n9rwHsJa7qSA==",
"dev": true,
"requires": {
"acorn": "^7.1.0",
"acorn": "^7.3.1",
"is-reference": "^1.1.4",
"periscopic": "^2.0.1",
"sourcemap-codec": "^1.4.6"
@ -2250,12 +2250,12 @@
"dev": true
},
"is-reference": {
"version": "1.1.4",
"resolved": "https://registry.npmjs.org/is-reference/-/is-reference-1.1.4.tgz",
"integrity": "sha512-uJA/CDPO3Tao3GTrxYn6AwkM4nUPJiGGYu5+cB8qbC7WGFlrKZbiRo7SFKxUAEpFUfiHofWCXBUNhvYJMh+6zw==",
"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": "0.0.39"
"@types/estree": "*"
}
},
"is-regex": {
@ -2527,9 +2527,9 @@
}
},
"lodash": {
"version": "4.17.15",
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz",
"integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==",
"version": "4.17.19",
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.19.tgz",
"integrity": "sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ==",
"dev": true
},
"lodash.sortby": {

@ -1,6 +1,6 @@
{
"name": "svelte",
"version": "3.23.2",
"version": "3.24.0",
"description": "Cybernetically enhanced web apps",
"module": "index.mjs",
"main": "index",
@ -68,10 +68,10 @@
"@types/node": "^8.10.53",
"@typescript-eslint/eslint-plugin": "^3.0.2",
"@typescript-eslint/parser": "^3.0.2",
"acorn": "^7.1.0",
"acorn": "^7.3.1",
"agadoo": "^1.1.0",
"c8": "^5.0.1",
"code-red": "0.1.2",
"code-red": "^0.1.3",
"codecov": "^3.5.0",
"css-tree": "1.0.0-alpha22",
"eslint": "^7.1.0",

@ -53,6 +53,26 @@ To build the website, run `npm run sapper`. The output can be found in `__sapper
Tests can be run using `npm run test`.
## Linking `@sveltejs/site-kit` and `@sveltejs/site-repl`
This site depends on `@sveltejs/site-kit`, a collection of styles, components and icons used in common by *.svelte.dev websites, and `@sveltejs/site-repl`.
In order to work on features that depend on those packages, you need to [link](https://docs.npmjs.com/cli/link) their repositories:
- `cd <somewhere>`
- `git clone https://github.com/sveltejs/site-kit`
- `git clone https://github.com/sveltejs/svelte-repl`
- `cd <somewhere>/site-kit`
- `npm link`
- `cd <somewhere>/svelte-repl`
- `npm link`
- `cd <svelte-repo>/site`
- `npm link @sveltejs/site-kit`
- `npm link @sveltejs/svelte-repl`
## Translating the API docs
Anchors are automatically generated using headings in the documentation and by default (for the english language) they are latinised to make sure the URL is always conforming to RFC3986.

@ -30,7 +30,7 @@ Given that, what if the framework *didn't actually run in the browser*? What if,
Svelte is a new framework that does exactly that. You write your components using HTML, CSS and JavaScript (plus a few extra bits you can [learn in under 5 minutes](https://v2.svelte.dev/guide)), and during your build process Svelte compiles them into tiny standalone JavaScript modules. By statically analysing the component template, we can make sure that the browser does as little work as possible.
The [Svelte implementation of TodoMVC](http://svelte-todomvc.surge.sh/) weighs 3.6kb zipped. For comparison, React plus ReactDOM *without any app code* weighs about 45kb zipped. It takes about 10x as long for the browser just to evaluate React as it does for Svelte to be up and running with an interactive TodoMVC.
The [Svelte implementation of TodoMVC](https://svelte-todomvc.surge.sh/) weighs 3.6kb zipped. For comparison, React plus ReactDOM *without any app code* weighs about 45kb zipped. It takes about 10x as long for the browser just to evaluate React as it does for Svelte to be up and running with an interactive TodoMVC.
And once your app *is* up and running, according to [js-framework-benchmark](https://github.com/krausest/js-framework-benchmark) **Svelte is fast as heck**. It's faster than React. It's faster than Vue. It's faster than Angular, or Ember, or Ractive, or Preact, or Riot, or Mithril. It's competitive with Inferno, which is probably the fastest UI framework in the world, for now, because [Dominic Gannaway](https://twitter.com/trueadm) is a wizard. (Svelte is slower at removing elements. We're [working on it](https://github.com/sveltejs/svelte/issues/26).)

@ -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.
@ -57,7 +57,7 @@ What about a more 'real world' example? Conveniently, the [RealWorld](https://gi
<aside><p>Code-splitting isn't free — if the reference implementation used code-splitting, it would be larger still</p></aside>
The entire app costs 132.7kb (39.9kb zipped), which is significantly smaller than the reference React/Redux implementation at 327kb (85.7kb), but even if was as large it would *feel* faster because of code-splitting. And that's a crucial point. We're told we need to code-split our apps, but if your app uses a traditional framework like React or Vue then there's a hard lower bound on the size of your initial code-split chunk — the framework itself, which is likely to be a significant portion of your total app size. With the Svelte approach, that's no longer the case.
The entire app costs 132.7kb (39.9kb zipped), which is significantly smaller than the reference React/Redux implementation at 327kb (85.7kb), but even if it was as large it would *feel* faster because of code-splitting. And that's a crucial point. We're told we need to code-split our apps, but if your app uses a traditional framework like React or Vue then there's a hard lower bound on the size of your initial code-split chunk — the framework itself, which is likely to be a significant portion of your total app size. With the Svelte approach, that's no longer the case.
But size is only part of the story. Svelte apps are also extremely performant and memory-efficient, and the framework includes powerful features that you would sacrifice if you chose a 'minimal' or 'simple' UI library.

@ -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
@ -74,8 +74,6 @@ This creates a new directory, `my-svelte-project`, adds files from the [sveltejs
In the `package.json` file, there is a section called `"scripts"`. These scripts define shortcuts for working with your application — `dev`, `build` and `start`. To launch your app in development mode, type the following:
> TODO update the template, it needs... some work
```bash
npm run dev
```

@ -0,0 +1,141 @@
---
title: Svelte <3 TypeScript
description: Typernetically enhanced web apps
author: Orta Therox
authorURL: https://twitter.com/orta
---
It's been by far the most requested feature for a while, and it's finally here: Svelte officially supports TypeScript.
We think it'll give you a much nicer development experience — one that also scales beautifully to larger Svelte code bases — regardless of whether you use TypeScript or JavaScript.
<figure>
<img alt="Screenshot of TypeScript in Svelte" src="media/svelte-ts.png">
<figcaption>Image of TypeScript + Svelte in VS Code (theme is <a href="https://marketplace.visualstudio.com/items?itemName=karyfoundation.theme-karyfoundation-themes">Kary Pro</a>.)</figcaption>
</figure>
## Try it now
You can start a new Svelte TypeScript project using the [normal template](https://github.com/sveltejs/template) and by running `node scripts/setupTypeScript.js` before you do anything else:
```bash
npx degit sveltejs/template svelte-typescript-app
cd svelte-typescript-app
node scripts/setupTypeScript.js
```
If you're a VS Code user, make sure you're using the (new) [official extension](https://marketplace.visualstudio.com/items?itemName=svelte.svelte-vscode), which replaces the popular extension by James Birtles.
Later in this blog post, we'll detail the individual steps involved in using TypeScript in an existing Svelte project.
## What does it mean to support TypeScript in Svelte?
TypeScript support in Svelte has been possible for a long time, but you had to mix a lot of disparate tools together and each project ran independently. Today, nearly all of these tools live under the Svelte organization and are maintained by a set of people who take responsibility over the whole pipeline and have common goals.
A week before COVID was declared a pandemic, [I pitched a consolidation](https://github.com/sveltejs/svelte/issues/4518) of the best Svelte tools and ideas from similar dev-ecosystems and provided a set of steps to get first class TypeScript support. Since then, many people have pitched in and written the code to get us there.
When we say that Svelte now supports TypeScript, we mean a few different things:
* You can use TypeScript inside your `<script>` blocks — just add the `lang="ts"` attribute
* Components with TypeScript can be type-checked with the `svelte-check` command
* You get autocompletion hints and type-checking as you're writing components, even in expressions inside markup
* TypeScript files understand the Svelte component API — no more red squiggles when you import a `.svelte` file into a `.ts` module
#### How does it work?
To understand the two main parts of TypeScript support, we'll compare it to the technique TypeScript uses to provide dev tools. There is a compiler `tsc` which you run on the command-line to convert `*.ts` to `*.js`, then there is a `TSServer` which is a node API that responds to requests from text editors. The `TSServer` is what provides all the JavaScript and TypeScript realtime introspection for editors while coding, and it has most of the compiler's code inside it.
For Svelte, we have the Svelte compiler, and now we have the [`svelte-language-server`](https://github.com/sveltejs/language-tools/tree/master/packages/language-server#svelte-language-server) which responds to text editor calls via the [Language Server Protocol standard](https://microsoft.github.io//language-server-protocol/overviews/lsp/overview/). First class TypeScript support means that _both_ of these two systems do a good job of handling TypeScript code.
The Svelte compiler support for TypeScript is handled by [Christian Kaisermann](https://github.com/kaisermann)'s [`svelte-preprocess`](https://github.com/sveltejs/svelte-preprocess#svelte-preprocess) which is now an official Svelte project.
For the editor level, we took inspiration from [Pine's](https://github.com/octref) work in the [Vue](https://vuejs.org) ecosystem via [Vetur](https://github.com/vuejs/vetur). Vetur provides an [LSP](https://github.com/vuejs/vetur/blob/master/server), a VS Code extension and a [CLI](https://github.com/vuejs/vetur/blob/master/vti). Svelte now also has an [LSP](https://github.com/sveltejs/language-tools/blob/master/packages/language-server), a [VS Code extension](https://github.com/sveltejs/language-tools/blob/master/packages/svelte-vscode) and a [CLI](https://github.com/sveltejs/language-tools/blob/master/packages/svelte-check).
#### `*.svelte` Introspection
For the official Svelte VS Code extension, we built off the foundations which [James Birtles](https://github.com/UnwrittenFun) has created in [`UnwrittenFun/svelte-vscode`](https://github.com/UnwrittenFun/svelte-vscode) and [`UnwrittenFun/svelte-language-server`](https://github.com/UnwrittenFun/svelte-language-server/).
[Simon Holthausen](https://github.com/dummdidumm) and [Lyu, Wei-Da](https://github.com/jasonlyu123) have done great work improving the JavaScript and TypeScript introspection, including integrating [@halfnelson](https://github.com/halfnelson)'s [svelte2tsx](https://github.com/sveltejs/language-tools/tree/master/packages/svelte2tsx#svelte2tsx) which powers understanding the props on components in your codebase.
## Adding TypeScript to an existing project
Before getting started, add the dependencies:
```bash
npm install --save-dev @tsconfig/svelte typescript svelte-preprocess svelte-check
```
##### 1. Compiling TypeScript
You first need to set up [`svelte-preprocess`](https://github.com/sveltejs/svelte-preprocess#svelte-preprocess), which passes the contents of your `<script lang="ts">` blocks through the TypeScript compiler.
In a Rollup project, that would look like this — note that we also need to install `@rollup/plugin-typescript` so that Rollup can handle `.ts` files:
```diff
+ import autoPreprocess from 'svelte-preprocess';
+ import typescript from '@rollup/plugin-typescript';
export default {
...,
plugins: [
svelte({
+ preprocess: autoPreprocess()
}),
+ typescript({ sourceMap: !production })
]
}
```
[Full instructions for other environments here](https://github.com/sveltejs/svelte-preprocess#usage).
To configure TypeScript, you will need to create a `tsconfig.json` in the root of your project:
```json
{
"extends": "@tsconfig/svelte/tsconfig.json",
"include": ["src/**/*", "src/node_modules"],
"exclude": ["node_modules/*", "__sapper__/*", "public/*"],
}
```
Your `include`/`exclude` may differ per project — these are defaults that should work across most Svelte projects.
##### 2. Editor Support
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.
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.
##### 3. CI Checks
Having red squiggles is great, well, kinda. On the long run though, you want to be able to verify that there are no errors in your code. To verify your project is error free, you can use the CLI tool [`svelte-check`](https://www.npmjs.com/package/svelte-check). It acts like an editor asking for errors against all of your `.svelte` files.
You can add the dependency to your project and then add it to CI.
```bash
npx svelte-check
Loading svelte-check in workspace: /Users/ortatherox/dev/svelte/example-app
Getting Svelte diagnostics...
====================================
/Users/ortatherox/dev/svelte/example-app/src/App.svelte:3:2
Error: Type '123' is not assignable to type 'string'. (ts)
====================================
svelte-check found 1 error
error Command failed with exit code 1.
```
## What about TypeScript in Sapper projects?
Watch this space!
## How can I contribute?
We're so glad you asked. The work is happening in the [sveltejs/language-tools](https://github.com/sveltejs/language-tools) repo and in the [#language-tools](https://discord.gg/enV6v8K) channel in the Svelte Discord. If you'd like to report issues, submit fixes, or help out with extensions for new editors and so on, that's where you can find us. See you there!

@ -773,7 +773,7 @@ Actions are functions that are called when an element is created. They can retur
---
An action can have parameters. If the returned value has an `update` method, it will be called whenever those parameters change, immediately after Svelte has applied updates to the markup.
An action can have a parameter. If the returned value has an `update` method, it will be called whenever that parameter changes, immediately after Svelte has applied updates to the markup.
> Don't worry about the fact that we're redeclaring the `foo` function for every component instance — Svelte will hoist any functions that don't depend on local state out of the component definition.

@ -16,16 +16,10 @@
$: remaining = todos.filter(t => !t.done).length;
</script>
<style>
.done {
opacity: 0.4;
}
</style>
<h1>Todos</h1>
{#each todos as todo}
<div class:done={todo.done}>
<div>
<input
type=checkbox
bind:checked={todo.done}
@ -34,6 +28,7 @@
<input
placeholder="What needs to be done?"
bind:value={todo.text}
disabled={todo.done}
>
</div>
{/each}

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

@ -1,5 +1,5 @@
---
question: How can I get VSCode to syntax-highlight my .svelte files?
question: How can I get VS Code to syntax-highlight my .svelte files?
---
There is an [official VSCode extension for Svelte](https://marketplace.visualstudio.com/items?itemName=svelte.svelte-vscode), however it is still in the **beta** testing stage, and not all issues have been ironed out.
There is an [official VS Code extension for Svelte](https://marketplace.visualstudio.com/items?itemName=svelte.svelte-vscode).

@ -0,0 +1,32 @@
---
question: How do I document my components?
---
In editors which use the Svelte Language Server you can document Components, functions and exports using specially formatted comments.
````svelte
<script>
/** What should we call the user? */
export let name = 'world';
</script>
<!--
@component
Here's some documentation for this component.
It will show up on hover.
- You can use markdown here.
- You can also use code blocks here.
- Usage:
```tsx
<main name="Arethra">
```
-->
<main>
<h1>
Hello, {name}
</h1>
</main>
````
Note: The `@component` is necessary in the HTML comment which describes your component.

@ -1,10 +1,11 @@
---
question: What about Typescript support?
question: What about TypeScript support?
---
You need to install a preprocessor such as [svelte-preprocess](https://github.com/sveltejs/svelte-preprocess). Work is ongoing to improve [IDE support](https://github.com/sveltejs/language-tools/issues/83). You can also run type checking from the command line with [svelte-check](https://www.npmjs.com/package/svelte-check).
You need to install a preprocessor such as [svelte-preprocess](https://github.com/sveltejs/svelte-preprocess). You can run type checking from the command line with [svelte-check](https://www.npmjs.com/package/svelte-check).
To declare the type of a reactive variable in a Svelte template, you should use the following syntax:
To declare the type of a reactive variable in a Svelte template, you can use the following syntax:
```
let x: number;
$: x = count + 1;

@ -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}
```
```

@ -1281,9 +1281,9 @@
}
},
"@sveltejs/site-kit": {
"version": "1.1.5",
"resolved": "https://registry.npmjs.org/@sveltejs/site-kit/-/site-kit-1.1.5.tgz",
"integrity": "sha512-Rs2quQ/H00DAN/ZTFa+unLefL335UW3Yo4I2rTocW5JwW73Kvi5++d7BcY8LsjhMCbG1PkwQmJE2RVrIIxQcOw==",
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/@sveltejs/site-kit/-/site-kit-1.2.1.tgz",
"integrity": "sha512-5AhOCBcproHF5UbmuOIB9CiyAmG6BXOr2G4EjeeDz/tyo9myfnRKIgJSy26q8Zlw6TOlwxhzcAgvL5sgZF+IsA==",
"dev": true,
"requires": {
"@sindresorhus/slugify": "^0.9.1",
@ -1291,9 +1291,9 @@
}
},
"@sveltejs/svelte-repl": {
"version": "0.1.19",
"resolved": "https://registry.npmjs.org/@sveltejs/svelte-repl/-/svelte-repl-0.1.19.tgz",
"integrity": "sha512-35R94X6uYgy6PHLQnQCsKcZ4zb6rGGQXjBYqjuCkoCykIlSLx8/avq6BGqudmE5pzVWDP3kk4063cHgccy1xYg==",
"version": "0.2.0",
"resolved": "https://registry.npmjs.org/@sveltejs/svelte-repl/-/svelte-repl-0.2.0.tgz",
"integrity": "sha512-2vLQnOVrsmn2d2K4a6urGm8OulGGSPhZCGNySSb1H8nOPsgKrdcTt5qoaxNYXgcyVp55Yow2SvXYXsyJKd4KEQ==",
"dev": true,
"requires": {
"codemirror": "^5.49.2",
@ -1601,9 +1601,9 @@
"dev": true
},
"codemirror": {
"version": "5.53.2",
"resolved": "https://registry.npmjs.org/codemirror/-/codemirror-5.53.2.tgz",
"integrity": "sha512-wvSQKS4E+P8Fxn/AQ+tQtJnF1qH5UOlxtugFLpubEZ5jcdH2iXTVinb+Xc/4QjshuOxRm4fUsU2QPF1JJKiyXA==",
"version": "5.55.0",
"resolved": "https://registry.npmjs.org/codemirror/-/codemirror-5.55.0.tgz",
"integrity": "sha512-TumikSANlwiGkdF/Blnu/rqovZ0Y3Jh8yy9TqrPbSM0xxSucq3RgnpVDQ+mD9q6JERJEIT2FMuF/fBGfkhIR/g==",
"dev": true
},
"color-convert": {
@ -2404,9 +2404,9 @@
}
},
"lodash": {
"version": "4.17.15",
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz",
"integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==",
"version": "4.17.19",
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.19.tgz",
"integrity": "sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ==",
"dev": true
},
"lodash.deburr": {

@ -36,8 +36,8 @@
"@babel/preset-env": "^7.6.0",
"@babel/runtime": "^7.6.0",
"@sindresorhus/slugify": "^0.9.1",
"@sveltejs/site-kit": "^1.1.5",
"@sveltejs/svelte-repl": "^0.1.19",
"@sveltejs/site-kit": "^1.2.1",
"@sveltejs/svelte-repl": "^0.2.0",
"degit": "^2.1.4",
"dotenv": "^8.1.0",
"esm": "^3.2.25",

@ -137,6 +137,15 @@
top: calc((var(--h3) - 24px) / 2);
}
.post :global(a) {
padding: 0;
transition: none;
}
.post :global(a):not(:hover) {
border: none;
}
@media (max-width: 768px) {
.post :global(.anchor) {
transform: scale(0.6);

@ -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('')}

@ -85,7 +85,7 @@ export default function() {
renderer.heading = (text, level, rawtext) => {
let slug;
const match = /<a href="([^"]+)">(.+)<\/a>/.exec(text);
const match = /<a href="([^"]+)"[^>]*>(.+)<\/a>/.exec(text);
if (match) {
slug = match[1];
text = match[2];

@ -227,6 +227,7 @@ export default app;` });
padding: .6rem var(--side-nav);
background-color: var(--second);
color: white;
white-space: nowrap;
}
.icon {

@ -1,6 +1,7 @@
import { langs } from '@sveltejs/site-kit/utils/markdown.js';
import PrismJS from 'prismjs';
import 'prismjs/components/prism-bash';
import 'prismjs/components/prism-diff';
import 'prism-svelte';
export function highlight(source, lang) {

Binary file not shown.

After

Width:  |  Height:  |  Size: 185 KiB

@ -836,7 +836,7 @@ export default class Component {
});
}
warn_on_undefined_store_value_references(node, parent, scope) {
warn_on_undefined_store_value_references(node, parent, scope: Scope) {
if (
node.type === 'LabeledStatement' &&
node.label.name === '$' &&
@ -852,8 +852,17 @@ export default class Component {
const object = get_object(node);
const { name } = object;
if (name[0] === '$' && !scope.has(name)) {
this.warn_if_undefined(name, object, null);
if (name[0] === '$') {
if (!scope.has(name)) {
this.warn_if_undefined(name, object, null);
}
if (name[1] !== '$' && scope.has(name.slice(1)) && scope.find_owner(name.slice(1)) !== this.instance_scope) {
this.error(node, {
code: `contextual-store`,
message: `Stores must be declared at the top level of the component (this may change in a future version of Svelte)`
});
}
}
}
}

@ -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',

@ -61,6 +61,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([
@ -507,6 +518,15 @@ 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')) {

@ -1,5 +1,5 @@
import { x } from 'code-red';
import { Node, Identifier, RestElement, Property } from 'estree';
import { Node, Identifier } from 'estree';
export interface Context {
key: Identifier;
@ -34,12 +34,10 @@ export function unpack_destructuring(contexts: Context[], node: Node, modifier:
const used_properties = [];
node.properties.forEach((property) => {
const props: (RestElement | Property) = (property as any);
if (props.type === 'RestElement') {
if (property.type === 'RestElement') {
unpack_destructuring(
contexts,
props.argument,
property.argument,
node => x`@object_without_properties(${modifier(node)}, [${used_properties}])` as Node
);
} else {

@ -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;
@ -75,14 +75,18 @@ export default class Expression {
if (is_reference(node, parent)) {
const { name, nodes } = flatten_reference(node);
references.add(name);
if (scope.has(name)) return;
if (name[0] === '$' && template_scope.names.has(name.slice(1))) {
component.error(node, {
code: `contextual-store`,
message: `Stores must be declared at the top level of the component (this may change in a future version of Svelte)`
});
if (name[0] === '$') {
const store_name = name.slice(1);
if (template_scope.names.has(store_name) || scope.has(store_name)) {
component.error(node, {
code: `contextual-store`,
message: `Stores must be declared at the top level of the component (this may change in a future version of Svelte)`
});
}
}
if (template_scope.is_let(name)) {
@ -198,7 +202,7 @@ export default class Expression {
scope = map.get(node);
}
if (is_reference(node, parent)) {
if (node.type === 'Identifier' && is_reference(node, parent)) {
const { name } = flatten_reference(node);
if (scope.has(name)) return;

@ -420,7 +420,7 @@ export default function dom(
${component.partly_hoisted}
${set && b`$$self.$set = ${set};`}
${set && b`$$self.$$set = ${set};`}
${capture_state && b`$$self.$capture_state = ${capture_state};`}

@ -298,6 +298,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 +318,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});
}
`);

@ -7,8 +7,9 @@ import { b, x } from 'code-red';
import Expression from '../../../nodes/shared/Expression';
import Text from '../../../nodes/Text';
import handle_select_value_binding from './handle_select_value_binding';
import { Identifier, Node } from 'estree';
export default class AttributeWrapper {
export class BaseAttributeWrapper {
node: Attribute;
parent: ElementWrapper;
@ -21,7 +22,29 @@ export default class AttributeWrapper {
parent.not_static_content();
block.add_dependencies(node.dependencies);
}
}
render(_block: Block) {}
}
export default class AttributeWrapper extends BaseAttributeWrapper {
node: Attribute;
parent: ElementWrapper;
metadata: any;
name: string;
property_name: string;
is_indirectly_bound_value: boolean;
is_src: boolean;
is_select_value_attribute: boolean;
is_input_value: boolean;
should_cache: boolean;
last: Identifier;
constructor(parent: ElementWrapper, block: Block, node: Attribute) {
super(parent, block, node);
if (node.dependencies.size > 0) {
// special case — <option value={foo}> — see below
if (this.parent.node.name === 'option' && node.name === 'value') {
let select: ElementWrapper = this.parent;
@ -42,31 +65,22 @@ export default class AttributeWrapper {
handle_select_value_binding(this, node.dependencies);
}
}
}
is_indirectly_bound_value() {
const element = this.parent;
const name = fix_attribute_casing(this.node.name);
return name === 'value' &&
(element.node.name === 'option' || // TODO check it's actually bound
(element.node.name === 'input' &&
element.node.bindings.some(
(binding) =>
/checked|group/.test(binding.name)
)));
this.name = fix_attribute_casing(this.node.name);
this.metadata = this.get_metadata();
this.is_indirectly_bound_value = is_indirectly_bound_value(this);
this.property_name = this.is_indirectly_bound_value
? '__value'
: this.metadata && this.metadata.property_name;
this.is_src = this.name === 'src'; // TODO retire this exception in favour of https://github.com/sveltejs/svelte/issues/3750
this.is_select_value_attribute = this.name === 'value' && this.parent.node.name === 'select';
this.is_input_value = this.name === 'value' && this.parent.node.name === 'input';
this.should_cache = should_cache(this);
}
render(block: Block) {
const element = this.parent;
const name = fix_attribute_casing(this.node.name);
const metadata = this.get_metadata();
const is_indirectly_bound_value = this.is_indirectly_bound_value();
const property_name = is_indirectly_bound_value
? '__value'
: metadata && metadata.property_name;
const { name, property_name, should_cache, is_indirectly_bound_value } = this;
// xlink is a special case... we could maybe extend this to generic
// namespaced attributes but I'm not sure that's applicable in
@ -82,29 +96,15 @@ export default class AttributeWrapper {
const dependencies = this.get_dependencies();
const value = this.get_value(block);
const is_src = this.node.name === 'src'; // TODO retire this exception in favour of https://github.com/sveltejs/svelte/issues/3750
const is_select_value_attribute =
name === 'value' && element.node.name === 'select';
const is_input_value = name === 'value' && element.node.name === 'input';
const should_cache = is_src || this.node.should_cache();
const last = should_cache && block.get_unique_name(
`${element.var.name}_${name.replace(/[^a-zA-Z_$]/g, '_')}_value`
);
if (should_cache) block.add_variable(last);
let updater;
const init = should_cache ? x`${last} = ${value}` : value;
const init = this.get_init(block, value);
if (is_legacy_input_type) {
block.chunks.hydrate.push(
b`@set_input_type(${element.var}, ${init});`
);
updater = b`@set_input_type(${element.var}, ${should_cache ? last : value});`;
} else if (is_select_value_attribute) {
updater = b`@set_input_type(${element.var}, ${should_cache ? this.last : value});`;
} else if (this.is_select_value_attribute) {
// annoying special case
const is_multiple_select = element.node.get_static_attribute_value('multiple');
@ -117,45 +117,37 @@ export default class AttributeWrapper {
block.chunks.mount.push(b`
${updater}
`);
} else if (is_src) {
} else if (this.is_src) {
block.chunks.hydrate.push(
b`if (${element.var}.src !== ${init}) ${method}(${element.var}, "${name}", ${last});`
b`if (${element.var}.src !== ${init}) ${method}(${element.var}, "${name}", ${this.last});`
);
updater = b`${method}(${element.var}, "${name}", ${should_cache ? last : value});`;
updater = b`${method}(${element.var}, "${name}", ${should_cache ? this.last : value});`;
} else if (property_name) {
block.chunks.hydrate.push(
b`${element.var}.${property_name} = ${init};`
);
updater = block.renderer.options.dev
? b`@prop_dev(${element.var}, "${property_name}", ${should_cache ? last : value});`
: b`${element.var}.${property_name} = ${should_cache ? last : value};`;
? b`@prop_dev(${element.var}, "${property_name}", ${should_cache ? this.last : value});`
: b`${element.var}.${property_name} = ${should_cache ? this.last : value};`;
} else {
block.chunks.hydrate.push(
b`${method}(${element.var}, "${name}", ${init});`
);
updater = b`${method}(${element.var}, "${name}", ${should_cache ? last : value});`;
updater = b`${method}(${element.var}, "${name}", ${should_cache ? this.last : value});`;
}
if (dependencies.length > 0) {
let condition = block.renderer.dirty(dependencies);
if (should_cache) {
condition = is_src
? x`${condition} && (${element.var}.src !== (${last} = ${value}))`
: x`${condition} && (${last} !== (${last} = ${value}))`;
}
if (is_input_value) {
const type = element.node.get_static_attribute_value('type');
if (is_indirectly_bound_value) {
const update_value = b`${element.var}.value = ${element.var}.__value;`;
block.chunks.hydrate.push(update_value);
if (type === null || type === "" || type === "text" || type === "email" || type === "password") {
condition = x`${condition} && ${element.var}.${property_name} !== ${should_cache ? last : value}`;
}
}
updater = b`
${updater}
${update_value};
`;
}
if (block.has_outros) {
condition = x`!#current || ${condition}`;
}
if (dependencies.length > 0) {
const condition = this.get_dom_update_conditions(block, block.renderer.dirty(dependencies));
block.chunks.update.push(b`
if (${condition}) {
@ -167,13 +159,44 @@ export default class AttributeWrapper {
if (this.node.is_true && name === 'autofocus') {
block.autofocus = element.var;
}
}
if (is_indirectly_bound_value) {
const update_value = b`${element.var}.value = ${element.var}.__value;`;
get_init(block: Block, value) {
this.last = this.should_cache && block.get_unique_name(
`${this.parent.var.name}_${this.name.replace(/[^a-zA-Z_$]/g, '_')}_value`
);
block.chunks.hydrate.push(update_value);
if (dependencies.length > 0) block.chunks.update.push(update_value);
if (this.should_cache) block.add_variable(this.last);
return this.should_cache ? x`${this.last} = ${value}` : value;
}
get_dom_update_conditions(block: Block, dependency_condition: Node) {
const { property_name, should_cache, last } = this;
const element = this.parent;
const value = this.get_value(block);
let condition = dependency_condition;
if (should_cache) {
condition = this.is_src
? x`${condition} && (${element.var}.src !== (${last} = ${value}))`
: x`${condition} && (${last} !== (${last} = ${value}))`;
}
if (this.is_input_value) {
const type = element.node.get_static_attribute_value('type');
if (type === null || type === "" || type === "text" || type === "email" || type === "password") {
condition = x`${condition} && ${element.var}.${property_name} !== ${should_cache ? last : value}`;
}
}
if (block.has_outros) {
condition = x`!#current || ${condition}`;
}
return condition;
}
get_dependencies() {
@ -194,15 +217,14 @@ export default class AttributeWrapper {
get_metadata() {
if (this.parent.node.namespace) return null;
const metadata = attribute_lookup[fix_attribute_casing(this.node.name)];
const metadata = attribute_lookup[this.name];
if (metadata && metadata.applies_to && !metadata.applies_to.includes(this.parent.node.name)) return null;
return metadata;
}
get_value(block) {
if (this.node.is_true) {
const metadata = this.get_metadata();
if (metadata && boolean_attribute.has(metadata.property_name.toLowerCase())) {
if (this.metadata && boolean_attribute.has(this.metadata.property_name.toLowerCase())) {
return x`true`;
}
return x`""`;
@ -350,4 +372,19 @@ const boolean_attribute = new Set([
'required',
'reversed',
'selected'
]);
]);
function should_cache(attribute: AttributeWrapper) {
return attribute.is_src || attribute.node.should_cache();
}
function is_indirectly_bound_value(attribute: AttributeWrapper) {
const element = attribute.parent;
return attribute.name === 'value' &&
(element.node.name === 'option' || // TODO check it's actually bound
(element.node.name === 'input' &&
element.node.bindings.some(
(binding) =>
/checked|group/.test(binding.name)
)));
}

@ -0,0 +1,3 @@
import { BaseAttributeWrapper } from "./Attribute";
export default class SpreadAttributeWrapper extends BaseAttributeWrapper {}

@ -11,6 +11,7 @@ import { b, x, p } from 'code-red';
import { namespaces } from '../../../../utils/namespaces';
import AttributeWrapper from './Attribute';
import StyleAttributeWrapper from './StyleAttribute';
import SpreadAttributeWrapper from './SpreadAttribute';
import { dimensions } from '../../../../utils/patterns';
import Binding from './Binding';
import InlineComponentWrapper from '../InlineComponent';
@ -137,7 +138,7 @@ const events = [
export default class ElementWrapper extends Wrapper {
node: Element;
fragment: FragmentWrapper;
attributes: AttributeWrapper[];
attributes: Array<AttributeWrapper | StyleAttributeWrapper | SpreadAttributeWrapper>;
bindings: Binding[];
event_handlers: EventHandler[];
class_dependencies: string[];
@ -221,6 +222,9 @@ export default class ElementWrapper extends Wrapper {
if (attribute.name === 'style') {
return new StyleAttributeWrapper(this, block, attribute);
}
if (attribute.type === 'Spread') {
return new SpreadAttributeWrapper(this, block, attribute);
}
return new AttributeWrapper(this, block, attribute);
});
@ -418,7 +422,7 @@ export default class ElementWrapper extends Wrapper {
return x`@_document.createElementNS("${namespace}", "${name}")`;
}
const is = this.attributes.find(attr => attr.node.name === 'is');
const is: AttributeWrapper = this.attributes.find(attr => attr.node.name === 'is') as any;
if (is) {
return x`@element_is("${name}", ${is.render_chunks(block).reduce((lhs, rhs) => x`${lhs} + ${rhs}`)})`;
}
@ -664,25 +668,24 @@ export default class ElementWrapper extends Wrapper {
this.attributes
.forEach(attr => {
const condition = attr.node.dependencies.size > 0
? block.renderer.dirty(Array.from(attr.node.dependencies))
const dependencies = attr.node.get_dependencies();
const condition = dependencies.length > 0
? block.renderer.dirty(dependencies)
: null;
if (attr.node.is_spread) {
if (attr instanceof SpreadAttributeWrapper) {
const snippet = attr.node.expression.manipulate(block);
initial_props.push(snippet);
updates.push(condition ? x`${condition} && ${snippet}` : snippet);
} else {
const metadata = attr.get_metadata();
const name = attr.is_indirectly_bound_value()
? '__value'
: (metadata && metadata.property_name) || fix_attribute_casing(attr.node.name);
const snippet = x`{ ${name}: ${attr.get_value(block)} }`;
initial_props.push(snippet);
const name = attr.property_name || attr.name;
initial_props.push(x`{ ${name}: ${attr.get_init(block, attr.get_value(block))} }`);
const snippet = x`{ ${name}: ${attr.should_cache ? attr.last : attr.get_value(block)} }`;
updates.push(condition ? x`${condition} && ${snippet}` : snippet);
updates.push(condition ? x`${attr.get_dom_update_conditions(block, condition)} && ${snippet}` : snippet);
}
});

@ -468,7 +468,7 @@ export default class InlineComponentWrapper extends Wrapper {
${name} = null;
}
} else if (${switch_value}) {
${updates.length && b`${name}.$set(${name_changes});`}
${updates.length > 0 && b`${name}.$set(${name_changes});`}
}
`);

@ -51,7 +51,7 @@ export default class RawMustacheTagWrapper extends Tag {
content => x`${html_tag}.p(${content})`
);
const update_anchor = in_head ? 'null' : needs_anchor ? html_anchor : this.next ? this.next.var : 'null';
const update_anchor = needs_anchor ? html_anchor : this.next ? this.next.var : 'null';
block.chunks.hydrate.push(b`${html_tag} = new @HtmlTag(${update_anchor});`);
block.chunks.mount.push(b`${html_tag}.m(${init}, ${parent_node || '#target'}, ${parent_node ? null : '#anchor'});`);

@ -7,6 +7,7 @@ import { b, p, x } from 'code-red';
import { sanitize } from '../../../utils/names';
import add_to_set from '../../utils/add_to_set';
import get_slot_data from '../../utils/get_slot_data';
import { is_reserved_keyword } from '../../utils/reserved_keywords';
import Expression from '../../nodes/shared/Expression';
import is_dynamic from './shared/is_dynamic';
import { Identifier, ObjectExpression } from 'estree';
@ -94,11 +95,7 @@ export default class SlotWrapper extends Wrapper {
}
});
const dynamic_dependencies = Array.from(attribute.dependencies).filter(name => {
if (this.node.scope.is_let(name)) return true;
const variable = renderer.component.var_lookup.get(name);
return is_dynamic(variable);
});
const dynamic_dependencies = Array.from(attribute.dependencies).filter((name) => this.is_dependency_dynamic(name));
if (dynamic_dependencies.length > 0) {
changes.properties.push(p`${attribute.name}: ${renderer.dirty(dynamic_dependencies)}`);
@ -157,17 +154,10 @@ export default class SlotWrapper extends Wrapper {
b`@transition_out(${slot_or_fallback}, #local);`
);
const is_dependency_dynamic = name => {
if (name === '$$scope') return true;
if (this.node.scope.is_let(name)) return true;
const variable = renderer.component.var_lookup.get(name);
return is_dynamic(variable);
};
const dynamic_dependencies = Array.from(this.dependencies).filter(is_dependency_dynamic);
const dynamic_dependencies = Array.from(this.dependencies).filter((name) => this.is_dependency_dynamic(name));
const fallback_dynamic_dependencies = has_fallback
? Array.from(this.fallback.dependencies).filter(is_dependency_dynamic)
? Array.from(this.fallback.dependencies).filter((name) => this.is_dependency_dynamic(name))
: [];
const slot_update = b`
@ -201,4 +191,12 @@ export default class SlotWrapper extends Wrapper {
b`if (${slot_or_fallback}) ${slot_or_fallback}.d(detaching);`
);
}
is_dependency_dynamic(name: string) {
if (name === '$$scope') return true;
if (this.node.scope.is_let(name)) return true;
if (is_reserved_keyword(name)) return true;
const variable = this.renderer.component.var_lookup.get(name);
return is_dynamic(variable);
}
}

@ -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`

@ -8,6 +8,12 @@ import error from '../utils/error';
type ParserState = (parser: Parser) => (ParserState | void);
interface LastAutoClosedTag {
tag: string;
reason: string;
depth: number;
}
export class Parser {
readonly template: string;
readonly filename?: string;
@ -20,6 +26,7 @@ export class Parser {
css: Style[] = [];
js: Script[] = [];
meta_tags = {};
last_auto_closed_tag?: LastAutoClosedTag;
constructor(template: string, options: ParserOptions) {
if (typeof template !== 'string') {

@ -133,11 +133,15 @@ export default function tag(parser: Parser) {
// close any elements that don't have their own closing tags, e.g. <div><p></div>
while (parent.name !== name) {
if (parent.type !== 'Element')
if (parent.type !== 'Element') {
const message = parser.last_auto_closed_tag && parser.last_auto_closed_tag.tag === name
? `</${name}> attempted to close <${name}> that was already automatically closed by <${parser.last_auto_closed_tag.reason}>`
: `</${name}> attempted to close an element that was not open`;
parser.error({
code: `invalid-closing-tag`,
message: `</${name}> attempted to close an element that was not open`
message
}, start);
}
parent.end = start;
parser.stack.pop();
@ -148,10 +152,19 @@ export default function tag(parser: Parser) {
parent.end = parser.index;
parser.stack.pop();
if (parser.last_auto_closed_tag && parser.stack.length < parser.last_auto_closed_tag.depth) {
parser.last_auto_closed_tag = null;
}
return;
} else if (closing_tag_omitted(parent.name, name)) {
parent.end = start;
parser.stack.pop();
parser.last_auto_closed_tag = {
tag: parent.name,
reason: name,
depth: parser.stack.length,
};
}
const unique_names: Set<string> = new Set();

@ -94,8 +94,8 @@ export default async function preprocess(
for (const fn of script) {
source = await replace_async(
source,
/<!--[^]*?-->|<script(\s[^]*?)?>([^]*?)<\/script>/gi,
async (match, attributes = '', content) => {
/<!--[^]*?-->|<script(\s[^]*?)?(?:>([^]*?)<\/script>|\/>)/gi,
async (match, attributes = '', content = '') => {
if (!attributes && !content) {
return match;
}
@ -114,8 +114,8 @@ export default async function preprocess(
for (const fn of style) {
source = await replace_async(
source,
/<!--[^]*?-->|<style(\s[^]*?)?>([^]*?)<\/style>/gi,
async (match, attributes = '', content) => {
/<!--[^]*?-->|<style(\s[^]*?)?(?:>([^]*?)<\/style>|\/>)/gi,
async (match, attributes = '', content = '') => {
if (!attributes && !content) {
return match;
}

@ -11,9 +11,9 @@ export interface AnimationConfig {
}
interface FlipParams {
delay: number;
duration: number | ((len: number) => number);
easing: (t: number) => number;
delay?: number;
duration?: number | ((len: number) => number);
easing?: (t: number) => number;
}
export function flip(node: Element, animation: { from: DOMRect; to: DOMRect }, params: FlipParams): AnimationConfig {

@ -1,6 +1,6 @@
import { add_render_callback, flush, schedule_update, dirty_components } from './scheduler';
import { current_component, set_current_component } from './lifecycle';
import { blank_object, is_function, run, run_all, noop } from './utils';
import { blank_object, is_empty, is_function, run, run_all, noop } from './utils';
import { children, detach } from './dom';
import { transition_in } from './transitions';
@ -33,6 +33,7 @@ interface T$$ {
context: Map<any, any>;
on_mount: any[];
on_destroy: any[];
skip_bound: boolean;
}
export function bind(component, name, callback) {
@ -120,7 +121,8 @@ export function init(component, options, instance, create_fragment, not_equal, p
// everything else
callbacks: blank_object(),
dirty
dirty,
skip_bound: false
};
let ready = false;
@ -129,7 +131,7 @@ export function init(component, options, instance, create_fragment, not_equal, p
? instance(component, prop_values, (i, ret, ...rest) => {
const value = rest.length ? rest[0] : ret;
if ($$.ctx && not_equal($$.ctx[i], $$.ctx[i] = value)) {
if ($$.bound[i]) $$.bound[i](value);
if (!$$.skip_bound && $$.bound[i]) $$.bound[i](value);
if (ready) make_dirty(component, i);
}
return ret;
@ -166,6 +168,7 @@ export let SvelteElement;
if (typeof HTMLElement === 'function') {
SvelteElement = class extends HTMLElement {
$$: T$$;
$$set?: ($$props: any) => void;
constructor() {
super();
this.attachShadow({ mode: 'open' });
@ -199,14 +202,19 @@ if (typeof HTMLElement === 'function') {
};
}
$set() {
// overridden by instance, if it has props
$set($$props) {
if (this.$$set && !is_empty($$props)) {
this.$$.skip_bound = true;
this.$$set($$props);
this.$$.skip_bound = false;
}
}
};
}
export class SvelteComponent {
$$: T$$;
$$set?: ($$props: any) => void;
$destroy() {
destroy_component(this, 1);
@ -223,7 +231,11 @@ export class SvelteComponent {
};
}
$set() {
// overridden by instance, if it has props
$set($$props) {
if (this.$$set && !is_empty($$props)) {
this.$$.skip_bound = true;
this.$$set($$props);
this.$$.skip_bound = false;
}
}
}

@ -73,7 +73,7 @@ export function dataset_dev(node: HTMLElement, property: string, value?: any) {
export function set_data_dev(text, data) {
data = '' + data;
if (text.data === data) return;
if (text.wholeText === data) return;
dispatch_dev("SvelteDOMSetData", { node: text, data });
text.data = data;

@ -193,7 +193,7 @@ export function claim_space(nodes) {
export function set_data(text, data) {
data = '' + data;
if (text.data !== data) text.data = data;
if (text.wholeText !== data) text.data = data;
}
export function set_input_value(input, value) {

@ -44,11 +44,11 @@ export function createEventDispatcher() {
};
}
export function setContext(key, context) {
export function setContext<T>(key, context: T) {
get_current_component().$$.context.set(key, context);
}
export function getContext(key) {
export function getContext<T>(key): T {
return get_current_component().$$.context.get(key);
}

@ -42,6 +42,10 @@ export function not_equal(a, b) {
return a != a ? b == b : a !== b;
}
export function is_empty(obj) {
return Object.keys(obj).length === 0;
}
export function validate_store(store, name) {
if (store != null && typeof store.subscribe !== 'function') {
throw new Error(`'${name}' is not a store with a 'subscribe' method`);

@ -12,11 +12,11 @@ export interface TransitionConfig {
}
interface BlurParams {
delay: number;
duration: number;
delay?: number;
duration?: number;
easing?: EasingFunction;
amount: number;
opacity: number;
amount?: number;
opacity?: number;
}
export function blur(node: Element, {
@ -41,9 +41,9 @@ export function blur(node: Element, {
}
interface FadeParams {
delay: number;
duration: number;
easing: EasingFunction;
delay?: number;
duration?: number;
easing?: EasingFunction;
}
export function fade(node: Element, {
@ -62,12 +62,12 @@ export function fade(node: Element, {
}
interface FlyParams {
delay: number;
duration: number;
easing: EasingFunction;
x: number;
y: number;
opacity: number;
delay?: number;
duration?: number;
easing?: EasingFunction;
x?: number;
y?: number;
opacity?: number;
}
export function fly(node: Element, {
@ -95,9 +95,9 @@ export function fly(node: Element, {
}
interface SlideParams {
delay: number;
duration: number;
easing: EasingFunction;
delay?: number;
duration?: number;
easing?: EasingFunction;
}
export function slide(node: Element, {
@ -133,11 +133,11 @@ export function slide(node: Element, {
}
interface ScaleParams {
delay: number;
duration: number;
easing: EasingFunction;
start: number;
opacity: number;
delay?: number;
duration?: number;
easing?: EasingFunction;
start?: number;
opacity?: number;
}
export function scale(node: Element, {
@ -166,10 +166,10 @@ export function scale(node: Element, {
}
interface DrawParams {
delay: number;
speed: number;
duration: number | ((len: number) => number);
easing: EasingFunction;
delay?: number;
speed?: number;
duration?: number | ((len: number) => number);
easing?: EasingFunction;
}
export function draw(node: SVGElement & { getTotalLength(): number }, {
@ -199,9 +199,9 @@ export function draw(node: SVGElement & { getTotalLength(): number }, {
}
interface CrossfadeParams {
delay: number;
duration: number | ((len: number) => number);
easing: EasingFunction;
delay?: number;
duration?: number | ((len: number) => number);
easing?: EasingFunction;
}
type ClientRectMap = Map<any, { rect: ClientRect }>;

@ -55,7 +55,7 @@ function instance($$self, $$props, $$invalidate) {
let { bar } = $$props;
const foo_function = () => handleFoo(bar);
$$self.$set = $$props => {
$$self.$$set = $$props => {
if ("bar" in $$props) $$invalidate(0, bar = $$props.bar);
};

@ -52,7 +52,7 @@ function instance($$self, $$props, $$invalidate) {
$$invalidate(0, open);
}
$$self.$set = $$props => {
$$self.$$set = $$props => {
if ("open" in $$props) $$invalidate(0, open = $$props.open);
};

@ -46,7 +46,7 @@ function instance($$self, $$props, $$invalidate) {
$$invalidate(1, h);
}
$$self.$set = $$props => {
$$self.$$set = $$props => {
if ("w" in $$props) $$invalidate(0, w = $$props.w);
if ("h" in $$props) $$invalidate(1, h = $$props.h);
};

@ -68,7 +68,7 @@ function instance($$self, $$props, $$invalidate) {
$$invalidate(0, files);
}
$$self.$set = $$props => {
$$self.$$set = $$props => {
if ("files" in $$props) $$invalidate(0, files = $$props.files);
};

@ -118,7 +118,7 @@ function instance($$self, $$props, $$invalidate) {
let { $$slots = {}, $$scope } = $$props;
validate_slots("Component", $$slots, []);
$$self.$set = $$props => {
$$self.$$set = $$props => {
if ("prop" in $$props) $$subscribe_prop($$invalidate(0, prop = $$props.prop));
if ("alias" in $$props) $$invalidate(1, realName = $$props.alias);
};

@ -48,7 +48,7 @@ function create_fragment(ctx) {
function instance($$self, $$props, $$invalidate) {
let { foo = 42 } = $$props;
$$self.$set = $$props => {
$$self.$$set = $$props => {
if ("foo" in $$props) $$invalidate(0, foo = $$props.foo);
};

@ -12,7 +12,7 @@ function instance($$self, $$props, $$invalidate) {
return x * 3;
}
$$self.$set = $$props => {
$$self.$$set = $$props => {
if ("x" in $$props) $$invalidate(0, x = $$props.x);
};

@ -47,7 +47,7 @@ function create_fragment(ctx) {
function instance($$self, $$props, $$invalidate) {
let { bar } = $$props;
$$self.$set = $$props => {
$$self.$$set = $$props => {
if ("bar" in $$props) $$invalidate(0, bar = $$props.bar);
};

@ -79,7 +79,7 @@ function instance($$self, $$props, $$invalidate) {
let { $$slots = {}, $$scope } = $$props;
validate_slots("Component", $$slots, []);
$$self.$set = $$props => {
$$self.$$set = $$props => {
if ("name" in $$props) $$invalidate(0, name = $$props.name);
};

@ -183,7 +183,7 @@ function instance($$self, $$props, $$invalidate) {
let { $$slots = {}, $$scope } = $$props;
validate_slots("Component", $$slots, []);
$$self.$set = $$props => {
$$self.$$set = $$props => {
if ("things" in $$props) $$invalidate(0, things = $$props.things);
if ("foo" in $$props) $$invalidate(1, foo = $$props.foo);
if ("bar" in $$props) $$invalidate(2, bar = $$props.bar);

@ -175,7 +175,7 @@ function instance($$self, $$props, $$invalidate) {
let { $$slots = {}, $$scope } = $$props;
validate_slots("Component", $$slots, []);
$$self.$set = $$props => {
$$self.$$set = $$props => {
if ("things" in $$props) $$invalidate(0, things = $$props.things);
if ("foo" in $$props) $$invalidate(1, foo = $$props.foo);
};

@ -104,7 +104,7 @@ function create_fragment(ctx) {
function instance($$self, $$props, $$invalidate) {
let { createElement } = $$props;
$$self.$set = $$props => {
$$self.$$set = $$props => {
if ("createElement" in $$props) $$invalidate(0, createElement = $$props.createElement);
};

@ -10,7 +10,7 @@ function instance($$self, $$props, $$invalidate) {
alert(JSON.stringify(data()));
});
$$self.$set = $$props => {
$$self.$$set = $$props => {
if ("foo" in $$props) $$invalidate(0, foo = $$props.foo);
};

@ -76,7 +76,7 @@ function instance($$self, $$props, $$invalidate) {
let { $$slots = {}, $$scope } = $$props;
validate_slots("Component", $$slots, []);
$$self.$set = $$props => {
$$self.$$set = $$props => {
if ("foo" in $$props) $$invalidate(0, foo = $$props.foo);
};

@ -106,7 +106,7 @@ function instance($$self, $$props, $$invalidate) {
let { d } = $$props;
let { e } = $$props;
$$self.$set = $$props => {
$$self.$$set = $$props => {
if ("a" in $$props) $$invalidate(0, a = $$props.a);
if ("b" in $$props) $$invalidate(1, b = $$props.b);
if ("c" in $$props) $$invalidate(2, c = $$props.c);

@ -152,7 +152,7 @@ function instance($$self, $$props, $$invalidate) {
let { time } = $$props;
let { foo } = $$props;
$$self.$set = $$props => {
$$self.$$set = $$props => {
if ("comments" in $$props) $$invalidate(0, comments = $$props.comments);
if ("elapsed" in $$props) $$invalidate(1, elapsed = $$props.elapsed);
if ("time" in $$props) $$invalidate(2, time = $$props.time);

@ -128,7 +128,7 @@ function foo(node, animation, params) {
function instance($$self, $$props, $$invalidate) {
let { things } = $$props;
$$self.$set = $$props => {
$$self.$$set = $$props => {
if ("things" in $$props) $$invalidate(0, things = $$props.things);
};

@ -97,7 +97,7 @@ function create_fragment(ctx) {
function instance($$self, $$props, $$invalidate) {
let { things } = $$props;
$$self.$set = $$props => {
$$self.$$set = $$props => {
if ("things" in $$props) $$invalidate(0, things = $$props.things);
};

@ -88,7 +88,7 @@ function create_fragment(ctx) {
function instance($$self, $$props, $$invalidate) {
let { foo } = $$props;
$$self.$set = $$props => {
$$self.$$set = $$props => {
if ("foo" in $$props) $$invalidate(0, foo = $$props.foo);
};

@ -66,7 +66,7 @@ function create_fragment(ctx) {
function instance($$self, $$props, $$invalidate) {
let { foo } = $$props;
$$self.$set = $$props => {
$$self.$$set = $$props => {
if ("foo" in $$props) $$invalidate(0, foo = $$props.foo);
};

@ -44,7 +44,7 @@ function instance($$self, $$props, $$invalidate) {
let { x } = $$props;
let { y } = $$props;
$$self.$set = $$props => {
$$self.$$set = $$props => {
if ("color" in $$props) $$invalidate(0, color = $$props.color);
if ("x" in $$props) $$invalidate(1, x = $$props.x);
if ("y" in $$props) $$invalidate(2, y = $$props.y);

@ -37,7 +37,7 @@ function create_fragment(ctx) {
function instance($$self, $$props, $$invalidate) {
let { data } = $$props;
$$self.$set = $$props => {
$$self.$$set = $$props => {
if ("data" in $$props) $$invalidate(0, data = $$props.data);
};

@ -37,7 +37,7 @@ function create_fragment(ctx) {
function instance($$self, $$props, $$invalidate) {
let { color } = $$props;
$$self.$set = $$props => {
$$self.$$set = $$props => {
if ("color" in $$props) $$invalidate(0, color = $$props.color);
};

@ -54,7 +54,7 @@ function instance($$self, $$props, $$invalidate) {
let { key } = $$props;
let { value } = $$props;
$$self.$set = $$props => {
$$self.$$set = $$props => {
if ("style" in $$props) $$invalidate(0, style = $$props.style);
if ("key" in $$props) $$invalidate(1, key = $$props.key);
if ("value" in $$props) $$invalidate(2, value = $$props.value);

@ -49,7 +49,7 @@ function instance($$self, $$props, $$invalidate) {
$$invalidate(0, files);
}
$$self.$set = $$props => {
$$self.$$set = $$props => {
if ("files" in $$props) $$invalidate(0, files = $$props.files);
};

@ -60,7 +60,7 @@ function instance($$self, $$props, $$invalidate) {
$$invalidate(0, value);
}
$$self.$set = $$props => {
$$self.$$set = $$props => {
if ("value" in $$props) $$invalidate(0, value = $$props.value);
};

@ -53,7 +53,7 @@ function instance($$self, $$props, $$invalidate) {
$$invalidate(0, foo);
}
$$self.$set = $$props => {
$$self.$$set = $$props => {
if ("foo" in $$props) $$invalidate(0, foo = $$props.foo);
};

@ -173,7 +173,7 @@ function instance($$self, $$props, $$invalidate) {
$$invalidate(10, ended);
}
$$self.$set = $$props => {
$$self.$$set = $$props => {
if ("buffered" in $$props) $$invalidate(0, buffered = $$props.buffered);
if ("seekable" in $$props) $$invalidate(1, seekable = $$props.seekable);
if ("played" in $$props) $$invalidate(2, played = $$props.played);

@ -0,0 +1,189 @@
/* generated by Svelte vX.Y.Z */
import {
SvelteComponent,
attr,
create_component,
destroy_component,
detach,
element,
init,
insert,
mount_component,
safe_not_equal,
set_data,
space,
text,
transition_in,
transition_out
} from "svelte/internal";
function create_fragment(ctx) {
let t0_value = /*a*/ ctx[0].normal + "";
let t0;
let t1_value = /*b*/ ctx[1]?.optional + "";
let t1;
let t2;
let t3_value = /*c*/ ctx[2]["computed"] + "";
let t3;
let t4_value = /*d*/ ctx[3]?.["computed_optional"] + "";
let t4;
let t5;
let t6_value = /*e*/ ctx[4]() + "";
let t6;
let t7_value = /*f*/ ctx[5]?.() + "";
let t7;
let t8;
let div;
let div_a_value;
let div_b_value;
let div_c_value;
let div_d_value;
let div_e_value;
let div_f_value;
let t9;
let component;
let current;
component = new /*Component*/ ctx[6]({
props: {
a: /*a*/ ctx[0].normal,
b: /*b*/ ctx[1]?.optional,
c: /*c*/ ctx[2]["computed"],
d: /*d*/ ctx[3]?.["computed_optional"],
e: /*e*/ ctx[4](),
f: /*f*/ ctx[5]?.()
}
});
return {
c() {
t0 = text(t0_value);
t1 = text(t1_value);
t2 = space();
t3 = text(t3_value);
t4 = text(t4_value);
t5 = space();
t6 = text(t6_value);
t7 = text(t7_value);
t8 = space();
div = element("div");
t9 = space();
create_component(component.$$.fragment);
attr(div, "a", div_a_value = /*a*/ ctx[0].normal);
attr(div, "b", div_b_value = /*b*/ ctx[1]?.optional);
attr(div, "c", div_c_value = /*c*/ ctx[2]["computed"]);
attr(div, "d", div_d_value = /*d*/ ctx[3]?.["computed_optional"]);
attr(div, "e", div_e_value = /*e*/ ctx[4]());
attr(div, "f", div_f_value = /*f*/ ctx[5]?.());
},
m(target, anchor) {
insert(target, t0, anchor);
insert(target, t1, anchor);
insert(target, t2, anchor);
insert(target, t3, anchor);
insert(target, t4, anchor);
insert(target, t5, anchor);
insert(target, t6, anchor);
insert(target, t7, anchor);
insert(target, t8, anchor);
insert(target, div, anchor);
insert(target, t9, anchor);
mount_component(component, target, anchor);
current = true;
},
p(ctx, [dirty]) {
if ((!current || dirty & /*a*/ 1) && t0_value !== (t0_value = /*a*/ ctx[0].normal + "")) set_data(t0, t0_value);
if ((!current || dirty & /*b*/ 2) && t1_value !== (t1_value = /*b*/ ctx[1]?.optional + "")) set_data(t1, t1_value);
if ((!current || dirty & /*c*/ 4) && t3_value !== (t3_value = /*c*/ ctx[2]["computed"] + "")) set_data(t3, t3_value);
if ((!current || dirty & /*d*/ 8) && t4_value !== (t4_value = /*d*/ ctx[3]?.["computed_optional"] + "")) set_data(t4, t4_value);
if ((!current || dirty & /*e*/ 16) && t6_value !== (t6_value = /*e*/ ctx[4]() + "")) set_data(t6, t6_value);
if ((!current || dirty & /*f*/ 32) && t7_value !== (t7_value = /*f*/ ctx[5]?.() + "")) set_data(t7, t7_value);
if (!current || dirty & /*a*/ 1 && div_a_value !== (div_a_value = /*a*/ ctx[0].normal)) {
attr(div, "a", div_a_value);
}
if (!current || dirty & /*b*/ 2 && div_b_value !== (div_b_value = /*b*/ ctx[1]?.optional)) {
attr(div, "b", div_b_value);
}
if (!current || dirty & /*c*/ 4 && div_c_value !== (div_c_value = /*c*/ ctx[2]["computed"])) {
attr(div, "c", div_c_value);
}
if (!current || dirty & /*d*/ 8 && div_d_value !== (div_d_value = /*d*/ ctx[3]?.["computed_optional"])) {
attr(div, "d", div_d_value);
}
if (!current || dirty & /*e*/ 16 && div_e_value !== (div_e_value = /*e*/ ctx[4]())) {
attr(div, "e", div_e_value);
}
if (!current || dirty & /*f*/ 32 && div_f_value !== (div_f_value = /*f*/ ctx[5]?.())) {
attr(div, "f", div_f_value);
}
const component_changes = {};
if (dirty & /*a*/ 1) component_changes.a = /*a*/ ctx[0].normal;
if (dirty & /*b*/ 2) component_changes.b = /*b*/ ctx[1]?.optional;
if (dirty & /*c*/ 4) component_changes.c = /*c*/ ctx[2]["computed"];
if (dirty & /*d*/ 8) component_changes.d = /*d*/ ctx[3]?.["computed_optional"];
if (dirty & /*e*/ 16) component_changes.e = /*e*/ ctx[4]();
if (dirty & /*f*/ 32) component_changes.f = /*f*/ ctx[5]?.();
component.$set(component_changes);
},
i(local) {
if (current) return;
transition_in(component.$$.fragment, local);
current = true;
},
o(local) {
transition_out(component.$$.fragment, local);
current = false;
},
d(detaching) {
if (detaching) detach(t0);
if (detaching) detach(t1);
if (detaching) detach(t2);
if (detaching) detach(t3);
if (detaching) detach(t4);
if (detaching) detach(t5);
if (detaching) detach(t6);
if (detaching) detach(t7);
if (detaching) detach(t8);
if (detaching) detach(div);
if (detaching) detach(t9);
destroy_component(component, detaching);
}
};
}
function instance($$self, $$props, $$invalidate) {
let { a } = $$props;
let { b } = $$props;
let { c } = $$props;
let { d } = $$props;
let { e } = $$props;
let { f } = $$props;
let Component;
$$self.$$set = $$props => {
if ("a" in $$props) $$invalidate(0, a = $$props.a);
if ("b" in $$props) $$invalidate(1, b = $$props.b);
if ("c" in $$props) $$invalidate(2, c = $$props.c);
if ("d" in $$props) $$invalidate(3, d = $$props.d);
if ("e" in $$props) $$invalidate(4, e = $$props.e);
if ("f" in $$props) $$invalidate(5, f = $$props.f);
};
return [a, b, c, d, e, f, Component];
}
class Component_1 extends SvelteComponent {
constructor(options) {
super();
init(this, options, instance, create_fragment, safe_not_equal, { a: 0, b: 1, c: 2, d: 3, e: 4, f: 5 });
}
}
export default Component_1;

@ -0,0 +1,31 @@
<script>
export let a;
export let b;
export let c;
export let d;
export let e;
export let f;
let Component;
</script>
{a.normal}{b?.optional}
{c['computed']}{d?.['computed_optional']}
{e()}{f?.()}
<div
a={a.normal}
b={b?.optional}
c={c['computed']}
d={d?.['computed_optional']}
e={e()}
f={f?.()}
/>
<Component
a={a.normal}
b={b?.optional}
c={c['computed']}
d={d?.['computed_optional']}
e={e()}
f={f?.()}
/>

@ -6,7 +6,7 @@ function instance($$self, $$props, $$invalidate) {
let a;
let b;
$$self.$set = $$props => {
$$self.$$set = $$props => {
if ("x" in $$props) $$invalidate(0, x = $$props.x);
};

@ -5,7 +5,7 @@ function instance($$self, $$props, $$invalidate) {
let { a = 1 } = $$props;
let { b = 2 } = $$props;
$$self.$set = $$props => {
$$self.$$set = $$props => {
if ("a" in $$props) $$invalidate(0, a = $$props.a);
if ("b" in $$props) $$invalidate(1, b = $$props.b);
};

@ -50,7 +50,7 @@ function create_fragment(ctx) {
function instance($$self, $$props, $$invalidate) {
let { current } = $$props;
$$self.$set = $$props => {
$$self.$$set = $$props => {
if ("current" in $$props) $$invalidate(0, current = $$props.current);
};

@ -67,7 +67,7 @@ function instance($$self, $$props, $$invalidate) {
let { url } = $$props;
let { slug } = $$props;
$$self.$set = $$props => {
$$self.$$set = $$props => {
if ("url" in $$props) $$invalidate(0, url = $$props.url);
if ("slug" in $$props) $$invalidate(1, slug = $$props.slug);
};

@ -22,7 +22,7 @@ function create_fragment(ctx) {
function instance($$self, $$props, $$invalidate) {
let { custom } = $$props;
$$self.$set = $$props => {
$$self.$$set = $$props => {
if ("custom" in $$props) $$invalidate(0, custom = $$props.custom);
};

@ -124,7 +124,7 @@ function instance($$self, $$props, $$invalidate) {
let { x } = $$props;
let { y } = $$props;
$$self.$set = $$props => {
$$self.$$set = $$props => {
if ("x" in $$props) $$invalidate(0, x = $$props.x);
if ("y" in $$props) $$invalidate(1, y = $$props.y);
};

@ -102,7 +102,7 @@ function create_fragment(ctx) {
function instance($$self, $$props, $$invalidate) {
let { num = 1 } = $$props;
$$self.$set = $$props => {
$$self.$$set = $$props => {
if ("num" in $$props) $$invalidate(0, num = $$props.num);
};

@ -243,7 +243,7 @@ function instance($$self, $$props, $$invalidate) {
let { d } = $$props;
let { e } = $$props;
$$self.$set = $$props => {
$$self.$$set = $$props => {
if ("a" in $$props) $$invalidate(0, a = $$props.a);
if ("b" in $$props) $$invalidate(1, b = $$props.b);
if ("c" in $$props) $$invalidate(2, c = $$props.c);

@ -93,7 +93,7 @@ function instance($$self, $$props, $$invalidate) {
$$invalidate(3, offsetWidth);
}
$$self.$set = $$props => {
$$self.$$set = $$props => {
if ("currentTime" in $$props) $$invalidate(0, currentTime = $$props.currentTime);
if ("videoHeight" in $$props) $$invalidate(1, videoHeight = $$props.videoHeight);
if ("videoWidth" in $$props) $$invalidate(2, videoWidth = $$props.videoWidth);

@ -78,7 +78,7 @@ function instance($$self, $$props, $$invalidate) {
$$invalidate(0, y = window.pageYOffset)
}
$$self.$set = $$props => {
$$self.$$set = $$props => {
if ("y" in $$props) $$invalidate(0, y = $$props.y);
};

@ -64,7 +64,8 @@
"value": "tooltip msg",
"raw": "'tooltip msg'"
}
]
],
"optional": false
}
}
],

@ -52,10 +52,10 @@
}
],
"context": {
"start": 17,
"end": 22,
"type": "Identifier",
"name": "thing"
"name": "thing",
"start": 17,
"end": 22
},
"key": {
"type": "Identifier",

@ -26,10 +26,10 @@
},
"value": null,
"error": {
"start": 47,
"end": 55,
"type": "Identifier",
"name": "theError"
"name": "theError",
"start": 47,
"end": 55
},
"pending": {
"start": 19,
@ -152,7 +152,8 @@
},
"name": "message"
},
"computed": false
"computed": false,
"optional": false
}
}
]

@ -25,16 +25,16 @@
"name": "thePromise"
},
"value": {
"start": 46,
"end": 54,
"type": "Identifier",
"name": "theValue"
"name": "theValue",
"start": 46,
"end": 54
},
"error": {
"start": 96,
"end": 104,
"type": "Identifier",
"name": "theError"
"name": "theError",
"start": 96,
"end": 104
},
"pending": {
"start": 19,
@ -209,7 +209,8 @@
},
"name": "message"
},
"computed": false
"computed": false,
"optional": false
}
}
]

@ -275,7 +275,8 @@
},
"name": "then"
},
"computed": false
"computed": false,
"optional": false
},
"arguments": [
{
@ -403,7 +404,8 @@
},
"name": "log"
},
"computed": false
"computed": false,
"optional": false
},
"arguments": [
{
@ -452,21 +454,25 @@
},
"name": "default"
},
"computed": false
"computed": false,
"optional": false
}
]
],
"optional": false
}
}
]
}
}
]
],
"optional": false
}
}
]
}
}
]
],
"optional": false
}
}
],

@ -57,10 +57,10 @@
}
],
"context": {
"start": 18,
"end": 24,
"type": "Identifier",
"name": "animal"
"name": "animal",
"start": 18,
"end": 24
},
"else": {
"start": 50,

@ -85,10 +85,10 @@
}
],
"context": {
"start": 18,
"end": 24,
"type": "Identifier",
"name": "animal"
"name": "animal",
"start": 18,
"end": 24
},
"index": "i"
}

@ -57,10 +57,10 @@
}
],
"context": {
"start": 16,
"end": 20,
"type": "Identifier",
"name": "todo"
"name": "todo",
"start": 16,
"end": 20
},
"key": {
"type": "MemberExpression",
@ -108,7 +108,8 @@
},
"name": "id"
},
"computed": false
"computed": false,
"optional": false
}
}
]

@ -57,10 +57,10 @@
}
],
"context": {
"start": 18,
"end": 24,
"type": "Identifier",
"name": "animal"
"name": "animal",
"start": 18,
"end": 24
}
}
]

@ -0,0 +1,10 @@
{
"code": "invalid-closing-tag",
"message": "</p> attempted to close an element that was not open",
"pos": 38,
"start": {
"character": 38,
"column": 0,
"line": 5
}
}

@ -0,0 +1,10 @@
{
"code": "invalid-closing-tag",
"message": "</p> attempted to close <p> that was already automatically closed by <pre>",
"pos": 24,
"start": {
"character": 24,
"column": 0,
"line": 3
}
}

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

Loading…
Cancel
Save