diff --git a/.eslintrc.js b/.eslintrc.js
index 2c7f2ed1b4..2023207f74 100644
--- a/.eslintrc.js
+++ b/.eslintrc.js
@@ -22,14 +22,7 @@ module.exports = {
'arrow-spacing': 2,
'no-inner-declarations': 0,
'require-atomic-updates': 'off',
- '@typescript-eslint/indent': [
- 'error',
- 'tab',
- {
- SwitchCase: 1,
- ignoredNodes: ['TemplateLiteral']
- }
- ],
+ '@typescript-eslint/indent': 'off',
'@typescript-eslint/camelcase': 'off',
'@typescript-eslint/no-use-before-define': 'off',
'@typescript-eslint/array-type': ['error', 'array-simple'],
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
new file mode 100644
index 0000000000..2488902b24
--- /dev/null
+++ b/.github/workflows/ci.yml
@@ -0,0 +1,25 @@
+name: CI
+on: [push, pull_request]
+jobs:
+ Tests:
+ runs-on: ${{ matrix.os }}
+ strategy:
+ matrix:
+ node-version: [8, 10, 12]
+ os: [ubuntu-latest, windows-latest, macOS-latest]
+ steps:
+ - run: git config --global core.autocrlf false
+ - uses: actions/checkout@v1
+ - uses: actions/setup-node@v1
+ with:
+ node-version: ${{ matrix.node-version }}
+ - run: npm install
+ - run: npm test
+ env:
+ CI: true
+ Lint:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v1
+ - uses: actions/setup-node@v1
+ - run: 'npm i && npm run lint'
diff --git a/.travis.yml b/.travis.yml
deleted file mode 100644
index a4603a26e2..0000000000
--- a/.travis.yml
+++ /dev/null
@@ -1,20 +0,0 @@
-language: node_js
-node_js:
- - "8"
- - "10"
- - "12"
-env:
- global:
- - BUILD_TIMEOUT=20000
-
-addons:
- apt:
- packages:
- - xvfb
-
-install:
- - export DISPLAY=':99.0'
- - Xvfb :99 -screen 0 1024x768x24 > /dev/null 2>&1 &
- - npm ci || npm install
-
-after_success: npm run codecov
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 5767a556e4..566fde5005 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,98 @@
# Svelte changelog
+## 3.14.1
+
+* Deconflict block method names with other variables ([#3900](https://github.com/sveltejs/svelte/issues/3900))
+* Fix entity encoding issue in text nodes with constant expressions ([#3911](https://github.com/sveltejs/svelte/issues/3911))
+* Make code for unknown prop warnings compatible with older js engines ([#3914](https://github.com/sveltejs/svelte/issues/3914))
+
+## 3.14.0
+
+* Add `loopGuardTimeout` option that augments `for`/`while` loops to prevent infinite loops, primarily for use in the REPL ([#3887](https://github.com/sveltejs/svelte/pull/3887))
+* Keep component bindings in sync when changed in reactive statements ([#3382](https://github.com/sveltejs/svelte/issues/3382))
+* Update attributes before bindings ([#3857](https://github.com/sveltejs/svelte/issues/3857))
+* Prevent variable naming conflict ([#3899](https://github.com/sveltejs/svelte/issues/3899))
+
+
+## 3.13.0
+
+* New structured code generation, which eliminates a number of edge cases and obscure bugs ([#3539](https://github.com/sveltejs/svelte/pull/3539))
+
+Also:
+
+* Fix `{#each}` context not shadowing outer scope when using `bind:` ([#1565](https://github.com/sveltejs/svelte/issues/1565))
+* Fix edge cases in matching selectors against elements ([#1710](https://github.com/sveltejs/svelte/issues/1710))
+* Fix several bugs related to interaction of `{...spread}` attributes with other features ([#2721](https://github.com/sveltejs/svelte/issues/2721), [#2916](https://github.com/sveltejs/svelte/issues/2916), [#3421](https://github.com/sveltejs/svelte/issues/3421), [#3681](https://github.com/sveltejs/svelte/issues/3681), [#3764](https://github.com/sveltejs/svelte/issues/3764), [#3790](https://github.com/sveltejs/svelte/issues/3790))
+* Allow exiting a reactive block early with `break $` ([#2828](https://github.com/sveltejs/svelte/issues/2828))
+* Fix binding to props that have been renamed with `export { ... as ... }` ([#3508](https://github.com/sveltejs/svelte/issues/3508))
+* Fix application of style scoping class in cases of ambiguity ([#3544](https://github.com/sveltejs/svelte/issues/3544))
+* Check attributes have changed before setting them to avoid image flicker ([#3579](https://github.com/sveltejs/svelte/pull/3579))
+* Fix generating malformed code for `{@debug}` tags with no dependencies ([#3588](https://github.com/sveltejs/svelte/issues/3588))
+* Fix generated code in specific case involving compound ifs and child components ([#3595](https://github.com/sveltejs/svelte/issues/3595))
+* Fix `bind:this` binding to a store ([#3591](https://github.com/sveltejs/svelte/issues/3591))
+* Use safer `HTMLElement` check before extending class ([#3608](https://github.com/sveltejs/svelte/issues/3608))
+* Add `location` as a known global ([#3619](https://github.com/sveltejs/svelte/pull/3619))
+* Support `{#await}` with `{:catch}` but no `{:then}` ([#3623](https://github.com/sveltejs/svelte/issues/3623))
+* Clean up dead code emitted for ``s ([#3631](https://github.com/sveltejs/svelte/issues/3631))
+* Fix tracking of dependencies of compound assignments in reactive statements ([#3634](https://github.com/sveltejs/svelte/issues/3634))
+* Flush changes in newly attached block when using `{#await}` ([#3660](https://github.com/sveltejs/svelte/issues/3660))
+* Throw exception immediately when calling `createEventDispatcher()` after component instantiation ([#3667](https://github.com/sveltejs/svelte/pull/3667))
+* Fix globals shadowing contextual template scope ([#3674](https://github.com/sveltejs/svelte/issues/3674))
+* Fix `` bindings to stores ([#3832](https://github.com/sveltejs/svelte/issues/3832))
+* Deconflict generated var names with builtins ([#3724](https://github.com/sveltejs/svelte/issues/3724))
+* Allow spring/tweened values to be initially undefined ([#3761](https://github.com/sveltejs/svelte/issues/3761))
+* Warn if using `` without `customElement: true` option ([#3782](https://github.com/sveltejs/svelte/pull/3782))
+* Add `Event` to list of known globals ([#3810](https://github.com/sveltejs/svelte/pull/3810))
+* Throw helpful error on empty CSS declaration ([#3801](https://github.com/sveltejs/svelte/issues/3801))
+* Support `easing` param on `fade` transition ([#3823](https://github.com/sveltejs/svelte/pull/3823))
+* Generate valid names from filenames with unicode characters ([#3845](https://github.com/sveltejs/svelte/issues/3845))
+* Don't generate any code for markup-less components ([#2200](https://github.com/sveltejs/svelte/issues/2200))
+* Deconflict with internal name `block` ([#3854](https://github.com/sveltejs/svelte/issues/3854))
+* Set attributes before bindings, to prevent erroneous assignments to `input.files` ([#3828](https://github.com/sveltejs/svelte/issues/3828))
+* Smarter unused CSS detection ([#3825](https://github.com/sveltejs/svelte/pull/3825))
+* Allow dynamic event handlers ([#3040](https://github.com/sveltejs/svelte/issues/3040))
+* Prevent erroneous `"undefined"` class name ([#3876](https://github.com/sveltejs/svelte/pull/3876))
+* Prevent resetting of `src` attribute unless changed ([#3579](https://github.com/sveltejs/svelte/pull/3579))
+* Prevent hydration of void element 'children' ([#3882](https://github.com/sveltejs/svelte/issues/3882))
+* Hoist globals even if mentioned in `
```
+---
+
+If the initial value is `undefined` or `null`, the first value change will take effect immediately, just as with `tweened` values (see above).
+
+```js
+const size = spring();
+$: $size = big ? 100 : 10;
+```
+
### `svelte/transition`
The `svelte/transition` module exports six functions: `fade`, `fly`, `slide`, `scale`, `draw` and `crossfade`. They are for use with svelte [`transitions`](docs#Transitions).
@@ -532,6 +554,42 @@ You can see the `fade` transition in action in the [transition tutorial](tutoria
{/if}
```
+#### `blur`
+
+```sv
+transition:blur={params}
+```
+```sv
+in:blur={params}
+```
+```sv
+out:blur={params}
+```
+
+---
+
+Animates a `blur` filter alongside an element's opacity.
+
+`blur` accepts the following parameters:
+
+* `delay` (`number`, default 0) — milliseconds before starting
+* `duration` (`number`, default 400) — milliseconds the transition lasts
+* `easing` (`function`, default `cubicInOut`) — an [easing function](docs#svelte_easing)
+* `opacity` (`number`, default 0) - the opacity value to animate out to and in from
+* `amount` (`number`, default 5) - the size of the blur in pixels
+
+```html
+
+
+{#if condition}
+
+ fades in and out
+
+{/if}
+```
+
#### `fly`
```sv
@@ -660,7 +718,7 @@ out:draw={params}
Animates the stroke of an SVG element, like a snake in a tube. `in` transitions begin with the path invisible and draw the path to the screen over time. `out` transitions start in a visible state and gradually erase the path. `draw` only works with elements that have a `getTotalLength` method, like `` and ``.
-`scale` accepts the following parameters:
+`draw` accepts the following parameters:
* `delay` (`number`, default 0) — milliseconds before starting
* `speed` (`number`, default undefined) - the speed of the animation, see below.
@@ -909,7 +967,7 @@ app.count += 1;
---
-Svelte components can also be compiled to custom elements (aka web components) using the `customElements: true` compiler option. You should specify a tag name for the component using the `` [element](docs#svelte_options).
+Svelte components can also be compiled to custom elements (aka web components) using the `customElement: true` compiler option. You should specify a tag name for the component using the `` [element](docs#svelte_options).
```html
@@ -983,8 +1041,12 @@ Unlike client-side components, server-side components don't have a lifespan afte
A server-side component exposes a `render` method that can be called with optional props. It returns an object with `head`, `html`, and `css` properties, where `head` contains the contents of any `` elements encountered.
+You can import a Svelte component directly into Node using [`svelte/register`](docs#svelte_register).
+
```js
-const App = require('./App.svelte');
+require('svelte/register');
+
+const App = require('./App.svelte').default;
const { head, html, css } = App.render({
answer: 42
diff --git a/site/content/docs/04-compile-time.md b/site/content/docs/04-compile-time.md
index f47fe564af..407b1dfc13 100644
--- a/site/content/docs/04-compile-time.md
+++ b/site/content/docs/04-compile-time.md
@@ -53,6 +53,7 @@ The following options can be passed to the compiler. None are required:
| `tag` | string | null
| `accessors` | boolean | `false`
| `css` | boolean | `true`
+| `loopGuardTimeout` | number | 0
| `preserveComments` | boolean | `false`
| `preserveWhitespace` | boolean | `false`
| `outputFilename` | string | `null`
@@ -73,6 +74,7 @@ The following options can be passed to the compiler. None are required:
| `customElement` | `false` | If `true`, tells the compiler to generate a custom element constructor instead of a regular Svelte component.
| `tag` | `null` | A `string` that tells Svelte what tag name to register the custom element with. It must be a lowercase alphanumeric string with at least one hyphen, e.g. `"my-element"`.
| `css` | `true` | If `true`, styles will be included in the JavaScript class and injected at runtime. It's recommended that you set this to `false` and use the CSS that is statically generated, as it will result in smaller JavaScript bundles and better performance.
+| `loopGuardTimeout` | 0 | A `number` that tells Svelte to break the loop if it blocks the thread for more than `loopGuardTimeout` ms. This is useful to prevent infinite loops. **Only available when `dev: true`**
| `preserveComments` | `false` | If `true`, your HTML comments will be preserved during server-side rendering. By default, they are stripped out.
| `preserveWhitespace` | `false` | If `true`, whitespace inside and between elements is kept as you typed it, rather than optimised by Svelte.
| `outputFilename` | `null` | A `string` used for your JavaScript sourcemap.
@@ -315,7 +317,7 @@ walk(ast: Node, {
---
-The `walk` function provides a way to walk to abstract syntax trees generated by the parser, using the compiler's own built-in instance of [estree-walker](https://github.com/Rich-Harris/estree-walker).
+The `walk` function provides a way to walk the abstract syntax trees generated by the parser, using the compiler's own built-in instance of [estree-walker](https://github.com/Rich-Harris/estree-walker).
The walker takes an abstract syntax tree to walk and an object with two optional methods: `enter` and `leave`. For each node, `enter` is called (if present). Then, unless `this.skip()` is called during `enter`, each of the children are traversed, and then `leave` is called on the node.
diff --git a/site/content/examples/05-bindings/08-media-elements/App.svelte b/site/content/examples/05-bindings/08-media-elements/App.svelte
index 2cf819fca0..469e9e12eb 100644
--- a/site/content/examples/05-bindings/08-media-elements/App.svelte
+++ b/site/content/examples/05-bindings/08-media-elements/App.svelte
@@ -14,7 +14,7 @@
showControlsTimeout = setTimeout(() => showControls = false, 2500);
showControls = true;
- if (e.which !== 1) return; // mouse not down
+ if (!(e.buttons & 1)) return; // mouse not down
if (!duration) return; // video not loaded yet
const { left, right } = this.getBoundingClientRect();
@@ -109,8 +109,8 @@
diff --git a/site/content/examples/12-svg/05-svg-transitions/App.svelte b/site/content/examples/12-svg/05-svg-transitions/App.svelte
index 6059b3645f..6e1e636b20 100644
--- a/site/content/examples/12-svg/05-svg-transitions/App.svelte
+++ b/site/content/examples/12-svg/05-svg-transitions/App.svelte
@@ -33,7 +33,7 @@
font-family: 'Overpass';
letter-spacing: 0.12em;
color: #676778;
- font-weight: 100;
+ font-weight: 400;
}
.centered span {
@@ -71,4 +71,4 @@
toggle me
-
\ No newline at end of file
+
diff --git a/site/content/examples/15-composition/04-modal/Modal.svelte b/site/content/examples/15-composition/04-modal/Modal.svelte
index 5ffa5989a4..4a5329b05b 100644
--- a/site/content/examples/15-composition/04-modal/Modal.svelte
+++ b/site/content/examples/15-composition/04-modal/Modal.svelte
@@ -1,9 +1,56 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
diff --git a/site/content/examples/18-module-context/01-module-exports/App.svelte b/site/content/examples/18-module-context/01-module-exports/App.svelte
index cd5ab44b21..1d5d94b5d1 100644
--- a/site/content/examples/18-module-context/01-module-exports/App.svelte
+++ b/site/content/examples/18-module-context/01-module-exports/App.svelte
@@ -8,7 +8,7 @@
let people = [
- {
- first: 'Hans',
- last: 'Emil'
- },
- {
- first: 'Max',
- last: 'Mustermann'
- },
- {
- first: 'Roman',
- last: 'Tisch'
- }
+ { first: 'Hans', last: 'Emil' },
+ { first: 'Max', last: 'Mustermann' },
+ { first: 'Roman', last: 'Tisch' }
];
let prefix = '';
@@ -39,7 +30,9 @@
}
function update() {
- people[i] = { first, last };
+ selected.first = first;
+ selected.last = last;
+ people = people;
}
function remove() {
diff --git a/site/content/tutorial/02-reactivity/04-updating-arrays-and-objects/text.md b/site/content/tutorial/02-reactivity/04-updating-arrays-and-objects/text.md
index b70b09f728..82e4c91d35 100644
--- a/site/content/tutorial/02-reactivity/04-updating-arrays-and-objects/text.md
+++ b/site/content/tutorial/02-reactivity/04-updating-arrays-and-objects/text.md
@@ -30,3 +30,12 @@ function addNumber() {
numbers[numbers.length] = numbers.length + 1;
}
```
+
+A simple rule of thumb: the name of the updated variable must appear on the left hand side of the assignment. For example this...
+
+```js
+const foo = obj.foo;
+foo.bar = 'baz';
+```
+
+...won't update references to `obj.foo.bar`, unless you follow it up with `obj = obj`.
\ No newline at end of file
diff --git a/site/content/tutorial/04-logic/05-keyed-each-blocks/text.md b/site/content/tutorial/04-logic/05-keyed-each-blocks/text.md
index 3c204d1413..4affb89cd6 100644
--- a/site/content/tutorial/04-logic/05-keyed-each-blocks/text.md
+++ b/site/content/tutorial/04-logic/05-keyed-each-blocks/text.md
@@ -4,13 +4,13 @@ title: Keyed each blocks
By default, when you modify the value of an `each` block, it will add and remove items at the *end* of the block, and update any values that have changed. That might not be what you want.
-It's easier to show why than to explain. Click the 'Remove first thing' button a few times, and notice that it's removing `` components from the end and updating the `value` for those that remain. Instead, we'd like to remove the first `` component and leave the rest unaffected.
+It's easier to show why than to explain. Click the 'Remove first thing' button a few times, and notice that it's removing `` components from the end and updating the `color` for those that remain. Instead, we'd like to remove the first `` component and leave the rest unaffected.
To do that, we specify a unique identifier for the `each` block:
```html
{#each things as thing (thing.id)}
-
+
{/each}
```
diff --git a/site/content/tutorial/06-bindings/10-media-elements/app-a/App.svelte b/site/content/tutorial/06-bindings/10-media-elements/app-a/App.svelte
index ec01cd5476..40276110f4 100644
--- a/site/content/tutorial/06-bindings/10-media-elements/app-a/App.svelte
+++ b/site/content/tutorial/06-bindings/10-media-elements/app-a/App.svelte
@@ -14,7 +14,7 @@
showControlsTimeout = setTimeout(() => showControls = false, 2500);
showControls = true;
- if (e.which !== 1) return; // mouse not down
+ if (!(e.buttons & 1)) return; // mouse not down
if (!duration) return; // video not loaded yet
const { left, right } = this.getBoundingClientRect();
@@ -109,8 +109,8 @@
@@ -124,4 +124,4 @@
{format(duration)}
-
\ No newline at end of file
+
diff --git a/site/content/tutorial/06-bindings/10-media-elements/app-b/App.svelte b/site/content/tutorial/06-bindings/10-media-elements/app-b/App.svelte
index c304581a77..8712d6718b 100644
--- a/site/content/tutorial/06-bindings/10-media-elements/app-b/App.svelte
+++ b/site/content/tutorial/06-bindings/10-media-elements/app-b/App.svelte
@@ -14,7 +14,7 @@
showControlsTimeout = setTimeout(() => showControls = false, 2500);
showControls = true;
- if (e.which !== 1) return; // mouse not down
+ if (!(e.buttons & 1)) return; // mouse not down
if (!duration) return; // video not loaded yet
const { left, right } = this.getBoundingClientRect();
@@ -109,8 +109,8 @@