From 7a7804be49d23b705f9429c36e62c6c20d2e68ed Mon Sep 17 00:00:00 2001
From: pngwn
Date: Fri, 26 Apr 2019 22:20:33 +0100
Subject: [PATCH 001/163] Document animations. #2532
---
site/content/docs/02-template-syntax.md | 133 +++++++++++++++++++++++-
1 file changed, 132 insertions(+), 1 deletion(-)
diff --git a/site/content/docs/02-template-syntax.md b/site/content/docs/02-template-syntax.md
index 917673a7b0..a69400f8e3 100644
--- a/site/content/docs/02-template-syntax.md
+++ b/site/content/docs/02-template-syntax.md
@@ -895,7 +895,138 @@ Local transitions only play when the block they belong to is created or destroye
### Animations
-TODO i can't remember how any of this works
+```sv
+animate:name
+```
+
+```sv
+animate:name={params}
+```
+
+```js
+animation = (node: HTMLElement, { from: DOMRect, to: DOMRect } , params: any) => {
+ delay?: number,
+ duration?: number,
+ easing?: (t: number) => number,
+ css?: (t: number, u: number) => string,
+ tick?: (t: number, u: number) => void
+}
+```
+
+```js
+DOMRect {
+ bottom: number,
+ height: number,
+ left: number,
+ right: number,
+ top: number,
+ width: number,
+ x: number,
+ y:number
+}
+```
+
+---
+
+An animation is triggered when the contents of a [keyed each block](docs#Each_blocks) are re-ordered. Animations do not run when an element is removed, only when the each block's data is reordered. Animate directives must be on an element that is an *immediate* child of a keyed each block.
+
+Animations can be used with Svelte's [built-in animation functions](docs#svelte_animate) or [custom animation functions](docs#Custom_animation_functions).
+
+```html
+
+{#each list as item, index (item)}
+
{item}
+{/each}
+```
+
+#### Animation Parameters
+
+---
+
+As with actions and transitions, animations can have parameters.
+
+(The double `{{curlies}}` aren't a special syntax; this is an object literal inside an expression tag.)
+
+```html
+{#each list as item, index (item)}
+
{item}
+{/each}
+```
+
+#### Custom animation functions
+
+---
+
+Animations can use custom functions that provide the `node`, an `animation` object and any `paramaters` as arguments. The `animation` parameter is an object containing `from` and `to` properties each containing a [DOMRect](https://developer.mozilla.org/en-US/docs/Web/API/DOMRect#Properties) describing the geometry of the element in its `start` and `end` positions. The `from` property is the DOMRect of the element in its starting position, the `to` property is the DOMRect of the element in its final position after the list has been reordered and the DOM updated.
+
+If the returned object has a `css` method, Svelte will create a CSS animation that plays on the element.
+
+The `t` argument passed to `css` is a value that goes from `0` and `1` after the `easing` function has been applied. The `u` argument is equal to `1 - t`.
+
+The function is called repeatedly *before* the animation begins, with different `t` and `u` arguments.
+
+
+```html
+
+
+{#each list as item, index (item)}
+
{item}
+{/each}
+```
+
+---
+
+
+A custom animation function can also return a `tick` function, which is called *during* the animation with the same `t` and `u` arguments.
+
+> If it's possible to use `css` instead of `tick`, do so — CSS animations can run off the main thread, preventing jank on slower devices.
+
+```html
+
+
+{#each list as item, index (item)}
+
From 5fddf49a236e5c6f3bddf8363ae38cd880efd1d0 Mon Sep 17 00:00:00 2001
From: Alex Ivasyuv
Date: Mon, 6 May 2019 21:30:56 +0300
Subject: [PATCH 007/163] Added CI
---
README.md | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/README.md b/README.md
index d59a5a6b23..6496d7f5ab 100644
--- a/README.md
+++ b/README.md
@@ -11,6 +11,11 @@
+
+
+
+
From 963f6e7aa6e48ef2761d67d82b58ac3a4dd27302 Mon Sep 17 00:00:00 2001
From: Emil Tholin
Date: Mon, 6 May 2019 22:41:51 +0200
Subject: [PATCH 008/163] Don't hoist functions dependent on injected reactive
variables
---
src/compile/Component.ts | 10 +++++-----
.../reactive-value-function-hoist/_config.js | 15 +++++++++++++++
.../reactive-value-function-hoist/main.svelte | 10 ++++++++++
3 files changed, 30 insertions(+), 5 deletions(-)
create mode 100644 test/runtime/samples/reactive-value-function-hoist/_config.js
create mode 100644 test/runtime/samples/reactive-value-function-hoist/main.svelte
diff --git a/src/compile/Component.ts b/src/compile/Component.ts
index 7d4aa72f03..5a31dcf501 100644
--- a/src/compile/Component.ts
+++ b/src/compile/Component.ts
@@ -920,7 +920,7 @@ export default class Component {
// reference instance variables other than other
// hoistable functions. TODO others?
- const { hoistable_nodes, var_lookup } = this;
+ const { hoistable_nodes, var_lookup, injected_reactive_declaration_vars } = this;
const top_level_function_declarations = new Map();
@@ -987,11 +987,11 @@ export default class Component {
const { name } = flatten_reference(node);
const owner = scope.find_owner(name);
- if (name[0] === '$' && !owner) {
+ if (node.type === 'Identifier' && injected_reactive_declaration_vars.has(name)) {
hoistable = false;
- }
-
- else if (owner === instance_scope) {
+ } else if (name[0] === '$' && !owner) {
+ hoistable = false;
+ } else if (owner === instance_scope) {
if (name === fn_declaration.id.name) return;
const variable = var_lookup.get(name);
diff --git a/test/runtime/samples/reactive-value-function-hoist/_config.js b/test/runtime/samples/reactive-value-function-hoist/_config.js
new file mode 100644
index 0000000000..6198a57ef6
--- /dev/null
+++ b/test/runtime/samples/reactive-value-function-hoist/_config.js
@@ -0,0 +1,15 @@
+export default {
+ html: `
+
+ `,
+
+ async test({ assert, target, window }) {
+ const event = new window.MouseEvent('click');
+ const button = target.querySelector('button');
+
+ await button.dispatchEvent(event);
+ assert.htmlEqual(target.innerHTML, `
+
+ `);
+ }
+};
diff --git a/test/runtime/samples/reactive-value-function-hoist/main.svelte b/test/runtime/samples/reactive-value-function-hoist/main.svelte
new file mode 100644
index 0000000000..0f2dadb561
--- /dev/null
+++ b/test/runtime/samples/reactive-value-function-hoist/main.svelte
@@ -0,0 +1,10 @@
+
+
+
From 80fe0e9cdbfe70550e6f3e839c7cdb6ef1628bc9 Mon Sep 17 00:00:00 2001
From: Conduitry
Date: Tue, 7 May 2019 20:21:26 -0400
Subject: [PATCH 009/163] site: add /chat redirect to Discord (#2708)
---
README.md | 2 +-
.../content/blog/2017-08-07-the-easiest-way-to-get-started.md | 2 +-
.../2017-12-31-sapper-towards-the-ideal-web-app-framework.md | 2 +-
site/content/blog/2018-04-18-version-2.md | 4 ++--
site/content/blog/2019-01-31-svelte-on-the-changelog.md | 3 +--
.../content/blog/2019-04-22-svelte-3-rethinking-reactivity.md | 2 +-
site/content/docs/00-introduction.md | 2 +-
.../content/tutorial/19-next-steps/01-congratulations/text.md | 2 +-
site/src/routes/_error.svelte | 2 +-
site/src/routes/_layout.svelte | 2 +-
site/src/routes/chat.js | 4 ++++
11 files changed, 15 insertions(+), 12 deletions(-)
create mode 100644 site/src/routes/chat.js
diff --git a/README.md b/README.md
index bcda0501ad..f8a1a916d8 100644
--- a/README.md
+++ b/README.md
@@ -9,7 +9,7 @@
Svelte is a new way to build web applications. It's a compiler that takes your declarative components and converts them into efficient JavaScript that surgically updates the DOM.
-Learn more at the [Svelte website](https://svelte.dev), or stop by the [Discord chatroom](https://discord.gg/yy75DKs).
+Learn more at the [Svelte website](https://svelte.dev), or stop by the [Discord chatroom](https://svelte.dev/chat).
## Development
diff --git a/site/content/blog/2017-08-07-the-easiest-way-to-get-started.md b/site/content/blog/2017-08-07-the-easiest-way-to-get-started.md
index e91166430c..596c469433 100644
--- a/site/content/blog/2017-08-07-the-easiest-way-to-get-started.md
+++ b/site/content/blog/2017-08-07-the-easiest-way-to-get-started.md
@@ -55,4 +55,4 @@ npx degit your-name/template my-new-project
And that's it! Do `npm run build` to create a production-ready version of your app, and check the project template's [README](https://github.com/sveltejs/template/blob/master/README.md) for instructions on how to easily deploy your app to the web with [Now](https://zeit.co/now) or [Surge](http://surge.sh/).
-You're not restricted to using Rollup — there are also integrations for [webpack](https://github.com/sveltejs/svelte-loader), [Browserify](https://github.com/tehshrike/sveltify) and others, or you can use the [Svelte CLI](https://github.com/sveltejs/svelte-cli) (Update from 2019: with Svelte 3 the CLI was deprecated and we now use [sirv-cli](https://www.npmjs.com/package/sirv-cli) in our template. Feel free to use whatever tool you like!) or the [API](https://github.com/sveltejs/svelte/tree/v2#api) directly. If you make a project template using one of these tools, please share it with the [Svelte Discord chatroom](https://discord.gg/yy75DKs), or via [@sveltejs](https://twitter.com/sveltejs) on Twitter!
+You're not restricted to using Rollup — there are also integrations for [webpack](https://github.com/sveltejs/svelte-loader), [Browserify](https://github.com/tehshrike/sveltify) and others, or you can use the [Svelte CLI](https://github.com/sveltejs/svelte-cli) (Update from 2019: with Svelte 3 the CLI was deprecated and we now use [sirv-cli](https://www.npmjs.com/package/sirv-cli) in our template. Feel free to use whatever tool you like!) or the [API](https://github.com/sveltejs/svelte/tree/v2#api) directly. If you make a project template using one of these tools, please share it with the [Svelte Discord chatroom](chat), or via [@sveltejs](https://twitter.com/sveltejs) on Twitter!
diff --git a/site/content/blog/2017-12-31-sapper-towards-the-ideal-web-app-framework.md b/site/content/blog/2017-12-31-sapper-towards-the-ideal-web-app-framework.md
index 040e95a8c3..8799fdacce 100644
--- a/site/content/blog/2017-12-31-sapper-towards-the-ideal-web-app-framework.md
+++ b/site/content/blog/2017-12-31-sapper-towards-the-ideal-web-app-framework.md
@@ -81,4 +81,4 @@ I believe the next frontier of web performance is 'whole-app optimisation'. Curr
Speaking of Glimmer, the idea of compiling components to bytecode is one that we'll probably steal in 2018. A framework like Sapper could conceivably determine which compilation mode to use based on the characteristics of your app. It could even serve JavaScript for the initial route for the fastest possible startup time, then lazily serve a bytecode interpreter for subsequent routes, resulting in the optimal combination of startup size and total app size.
-Mostly, though, we want the direction of Sapper to be determined by its users. If you're the kind of developer who enjoys life on the bleeding edge and would like to help shape the future of how we build web apps, please join us on [GitHub](https://github.com/sveltejs/svelte) and [Discord](https://discord.gg/yy75DKs).
+Mostly, though, we want the direction of Sapper to be determined by its users. If you're the kind of developer who enjoys life on the bleeding edge and would like to help shape the future of how we build web apps, please join us on [GitHub](https://github.com/sveltejs/svelte) and [Discord](chat).
diff --git a/site/content/blog/2018-04-18-version-2.md b/site/content/blog/2018-04-18-version-2.md
index 778d703b1d..900debc0fb 100644
--- a/site/content/blog/2018-04-18-version-2.md
+++ b/site/content/blog/2018-04-18-version-2.md
@@ -12,7 +12,7 @@ Almost a year after we first started talking about version 2 on the Svelte issue
## tl;dr
-Each of these items is described in more depth below. If you get stuck, ask for help in our friendly [Discord chatroom](https://discord.gg/yy75DKs).
+Each of these items is described in more depth below. If you get stuck, ask for help in our friendly [Discord chatroom](chat).
- Install Svelte v2 from npm
- Upgrade your templates with [svelte-upgrade](https://github.com/sveltejs/svelte-upgrade)
@@ -201,4 +201,4 @@ Before, there was a `svelte.validate` method which checked your component was va
## My app is broken! Help!
-Hopefully this covers everything, and the update should be easier for you than it was for us. But if you find bugs, or discover things that aren't mentioned here, swing by [Discord chatroom](https://discord.gg/yy75DKs) or raise an issue on the [tracker](https://github.com/sveltejs/svelte/issues).
+Hopefully this covers everything, and the update should be easier for you than it was for us. But if you find bugs, or discover things that aren't mentioned here, swing by [Discord chatroom](chat) or raise an issue on the [tracker](https://github.com/sveltejs/svelte/issues).
diff --git a/site/content/blog/2019-01-31-svelte-on-the-changelog.md b/site/content/blog/2019-01-31-svelte-on-the-changelog.md
index 936c50240e..0b8e1894e4 100644
--- a/site/content/blog/2019-01-31-svelte-on-the-changelog.md
+++ b/site/content/blog/2019-01-31-svelte-on-the-changelog.md
@@ -14,9 +14,8 @@ Earlier this month, I had the privilege of appearing on [The Changelog](https://
...and, most importantly, Svelte 3.
-Unless you hang out in our [Discord server](https://discord.gg/yy75DKs) or follow [@sveltejs](https://twitter.com/sveltejs) on Twitter, you might not know that Svelte 3 is just around the corner, and it's going to be a huge release. We've rethought the developer experience from the ground up, and while it *will* be a nuisance if you need to upgrade a Svelte 2 app (more on that soon) we think you're going to love it.
+Unless you hang out in our [Discord server](chat) or follow [@sveltejs](https://twitter.com/sveltejs) on Twitter, you might not know that Svelte 3 is just around the corner, and it's going to be a huge release. We've rethought the developer experience from the ground up, and while it *will* be a nuisance if you need to upgrade a Svelte 2 app (more on that soon) we think you're going to love it.
On the podcast [Adam](https://twitter.com/adamstac), [Jerod](https://twitter.com/jerodsanto) and I talk about some of the changes and why we're making them. You can listen here or on the [podcast page](https://changelog.com/podcast/332).
-
diff --git a/site/content/blog/2019-04-22-svelte-3-rethinking-reactivity.md b/site/content/blog/2019-04-22-svelte-3-rethinking-reactivity.md
index 0721c09692..3ae0085e86 100644
--- a/site/content/blog/2019-04-22-svelte-3-rethinking-reactivity.md
+++ b/site/content/blog/2019-04-22-svelte-3-rethinking-reactivity.md
@@ -94,4 +94,4 @@ We don't take this lightly: hopefully once you've experienced Svelte 3 you'll un
As grueling as this release has been, we're nowhere near finished. We have a ton of ideas for generating smarter, more compact code, and a long feature wish-list. [Sapper](https://sapper.svelte.dev), our Next.js-style app framework, is still in the middle of being updated to use Svelte 3. The [Svelte Native](https://svelte-native.technology/) community project, which allows you to write Android and iOS apps in Svelte, is making solid progress but deserves more complete support from core. We don't yet have the bounty of editor extensions, syntax highlighters, component kits, devtools and so on that other frameworks have, and we should fix that. We *really* want to add first-class TypeScript support.
-But in the meantime we think Svelte 3 is the best way to build web apps yet. Take an hour to go through the [tutorial](tutorial) and we hope to convince you of the same. Either way, we'd love to see you in our [Discord chatroom](https://discord.gg/yy75DKs) and on [GitHub](https://github.com/sveltejs/svelte) — everyone is welcome, especially you.
\ No newline at end of file
+But in the meantime we think Svelte 3 is the best way to build web apps yet. Take an hour to go through the [tutorial](tutorial) and we hope to convince you of the same. Either way, we'd love to see you in our [Discord chatroom](chat) and on [GitHub](https://github.com/sveltejs/svelte) — everyone is welcome, especially you.
\ No newline at end of file
diff --git a/site/content/docs/00-introduction.md b/site/content/docs/00-introduction.md
index c218cdfb5f..2456b85f9c 100644
--- a/site/content/docs/00-introduction.md
+++ b/site/content/docs/00-introduction.md
@@ -2,7 +2,7 @@
title: Before we begin
---
-> Temporary note: This document is a work-in-progress. Please forgive any missing or misleading parts, and don't be shy about asking for help in the [Discord chatroom](https://discord.gg/yy75DKs). The [tutorial](tutorial) is more complete; start there.
+> Temporary note: This document is a work-in-progress. Please forgive any missing or misleading parts, and don't be shy about asking for help in the [Discord chatroom](chat). The [tutorial](tutorial) is more complete; start there.
This page contains detailed API reference documentation. It's intended to be a resource for people who already have some familiarity with Svelte.
diff --git a/site/content/tutorial/19-next-steps/01-congratulations/text.md b/site/content/tutorial/19-next-steps/01-congratulations/text.md
index e513989afe..c4436113bc 100644
--- a/site/content/tutorial/19-next-steps/01-congratulations/text.md
+++ b/site/content/tutorial/19-next-steps/01-congratulations/text.md
@@ -8,4 +8,4 @@ To get set up in your local development environment, check out [the quickstart g
If you're looking for a more expansive framework that includes routing, server-side rendering and everything else, take a look at [Sapper](https://sapper.svelte.dev).
-Most importantly: since you're now a member of the Svelte community, you should [join our friendly Discord chatroom](https://discord.gg/yy75DKs). That's where you'll find fellow Svelte users, and it's where we plan the future of the framework.
\ No newline at end of file
+Most importantly: since you're now a member of the Svelte community, you should [join our friendly Discord chatroom](chat). That's where you'll find fellow Svelte users, and it's where we plan the future of the framework.
\ No newline at end of file
diff --git a/site/src/routes/_error.svelte b/site/src/routes/_error.svelte
index 282980a2ad..c23805166b 100644
--- a/site/src/routes/_error.svelte
+++ b/site/src/routes/_error.svelte
@@ -61,7 +61,7 @@
Please try reloading the page.
{/if}
-
If the error persists, please drop by Discord chatroom and let us know, or raise an issue on GitHub. Thanks!
+
If the error persists, please drop by Discord chatroom and let us know, or raise an issue on GitHub. Thanks!
{/if}
{:else}
It looks like you're offline
diff --git a/site/src/routes/_layout.svelte b/site/src/routes/_layout.svelte
index bc557fb4da..18c1d2a8b7 100644
--- a/site/src/routes/_layout.svelte
+++ b/site/src/routes/_layout.svelte
@@ -24,7 +24,7 @@
Sapper
-
+
diff --git a/site/src/routes/chat.js b/site/src/routes/chat.js
new file mode 100644
index 0000000000..2fdeda2675
--- /dev/null
+++ b/site/src/routes/chat.js
@@ -0,0 +1,4 @@
+export function get(req, res) {
+ res.writeHead(302, { Location: 'https://discord.gg/yy75DKs' });
+ res.end();
+}
\ No newline at end of file
From 4631b1b93fbb5161f3be9996b5734acc13f6cf0c Mon Sep 17 00:00:00 2001
From: Julien Mourer
Date: Wed, 8 May 2019 20:47:17 +0200
Subject: [PATCH 010/163] Add `window` and `document` to globals
To prevent the following warning message:
```
(!) svelte plugin: 'window' is not defined
src/templates/Share.svelte
20:
21:
22: {#if window.navigator.share}
^
23:
24: {:else}
```
---
src/utils/names.ts | 2 ++
1 file changed, 2 insertions(+)
diff --git a/src/utils/names.ts b/src/utils/names.ts
index 2eafdf06a3..f1413548aa 100644
--- a/src/utils/names.ts
+++ b/src/utils/names.ts
@@ -10,6 +10,7 @@ export const globals = new Set([
'Date',
'decodeURI',
'decodeURIComponent',
+ 'document',
'encodeURI',
'encodeURIComponent',
'Infinity',
@@ -31,6 +32,7 @@ export const globals = new Set([
'Set',
'String',
'undefined',
+ 'window',
]);
export const reserved = new Set([
From 6d32f999040cf47e5eb1e5480e0594919edb5b72 Mon Sep 17 00:00:00 2001
From: Rich Harris
Date: Wed, 8 May 2019 23:16:51 -0400
Subject: [PATCH 011/163] Update README.md
---
README.md | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/README.md b/README.md
index 6496d7f5ab..19c0565586 100644
--- a/README.md
+++ b/README.md
@@ -1,8 +1,8 @@
-
+
-
+
From ec74b21c37a633ea87aa062974b87a885025c85d Mon Sep 17 00:00:00 2001
From: Richard Harris
Date: Thu, 9 May 2019 00:01:41 -0400
Subject: [PATCH 012/163] -> v3.2.2
---
CHANGELOG.md | 7 +++++++
package.json | 2 +-
2 files changed, 8 insertions(+), 1 deletion(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index a509bd0f47..239f2d28e3 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,12 @@
# Svelte changelog
+## 3.2.2
+
+* Add `window` and `document` to expected globals ([#2722](https://github.com/sveltejs/svelte/pull/2722))
+* Prevent hoisting of functions that depend on reactive state ([#2703](https://github.com/sveltejs/svelte/pull/2703))
+* Generate correct code when slot has no changes ([#2697](https://github.com/sveltejs/svelte/issues/2697))
+* Prevent `Object.prototype`-related bugs ([#2696](https://github.com/sveltejs/svelte/pull/2696))
+
## 3.2.1
* Use same comparison logic for `derived` as for other stores ([#2644](https://github.com/sveltejs/svelte/issues/2644))
diff --git a/package.json b/package.json
index b9f70f547a..ccbedde168 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "svelte",
- "version": "3.2.1",
+ "version": "3.2.2",
"description": "Cybernetically enhanced web apps",
"module": "index.mjs",
"main": "index",
From fdc51de0906cfa45b2ec37b429a5a8696dd1d1bb Mon Sep 17 00:00:00 2001
From: Rich Harris
Date: Thu, 9 May 2019 21:18:13 -0400
Subject: [PATCH 013/163] allow derivers to return cleanup functions - fixes
#2553
---
store.mjs | 4 ++++
test/store/index.js | 31 +++++++++++++++++++++++++++++++
2 files changed, 35 insertions(+)
diff --git a/store.mjs b/store.mjs
index bc9bc46ed1..624ede3dde 100644
--- a/store.mjs
+++ b/store.mjs
@@ -51,11 +51,14 @@ export function derived(stores, fn, initial_value) {
const values = [];
let pending = 0;
+ let cleanup = noop;
const sync = () => {
if (pending) return;
+ cleanup();
const result = fn(single ? values[0] : values, set);
if (auto) set(result);
+ else cleanup = result || noop;
};
const unsubscribers = stores.map((store, i) => store.subscribe(
@@ -74,6 +77,7 @@ export function derived(stores, fn, initial_value) {
return function stop() {
run_all(unsubscribers);
+ cleanup();
};
});
}
diff --git a/test/store/index.js b/test/store/index.js
index 44617d6d00..5f9176cffb 100644
--- a/test/store/index.js
+++ b/test/store/index.js
@@ -211,6 +211,37 @@ describe('store', () => {
unsubscribe();
});
+
+ it('calls a cleanup function', () => {
+ const num = writable(1);
+
+ const values = [];
+ const cleaned_up = [];
+
+ const d = derived(num, ($num, set) => {
+ set($num * 2);
+
+ return function cleanup() {
+ cleaned_up.push($num);
+ };
+ });
+
+ num.set(2);
+
+ const unsubscribe = d.subscribe(value => {
+ values.push(value);
+ });
+
+ num.set(3);
+ num.set(4);
+
+ assert.deepEqual(values, [4, 6, 8]);
+ assert.deepEqual(cleaned_up, [2, 3]);
+
+ unsubscribe();
+
+ assert.deepEqual(cleaned_up, [2, 3, 4]);
+ });
});
describe('get', () => {
From 9eec0fcd983ac14f525db42413dcd582c2fac98a Mon Sep 17 00:00:00 2001
From: Benjamin Milde
Date: Sat, 11 May 2019 17:42:36 +0200
Subject: [PATCH 014/163] Implement suggestions
---
src/parse/state/tag.ts | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/src/parse/state/tag.ts b/src/parse/state/tag.ts
index f02eed037c..365085ca08 100644
--- a/src/parse/state/tag.ts
+++ b/src/parse/state/tag.ts
@@ -368,14 +368,16 @@ function read_attribute(parser: Parser, unique_names: Set) {
const colon_index = name.indexOf(':');
const type = colon_index !== -1 && get_directive_type(name.slice(0, colon_index));
- if (unique_names.has(name) && type != "EventHandler") {
+ if (unique_names.has(name)) {
parser.error({
code: `duplicate-attribute`,
message: 'Attributes need to be unique'
}, start);
}
- unique_names.add(name);
+ if (type !== "EventHandler") {
+ unique_names.add(name);
+ }
let value: any[] | true = true;
if (parser.eat('=')) {
From abe486e7e38d5ed103af603bfd5348f7db355948 Mon Sep 17 00:00:00 2001
From: Benjamin Milde
Date: Sat, 11 May 2019 17:42:59 +0200
Subject: [PATCH 015/163] Switch test to runtime test
---
.../input.svelte | 1 -
.../output.json | 96 -------------------
.../samples/event-handler-multiple/_config.js | 14 +++
.../event-handler-multiple/main.svelte | 6 ++
4 files changed, 20 insertions(+), 97 deletions(-)
delete mode 100644 test/parser/samples/non-unique-attribute-event-handler/input.svelte
delete mode 100644 test/parser/samples/non-unique-attribute-event-handler/output.json
create mode 100644 test/runtime/samples/event-handler-multiple/_config.js
create mode 100644 test/runtime/samples/event-handler-multiple/main.svelte
diff --git a/test/parser/samples/non-unique-attribute-event-handler/input.svelte b/test/parser/samples/non-unique-attribute-event-handler/input.svelte
deleted file mode 100644
index b13403f77d..0000000000
--- a/test/parser/samples/non-unique-attribute-event-handler/input.svelte
+++ /dev/null
@@ -1 +0,0 @@
-
diff --git a/test/parser/samples/non-unique-attribute-event-handler/output.json b/test/parser/samples/non-unique-attribute-event-handler/output.json
deleted file mode 100644
index 9579fe5b4c..0000000000
--- a/test/parser/samples/non-unique-attribute-event-handler/output.json
+++ /dev/null
@@ -1,96 +0,0 @@
-{
- "html": {
- "start": 0,
- "end": 87,
- "type": "Fragment",
- "children": [
- {
- "start": 0,
- "end": 87,
- "type": "Element",
- "name": "button",
- "attributes": [
- {
- "start": 8,
- "end": 45,
- "type": "EventHandler",
- "name": "click",
- "modifiers": [],
- "expression": {
- "type": "ArrowFunctionExpression",
- "start": 19,
- "end": 43,
- "id": null,
- "expression": true,
- "generator": false,
- "async": false,
- "params": [],
- "body": {
- "type": "AssignmentExpression",
- "start": 25,
- "end": 43,
- "operator": "=",
- "left": {
- "type": "Identifier",
- "start": 25,
- "end": 32,
- "name": "visible"
- },
- "right": {
- "type": "UnaryExpression",
- "start": 35,
- "end": 43,
- "operator": "!",
- "prefix": true,
- "argument": {
- "type": "Identifier",
- "start": 36,
- "end": 43,
- "name": "visible"
- }
- }
- }
- }
- },
- {
- "start": 46,
- "end": 77,
- "type": "EventHandler",
- "name": "click",
- "modifiers": [],
- "expression": {
- "type": "ArrowFunctionExpression",
- "start": 57,
- "end": 75,
- "id": null,
- "expression": true,
- "generator": false,
- "async": false,
- "params": [],
- "body": {
- "type": "AssignmentExpression",
- "start": 63,
- "end": 75,
- "operator": "=",
- "left": {
- "type": "Identifier",
- "start": 63,
- "end": 67,
- "name": "ajax"
- },
- "right": {
- "type": "Literal",
- "start": 70,
- "end": 75,
- "value": false,
- "raw": "false"
- }
- }
- }
- }
- ],
- "children": []
- }
- ]
- }
-}
diff --git a/test/runtime/samples/event-handler-multiple/_config.js b/test/runtime/samples/event-handler-multiple/_config.js
new file mode 100644
index 0000000000..cf17c61f60
--- /dev/null
+++ b/test/runtime/samples/event-handler-multiple/_config.js
@@ -0,0 +1,14 @@
+export default {
+ html: `
+
+ `,
+
+ async test({ assert, component, target, window }) {
+ const button = target.querySelector('button');
+ const event = new window.MouseEvent('click');
+
+ await button.dispatchEvent(event);
+ assert.equal(component.clickHandlerOne, 1);
+ assert.equal(component.clickHandlerTwo, 1);
+ }
+};
diff --git a/test/runtime/samples/event-handler-multiple/main.svelte b/test/runtime/samples/event-handler-multiple/main.svelte
new file mode 100644
index 0000000000..f327a7fd2a
--- /dev/null
+++ b/test/runtime/samples/event-handler-multiple/main.svelte
@@ -0,0 +1,6 @@
+
+
+
From 5e8383cf37601523a1c930ac354de0af4e752f7e Mon Sep 17 00:00:00 2001
From: "Daniel J. Wilson"
Date: Sat, 11 May 2019 23:42:32 -0400
Subject: [PATCH 016/163] Replace tag with attribute for alt
Being an attribute, alt should be mentioned as such.
---
.../tutorial/01-introduction/03-dynamic-attributes/text.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/site/content/tutorial/01-introduction/03-dynamic-attributes/text.md b/site/content/tutorial/01-introduction/03-dynamic-attributes/text.md
index 6deaad5837..1fd6774b8a 100644
--- a/site/content/tutorial/01-introduction/03-dynamic-attributes/text.md
+++ b/site/content/tutorial/01-introduction/03-dynamic-attributes/text.md
@@ -16,7 +16,7 @@ That's better. But Svelte is giving us a warning:
When building web apps, it's important to make sure that they're *accessible* to the broadest possible userbase, including people with (for example) impaired vision or motion, or people without powerful hardware or good internet connections. Accessibility (shortened to a11y) isn't always easy to get right, but Svelte will help by warning you if you write inaccessible markup.
-In this case, we're missing the `alt` tag that describes the image for people using screenreaders, or people with slow or flaky internet connections that can't download the image. Let's add one:
+In this case, we're missing the `alt` attribute that describes the image for people using screenreaders, or people with slow or flaky internet connections that can't download the image. Let's add one:
```html
From 66a4c1a9bccbdbbfad986d14f6efab801d807681 Mon Sep 17 00:00:00 2001
From: "Daniel J. Wilson"
Date: Sun, 12 May 2019 00:19:53 -0400
Subject: [PATCH 017/163] Pluralize elements
---
site/content/tutorial/06-bindings/01-text-inputs/text.md | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/site/content/tutorial/06-bindings/01-text-inputs/text.md b/site/content/tutorial/06-bindings/01-text-inputs/text.md
index 0082586133..cb11b3b58a 100644
--- a/site/content/tutorial/06-bindings/01-text-inputs/text.md
+++ b/site/content/tutorial/06-bindings/01-text-inputs/text.md
@@ -4,7 +4,7 @@ title: Text inputs
As a general rule, data flow in Svelte is *top down* — a parent component can set props on a child component, and a component can set attributes on an element, but not the other way around.
-Sometimes it's useful to break that rule. Take the case of the `` element in this component — we *could* add an `on:input` event handler that set the value of `name` to `event.target.value`, but it's a bit... boilerplatey. It gets even worse with other kinds of form element, as we'll see.
+Sometimes it's useful to break that rule. Take the case of the `` element in this component — we *could* add an `on:input` event handler that set the value of `name` to `event.target.value`, but it's a bit... boilerplatey. It gets even worse with other kinds of form elements, as we'll see.
Instead, we can use the `bind:value` directive:
@@ -12,4 +12,4 @@ Instead, we can use the `bind:value` directive:
```
-This means that not only will changes to the value of `name` update the input value, but changes to the input value will update `name`.
\ No newline at end of file
+This means that not only will changes to the value of `name` update the input value, but changes to the input value will update `name`.
From 1b4446030b8641a2859b507522f3016f579cea20 Mon Sep 17 00:00:00 2001
From: pngwn
Date: Sun, 12 May 2019 10:13:52 +0100
Subject: [PATCH 018/163] Update animate example to use animate directive and
built-in crossfade function.
---
.../10-animations/00-animate/App.svelte | 7 +-
.../10-animations/00-animate/crossfade.js | 65 -------------------
2 files changed, 5 insertions(+), 67 deletions(-)
delete mode 100644 site/content/examples/10-animations/00-animate/crossfade.js
diff --git a/site/content/examples/10-animations/00-animate/App.svelte b/site/content/examples/10-animations/00-animate/App.svelte
index c46096c204..3b9da92a27 100644
--- a/site/content/examples/10-animations/00-animate/App.svelte
+++ b/site/content/examples/10-animations/00-animate/App.svelte
@@ -1,8 +1,9 @@
+
+
foo {foo}
\ No newline at end of file
diff --git a/test/runtime/samples/component-namespaced/_config.js b/test/runtime/samples/component-namespaced/_config.js
new file mode 100644
index 0000000000..e5f4c680da
--- /dev/null
+++ b/test/runtime/samples/component-namespaced/_config.js
@@ -0,0 +1,16 @@
+export default {
+ props: {
+ a: 1
+ },
+
+ html: `
+
`,
+ before_test() {
+ delete require.cache[path.resolve(__dirname, 'components.js')];
+ },
+
test({ assert, component, target }) {
component.a = 2;
assert.htmlEqual(target.innerHTML, `
diff --git a/test/server-side-rendering/index.js b/test/server-side-rendering/index.js
index 2806a1b5c2..9f67ee06e9 100644
--- a/test/server-side-rendering/index.js
+++ b/test/server-side-rendering/index.js
@@ -97,7 +97,7 @@ describe("ssr", () => {
const cwd = path.resolve("test/runtime/samples", dir);
Object.keys(require.cache)
- .filter(x => x.startsWith(cwd))
+ .filter(x => x.endsWith('.svelte'))
.forEach(file => {
delete require.cache[file];
});
From 830e3d01cf439f446e1cabcdd44e53310316195d Mon Sep 17 00:00:00 2001
From: Rich Harris
Date: Sun, 12 May 2019 14:24:19 -0400
Subject: [PATCH 026/163] failing vars test
---
.../vars/samples/component-namespaced/_config.js | 16 ++++++++++++++++
.../samples/component-namespaced/input.svelte | 5 +++++
2 files changed, 21 insertions(+)
create mode 100644 test/vars/samples/component-namespaced/_config.js
create mode 100644 test/vars/samples/component-namespaced/input.svelte
diff --git a/test/vars/samples/component-namespaced/_config.js b/test/vars/samples/component-namespaced/_config.js
new file mode 100644
index 0000000000..ac63873967
--- /dev/null
+++ b/test/vars/samples/component-namespaced/_config.js
@@ -0,0 +1,16 @@
+export default {
+ test(assert, vars) {
+ assert.deepEqual(vars, [
+ {
+ name: 'NS',
+ export_name: null,
+ injected: false,
+ module: false,
+ mutated: false,
+ reassigned: false,
+ referenced: true,
+ writable: false
+ }
+ ]);
+ }
+};
\ No newline at end of file
diff --git a/test/vars/samples/component-namespaced/input.svelte b/test/vars/samples/component-namespaced/input.svelte
new file mode 100644
index 0000000000..996d2d8769
--- /dev/null
+++ b/test/vars/samples/component-namespaced/input.svelte
@@ -0,0 +1,5 @@
+
+
+
\ No newline at end of file
From f9a66e558b3ca6f851ad1738bed8c4baac96d60f Mon Sep 17 00:00:00 2001
From: Rich Harris
Date: Sun, 12 May 2019 14:25:44 -0400
Subject: [PATCH 027/163] failing missing-declaration test
---
test/validator/samples/component-namespaced/input.svelte | 5 +++++
test/validator/samples/component-namespaced/warnings.json | 1 +
2 files changed, 6 insertions(+)
create mode 100644 test/validator/samples/component-namespaced/input.svelte
create mode 100644 test/validator/samples/component-namespaced/warnings.json
diff --git a/test/validator/samples/component-namespaced/input.svelte b/test/validator/samples/component-namespaced/input.svelte
new file mode 100644
index 0000000000..996d2d8769
--- /dev/null
+++ b/test/validator/samples/component-namespaced/input.svelte
@@ -0,0 +1,5 @@
+
+
+
\ No newline at end of file
diff --git a/test/validator/samples/component-namespaced/warnings.json b/test/validator/samples/component-namespaced/warnings.json
new file mode 100644
index 0000000000..0637a088a0
--- /dev/null
+++ b/test/validator/samples/component-namespaced/warnings.json
@@ -0,0 +1 @@
+[]
\ No newline at end of file
From 85543f54dd74cc6c67a3be50878e87ffadde92f7 Mon Sep 17 00:00:00 2001
From: Rich Harris
Date: Sun, 12 May 2019 14:31:11 -0400
Subject: [PATCH 028/163] fix vars/warnings
---
src/compile/Component.ts | 6 ++----
src/compile/nodes/Action.ts | 2 +-
src/compile/nodes/Animation.ts | 2 +-
src/compile/nodes/InlineComponent.ts | 5 +++--
src/compile/nodes/Transition.ts | 2 +-
src/compile/nodes/shared/Expression.ts | 2 +-
6 files changed, 9 insertions(+), 10 deletions(-)
diff --git a/src/compile/Component.ts b/src/compile/Component.ts
index aad5e98413..dd41a0a645 100644
--- a/src/compile/Component.ts
+++ b/src/compile/Component.ts
@@ -759,7 +759,7 @@ export default class Component {
const { name } = object;
if (name[0] === '$' && !scope.has(name)) {
- component.warn_if_undefined(object, null);
+ component.warn_if_undefined(name, object, null);
}
}
},
@@ -1202,9 +1202,7 @@ export default class Component {
return `ctx.${name}`;
}
- warn_if_undefined(node, template_scope: TemplateScope) {
- let { name } = node;
-
+ warn_if_undefined(name: string, node, template_scope: TemplateScope) {
if (name[0] === '$') {
name = name.slice(1);
this.has_reactive_assignments = true; // TODO does this belong here?
diff --git a/src/compile/nodes/Action.ts b/src/compile/nodes/Action.ts
index feec3fada8..77b9e3c846 100644
--- a/src/compile/nodes/Action.ts
+++ b/src/compile/nodes/Action.ts
@@ -11,7 +11,7 @@ export default class Action extends Node {
constructor(component: Component, parent, scope, info) {
super(component, parent, scope, info);
- component.warn_if_undefined(info, scope);
+ component.warn_if_undefined(info.name, info, scope);
this.name = info.name;
component.qualify(info.name);
diff --git a/src/compile/nodes/Animation.ts b/src/compile/nodes/Animation.ts
index 638a88b169..6ccdbb0803 100644
--- a/src/compile/nodes/Animation.ts
+++ b/src/compile/nodes/Animation.ts
@@ -10,7 +10,7 @@ export default class Animation extends Node {
constructor(component: Component, parent, scope, info) {
super(component, parent, scope, info);
- component.warn_if_undefined(info, scope);
+ component.warn_if_undefined(info.name, info, scope);
this.name = info.name;
component.qualify(info.name);
diff --git a/src/compile/nodes/InlineComponent.ts b/src/compile/nodes/InlineComponent.ts
index 0d8801aad1..3359e981ed 100644
--- a/src/compile/nodes/InlineComponent.ts
+++ b/src/compile/nodes/InlineComponent.ts
@@ -23,8 +23,9 @@ export default class InlineComponent extends Node {
super(component, parent, scope, info);
if (info.name !== 'svelte:component' && info.name !== 'svelte:self') {
- component.warn_if_undefined(info, scope);
- component.add_reference(info.name);
+ const name = info.name.split('.')[0]; // accommodate namespaces
+ component.warn_if_undefined(name, info, scope);
+ component.add_reference(name);
}
this.name = info.name;
diff --git a/src/compile/nodes/Transition.ts b/src/compile/nodes/Transition.ts
index c3f22d888e..82eb578f0f 100644
--- a/src/compile/nodes/Transition.ts
+++ b/src/compile/nodes/Transition.ts
@@ -12,7 +12,7 @@ export default class Transition extends Node {
constructor(component: Component, parent, scope, info) {
super(component, parent, scope, info);
- component.warn_if_undefined(info, scope);
+ component.warn_if_undefined(info.name, info, scope);
this.name = info.name;
component.qualify(info.name);
diff --git a/src/compile/nodes/shared/Expression.ts b/src/compile/nodes/shared/Expression.ts
index 22cb403f75..fc188e9673 100644
--- a/src/compile/nodes/shared/Expression.ts
+++ b/src/compile/nodes/shared/Expression.ts
@@ -149,7 +149,7 @@ export default class Expression {
}
component.add_reference(name);
- component.warn_if_undefined(nodes[0], template_scope);
+ component.warn_if_undefined(name, nodes[0], template_scope);
}
this.skip();
From c72e863a7f832b318e84513b7f34332281835a28 Mon Sep 17 00:00:00 2001
From: pngwn
Date: Sun, 12 May 2019 20:27:19 +0100
Subject: [PATCH 029/163] Document svelte/transition - fade, fly, slide, scale,
draw.
---
site/content/docs/03-run-time.md | 200 ++++++++++++++++++++++++++++++-
1 file changed, 197 insertions(+), 3 deletions(-)
diff --git a/site/content/docs/03-run-time.md b/site/content/docs/03-run-time.md
index fe981896b9..dde8d18bcf 100644
--- a/site/content/docs/03-run-time.md
+++ b/site/content/docs/03-run-time.md
@@ -517,10 +517,204 @@ Both `set` and `update` can take a second argument — an object with `hard` or
### `svelte/transition`
-TODO
+The `svelte/transition` module exports six functions: `fade`, `fly`, `slide`, `scale`, `draw` and `crossfade`. They are for use with svelte [`transitions`](docs#Transitions).
+
+#### `fade`
+
+```sv
+transition:fade={params}
+```
+```sv
+in:fade={params}
+```
+```sv
+out:fade={params}
+```
+
+---
+
+Animates the opacity of an element from 0 to the current opacity for `in` transitions and from the current opacity to 0 for `out` transitions.
+
+`fade` accepts the following parameters:
+
+* `delay` (`number`, default 0) — milliseconds before starting
+* `duration` (`number`, default 400) — milliseconds the transition lasts
+
+You can see the `fade` transition in action in the [transition tutorial](tutorial/transition).
+
+```html
+
+
+{#if condition}
+
+ fades in and out
+
+{/if}
+```
+
+#### `fly`
+
+```sv
+transition:fly={params}
+```
+```sv
+in:fly={params}
+```
+```sv
+out:fly={params}
+```
+
+---
+
+Animates the x and y positions and the opacity of an element. `in` transitions animate from an element's current (default) values to the provided values, passed as parameters. `out` transitions animate from the provided values to an element's default values.
+
+`fly` accepts the following parameters:
+
+* `delay` (`number`, default 0) — milliseconds before starting
+* `duration` (`number`, default 400) — milliseconds the transition lasts
+* `easing` (`function`, default `cubicOut`) — an [easing function](docs#svelte_easing)
+* `x` (`number`, default 0) - the x offset to animate out to and in from
+* `y` (`number`, default 0) - the y offset to animate out to and in from
+* `opacity` (`number`, default 0) - the opacity value to animate out to and in from
+
+You can see the `fly` transition in action in the [transition tutorial](tutorial/adding-parameters-to-transitions).
+
+```html
+
+
+{#if condition}
+
+ flies in and out
+
+{/if}
+```
+
+#### `slide`
+
+```sv
+transition:slide={params}
+```
+```sv
+in:slide={params}
+```
+```sv
+out:slide={params}
+```
+
+---
+
+Slides an element in and out.
+
+`slide` accepts the following parameters:
+
+* `delay` (`number`, default 0) — milliseconds before starting
+* `duration` (`number`, default 400) — milliseconds the transition lasts
+* `easing` (`function`, default `cubicOut`) — an [easing function](docs#svelte_easing)
+
+```html
+
+
+{#if condition}
+
+ flies in and out
+
+{/if}
+```
+
+#### `scale`
+
+```sv
+transition:scale={params}
+```
+```sv
+in:scale={params}
+```
+```sv
+out:scale={params}
+```
+
+---
+
+Animates the opacity and scale of an element. `in` transitions animate from an element's current (default) values to the provided values, passed as parameters. `out` transitions animate from the provided values to an element's default values.
+
+`scale` accepts the following parameters:
+
+* `delay` (`number`, default 0) — milliseconds before starting
+* `duration` (`number`, default 400) — milliseconds the transition lasts
+* `easing` (`function`, default `cubicOut`) — an [easing function](docs#svelte_easing)
+* `start` (`number`, default 0) - the scale value to animate out to and in from
+* `opacity` (`number`, default 0) - the opacity value to animate out to and in from
+
+```html
+
+
+{#if condition}
+
+ scales in and out
+
+{/if}
+```
+
+#### `draw`
+
+```sv
+transition:draw={params}
+```
+```sv
+in:draw={params}
+```
+```sv
+out:draw={params}
+```
+
+---
+
+Animates the stroke of an SVG path, like a snake in a tube. `in` transitions being with the path invisible and draw the path to the screen over time. `out` transitions start in a visible state and gradually erases the path. `draw` only works with SVG Path elements.
+
+`scale` accepts the following parameters:
+
+* `delay` (`number`, default 0) — milliseconds before starting
+* `speed` (`number`, default undefined) - the speed of the animation, see below.
+* `duration` (`number` | `function`, default 800) — milliseconds the transition lasts
+* `easing` (`function`, default `cubicInOut`) — an [easing function](docs#svelte_easing)
+
+The `speed` parameter is a means of setting the duration of the transition relative to the path's length. It is modifier that is applied to the length of the path: `duration = length / speed`. A path that is 1000 pixels with a speed of 1 will have a duration of `1000ms`, setting the speed to `0.5` will halve that duration and setting it to `2` will double it.
+
+```html
+
+
+
+
+```
+
+
+
+
-* fade, fly, slide, scale, draw
-* crossfade...
### `svelte/animate`
From 0c76b9637a0110fc75974b9d8ccf17d89cc27606 Mon Sep 17 00:00:00 2001
From: Rich Harris
Date: Sun, 12 May 2019 16:22:37 -0400
Subject: [PATCH 030/163] minor correction
---
site/content/docs/03-run-time.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/site/content/docs/03-run-time.md b/site/content/docs/03-run-time.md
index dde8d18bcf..dc52a9dec0 100644
--- a/site/content/docs/03-run-time.md
+++ b/site/content/docs/03-run-time.md
@@ -680,7 +680,7 @@ out:draw={params}
---
-Animates the stroke of an SVG path, like a snake in a tube. `in` transitions being with the path invisible and draw the path to the screen over time. `out` transitions start in a visible state and gradually erases the path. `draw` only works with SVG Path elements.
+Animates the stroke of an SVG element, like a snake in a tube. `in` transitions being 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:
From 438acdc09ac93d217f5de4a517217db6570d7dbc Mon Sep 17 00:00:00 2001
From: Conduitry
Date: Sun, 12 May 2019 16:32:22 -0400
Subject: [PATCH 031/163] typo
---
site/content/docs/03-run-time.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/site/content/docs/03-run-time.md b/site/content/docs/03-run-time.md
index dc52a9dec0..1beacc4169 100644
--- a/site/content/docs/03-run-time.md
+++ b/site/content/docs/03-run-time.md
@@ -680,7 +680,7 @@ out:draw={params}
---
-Animates the stroke of an SVG element, like a snake in a tube. `in` transitions being 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 ``.
+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:
From 3b4c6ed4ebb31e2cd662548024967100783100ad Mon Sep 17 00:00:00 2001
From: Sander Hahn
Date: Fri, 10 May 2019 18:56:54 +0200
Subject: [PATCH 032/163] typescript version of store
---
.gitignore | 2 +-
package.json | 3 +-
rollup.config.js | 31 ++++++++++-
src/store.ts | 130 +++++++++++++++++++++++++++++++++++++++++++++++
store.mjs | 85 -------------------------------
tsconfig.json | 3 +-
6 files changed, 165 insertions(+), 89 deletions(-)
create mode 100644 src/store.ts
delete mode 100644 store.mjs
diff --git a/.gitignore b/.gitignore
index 06671edc2b..7aa75b29f4 100644
--- a/.gitignore
+++ b/.gitignore
@@ -6,7 +6,7 @@ node_modules
/compiler.js
/index.js
/internal.*
-/store.js
+/store.*
/easing.js
/motion.*
/transition.js
diff --git a/package.json b/package.json
index ccbedde168..e0364bfa3a 100644
--- a/package.json
+++ b/package.json
@@ -31,7 +31,8 @@
"dev": "rollup -cw",
"pretest": "npm run build",
"posttest": "agadoo src/internal/index.js",
- "prepublishOnly": "export PUBLISH=true && npm run lint && npm test"
+ "prepublishOnly": "export PUBLISH=true && npm run lint && npm test",
+ "tsd": "tsc -d src/store.ts --outDir ."
},
"repository": {
"type": "git",
diff --git a/rollup.config.js b/rollup.config.js
index f7b2d07d4b..0d19e59d4a 100644
--- a/rollup.config.js
+++ b/rollup.config.js
@@ -87,8 +87,37 @@ export default [
external: id => id.startsWith('svelte/')
},
+ /* store.mjs */
+ {
+ input: `src/store.ts`,
+ output: [
+ {
+ file: `store.mjs`,
+ format: 'esm',
+ paths: id => id.startsWith('svelte/') && id.replace('svelte', '.')
+ },
+ {
+ file: `store.js`,
+ format: 'cjs',
+ paths: id => id.startsWith('svelte/') && id.replace('svelte', '.')
+ }
+ ],
+ plugins: [
+ is_publish
+ ? typescript({
+ include: 'src/**',
+ exclude: 'src/internal/**',
+ typescript: require('typescript')
+ })
+ : sucrase({
+ transforms: ['typescript']
+ })
+ ],
+ external: id => id.startsWith('svelte/')
+ },
+
// everything else
- ...['index', 'store', 'easing', 'transition', 'animate'].map(name => ({
+ ...['index', 'easing', 'transition', 'animate'].map(name => ({
input: `${name}.mjs`,
output: {
file: `${name}.js`,
diff --git a/src/store.ts b/src/store.ts
new file mode 100644
index 0000000000..e27059a4d7
--- /dev/null
+++ b/src/store.ts
@@ -0,0 +1,130 @@
+import { run_all, noop, safe_not_equal } from './internal/utils';
+
+type Subscriber = (value: T) => void;
+
+type Unsubscriber = () => void;
+
+type Updater = (value: T) => T;
+
+type Invalidater = (value?: T) => void;
+
+type StartStopNotifier = (set: Subscriber) => Unsubscriber | void;
+
+export interface ReadableStore {
+ subscribe(run: Subscriber, invalidate?: Invalidater): Unsubscriber;
+}
+
+export interface WritableStore extends ReadableStore {
+ set(value: T): void;
+ update(updater: Updater): void;
+}
+
+type SubscribeInvalidateTuple = [Subscriber, Invalidater];
+
+export function readable(value: T, start: StartStopNotifier): ReadableStore {
+ return {
+ subscribe: writable(value, start).subscribe,
+ };
+}
+
+export function writable(value: T, start: StartStopNotifier = noop): WritableStore {
+ let stop: Unsubscriber;
+ const subscribers: Array> = [];
+
+ function set(new_value: T): void {
+ if (safe_not_equal(value, new_value)) {
+ value = new_value;
+ if (!stop) {
+ return; // not ready
+ }
+ subscribers.forEach((s) => s[1]());
+ subscribers.forEach((s) => s[0](value));
+ }
+ }
+
+ function update(fn: Updater): void {
+ set(fn(value));
+ }
+
+ function subscribe(run: Subscriber, invalidate: Invalidater = noop): Unsubscriber {
+ const subscriber: SubscribeInvalidateTuple = [run, invalidate];
+ subscribers.push(subscriber);
+ if (subscribers.length === 1) {
+ stop = start(set) || noop;
+ }
+ run(value);
+
+ return () => {
+ const index = subscribers.indexOf(subscriber);
+ if (index !== -1) {
+ subscribers.splice(index, 1);
+ }
+ if (subscribers.length === 0) {
+ stop();
+ }
+ };
+ }
+
+ return { set, update, subscribe };
+}
+
+export function derived(
+ stores: ReadableStore | Array>,
+ fn: (values: T | T[], set?: Subscriber) => T | Unsubscriber | void,
+ initial_value: T): ReadableStore {
+
+ const single = !Array.isArray(stores);
+ const stores_array: Array> = single
+ ? [stores as ReadableStore]
+ : stores as Array>;
+
+ const auto = fn.length < 2;
+
+ return readable(initial_value, (set) => {
+ let inited = false;
+ const values: T[] = [];
+
+ let pending = 0;
+ let cleanup = noop;
+
+ const sync = () => {
+ if (pending) {
+ return;
+ }
+ cleanup();
+ const result = fn(single ? values[0] : values, set);
+ if (auto) {
+ set(result as T);
+ } else {
+ cleanup = result as Unsubscriber || noop;
+ }
+ };
+
+ const unsubscribers = stores_array.map((store, i) => store.subscribe(
+ (value) => {
+ values[i] = value;
+ pending &= ~(1 << i);
+ if (inited) {
+ sync();
+ }
+ },
+ () => {
+ pending |= (1 << i);
+ }),
+ );
+
+ inited = true;
+ sync();
+
+ return function stop() {
+ run_all(unsubscribers);
+ cleanup();
+ };
+ });
+}
+
+export function get(store: ReadableStore): T {
+ let value: T | undefined;
+ store.subscribe((_: T) => value = _)();
+ return value as T;
+}
diff --git a/store.mjs b/store.mjs
deleted file mode 100644
index 624ede3dde..0000000000
--- a/store.mjs
+++ /dev/null
@@ -1,85 +0,0 @@
-import { run_all, noop, get_store_value, safe_not_equal } from './internal';
-
-export function readable(value, start) {
- return {
- subscribe: writable(value, start).subscribe
- };
-}
-
-export function writable(value, start = noop) {
- let stop;
- const subscribers = [];
-
- function set(new_value) {
- if (safe_not_equal(value, new_value)) {
- value = new_value;
- if (!stop) return; // not ready
- subscribers.forEach(s => s[1]());
- subscribers.forEach(s => s[0](value));
- }
- }
-
- function update(fn) {
- set(fn(value));
- }
-
- function subscribe(run, invalidate = noop) {
- const subscriber = [run, invalidate];
- subscribers.push(subscriber);
- if (subscribers.length === 1) stop = start(set) || noop;
- run(value);
-
- return () => {
- const index = subscribers.indexOf(subscriber);
- if (index !== -1) subscribers.splice(index, 1);
- if (subscribers.length === 0) stop();
- };
- }
-
- return { set, update, subscribe };
-}
-
-export function derived(stores, fn, initial_value) {
- const single = !Array.isArray(stores);
- if (single) stores = [stores];
-
- const auto = fn.length < 2;
- let value = {};
-
- return readable(initial_value, set => {
- let inited = false;
- const values = [];
-
- let pending = 0;
- let cleanup = noop;
-
- const sync = () => {
- if (pending) return;
- cleanup();
- const result = fn(single ? values[0] : values, set);
- if (auto) set(result);
- else cleanup = result || noop;
- };
-
- const unsubscribers = stores.map((store, i) => store.subscribe(
- value => {
- values[i] = value;
- pending &= ~(1 << i);
- if (inited) sync();
- },
- () => {
- pending |= (1 << i);
- })
- );
-
- inited = true;
- sync();
-
- return function stop() {
- run_all(unsubscribers);
- cleanup();
- };
- });
-}
-
-export { get_store_value as get };
diff --git a/tsconfig.json b/tsconfig.json
index fdb7367e05..5da2d13a01 100644
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -7,7 +7,8 @@
"allowJs": true,
"lib": ["es5", "es6", "dom"],
"importHelpers": true,
- "moduleResolution": "node"
+ "moduleResolution": "node",
+ "strict": true
},
"include": [
"src"
From b6b7c621d062752121aced2a9108b1cc3c777179 Mon Sep 17 00:00:00 2001
From: Sander Hahn
Date: Mon, 13 May 2019 00:25:32 +0200
Subject: [PATCH 033/163] run tsd on prepare
---
package.json | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/package.json b/package.json
index e0364bfa3a..24feedd1e7 100644
--- a/package.json
+++ b/package.json
@@ -27,7 +27,7 @@
"precodecov": "npm run coverage",
"lint": "eslint src test/*.js",
"build": "rollup -c",
- "prepare": "npm run build",
+ "prepare": "npm run build && npm run tsd",
"dev": "rollup -cw",
"pretest": "npm run build",
"posttest": "agadoo src/internal/index.js",
From fbb6c9fd4e4197f0edf598f56eeb1066fa52b915 Mon Sep 17 00:00:00 2001
From: Rich Harris
Date: Mon, 13 May 2019 09:27:28 -0400
Subject: [PATCH 034/163] -> v3.3.0
---
CHANGELOG.md | 6 ++++++
package.json | 2 +-
2 files changed, 7 insertions(+), 1 deletion(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 239f2d28e3..1d6a7b34dd 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,11 @@
# Svelte changelog
+## 3.3.0
+
+* Allow multiple event listeners on a single node ([#2688](https://github.com/sveltejs/svelte/issues/2688))
+* Allow derivers to return a cleanup function ([#2553](https://github.com/sveltejs/svelte/issues/2553))
+* Support namespaced components (``) ([#2743](https://github.com/sveltejs/svelte/pull/2743))
+
## 3.2.2
* Add `window` and `document` to expected globals ([#2722](https://github.com/sveltejs/svelte/pull/2722))
diff --git a/package.json b/package.json
index ccbedde168..437eef8d0e 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "svelte",
- "version": "3.2.2",
+ "version": "3.3.0",
"description": "Cybernetically enhanced web apps",
"module": "index.mjs",
"main": "index",
From 690f163e889f9c93146419b9c03aadfd0f5176e5 Mon Sep 17 00:00:00 2001
From: Colin Casey
Date: Mon, 13 May 2019 15:16:51 -0300
Subject: [PATCH 035/163] FIX #2417: allows custom element to be defined
without a tag * warning given on compile if tag is absent * no warning if tag
is set to `null`
---
src/compile/Component.ts | 14 +++++++++-----
src/compile/render-dom/index.ts | 8 ++++++--
test/custom-elements/index.js | 15 +++++++++++++++
.../samples/no-tag-warning/_config.js | 17 +++++++++++++++++
.../samples/no-tag-warning/main.svelte | 7 +++++++
.../samples/no-tag-warning/test.js | 12 ++++++++++++
test/custom-elements/samples/no-tag/_config.js | 3 +++
test/custom-elements/samples/no-tag/main.svelte | 7 +++++++
test/custom-elements/samples/no-tag/test.js | 12 ++++++++++++
9 files changed, 88 insertions(+), 7 deletions(-)
create mode 100644 test/custom-elements/samples/no-tag-warning/_config.js
create mode 100644 test/custom-elements/samples/no-tag-warning/main.svelte
create mode 100644 test/custom-elements/samples/no-tag-warning/test.js
create mode 100644 test/custom-elements/samples/no-tag/_config.js
create mode 100644 test/custom-elements/samples/no-tag/main.svelte
create mode 100644 test/custom-elements/samples/no-tag/test.js
diff --git a/src/compile/Component.ts b/src/compile/Component.ts
index dd41a0a645..cbebeede49 100644
--- a/src/compile/Component.ts
+++ b/src/compile/Component.ts
@@ -152,10 +152,14 @@ export default class Component {
this.namespace = namespaces[this.component_options.namespace] || this.component_options.namespace;
if (compile_options.customElement) {
- this.tag = this.component_options.tag || compile_options.tag;
- if (!this.tag) {
- throw new Error(`Cannot compile to a custom element without specifying a tag name via options.tag or `);
+ if (this.component_options.tag === undefined && compile_options.tag === undefined) {
+ const svelteOptions = ast.html.children.find(child => child.name === 'svelte:options');
+ this.warn(svelteOptions, {
+ code: 'custom-element-no-tag',
+ message: `No custom element 'tag' option was specified. To automatically register a custom element, specify a name with a hyphen in it, e.g. . To hide this warning, use `
+ });
}
+ this.tag = this.component_options.tag || compile_options.tag;
} else {
this.tag = this.name;
}
@@ -1265,9 +1269,9 @@ function process_component_options(component: Component, nodes) {
const message = `'tag' must be a string literal`;
const tag = get_value(attribute, code, message);
- if (typeof tag !== 'string') component.error(attribute, { code, message });
+ if (typeof tag !== 'string' && tag !== null) component.error(attribute, { code, message });
- if (!/^[a-zA-Z][a-zA-Z0-9]*-[a-zA-Z0-9-]+$/.test(tag)) {
+ if (tag && !/^[a-zA-Z][a-zA-Z0-9]*-[a-zA-Z0-9-]+$/.test(tag)) {
component.error(attribute, {
code: `invalid-tag-property`,
message: `tag name must be two or more words joined by the '-' character`
diff --git a/src/compile/render-dom/index.ts b/src/compile/render-dom/index.ts
index 0a0743b2a0..8d456a050d 100644
--- a/src/compile/render-dom/index.ts
+++ b/src/compile/render-dom/index.ts
@@ -462,9 +462,13 @@ export default function dom(
${body.length > 0 && body.join('\n\n')}
}
-
- customElements.define("${component.tag}", ${name});
`);
+
+ if (component.tag != null) {
+ builder.add_block(deindent`
+ customElements.define("${component.tag}", ${name});
+ `);
+ }
} else {
const superclass = options.dev ? 'SvelteComponentDev' : 'SvelteComponent';
diff --git a/test/custom-elements/index.js b/test/custom-elements/index.js
index 32e95266ec..5ac0b73bbf 100644
--- a/test/custom-elements/index.js
+++ b/test/custom-elements/index.js
@@ -5,6 +5,7 @@ import { rollup } from 'rollup';
import * as virtual from 'rollup-plugin-virtual';
import * as puppeteer from 'puppeteer';
import { addLineNumbers, loadConfig, loadSvelte } from "../helpers.js";
+import { deepEqual } from 'assert';
const page = `
@@ -59,9 +60,11 @@ describe('custom-elements', function() {
const skip = /\.skip$/.test(dir);
const internal = path.resolve('internal.mjs');
const index = path.resolve('index.mjs');
+ const warnings = [];
(solo ? it.only : skip ? it.skip : it)(dir, async () => {
const config = loadConfig(`./custom-elements/samples/${dir}/_config.js`);
+ const expected_warnings = config.warnings || [];
const bundle = await rollup({
input: `test/custom-elements/samples/${dir}/test.js`,
@@ -84,6 +87,8 @@ describe('custom-elements', function() {
dev: config.dev
});
+ compiled.warnings.forEach(w => warnings.push(w));
+
return compiled.js;
}
}
@@ -112,6 +117,16 @@ describe('custom-elements', function() {
} catch (err) {
console.log(addLineNumbers(code));
throw err;
+ } finally {
+ if (expected_warnings) {
+ deepEqual(warnings.map(w => ({
+ code: w.code,
+ message: w.message,
+ pos: w.pos,
+ start: w.start,
+ end: w.end
+ })), expected_warnings);
+ }
}
});
});
diff --git a/test/custom-elements/samples/no-tag-warning/_config.js b/test/custom-elements/samples/no-tag-warning/_config.js
new file mode 100644
index 0000000000..7cdfdbaec6
--- /dev/null
+++ b/test/custom-elements/samples/no-tag-warning/_config.js
@@ -0,0 +1,17 @@
+export default {
+ warnings: [{
+ code: "custom-element-no-tag",
+ message: "No custom element 'tag' option was specified. To automatically register a custom element, specify a name with a hyphen in it, e.g. . To hide this warning, use ",
+ pos: 0,
+ start: {
+ character: 0,
+ column: 0,
+ line: 1
+ },
+ end: {
+ character: 18,
+ column: 18,
+ line: 1
+ }
+ }]
+};
diff --git a/test/custom-elements/samples/no-tag-warning/main.svelte b/test/custom-elements/samples/no-tag-warning/main.svelte
new file mode 100644
index 0000000000..4f7cdc52ca
--- /dev/null
+++ b/test/custom-elements/samples/no-tag-warning/main.svelte
@@ -0,0 +1,7 @@
+
+
+
+
+
Hello {name}!
diff --git a/test/custom-elements/samples/no-tag-warning/test.js b/test/custom-elements/samples/no-tag-warning/test.js
new file mode 100644
index 0000000000..c77f035088
--- /dev/null
+++ b/test/custom-elements/samples/no-tag-warning/test.js
@@ -0,0 +1,12 @@
+import * as assert from 'assert';
+import CustomElement from './main.svelte';
+
+export default function (target) {
+ customElements.define('no-tag', CustomElement);
+ target.innerHTML = ``;
+
+ const el = target.querySelector('no-tag');
+ const h1 = el.shadowRoot.querySelector('h1');
+
+ assert.equal(h1.textContent, 'Hello world!');
+}
diff --git a/test/custom-elements/samples/no-tag/_config.js b/test/custom-elements/samples/no-tag/_config.js
new file mode 100644
index 0000000000..c81f1a9f82
--- /dev/null
+++ b/test/custom-elements/samples/no-tag/_config.js
@@ -0,0 +1,3 @@
+export default {
+ warnings: []
+};
diff --git a/test/custom-elements/samples/no-tag/main.svelte b/test/custom-elements/samples/no-tag/main.svelte
new file mode 100644
index 0000000000..031bd93694
--- /dev/null
+++ b/test/custom-elements/samples/no-tag/main.svelte
@@ -0,0 +1,7 @@
+
+
+
+
+
Hello {name}!
diff --git a/test/custom-elements/samples/no-tag/test.js b/test/custom-elements/samples/no-tag/test.js
new file mode 100644
index 0000000000..c77f035088
--- /dev/null
+++ b/test/custom-elements/samples/no-tag/test.js
@@ -0,0 +1,12 @@
+import * as assert from 'assert';
+import CustomElement from './main.svelte';
+
+export default function (target) {
+ customElements.define('no-tag', CustomElement);
+ target.innerHTML = ``;
+
+ const el = target.querySelector('no-tag');
+ const h1 = el.shadowRoot.querySelector('h1');
+
+ assert.equal(h1.textContent, 'Hello world!');
+}
From 97184b789caa8885e8f6233ca7c538135c4193db Mon Sep 17 00:00:00 2001
From: Emil Tholin
Date: Tue, 14 May 2019 11:32:37 +0200
Subject: [PATCH 036/163] Set quote_mark to null when closing quote mark is
found
---
src/compile/render-dom/wrappers/Element/StyleAttribute.ts | 4 ++--
test/runtime/samples/attribute-url/_config.js | 8 ++++++++
test/runtime/samples/attribute-url/main.svelte | 6 ++++++
3 files changed, 16 insertions(+), 2 deletions(-)
create mode 100644 test/runtime/samples/attribute-url/_config.js
create mode 100644 test/runtime/samples/attribute-url/main.svelte
diff --git a/src/compile/render-dom/wrappers/Element/StyleAttribute.ts b/src/compile/render-dom/wrappers/Element/StyleAttribute.ts
index b0a3663c63..43524ff372 100644
--- a/src/compile/render-dom/wrappers/Element/StyleAttribute.ts
+++ b/src/compile/render-dom/wrappers/Element/StyleAttribute.ts
@@ -122,7 +122,7 @@ function get_style_value(chunks: Node[]) {
} else if (char === '\\') {
escaped = true;
} else if (char === quote_mark) {
- quote_mark === null;
+ quote_mark = null;
} else if (char === '"' || char === "'") {
quote_mark = char;
} else if (char === ')' && in_url) {
@@ -173,4 +173,4 @@ function get_style_value(chunks: Node[]) {
function is_dynamic(value: Node[]) {
return value.length > 1 || value[0].type !== 'Text';
-}
\ No newline at end of file
+}
diff --git a/test/runtime/samples/attribute-url/_config.js b/test/runtime/samples/attribute-url/_config.js
new file mode 100644
index 0000000000..28bc1bcb0c
--- /dev/null
+++ b/test/runtime/samples/attribute-url/_config.js
@@ -0,0 +1,8 @@
+export default {
+ test({ assert, target }) {
+ const div = target.querySelector( 'div' );
+
+ assert.equal( div.style.backgroundImage, 'url(https://example.com/foo.jpg)');
+ assert.equal( div.style.color, 'red' );
+ }
+};
diff --git a/test/runtime/samples/attribute-url/main.svelte b/test/runtime/samples/attribute-url/main.svelte
new file mode 100644
index 0000000000..357a352aaa
--- /dev/null
+++ b/test/runtime/samples/attribute-url/main.svelte
@@ -0,0 +1,6 @@
+
+
+
{color}
From de60ffb497fc7635a152dee4e2f0c6e37876d898 Mon Sep 17 00:00:00 2001
From: Steven Weathers
Date: Tue, 14 May 2019 20:42:08 -0400
Subject: [PATCH 037/163] Add Thunderdome Link to Who's Using
---
.../routes/_components/WhosUsingSvelte.svelte | 1 +
site/static/organisations/thunderdome.svg | 154 ++++++++++++++++++
2 files changed, 155 insertions(+)
create mode 100644 site/static/organisations/thunderdome.svg
diff --git a/site/src/routes/_components/WhosUsingSvelte.svelte b/site/src/routes/_components/WhosUsingSvelte.svelte
index 1700312055..21c57d065a 100644
--- a/site/src/routes/_components/WhosUsingSvelte.svelte
+++ b/site/src/routes/_components/WhosUsingSvelte.svelte
@@ -54,5 +54,6 @@
+ + your company?
diff --git a/site/static/organisations/thunderdome.svg b/site/static/organisations/thunderdome.svg
new file mode 100644
index 0000000000..c8cbdaf039
--- /dev/null
+++ b/site/static/organisations/thunderdome.svg
@@ -0,0 +1,154 @@
+
+
From 011b33181ee566c1566082dc645da2bb5e412f7e Mon Sep 17 00:00:00 2001
From: Conduitry
Date: Tue, 14 May 2019 23:59:07 -0400
Subject: [PATCH 038/163] site: fix immutable tutorial and example on Firefox
(#2601)
---
.../20-miscellaneous/02-immutable-data/flash.js | 16 +++++++++-------
.../07-svelte-options/app-a/flash.js | 16 +++++++++-------
.../07-svelte-options/app-b/flash.js | 16 +++++++++-------
3 files changed, 27 insertions(+), 21 deletions(-)
diff --git a/site/content/examples/20-miscellaneous/02-immutable-data/flash.js b/site/content/examples/20-miscellaneous/02-immutable-data/flash.js
index 8dff9cbe2f..c788cc6d35 100644
--- a/site/content/examples/20-miscellaneous/02-immutable-data/flash.js
+++ b/site/content/examples/20-miscellaneous/02-immutable-data/flash.js
@@ -1,11 +1,13 @@
export default function flash(element) {
- element.style.transition = 'none';
- element.style.color = 'rgba(255,62,0,1)';
- element.style.backgroundColor = 'rgba(255,62,0,0.2)';
+ requestAnimationFrame(() => {
+ element.style.transition = 'none';
+ element.style.color = 'rgba(255,62,0,1)';
+ element.style.backgroundColor = 'rgba(255,62,0,0.2)';
- setTimeout(() => {
- element.style.transition = 'color 1s, background 1s';
- element.style.color = '';
- element.style.backgroundColor = '';
+ setTimeout(() => {
+ element.style.transition = 'color 1s, background 1s';
+ element.style.color = '';
+ element.style.backgroundColor = '';
+ });
});
}
\ No newline at end of file
diff --git a/site/content/tutorial/16-special-elements/07-svelte-options/app-a/flash.js b/site/content/tutorial/16-special-elements/07-svelte-options/app-a/flash.js
index 8dff9cbe2f..c788cc6d35 100644
--- a/site/content/tutorial/16-special-elements/07-svelte-options/app-a/flash.js
+++ b/site/content/tutorial/16-special-elements/07-svelte-options/app-a/flash.js
@@ -1,11 +1,13 @@
export default function flash(element) {
- element.style.transition = 'none';
- element.style.color = 'rgba(255,62,0,1)';
- element.style.backgroundColor = 'rgba(255,62,0,0.2)';
+ requestAnimationFrame(() => {
+ element.style.transition = 'none';
+ element.style.color = 'rgba(255,62,0,1)';
+ element.style.backgroundColor = 'rgba(255,62,0,0.2)';
- setTimeout(() => {
- element.style.transition = 'color 1s, background 1s';
- element.style.color = '';
- element.style.backgroundColor = '';
+ setTimeout(() => {
+ element.style.transition = 'color 1s, background 1s';
+ element.style.color = '';
+ element.style.backgroundColor = '';
+ });
});
}
\ No newline at end of file
diff --git a/site/content/tutorial/16-special-elements/07-svelte-options/app-b/flash.js b/site/content/tutorial/16-special-elements/07-svelte-options/app-b/flash.js
index 8dff9cbe2f..c788cc6d35 100644
--- a/site/content/tutorial/16-special-elements/07-svelte-options/app-b/flash.js
+++ b/site/content/tutorial/16-special-elements/07-svelte-options/app-b/flash.js
@@ -1,11 +1,13 @@
export default function flash(element) {
- element.style.transition = 'none';
- element.style.color = 'rgba(255,62,0,1)';
- element.style.backgroundColor = 'rgba(255,62,0,0.2)';
+ requestAnimationFrame(() => {
+ element.style.transition = 'none';
+ element.style.color = 'rgba(255,62,0,1)';
+ element.style.backgroundColor = 'rgba(255,62,0,0.2)';
- setTimeout(() => {
- element.style.transition = 'color 1s, background 1s';
- element.style.color = '';
- element.style.backgroundColor = '';
+ setTimeout(() => {
+ element.style.transition = 'color 1s, background 1s';
+ element.style.color = '';
+ element.style.backgroundColor = '';
+ });
});
}
\ No newline at end of file
From 85073dbb723796465cce6f31654f9f1166bd9e71 Mon Sep 17 00:00:00 2001
From: Peter Varholak
Date: Tue, 14 May 2019 22:09:20 -0700
Subject: [PATCH 039/163] add @debug API docs
---
site/content/docs/02-template-syntax.md | 43 +++++++++++++++++++++++++
1 file changed, 43 insertions(+)
diff --git a/site/content/docs/02-template-syntax.md b/site/content/docs/02-template-syntax.md
index c6fd5c8b2d..44256b52e7 100644
--- a/site/content/docs/02-template-syntax.md
+++ b/site/content/docs/02-template-syntax.md
@@ -1261,3 +1261,46 @@ The `` element provides a place to specify per-component compile
```html
```
+
+
+### @debug
+
+```sv
+{@debug variable}
+```
+```sv
+{@debug var1, var2, ..., varN}
+```
+
+---
+
+The `{@debug ...}` tag offers an alternative to `console.log(...)`. It allows you to inspect the value of a specific variable, but additionally pauses code execution when you have devtools open.
+
+```html
+
+
+{@debug user}
+
+
Hello {user.firstname}!
+```
+
+---
+
+`{@debug ...}` can also accept a comma-separated list of values, however it accepts only variable identifiers, and as such does not support inspecting of expressions.
+
+```sv
+# Compiles
+{@debug user}
+{@debug user1, user2, user3}
+
+# WON'T compile
+{@debug user.firstname}
+{@debug myArray[0]}
+{@debug !isReady}
+{@debug typeof user === 'object'}
+```
From 52eda23a53061a951fee06050733556a7ad42773 Mon Sep 17 00:00:00 2001
From: Sander Hahn
Date: Wed, 15 May 2019 07:34:06 +0200
Subject: [PATCH 040/163] advanced type for derived
---
src/store.ts | 32 ++++++++++++++++++-------------
test/{store/index.js => store.ts} | 28 ++++++++++++++++++++++-----
tsconfig.json | 3 +--
3 files changed, 43 insertions(+), 20 deletions(-)
rename test/{store/index.js => store.ts} (88%)
diff --git a/src/store.ts b/src/store.ts
index e27059a4d7..462f155c2a 100644
--- a/src/store.ts
+++ b/src/store.ts
@@ -10,24 +10,24 @@ type Invalidater = (value?: T) => void;
type StartStopNotifier = (set: Subscriber) => Unsubscriber | void;
-export interface ReadableStore {
+export interface Readable {
subscribe(run: Subscriber, invalidate?: Invalidater): Unsubscriber;
}
-export interface WritableStore extends ReadableStore {
+export interface Writable extends Readable {
set(value: T): void;
update(updater: Updater): void;
}
type SubscribeInvalidateTuple = [Subscriber, Invalidater];
-export function readable(value: T, start: StartStopNotifier): ReadableStore {
+export function readable(value: T, start: StartStopNotifier): Readable {
return {
subscribe: writable(value, start).subscribe,
};
}
-export function writable(value: T, start: StartStopNotifier = noop): WritableStore {
+export function writable(value: T, start: StartStopNotifier = noop): Writable {
let stop: Unsubscriber;
const subscribers: Array> = [];
@@ -68,21 +68,27 @@ export function writable(value: T, start: StartStopNotifier = noop): Writa
return { set, update, subscribe };
}
-export function derived(
- stores: ReadableStore | Array>,
- fn: (values: T | T[], set?: Subscriber) => T | Unsubscriber | void,
- initial_value: T): ReadableStore {
+type Stores = Readable | [Readable, ...Array>];
+
+type StoresValues = T extends Readable ? U :
+ { [K in keyof T]: T[K] extends Readable ? U : never };
+
+export function derived(
+ stores: S,
+ fn: (values: StoresValues, set?: Subscriber) => T | Unsubscriber | void,
+ initial_value?: T,
+): Readable {
const single = !Array.isArray(stores);
- const stores_array: Array> = single
- ? [stores as ReadableStore]
- : stores as Array>;
+ const stores_array: Array> = single
+ ? [stores as Readable]
+ : stores as Array>;
const auto = fn.length < 2;
return readable(initial_value, (set) => {
let inited = false;
- const values: T[] = [];
+ const values: StoresValues = [] as StoresValues;
let pending = 0;
let cleanup = noop;
@@ -123,7 +129,7 @@ export function derived(
});
}
-export function get(store: ReadableStore): T {
+export function get(store: Readable): T {
let value: T | undefined;
store.subscribe((_: T) => value = _)();
return value as T;
diff --git a/test/store/index.js b/test/store.ts
similarity index 88%
rename from test/store/index.js
rename to test/store.ts
index 5f9176cffb..9b3d5d1788 100644
--- a/test/store/index.js
+++ b/test/store.ts
@@ -1,5 +1,5 @@
import * as assert from 'assert';
-import { readable, writable, derived, get } from '../../store.js';
+import { readable, writable, derived, get } from '../store';
describe('store', () => {
describe('writable', () => {
@@ -30,10 +30,10 @@ describe('store', () => {
return () => called -= 1;
});
- const unsubscribe1 = store.subscribe(() => {});
+ const unsubscribe1 = store.subscribe(() => { });
assert.equal(called, 1);
- const unsubscribe2 = store.subscribe(() => {});
+ const unsubscribe2 = store.subscribe(() => { });
assert.equal(called, 1);
unsubscribe1();
@@ -73,7 +73,7 @@ describe('store', () => {
set(0);
return () => {
- tick = () => {};
+ tick = () => { };
running = false;
};
});
@@ -242,11 +242,29 @@ describe('store', () => {
assert.deepEqual(cleaned_up, [2, 3, 4]);
});
+
+ it('allows derived with different types', () => {
+ const a = writable('one');
+ const b = writable(1);
+ const c = derived([a, b], ([a, b]) => `${a} ${b}`);
+
+ const values: string[] = [];
+
+ const unsubscribe = c.subscribe(value => {
+ values.push(value);
+ });
+
+ a.set('two');
+ b.set(2);
+ assert.deepEqual(values, 'two 2');
+
+ unsubscribe();
+ });
});
describe('get', () => {
it('gets the current value of a store', () => {
- const store = readable(42, () => {});
+ const store = readable(42, () => { });
assert.equal(get(store), 42);
});
});
diff --git a/tsconfig.json b/tsconfig.json
index 5da2d13a01..fdb7367e05 100644
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -7,8 +7,7 @@
"allowJs": true,
"lib": ["es5", "es6", "dom"],
"importHelpers": true,
- "moduleResolution": "node",
- "strict": true
+ "moduleResolution": "node"
},
"include": [
"src"
From 643aa41b9aa0fcc2a1ba1566388ec0564a57cee4 Mon Sep 17 00:00:00 2001
From: Emil Tholin
Date: Tue, 14 May 2019 13:15:59 +0200
Subject: [PATCH 041/163] Set mutated const variables as reactive dependencies
---
src/compile/Component.ts | 4 +++-
src/compile/render-dom/index.ts | 2 +-
.../reactive-value-mutate-const/_config.js | 17 +++++++++++++++++
.../reactive-value-mutate-const/main.svelte | 9 +++++++++
4 files changed, 30 insertions(+), 2 deletions(-)
create mode 100644 test/runtime/samples/reactive-value-mutate-const/_config.js
create mode 100644 test/runtime/samples/reactive-value-mutate-const/main.svelte
diff --git a/src/compile/Component.ts b/src/compile/Component.ts
index dd41a0a645..259144d691 100644
--- a/src/compile/Component.ts
+++ b/src/compile/Component.ts
@@ -1114,9 +1114,11 @@ export default class Component {
if (!assignee_nodes.has(identifier)) {
const { name } = identifier;
const owner = scope.find_owner(name);
+ const component_var = component.var_lookup.get(name);
+ const is_writable_or_mutated = component_var && (component_var.writable || component_var.mutated);
if (
(!owner || owner === component.instance_scope) &&
- (name[0] === '$' || component.var_lookup.has(name) && component.var_lookup.get(name).writable)
+ (name[0] === '$' || is_writable_or_mutated)
) {
dependencies.add(name);
}
diff --git a/src/compile/render-dom/index.ts b/src/compile/render-dom/index.ts
index 0a0743b2a0..1cd0664ecf 100644
--- a/src/compile/render-dom/index.ts
+++ b/src/compile/render-dom/index.ts
@@ -364,7 +364,7 @@ export default function dom(
}
const variable = component.var_lookup.get(n);
- return variable && variable.writable;
+ return variable && (variable.writable || variable.mutated);
})
.map(n => `$$dirty.${n}`).join(' || ');
diff --git a/test/runtime/samples/reactive-value-mutate-const/_config.js b/test/runtime/samples/reactive-value-mutate-const/_config.js
new file mode 100644
index 0000000000..da0a19dd28
--- /dev/null
+++ b/test/runtime/samples/reactive-value-mutate-const/_config.js
@@ -0,0 +1,17 @@
+export default {
+ html: `
+
+
From 3f312231863237b8240c23775563e95ec4a7ea7d Mon Sep 17 00:00:00 2001
From: Emil Tholin
Date: Wed, 15 May 2019 17:26:57 +0200
Subject: [PATCH 046/163] Add error for missing equals after attribute name
---
src/parse/state/tag.ts | 7 ++++++-
.../samples/attribute-expected-equals/errors.json | 15 +++++++++++++++
.../attribute-expected-equals/input.svelte | 5 +++++
3 files changed, 26 insertions(+), 1 deletion(-)
create mode 100644 test/validator/samples/attribute-expected-equals/errors.json
create mode 100644 test/validator/samples/attribute-expected-equals/input.svelte
diff --git a/src/parse/state/tag.ts b/src/parse/state/tag.ts
index 365085ca08..56195549d8 100644
--- a/src/parse/state/tag.ts
+++ b/src/parse/state/tag.ts
@@ -358,7 +358,7 @@ function read_attribute(parser: Parser, unique_names: Set) {
}
}
- let name = parser.read_until(/(\s|=|\/|>)/);
+ let name = parser.read_until(/[\s=\/>"']/);
if (!name) return null;
let end = parser.index;
@@ -383,6 +383,11 @@ function read_attribute(parser: Parser, unique_names: Set) {
if (parser.eat('=')) {
value = read_attribute_value(parser);
end = parser.index;
+ } else if (parser.match_regex(/["']/)) {
+ parser.error({
+ code: `unexpected-token`,
+ message: `Expected =`
+ }, parser.index);
}
if (type) {
diff --git a/test/validator/samples/attribute-expected-equals/errors.json b/test/validator/samples/attribute-expected-equals/errors.json
new file mode 100644
index 0000000000..a3fa9d3cac
--- /dev/null
+++ b/test/validator/samples/attribute-expected-equals/errors.json
@@ -0,0 +1,15 @@
+[{
+ "code": "unexpected-token",
+ "message": "Expected =",
+ "start": {
+ "line": 5,
+ "column": 9,
+ "character": 50
+ },
+ "end": {
+ "line": 5,
+ "column": 9,
+ "character": 50
+ },
+ "pos": 50
+}]
diff --git a/test/validator/samples/attribute-expected-equals/input.svelte b/test/validator/samples/attribute-expected-equals/input.svelte
new file mode 100644
index 0000000000..91f4b0ca7b
--- /dev/null
+++ b/test/validator/samples/attribute-expected-equals/input.svelte
@@ -0,0 +1,5 @@
+
+
+
Hello {name}!
From 98122bc577f4b23ae92bd372f893b8544eb71e34 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Micha=C5=82=20Terczy=C5=84ski?=
Date: Wed, 15 May 2019 20:31:30 +0200
Subject: [PATCH 047/163] Fix link to license
---
README.md | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/README.md b/README.md
index ac0e4ff366..4d03eca934 100644
--- a/README.md
+++ b/README.md
@@ -2,7 +2,7 @@
-
+
@@ -16,7 +16,7 @@
alt="build status">
-
+
From 51be7cf8e3d440f9195e17ab7defa789e110a911 Mon Sep 17 00:00:00 2001
From: Rich Harris
Date: Wed, 15 May 2019 18:04:25 -0400
Subject: [PATCH 048/163] explain how debug tag without args fires on all state
changes
---
site/content/docs/02-template-syntax.md | 16 ++++++++++------
1 file changed, 10 insertions(+), 6 deletions(-)
diff --git a/site/content/docs/02-template-syntax.md b/site/content/docs/02-template-syntax.md
index 44256b52e7..5b8a22f9bf 100644
--- a/site/content/docs/02-template-syntax.md
+++ b/site/content/docs/02-template-syntax.md
@@ -1266,7 +1266,7 @@ The `` element provides a place to specify per-component compile
### @debug
```sv
-{@debug variable}
+{@debug}
```
```sv
{@debug var1, var2, ..., varN}
@@ -1274,7 +1274,9 @@ The `` element provides a place to specify per-component compile
---
-The `{@debug ...}` tag offers an alternative to `console.log(...)`. It allows you to inspect the value of a specific variable, but additionally pauses code execution when you have devtools open.
+The `{@debug ...}` tag offers an alternative to `console.log(...)`. It logs the values of specific variables whenever they change, and pauses code execution if you have devtools open.
+
+It accepts a comma-separated list of variable names (not arbitrary expressions).
```html
+
+