From 40987b7780ef1865fb94e89b4d2f5a53a71056f9 Mon Sep 17 00:00:00 2001 From: rmacklin <1863540+rmacklin@users.noreply.github.com> Date: Thu, 23 Jul 2020 17:10:41 -0700 Subject: [PATCH 01/94] site: update links in the Sapper intro blog post (#5189) --- ...2017-12-31-sapper-towards-the-ideal-web-app-framework.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) 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 67e732c230..60609609f7 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 @@ -5,7 +5,7 @@ author: Rich Harris authorURL: https://twitter.com/Rich_Harris --- -> Quickstart for the impatient: [the Sapper docs](https://sapper.svelte.technology), and the [starter template](https://github.com/sveltejs/sapper-template) +> Quickstart for the impatient: [the Sapper docs](https://sapper.svelte.dev), and the [starter template](https://github.com/sveltejs/sapper-template) If you had to list the characteristics of the perfect Node.js web application framework, you'd probably come up with something like this: @@ -47,9 +47,9 @@ What happens if we use the new model as a starting point? ## Introducing Sapper - + -[Sapper](https://sapper.svelte.technology) is the answer to that question. **Sapper is a Next.js-style framework that aims to meet the eleven criteria at the top of this article while dramatically reducing the amount of code that gets sent to the browser.** It's implemented as Express-compatible middleware, meaning it's easy to understand and customise. +[Sapper](https://sapper.svelte.dev) is the answer to that question. **Sapper is a Next.js-style framework that aims to meet the eleven criteria at the top of this article while dramatically reducing the amount of code that gets sent to the browser.** It's implemented as Express-compatible middleware, meaning it's easy to understand and customise. The same 'hello world' app that took 204kb with React and Next weighs just 7kb with Sapper. That number is likely to fall further in the future as we explore the space of optimisation possibilities, such as not shipping any JavaScript *at all* for pages that aren't interactive, beyond the tiny Sapper runtime that handles client-side routing. From 3dad14f0e1b42ab19a671ee62a92c0f9fc1706df Mon Sep 17 00:00:00 2001 From: Tan Li Hau Date: Sat, 25 Jul 2020 02:48:43 +0800 Subject: [PATCH 02/94] better error message for mismatched tags due to autoclosing (#5060) --- CHANGELOG.md | 1 + src/compiler/parse/index.ts | 7 +++++++ src/compiler/parse/state/tag.ts | 17 +++++++++++++++-- .../error.json | 10 ++++++++++ .../input.svelte | 5 +++++ .../error.json | 10 ++++++++++ .../input.svelte | 3 +++ 7 files changed, 51 insertions(+), 2 deletions(-) create mode 100644 test/parser/samples/error-unmatched-closing-tag-autoclose-2/error.json create mode 100644 test/parser/samples/error-unmatched-closing-tag-autoclose-2/input.svelte create mode 100644 test/parser/samples/error-unmatched-closing-tag-autoclose/error.json create mode 100644 test/parser/samples/error-unmatched-closing-tag-autoclose/input.svelte diff --git a/CHANGELOG.md b/CHANGELOG.md index bd070862f3..6eda3003ef 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ * Prevent duplicate invalidation with certain two-way component bindings ([#3180](https://github.com/sveltejs/svelte/issues/3180), [#5117](https://github.com/sveltejs/svelte/issues/5117), [#5144](https://github.com/sveltejs/svelte/issues/5144)) * Fix reactivity when passing `$$props` to a `` ([#3364](https://github.com/sveltejs/svelte/issues/3364)) * Fix unneeded invalidation of `$$props` and `$$restProps` ([#4993](https://github.com/sveltejs/svelte/issues/4993), [#5118](https://github.com/sveltejs/svelte/issues/5118)) +* Provide better compiler error message when mismatched tags are due to autoclosing of tags ([#5049](https://github.com/sveltejs/svelte/issues/5049)) ## 3.24.0 diff --git a/src/compiler/parse/index.ts b/src/compiler/parse/index.ts index a809eeebeb..52795c02a9 100644 --- a/src/compiler/parse/index.ts +++ b/src/compiler/parse/index.ts @@ -8,6 +8,12 @@ import error from '../utils/error'; type ParserState = (parser: Parser) => (ParserState | void); +interface LastAutoClosedTag { + tag: string; + reason: string; + depth: number; +} + export class Parser { readonly template: string; readonly filename?: string; @@ -20,6 +26,7 @@ export class Parser { css: Style[] = []; js: Script[] = []; meta_tags = {}; + last_auto_closed_tag?: LastAutoClosedTag; constructor(template: string, options: ParserOptions) { if (typeof template !== 'string') { diff --git a/src/compiler/parse/state/tag.ts b/src/compiler/parse/state/tag.ts index ce8a0a9aa7..311bf852e2 100644 --- a/src/compiler/parse/state/tag.ts +++ b/src/compiler/parse/state/tag.ts @@ -133,11 +133,15 @@ export default function tag(parser: Parser) { // close any elements that don't have their own closing tags, e.g.

while (parent.name !== name) { - if (parent.type !== 'Element') + if (parent.type !== 'Element') { + const message = parser.last_auto_closed_tag && parser.last_auto_closed_tag.tag === name + ? ` attempted to close <${name}> that was already automatically closed by <${parser.last_auto_closed_tag.reason}>` + : ` attempted to close an element that was not open`; parser.error({ code: `invalid-closing-tag`, - message: ` attempted to close an element that was not open` + message }, start); + } parent.end = start; parser.stack.pop(); @@ -148,10 +152,19 @@ export default function tag(parser: Parser) { parent.end = parser.index; parser.stack.pop(); + if (parser.last_auto_closed_tag && parser.stack.length < parser.last_auto_closed_tag.depth) { + parser.last_auto_closed_tag = null; + } + return; } else if (closing_tag_omitted(parent.name, name)) { parent.end = start; parser.stack.pop(); + parser.last_auto_closed_tag = { + tag: parent.name, + reason: name, + depth: parser.stack.length, + }; } const unique_names: Set = new Set(); diff --git a/test/parser/samples/error-unmatched-closing-tag-autoclose-2/error.json b/test/parser/samples/error-unmatched-closing-tag-autoclose-2/error.json new file mode 100644 index 0000000000..d24296bd96 --- /dev/null +++ b/test/parser/samples/error-unmatched-closing-tag-autoclose-2/error.json @@ -0,0 +1,10 @@ +{ + "code": "invalid-closing-tag", + "message": "

attempted to close an element that was not open", + "pos": 38, + "start": { + "character": 38, + "column": 0, + "line": 5 + } +} diff --git a/test/parser/samples/error-unmatched-closing-tag-autoclose-2/input.svelte b/test/parser/samples/error-unmatched-closing-tag-autoclose-2/input.svelte new file mode 100644 index 0000000000..5182577921 --- /dev/null +++ b/test/parser/samples/error-unmatched-closing-tag-autoclose-2/input.svelte @@ -0,0 +1,5 @@ +
+

+

pre tag
+
+

\ No newline at end of file diff --git a/test/parser/samples/error-unmatched-closing-tag-autoclose/error.json b/test/parser/samples/error-unmatched-closing-tag-autoclose/error.json new file mode 100644 index 0000000000..e6532d747e --- /dev/null +++ b/test/parser/samples/error-unmatched-closing-tag-autoclose/error.json @@ -0,0 +1,10 @@ +{ + "code": "invalid-closing-tag", + "message": "

attempted to close

that was already automatically closed by

",
+	"pos": 24,
+	"start": {
+		"character": 24,
+		"column": 0,
+		"line": 3
+	}
+}
diff --git a/test/parser/samples/error-unmatched-closing-tag-autoclose/input.svelte b/test/parser/samples/error-unmatched-closing-tag-autoclose/input.svelte
new file mode 100644
index 0000000000..0bfd609736
--- /dev/null
+++ b/test/parser/samples/error-unmatched-closing-tag-autoclose/input.svelte
@@ -0,0 +1,3 @@
+

+

pre tag
+

\ No newline at end of file From 02e10b1159b886a5774b70653f9bbc74b4d7ff37 Mon Sep 17 00:00:00 2001 From: Tan Li Hau Date: Sat, 25 Jul 2020 03:48:29 +0800 Subject: [PATCH 03/94] fix bind:group contextual reference (#5199) --- CHANGELOG.md | 1 + src/compiler/compile/nodes/Binding.ts | 5 +- .../compile/nodes/shared/Expression.ts | 5 +- .../shared/mark_each_block_bindings.ts | 10 ++- .../binding-input-group-each-6/_config.js | 87 +++++++++++++++++++ .../binding-input-group-each-6/main.svelte | 22 +++++ 6 files changed, 122 insertions(+), 8 deletions(-) create mode 100644 test/runtime/samples/binding-input-group-each-6/_config.js create mode 100644 test/runtime/samples/binding-input-group-each-6/main.svelte diff --git a/CHANGELOG.md b/CHANGELOG.md index 6eda3003ef..da084600b7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,7 @@ * Fix reactivity when passing `$$props` to a `` ([#3364](https://github.com/sveltejs/svelte/issues/3364)) * Fix unneeded invalidation of `$$props` and `$$restProps` ([#4993](https://github.com/sveltejs/svelte/issues/4993), [#5118](https://github.com/sveltejs/svelte/issues/5118)) * Provide better compiler error message when mismatched tags are due to autoclosing of tags ([#5049](https://github.com/sveltejs/svelte/issues/5049)) +* Fix `bind:group` when using contextual reference ([#5174](https://github.com/sveltejs/svelte/issues/5174)) ## 3.24.0 diff --git a/src/compiler/compile/nodes/Binding.ts b/src/compiler/compile/nodes/Binding.ts index bcb07280b0..c561e72b99 100644 --- a/src/compiler/compile/nodes/Binding.ts +++ b/src/compiler/compile/nodes/Binding.ts @@ -41,7 +41,8 @@ export default class Binding extends Node { this.raw_expression = JSON.parse(JSON.stringify(info.expression)); const { name } = get_object(this.expression.node); - this.is_contextual = scope.names.has(name); + + this.is_contextual = Array.from(this.expression.references).some(name => scope.names.has(name)); // make sure we track this as a mutable ref if (scope.is_let(name)) { @@ -49,7 +50,7 @@ export default class Binding extends Node { code: 'invalid-binding', message: 'Cannot bind to a variable declared with the let: directive' }); - } else if (this.is_contextual) { + } else if (scope.names.has(name)) { if (scope.is_await(name)) { component.error(this, { code: 'invalid-binding', diff --git a/src/compiler/compile/nodes/shared/Expression.ts b/src/compiler/compile/nodes/shared/Expression.ts index 8bfc2bffce..bbbc1b2f2d 100644 --- a/src/compiler/compile/nodes/shared/Expression.ts +++ b/src/compiler/compile/nodes/shared/Expression.ts @@ -24,7 +24,7 @@ export default class Expression { component: Component; owner: Owner; node: any; - references: Set; + references: Set = new Set(); dependencies: Set = new Set(); contextual_dependencies: Set = new Set(); @@ -50,7 +50,7 @@ export default class Expression { this.template_scope = template_scope; this.owner = owner; - const { dependencies, contextual_dependencies } = this; + const { dependencies, contextual_dependencies, references } = this; let { map, scope } = create_scopes(info); this.scope = scope; @@ -75,6 +75,7 @@ export default class Expression { if (is_reference(node, parent)) { const { name, nodes } = flatten_reference(node); + references.add(name); if (scope.has(name)) return; diff --git a/src/compiler/compile/render_dom/wrappers/shared/mark_each_block_bindings.ts b/src/compiler/compile/render_dom/wrappers/shared/mark_each_block_bindings.ts index 490d52bd9d..884d4b88b8 100644 --- a/src/compiler/compile/render_dom/wrappers/shared/mark_each_block_bindings.ts +++ b/src/compiler/compile/render_dom/wrappers/shared/mark_each_block_bindings.ts @@ -2,7 +2,6 @@ import EachBlock from "../../../nodes/EachBlock"; import InlineComponentWrapper from "../InlineComponent"; import ElementWrapper from "../Element"; import Binding from "../../../nodes/Binding"; -import get_object from "../../../utils/get_object"; export default function mark_each_block_bindings( parent: ElementWrapper | InlineComponentWrapper, @@ -10,9 +9,12 @@ export default function mark_each_block_bindings( ) { // we need to ensure that the each block creates a context including // the list and the index, if they're not otherwise referenced - const object = get_object(binding.expression.node).name; - const each_block = parent.node.scope.get_owner(object); - (each_block as EachBlock).has_binding = true; + binding.expression.references.forEach(name => { + const each_block = parent.node.scope.get_owner(name); + if (each_block) { + (each_block as EachBlock).has_binding = true; + } + }); if (binding.name === "group") { // for ``, we make sure that all the each blocks creates context with `index` diff --git a/test/runtime/samples/binding-input-group-each-6/_config.js b/test/runtime/samples/binding-input-group-each-6/_config.js new file mode 100644 index 0000000000..9eb251bf5d --- /dev/null +++ b/test/runtime/samples/binding-input-group-each-6/_config.js @@ -0,0 +1,87 @@ +export default { + html: ` + + + +

+ + + +

+ + + +

+ `, + + async test({ assert, component, target, window }) { + const inputs = target.querySelectorAll('input'); + assert.equal(inputs[0].checked, false); + assert.equal(inputs[1].checked, false); + assert.equal(inputs[2].checked, false); + + assert.equal(inputs[3].checked, false); + assert.equal(inputs[4].checked, false); + assert.equal(inputs[5].checked, false); + + assert.equal(inputs[6].checked, false); + assert.equal(inputs[7].checked, false); + assert.equal(inputs[8].checked, false); + + const event = new window.Event('change'); + + inputs[2].checked = true; + await inputs[2].dispatchEvent(event); + + assert.htmlEqual(target.innerHTML, ` + + + +

z

+ + + +

+ + + +

+ `); + + inputs[4].checked = true; + await inputs[4].dispatchEvent(event); + + assert.htmlEqual(target.innerHTML, ` + + + +

z

+ + + +

y

+ + + +

+ `); + + inputs[5].checked = true; + await inputs[5].dispatchEvent(event); + + assert.htmlEqual(target.innerHTML, ` + + + +

z

+ + + +

y, z

+ + + +

+ `); + } +}; diff --git a/test/runtime/samples/binding-input-group-each-6/main.svelte b/test/runtime/samples/binding-input-group-each-6/main.svelte new file mode 100644 index 0000000000..85be939e8a --- /dev/null +++ b/test/runtime/samples/binding-input-group-each-6/main.svelte @@ -0,0 +1,22 @@ + + +{#each Object.keys(list) as key} + {#each values as value} + + {/each} +

{list[key].join(', ')}

+{/each} From 1f87f5fb2043522b5889e06ced6a0cf7b02c1e25 Mon Sep 17 00:00:00 2001 From: "M. Habib Rosyad" Date: Wed, 29 Jul 2020 01:48:16 +0700 Subject: [PATCH 04/94] site: fix escaping in RSS feed (#5214) --- site/src/routes/blog/rss.xml.js | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/site/src/routes/blog/rss.xml.js b/site/src/routes/blog/rss.xml.js index 974806ad44..544474b274 100644 --- a/site/src/routes/blog/rss.xml.js +++ b/site/src/routes/blog/rss.xml.js @@ -8,6 +8,18 @@ function formatPubdate(str) { return `${d} ${months[+m]} ${y} 12:00 +0000`; } +function escapeHTML(html) { + const chars = { + '"' : 'quot', + "'": '#39', + '&': 'amp', + '<' : 'lt', + '>' : 'gt' + }; + + return html.replace(/["'&<>]/g, c => `&${chars[c]};`); +} + const rss = ` @@ -23,9 +35,9 @@ const rss = ` ${get_posts().filter(post => !post.metadata.draft).map(post => ` - ${post.metadata.title} + ${escapeHTML(post.metadata.title)} https://svelte.dev/blog/${post.slug} - ${post.metadata.description} + ${escapeHTML(post.metadata.description)} ${formatPubdate(post.metadata.pubdate)} `).join('')} From f4f16da455952cb0b630f7494a0bbc4f4d4a4b4b Mon Sep 17 00:00:00 2001 From: Conduitry Date: Tue, 28 Jul 2020 16:39:17 -0400 Subject: [PATCH 05/94] site: use relative link to tutorial in FAQ entry --- site/content/faq/100-im-new-to-svelte.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/site/content/faq/100-im-new-to-svelte.md b/site/content/faq/100-im-new-to-svelte.md index 18e4b6742f..0f1df9cff5 100644 --- a/site/content/faq/100-im-new-to-svelte.md +++ b/site/content/faq/100-im-new-to-svelte.md @@ -2,6 +2,6 @@ question: I'm new to Svelte. Where should I start? --- -We think the best way to get started is playing through the interactive [Tutorial](https://svelte.dev/tutorial). Each step there is mainly focused on one specific aspect and is easy to follow. You'll be editing and running real Svelte components right in your browser. +We think the best way to get started is playing through the interactive [Tutorial](tutorial). Each step there is mainly focused on one specific aspect and is easy to follow. You'll be editing and running real Svelte components right in your browser. Five to ten minutes should be enough to get you up and running. An hour and a half should get you through the entire tutorial. \ No newline at end of file From a0ed7040f1daa9d0d4d984ab7737ddce3755bf65 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Paulo?= <62244135+joaopaulobdac@users.noreply.github.com> Date: Thu, 30 Jul 2020 12:43:45 -0300 Subject: [PATCH 06/94] site: clarify file -> module in tutorial (#5171) --- .../tutorial/16-special-elements/01-svelte-self/text.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/site/content/tutorial/16-special-elements/01-svelte-self/text.md b/site/content/tutorial/16-special-elements/01-svelte-self/text.md index 773dded83e..c7946f6c6d 100644 --- a/site/content/tutorial/16-special-elements/01-svelte-self/text.md +++ b/site/content/tutorial/16-special-elements/01-svelte-self/text.md @@ -14,7 +14,7 @@ It's useful for things like this folder tree view, where folders can contain *ot {/if} ``` -...but that's impossible, because a file can't import itself. Instead, we use ``: +...but that's impossible, because a module can't import itself. Instead, we use ``: ```html {#if file.type === 'folder'} @@ -22,4 +22,4 @@ It's useful for things like this folder tree view, where folders can contain *ot {:else} {/if} -``` \ No newline at end of file +``` From 231e4a0b3c8887ae9c76e5fa03b00e2e97704a1a Mon Sep 17 00:00:00 2001 From: Charles Rosaaen Date: Mon, 3 Aug 2020 12:48:35 -0700 Subject: [PATCH 07/94] site: update link in blog for SCode extension (#5232) --- site/content/blog/2019-04-16-svelte-for-new-developers.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/site/content/blog/2019-04-16-svelte-for-new-developers.md b/site/content/blog/2019-04-16-svelte-for-new-developers.md index fd7a88e6f1..921e699842 100644 --- a/site/content/blog/2019-04-16-svelte-for-new-developers.md +++ b/site/content/blog/2019-04-16-svelte-for-new-developers.md @@ -51,7 +51,7 @@ Once installed, you'll have access to three new commands: ## Installing a text editor -To write code, you need a good editor. The most popular choice is [Visual Studio Code](https://code.visualstudio.com/) or VSCode, and justifiably so — it's well-designed and fully-featured, and has a wealth of extensions ([including one for Svelte](https://marketplace.visualstudio.com/items?itemName=JamesBirtles.svelte-vscode), which provides syntax highlighting and diagnostic messages when you're writing components). +To write code, you need a good editor. The most popular choice is [Visual Studio Code](https://code.visualstudio.com/) or VSCode, and justifiably so — it's well-designed and fully-featured, and has a wealth of extensions ([including one for Svelte](https://marketplace.visualstudio.com/items?itemName=svelte.svelte-vscode), which provides syntax highlighting and diagnostic messages when you're writing components). ## Creating a project From d81cb83ae00162351c7b902237d0412a8d6a7ba0 Mon Sep 17 00:00:00 2001 From: pngwn Date: Wed, 5 Aug 2020 14:29:26 +0100 Subject: [PATCH 08/94] Add type param to setContext and getContext (#5224) --- src/runtime/internal/lifecycle.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/runtime/internal/lifecycle.ts b/src/runtime/internal/lifecycle.ts index a8e37e9632..34d52672a2 100644 --- a/src/runtime/internal/lifecycle.ts +++ b/src/runtime/internal/lifecycle.ts @@ -44,11 +44,11 @@ export function createEventDispatcher() { }; } -export function setContext(key, context) { +export function setContext(key, context: T) { get_current_component().$$.context.set(key, context); } -export function getContext(key) { +export function getContext(key): T { return get_current_component().$$.context.get(key); } From fdf3ab88be411471422abdca40bdbac233bf5391 Mon Sep 17 00:00:00 2001 From: Carlos Roso Date: Wed, 5 Aug 2020 10:41:54 -0500 Subject: [PATCH 09/94] Fix transitions for each-else blocks (#5179) Co-authored-by: khang8591 --- .../compile/render_dom/wrappers/EachBlock.ts | 21 ++++++-- .../_config.js | 54 +++++++++++++++++++ .../main.svelte | 27 ++++++++++ .../_config.js | 22 ++++++++ .../main.svelte | 18 +++++++ .../_config.js | 20 +++++++ .../main.svelte | 18 +++++++ 7 files changed, 176 insertions(+), 4 deletions(-) create mode 100644 test/runtime/samples/transition-js-each-else-block-intro-outro/_config.js create mode 100644 test/runtime/samples/transition-js-each-else-block-intro-outro/main.svelte create mode 100644 test/runtime/samples/transition-js-each-else-block-intro/_config.js create mode 100644 test/runtime/samples/transition-js-each-else-block-intro/main.svelte create mode 100644 test/runtime/samples/transition-js-each-else-block-outro/_config.js create mode 100644 test/runtime/samples/transition-js-each-else-block-outro/main.svelte diff --git a/src/compiler/compile/render_dom/wrappers/EachBlock.ts b/src/compiler/compile/render_dom/wrappers/EachBlock.ts index bd981a0603..126b114487 100644 --- a/src/compiler/compile/render_dom/wrappers/EachBlock.ts +++ b/src/compiler/compile/render_dom/wrappers/EachBlock.ts @@ -298,6 +298,19 @@ export default class EachBlockWrapper extends Wrapper { } `); + const has_transitions = !!(this.else.block.has_intro_method || this.else.block.has_outro_method); + + const destroy_block_else = this.else.block.has_outro_method + ? b` + @group_outros(); + @transition_out(${each_block_else}, 1, 1, () => { + ${each_block_else} = null; + }); + @check_outros();` + : b` + ${each_block_else}.d(1); + ${each_block_else} = null;`; + if (this.else.block.has_update_method) { this.updates.push(b` if (!${this.vars.data_length} && ${each_block_else}) { @@ -305,22 +318,22 @@ export default class EachBlockWrapper extends Wrapper { } else if (!${this.vars.data_length}) { ${each_block_else} = ${this.else.block.name}(#ctx); ${each_block_else}.c(); + ${has_transitions && b`@transition_in(${each_block_else}, 1);`} ${each_block_else}.m(${update_mount_node}, ${update_anchor_node}); } else if (${each_block_else}) { - ${each_block_else}.d(1); - ${each_block_else} = null; + ${destroy_block_else}; } `); } else { this.updates.push(b` if (${this.vars.data_length}) { if (${each_block_else}) { - ${each_block_else}.d(1); - ${each_block_else} = null; + ${destroy_block_else}; } } else if (!${each_block_else}) { ${each_block_else} = ${this.else.block.name}(#ctx); ${each_block_else}.c(); + ${has_transitions && b`@transition_in(${each_block_else}, 1);`} ${each_block_else}.m(${update_mount_node}, ${update_anchor_node}); } `); diff --git a/test/runtime/samples/transition-js-each-else-block-intro-outro/_config.js b/test/runtime/samples/transition-js-each-else-block-intro-outro/_config.js new file mode 100644 index 0000000000..13d0cf0b23 --- /dev/null +++ b/test/runtime/samples/transition-js-each-else-block-intro-outro/_config.js @@ -0,0 +1,54 @@ +export default { + props: { + things: ['a', 'b', 'c'] + }, + + test({ assert, component, target, window, raf }) { + component.things = []; + let div = target.querySelector('div'); + assert.equal(div.foo, 0); + + raf.tick(200); + assert.equal(div.foo, 0.5); + + raf.tick(300); + assert.equal(div.foo, 0.75); + + raf.tick(400); + assert.equal(div.foo, 1); + + raf.tick(600); + component.things = ['a', 'b', 'c']; + + raf.tick(700); + assert.equal(div.foo, 1); + assert.equal(div.bar, 0.75); + + raf.tick(800); + assert.equal(div.foo, 1); + assert.equal(div.bar, 0.5); + + raf.tick(900); + assert.equal(div.foo, 1); + assert.equal(div.bar, 0.25); + + // test outro before intro complete + raf.tick(1000); + component.things = []; + div = target.querySelector('div'); + + raf.tick(1200); + assert.equal(div.foo, 0.5); + + component.things = ['a', 'b', 'c']; + raf.tick(1300); + assert.equal(div.foo, 0.75); + assert.equal(div.bar, 0.75); + + raf.tick(1400); + assert.equal(div.foo, 1); + assert.equal(div.bar, 0.5); + + raf.tick(2000); + } +}; \ No newline at end of file diff --git a/test/runtime/samples/transition-js-each-else-block-intro-outro/main.svelte b/test/runtime/samples/transition-js-each-else-block-intro-outro/main.svelte new file mode 100644 index 0000000000..1691e77f52 --- /dev/null +++ b/test/runtime/samples/transition-js-each-else-block-intro-outro/main.svelte @@ -0,0 +1,27 @@ + + +{#each things as thing} +

{thing}

+{:else} +
else
+{/each} \ No newline at end of file diff --git a/test/runtime/samples/transition-js-each-else-block-intro/_config.js b/test/runtime/samples/transition-js-each-else-block-intro/_config.js new file mode 100644 index 0000000000..f061e312ff --- /dev/null +++ b/test/runtime/samples/transition-js-each-else-block-intro/_config.js @@ -0,0 +1,22 @@ +export default { + props: { + things: ['a', 'b', 'c'] + }, + + test({ assert, component, target, window, raf }) { + component.things = []; + const div = target.querySelector('div'); + assert.equal(div.foo, 0); + + raf.tick(200); + assert.equal(div.foo, 0.5); + + raf.tick(300); + assert.equal(div.foo, 0.75); + + raf.tick(400); + assert.equal(div.foo, 1); + + raf.tick(500); + } +}; \ No newline at end of file diff --git a/test/runtime/samples/transition-js-each-else-block-intro/main.svelte b/test/runtime/samples/transition-js-each-else-block-intro/main.svelte new file mode 100644 index 0000000000..bda8746c46 --- /dev/null +++ b/test/runtime/samples/transition-js-each-else-block-intro/main.svelte @@ -0,0 +1,18 @@ + + +{#each things as thing} +

{thing}

+{:else} +
else
+{/each} \ No newline at end of file diff --git a/test/runtime/samples/transition-js-each-else-block-outro/_config.js b/test/runtime/samples/transition-js-each-else-block-outro/_config.js new file mode 100644 index 0000000000..863753b34a --- /dev/null +++ b/test/runtime/samples/transition-js-each-else-block-outro/_config.js @@ -0,0 +1,20 @@ +export default { + props: { + things: [] + }, + test({ assert, component, target, window, raf }) { + const div = target.querySelector('div'); + component.things = ['a', 'b', 'c']; + + raf.tick(200); + assert.equal(div.foo, 0.5); + + raf.tick(300); + assert.equal(div.foo, 0.25); + + raf.tick(400); + assert.equal(div.foo, 0); + + raf.tick(500); + } +}; \ No newline at end of file diff --git a/test/runtime/samples/transition-js-each-else-block-outro/main.svelte b/test/runtime/samples/transition-js-each-else-block-outro/main.svelte new file mode 100644 index 0000000000..246c146127 --- /dev/null +++ b/test/runtime/samples/transition-js-each-else-block-outro/main.svelte @@ -0,0 +1,18 @@ + + +{#each things as thing} +

{thing}

+{:else} +
else
+{/each} \ No newline at end of file From f0d586f4a400edaf59d52601f987283ca76be387 Mon Sep 17 00:00:00 2001 From: Conduitry Date: Wed, 5 Aug 2020 11:44:32 -0400 Subject: [PATCH 10/94] update changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index da084600b7..2c276db868 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,7 @@ * Prevent duplicate invalidation with certain two-way component bindings ([#3180](https://github.com/sveltejs/svelte/issues/3180), [#5117](https://github.com/sveltejs/svelte/issues/5117), [#5144](https://github.com/sveltejs/svelte/issues/5144)) * Fix reactivity when passing `$$props` to a `` ([#3364](https://github.com/sveltejs/svelte/issues/3364)) +* Fix transitions on `{#each}` `{:else}` ([#4970](https://github.com/sveltejs/svelte/issues/4970)) * Fix unneeded invalidation of `$$props` and `$$restProps` ([#4993](https://github.com/sveltejs/svelte/issues/4993), [#5118](https://github.com/sveltejs/svelte/issues/5118)) * Provide better compiler error message when mismatched tags are due to autoclosing of tags ([#5049](https://github.com/sveltejs/svelte/issues/5049)) * Fix `bind:group` when using contextual reference ([#5174](https://github.com/sveltejs/svelte/issues/5174)) From 62ab75e365c8185b3a6cb8a3f3e91c64908778b3 Mon Sep 17 00:00:00 2001 From: Bassam Ismail Date: Wed, 5 Aug 2020 21:27:20 +0530 Subject: [PATCH 11/94] add a11y-label-has-associated-control check (#5074) --- src/compiler/compile/nodes/Element.ts | 21 ++++++++++++ .../input.svelte | 6 ++++ .../warnings.json | 32 +++++++++++++++++++ 3 files changed, 59 insertions(+) create mode 100644 test/validator/samples/a11y-label-has-associated-control/input.svelte create mode 100644 test/validator/samples/a11y-label-has-associated-control/warnings.json diff --git a/src/compiler/compile/nodes/Element.ts b/src/compiler/compile/nodes/Element.ts index 7a70e603a7..ffcf0e51f2 100644 --- a/src/compiler/compile/nodes/Element.ts +++ b/src/compiler/compile/nodes/Element.ts @@ -61,6 +61,17 @@ const a11y_no_onchange = new Set([ 'option' ]); +const a11y_labelable = new Set([ + "button", + "input", + "keygen", + "meter", + "output", + "progress", + "select", + "textarea" +]); + const invisible_elements = new Set(['meta', 'html', 'script', 'style']); const valid_modifiers = new Set([ @@ -507,6 +518,16 @@ export default class Element extends Node { } } + if (this.name === 'label') { + const has_input_child = this.children.some(i => (i instanceof Element && a11y_labelable.has(i.name) )); + if (!attribute_map.has('for') && !has_input_child) { + component.warn(this, { + code: `a11y-label-has-associated-control`, + message: `A11y: A form label must be associated with a control.` + }); + } + } + if (a11y_no_onchange.has(this.name)) { if (handlers_map.has('change') && !handlers_map.has('blur')) { component.warn(this, { diff --git a/test/validator/samples/a11y-label-has-associated-control/input.svelte b/test/validator/samples/a11y-label-has-associated-control/input.svelte new file mode 100644 index 0000000000..43304689dc --- /dev/null +++ b/test/validator/samples/a11y-label-has-associated-control/input.svelte @@ -0,0 +1,6 @@ + + + + + + diff --git a/test/validator/samples/a11y-label-has-associated-control/warnings.json b/test/validator/samples/a11y-label-has-associated-control/warnings.json new file mode 100644 index 0000000000..b70a1a47de --- /dev/null +++ b/test/validator/samples/a11y-label-has-associated-control/warnings.json @@ -0,0 +1,32 @@ +[ + { + "code": "a11y-label-has-associated-control", + "end": { + "character": 16, + "column": 16, + "line": 1 + }, + "message": "A11y: A form label must be associated with a control.", + "pos": 0, + "start": { + "character": 0, + "column": 0, + "line": 1 + } + }, + { + "code": "a11y-label-has-associated-control", + "end": { + "character": 149, + "column": 30, + "line": 6 + }, + "message": "A11y: A form label must be associated with a control.", + "pos": 119, + "start": { + "character": 119, + "column": 0, + "line": 6 + } + } +] From 308f3c284dfb4ac86e16475798a77dc2f5dc930b Mon Sep 17 00:00:00 2001 From: Conduitry Date: Wed, 5 Aug 2020 11:58:38 -0400 Subject: [PATCH 12/94] update changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2c276db868..ac39b41ee3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,7 @@ * Fix transitions on `{#each}` `{:else}` ([#4970](https://github.com/sveltejs/svelte/issues/4970)) * Fix unneeded invalidation of `$$props` and `$$restProps` ([#4993](https://github.com/sveltejs/svelte/issues/4993), [#5118](https://github.com/sveltejs/svelte/issues/5118)) * Provide better compiler error message when mismatched tags are due to autoclosing of tags ([#5049](https://github.com/sveltejs/svelte/issues/5049)) +* Add `a11y-label-has-associated-control` warning ([#5074](https://github.com/sveltejs/svelte/pull/5074)) * Fix `bind:group` when using contextual reference ([#5174](https://github.com/sveltejs/svelte/issues/5174)) ## 3.24.0 From fb51dd8f072468aa81052e123d8fb6b2193d7489 Mon Sep 17 00:00:00 2001 From: Bassam Ismail Date: Wed, 5 Aug 2020 21:51:44 +0530 Subject: [PATCH 13/94] add a11y-media-has-caption check (#5075) --- src/compiler/compile/nodes/Element.ts | 19 +++++++++++ .../expected.html | 4 +-- .../input.svelte | 6 ++-- .../a11y-media-has-caption/input.svelte | 4 +++ .../a11y-media-has-caption/warnings.json | 32 +++++++++++++++++++ 5 files changed, 60 insertions(+), 5 deletions(-) create mode 100644 test/validator/samples/a11y-media-has-caption/input.svelte create mode 100644 test/validator/samples/a11y-media-has-caption/warnings.json diff --git a/src/compiler/compile/nodes/Element.ts b/src/compiler/compile/nodes/Element.ts index ffcf0e51f2..145866cf4f 100644 --- a/src/compiler/compile/nodes/Element.ts +++ b/src/compiler/compile/nodes/Element.ts @@ -528,6 +528,25 @@ export default class Element extends Node { } } + if (this.is_media_node()) { + if (attribute_map.has('muted')) { + return; + } + + let has_caption; + const track = this.children.find((i: Element) => i.name === 'track'); + if (track) { + has_caption = track.attributes.find(a => a.name === 'kind' && a.get_static_value() === 'captions'); + } + + if (!has_caption) { + component.warn(this, { + code: `a11y-media-has-caption`, + message: `A11y: Media elements must have a ` + }); + } + } + if (a11y_no_onchange.has(this.name)) { if (handlers_map.has('change') && !handlers_map.has('blur')) { component.warn(this, { diff --git a/test/css/samples/omit-scoping-attribute-attribute-selector/expected.html b/test/css/samples/omit-scoping-attribute-attribute-selector/expected.html index 52175f98b6..f585d6bcdd 100644 --- a/test/css/samples/omit-scoping-attribute-attribute-selector/expected.html +++ b/test/css/samples/omit-scoping-attribute-attribute-selector/expected.html @@ -1,2 +1,2 @@ -
-
\ No newline at end of file +
+
diff --git a/test/css/samples/omit-scoping-attribute-attribute-selector/input.svelte b/test/css/samples/omit-scoping-attribute-attribute-selector/input.svelte index 6f4549ead8..af06836d29 100644 --- a/test/css/samples/omit-scoping-attribute-attribute-selector/input.svelte +++ b/test/css/samples/omit-scoping-attribute-attribute-selector/input.svelte @@ -1,10 +1,10 @@
- - + +
\ No newline at end of file + diff --git a/test/validator/samples/a11y-media-has-caption/input.svelte b/test/validator/samples/a11y-media-has-caption/input.svelte new file mode 100644 index 0000000000..105269cddb --- /dev/null +++ b/test/validator/samples/a11y-media-has-caption/input.svelte @@ -0,0 +1,4 @@ + + + + diff --git a/test/validator/samples/a11y-media-has-caption/warnings.json b/test/validator/samples/a11y-media-has-caption/warnings.json new file mode 100644 index 0000000000..a8c894b1d4 --- /dev/null +++ b/test/validator/samples/a11y-media-has-caption/warnings.json @@ -0,0 +1,32 @@ +[ + { + "code": "a11y-media-has-caption", + "end": { + "character": 55, + "column": 15, + "line": 2 + }, + "message": "A11y: Media elements must have a ", + "pos": 40, + "start": { + "character": 40, + "column": 0, + "line": 2 + } + }, + { + "code": "a11y-media-has-caption", + "end": { + "character": 80, + "column": 24, + "line": 3 + }, + "message": "A11y: Media elements must have a ", + "pos": 56, + "start": { + "character": 56, + "column": 0, + "line": 3 + } + } +] From 0f3bbb441e1a6895f0e236edc83147672c8014e2 Mon Sep 17 00:00:00 2001 From: Conduitry Date: Wed, 5 Aug 2020 12:22:22 -0400 Subject: [PATCH 14/94] update changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index ac39b41ee3..d788205b0a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,7 @@ * Fix unneeded invalidation of `$$props` and `$$restProps` ([#4993](https://github.com/sveltejs/svelte/issues/4993), [#5118](https://github.com/sveltejs/svelte/issues/5118)) * Provide better compiler error message when mismatched tags are due to autoclosing of tags ([#5049](https://github.com/sveltejs/svelte/issues/5049)) * Add `a11y-label-has-associated-control` warning ([#5074](https://github.com/sveltejs/svelte/pull/5074)) +* Add `a11y-media-has-caption` warning ([#5075](https://github.com/sveltejs/svelte/pull/5075)) * Fix `bind:group` when using contextual reference ([#5174](https://github.com/sveltejs/svelte/issues/5174)) ## 3.24.0 From a62d7362150bacc6c84fe8c813ba9b8849216763 Mon Sep 17 00:00:00 2001 From: Conduitry Date: Wed, 5 Aug 2020 12:25:52 -0400 Subject: [PATCH 15/94] -> v3.24.1 --- CHANGELOG.md | 2 +- package-lock.json | 2 +- package.json | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d788205b0a..2863bf73eb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,6 @@ # Svelte changelog -## Unreleased +## 3.24.1 * Prevent duplicate invalidation with certain two-way component bindings ([#3180](https://github.com/sveltejs/svelte/issues/3180), [#5117](https://github.com/sveltejs/svelte/issues/5117), [#5144](https://github.com/sveltejs/svelte/issues/5144)) * Fix reactivity when passing `$$props` to a `` ([#3364](https://github.com/sveltejs/svelte/issues/3364)) diff --git a/package-lock.json b/package-lock.json index 82ad8fb6f6..0110595c76 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "svelte", - "version": "3.24.0", + "version": "3.24.1", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index 6927dc3d0d..e0de8670ef 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "svelte", - "version": "3.24.0", + "version": "3.24.1", "description": "Cybernetically enhanced web apps", "module": "index.mjs", "main": "index", From cf57050f4919bb3ae5cb3b5801a5919f1672b2ab Mon Sep 17 00:00:00 2001 From: Ben McCann <322311+benmccann@users.noreply.github.com> Date: Fri, 7 Aug 2020 04:16:10 -0700 Subject: [PATCH 16/94] Mention "import type" in TypeScript FAQ (#5243) * Mention "import type" in TypeScript FAQ * Update site/content/faq/500-what-about-typescript-support.md Co-authored-by: Christian Kaisermann --- site/content/faq/500-what-about-typescript-support.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/site/content/faq/500-what-about-typescript-support.md b/site/content/faq/500-what-about-typescript-support.md index adfd63764e..98838bab3d 100644 --- a/site/content/faq/500-what-about-typescript-support.md +++ b/site/content/faq/500-what-about-typescript-support.md @@ -10,3 +10,11 @@ To declare the type of a reactive variable in a Svelte template, you should use let x: number; $: x = count + 1; ``` + +To import a type or interface make sure to use [TypeScript's `type` modifier](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-8.html#type-only-imports-and-export): + +``` +import type { SomeInterface } from './SomeFile'; +``` + +You must use the `type` modifier because `svelte-preprocess` doesn't know whether an import is a type or a value — it only transpiles one file at a time without knowledge of the other files and therefore can't safely erase imports which only contain types without this modifier present. From 1398affa53050a4685bdf00b373197e7ba0d0965 Mon Sep 17 00:00:00 2001 From: Ben McCann <322311+benmccann@users.noreply.github.com> Date: Fri, 7 Aug 2020 15:01:58 -0700 Subject: [PATCH 17/94] Update TypeScript blog post with info about Sapper (#5249) --- site/content/blog/2020-07-17-svelte-and-typescript.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/site/content/blog/2020-07-17-svelte-and-typescript.md b/site/content/blog/2020-07-17-svelte-and-typescript.md index c3afb95c73..9c228a17da 100644 --- a/site/content/blog/2020-07-17-svelte-and-typescript.md +++ b/site/content/blog/2020-07-17-svelte-and-typescript.md @@ -134,7 +134,7 @@ error Command failed with exit code 1. ## What about TypeScript in Sapper projects? -Watch this space! +TypeScript support was added to Sapper in 0.28, so if you're using an older version be sure to [upgrade](https://sapper.svelte.dev/migrating#0_27_to_0_28). ## How can I contribute? From 4c449a741f9941d785c2ccb7cd79ebf12e7c68df Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Mon, 10 Aug 2020 22:53:06 -0400 Subject: [PATCH 18/94] bump site-kit version --- site/package-lock.json | 6 +++--- site/package.json | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/site/package-lock.json b/site/package-lock.json index bde0e87f82..66d9be0d00 100644 --- a/site/package-lock.json +++ b/site/package-lock.json @@ -1281,9 +1281,9 @@ } }, "@sveltejs/site-kit": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@sveltejs/site-kit/-/site-kit-1.2.1.tgz", - "integrity": "sha512-5AhOCBcproHF5UbmuOIB9CiyAmG6BXOr2G4EjeeDz/tyo9myfnRKIgJSy26q8Zlw6TOlwxhzcAgvL5sgZF+IsA==", + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/@sveltejs/site-kit/-/site-kit-1.2.3.tgz", + "integrity": "sha512-2IwPD1soaUczsXHi6aXZ6EO0R0K/C4PDAPrZ//CX9gKGNmkAky4xmsqsrT/R1gPPPWbGeELkaU2NXDSt8DYXlQ==", "dev": true, "requires": { "@sindresorhus/slugify": "^0.9.1", diff --git a/site/package.json b/site/package.json index 2564fce2c6..e8ff39bd06 100644 --- a/site/package.json +++ b/site/package.json @@ -36,7 +36,7 @@ "@babel/preset-env": "^7.6.0", "@babel/runtime": "^7.6.0", "@sindresorhus/slugify": "^0.9.1", - "@sveltejs/site-kit": "^1.2.1", + "@sveltejs/site-kit": "^1.2.3", "@sveltejs/svelte-repl": "^0.2.0", "degit": "^2.1.4", "dotenv": "^8.1.0", From a1cb70dde41d0e22eff916bbf03f981dce9f4dcb Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Mon, 10 Aug 2020 23:15:12 -0400 Subject: [PATCH 19/94] bump site-kit version --- site/package-lock.json | 6 +++--- site/package.json | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/site/package-lock.json b/site/package-lock.json index 66d9be0d00..caeb17a9bc 100644 --- a/site/package-lock.json +++ b/site/package-lock.json @@ -1281,9 +1281,9 @@ } }, "@sveltejs/site-kit": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/@sveltejs/site-kit/-/site-kit-1.2.3.tgz", - "integrity": "sha512-2IwPD1soaUczsXHi6aXZ6EO0R0K/C4PDAPrZ//CX9gKGNmkAky4xmsqsrT/R1gPPPWbGeELkaU2NXDSt8DYXlQ==", + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@sveltejs/site-kit/-/site-kit-1.2.4.tgz", + "integrity": "sha512-W+/PthWX4R8UvKr+IyWIITGoY3cl/54ePZr3dU9ZlyP9r/weEvvKDBvjmW8tAKQFRfbxyySmXUxEGBoPhF8XAA==", "dev": true, "requires": { "@sindresorhus/slugify": "^0.9.1", diff --git a/site/package.json b/site/package.json index e8ff39bd06..fd5be85976 100644 --- a/site/package.json +++ b/site/package.json @@ -36,7 +36,7 @@ "@babel/preset-env": "^7.6.0", "@babel/runtime": "^7.6.0", "@sindresorhus/slugify": "^0.9.1", - "@sveltejs/site-kit": "^1.2.3", + "@sveltejs/site-kit": "^1.2.4", "@sveltejs/svelte-repl": "^0.2.0", "degit": "^2.1.4", "dotenv": "^8.1.0", From 5194f596f775965d6538470574296d8fd6da43ba Mon Sep 17 00:00:00 2001 From: Tan Li Hau Date: Thu, 13 Aug 2020 02:53:18 +0800 Subject: [PATCH 20/94] do not declare variable for member assignment in reactive declaration in SSR (#5251) --- CHANGELOG.md | 4 ++ src/compiler/compile/render_ssr/index.ts | 39 ++++++------------- .../reactive-value-assign-property/_config.js | 5 +++ .../main.svelte | 6 +++ 4 files changed, 26 insertions(+), 28 deletions(-) create mode 100644 test/runtime/samples/reactive-value-assign-property/_config.js create mode 100644 test/runtime/samples/reactive-value-assign-property/main.svelte diff --git a/CHANGELOG.md b/CHANGELOG.md index 2863bf73eb..fd590c71aa 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Svelte changelog +## Unreleased + +* In SSR mode, do not automatically declare variables for reactive assignments to member expressions ([#5247](https://github.com/sveltejs/svelte/issues/5247)) + ## 3.24.1 * Prevent duplicate invalidation with certain two-way component bindings ([#3180](https://github.com/sveltejs/svelte/issues/3180), [#5117](https://github.com/sveltejs/svelte/issues/5117), [#5144](https://github.com/sveltejs/svelte/issues/5144)) diff --git a/src/compiler/compile/render_ssr/index.ts b/src/compiler/compile/render_ssr/index.ts index c87fe3bdd9..a72b8b35ae 100644 --- a/src/compiler/compile/render_ssr/index.ts +++ b/src/compiler/compile/render_ssr/index.ts @@ -5,8 +5,7 @@ import { string_literal } from '../utils/stringify'; import Renderer from './Renderer'; import { INode as TemplateNode } from '../nodes/interfaces'; // TODO import Text from '../nodes/Text'; -import { extract_names } from '../utils/scope'; -import { LabeledStatement, Statement, ExpressionStatement, AssignmentExpression, Node } from 'estree'; +import { LabeledStatement, Statement, Node } from 'estree'; export default function ssr( component: Component, @@ -72,37 +71,17 @@ export default function ssr( }) : []; + const injected = Array.from(component.injected_reactive_declaration_vars).filter(name => { + const variable = component.var_lookup.get(name); + return variable.injected; + }); + const reactive_declarations = component.reactive_declarations.map(d => { const body: Statement = (d.node as LabeledStatement).body; let statement = b`${body}`; - if (d.declaration) { - const declared = extract_names(d.declaration); - const injected = declared.filter(name => { - return name[0] !== '$' && component.var_lookup.get(name).injected; - }); - - const self_dependencies = injected.filter(name => d.dependencies.has(name)); - - if (injected.length) { - // in some cases we need to do `let foo; [expression]`, in - // others we can do `let [expression]` - const separate = ( - self_dependencies.length > 0 || - declared.length > injected.length - ); - - const { left, right } = (body as ExpressionStatement).expression as AssignmentExpression; - - statement = separate - ? b` - ${injected.map(name => b`let ${name};`)} - ${statement}` - : b` - let ${left} = ${right}`; - } - } else { // TODO do not add label if it's not referenced + if (!d.declaration) { // TODO do not add label if it's not referenced statement = b`$: { ${statement} }`; } @@ -119,6 +98,8 @@ export default function ssr( ${reactive_store_values} + ${injected.map(name => b`let ${name};`)} + ${reactive_declarations} $$rendered = ${literal}; @@ -129,6 +110,8 @@ export default function ssr( : b` ${reactive_store_values} + ${injected.map(name => b`let ${name};`)} + ${reactive_declarations} return ${literal};`; diff --git a/test/runtime/samples/reactive-value-assign-property/_config.js b/test/runtime/samples/reactive-value-assign-property/_config.js new file mode 100644 index 0000000000..7b6c1d2965 --- /dev/null +++ b/test/runtime/samples/reactive-value-assign-property/_config.js @@ -0,0 +1,5 @@ +export default { + html: ` +

Hello world!

+ `, +}; diff --git a/test/runtime/samples/reactive-value-assign-property/main.svelte b/test/runtime/samples/reactive-value-assign-property/main.svelte new file mode 100644 index 0000000000..58e0fdb03c --- /dev/null +++ b/test/runtime/samples/reactive-value-assign-property/main.svelte @@ -0,0 +1,6 @@ + + +

Hello {user.name}!

\ No newline at end of file From 8f17d6c78c7de1af54b8eb5ccffc68c78708d26b Mon Sep 17 00:00:00 2001 From: Luca Bonavita Date: Wed, 12 Aug 2020 21:05:59 +0100 Subject: [PATCH 21/94] docs: document `bind:files` (#5141) --- site/content/docs/02-template-syntax.md | 15 +++++++ .../05-bindings/05-file-inputs/App.svelte | 37 ++++++++++++++++++ .../05-bindings/05-file-inputs/meta.json | 3 ++ .../App.svelte | 0 .../meta.json | 0 .../App.svelte | 0 .../meta.json | 0 .../App.svelte | 0 .../meta.json | 0 .../App.svelte | 0 .../meta.json | 0 .../App.svelte | 0 .../meta.json | 0 .../{10-bind-this => 11-bind-this}/App.svelte | 0 .../{10-bind-this => 11-bind-this}/meta.json | 0 .../App.svelte | 0 .../Keypad.svelte | 0 .../meta.json | 0 .../examples/thumbnails/file-inputs.jpg | Bin 0 -> 2751 bytes 19 files changed, 55 insertions(+) create mode 100644 site/content/examples/05-bindings/05-file-inputs/App.svelte create mode 100644 site/content/examples/05-bindings/05-file-inputs/meta.json rename site/content/examples/05-bindings/{05-select-bindings => 06-select-bindings}/App.svelte (100%) rename site/content/examples/05-bindings/{05-select-bindings => 06-select-bindings}/meta.json (100%) rename site/content/examples/05-bindings/{06-multiple-select-bindings => 07-multiple-select-bindings}/App.svelte (100%) rename site/content/examples/05-bindings/{06-multiple-select-bindings => 07-multiple-select-bindings}/meta.json (100%) rename site/content/examples/05-bindings/{07-each-block-bindings => 08-each-block-bindings}/App.svelte (100%) rename site/content/examples/05-bindings/{07-each-block-bindings => 08-each-block-bindings}/meta.json (100%) rename site/content/examples/05-bindings/{08-media-elements => 09-media-elements}/App.svelte (100%) rename site/content/examples/05-bindings/{08-media-elements => 09-media-elements}/meta.json (100%) rename site/content/examples/05-bindings/{09-dimensions => 10-dimensions}/App.svelte (100%) rename site/content/examples/05-bindings/{09-dimensions => 10-dimensions}/meta.json (100%) rename site/content/examples/05-bindings/{10-bind-this => 11-bind-this}/App.svelte (100%) rename site/content/examples/05-bindings/{10-bind-this => 11-bind-this}/meta.json (100%) rename site/content/examples/05-bindings/{11-component-bindings => 12-component-bindings}/App.svelte (100%) rename site/content/examples/05-bindings/{11-component-bindings => 12-component-bindings}/Keypad.svelte (100%) rename site/content/examples/05-bindings/{11-component-bindings => 12-component-bindings}/meta.json (100%) create mode 100644 site/static/examples/thumbnails/file-inputs.jpg diff --git a/site/content/docs/02-template-syntax.md b/site/content/docs/02-template-syntax.md index 6d0847eb41..cfc7d7ba7a 100644 --- a/site/content/docs/02-template-syntax.md +++ b/site/content/docs/02-template-syntax.md @@ -544,6 +544,21 @@ Numeric input values are coerced; even though `input.value` is a string as far a ``` +--- + +On `` elements with `type="file"`, you can use `bind:files` to get the [`FileList` of selected files](https://developer.mozilla.org/en-US/docs/Web/API/FileList). + +```sv + + +``` + ##### Binding ` + + + + +{#if files} +

Selected files:

+ {#each Array.from(files) as file} +

{file.name} ({file.size} bytes)

+ {/each} +{/if} diff --git a/site/content/examples/05-bindings/05-file-inputs/meta.json b/site/content/examples/05-bindings/05-file-inputs/meta.json new file mode 100644 index 0000000000..92d0587e87 --- /dev/null +++ b/site/content/examples/05-bindings/05-file-inputs/meta.json @@ -0,0 +1,3 @@ +{ + "title": "File inputs" +} diff --git a/site/content/examples/05-bindings/05-select-bindings/App.svelte b/site/content/examples/05-bindings/06-select-bindings/App.svelte similarity index 100% rename from site/content/examples/05-bindings/05-select-bindings/App.svelte rename to site/content/examples/05-bindings/06-select-bindings/App.svelte diff --git a/site/content/examples/05-bindings/05-select-bindings/meta.json b/site/content/examples/05-bindings/06-select-bindings/meta.json similarity index 100% rename from site/content/examples/05-bindings/05-select-bindings/meta.json rename to site/content/examples/05-bindings/06-select-bindings/meta.json diff --git a/site/content/examples/05-bindings/06-multiple-select-bindings/App.svelte b/site/content/examples/05-bindings/07-multiple-select-bindings/App.svelte similarity index 100% rename from site/content/examples/05-bindings/06-multiple-select-bindings/App.svelte rename to site/content/examples/05-bindings/07-multiple-select-bindings/App.svelte diff --git a/site/content/examples/05-bindings/06-multiple-select-bindings/meta.json b/site/content/examples/05-bindings/07-multiple-select-bindings/meta.json similarity index 100% rename from site/content/examples/05-bindings/06-multiple-select-bindings/meta.json rename to site/content/examples/05-bindings/07-multiple-select-bindings/meta.json diff --git a/site/content/examples/05-bindings/07-each-block-bindings/App.svelte b/site/content/examples/05-bindings/08-each-block-bindings/App.svelte similarity index 100% rename from site/content/examples/05-bindings/07-each-block-bindings/App.svelte rename to site/content/examples/05-bindings/08-each-block-bindings/App.svelte diff --git a/site/content/examples/05-bindings/07-each-block-bindings/meta.json b/site/content/examples/05-bindings/08-each-block-bindings/meta.json similarity index 100% rename from site/content/examples/05-bindings/07-each-block-bindings/meta.json rename to site/content/examples/05-bindings/08-each-block-bindings/meta.json diff --git a/site/content/examples/05-bindings/08-media-elements/App.svelte b/site/content/examples/05-bindings/09-media-elements/App.svelte similarity index 100% rename from site/content/examples/05-bindings/08-media-elements/App.svelte rename to site/content/examples/05-bindings/09-media-elements/App.svelte diff --git a/site/content/examples/05-bindings/08-media-elements/meta.json b/site/content/examples/05-bindings/09-media-elements/meta.json similarity index 100% rename from site/content/examples/05-bindings/08-media-elements/meta.json rename to site/content/examples/05-bindings/09-media-elements/meta.json diff --git a/site/content/examples/05-bindings/09-dimensions/App.svelte b/site/content/examples/05-bindings/10-dimensions/App.svelte similarity index 100% rename from site/content/examples/05-bindings/09-dimensions/App.svelte rename to site/content/examples/05-bindings/10-dimensions/App.svelte diff --git a/site/content/examples/05-bindings/09-dimensions/meta.json b/site/content/examples/05-bindings/10-dimensions/meta.json similarity index 100% rename from site/content/examples/05-bindings/09-dimensions/meta.json rename to site/content/examples/05-bindings/10-dimensions/meta.json diff --git a/site/content/examples/05-bindings/10-bind-this/App.svelte b/site/content/examples/05-bindings/11-bind-this/App.svelte similarity index 100% rename from site/content/examples/05-bindings/10-bind-this/App.svelte rename to site/content/examples/05-bindings/11-bind-this/App.svelte diff --git a/site/content/examples/05-bindings/10-bind-this/meta.json b/site/content/examples/05-bindings/11-bind-this/meta.json similarity index 100% rename from site/content/examples/05-bindings/10-bind-this/meta.json rename to site/content/examples/05-bindings/11-bind-this/meta.json diff --git a/site/content/examples/05-bindings/11-component-bindings/App.svelte b/site/content/examples/05-bindings/12-component-bindings/App.svelte similarity index 100% rename from site/content/examples/05-bindings/11-component-bindings/App.svelte rename to site/content/examples/05-bindings/12-component-bindings/App.svelte diff --git a/site/content/examples/05-bindings/11-component-bindings/Keypad.svelte b/site/content/examples/05-bindings/12-component-bindings/Keypad.svelte similarity index 100% rename from site/content/examples/05-bindings/11-component-bindings/Keypad.svelte rename to site/content/examples/05-bindings/12-component-bindings/Keypad.svelte diff --git a/site/content/examples/05-bindings/11-component-bindings/meta.json b/site/content/examples/05-bindings/12-component-bindings/meta.json similarity index 100% rename from site/content/examples/05-bindings/11-component-bindings/meta.json rename to site/content/examples/05-bindings/12-component-bindings/meta.json diff --git a/site/static/examples/thumbnails/file-inputs.jpg b/site/static/examples/thumbnails/file-inputs.jpg new file mode 100644 index 0000000000000000000000000000000000000000..d302633f6b6fd370594d1d116dfb0b6a8adbd436 GIT binary patch literal 2751 zcmdT^XH?S(690z)O7jRIz*3Z@iBUkMgie+sC`DRm2`WtzB=jnRaCdMhf}*epxPS>I z2@s@{grdvAVp!>+1Oieep$SrS6#MnSvAAz*NI3O+Etq}T-cqjMkzJb_4Q~U7v zF#kAAK%n1mBp`@{gbYkZOIB9P&s^W!@BhZ(O8{~l=mC1bAPB$*0f8Z)!+!&E00;ns zjsScGm|s8;#CPn-X(0}Pz+gZ?h+l{gEcBlM5Z{p-A}9g<_5$oXCs$Mop>$AEN!RDt z#qfV*Kd-HOFQu)lg3vR!@QsYBf3V6q8W;kY0sCM3 z`70~J(r_{%N^+Y`*5Q$|Vzz^n0$h*lNo$U5t$|+9Vk+{mVyV52#tdYzrZ;(!4fcsx zyQ(=LCz2NwACo+eVYu`*2>!UpF7ht<6Ox418eOh%xx8pMEDVC-^enhC)ghQ94gBXB zb}|MK6qvNF-eu>O1zkotXQXCH_DMf?uUHW9O4KKMrFD8=b}^^E<)RrK#arNzmB_TQ z;K%Kk=r;M4w5QBPC+Mkk=%8y;(|zG`U9Z=~;PkAybn>Iqzb}^`1^vnXs>%l=H+?oW zk`4iuaNEqGzO9YDFR)3tFJHt-8Fe<0shr*apqoT67$n)FxQ}G30 zUD-bFu1z;_>L~^f6`B$-vLC*Dy1_+*$~jj59n>Q$Kaqvi*bhbVpy9 zAw7Pc{C9)d2vY;utXofhkQCL>Nqp7h>71qS4JO7moMlB9aK>3PyD3kIth^u-smFoC zLkXff{deFrcLVm6eE#eX9r%93TeWw2mK9N_KchxP%leS-h0~0Z2k>)pYX6$#l?SyY z7O2(fV9s(Vg~_GO-WqtVX8NSp2pYP6jLlAqjaC3%e6-Xr^Fj zpf|#-N{D|?p=5kIKn7payx>*+#Lf2M`^oi2ciFxrq(Lv|^d)u^d0cz! z)$f(UU0Im0)D_w3qR8@Q-vkfyYFg6~wgYURy4P~Grnt1dF&4RiHb;&U?IEs!y4C~`8c_l zC5t00)GA5-d4;VzRe{I%2ubkDtOanyCN_ZCtJ;Jp)0WS?ROy)$r0W#^paLm{-)`>; zEiW4z8@C+asm%;l(@s|RSiOubpj(k9RWSu0M_856dIFa5p&3Y;81xPoK^ z#`Ah?&Er|)IFG?MonGY5;sFt9jx2tN3g-op)mMD&RI2P2O>sG&j*bvYqLA<3;*4Hd zvZMtY(yROX<75&0Co9_O5T@3zoc^}E6ezXdrWjymd8^V*f4%uN1^1LTK|D|W>~2~T zeZEt{_*|NlvT`PAv{7H_G@wX#+DdIAJjB&cUhu4WFmI-Krqh1{%beIJ8r&OPi#9~X z&YPJ&QcTKR!4f?7Yh(_A%=$y17|nafNS7+F9Y%ThG@{@=Jw!i=OXZYB@;@WOU&<5@ zA#}=jRfdGxGGrMhMf=yXjLn{c2@Py+wdA?dGOH0QCT$AS$}92a`++exrbXYU@GX;i zbLrMpnG9u=dm0J~puq#b|M{;H{1WcPIu+5<)71;}3xbC+l@`Q=-rgsuX5CaCZ)FOc zG;i7om1{#rz?v)LI6Uy9>Na%uhNFBco;QuSoxE^1)NPY7a_n35?dHts5(D8$R%^%( msK;%(dOntP;!jWJ+ZMOFDq$@GdEnsBhx|I_Usy3aocI;?`dRb< literal 0 HcmV?d00001 From 5d5a608d324abcae2250366a464fbc79f18fd7f4 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 12 Aug 2020 16:07:36 -0400 Subject: [PATCH 22/94] Bump prismjs from 1.17.1 to 1.21.0 in /site (#5250) Bumps [prismjs](https://github.com/PrismJS/prism) from 1.17.1 to 1.21.0. - [Release notes](https://github.com/PrismJS/prism/releases) - [Changelog](https://github.com/PrismJS/prism/blob/master/CHANGELOG.md) - [Commits](https://github.com/PrismJS/prism/compare/v1.17.1...v1.21.0) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- site/package-lock.json | 12 ++++++------ site/package.json | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/site/package-lock.json b/site/package-lock.json index caeb17a9bc..00da27f0c7 100644 --- a/site/package-lock.json +++ b/site/package-lock.json @@ -1573,9 +1573,9 @@ } }, "clipboard": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/clipboard/-/clipboard-2.0.4.tgz", - "integrity": "sha512-Vw26VSLRpJfBofiVaFb/I8PVfdI1OxKcYShe6fm0sP/DtmiWQNCjhM/okTvdCo0G+lMMm1rMYbk4IK4x1X+kgQ==", + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/clipboard/-/clipboard-2.0.6.tgz", + "integrity": "sha512-g5zbiixBRk/wyKakSwCKd7vQXDjFnAMGHoEyBogG/bw9kTD9GvdAvaoRR1ALcEzt3pVKxZR0pViekPMIS0QyGg==", "optional": true, "requires": { "good-listener": "^1.2.2", @@ -3170,9 +3170,9 @@ "integrity": "sha512-plS7uY0WWiTBwWZs9KM3M88ZxHWKbrbMUDf52CPum6BqAxiLmKROmaTnmhXtv0krQ0l0HRLcFS8JDwOFyPt/OQ==" }, "prismjs": { - "version": "1.17.1", - "resolved": "https://registry.npmjs.org/prismjs/-/prismjs-1.17.1.tgz", - "integrity": "sha512-PrEDJAFdUGbOP6xK/UsfkC5ghJsPJviKgnQOoxaDbBjwc8op68Quupwt1DeAFoG8GImPhiKXAvvsH7wDSLsu1Q==", + "version": "1.21.0", + "resolved": "https://registry.npmjs.org/prismjs/-/prismjs-1.21.0.tgz", + "integrity": "sha512-uGdSIu1nk3kej2iZsLyDoJ7e9bnPzIgY0naW/HdknGj61zScaprVEVGHrPoXqI+M9sP0NDnTK2jpkvmldpuqDw==", "requires": { "clipboard": "^2.0.0" } diff --git a/site/package.json b/site/package.json index fd5be85976..c416fe5bf1 100644 --- a/site/package.json +++ b/site/package.json @@ -25,7 +25,7 @@ "pg": "^7.12.1", "polka": "^1.0.0-next.9", "prism-svelte": "^0.4.3", - "prismjs": "^1.17.1", + "prismjs": "^1.21.0", "sirv": "^1.0.0-next.2", "yootils": "0.0.16" }, From ad8d8564ec6899d71c96b152194a0f985fa7508c Mon Sep 17 00:00:00 2001 From: Venkateshwaran Selvaraj <38975782+venkateshwarans@users.noreply.github.com> Date: Thu, 13 Aug 2020 01:41:43 +0530 Subject: [PATCH 23/94] Adding Rich Harris's Frontend Masters course on FAQ page (#5180) * Adding Rich Harris's Frontend Masters course on FAQ page Co-authored-by: Ben McCann <322311+benmccann@users.noreply.github.com> --- site/content/faq/200-are-there-any-video-courses.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/site/content/faq/200-are-there-any-video-courses.md b/site/content/faq/200-are-there-any-video-courses.md index 0c2c1f680e..1a70cdfcf5 100644 --- a/site/content/faq/200-are-there-any-video-courses.md +++ b/site/content/faq/200-are-there-any-video-courses.md @@ -2,7 +2,11 @@ question: Are there any video courses? --- -There are no official ones, but here are a couple of third-part ones that we know of. +Rich Harris, the creator of Svelte, taught a course: + +- [Frontend Masters](https://frontendmasters.com/courses/svelte/) + +There are also a couple of third-party courses: - [Egghead](https://egghead.io/playlists/getting-started-with-svelte-3-05a8541a) - [Udemy](https://www.udemy.com/sveltejs-the-complete-guide/) From 7aae362bcbd42e7f8e1ddb1f08a86ce04132d002 Mon Sep 17 00:00:00 2001 From: Tan Li Hau Date: Thu, 13 Aug 2020 04:20:52 +0800 Subject: [PATCH 24/94] fix reference for namespaced component (#5256) --- CHANGELOG.md | 1 + .../wrappers/InlineComponent/index.ts | 3 ++- .../utils/string_to_member_expression.ts | 17 +++++++++++++++++ .../samples/component-namespace/Tooltip.svelte | 1 + .../samples/component-namespace/Widget.svelte | 5 +++++ .../samples/component-namespace/_config.js | 3 +++ .../samples/component-namespace/main.svelte | 8 ++++++++ 7 files changed, 37 insertions(+), 1 deletion(-) create mode 100644 src/compiler/compile/utils/string_to_member_expression.ts create mode 100644 test/runtime/samples/component-namespace/Tooltip.svelte create mode 100644 test/runtime/samples/component-namespace/Widget.svelte create mode 100644 test/runtime/samples/component-namespace/_config.js create mode 100644 test/runtime/samples/component-namespace/main.svelte diff --git a/CHANGELOG.md b/CHANGELOG.md index fd590c71aa..6eda8563c2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ ## Unreleased * In SSR mode, do not automatically declare variables for reactive assignments to member expressions ([#5247](https://github.com/sveltejs/svelte/issues/5247)) +* Fix using ``s in child `{#await}`/`{#each}` contexts ([#5255](https://github.com/sveltejs/svelte/issues/5255)) ## 3.24.1 diff --git a/src/compiler/compile/render_dom/wrappers/InlineComponent/index.ts b/src/compiler/compile/render_dom/wrappers/InlineComponent/index.ts index 814f365a84..904cfa3329 100644 --- a/src/compiler/compile/render_dom/wrappers/InlineComponent/index.ts +++ b/src/compiler/compile/render_dom/wrappers/InlineComponent/index.ts @@ -17,6 +17,7 @@ import { Node, Identifier, ObjectExpression } from 'estree'; import EventHandler from '../Element/EventHandler'; import { extract_names } from 'periscopic'; import mark_each_block_bindings from '../shared/mark_each_block_bindings'; +import { string_to_member_expression } from '../../../utils/string_to_member_expression'; export default class InlineComponentWrapper extends Wrapper { var: Identifier; @@ -484,7 +485,7 @@ export default class InlineComponentWrapper extends Wrapper { } else { const expression = this.node.name === 'svelte:self' ? component.name - : this.renderer.reference(this.node.name); + : this.renderer.reference(string_to_member_expression(this.node.name)); block.chunks.init.push(b` ${(this.node.attributes.length > 0 || this.node.bindings.length > 0) && b` diff --git a/src/compiler/compile/utils/string_to_member_expression.ts b/src/compiler/compile/utils/string_to_member_expression.ts new file mode 100644 index 0000000000..553c1371bd --- /dev/null +++ b/src/compiler/compile/utils/string_to_member_expression.ts @@ -0,0 +1,17 @@ +import { MemberExpression, Identifier } from "estree"; + +export function string_to_member_expression(name: string) { + const parts = name.split("."); + let node: MemberExpression | Identifier = { + type: "Identifier", + name: parts[0], + }; + for (let i = 1; i < parts.length; i++) { + node = { + type: "MemberExpression", + object: node, + property: { type: "Identifier", name: parts[i] }, + } as MemberExpression; + } + return node; +} diff --git a/test/runtime/samples/component-namespace/Tooltip.svelte b/test/runtime/samples/component-namespace/Tooltip.svelte new file mode 100644 index 0000000000..9b44ef57a8 --- /dev/null +++ b/test/runtime/samples/component-namespace/Tooltip.svelte @@ -0,0 +1 @@ +

i am a widget

\ No newline at end of file diff --git a/test/runtime/samples/component-namespace/Widget.svelte b/test/runtime/samples/component-namespace/Widget.svelte new file mode 100644 index 0000000000..b6aa45c6a8 --- /dev/null +++ b/test/runtime/samples/component-namespace/Widget.svelte @@ -0,0 +1,5 @@ + \ No newline at end of file diff --git a/test/runtime/samples/component-namespace/_config.js b/test/runtime/samples/component-namespace/_config.js new file mode 100644 index 0000000000..5b96ac8df0 --- /dev/null +++ b/test/runtime/samples/component-namespace/_config.js @@ -0,0 +1,3 @@ +export default { + html: '

i am a widget

' +}; diff --git a/test/runtime/samples/component-namespace/main.svelte b/test/runtime/samples/component-namespace/main.svelte new file mode 100644 index 0000000000..3f53b2b1c8 --- /dev/null +++ b/test/runtime/samples/component-namespace/main.svelte @@ -0,0 +1,8 @@ + + +{#each widgets as LazyWidget} + +{/each} \ No newline at end of file From 0e1345548f6568fcafe242c1aa0396b68d66fbcc Mon Sep 17 00:00:00 2001 From: Zachiah <50641830+Zachiah@users.noreply.github.com> Date: Wed, 12 Aug 2020 14:57:04 -0600 Subject: [PATCH 25/94] add selector to message of css-unused-selector warning (#5253) --- src/compiler/compile/css/Stylesheet.ts | 2 +- test/css/samples/empty-class/_config.js | 2 +- .../global-with-unused-descendant/_config.js | 2 +- .../_config.js | 2 +- .../unused-selector-leading/_config.js | 4 ++-- .../unused-selector-string-concat/_config.js | 20 +++++++++---------- .../unused-selector-ternary-concat/_config.js | 2 +- .../unused-selector-ternary-nested/_config.js | 4 ++-- .../unused-selector-ternary/_config.js | 2 +- test/css/samples/unused-selector/_config.js | 2 +- 10 files changed, 21 insertions(+), 21 deletions(-) diff --git a/src/compiler/compile/css/Stylesheet.ts b/src/compiler/compile/css/Stylesheet.ts index 246dab0f12..27438947ff 100644 --- a/src/compiler/compile/css/Stylesheet.ts +++ b/src/compiler/compile/css/Stylesheet.ts @@ -435,7 +435,7 @@ export default class Stylesheet { child.warn_on_unused_selector((selector: Selector) => { component.warn(selector.node, { code: `css-unused-selector`, - message: `Unused CSS selector` + message: `Unused CSS selector "${this.source.slice(selector.node.start, selector.node.end)}"` }); }); }); diff --git a/test/css/samples/empty-class/_config.js b/test/css/samples/empty-class/_config.js index cc766d9478..064de4a564 100644 --- a/test/css/samples/empty-class/_config.js +++ b/test/css/samples/empty-class/_config.js @@ -2,7 +2,7 @@ export default { warnings: [{ filename: "SvelteComponent.svelte", code: `css-unused-selector`, - message: "Unused CSS selector", + message: 'Unused CSS selector ".x"', start: { line: 4, column: 1, diff --git a/test/css/samples/global-with-unused-descendant/_config.js b/test/css/samples/global-with-unused-descendant/_config.js index 3ed2dd2728..69a69ad650 100644 --- a/test/css/samples/global-with-unused-descendant/_config.js +++ b/test/css/samples/global-with-unused-descendant/_config.js @@ -13,7 +13,7 @@ export default { 3: color: red; 4: } `, - message: 'Unused CSS selector', + message: 'Unused CSS selector ":global(.foo) .bar"', pos: 9, start: { character: 9, diff --git a/test/css/samples/omit-scoping-attribute-descendant/_config.js b/test/css/samples/omit-scoping-attribute-descendant/_config.js index a4aaec7c19..25e2a28ebb 100644 --- a/test/css/samples/omit-scoping-attribute-descendant/_config.js +++ b/test/css/samples/omit-scoping-attribute-descendant/_config.js @@ -1,7 +1,7 @@ export default { warnings: [{ code: `css-unused-selector`, - message: 'Unused CSS selector', + message: 'Unused CSS selector "div > p"', start: { line: 8, column: 1, diff --git a/test/css/samples/unused-selector-leading/_config.js b/test/css/samples/unused-selector-leading/_config.js index 20310a5847..2516567f59 100644 --- a/test/css/samples/unused-selector-leading/_config.js +++ b/test/css/samples/unused-selector-leading/_config.js @@ -3,7 +3,7 @@ export default { { filename: "SvelteComponent.svelte", code: `css-unused-selector`, - message: "Unused CSS selector", + message: 'Unused CSS selector ".foo"', start: { line: 4, column: 1, @@ -27,7 +27,7 @@ export default { { filename: "SvelteComponent.svelte", code: `css-unused-selector`, - message: "Unused CSS selector", + message: 'Unused CSS selector ".baz"', start: { line: 4, column: 13, diff --git a/test/css/samples/unused-selector-string-concat/_config.js b/test/css/samples/unused-selector-string-concat/_config.js index 81318fd3ac..ea8f85754e 100644 --- a/test/css/samples/unused-selector-string-concat/_config.js +++ b/test/css/samples/unused-selector-string-concat/_config.js @@ -2,7 +2,7 @@ export default { warnings: [ { code: 'css-unused-selector', - message: 'Unused CSS selector', + message: 'Unused CSS selector ".fooaa"', frame: ` 9: `, - message: 'Unused CSS selector', + message: 'Unused CSS selector ".unused"', pos: 198, start: { character: 198, diff --git a/test/css/samples/unused-selector-ternary-nested/_config.js b/test/css/samples/unused-selector-ternary-nested/_config.js index afee5ac822..936ac639e5 100644 --- a/test/css/samples/unused-selector-ternary-nested/_config.js +++ b/test/css/samples/unused-selector-ternary-nested/_config.js @@ -2,7 +2,7 @@ export default { warnings: [ { code: 'css-unused-selector', - message: 'Unused CSS selector', + message: 'Unused CSS selector ".hover.unused"', frame: ` 13: .thing.active {color: blue;} 14: .hover { color: blue; } @@ -16,7 +16,7 @@ export default { }, { code: 'css-unused-selector', - message: 'Unused CSS selector', + message: 'Unused CSS selector ".unused"', frame: ` 15: .hover.unused { color: blue; } 16: diff --git a/test/css/samples/unused-selector-ternary/_config.js b/test/css/samples/unused-selector-ternary/_config.js index 4ff2713108..4eb12f3fe2 100644 --- a/test/css/samples/unused-selector-ternary/_config.js +++ b/test/css/samples/unused-selector-ternary/_config.js @@ -6,7 +6,7 @@ export default { warnings: [{ filename: "SvelteComponent.svelte", code: `css-unused-selector`, - message: "Unused CSS selector", + message: 'Unused CSS selector ".maybeactive"', start: { line: 16, column: 1, diff --git a/test/css/samples/unused-selector/_config.js b/test/css/samples/unused-selector/_config.js index 49fb3a27e7..790eb9e875 100644 --- a/test/css/samples/unused-selector/_config.js +++ b/test/css/samples/unused-selector/_config.js @@ -2,7 +2,7 @@ export default { warnings: [{ filename: "SvelteComponent.svelte", code: `css-unused-selector`, - message: "Unused CSS selector", + message: 'Unused CSS selector ".bar"', start: { line: 8, column: 1, From 6ebe7f8210a2b81a79a07420d45f9bbe04a5cfa7 Mon Sep 17 00:00:00 2001 From: Conduitry Date: Wed, 12 Aug 2020 16:58:45 -0400 Subject: [PATCH 26/94] update changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6eda8563c2..1c5d665195 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ ## Unreleased * In SSR mode, do not automatically declare variables for reactive assignments to member expressions ([#5247](https://github.com/sveltejs/svelte/issues/5247)) +* Include selector in message of `unused-css-selector` warning ([#5252](https://github.com/sveltejs/svelte/issues/5252)) * Fix using ``s in child `{#await}`/`{#each}` contexts ([#5255](https://github.com/sveltejs/svelte/issues/5255)) ## 3.24.1 From aa7e5e32b1566ce4a3b399064f74206204af72dd Mon Sep 17 00:00:00 2001 From: Simon H <5968653+dummdidumm@users.noreply.github.com> Date: Wed, 12 Aug 2020 23:05:49 +0200 Subject: [PATCH 27/94] add typings for createEventDispatcher (#5260) --- src/runtime/internal/lifecycle.ts | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/runtime/internal/lifecycle.ts b/src/runtime/internal/lifecycle.ts index 34d52672a2..304e8d6a68 100644 --- a/src/runtime/internal/lifecycle.ts +++ b/src/runtime/internal/lifecycle.ts @@ -27,7 +27,9 @@ export function onDestroy(fn) { get_current_component().$$.on_destroy.push(fn); } -export function createEventDispatcher() { +export function createEventDispatcher< + EventMap extends {} = any +>(): >(type: EventKey, detail?: EventMap[EventKey]) => void { const component = get_current_component(); return (type: string, detail?: any) => { @@ -61,4 +63,4 @@ export function bubble(component, event) { if (callbacks) { callbacks.slice().forEach(fn => fn(event)); } -} \ No newline at end of file +} From 76b7196a1bfbf4dd40a82b8dc80b0aed08ea73bd Mon Sep 17 00:00:00 2001 From: Conduitry Date: Wed, 12 Aug 2020 17:06:26 -0400 Subject: [PATCH 28/94] update changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1c5d665195..05a4b12fa3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,7 @@ ## Unreleased +* Add types to `createEventDispatcher` ([#5211](https://github.com/sveltejs/svelte/issues/5211)) * In SSR mode, do not automatically declare variables for reactive assignments to member expressions ([#5247](https://github.com/sveltejs/svelte/issues/5247)) * Include selector in message of `unused-css-selector` warning ([#5252](https://github.com/sveltejs/svelte/issues/5252)) * Fix using ``s in child `{#await}`/`{#each}` contexts ([#5255](https://github.com/sveltejs/svelte/issues/5255)) From e879cb5a4ceff11845a9c028b369bfa9c9aa274f Mon Sep 17 00:00:00 2001 From: Tan Li Hau Date: Thu, 13 Aug 2020 05:24:19 +0800 Subject: [PATCH 29/94] fix not passing child_ctx for catch block (#5261) --- CHANGELOG.md | 1 + .../compile/render_dom/wrappers/AwaitBlock.ts | 13 +++- .../await-with-update-2/Component.svelte | 7 ++ .../samples/await-with-update-2/_config.js | 64 +++++++++++++++++++ .../samples/await-with-update-2/main.svelte | 16 +++++ .../await-with-update/Component.svelte | 5 ++ .../samples/await-with-update/_config.js | 60 +++++++++++++++++ .../samples/await-with-update/main.svelte | 16 +++++ 8 files changed, 180 insertions(+), 2 deletions(-) create mode 100644 test/runtime/samples/await-with-update-2/Component.svelte create mode 100644 test/runtime/samples/await-with-update-2/_config.js create mode 100644 test/runtime/samples/await-with-update-2/main.svelte create mode 100644 test/runtime/samples/await-with-update/Component.svelte create mode 100644 test/runtime/samples/await-with-update/_config.js create mode 100644 test/runtime/samples/await-with-update/main.svelte diff --git a/CHANGELOG.md b/CHANGELOG.md index 05a4b12fa3..bface6c86d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,7 @@ * In SSR mode, do not automatically declare variables for reactive assignments to member expressions ([#5247](https://github.com/sveltejs/svelte/issues/5247)) * Include selector in message of `unused-css-selector` warning ([#5252](https://github.com/sveltejs/svelte/issues/5252)) * Fix using ``s in child `{#await}`/`{#each}` contexts ([#5255](https://github.com/sveltejs/svelte/issues/5255)) +* Fix using `` in `{:catch}` ([#5259](https://github.com/sveltejs/svelte/issues/5259)) ## 3.24.1 diff --git a/src/compiler/compile/render_dom/wrappers/AwaitBlock.ts b/src/compiler/compile/render_dom/wrappers/AwaitBlock.ts index ceb898bf79..495f1b3157 100644 --- a/src/compiler/compile/render_dom/wrappers/AwaitBlock.ts +++ b/src/compiler/compile/render_dom/wrappers/AwaitBlock.ts @@ -231,6 +231,15 @@ export default class AwaitBlockWrapper extends Wrapper { const dependencies = this.node.expression.dynamic_dependencies(); + let update_child_context; + if (this.then.value && this.catch.value) { + update_child_context = b`#child_ctx[${this.then.value_index}] = #child_ctx[${this.catch.value_index}] = ${info}.resolved;`; + } else if (this.then.value) { + update_child_context = b`#child_ctx[${this.then.value_index}] = ${info}.resolved;`; + } else if (this.catch.value) { + update_child_context = b`#child_ctx[${this.catch.value_index}] = ${info}.resolved;`; + } + if (dependencies.length > 0) { const condition = x` ${block.renderer.dirty(dependencies)} && @@ -247,7 +256,7 @@ export default class AwaitBlockWrapper extends Wrapper { } else { const #child_ctx = #ctx.slice(); - ${this.then.value && b`#child_ctx[${this.then.value_index}] = ${info}.resolved;`} + ${update_child_context} ${info}.block.p(#child_ctx, #dirty); } `); @@ -261,7 +270,7 @@ export default class AwaitBlockWrapper extends Wrapper { block.chunks.update.push(b` { const #child_ctx = #ctx.slice(); - ${this.then.value && b`#child_ctx[${this.then.value_index}] = ${info}.resolved;`} + ${update_child_context} ${info}.block.p(#child_ctx, #dirty); } `); diff --git a/test/runtime/samples/await-with-update-2/Component.svelte b/test/runtime/samples/await-with-update-2/Component.svelte new file mode 100644 index 0000000000..1301db3f99 --- /dev/null +++ b/test/runtime/samples/await-with-update-2/Component.svelte @@ -0,0 +1,7 @@ + + +
count: {count}
+
value: {value}
\ No newline at end of file diff --git a/test/runtime/samples/await-with-update-2/_config.js b/test/runtime/samples/await-with-update-2/_config.js new file mode 100644 index 0000000000..7584381eeb --- /dev/null +++ b/test/runtime/samples/await-with-update-2/_config.js @@ -0,0 +1,64 @@ +export default { + props: { + thePromise: new Promise((_) => {}), + count: 0, + }, + + html: ` +

loading...

+ `, + + async test({ assert, component, target }) { + await (component.thePromise = Promise.resolve({ value: "success", Component: component.Component })); + + assert.htmlEqual( + target.innerHTML, + ` +
Resolved: +
count: 0
+
value: success
+
+ ` + ); + + component.count = 5; + + assert.htmlEqual( + target.innerHTML, + ` +
Resolved: +
count: 5
+
value: success
+
+ ` + ); + + try { + await (component.thePromise = Promise.reject({ value: "failure", Component: component.Component })); + } catch (error) { + // ignore + } + + assert.htmlEqual( + target.innerHTML, + ` +
Rejected: +
count: 5
+
value: failure
+
+ ` + ); + + component.count = 10; + + assert.htmlEqual( + target.innerHTML, + ` +
Rejected: +
count: 10
+
value: failure
+
+ ` + ); + }, +}; diff --git a/test/runtime/samples/await-with-update-2/main.svelte b/test/runtime/samples/await-with-update-2/main.svelte new file mode 100644 index 0000000000..b29c875f92 --- /dev/null +++ b/test/runtime/samples/await-with-update-2/main.svelte @@ -0,0 +1,16 @@ + + +
+ {#await thePromise} +

loading...

+ {:then { value: theValue, Component }} + Resolved: + {:catch { value: theError, Component } } + Rejected: + {/await} +
\ No newline at end of file diff --git a/test/runtime/samples/await-with-update/Component.svelte b/test/runtime/samples/await-with-update/Component.svelte new file mode 100644 index 0000000000..5f13c80e65 --- /dev/null +++ b/test/runtime/samples/await-with-update/Component.svelte @@ -0,0 +1,5 @@ + + +
count: {count}
\ No newline at end of file diff --git a/test/runtime/samples/await-with-update/_config.js b/test/runtime/samples/await-with-update/_config.js new file mode 100644 index 0000000000..31de26ddba --- /dev/null +++ b/test/runtime/samples/await-with-update/_config.js @@ -0,0 +1,60 @@ +export default { + props: { + thePromise: new Promise((_) => {}), + count: 0, + }, + + html: ` +

loading...

+ `, + + async test({ assert, component, target }) { + await (component.thePromise = Promise.resolve(component.Component)); + + assert.htmlEqual( + target.innerHTML, + ` +
Resolved: +
count: 0
+
+ ` + ); + + component.count = 5; + + assert.htmlEqual( + target.innerHTML, + ` +
Resolved: +
count: 5
+
+ ` + ); + + try { + await (component.thePromise = Promise.reject(component.Component)); + } catch (error) { + // ignore + } + + assert.htmlEqual( + target.innerHTML, + ` +
Rejected: +
count: 5
+
+ ` + ); + + component.count = 10; + + assert.htmlEqual( + target.innerHTML, + ` +
Rejected: +
count: 10
+
+ ` + ); + }, +}; diff --git a/test/runtime/samples/await-with-update/main.svelte b/test/runtime/samples/await-with-update/main.svelte new file mode 100644 index 0000000000..51c5b76a21 --- /dev/null +++ b/test/runtime/samples/await-with-update/main.svelte @@ -0,0 +1,16 @@ + + +
+ {#await thePromise} +

loading...

+ {:then theValue} + Resolved: + {:catch theError} + Rejected: + {/await} +
\ No newline at end of file From dccdb9f1304b55b3a3bea68902d86dbf507cb4d4 Mon Sep 17 00:00:00 2001 From: Wolfr Date: Wed, 12 Aug 2020 23:43:45 +0200 Subject: [PATCH 30/94] site: show REPL input/output toggle on iOS without scrolling (#5175) --- site/src/components/Repl/InputOutputToggle.svelte | 2 +- site/src/components/Repl/ReplWidget.svelte | 3 +++ site/src/routes/_layout.svelte | 1 + .../routes/repl/[id]/_components/AppControls/index.svelte | 1 + site/src/routes/repl/[id]/index.svelte | 5 ++++- site/src/routes/repl/embed.svelte | 2 ++ 6 files changed, 12 insertions(+), 2 deletions(-) diff --git a/site/src/components/Repl/InputOutputToggle.svelte b/site/src/components/Repl/InputOutputToggle.svelte index dc4db92269..8233ee58b2 100644 --- a/site/src/components/Repl/InputOutputToggle.svelte +++ b/site/src/components/Repl/InputOutputToggle.svelte @@ -5,8 +5,8 @@ From 0ac341d2c6823114786788fb2d49bb324b372e4b Mon Sep 17 00:00:00 2001 From: Tan Li Hau Date: Thu, 13 Aug 2020 22:20:55 +0800 Subject: [PATCH 31/94] expose which slots are present in $$slots (#4602) --- CHANGELOG.md | 1 + src/compiler/compile/render_dom/Renderer.ts | 2 +- src/compiler/compile/render_dom/index.ts | 16 ++++++++-- .../compile/render_dom/wrappers/Slot.ts | 2 +- .../compile/render_ssr/handlers/Slot.ts | 4 +-- src/compiler/compile/render_ssr/index.ts | 6 +++- .../compile/utils/reserved_keywords.ts | 2 +- src/runtime/internal/utils.ts | 8 +++++ .../samples/capture-inject-state/expected.js | 5 ++- test/js/samples/debug-empty/expected.js | 5 ++- .../debug-foo-bar-baz-things/expected.js | 5 ++- test/js/samples/debug-foo/expected.js | 5 ++- test/js/samples/debug-hoisted/expected.js | 4 +-- .../samples/debug-no-dependencies/expected.js | 4 +-- test/js/samples/debug-ssr-foo/expected.js | 2 +- .../expected.js | 5 ++- test/js/samples/loop-protect/expected.js | 5 ++- .../samples/ssr-no-oncreate-etc/expected.js | 2 +- .../samples/ssr-preserve-comments/expected.js | 2 +- test/runtime/samples/$$slot/A.svelte | 31 +++++++++++++++++++ test/runtime/samples/$$slot/_config.js | 18 +++++++++++ test/runtime/samples/$$slot/main.svelte | 23 ++++++++++++++ 22 files changed, 123 insertions(+), 34 deletions(-) create mode 100644 test/runtime/samples/$$slot/A.svelte create mode 100644 test/runtime/samples/$$slot/_config.js create mode 100644 test/runtime/samples/$$slot/main.svelte diff --git a/CHANGELOG.md b/CHANGELOG.md index bface6c86d..ceff78b107 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,7 @@ ## Unreleased +* Expose object of which slots have received content in `$$slots` ([#2106](https://github.com/sveltejs/svelte/issues/2106)) * Add types to `createEventDispatcher` ([#5211](https://github.com/sveltejs/svelte/issues/5211)) * In SSR mode, do not automatically declare variables for reactive assignments to member expressions ([#5247](https://github.com/sveltejs/svelte/issues/5247)) * Include selector in message of `unused-css-selector` warning ([#5252](https://github.com/sveltejs/svelte/issues/5252)) diff --git a/src/compiler/compile/render_dom/Renderer.ts b/src/compiler/compile/render_dom/Renderer.ts index c02d646ebf..5092626d25 100644 --- a/src/compiler/compile/render_dom/Renderer.ts +++ b/src/compiler/compile/render_dom/Renderer.ts @@ -60,7 +60,7 @@ export default class Renderer { if (component.slots.size > 0) { this.add_to_context('$$scope'); - this.add_to_context('$$slots'); + this.add_to_context('#slots'); } if (this.binding_groups.size > 0) { diff --git a/src/compiler/compile/render_dom/index.ts b/src/compiler/compile/render_dom/index.ts index 7d0dce8315..4ee9abae49 100644 --- a/src/compiler/compile/render_dom/index.ts +++ b/src/compiler/compile/render_dom/index.ts @@ -70,6 +70,15 @@ export default function dom( ); } + const uses_slots = component.var_lookup.has('$$slots'); + let compute_slots; + if (uses_slots) { + compute_slots = b` + const $$slots = @compute_slots(#slots); + `; + } + + const uses_props = component.var_lookup.has('$$props'); const uses_rest = component.var_lookup.has('$$restProps'); const $$props = uses_props || uses_rest ? `$$new_props` : `$$props`; @@ -409,13 +418,14 @@ export default function dom( ${resubscribable_reactive_store_unsubscribers} + ${component.slots.size || component.compile_options.dev || uses_slots ? b`let { $$slots: #slots = {}, $$scope } = $$props;` : null} + ${component.compile_options.dev && b`@validate_slots('${component.tag}', #slots, [${[...component.slots.keys()].map(key => `'${key}'`).join(',')}]);`} + ${compute_slots} + ${instance_javascript} ${unknown_props_check} - ${component.slots.size || component.compile_options.dev ? b`let { $$slots = {}, $$scope } = $$props;` : null} - ${component.compile_options.dev && b`@validate_slots('${component.tag}', $$slots, [${[...component.slots.keys()].map(key => `'${key}'`).join(',')}]);`} - ${renderer.binding_groups.size > 0 && b`const $$binding_groups = [${[...renderer.binding_groups.keys()].map(_ => x`[]`)}];`} ${component.partly_hoisted} diff --git a/src/compiler/compile/render_dom/wrappers/Slot.ts b/src/compiler/compile/render_dom/wrappers/Slot.ts index bf808196c0..5c02e78158 100644 --- a/src/compiler/compile/render_dom/wrappers/Slot.ts +++ b/src/compiler/compile/render_dom/wrappers/Slot.ts @@ -125,7 +125,7 @@ export default class SlotWrapper extends Wrapper { const slot_or_fallback = has_fallback ? block.get_unique_name(`${sanitize(slot_name)}_slot_or_fallback`) : slot; block.chunks.init.push(b` - const ${slot_definition} = ${renderer.reference('$$slots')}.${slot_name}; + const ${slot_definition} = ${renderer.reference('#slots')}.${slot_name}; const ${slot} = @create_slot(${slot_definition}, #ctx, ${renderer.reference('$$scope')}, ${get_slot_context_fn}); ${has_fallback ? b`const ${slot_or_fallback} = ${slot} || ${this.fallback.name}(#ctx);` : null} `); diff --git a/src/compiler/compile/render_ssr/handlers/Slot.ts b/src/compiler/compile/render_ssr/handlers/Slot.ts index 3b1e199c75..32b6246e64 100644 --- a/src/compiler/compile/render_ssr/handlers/Slot.ts +++ b/src/compiler/compile/render_ssr/handlers/Slot.ts @@ -11,8 +11,8 @@ export default function(node: Slot, renderer: Renderer, options: RenderOptions) const result = renderer.pop(); renderer.add_expression(x` - $$slots.${node.slot_name} - ? $$slots.${node.slot_name}(${slot_data}) + #slots.${node.slot_name} + ? #slots.${node.slot_name}(${slot_data}) : ${result} `); } diff --git a/src/compiler/compile/render_ssr/index.ts b/src/compiler/compile/render_ssr/index.ts index a72b8b35ae..ff45abd78b 100644 --- a/src/compiler/compile/render_ssr/index.ts +++ b/src/compiler/compile/render_ssr/index.ts @@ -34,6 +34,9 @@ export default function ssr( const props = component.vars.filter(variable => !variable.module && variable.export_name); const rest = uses_rest ? b`let $$restProps = @compute_rest_props($$props, [${props.map(prop => `"${prop.export_name}"`).join(',')}]);` : null; + const uses_slots = component.var_lookup.has('$$slots'); + const slots = uses_slots ? b`let $$slots = @compute_slots(#slots);` : null; + const reactive_stores = component.vars.filter(variable => variable.name[0] === '$' && variable.name[1] !== '$'); const reactive_store_values = reactive_stores .map(({ name }) => { @@ -118,6 +121,7 @@ export default function ssr( const blocks = [ rest, + slots, ...reactive_stores.map(({ name }) => { const store_name = name.slice(1); const store = component.var_lookup.get(store_name); @@ -144,7 +148,7 @@ export default function ssr( ${component.fully_hoisted} - const ${name} = @create_ssr_component(($$result, $$props, $$bindings, $$slots) => { + const ${name} = @create_ssr_component(($$result, $$props, $$bindings, #slots) => { ${blocks} }); `; diff --git a/src/compiler/compile/utils/reserved_keywords.ts b/src/compiler/compile/utils/reserved_keywords.ts index 75825c1719..d6eb8b9673 100644 --- a/src/compiler/compile/utils/reserved_keywords.ts +++ b/src/compiler/compile/utils/reserved_keywords.ts @@ -1,4 +1,4 @@ -export const reserved_keywords = new Set(["$$props", "$$restProps"]); +export const reserved_keywords = new Set(["$$props", "$$restProps", "$$slots"]); export function is_reserved_keyword(name) { return reserved_keywords.has(name); diff --git a/src/runtime/internal/utils.ts b/src/runtime/internal/utils.ts index 3fd0a2b701..633b6f054c 100644 --- a/src/runtime/internal/utils.ts +++ b/src/runtime/internal/utils.ts @@ -128,6 +128,14 @@ export function compute_rest_props(props, keys) { return rest; } +export function compute_slots(slots) { + const result = {}; + for (const key in slots) { + result[key] = true; + } + return result; +} + export function once(fn) { let ran = false; return function(this: any, ...args) { diff --git a/test/js/samples/capture-inject-state/expected.js b/test/js/samples/capture-inject-state/expected.js index 6aa93b9c5a..6a0351ae44 100644 --- a/test/js/samples/capture-inject-state/expected.js +++ b/test/js/samples/capture-inject-state/expected.js @@ -103,6 +103,8 @@ function instance($$self, $$props, $$invalidate) { $$subscribe_prop = () => ($$unsubscribe_prop(), $$unsubscribe_prop = subscribe(prop, $$value => $$invalidate(2, $prop = $$value)), prop); $$self.$$.on_destroy.push(() => $$unsubscribe_prop()); + let { $$slots: slots = {}, $$scope } = $$props; + validate_slots("Component", slots, []); let { prop } = $$props; validate_store(prop, "prop"); $$subscribe_prop(); @@ -115,9 +117,6 @@ function instance($$self, $$props, $$invalidate) { if (!~writable_props.indexOf(key) && key.slice(0, 2) !== "$$") console.warn(` was created with unknown prop '${key}'`); }); - let { $$slots = {}, $$scope } = $$props; - validate_slots("Component", $$slots, []); - $$self.$$set = $$props => { if ("prop" in $$props) $$subscribe_prop($$invalidate(0, prop = $$props.prop)); if ("alias" in $$props) $$invalidate(1, realName = $$props.alias); diff --git a/test/js/samples/debug-empty/expected.js b/test/js/samples/debug-empty/expected.js index 6781e5333c..f427f1bf45 100644 --- a/test/js/samples/debug-empty/expected.js +++ b/test/js/samples/debug-empty/expected.js @@ -69,6 +69,8 @@ function create_fragment(ctx) { } function instance($$self, $$props, $$invalidate) { + let { $$slots: slots = {}, $$scope } = $$props; + validate_slots("Component", slots, []); let { name } = $$props; const writable_props = ["name"]; @@ -76,9 +78,6 @@ function instance($$self, $$props, $$invalidate) { if (!~writable_props.indexOf(key) && key.slice(0, 2) !== "$$") console.warn(` was created with unknown prop '${key}'`); }); - let { $$slots = {}, $$scope } = $$props; - validate_slots("Component", $$slots, []); - $$self.$$set = $$props => { if ("name" in $$props) $$invalidate(0, name = $$props.name); }; diff --git a/test/js/samples/debug-foo-bar-baz-things/expected.js b/test/js/samples/debug-foo-bar-baz-things/expected.js index 087d2e399d..7439b3310b 100644 --- a/test/js/samples/debug-foo-bar-baz-things/expected.js +++ b/test/js/samples/debug-foo-bar-baz-things/expected.js @@ -170,6 +170,8 @@ function create_fragment(ctx) { } function instance($$self, $$props, $$invalidate) { + let { $$slots: slots = {}, $$scope } = $$props; + validate_slots("Component", slots, []); let { things } = $$props; let { foo } = $$props; let { bar } = $$props; @@ -180,9 +182,6 @@ function instance($$self, $$props, $$invalidate) { if (!~writable_props.indexOf(key) && key.slice(0, 2) !== "$$") console.warn(` was created with unknown prop '${key}'`); }); - let { $$slots = {}, $$scope } = $$props; - validate_slots("Component", $$slots, []); - $$self.$$set = $$props => { if ("things" in $$props) $$invalidate(0, things = $$props.things); if ("foo" in $$props) $$invalidate(1, foo = $$props.foo); diff --git a/test/js/samples/debug-foo/expected.js b/test/js/samples/debug-foo/expected.js index 9f12bfb807..d869a5cf9e 100644 --- a/test/js/samples/debug-foo/expected.js +++ b/test/js/samples/debug-foo/expected.js @@ -164,6 +164,8 @@ function create_fragment(ctx) { } function instance($$self, $$props, $$invalidate) { + let { $$slots: slots = {}, $$scope } = $$props; + validate_slots("Component", slots, []); let { things } = $$props; let { foo } = $$props; const writable_props = ["things", "foo"]; @@ -172,9 +174,6 @@ function instance($$self, $$props, $$invalidate) { if (!~writable_props.indexOf(key) && key.slice(0, 2) !== "$$") console.warn(` was created with unknown prop '${key}'`); }); - let { $$slots = {}, $$scope } = $$props; - validate_slots("Component", $$slots, []); - $$self.$$set = $$props => { if ("things" in $$props) $$invalidate(0, things = $$props.things); if ("foo" in $$props) $$invalidate(1, foo = $$props.foo); diff --git a/test/js/samples/debug-hoisted/expected.js b/test/js/samples/debug-hoisted/expected.js index 0e634297f0..c6257ac90d 100644 --- a/test/js/samples/debug-hoisted/expected.js +++ b/test/js/samples/debug-hoisted/expected.js @@ -49,6 +49,8 @@ function create_fragment(ctx) { } function instance($$self, $$props, $$invalidate) { + let { $$slots: slots = {}, $$scope } = $$props; + validate_slots("Component", slots, []); let obj = { x: 5 }; let kobzol = 5; const writable_props = []; @@ -57,8 +59,6 @@ function instance($$self, $$props, $$invalidate) { if (!~writable_props.indexOf(key) && key.slice(0, 2) !== "$$") console.warn(` was created with unknown prop '${key}'`); }); - let { $$slots = {}, $$scope } = $$props; - validate_slots("Component", $$slots, []); $$self.$capture_state = () => ({ obj, kobzol }); $$self.$inject_state = $$props => { diff --git a/test/js/samples/debug-no-dependencies/expected.js b/test/js/samples/debug-no-dependencies/expected.js index 76068e8cf4..4d8d05d3aa 100644 --- a/test/js/samples/debug-no-dependencies/expected.js +++ b/test/js/samples/debug-no-dependencies/expected.js @@ -136,14 +136,14 @@ function create_fragment(ctx) { } function instance($$self, $$props) { + let { $$slots: slots = {}, $$scope } = $$props; + validate_slots("Component", slots, []); const writable_props = []; Object.keys($$props).forEach(key => { if (!~writable_props.indexOf(key) && key.slice(0, 2) !== "$$") console.warn(` was created with unknown prop '${key}'`); }); - let { $$slots = {}, $$scope } = $$props; - validate_slots("Component", $$slots, []); return []; } diff --git a/test/js/samples/debug-ssr-foo/expected.js b/test/js/samples/debug-ssr-foo/expected.js index fe34a6a4fd..69da37b2d9 100644 --- a/test/js/samples/debug-ssr-foo/expected.js +++ b/test/js/samples/debug-ssr-foo/expected.js @@ -1,7 +1,7 @@ /* generated by Svelte vX.Y.Z */ import { create_ssr_component, debug, each, escape } from "svelte/internal"; -const Component = create_ssr_component(($$result, $$props, $$bindings, $$slots) => { +const Component = create_ssr_component(($$result, $$props, $$bindings, slots) => { let { things } = $$props; let { foo } = $$props; if ($$props.things === void 0 && $$bindings.things && things !== void 0) $$bindings.things(things); diff --git a/test/js/samples/dev-warning-missing-data-computed/expected.js b/test/js/samples/dev-warning-missing-data-computed/expected.js index fd34778f8d..8c7f8bb1cf 100644 --- a/test/js/samples/dev-warning-missing-data-computed/expected.js +++ b/test/js/samples/dev-warning-missing-data-computed/expected.js @@ -65,6 +65,8 @@ function create_fragment(ctx) { } function instance($$self, $$props, $$invalidate) { + let { $$slots: slots = {}, $$scope } = $$props; + validate_slots("Component", slots, []); let { foo } = $$props; let bar; const writable_props = ["foo"]; @@ -73,9 +75,6 @@ function instance($$self, $$props, $$invalidate) { if (!~writable_props.indexOf(key) && key.slice(0, 2) !== "$$") console.warn(` was created with unknown prop '${key}'`); }); - let { $$slots = {}, $$scope } = $$props; - validate_slots("Component", $$slots, []); - $$self.$$set = $$props => { if ("foo" in $$props) $$invalidate(0, foo = $$props.foo); }; diff --git a/test/js/samples/loop-protect/expected.js b/test/js/samples/loop-protect/expected.js index 2ee7d90f17..1042b20823 100644 --- a/test/js/samples/loop-protect/expected.js +++ b/test/js/samples/loop-protect/expected.js @@ -67,6 +67,8 @@ function foo() { } function instance($$self, $$props, $$invalidate) { + let { $$slots: slots = {}, $$scope } = $$props; + validate_slots("Component", slots, []); let node; { @@ -111,9 +113,6 @@ function instance($$self, $$props, $$invalidate) { if (!~writable_props.indexOf(key) && key.slice(0, 2) !== "$$") console_1.warn(` was created with unknown prop '${key}'`); }); - let { $$slots = {}, $$scope } = $$props; - validate_slots("Component", $$slots, []); - function div_binding($$value) { binding_callbacks[$$value ? "unshift" : "push"](() => { node = $$value; diff --git a/test/js/samples/ssr-no-oncreate-etc/expected.js b/test/js/samples/ssr-no-oncreate-etc/expected.js index 803f06a882..b91deb3e97 100644 --- a/test/js/samples/ssr-no-oncreate-etc/expected.js +++ b/test/js/samples/ssr-no-oncreate-etc/expected.js @@ -15,7 +15,7 @@ function swipe(node, callback) { } // TODO implement -const Component = create_ssr_component(($$result, $$props, $$bindings, $$slots) => { +const Component = create_ssr_component(($$result, $$props, $$bindings, slots) => { onMount(() => { console.log("onMount"); }); diff --git a/test/js/samples/ssr-preserve-comments/expected.js b/test/js/samples/ssr-preserve-comments/expected.js index 1dc12710c0..de9fa7582e 100644 --- a/test/js/samples/ssr-preserve-comments/expected.js +++ b/test/js/samples/ssr-preserve-comments/expected.js @@ -1,7 +1,7 @@ /* generated by Svelte vX.Y.Z */ import { create_ssr_component } from "svelte/internal"; -const Component = create_ssr_component(($$result, $$props, $$bindings, $$slots) => { +const Component = create_ssr_component(($$result, $$props, $$bindings, slots) => { return `
content
more content
`; diff --git a/test/runtime/samples/$$slot/A.svelte b/test/runtime/samples/$$slot/A.svelte new file mode 100644 index 0000000000..ffa166166c --- /dev/null +++ b/test/runtime/samples/$$slot/A.svelte @@ -0,0 +1,31 @@ + + + + + +$$slots: {toString($$slots)} + +{#if $$slots.b} +
+ +
+{:else} + Slot b is not available +{/if} \ No newline at end of file diff --git a/test/runtime/samples/$$slot/_config.js b/test/runtime/samples/$$slot/_config.js new file mode 100644 index 0000000000..13b2137cdb --- /dev/null +++ b/test/runtime/samples/$$slot/_config.js @@ -0,0 +1,18 @@ +export default { + html: ` + byeworld + hello world + $$slots: {"a":true,"default":true} + Slot b is not available + + bye world + hello world + $$slots: {"a":true,"b":true,"default":true} +
hello world
+ `, + + async test({ assert, target, component }) { + assert.equal(component.getA(), ''); + assert.equal(component.getB(), 'foo'); + } +}; diff --git a/test/runtime/samples/$$slot/main.svelte b/test/runtime/samples/$$slot/main.svelte new file mode 100644 index 0000000000..8b7efae573 --- /dev/null +++ b/test/runtime/samples/$$slot/main.svelte @@ -0,0 +1,23 @@ + + + + hello world + bye + world + + + + hello world + hello world + bye world + From 935caee2697deb6235af74d22fda60314527452d Mon Sep 17 00:00:00 2001 From: Teymour Aldridge <42674621+teymour-aldridge@users.noreply.github.com> Date: Fri, 14 Aug 2020 03:24:35 +0100 Subject: [PATCH 32/94] Minor code simplification (#5065) --- src/compiler/compile/render_dom/Renderer.ts | 3 +-- src/compiler/compile/render_dom/index.ts | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/src/compiler/compile/render_dom/Renderer.ts b/src/compiler/compile/render_dom/Renderer.ts index 5092626d25..576f70984e 100644 --- a/src/compiler/compile/render_dom/Renderer.ts +++ b/src/compiler/compile/render_dom/Renderer.ts @@ -160,8 +160,7 @@ export default class Renderer { member.is_contextual = true; } else { member.is_non_contextual = true; - const variable = this.component.var_lookup.get(name); - member.variable = variable; + member.variable = this.component.var_lookup.get(name); } return member; diff --git a/src/compiler/compile/render_dom/index.ts b/src/compiler/compile/render_dom/index.ts index 4ee9abae49..ab4ee904e8 100644 --- a/src/compiler/compile/render_dom/index.ts +++ b/src/compiler/compile/render_dom/index.ts @@ -302,8 +302,7 @@ export default function dom( const variable = component.var_lookup.get(prop.name); if (variable.hoistable) return false; - if (prop.name[0] === '$') return false; - return true; + return prop.name[0] !== '$'; }); const reactive_stores = component.vars.filter(variable => variable.name[0] === '$' && variable.name[1] !== '$'); From cd95654a970046e6bd03a7081dfd5f27ec0d4abc Mon Sep 17 00:00:00 2001 From: Alex Rock Date: Fri, 14 Aug 2020 05:36:55 +0200 Subject: [PATCH 33/94] Allow using the compiler as an ESM module (#4972) --- rollup.config.js | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/rollup.config.js b/rollup.config.js index 6f3d893a33..82a2b9ae34 100644 --- a/rollup.config.js +++ b/rollup.config.js @@ -99,12 +99,20 @@ export default [ json(), ts_plugin ], - output: { - file: 'compiler.js', - format: is_publish ? 'umd' : 'cjs', - name: 'svelte', - sourcemap: true, - }, + output: [ + { + file: 'compiler.js', + format: is_publish ? 'umd' : 'cjs', + name: 'svelte', + sourcemap: true, + }, + { + file: 'compiler.mjs', + format: 'esm', + name: 'svelte', + sourcemap: true, + } + ], external: is_publish ? [] : id => id === 'acorn' || id === 'magic-string' || id.startsWith('css-tree') From e0e434234db527dbce14ef4180f284dd779b6194 Mon Sep 17 00:00:00 2001 From: Irshad PI Date: Mon, 17 Aug 2020 19:22:29 +0530 Subject: [PATCH 34/94] Await: re-throw error when there is no catch block and promise is rejected (#5149) --- .../compile/render_dom/wrappers/AwaitBlock.ts | 1 + src/runtime/internal/await_block.ts | 3 ++ .../samples/await-without-catch/_config.js | 44 +++++++++++++++++++ .../samples/await-without-catch/main.svelte | 9 ++++ 4 files changed, 57 insertions(+) create mode 100644 test/runtime/samples/await-without-catch/_config.js create mode 100644 test/runtime/samples/await-without-catch/main.svelte diff --git a/src/compiler/compile/render_dom/wrappers/AwaitBlock.ts b/src/compiler/compile/render_dom/wrappers/AwaitBlock.ts index 495f1b3157..e890715692 100644 --- a/src/compiler/compile/render_dom/wrappers/AwaitBlock.ts +++ b/src/compiler/compile/render_dom/wrappers/AwaitBlock.ts @@ -188,6 +188,7 @@ export default class AwaitBlockWrapper extends Wrapper { ctx: #ctx, current: null, token: null, + hasCatch: ${this.catch.node.start !== null ? 'true' : 'false'}, pending: ${this.pending.block.name}, then: ${this.then.block.name}, catch: ${this.catch.block.name}, diff --git a/src/runtime/internal/await_block.ts b/src/runtime/internal/await_block.ts index f70cbd6c2c..3821520837 100644 --- a/src/runtime/internal/await_block.ts +++ b/src/runtime/internal/await_block.ts @@ -59,6 +59,9 @@ export function handle_promise(promise, info) { update(info.then, 1, info.value, value); set_current_component(null); }, error => { + if (!info.hasCatch) { + throw error; + } set_current_component(current_component); update(info.catch, 2, info.error, error); set_current_component(null); diff --git a/test/runtime/samples/await-without-catch/_config.js b/test/runtime/samples/await-without-catch/_config.js new file mode 100644 index 0000000000..2030ed7949 --- /dev/null +++ b/test/runtime/samples/await-without-catch/_config.js @@ -0,0 +1,44 @@ +let fulfil; + +let promise = new Promise(f => { + fulfil = f; +}); + +export default { + props: { + promise + }, + + html: ` +

loading...

+ `, + + test({ assert, component, target }) { + fulfil(42); + + return promise + .then(() => { + assert.htmlEqual(target.innerHTML, ` +

loaded

+ `); + + let reject; + + promise = new Promise((f, r) => { + reject = r; + }); + + component.promise = promise; + + assert.htmlEqual(target.innerHTML, ` +

loading...

+ `); + + reject(new Error('this error should be thrown')); + return promise; + }) + .catch((err) => { + assert.equal(err.message, 'this error should be thrown'); + }); + } +}; \ No newline at end of file diff --git a/test/runtime/samples/await-without-catch/main.svelte b/test/runtime/samples/await-without-catch/main.svelte new file mode 100644 index 0000000000..f528a8bf69 --- /dev/null +++ b/test/runtime/samples/await-without-catch/main.svelte @@ -0,0 +1,9 @@ + + +{#await promise} +

loading...

+{:then value} +

loaded

+{/await} \ No newline at end of file From 1d9e2a13f20e02b3c119d11627fe7b1d811b0167 Mon Sep 17 00:00:00 2001 From: Conduitry Date: Mon, 17 Aug 2020 09:53:37 -0400 Subject: [PATCH 35/94] update changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index ceff78b107..e5e886646c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ ## Unreleased * Expose object of which slots have received content in `$$slots` ([#2106](https://github.com/sveltejs/svelte/issues/2106)) +* Re-throw an unhandled rejection when an `{#await}` block with no `{:catch}` gets a rejection ([#5129](https://github.com/sveltejs/svelte/issues/5129)) * Add types to `createEventDispatcher` ([#5211](https://github.com/sveltejs/svelte/issues/5211)) * In SSR mode, do not automatically declare variables for reactive assignments to member expressions ([#5247](https://github.com/sveltejs/svelte/issues/5247)) * Include selector in message of `unused-css-selector` warning ([#5252](https://github.com/sveltejs/svelte/issues/5252)) From 82dc26a31c37906153e07686b73d3af08dd50154 Mon Sep 17 00:00:00 2001 From: Antony Jones Date: Thu, 20 Aug 2020 16:51:28 +0100 Subject: [PATCH 36/94] Fix lint warnings (#5263) --- package-lock.json | 4 +- package.json | 2 +- src/compiler/compile/Component.ts | 78 +++++++++---------- src/compiler/compile/index.ts | 4 +- src/compiler/compile/nodes/Binding.ts | 2 +- src/compiler/compile/nodes/Element.ts | 4 +- src/compiler/compile/nodes/Text.ts | 2 +- src/compiler/compile/render_dom/Block.ts | 2 +- src/compiler/compile/render_dom/Renderer.ts | 2 +- .../render_dom/wrappers/Element/Attribute.ts | 10 +-- .../render_dom/wrappers/Element/Binding.ts | 4 +- .../render_dom/wrappers/Element/index.ts | 2 +- .../compile/render_dom/wrappers/IfBlock.ts | 2 +- .../wrappers/InlineComponent/index.ts | 2 +- .../compile/render_dom/wrappers/Window.ts | 4 +- .../wrappers/shared/get_slot_definition.ts | 4 +- .../utils/string_to_member_expression.ts | 4 +- src/compiler/compile/utils/stringify.ts | 2 +- src/compiler/parse/index.ts | 2 +- src/compiler/parse/read/script.ts | 2 +- src/compiler/parse/read/style.ts | 2 +- src/compiler/parse/state/mustache.ts | 16 ++-- src/compiler/parse/state/tag.ts | 20 ++--- src/compiler/parse/state/text.ts | 2 +- src/compiler/parse/utils/entities.ts | 2 +- src/compiler/parse/utils/html.ts | 6 +- src/compiler/preprocess/index.ts | 2 +- src/compiler/utils/fuzzymatch.ts | 4 +- src/compiler/utils/names.ts | 2 +- src/compiler/utils/namespaces.ts | 2 +- src/runtime/store/index.ts | 4 +- .../unused-selector-string-concat/_config.js | 24 +++--- .../unused-selector-ternary-bailed/_config.js | 2 +- .../unused-selector-ternary-concat/_config.js | 10 +-- .../unused-selector-ternary-nested/_config.js | 8 +- test/helpers.js | 1 + .../samples/dynamic-text-nil/_config.js | 4 +- test/hydration/samples/element-ref/_config.js | 2 +- test/js/samples/loop-protect/_config.js | 4 +- test/preprocess/samples/comments/_config.js | 6 +- .../samples/$$rest-without-props/_config.js | 2 +- test/runtime/samples/$$rest/_config.js | 2 +- .../_config.js | 2 +- .../action-ternary-template/_config.js | 4 +- test/runtime/samples/action-this/_config.js | 2 +- .../apply-directives-in-order-2/_config.js | 6 +- .../apply-directives-in-order/_config.js | 2 +- .../attribute-boolean-false/_config.js | 2 +- .../samples/attribute-boolean-true/_config.js | 2 +- .../_config.js | 2 +- .../_config.js | 2 +- .../samples/attribute-false/_config.js | 2 +- .../_config.js | 2 +- .../_config.js | 2 +- .../_config.js | 2 +- .../_config.js | 2 +- .../runtime/samples/attribute-null/_config.js | 2 +- .../attribute-prefer-expression/_config.js | 4 +- .../samples/attribute-undefined/_config.js | 2 +- .../samples/await-with-update-2/_config.js | 4 +- .../samples/await-with-update/_config.js | 4 +- .../_config.js | 2 +- .../binding-contenteditable-html/_config.js | 4 +- .../_config.js | 2 +- .../binding-contenteditable-text/_config.js | 4 +- .../_config.js | 4 +- .../_config.js | 10 +-- .../_config.js | 2 +- .../binding-input-group-each-1/_config.js | 4 +- .../binding-input-group-each-3/_config.js | 4 +- .../samples/binding-input-number-2/_config.js | 2 +- .../samples/binding-input-number/_config.js | 4 +- .../_config.js | 2 +- .../binding-input-range-change/_config.js | 4 +- .../samples/binding-input-range/_config.js | 4 +- .../_config.js | 4 +- .../_config.js | 2 +- .../binding-input-text-contextual/_config.js | 4 +- .../_config.js | 6 +- .../_config.js | 6 +- .../_config.js | 6 +- .../_config.js | 8 +- .../_config.js | 6 +- .../binding-input-text-deep/_config.js | 6 +- .../binding-input-text-undefined/_config.js | 2 +- .../samples/binding-input-text/_config.js | 4 +- .../binding-select-initial-value/_config.js | 4 +- .../binding-select-optgroup/_config.js | 2 +- .../runtime/samples/binding-select/_config.js | 4 +- .../samples/binding-store-deep/_config.js | 2 +- test/runtime/samples/binding-store/_config.js | 2 +- .../samples/binding-textarea/_config.js | 4 +- .../_config.js | 4 +- .../samples/bitmask-overflow-2/_config.js | 2 +- .../samples/bitmask-overflow-3/_config.js | 2 +- .../bitmask-overflow-slot-2/_config.js | 2 +- .../class-with-spread-and-bind/_config.js | 4 +- .../samples/component-binding-deep/_config.js | 2 +- .../component-binding-store/_config.js | 2 +- .../component-event-not-stale/_config.js | 4 +- .../component-events-console/_config.js | 2 +- .../component-shorthand-import/_config.js | 2 +- .../component-slot-fallback-3/_config.js | 2 +- .../component-slot-fallback-4/_config.js | 2 +- .../component-slot-let-in-slot/_config.js | 2 +- .../component-slot-nested-if/_config.js | 2 +- .../samples/deconflict-builtins-2/_config.js | 2 +- .../dev-warning-missing-data-each/_config.js | 12 +-- .../runtime/samples/document-event/_config.js | 2 +- .../each-block-array-literal/_config.js | 2 +- .../_config.js | 2 +- .../each-block-destructured-array/_config.js | 2 +- .../_config.js | 2 +- .../_config.js | 4 +- .../_config.js | 2 +- .../each-block-destructured-object/_config.js | 2 +- .../each-block-else-mount-or-intro/_config.js | 2 +- .../samples/each-block-in-if-block/_config.js | 2 +- .../_config.js | 2 +- .../samples/each-block-keyed-empty/_config.js | 2 +- .../each-block-keyed-non-prop/_config.js | 2 +- .../_config.js | 2 +- .../samples/each-block-keyed-shift/_config.js | 2 +- .../each-block-keyed-siblings/_config.js | 4 +- .../each-block-keyed-static/_config.js | 2 +- .../each-block-scope-shadow-bind-2/_config.js | 2 +- .../each-block-scope-shadow-bind-3/_config.js | 2 +- .../each-block-scope-shadow-bind-4/_config.js | 2 +- .../each-block-scope-shadow-bind/_config.js | 2 +- .../each-block-scope-shadow-self/_config.js | 2 +- .../each-blocks-assignment-2/_config.js | 2 +- .../samples/each-blocks-assignment/_config.js | 2 +- test/runtime/samples/empty-dom/_config.js | 2 +- .../samples/empty-style-block/_config.js | 2 +- .../escape-template-literals/_config.js | 2 +- .../samples/event-handler-async/_config.js | 2 +- .../event-handler-dynamic-2/_config.js | 2 +- .../_config.js | 2 +- .../_config.js | 2 +- .../event-handler-dynamic-hash/_config.js | 2 +- .../event-handler-dynamic-invalid/_config.js | 2 +- .../_config.js | 2 +- .../samples/event-handler-dynamic/_config.js | 2 +- .../event-handler-each-this/_config.js | 2 +- .../event-handler-modifier-self/_config.js | 2 +- .../_config.js | 12 +-- .../_config.js | 2 +- .../_config.js | 2 +- .../_config.js | 4 +- .../samples/if-block-else-in-each/_config.js | 4 +- .../if-block-else-partial-outro/_config.js | 4 +- .../_config.js | 2 +- .../_config.js | 2 +- .../samples/initial-state-assign/_config.js | 2 +- .../_config.js | 6 +- .../loop-protect-generator-opt-out/_config.js | 4 +- .../loop-protect-inner-function/_config.js | 2 +- test/runtime/samples/loop-protect/_config.js | 2 +- .../nested-transition-detach-each/_config.js | 2 +- .../_config.js | 2 +- .../_config.js | 2 +- .../samples/noscript-removal/_config.js | 2 +- .../paren-wrapped-expressions/_config.js | 2 +- test/runtime/samples/prop-exports/_config.js | 2 +- .../_config.js | 4 +- .../samples/props-reactive-slot/_config.js | 2 +- .../samples/raw-mustache-as-root/_config.js | 2 +- .../raw-mustache-inside-head/_config.js | 2 +- .../raw-mustache-inside-slot/_config.js | 2 +- .../samples/raw-mustaches-td-tr/_config.js | 4 +- .../_config.js | 2 +- .../reactive-import-statement/_config.js | 2 +- .../reactive-value-assign-property/_config.js | 2 +- .../self-reference-component/_config.js | 2 +- .../samples/set-undefined-attr/_config.js | 2 +- .../samples/sigil-component-prop/_config.js | 2 +- .../slot-if-block-update-no-anchor/_config.js | 2 +- .../samples/spread-component-2/_config.js | 2 +- .../_config.js | 2 +- .../_config.js | 2 +- .../_config.js | 8 +- .../spread-component-dynamic/_config.js | 8 +- .../_config.js | 2 +- .../samples/spread-each-component/_config.js | 2 +- .../samples/spread-each-element/_config.js | 2 +- .../samples/spread-element-boolean/_config.js | 2 +- .../spread-element-input-value/_config.js | 6 +- .../_config.js | 2 +- .../spread-element-multiple/_config.js | 8 +- .../_config.js | 2 +- .../samples/store-resubscribe-b/_config.js | 2 +- .../store-resubscribe-export/_config.js | 8 +- .../store-resubscribe-observable/_config.js | 2 +- .../svg-tspan-preserve-space/_config.js | 2 +- .../this-in-function-expressions/_config.js | 2 +- .../_config.js | 2 +- .../transition-css-duration/_config.js | 2 +- .../samples/transition-css-iframe/_config.js | 2 +- .../transition-css-in-out-in/_config.js | 2 +- .../_config.js | 2 +- .../transition-js-aborted-outro/_config.js | 4 +- .../transition-js-deferred-b/_config.js | 2 +- .../samples/transition-js-deferred/_config.js | 2 +- .../_config.js | 2 +- .../_config.js | 2 +- .../_config.js | 2 +- .../_config.js | 2 +- .../_config.js | 2 +- .../_config.js | 2 +- .../_config.js | 2 +- .../transition-js-local-and-global/_config.js | 2 +- .../_config.js | 2 +- .../_config.js | 2 +- .../transition-js-local-nested-if/_config.js | 2 +- .../samples/transition-js-local/_config.js | 2 +- .../_config.js | 2 +- .../_config.js | 2 +- .../transition-js-nested-each/_config.js | 2 +- .../transition-js-nested-if/_config.js | 2 +- .../_config.js | 2 +- .../transition-js-parameterised/_config.js | 2 +- .../unchanged-expression-escape/_config.js | 2 +- .../unchanged-expression-xss/_config.js | 2 +- .../samples/whitespace-list/_config.js | 2 +- .../window-bind-scroll-update/_config.js | 2 +- .../window-binding-scroll-store/_config.js | 10 +-- .../samples/window-event-custom/_config.js | 2 +- test/vars/samples/assumed-global/_config.js | 2 +- .../vars/samples/duplicate-globals/_config.js | 2 +- .../duplicate-non-hoistable/_config.js | 2 +- test/vars/samples/duplicate-vars/_config.js | 2 +- .../vars/samples/implicit-reactive/_config.js | 2 +- .../samples/referenced-from-script/_config.js | 32 ++++---- .../samples/template-references/_config.js | 10 +-- test/vars/samples/undeclared/_config.js | 2 +- 235 files changed, 424 insertions(+), 423 deletions(-) diff --git a/package-lock.json b/package-lock.json index 0110595c76..4e9e06824a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -144,8 +144,8 @@ } }, "@sveltejs/eslint-config": { - "version": "github:sveltejs/eslint-config#e8a9b27cd3f7aa66388474412b1a5c11c5a44ade", - "from": "github:sveltejs/eslint-config#v0.0.1", + "version": "github:sveltejs/eslint-config#848ce6464a9ae9c2f3a3095474701dfe9ab851df", + "from": "github:sveltejs/eslint-config#v5.0.0", "dev": true }, "@tootallnate/once": { diff --git a/package.json b/package.json index e0de8670ef..36453769e6 100644 --- a/package.json +++ b/package.json @@ -63,7 +63,7 @@ "@rollup/plugin-sucrase": "^3.0.0", "@rollup/plugin-typescript": "^2.0.1", "@rollup/plugin-virtual": "^2.0.0", - "@sveltejs/eslint-config": "github:sveltejs/eslint-config#v0.0.1", + "@sveltejs/eslint-config": "github:sveltejs/eslint-config#v5.0.0", "@types/mocha": "^5.2.7", "@types/node": "^8.10.53", "@typescript-eslint/eslint-plugin": "^3.0.2", diff --git a/src/compiler/compile/Component.ts b/src/compiler/compile/Component.ts index 88fe197993..ed2b10e404 100644 --- a/src/compiler/compile/Component.ts +++ b/src/compiler/compile/Component.ts @@ -8,7 +8,7 @@ import { create_scopes, extract_names, Scope, - extract_identifiers, + extract_identifiers } from './utils/scope'; import Stylesheet from './css/Stylesheet'; import { test } from '../config'; @@ -155,7 +155,7 @@ export default class Component { ) || { start: 0, end: 0 }; this.warn(svelteOptions, { code: 'custom-element-no-tag', - message: `No custom element 'tag' option was specified. To automatically register a custom element, specify a name with a hyphen in it, e.g. . To hide this warning, use `, + 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; @@ -190,7 +190,7 @@ export default class Component { this.add_var({ name, injected: true, - referenced: true, + referenced: true }); } else if (name[0] === '$') { this.add_var({ @@ -198,7 +198,7 @@ export default class Component { injected: true, referenced: true, mutated: true, - writable: true, + writable: true }); const subscribable_name = name.slice(1); @@ -289,7 +289,7 @@ export default class Component { } const imported_helpers = Array.from(this.helpers, ([name, alias]) => ({ name, - alias, + alias })); create_module( @@ -305,7 +305,7 @@ export default class Component { .filter(variable => variable.module && variable.export_name) .map(variable => ({ name: variable.name, - as: variable.export_name, + as: variable.export_name })) ); @@ -342,9 +342,9 @@ export default class Component { reassigned: v.reassigned || false, referenced: v.referenced || false, writable: v.writable || false, - referenced_from_script: v.referenced_from_script || false, + referenced_from_script: v.referenced_from_script || false })), - stats: this.stats.render(), + stats: this.stats.render() }; } @@ -409,7 +409,7 @@ export default class Component { source: this.source, start: pos.start, end: pos.end, - filename: this.compile_options.filename, + filename: this.compile_options.filename }); } @@ -441,7 +441,7 @@ export default class Component { pos: pos.start, filename: this.compile_options.filename, toString: () => - `${warning.message} (${start.line}:${start.column})\n${frame}`, + `${warning.message} (${start.line}:${start.column})\n${frame}` }); } @@ -453,7 +453,7 @@ export default class Component { if (node.type === 'ExportDefaultDeclaration') { this.error(node, { code: `default-export`, - message: `A component cannot have a default export`, + message: `A component cannot have a default export` }); } @@ -461,7 +461,7 @@ export default class Component { if (node.source) { this.error(node, { code: `not-implemented`, - message: `A component currently cannot have an export ... from`, + message: `A component currently cannot have an export ... from` }); } if (node.declaration) { @@ -531,10 +531,10 @@ export default class Component { if (node.type === 'LabeledStatement' && node.label.name === '$') { component.warn(node as any, { code: 'module-script-reactive-declaration', - message: '$: has no effect in a module script', + message: '$: has no effect in a module script' }); } - }, + } }); const { scope, globals } = create_scopes(script.content); @@ -544,7 +544,7 @@ export default class Component { if (name[0] === '$') { this.error(node as any, { code: 'illegal-declaration', - message: `The $ prefix is reserved, and cannot be used for variable and import names`, + message: `The $ prefix is reserved, and cannot be used for variable and import names` }); } @@ -562,7 +562,7 @@ export default class Component { if (name[0] === '$') { this.error(node as any, { code: 'illegal-subscription', - message: `Cannot reference store value inside + + \ No newline at end of file From 8148a7a33444805320923e4c4e071f62dee3df6c Mon Sep 17 00:00:00 2001 From: Tan Li Hau Date: Fri, 28 Aug 2020 07:25:33 +0800 Subject: [PATCH 40/94] each binding with store props (#5289) --- CHANGELOG.md | 1 + src/compiler/compile/render_dom/Block.ts | 27 ++++++++----------- .../compile/render_dom/wrappers/EachBlock.ts | 8 +++--- .../store-each-binding-deep/_config.js | 14 ++++++++++ .../store-each-binding-deep/main.svelte | 11 ++++++++ 5 files changed, 40 insertions(+), 21 deletions(-) create mode 100644 test/runtime/samples/store-each-binding-deep/_config.js create mode 100644 test/runtime/samples/store-each-binding-deep/main.svelte diff --git a/CHANGELOG.md b/CHANGELOG.md index 5c4ca12b51..0ccfeff273 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,7 @@ * Fix using ``s in child `{#await}`/`{#each}` contexts ([#5255](https://github.com/sveltejs/svelte/issues/5255)) * Fix using `` in `{:catch}` ([#5259](https://github.com/sveltejs/svelte/issues/5259)) * Fix setting one-way bound `` `value` to `undefined` when it has spread attributes ([#5270](https://github.com/sveltejs/svelte/issues/5270)) +* Fix deep two-way bindings inside an `{#each}` involving a store ([#5286](https://github.com/sveltejs/svelte/issues/5286)) ## 3.24.1 diff --git a/src/compiler/compile/render_dom/Block.ts b/src/compiler/compile/render_dom/Block.ts index 3f10114f45..1562635d07 100644 --- a/src/compiler/compile/render_dom/Block.ts +++ b/src/compiler/compile/render_dom/Block.ts @@ -4,6 +4,15 @@ import { b, x } from 'code-red'; import { Node, Identifier, ArrayPattern } from 'estree'; import { is_head } from './wrappers/shared/is_head'; +export interface Bindings { + object: Identifier; + property: Identifier; + snippet: Node; + store: string; + tail: Node; + modifier: (node: Node) => Node; +} + export interface BlockOptions { parent?: Block; name: Identifier; @@ -11,14 +20,7 @@ export interface BlockOptions { renderer?: Renderer; comment?: string; key?: Identifier; - bindings?: Map Node; - }>; + bindings?: Map; dependencies?: Set; } @@ -36,14 +38,7 @@ export default class Block { dependencies: Set = new Set(); - bindings: Map Node; - }>; + bindings: Map; chunks: { declarations: Array; diff --git a/src/compiler/compile/render_dom/wrappers/EachBlock.ts b/src/compiler/compile/render_dom/wrappers/EachBlock.ts index 126b114487..2513ea1adc 100644 --- a/src/compiler/compile/render_dom/wrappers/EachBlock.ts +++ b/src/compiler/compile/render_dom/wrappers/EachBlock.ts @@ -7,6 +7,7 @@ import FragmentWrapper from './Fragment'; import { b, x } from 'code-red'; import ElseBlock from '../../nodes/ElseBlock'; import { Identifier, Node } from 'estree'; +import get_object from '../../utils/get_object'; export class ElseBlockWrapper extends Wrapper { node: ElseBlock; @@ -139,11 +140,8 @@ export default class EachBlockWrapper extends Wrapper { view_length: fixed_length === null ? x`${iterations}.length` : fixed_length }; - const store = - node.expression.node.type === 'Identifier' && - node.expression.node.name[0] === '$' - ? node.expression.node.name.slice(1) - : null; + const object = get_object(node.expression.node); + const store = object.type === 'Identifier' && object.name[0] === '$' ? object.name.slice(1) : null; node.contexts.forEach(prop => { this.block.bindings.set(prop.key.name, { diff --git a/test/runtime/samples/store-each-binding-deep/_config.js b/test/runtime/samples/store-each-binding-deep/_config.js new file mode 100644 index 0000000000..70776940dd --- /dev/null +++ b/test/runtime/samples/store-each-binding-deep/_config.js @@ -0,0 +1,14 @@ +export default { + async test({ assert, target, window }) { + const input = target.querySelector('input'); + + const event = new window.Event('input'); + input.value = 'changed'; + await input.dispatchEvent(event); + + assert.htmlEqual(target.innerHTML, ` + +

changed

+ `); + } +}; \ No newline at end of file diff --git a/test/runtime/samples/store-each-binding-deep/main.svelte b/test/runtime/samples/store-each-binding-deep/main.svelte new file mode 100644 index 0000000000..8f1cabf5b8 --- /dev/null +++ b/test/runtime/samples/store-each-binding-deep/main.svelte @@ -0,0 +1,11 @@ + + +{#each $itemStore.prop.things as thing } + +{/each} + +

{$itemStore.prop.things[0].name}

\ No newline at end of file From 84ac3a53d53a84194cd9f121a27809a60764d6fc Mon Sep 17 00:00:00 2001 From: Ben McCann <322311+benmccann@users.noreply.github.com> Date: Sun, 30 Aug 2020 17:08:24 -0700 Subject: [PATCH 41/94] fix(types): specify `CompleOptions.generate` values (#5321) --- src/compiler/interfaces.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/compiler/interfaces.ts b/src/compiler/interfaces.ts index a5e286462f..6e96e340ad 100644 --- a/src/compiler/interfaces.ts +++ b/src/compiler/interfaces.ts @@ -108,7 +108,7 @@ export interface CompileOptions { format?: ModuleFormat; name?: string; filename?: string; - generate?: string | false; + generate?: 'dom' | 'ssr' | false; outputFilename?: string; cssOutputFilename?: string; @@ -166,4 +166,4 @@ export interface Var { export interface CssResult { code: string; map: SourceMap; -} \ No newline at end of file +} From e0f937d33e754dbd0f186541961a17b051fecdab Mon Sep 17 00:00:00 2001 From: Ben McCann <322311+benmccann@users.noreply.github.com> Date: Tue, 1 Sep 2020 11:02:03 -0700 Subject: [PATCH 42/94] Add a script for copy-workers (#5338) --- site/package.json | 2 +- site/scripts/copy-workers.js | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) create mode 100644 site/scripts/copy-workers.js diff --git a/site/package.json b/site/package.json index c416fe5bf1..1aaef9b096 100644 --- a/site/package.json +++ b/site/package.json @@ -4,7 +4,7 @@ "description": "Docs and examples for Svelte", "scripts": { "dev": "npm run copy-workers && sapper dev", - "copy-workers": "rm -rf static/workers && cp -r node_modules/@sveltejs/svelte-repl/workers static", + "copy-workers": "node scripts/copy-workers.js", "migrate": "node-pg-migrate -r dotenv/config", "sapper": "npm run copy-workers && sapper build --legacy", "update": "node scripts/update_template.js && node scripts/get-contributors.js && node scripts/update_whos_using.js", diff --git a/site/scripts/copy-workers.js b/site/scripts/copy-workers.js new file mode 100644 index 0000000000..4856764ad0 --- /dev/null +++ b/site/scripts/copy-workers.js @@ -0,0 +1,4 @@ +const sh = require('shelljs'); + +sh.rm('-rf', 'static/workers'); +sh.cp('-r', 'node_modules/@sveltejs/svelte-repl/workers', 'static'); From 9a5733a26b2ad001ef20c90f5e8f1afd12f246e5 Mon Sep 17 00:00:00 2001 From: Ben McCann <322311+benmccann@users.noreply.github.com> Date: Tue, 1 Sep 2020 16:05:54 -0700 Subject: [PATCH 43/94] Add opencollective link to readme (#5341) --- README.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/README.md b/README.md index 33faec0588..3c174d03d9 100644 --- a/README.md +++ b/README.md @@ -20,6 +20,15 @@ Svelte is a new way to build web applications. It's a compiler that takes your d Learn more at the [Svelte website](https://svelte.dev), or stop by the [Discord chatroom](https://svelte.dev/chat). +## Supporting Svelte + +Svelte is an MIT-licensed open source project with its ongoing development made possible entirely by the support of awesome volunteers. If you'd like to support their efforts, please consider: + +- [Becoming a backer on Open Collective](https://opencollective.com/svelte). + +Funds donated via Open Collective will be used for compensating expenses related to Svelte's development such as hosting costs. If sufficient donations are received, funds may also be used to support Svelte's development more directly. + + ## Development Pull requests are encouraged and always welcome. [Pick an issue](https://github.com/sveltejs/svelte/issues?q=is%3Aissue+is%3Aopen+sort%3Aupdated-desc) and help us out! From f1838ed8aaadc24c61ac70a8170c2fbb37277658 Mon Sep 17 00:00:00 2001 From: Conduitry Date: Fri, 4 Sep 2020 07:55:28 -0400 Subject: [PATCH 44/94] site: bump svelte-repl --- site/package-lock.json | 12 ++++++------ site/package.json | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/site/package-lock.json b/site/package-lock.json index 00da27f0c7..aa08b6dd90 100644 --- a/site/package-lock.json +++ b/site/package-lock.json @@ -1291,9 +1291,9 @@ } }, "@sveltejs/svelte-repl": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/@sveltejs/svelte-repl/-/svelte-repl-0.2.0.tgz", - "integrity": "sha512-2vLQnOVrsmn2d2K4a6urGm8OulGGSPhZCGNySSb1H8nOPsgKrdcTt5qoaxNYXgcyVp55Yow2SvXYXsyJKd4KEQ==", + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/@sveltejs/svelte-repl/-/svelte-repl-0.2.1.tgz", + "integrity": "sha512-ShNjMdsEAzGLu2PoogJEuWcV47E+1CsO8dNJ2wZcs7xyPsvuswp6KV1jFsBQmWZ+jLqtnRhlo6w2Mf43XOS/Dg==", "dev": true, "requires": { "codemirror": "^5.49.2", @@ -1601,9 +1601,9 @@ "dev": true }, "codemirror": { - "version": "5.55.0", - "resolved": "https://registry.npmjs.org/codemirror/-/codemirror-5.55.0.tgz", - "integrity": "sha512-TumikSANlwiGkdF/Blnu/rqovZ0Y3Jh8yy9TqrPbSM0xxSucq3RgnpVDQ+mD9q6JERJEIT2FMuF/fBGfkhIR/g==", + "version": "5.57.0", + "resolved": "https://registry.npmjs.org/codemirror/-/codemirror-5.57.0.tgz", + "integrity": "sha512-WGc6UL7Hqt+8a6ZAsj/f1ApQl3NPvHY/UQSzG6fB6l4BjExgVdhFaxd7mRTw1UCiYe/6q86zHP+kfvBQcZGvUg==", "dev": true }, "color-convert": { diff --git a/site/package.json b/site/package.json index 1aaef9b096..c6c6790dd1 100644 --- a/site/package.json +++ b/site/package.json @@ -37,7 +37,7 @@ "@babel/runtime": "^7.6.0", "@sindresorhus/slugify": "^0.9.1", "@sveltejs/site-kit": "^1.2.4", - "@sveltejs/svelte-repl": "^0.2.0", + "@sveltejs/svelte-repl": "^0.2.1", "degit": "^2.1.4", "dotenv": "^8.1.0", "esm": "^3.2.25", From 9db8773070ecbcc254a960083b16723e0713db18 Mon Sep 17 00:00:00 2001 From: Ben McCann <322311+benmccann@users.noreply.github.com> Date: Fri, 4 Sep 2020 12:50:27 -0700 Subject: [PATCH 45/94] Update site dependencies (#5354) --- site/package-lock.json | 566 ++++++++++++++++++++++++----------------- site/package.json | 22 +- site/rollup.config.js | 12 +- 3 files changed, 343 insertions(+), 257 deletions(-) diff --git a/site/package-lock.json b/site/package-lock.json index aa08b6dd90..f05f5de4c0 100644 --- a/site/package-lock.json +++ b/site/package-lock.json @@ -315,6 +315,12 @@ "@babel/types": "^7.4.4" } }, + "@babel/helper-validator-identifier": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.10.4.tgz", + "integrity": "sha512-3U9y+43hz7ZM+rzG24Qe2mufW5KhvFg/NhnNph+i9mgCtdTCtMJuI1TMkrIUiK7Ix4PYlRF9I5dhqaLYA/ADXw==", + "dev": true + }, "@babel/helper-wrap-function": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.2.0.tgz", @@ -1270,6 +1276,168 @@ "resolved": "https://registry.npmjs.org/@polka/url/-/url-1.0.0-next.9.tgz", "integrity": "sha512-VZqSaulg2kVQYMulmuZcvapPwH5/y81YHANiFIKz1GNZoG/F4o1JSeLlrvXJ8tC+RPUjxdrebfT3Qn+bnMi0bA==" }, + "@rollup/plugin-babel": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/@rollup/plugin-babel/-/plugin-babel-5.2.0.tgz", + "integrity": "sha512-CPABsajaKjINgBQ3it+yMnfVO3ibsrMBxRzbUOUw2cL1hsZJ7aogU8mgglQm3S2hHJgjnAmxPz0Rq7DVdmHsTw==", + "dev": true, + "requires": { + "@babel/helper-module-imports": "^7.10.4", + "@rollup/pluginutils": "^3.1.0" + }, + "dependencies": { + "@babel/helper-module-imports": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.10.4.tgz", + "integrity": "sha512-nEQJHqYavI217oD9+s5MUBzk6x1IlvoS9WTPfgG43CbMEeStE0v+r+TucWdx8KFGowPGvyOkDT9+7DHedIDnVw==", + "dev": true, + "requires": { + "@babel/types": "^7.10.4" + } + }, + "@babel/types": { + "version": "7.11.5", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.11.5.tgz", + "integrity": "sha512-bvM7Qz6eKnJVFIn+1LPtjlBFPVN5jNDc1XmN15vWe7Q3DPBufWWsLiIvUu7xW87uTG6QoggpIDnUgLQvPheU+Q==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.10.4", + "lodash": "^4.17.19", + "to-fast-properties": "^2.0.0" + } + } + } + }, + "@rollup/plugin-commonjs": { + "version": "15.0.0", + "resolved": "https://registry.npmjs.org/@rollup/plugin-commonjs/-/plugin-commonjs-15.0.0.tgz", + "integrity": "sha512-8uAdikHqVyrT32w1zB9VhW6uGwGjhKgnDNP4pQJsjdnyF4FgCj6/bmv24c7v2CuKhq32CcyCwRzMPEElaKkn0w==", + "dev": true, + "requires": { + "@rollup/pluginutils": "^3.1.0", + "commondir": "^1.0.1", + "estree-walker": "^2.0.1", + "glob": "^7.1.6", + "is-reference": "^1.2.1", + "magic-string": "^0.25.7", + "resolve": "^1.17.0" + }, + "dependencies": { + "estree-walker": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.1.tgz", + "integrity": "sha512-tF0hv+Yi2Ot1cwj9eYHtxC0jB9bmjacjQs6ZBTj82H8JwUywFuc+7E83NWfNMwHXZc11mjfFcVXPe9gEP4B8dg==", + "dev": true + }, + "glob": { + "version": "7.1.6", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", + "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "is-reference": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/is-reference/-/is-reference-1.2.1.tgz", + "integrity": "sha512-U82MsXXiFIrjCK4otLT+o2NA2Cd2g5MLoOVXUZjIOhLurrRxpEXzI8O0KZHr3IjLvlAH1kTPYSuqer5T9ZVBKQ==", + "dev": true, + "requires": { + "@types/estree": "*" + } + }, + "magic-string": { + "version": "0.25.7", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.25.7.tgz", + "integrity": "sha512-4CrMT5DOHTDk4HYDlzmwu4FVCcIYI8gauveasrdCu2IKIFOJ3f0v/8MDGJCDL9oD2ppz/Av1b0Nj345H9M+XIA==", + "dev": true, + "requires": { + "sourcemap-codec": "^1.4.4" + } + }, + "resolve": { + "version": "1.17.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz", + "integrity": "sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==", + "dev": true, + "requires": { + "path-parse": "^1.0.6" + } + } + } + }, + "@rollup/plugin-json": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/@rollup/plugin-json/-/plugin-json-4.1.0.tgz", + "integrity": "sha512-yfLbTdNS6amI/2OpmbiBoW12vngr5NW2jCJVZSBEz+H5KfUJZ2M7sDjk0U6GOOdCWFVScShte29o9NezJ53TPw==", + "dev": true, + "requires": { + "@rollup/pluginutils": "^3.0.8" + } + }, + "@rollup/plugin-node-resolve": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-9.0.0.tgz", + "integrity": "sha512-gPz+utFHLRrd41WMP13Jq5mqqzHL3OXrfj3/MkSyB6UBIcuNt9j60GCbarzMzdf1VHFpOxfQh/ez7wyadLMqkg==", + "dev": true, + "requires": { + "@rollup/pluginutils": "^3.1.0", + "@types/resolve": "1.17.1", + "builtin-modules": "^3.1.0", + "deepmerge": "^4.2.2", + "is-module": "^1.0.0", + "resolve": "^1.17.0" + }, + "dependencies": { + "resolve": { + "version": "1.17.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz", + "integrity": "sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==", + "dev": true, + "requires": { + "path-parse": "^1.0.6" + } + } + } + }, + "@rollup/plugin-replace": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/@rollup/plugin-replace/-/plugin-replace-2.3.3.tgz", + "integrity": "sha512-XPmVXZ7IlaoWaJLkSCDaa0Y6uVo5XQYHhiMFzOd5qSv5rE+t/UJToPIOE56flKIxBFQI27ONsxb7dqHnwSsjKQ==", + "dev": true, + "requires": { + "@rollup/pluginutils": "^3.0.8", + "magic-string": "^0.25.5" + }, + "dependencies": { + "magic-string": { + "version": "0.25.7", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.25.7.tgz", + "integrity": "sha512-4CrMT5DOHTDk4HYDlzmwu4FVCcIYI8gauveasrdCu2IKIFOJ3f0v/8MDGJCDL9oD2ppz/Av1b0Nj345H9M+XIA==", + "dev": true, + "requires": { + "sourcemap-codec": "^1.4.4" + } + } + } + }, + "@rollup/pluginutils": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-3.1.0.tgz", + "integrity": "sha512-GksZ6pr6TpIjHm8h9lSQ8pi8BE9VeubNT0OMJ3B5uZJ8pz73NPiqOtCog/x2/QzM1ENChPKxMDhiQuRHsqc+lg==", + "dev": true, + "requires": { + "@types/estree": "0.0.39", + "estree-walker": "^1.0.1", + "picomatch": "^2.2.2" + } + }, "@sindresorhus/slugify": { "version": "0.9.1", "resolved": "https://registry.npmjs.org/@sindresorhus/slugify/-/slugify-0.9.1.tgz", @@ -1356,20 +1524,14 @@ } }, "@types/resolve": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-0.0.8.tgz", - "integrity": "sha512-auApPaJf3NPfe18hSoJkp8EbZzer2ISk7o8mCC3M9he/a04+gbMF97NkpD2S8riMGvm4BMRI59/SZQSaLTKpsQ==", + "version": "1.17.1", + "resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-1.17.1.tgz", + "integrity": "sha512-yy7HuzQhj0dhGpD8RLXSZWEkLsV9ibvxvi6EiJ3bkqLAO1RGo0WbkWQiwpRlSFymTJRz0d3k5LM3kkx8ArDbLw==", "dev": true, "requires": { "@types/node": "*" } }, - "acorn": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.1.1.tgz", - "integrity": "sha512-add7dgA5ppRPxCFJoAGfMDi7PIBXq1RtGo7BhbLaxwrXPOmw8gq48Y9ozT01hUKy9byMjlR20EJhu5zlkErEkg==", - "dev": true - }, "ansi-colors": { "version": "3.2.3", "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-3.2.3.tgz", @@ -1556,9 +1718,9 @@ "dev": true }, "clean-css": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/clean-css/-/clean-css-4.2.1.tgz", - "integrity": "sha512-4ZxI6dy4lrY6FHzfiy1aEOXgu4LIsW2MhwG0VBKdcoGoH/XLFgaHSdLTGr4O8Be6A8r3MOphEiI8Gc1n0ecf3g==", + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/clean-css/-/clean-css-4.2.3.tgz", + "integrity": "sha512-VcMWDN54ZN/DS+g58HYL5/n4Zrqe8vHJpGA8KdgUXFU4fuP/aHNw8eld9SyEIyabIMJX/0RaY/fplOo5hYLSFA==", "dev": true, "requires": { "source-map": "~0.6.0" @@ -1622,9 +1784,15 @@ "dev": true }, "commander": { - "version": "2.20.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.0.tgz", - "integrity": "sha512-7j2y+40w61zy6YC2iRNpUe/NwhNyoXrYpHMrSunaMG64nRnaf96zO/KMQR4OyN/UnE5KLyEBnKHd4aG3rskjpQ==", + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", + "dev": true + }, + "commondir": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", + "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=", "dev": true }, "concat-map": { @@ -1693,12 +1861,6 @@ } } }, - "core-util-is": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", - "dev": true - }, "cross-spawn": { "version": "6.0.5", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", @@ -1727,6 +1889,12 @@ "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", "dev": true }, + "deepmerge": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.2.2.tgz", + "integrity": "sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==", + "dev": true + }, "define-properties": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", @@ -1865,9 +2033,9 @@ "dev": true }, "estree-walker": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-0.6.1.tgz", - "integrity": "sha512-SqmZANLWS0mnatqbSfRP5g8OXZC12Fgg1IwNtLsyHDzJizORW4khDfjPqJZsemPWBB2uqykUah5YpQ6epsqC/w==", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-1.0.1.tgz", + "integrity": "sha512-1fMXF3YP4pZZVozF8j/ZLfvnR8NSIljt56UhbZ5PeeDmmGHpgpdwQt7ITlGvYaQukCvuBRMLEiKiYC+oeIg4cg==", "dev": true }, "esutils": { @@ -1950,6 +2118,13 @@ "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", "dev": true }, + "fsevents": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.3.tgz", + "integrity": "sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ==", + "dev": true, + "optional": true + }, "function-bind": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", @@ -2178,15 +2353,6 @@ "integrity": "sha1-Mlj7afeMFNW4FdZkM2tM/7ZEFZE=", "dev": true }, - "is-reference": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/is-reference/-/is-reference-1.1.3.tgz", - "integrity": "sha512-W1iHHv/oyBb2pPxkBxtaewxa1BC58Pn5J0hogyCdefwUIvb6R+TGbAcIa4qPNYLqLhb3EnOgUf2MQkkF76BcKw==", - "dev": true, - "requires": { - "@types/estree": "0.0.39" - } - }, "is-regex": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.4.tgz", @@ -2211,12 +2377,6 @@ "has-symbols": "^1.0.0" } }, - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true - }, "isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", @@ -2224,22 +2384,29 @@ "dev": true }, "jest-worker": { - "version": "24.6.0", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-24.6.0.tgz", - "integrity": "sha512-jDwgW5W9qGNvpI1tNnvajh0a5IE/PuGLFmHk6aR/BZFz8tSgGw17GsDPXAJ6p91IvYDjOw8GpFbvvZGAK+DPQQ==", + "version": "26.3.0", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-26.3.0.tgz", + "integrity": "sha512-Vmpn2F6IASefL+DVBhPzI2J9/GJUsqzomdeN+P+dK8/jKxbh8R3BtFnx3FIta7wYlPU62cpJMJQo4kuOowcMnw==", "dev": true, "requires": { - "merge-stream": "^1.0.1", - "supports-color": "^6.1.0" + "@types/node": "*", + "merge-stream": "^2.0.0", + "supports-color": "^7.0.0" }, "dependencies": { + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, "supports-color": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", - "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "dev": true, "requires": { - "has-flag": "^3.0.0" + "has-flag": "^4.0.0" } } } @@ -2474,15 +2641,6 @@ "integrity": "sha1-miyr0bno4K6ZOkv31YdcOcQujqw=", "dev": true }, - "magic-string": { - "version": "0.25.2", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.25.2.tgz", - "integrity": "sha512-iLs9mPjh9IuTtRsqqhNGYcZXGei0Nh/A4xirrsqW7c+QhKVFL2vm7U09ru6cHRD22azaP/wMDgI+HCqbETMTtg==", - "dev": true, - "requires": { - "sourcemap-codec": "^1.4.4" - } - }, "map-age-cleaner": { "version": "0.1.3", "resolved": "https://registry.npmjs.org/map-age-cleaner/-/map-age-cleaner-0.1.3.tgz", @@ -2493,9 +2651,9 @@ } }, "marked": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/marked/-/marked-0.7.0.tgz", - "integrity": "sha512-c+yYdCZJQrsRjTPhUx7VKkApw9bwDkNbHUKo1ovgcfDjb2kc8rLuRbIFyXL5WOEUwzSSKo3IXpph2K6DqB/KZg==" + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/marked/-/marked-1.1.1.tgz", + "integrity": "sha512-mJzT8D2yPxoPh7h0UXkB+dBj4FykPJ2OIfxAWeIHrvoHDkFxukV/29QxoFQoPM6RLEwhIFdJpmKBlqVM3s2ZIw==" }, "mem": { "version": "4.3.0", @@ -2515,18 +2673,15 @@ "dev": true }, "merge-stream": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-1.0.1.tgz", - "integrity": "sha1-QEEgLVCKNCugAXQAjfDCUbjBNeE=", - "dev": true, - "requires": { - "readable-stream": "^2.0.1" - } + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", + "dev": true }, "mime": { - "version": "2.4.4", - "resolved": "https://registry.npmjs.org/mime/-/mime-2.4.4.tgz", - "integrity": "sha512-LRxmNwziLPT828z+4YkNzloCFC2YM4wrB99k+AV5ZbEyfGNWfG8SO1FUXLmLDBSo89NrJZ4DIWeLjy1CHGhMGA==" + "version": "2.4.6", + "resolved": "https://registry.npmjs.org/mime/-/mime-2.4.6.tgz", + "integrity": "sha512-RZKhC3EmpBchfTGBVb8fb+RL2cWyw/32lshnsETttkBAyAUXSGHxbEJWWRXc751DrIxG1q04b8QwMbAwkRPpUA==" }, "mimic-fn": { "version": "2.1.0", @@ -3105,6 +3260,12 @@ "integrity": "sha512-CzFr90qM24ju5f88quFC/6qohjC144rehe5n6DH900lgXmUe86+xCKc10ev56gRKC4/BkHUoG4uSiQgBiIXwDA==", "dev": true }, + "picomatch": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.2.tgz", + "integrity": "sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg==", + "dev": true + }, "pidtree": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/pidtree/-/pidtree-0.3.0.tgz", @@ -3189,12 +3350,6 @@ "integrity": "sha1-FjjYqONML0QKkduVq5rrZ3/Bhc8=", "dev": true }, - "process-nextick-args": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", - "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", - "dev": true - }, "pump": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", @@ -3205,6 +3360,15 @@ "once": "^1.3.1" } }, + "randombytes": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "dev": true, + "requires": { + "safe-buffer": "^5.1.0" + } + }, "read-pkg": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz", @@ -3216,21 +3380,6 @@ "path-type": "^3.0.0" } }, - "readable-stream": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", - "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, "rechoir": { "version": "0.6.2", "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz", @@ -3361,121 +3510,80 @@ } }, "rollup": { - "version": "1.21.2", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-1.21.2.tgz", - "integrity": "sha512-sCAHlcQ/PExU5t/kRwkEWHdhGmQrZ2IgdQzbjPVNfhWbKHMMZGYqkASVTpQqRPLtQKg15xzEscc+BnIK/TE7/Q==", + "version": "2.26.10", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.26.10.tgz", + "integrity": "sha512-dUnjCWOA0h9qNX6qtcHidyatz8FAFZxVxt1dbcGtKdlJkpSxGK3G9+DLCYvtZr9v94D129ij9zUhG+xbRoqepw==", "dev": true, "requires": { - "@types/estree": "0.0.39", - "@types/node": "^12.7.4", - "acorn": "^7.0.0" - }, - "dependencies": { - "@types/node": { - "version": "12.7.4", - "resolved": "https://registry.npmjs.org/@types/node/-/node-12.7.4.tgz", - "integrity": "sha512-W0+n1Y+gK/8G2P/piTkBBN38Qc5Q1ZSO6B5H3QmPCUewaiXOo2GCAWZ4ElZCcNhjJuBSUSLGFUJnmlCn5+nxOQ==", - "dev": true - } - } - }, - "rollup-plugin-babel": { - "version": "4.3.3", - "resolved": "https://registry.npmjs.org/rollup-plugin-babel/-/rollup-plugin-babel-4.3.3.tgz", - "integrity": "sha512-tKzWOCmIJD/6aKNz0H1GMM+lW1q9KyFubbWzGiOG540zxPPifnEAHTZwjo0g991Y+DyOZcLqBgqOdqazYE5fkw==", - "dev": true, - "requires": { - "@babel/helper-module-imports": "^7.0.0", - "rollup-pluginutils": "^2.8.1" + "fsevents": "~2.1.2" } }, - "rollup-plugin-commonjs": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/rollup-plugin-commonjs/-/rollup-plugin-commonjs-10.1.0.tgz", - "integrity": "sha512-jlXbjZSQg8EIeAAvepNwhJj++qJWNJw1Cl0YnOqKtP5Djx+fFGkp3WRh+W0ASCaFG5w1jhmzDxgu3SJuVxPF4Q==", - "dev": true, - "requires": { - "estree-walker": "^0.6.1", - "is-reference": "^1.1.2", - "magic-string": "^0.25.2", - "resolve": "^1.11.0", - "rollup-pluginutils": "^2.8.1" - } + "rollup-dependency-tree": { + "version": "0.0.10", + "resolved": "https://registry.npmjs.org/rollup-dependency-tree/-/rollup-dependency-tree-0.0.10.tgz", + "integrity": "sha512-xgnV7DomkPLkQDFzfa5b3JW3kLQrrY8QiI4qbz/4uBk8NPj5sTjI12xQbEIzzvrLvhUSk/3WBscSVYHkgDxmvA==", + "dev": true }, - "rollup-plugin-json": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/rollup-plugin-json/-/rollup-plugin-json-4.0.0.tgz", - "integrity": "sha512-hgb8N7Cgfw5SZAkb3jf0QXii6QX/FOkiIq2M7BAQIEydjHvTyxXHQiIzZaTFgx1GK0cRCHOCBHIyEkkLdWKxow==", + "rollup-plugin-svelte": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/rollup-plugin-svelte/-/rollup-plugin-svelte-6.0.0.tgz", + "integrity": "sha512-y9qtWa+iNYwXdOZqaEqz3i6k3gzofC9JXzv+WVKDOt0DLiJxJaSrlKKf4YkKG91RzTK5Lo+0fW8in9QH/DxEhA==", "dev": true, "requires": { - "rollup-pluginutils": "^2.5.0" + "require-relative": "^0.8.7", + "rollup-pluginutils": "^2.8.2", + "sourcemap-codec": "^1.4.8" } }, - "rollup-plugin-node-resolve": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/rollup-plugin-node-resolve/-/rollup-plugin-node-resolve-5.2.0.tgz", - "integrity": "sha512-jUlyaDXts7TW2CqQ4GaO5VJ4PwwaV8VUGA7+km3n6k6xtOEacf61u0VXwN80phY/evMcaS+9eIeJ9MOyDxt5Zw==", + "rollup-plugin-terser": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/rollup-plugin-terser/-/rollup-plugin-terser-7.0.1.tgz", + "integrity": "sha512-HL0dgzSxBYG/Ly9i/E5Sc+PuKKZ0zBzk11VmLCfdUtpqH4yYqkLclPkTqRy85FU9246yetImOClaQ/ufnj08vg==", "dev": true, "requires": { - "@types/resolve": "0.0.8", - "builtin-modules": "^3.1.0", - "is-module": "^1.0.0", - "resolve": "^1.11.1", - "rollup-pluginutils": "^2.8.1" + "@babel/code-frame": "^7.10.4", + "jest-worker": "^26.2.1", + "serialize-javascript": "^4.0.0", + "terser": "^5.0.0" }, "dependencies": { - "resolve": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.11.1.tgz", - "integrity": "sha512-vIpgF6wfuJOZI7KKKSP+HmiKggadPQAdsp5HiC1mvqnfp0gF1vdwgBWZIdrVft9pgqoMFQN+R7BSWZiBxx+BBw==", + "@babel/code-frame": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.10.4.tgz", + "integrity": "sha512-vG6SvB6oYEhvgisZNFRmRCUkLz11c7rp+tbNTynGqc6mS1d5ATd/sGyV6W0KZZnXRKMTzZDRgQT3Ou9jhpAfUg==", "dev": true, "requires": { - "path-parse": "^1.0.6" + "@babel/highlight": "^7.10.4" + } + }, + "@babel/highlight": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.10.4.tgz", + "integrity": "sha512-i6rgnR/YgPEQzZZnbTHHuZdlE8qyoBNalD6F+q4vAFlcMEcqmkoG+mPqJYJCo63qPf74+Y1UZsl3l6f7/RIkmA==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.10.4", + "chalk": "^2.0.0", + "js-tokens": "^4.0.0" } } } }, - "rollup-plugin-replace": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/rollup-plugin-replace/-/rollup-plugin-replace-2.2.0.tgz", - "integrity": "sha512-/5bxtUPkDHyBJAKketb4NfaeZjL5yLZdeUihSfbF2PQMz+rSTEb8ARKoOl3UBT4m7/X+QOXJo3sLTcq+yMMYTA==", - "dev": true, - "requires": { - "magic-string": "^0.25.2", - "rollup-pluginutils": "^2.6.0" - } - }, - "rollup-plugin-svelte": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/rollup-plugin-svelte/-/rollup-plugin-svelte-5.1.0.tgz", - "integrity": "sha512-4MRZG29dAWDpoxEs5uIHzDnYafQEOLaKIJAuDYUtFIzEm1F1IGSTlFyjd8/qk4wltlHdu6V7YfZY53+CKryhMg==", - "dev": true, - "requires": { - "require-relative": "^0.8.7", - "rollup-pluginutils": "^2.3.3", - "sourcemap-codec": "^1.4.4" - } - }, - "rollup-plugin-terser": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/rollup-plugin-terser/-/rollup-plugin-terser-5.1.1.tgz", - "integrity": "sha512-McIMCDEY8EU6Y839C09UopeRR56wXHGdvKKjlfiZG/GrP6wvZQ62u2ko/Xh1MNH2M9WDL+obAAHySljIZYCuPQ==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.0.0", - "jest-worker": "^24.6.0", - "rollup-pluginutils": "^2.8.1", - "serialize-javascript": "^1.7.0", - "terser": "^4.1.0" - } - }, "rollup-pluginutils": { - "version": "2.8.1", - "resolved": "https://registry.npmjs.org/rollup-pluginutils/-/rollup-pluginutils-2.8.1.tgz", - "integrity": "sha512-J5oAoysWar6GuZo0s+3bZ6sVZAC0pfqKz68De7ZgDi5z63jOVZn1uJL/+z1jeKHNbGII8kAyHF5q8LnxSX5lQg==", + "version": "2.8.2", + "resolved": "https://registry.npmjs.org/rollup-pluginutils/-/rollup-pluginutils-2.8.2.tgz", + "integrity": "sha512-EEp9NhnUkwY8aif6bxgovPHMoMoNr2FulJziTndpt5H9RdwC47GSGuII9XxpSdzVGM0GWrNPHV6ie1LTNJPaLQ==", "dev": true, "requires": { "estree-walker": "^0.6.1" + }, + "dependencies": { + "estree-walker": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-0.6.1.tgz", + "integrity": "sha512-SqmZANLWS0mnatqbSfRP5g8OXZC12Fgg1IwNtLsyHDzJizORW4khDfjPqJZsemPWBB2uqykUah5YpQ6epsqC/w==", + "dev": true + } } }, "safe-buffer": { @@ -3495,22 +3603,24 @@ } }, "sapper": { - "version": "0.27.11", - "resolved": "https://registry.npmjs.org/sapper/-/sapper-0.27.11.tgz", - "integrity": "sha512-5EaPZhlc8OnyN3UCI6dRSM1Gz5sxyzLZG/1z5nMvZhg9Ng+rSvEvJx/rW/tSHcnQPa8or7+YcbfvQHKS5oPHiw==", + "version": "0.28.4", + "resolved": "https://registry.npmjs.org/sapper/-/sapper-0.28.4.tgz", + "integrity": "sha512-+6nw10RiMylt8SEXFbY49TWv37TX7x6clTeBKGsAfdlWmIXha8q/Mu9ruVK/Kwsiupv62MREU9vvwtuvLWBtqg==", "dev": true, "requires": { "html-minifier": "^4.0.0", "http-link-header": "^1.0.2", + "rollup-dependency-tree": "0.0.10", "shimport": "^1.0.1", + "source-map": "^0.6.1", "sourcemap-codec": "^1.4.6", "string-hash": "^1.1.3" }, "dependencies": { - "sourcemap-codec": { - "version": "1.4.6", - "resolved": "https://registry.npmjs.org/sourcemap-codec/-/sourcemap-codec-1.4.6.tgz", - "integrity": "sha512-1ZooVLYFxC448piVLBbtOxFcXwnymH9oUF8nRd3CuYDVvkRBxRl6pB4Mtas5a4drtL+E8LDgFkQNcgIw6tc8Hg==", + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", "dev": true } } @@ -3533,10 +3643,13 @@ "integrity": "sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA==" }, "serialize-javascript": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-1.7.0.tgz", - "integrity": "sha512-ke8UG8ulpFOxO8f8gRYabHQe/ZntKlcig2Mp+8+URDP1D8vJZ0KUt7LYo07q25Z/+JVSgpr/cui9PIp5H6/+nA==", - "dev": true + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-4.0.0.tgz", + "integrity": "sha512-GaNA54380uFefWghODBWEGisLZFj00nS5ACs6yHa9nLqlLpVLO8ChDGeKRjZnV4Nh4n0Qi7nhYZD/9fCPzEqkw==", + "dev": true, + "requires": { + "randombytes": "^2.1.0" + } }, "set-blocking": { "version": "2.0.0", @@ -3595,9 +3708,9 @@ "dev": true }, "sirv": { - "version": "1.0.0-next.2", - "resolved": "https://registry.npmjs.org/sirv/-/sirv-1.0.0-next.2.tgz", - "integrity": "sha512-hWp0todr4jSb1BFBiANRmqYRXzX02l36/X4tyHPYKqMZ+e1hrDZKUjIIXrAOBRWlAE/G5cGImUciMrUcU8DeOg==", + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/sirv/-/sirv-1.0.6.tgz", + "integrity": "sha512-LRGu7Op4Xl9hhigOy2kcB53zAYTjNDdpooey49dIU0cMdpOv9ithVf7nstk3jvs8EhMiT/VORoyazZYGgw4vnA==", "requires": { "@polka/url": "^1.0.0-next.9", "mime": "^2.3.1", @@ -3611,9 +3724,9 @@ "dev": true }, "source-map-support": { - "version": "0.5.12", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.12.tgz", - "integrity": "sha512-4h2Pbvyy15EE02G+JOZpUCmqWJuqrs+sEkzewTm++BPi7Hvn/HwcqLAcNxYAyI0x13CpPPn+kMjl+hplXMHITQ==", + "version": "0.5.19", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.19.tgz", + "integrity": "sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw==", "dev": true, "requires": { "buffer-from": "^1.0.0", @@ -3629,9 +3742,9 @@ } }, "sourcemap-codec": { - "version": "1.4.4", - "resolved": "https://registry.npmjs.org/sourcemap-codec/-/sourcemap-codec-1.4.4.tgz", - "integrity": "sha512-CYAPYdBu34781kLHkaW3m6b/uUSyMOC2R61gcYMWooeuaGtjof86ZA/8T+qVPPt7np1085CR9hmMGrySwEc8Xg==", + "version": "1.4.8", + "resolved": "https://registry.npmjs.org/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz", + "integrity": "sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==", "dev": true }, "spdx-correct": { @@ -3718,15 +3831,6 @@ "function-bind": "^1.1.1" } }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - }, "strip-ansi": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", @@ -3791,9 +3895,9 @@ } }, "terser": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/terser/-/terser-4.1.2.tgz", - "integrity": "sha512-jvNoEQSPXJdssFwqPSgWjsOrb+ELoE+ILpHPKXC83tIxOlh2U75F1KuB2luLD/3a6/7K3Vw5pDn+hvu0C4AzSw==", + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.3.0.tgz", + "integrity": "sha512-XTT3D3AwxC54KywJijmY2mxZ8nJiEjBHVYzq8l9OaYuRFWeQNBwvipuzzYEP4e+/AVcd1hqG/CqgsdIRyT45Fg==", "dev": true, "requires": { "commander": "^2.20.0", @@ -3839,9 +3943,9 @@ "dev": true }, "totalist": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/totalist/-/totalist-1.0.1.tgz", - "integrity": "sha512-HuAt9bWDCdLkebrIQr+i63NgQSvjeD2VTNUIEBqof/4pG4Gb6omuBOMUX0vF371cbfImXQzmb4Ue/0c9MUWGew==" + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/totalist/-/totalist-1.1.0.tgz", + "integrity": "sha512-gduQwd1rOdDMGxFG1gEvhV88Oirdo2p+KjoYFU7k2g+i7n6AFFbDQ5kMPUsW0pNbfQsB/cwXvT1i4Bue0s9g5g==" }, "trim-right": { "version": "1.0.1", @@ -3858,22 +3962,10 @@ } }, "uglify-js": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.6.0.tgz", - "integrity": "sha512-W+jrUHJr3DXKhrsS7NUVxn3zqMOFn0hL/Ei6v0anCIMoKC93TjcflTagwIHLW7SfMFfiQuktQyFVCFHGUE0+yg==", - "dev": true, - "requires": { - "commander": "~2.20.0", - "source-map": "~0.6.1" - }, - "dependencies": { - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - } - } + "version": "3.10.3", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.10.3.tgz", + "integrity": "sha512-Lh00i69Uf6G74mvYpHCI9KVVXLcHW/xu79YTvH7Mkc9zyKUeSPz0owW0dguj0Scavns3ZOh3wY63J0Zb97Za2g==", + "dev": true }, "unicode-canonical-property-names-ecmascript": { "version": "1.0.4", @@ -3918,12 +4010,6 @@ "pako": "^1.0.5" } }, - "util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", - "dev": true - }, "util.promisify": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/util.promisify/-/util.promisify-1.0.0.tgz", diff --git a/site/package.json b/site/package.json index c6c6790dd1..235273b637 100644 --- a/site/package.json +++ b/site/package.json @@ -21,12 +21,12 @@ "flru": "^1.0.2", "httpie": "^1.1.2", "jsonwebtoken": "^8.5.1", - "marked": "^0.7.0", + "marked": "^1.0.0", "pg": "^7.12.1", "polka": "^1.0.0-next.9", "prism-svelte": "^0.4.3", "prismjs": "^1.21.0", - "sirv": "^1.0.0-next.2", + "sirv": "^1.0.0", "yootils": "0.0.16" }, "devDependencies": { @@ -35,6 +35,11 @@ "@babel/plugin-transform-runtime": "^7.6.0", "@babel/preset-env": "^7.6.0", "@babel/runtime": "^7.6.0", + "@rollup/plugin-babel": "^5.0.0", + "@rollup/plugin-commonjs": "^15.0.0", + "@rollup/plugin-json": "^4.1.0", + "@rollup/plugin-node-resolve": "^9.0.0", + "@rollup/plugin-replace": "^2.2.0", "@sindresorhus/slugify": "^0.9.1", "@sveltejs/site-kit": "^1.2.4", "@sveltejs/svelte-repl": "^0.2.1", @@ -46,15 +51,10 @@ "node-fetch": "^2.6.0", "node-pg-migrate": "^3.22.0", "npm-run-all": "^4.1.5", - "rollup": "^1.21.2", - "rollup-plugin-babel": "^4.3.3", - "rollup-plugin-commonjs": "^10.1.0", - "rollup-plugin-json": "^4.0.0", - "rollup-plugin-node-resolve": "^5.2.0", - "rollup-plugin-replace": "^2.2.0", - "rollup-plugin-svelte": "^5.1.0", - "rollup-plugin-terser": "^5.1.1", - "sapper": "^0.27.11", + "rollup": "^2.26.10", + "rollup-plugin-svelte": "^6.0.0", + "rollup-plugin-terser": "^7.0.0", + "sapper": "^0.28.4", "shelljs": "^0.8.3", "svelte": "^3.12.0" }, diff --git a/site/rollup.config.js b/site/rollup.config.js index d4efb4eb29..a70fe53e4e 100644 --- a/site/rollup.config.js +++ b/site/rollup.config.js @@ -1,10 +1,10 @@ import 'dotenv/config'; -import resolve from 'rollup-plugin-node-resolve'; -import replace from 'rollup-plugin-replace'; -import commonjs from 'rollup-plugin-commonjs'; +import babel from '@rollup/plugin-babel'; +import commonjs from '@rollup/plugin-commonjs'; +import json from '@rollup/plugin-json'; +import replace from '@rollup/plugin-replace'; +import resolve from '@rollup/plugin-node-resolve'; import svelte from 'rollup-plugin-svelte'; -import babel from 'rollup-plugin-babel'; -import json from 'rollup-plugin-json'; import { terser } from 'rollup-plugin-terser'; import config from 'sapper/config/rollup.js'; import pkg from './package.json'; @@ -44,7 +44,7 @@ export default { legacy && babel({ extensions: ['.js', '.mjs', '.html', '.svelte'], - runtimeHelpers: true, + babelHelpers: 'runtime', exclude: ['node_modules/@babel/**'], presets: [ ['@babel/preset-env', { From c8c50b5ba8b697110f7a21c676f0124bf5041ccf Mon Sep 17 00:00:00 2001 From: Ben McCann <322311+benmccann@users.noreply.github.com> Date: Fri, 4 Sep 2020 19:54:00 -0700 Subject: [PATCH 46/94] site: copy preserveEntrySignatures settings from template (#5356) --- site/rollup.config.js | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/site/rollup.config.js b/site/rollup.config.js index a70fe53e4e..0078711c7a 100644 --- a/site/rollup.config.js +++ b/site/rollup.config.js @@ -63,6 +63,8 @@ export default { module: true }) ], + + preserveEntrySignatures: false, onwarn }, @@ -91,6 +93,8 @@ export default { require('module').builtinModules || Object.keys(process.binding('natives')) ) ], + + preserveEntrySignatures: 'strict', onwarn }, @@ -105,6 +109,9 @@ export default { }), commonjs(), !dev && terser() - ] + ], + + preserveEntrySignatures: false, + onwarn } }; From 1503f644d41eb5e1a769066135c385cd0bc8a132 Mon Sep 17 00:00:00 2001 From: Conduitry Date: Sun, 6 Sep 2020 19:31:54 -0400 Subject: [PATCH 47/94] site: update to sapper@0.28.5 --- site/package-lock.json | 20 ++++++++++---------- site/package.json | 2 +- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/site/package-lock.json b/site/package-lock.json index f05f5de4c0..8be99e589d 100644 --- a/site/package-lock.json +++ b/site/package-lock.json @@ -3519,9 +3519,9 @@ } }, "rollup-dependency-tree": { - "version": "0.0.10", - "resolved": "https://registry.npmjs.org/rollup-dependency-tree/-/rollup-dependency-tree-0.0.10.tgz", - "integrity": "sha512-xgnV7DomkPLkQDFzfa5b3JW3kLQrrY8QiI4qbz/4uBk8NPj5sTjI12xQbEIzzvrLvhUSk/3WBscSVYHkgDxmvA==", + "version": "0.0.11", + "resolved": "https://registry.npmjs.org/rollup-dependency-tree/-/rollup-dependency-tree-0.0.11.tgz", + "integrity": "sha512-g+mY+9ayok0FKAzFxS9GxX6cSWOFNPYu8H37i32+dsz7tb1SYaGawzsBl1qfLBKaL2WjwowmZ72BhdybZDx79Q==", "dev": true }, "rollup-plugin-svelte": { @@ -3603,14 +3603,14 @@ } }, "sapper": { - "version": "0.28.4", - "resolved": "https://registry.npmjs.org/sapper/-/sapper-0.28.4.tgz", - "integrity": "sha512-+6nw10RiMylt8SEXFbY49TWv37TX7x6clTeBKGsAfdlWmIXha8q/Mu9ruVK/Kwsiupv62MREU9vvwtuvLWBtqg==", + "version": "0.28.5", + "resolved": "https://registry.npmjs.org/sapper/-/sapper-0.28.5.tgz", + "integrity": "sha512-pR+HZ3no95VoYfzMWv3nVZQY7vwJXF4C/vTnqMDuu7iVPm8X03pKHoXLRJZ1bREeey6Xteq7Et3RbPeXKfg5Fg==", "dev": true, "requires": { "html-minifier": "^4.0.0", "http-link-header": "^1.0.2", - "rollup-dependency-tree": "0.0.10", + "rollup-dependency-tree": "0.0.11", "shimport": "^1.0.1", "source-map": "^0.6.1", "sourcemap-codec": "^1.4.6", @@ -3962,9 +3962,9 @@ } }, "uglify-js": { - "version": "3.10.3", - "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.10.3.tgz", - "integrity": "sha512-Lh00i69Uf6G74mvYpHCI9KVVXLcHW/xu79YTvH7Mkc9zyKUeSPz0owW0dguj0Scavns3ZOh3wY63J0Zb97Za2g==", + "version": "3.10.4", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.10.4.tgz", + "integrity": "sha512-kBFT3U4Dcj4/pJ52vfjCSfyLyvG9VYYuGYPmrPvAxRw/i7xHiT4VvCev+uiEMcEEiu6UNB6KgWmGtSUYIWScbw==", "dev": true }, "unicode-canonical-property-names-ecmascript": { diff --git a/site/package.json b/site/package.json index 235273b637..2cc2e454ef 100644 --- a/site/package.json +++ b/site/package.json @@ -54,7 +54,7 @@ "rollup": "^2.26.10", "rollup-plugin-svelte": "^6.0.0", "rollup-plugin-terser": "^7.0.0", - "sapper": "^0.28.4", + "sapper": "^0.28.5", "shelljs": "^0.8.3", "svelte": "^3.12.0" }, From b1c67a16c607fdd3e2150122f58604d7a1f1dcbc Mon Sep 17 00:00:00 2001 From: Conduitry Date: Wed, 9 Sep 2020 09:45:52 -0400 Subject: [PATCH 48/94] site: update to sapper@0.28.6 --- site/package-lock.json | 13 +++---------- site/package.json | 2 +- 2 files changed, 4 insertions(+), 11 deletions(-) diff --git a/site/package-lock.json b/site/package-lock.json index 8be99e589d..da6a8e809d 100644 --- a/site/package-lock.json +++ b/site/package-lock.json @@ -3518,12 +3518,6 @@ "fsevents": "~2.1.2" } }, - "rollup-dependency-tree": { - "version": "0.0.11", - "resolved": "https://registry.npmjs.org/rollup-dependency-tree/-/rollup-dependency-tree-0.0.11.tgz", - "integrity": "sha512-g+mY+9ayok0FKAzFxS9GxX6cSWOFNPYu8H37i32+dsz7tb1SYaGawzsBl1qfLBKaL2WjwowmZ72BhdybZDx79Q==", - "dev": true - }, "rollup-plugin-svelte": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/rollup-plugin-svelte/-/rollup-plugin-svelte-6.0.0.tgz", @@ -3603,14 +3597,13 @@ } }, "sapper": { - "version": "0.28.5", - "resolved": "https://registry.npmjs.org/sapper/-/sapper-0.28.5.tgz", - "integrity": "sha512-pR+HZ3no95VoYfzMWv3nVZQY7vwJXF4C/vTnqMDuu7iVPm8X03pKHoXLRJZ1bREeey6Xteq7Et3RbPeXKfg5Fg==", + "version": "0.28.6", + "resolved": "https://registry.npmjs.org/sapper/-/sapper-0.28.6.tgz", + "integrity": "sha512-PLCZXBcXcL2ISBh+CqoUxcT0MwMnA8N71UDNhQig0Em5Z8vqg+g2jpKfYSnnyxqB5Plwc9LipN5ZJr42Vs4hXg==", "dev": true, "requires": { "html-minifier": "^4.0.0", "http-link-header": "^1.0.2", - "rollup-dependency-tree": "0.0.11", "shimport": "^1.0.1", "source-map": "^0.6.1", "sourcemap-codec": "^1.4.6", diff --git a/site/package.json b/site/package.json index 2cc2e454ef..f760cd871d 100644 --- a/site/package.json +++ b/site/package.json @@ -54,7 +54,7 @@ "rollup": "^2.26.10", "rollup-plugin-svelte": "^6.0.0", "rollup-plugin-terser": "^7.0.0", - "sapper": "^0.28.5", + "sapper": "^0.28.6", "shelljs": "^0.8.3", "svelte": "^3.12.0" }, From 51e2626f42e00df15730152c2d0cedf06ace0f49 Mon Sep 17 00:00:00 2001 From: Tan Li Hau Date: Fri, 11 Sep 2020 02:42:38 +0800 Subject: [PATCH 49/94] fix $$props reactivity in fallback of a slot (#5375) --- CHANGELOG.md | 1 + .../render_dom/wrappers/shared/is_dynamic.ts | 2 ++ .../component-slot-fallback-6/Foo.svelte | 1 + .../component-slot-fallback-6/Inner.svelte | 9 +++++++++ .../component-slot-fallback-6/_config.js | 18 ++++++++++++++++++ .../component-slot-fallback-6/main.svelte | 8 ++++++++ 6 files changed, 39 insertions(+) create mode 100644 test/runtime/samples/component-slot-fallback-6/Foo.svelte create mode 100644 test/runtime/samples/component-slot-fallback-6/Inner.svelte create mode 100644 test/runtime/samples/component-slot-fallback-6/_config.js create mode 100644 test/runtime/samples/component-slot-fallback-6/main.svelte diff --git a/CHANGELOG.md b/CHANGELOG.md index 0ccfeff273..19e8cced8f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,7 @@ * Fix using `` in `{:catch}` ([#5259](https://github.com/sveltejs/svelte/issues/5259)) * Fix setting one-way bound `` `value` to `undefined` when it has spread attributes ([#5270](https://github.com/sveltejs/svelte/issues/5270)) * Fix deep two-way bindings inside an `{#each}` involving a store ([#5286](https://github.com/sveltejs/svelte/issues/5286)) +* Fix reactivity of `$$props` in slot fallback content ([#5367](https://github.com/sveltejs/svelte/issues/5367)) ## 3.24.1 diff --git a/src/compiler/compile/render_dom/wrappers/shared/is_dynamic.ts b/src/compiler/compile/render_dom/wrappers/shared/is_dynamic.ts index d32ebe4594..aca2096154 100644 --- a/src/compiler/compile/render_dom/wrappers/shared/is_dynamic.ts +++ b/src/compiler/compile/render_dom/wrappers/shared/is_dynamic.ts @@ -1,9 +1,11 @@ import { Var } from '../../../../interfaces'; +import { is_reserved_keyword } from '../../../utils/reserved_keywords'; export default function is_dynamic(variable: Var) { if (variable) { if (variable.mutated || variable.reassigned) return true; // dynamic internal state if (!variable.module && variable.writable && variable.export_name) return true; // writable props + if (is_reserved_keyword(variable.name)) return true; } return false; diff --git a/test/runtime/samples/component-slot-fallback-6/Foo.svelte b/test/runtime/samples/component-slot-fallback-6/Foo.svelte new file mode 100644 index 0000000000..0385342cef --- /dev/null +++ b/test/runtime/samples/component-slot-fallback-6/Foo.svelte @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/test/runtime/samples/component-slot-fallback-6/Inner.svelte b/test/runtime/samples/component-slot-fallback-6/Inner.svelte new file mode 100644 index 0000000000..28f0fdd869 --- /dev/null +++ b/test/runtime/samples/component-slot-fallback-6/Inner.svelte @@ -0,0 +1,9 @@ + + + + + {JSON.stringify($$props)} + + diff --git a/test/runtime/samples/component-slot-fallback-6/_config.js b/test/runtime/samples/component-slot-fallback-6/_config.js new file mode 100644 index 0000000000..fb1a658f26 --- /dev/null +++ b/test/runtime/samples/component-slot-fallback-6/_config.js @@ -0,0 +1,18 @@ +// $$props reactivity in slot fallback +export default { + html: ` + + {"value":""} + `, + + async test({ assert, target, window }) { + const input = target.querySelector("input"); + input.value = "abc"; + await input.dispatchEvent(new window.Event('input')); + + assert.htmlEqual(target.innerHTML, ` + + {"value":"abc"} + `); + } +}; diff --git a/test/runtime/samples/component-slot-fallback-6/main.svelte b/test/runtime/samples/component-slot-fallback-6/main.svelte new file mode 100644 index 0000000000..35abebef10 --- /dev/null +++ b/test/runtime/samples/component-slot-fallback-6/main.svelte @@ -0,0 +1,8 @@ + + + + + From 8a28d1bb382e75546ca8b53e5235113bf82f9ecd Mon Sep 17 00:00:00 2001 From: Tan Li Hau Date: Fri, 11 Sep 2020 03:28:22 +0800 Subject: [PATCH 50/94] valid XHTML syntax in innerHTML for static elements (#5317) --- CHANGELOG.md | 1 + .../render_dom/wrappers/Element/index.ts | 6 ++- .../expected.js | 39 +++++++++++++++++++ .../input.svelte | 3 ++ 4 files changed, 47 insertions(+), 2 deletions(-) create mode 100644 test/js/samples/valid-inner-html-for-static-element/expected.js create mode 100644 test/js/samples/valid-inner-html-for-static-element/input.svelte diff --git a/CHANGELOG.md b/CHANGELOG.md index 19e8cced8f..d3bd11c8b3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,7 @@ * Fix using `` in `{:catch}` ([#5259](https://github.com/sveltejs/svelte/issues/5259)) * Fix setting one-way bound `` `value` to `undefined` when it has spread attributes ([#5270](https://github.com/sveltejs/svelte/issues/5270)) * Fix deep two-way bindings inside an `{#each}` involving a store ([#5286](https://github.com/sveltejs/svelte/issues/5286)) +* Use valid XHTML for elements that are optimised and inserted with `.innerHTML` ([#5315](https://github.com/sveltejs/svelte/issues/5315)) * Fix reactivity of `$$props` in slot fallback content ([#5367](https://github.com/sveltejs/svelte/issues/5367)) ## 3.24.1 diff --git a/src/compiler/compile/render_dom/wrappers/Element/index.ts b/src/compiler/compile/render_dom/wrappers/Element/index.ts index b3533d2fa0..2e35f0271f 100644 --- a/src/compiler/compile/render_dom/wrappers/Element/index.ts +++ b/src/compiler/compile/render_dom/wrappers/Element/index.ts @@ -997,12 +997,14 @@ function to_html(wrappers: Array, block, literal, state); state.quasi.value.raw += ``; + } else { + state.quasi.value.raw += '/>'; } } }); diff --git a/test/js/samples/valid-inner-html-for-static-element/expected.js b/test/js/samples/valid-inner-html-for-static-element/expected.js new file mode 100644 index 0000000000..f1ced27ba4 --- /dev/null +++ b/test/js/samples/valid-inner-html-for-static-element/expected.js @@ -0,0 +1,39 @@ +/* generated by Svelte vX.Y.Z */ +import { + SvelteComponent, + detach, + element, + init, + insert, + noop, + safe_not_equal +} from "svelte/internal"; + +function create_fragment(ctx) { + let div; + + return { + c() { + div = element("div"); + div.innerHTML = `Star`; + }, + m(target, anchor) { + insert(target, div, anchor); + }, + p: noop, + i: noop, + o: noop, + d(detaching) { + if (detaching) detach(div); + } + }; +} + +class Component extends SvelteComponent { + constructor(options) { + super(); + init(this, options, null, create_fragment, safe_not_equal, {}); + } +} + +export default Component; \ No newline at end of file diff --git a/test/js/samples/valid-inner-html-for-static-element/input.svelte b/test/js/samples/valid-inner-html-for-static-element/input.svelte new file mode 100644 index 0000000000..3990b2a0c2 --- /dev/null +++ b/test/js/samples/valid-inner-html-for-static-element/input.svelte @@ -0,0 +1,3 @@ +
+ Star +
\ No newline at end of file From 80e474a2442e109e5e2a39bf02bb11e6c6b7b029 Mon Sep 17 00:00:00 2001 From: Cam Jackson Date: Fri, 11 Sep 2020 05:28:59 +1000 Subject: [PATCH 51/94] site: Replace "active" with "selected" as an example class name (#5309) --- .../tutorial/13-classes/01-classes/app-a/App.svelte | 8 ++++---- .../tutorial/13-classes/01-classes/app-b/App.svelte | 8 ++++---- site/content/tutorial/13-classes/01-classes/text.md | 6 +++--- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/site/content/tutorial/13-classes/01-classes/app-a/App.svelte b/site/content/tutorial/13-classes/01-classes/app-a/App.svelte index 68cb642463..baa2543562 100644 --- a/site/content/tutorial/13-classes/01-classes/app-a/App.svelte +++ b/site/content/tutorial/13-classes/01-classes/app-a/App.svelte @@ -7,23 +7,23 @@ display: block; } - .active { + .selected { background-color: #ff3e00; color: white; } \ No newline at end of file diff --git a/site/content/tutorial/13-classes/01-classes/app-b/App.svelte b/site/content/tutorial/13-classes/01-classes/app-b/App.svelte index 4da386991d..a8861ad537 100644 --- a/site/content/tutorial/13-classes/01-classes/app-b/App.svelte +++ b/site/content/tutorial/13-classes/01-classes/app-b/App.svelte @@ -7,23 +7,23 @@ display: block; } - .active { + .selected { background-color: #ff3e00; color: white; } \ No newline at end of file diff --git a/site/content/tutorial/13-classes/01-classes/text.md b/site/content/tutorial/13-classes/01-classes/text.md index 7ad3045399..6e5b3b3c0d 100644 --- a/site/content/tutorial/13-classes/01-classes/text.md +++ b/site/content/tutorial/13-classes/01-classes/text.md @@ -6,7 +6,7 @@ Like any other attribute, you can specify classes with a JavaScript attribute, s ```html ``` @@ -15,9 +15,9 @@ This is such a common pattern in UI development that Svelte includes a special d ```html ``` -The `active` class is added to the element whenever the value of the expression is truthy, and removed when it's falsy. \ No newline at end of file +The `selected` class is added to the element whenever the value of the expression is truthy, and removed when it's falsy. From ae971f80ae11659c8885748a5aeaac82eb5ec17b Mon Sep 17 00:00:00 2001 From: Eugene Hwang Date: Thu, 10 Sep 2020 15:31:28 -0400 Subject: [PATCH 52/94] docs: adjust explanations of `$$props` and `$$restProps` (#5368) --- site/content/docs/02-template-syntax.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/site/content/docs/02-template-syntax.md b/site/content/docs/02-template-syntax.md index cfc7d7ba7a..e93449728b 100644 --- a/site/content/docs/02-template-syntax.md +++ b/site/content/docs/02-template-syntax.md @@ -107,7 +107,7 @@ An element or component can have multiple spread attributes, interspersed with r --- -*`$$props`* references all props that are passed to a component – including ones that are not declared with `export`. It is useful in rare cases, but not generally recommended, as it is difficult for Svelte to optimise. +*`$$props`* references all props that are passed to a component, including ones that are not declared with `export`. It is not generally recommended, as it is difficult for Svelte to optimise. But it can be useful in rare cases – for example, when you don't know at compile time what props might be passed to a component. ```sv @@ -115,7 +115,7 @@ An element or component can have multiple spread attributes, interspersed with r --- -*`$$restProps`* contains only the props which are *not* declared with `export`. It can be used to pass down other unknown attributes to an element in a component. +*`$$restProps`* contains only the props which are *not* declared with `export`. It can be used to pass down other unknown attributes to an element in a component. It shares the same optimisation problems as *`$$props`*, and is likewise not recommended. ```html From 211fc92e69b7eb02b2e7f0d67e6569c8fcbfcb52 Mon Sep 17 00:00:00 2001 From: rdb Date: Thu, 10 Sep 2020 21:39:45 +0200 Subject: [PATCH 53/94] Fix current component not being cleared after component update (#4909) --- src/runtime/internal/scheduler.ts | 1 + .../onmount-get-current-component/_config.js | 4 ++++ .../onmount-get-current-component/main.svelte | 16 ++++++++++++++++ 3 files changed, 21 insertions(+) create mode 100644 test/runtime/samples/onmount-get-current-component/_config.js create mode 100644 test/runtime/samples/onmount-get-current-component/main.svelte diff --git a/src/runtime/internal/scheduler.ts b/src/runtime/internal/scheduler.ts index b0db71035a..568739e4f8 100644 --- a/src/runtime/internal/scheduler.ts +++ b/src/runtime/internal/scheduler.ts @@ -45,6 +45,7 @@ export function flush() { set_current_component(component); update(component.$$); } + set_current_component(null); dirty_components.length = 0; diff --git a/test/runtime/samples/onmount-get-current-component/_config.js b/test/runtime/samples/onmount-get-current-component/_config.js new file mode 100644 index 0000000000..727f8a2d8e --- /dev/null +++ b/test/runtime/samples/onmount-get-current-component/_config.js @@ -0,0 +1,4 @@ +export default { + skip_if_ssr: true, + html: `1`, +}; diff --git a/test/runtime/samples/onmount-get-current-component/main.svelte b/test/runtime/samples/onmount-get-current-component/main.svelte new file mode 100644 index 0000000000..de64bc65fa --- /dev/null +++ b/test/runtime/samples/onmount-get-current-component/main.svelte @@ -0,0 +1,16 @@ + + +{gotException} From b7710b93bcc186d27b2a5dad82524d9cd311b052 Mon Sep 17 00:00:00 2001 From: Conduitry Date: Thu, 10 Sep 2020 15:39:59 -0400 Subject: [PATCH 54/94] update changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index d3bd11c8b3..3227ac382c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ ## Unreleased * Expose object of which slots have received content in `$$slots` ([#2106](https://github.com/sveltejs/svelte/issues/2106)) +* Correctly disallow using lifecycle hooks after synchronous component initialisation ([#4259](https://github.com/sveltejs/svelte/issues/4259), [#4899](https://github.com/sveltejs/svelte/issues/4899)) * Re-throw an unhandled rejection when an `{#await}` block with no `{:catch}` gets a rejection ([#5129](https://github.com/sveltejs/svelte/issues/5129)) * Add types to `createEventDispatcher` ([#5211](https://github.com/sveltejs/svelte/issues/5211)) * In SSR mode, do not automatically declare variables for reactive assignments to member expressions ([#5247](https://github.com/sveltejs/svelte/issues/5247)) From c96673bcead31758104bb605d42b7edc50a1aee1 Mon Sep 17 00:00:00 2001 From: milahu Date: Thu, 10 Sep 2020 21:41:42 +0200 Subject: [PATCH 55/94] Upgrade to mocha 7 and migrate to mocharc (#5357) Co-authored-by: Ben McCann <322311+benmccann@users.noreply.github.com> --- .mocharc.coverage.js | 10 + .mocharc.js | 5 + mocha.coverage.opts | 4 - mocha.opts | 1 - package-lock.json | 478 ++++++++++++++++++------------------------- package.json | 10 +- 6 files changed, 216 insertions(+), 292 deletions(-) create mode 100644 .mocharc.coverage.js create mode 100644 .mocharc.js delete mode 100644 mocha.coverage.opts delete mode 100644 mocha.opts diff --git a/.mocharc.coverage.js b/.mocharc.coverage.js new file mode 100644 index 0000000000..91c93518ca --- /dev/null +++ b/.mocharc.coverage.js @@ -0,0 +1,10 @@ +module.exports = Object.assign( + {}, + require('./mocharc.js'), + { + fullTrace: true, + require: [ + 'source-map-support/register' + ] + } +); diff --git a/.mocharc.js b/.mocharc.js new file mode 100644 index 0000000000..6159fd937f --- /dev/null +++ b/.mocharc.js @@ -0,0 +1,5 @@ +module.exports = { + file: [ + 'test/test.js' + ] +}; diff --git a/mocha.coverage.opts b/mocha.coverage.opts deleted file mode 100644 index cfec67a99a..0000000000 --- a/mocha.coverage.opts +++ /dev/null @@ -1,4 +0,0 @@ ---require source-map-support/register ---full-trace ---recursive -test/test.js diff --git a/mocha.opts b/mocha.opts deleted file mode 100644 index 427b029758..0000000000 --- a/mocha.opts +++ /dev/null @@ -1 +0,0 @@ -test/test.js \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 4e9e06824a..d3012bbf70 100644 --- a/package-lock.json +++ b/package-lock.json @@ -197,9 +197,9 @@ "dev": true }, "@types/mocha": { - "version": "5.2.7", - "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-5.2.7.tgz", - "integrity": "sha512-NYrtPht0wGzhwe9+/idPaBB+TqkY9AhTvOLMkThm0IoEfLaiVQZwBwyJ5puCkO3AUCWrmcoePjp2mbFocKy4SQ==", + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-7.0.2.tgz", + "integrity": "sha512-ZvO2tAcjmMi8V/5Z3JsyofMe3hasRcaw88cto5etSVMwVQfeivGAlEYmaQgceUSVYFofVjT+ioHsATjdWcFt1w==", "dev": true }, "@types/node": { @@ -422,6 +422,16 @@ "integrity": "sha1-q8av7tzqUugJzcA3au0845Y10X8=", "dev": true }, + "anymatch": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.1.tgz", + "integrity": "sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg==", + "dev": true, + "requires": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + } + }, "argparse": { "version": "1.0.10", "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", @@ -630,6 +640,12 @@ "tweetnacl": "^0.14.3" } }, + "binary-extensions": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.1.0.tgz", + "integrity": "sha512-1Yj8h9Q+QDF5FzhMs/c9+6UntbD5MkRfRwac8DoEm9ZfUBZ7tZ55YcGVAzEe4bXsdQHEk+s9S5wsOKVdZrw0tQ==", + "dev": true + }, "brace-expansion": { "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", @@ -640,6 +656,15 @@ "concat-map": "0.0.1" } }, + "braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dev": true, + "requires": { + "fill-range": "^7.0.1" + } + }, "browser-process-hrtime": { "version": "0.1.3", "resolved": "https://registry.npmjs.org/browser-process-hrtime/-/browser-process-hrtime-0.1.3.tgz", @@ -736,6 +761,22 @@ "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==", "dev": true }, + "chokidar": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.3.0.tgz", + "integrity": "sha512-dGmKLDdT3Gdl7fBUe8XK+gAtGmzy5Fn0XkkWQuYxGIgWVPPse2CxFA5mtrlD0TOHaHjEUqkWNyP1XdHoJES/4A==", + "dev": true, + "requires": { + "anymatch": "~3.1.1", + "braces": "~3.0.2", + "fsevents": "~2.1.1", + "glob-parent": "~5.1.0", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.2.0" + } + }, "cli-cursor": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", @@ -762,12 +803,6 @@ "wrap-ansi": "^5.1.0" } }, - "code-point-at": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", - "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=", - "dev": true - }, "code-red": { "version": "0.1.3", "resolved": "https://registry.npmjs.org/code-red/-/code-red-0.1.3.tgz", @@ -1020,23 +1055,36 @@ } }, "es-abstract": { - "version": "1.13.0", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.13.0.tgz", - "integrity": "sha512-vDZfg/ykNxQVwup/8E1BZhVzFfBxs9NqMzGcvIJrqg5k2/5Za2bWo40dK2J1pgLngZ7c+Shh8lwYtLGyrwPutg==", + "version": "1.17.6", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.6.tgz", + "integrity": "sha512-Fr89bON3WFyUi5EvAeI48QTWX0AyekGgLA8H+c+7fbfCkJwRWRMLd8CQedNEyJuoYYhmtEqY92pgte1FAhBlhw==", "dev": true, "requires": { - "es-to-primitive": "^1.2.0", + "es-to-primitive": "^1.2.1", "function-bind": "^1.1.1", "has": "^1.0.3", - "is-callable": "^1.1.4", - "is-regex": "^1.0.4", - "object-keys": "^1.0.12" + "has-symbols": "^1.0.1", + "is-callable": "^1.2.0", + "is-regex": "^1.1.0", + "object-inspect": "^1.7.0", + "object-keys": "^1.1.1", + "object.assign": "^4.1.0", + "string.prototype.trimend": "^1.0.1", + "string.prototype.trimstart": "^1.0.1" + }, + "dependencies": { + "has-symbols": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.1.tgz", + "integrity": "sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==", + "dev": true + } } }, "es-to-primitive": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.0.tgz", - "integrity": "sha512-qZryBOJjV//LaxLTV6UC//WewneB3LcXOL9NP++ozKVXsIIIpm/2c13UDiD9Jp2eThsecw9m3jPqDwTyobcdbg==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", + "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", "dev": true, "requires": { "is-callable": "^1.1.4", @@ -1722,6 +1770,15 @@ "flat-cache": "^2.0.1" } }, + "fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dev": true, + "requires": { + "to-regex-range": "^5.0.1" + } + }, "find-up": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", @@ -1790,6 +1847,13 @@ "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", "dev": true }, + "fsevents": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.3.tgz", + "integrity": "sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ==", + "dev": true, + "optional": true + }, "function-bind": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", @@ -2204,16 +2268,25 @@ "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", "dev": true }, + "is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dev": true, + "requires": { + "binary-extensions": "^2.0.0" + } + }, "is-buffer": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.3.tgz", - "integrity": "sha512-U15Q7MXTuZlrbymiz95PJpZxu8IlipAp4dtS3wOdgPXx3mqBnslrWU14kxfHB+Py/+2PVKSr37dMAgM2A4uArw==", + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.4.tgz", + "integrity": "sha512-Kq1rokWXOPXWuaMAqZiJW4XxsmD9zGx9q4aePabbn3qCRGedtH7Cm+zV8WETitMfu1wdh+Rvd6w5egwSngUX2A==", "dev": true }, "is-callable": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.4.tgz", - "integrity": "sha512-r5p9sxJjYnArLjObpjA4xu5EKI3CuKHkJXMhT7kwbpUyIFD1n5PMAsoPvWnvtZiNz7LjkYDRZhd7FlI0eMijEA==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.1.tgz", + "integrity": "sha512-wliAfSzx6V+6WfMOmus1xy0XvSgf/dlStkvTfq7F0g4bOIW0PSUbnyse3NhDwdyYS1ozfUtAAySqTws3z9Eqgg==", "dev": true }, "is-date-object": { @@ -2249,6 +2322,12 @@ "integrity": "sha1-Mlj7afeMFNW4FdZkM2tM/7ZEFZE=", "dev": true }, + "is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true + }, "is-reference": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/is-reference/-/is-reference-1.2.1.tgz", @@ -2259,12 +2338,20 @@ } }, "is-regex": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.4.tgz", - "integrity": "sha1-VRdIm1RwkbCTDglWVM7SXul+lJE=", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.1.tgz", + "integrity": "sha512-1+QkEcxiLlB7VEyFtyBg94e08OAsvq7FUBgApTq/w2ymCLyKJgDPsybBENVtA7XCQEgEXxKPonG+mvYRxh/LIg==", "dev": true, "requires": { - "has": "^1.0.1" + "has-symbols": "^1.0.1" + }, + "dependencies": { + "has-symbols": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.1.tgz", + "integrity": "sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==", + "dev": true + } } }, "is-stream": { @@ -2539,12 +2626,12 @@ "dev": true }, "log-symbols": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-2.2.0.tgz", - "integrity": "sha512-VeIAFslyIerEJLXHziedo2basKbMKtTw3vfn5IzG0XTjhAVEJyNHnL2p7vc+wBDSdQuUpNw3M2u6xb9QsAY5Eg==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-3.0.0.tgz", + "integrity": "sha512-dSkNGuI7iG3mfvDzUuYZyvk5dD9ocYCYzNU6CYDE6+Xqd+gwme6Z00NS3dUh8mq/73HaEtT7m6W+yUPtU6BZnQ==", "dev": true, "requires": { - "chalk": "^2.0.1" + "chalk": "^2.4.2" } }, "lru-cache": { @@ -2662,13 +2749,14 @@ } }, "mocha": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-6.2.0.tgz", - "integrity": "sha512-qwfFgY+7EKAAUAdv7VYMZQknI7YJSGesxHyhn6qD52DV8UcSZs5XwCifcZGMVIE4a5fbmhvbotxC0DLQ0oKohQ==", + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-7.2.0.tgz", + "integrity": "sha512-O9CIypScywTVpNaRrCAgoUnJgozpIofjKUYmJhiCIJMiuYnLI6otcb1/kpW9/n/tJODHGZ7i8aLQoDVsMtOKQQ==", "dev": true, "requires": { "ansi-colors": "3.2.3", "browser-stdout": "1.3.1", + "chokidar": "3.3.0", "debug": "3.2.6", "diff": "3.5.0", "escape-string-regexp": "1.0.5", @@ -2677,50 +2765,21 @@ "growl": "1.10.5", "he": "1.2.0", "js-yaml": "3.13.1", - "log-symbols": "2.2.0", + "log-symbols": "3.0.0", "minimatch": "3.0.4", - "mkdirp": "0.5.1", + "mkdirp": "0.5.5", "ms": "2.1.1", - "node-environment-flags": "1.0.5", + "node-environment-flags": "1.0.6", "object.assign": "4.1.0", "strip-json-comments": "2.0.1", "supports-color": "6.0.0", "which": "1.3.1", "wide-align": "1.1.3", - "yargs": "13.2.2", - "yargs-parser": "13.0.0", - "yargs-unparser": "1.5.0" + "yargs": "13.3.2", + "yargs-parser": "13.1.2", + "yargs-unparser": "1.6.0" }, "dependencies": { - "ansi-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", - "dev": true - }, - "cliui": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-4.1.0.tgz", - "integrity": "sha512-4FG+RSG9DL7uEwRUZXZn3SS34DiDPfzP0VOiEwtUWlE+AR2EIg+hSyvrIgUUfhdgR/UkAeW2QHgeP+hWrXs7jQ==", - "dev": true, - "requires": { - "string-width": "^2.1.1", - "strip-ansi": "^4.0.0", - "wrap-ansi": "^2.0.0" - }, - "dependencies": { - "string-width": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", - "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", - "dev": true, - "requires": { - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^4.0.0" - } - } - } - }, "glob": { "version": "7.1.3", "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz", @@ -2735,36 +2794,12 @@ "path-is-absolute": "^1.0.0" } }, - "minimist": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", - "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", - "dev": true - }, - "mkdirp": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", - "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", - "dev": true, - "requires": { - "minimist": "0.0.8" - } - }, "ms": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", "dev": true }, - "strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", - "dev": true, - "requires": { - "ansi-regex": "^3.0.0" - } - }, "strip-json-comments": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", @@ -2780,76 +2815,28 @@ "has-flag": "^3.0.0" } }, - "wrap-ansi": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz", - "integrity": "sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=", - "dev": true, - "requires": { - "string-width": "^1.0.1", - "strip-ansi": "^3.0.1" - }, - "dependencies": { - "ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", - "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", - "dev": true, - "requires": { - "number-is-nan": "^1.0.0" - } - }, - "string-width": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", - "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", - "dev": true, - "requires": { - "code-point-at": "^1.0.0", - "is-fullwidth-code-point": "^1.0.0", - "strip-ansi": "^3.0.0" - } - }, - "strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", - "dev": true, - "requires": { - "ansi-regex": "^2.0.0" - } - } - } - }, "yargs": { - "version": "13.2.2", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.2.2.tgz", - "integrity": "sha512-WyEoxgyTD3w5XRpAQNYUB9ycVH/PQrToaTXdYXRdOXvEy1l19br+VJsc0vcO8PTGg5ro/l/GY7F/JMEBmI0BxA==", + "version": "13.3.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz", + "integrity": "sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==", "dev": true, "requires": { - "cliui": "^4.0.0", + "cliui": "^5.0.0", "find-up": "^3.0.0", "get-caller-file": "^2.0.1", - "os-locale": "^3.1.0", "require-directory": "^2.1.1", "require-main-filename": "^2.0.0", "set-blocking": "^2.0.0", "string-width": "^3.0.0", "which-module": "^2.0.0", "y18n": "^4.0.0", - "yargs-parser": "^13.0.0" + "yargs-parser": "^13.1.2" } }, "yargs-parser": { - "version": "13.0.0", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.0.0.tgz", - "integrity": "sha512-w2LXjoL8oRdRQN+hOyppuXs+V/fVAYtpcrRxZuF7Kt/Oc+Jr2uAcVntaUTNT6w5ihoWfFDpNY8CPx1QskxZ/pw==", + "version": "13.1.2", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz", + "integrity": "sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==", "dev": true, "requires": { "camelcase": "^5.0.0", @@ -2894,9 +2881,9 @@ "dev": true }, "node-environment-flags": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/node-environment-flags/-/node-environment-flags-1.0.5.tgz", - "integrity": "sha512-VNYPRfGfmZLx0Ye20jWzHUjyTW/c+6Wq+iLhDzUI4XmhrDd9l/FozXV3F2xOaXjvp0co0+v1YSR3CMP6g+VvLQ==", + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/node-environment-flags/-/node-environment-flags-1.0.6.tgz", + "integrity": "sha512-5Evy2epuL+6TM0lCQGpFIj6KwiEsGh1SrHUhTbNX+sLbBtjidPZFAnVK9y5yU1+h//RitLbRHTIMyxQPtxMdHw==", "dev": true, "requires": { "object.getownpropertydescriptors": "^2.0.3", @@ -2904,9 +2891,9 @@ }, "dependencies": { "semver": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.0.tgz", - "integrity": "sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA==", + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", "dev": true } } @@ -2935,6 +2922,12 @@ "validate-npm-package-license": "^3.0.1" } }, + "normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true + }, "npm-run-path": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", @@ -2944,12 +2937,6 @@ "path-key": "^2.0.0" } }, - "number-is-nan": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", - "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=", - "dev": true - }, "nwsapi": { "version": "2.1.4", "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.1.4.tgz", @@ -2993,13 +2980,13 @@ } }, "object.getownpropertydescriptors": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.0.3.tgz", - "integrity": "sha1-h1jIRvW0B62rDyNuCYbxSwUcqhY=", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.0.tgz", + "integrity": "sha512-Z53Oah9A3TdLoblT7VKJaTDdXdT+lQO+cNpKVnya5JDe9uLvzu1YyY1yFDFrcxrlRgWrEFH0jJtD/IbuwjcEVg==", "dev": true, "requires": { - "define-properties": "^1.1.2", - "es-abstract": "^1.5.1" + "define-properties": "^1.1.3", + "es-abstract": "^1.17.0-next.1" } }, "object.values": { @@ -3253,6 +3240,12 @@ "is-reference": "^1.1.4" } }, + "picomatch": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.2.tgz", + "integrity": "sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg==", + "dev": true + }, "pify": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", @@ -3466,6 +3459,15 @@ "util-deprecate": "~1.0.1" } }, + "readdirp": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.2.0.tgz", + "integrity": "sha512-crk4Qu3pmXwgxdSgGhgA/eXiJAPQiX4GMOZZMXnqKxHX7TaoL+3gQVo/WeuAiogr07DpnfjIMpXXa+PAIvwPGQ==", + "dev": true, + "requires": { + "picomatch": "^2.0.4" + } + }, "regexpp": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.1.0.tgz", @@ -4257,6 +4259,15 @@ "os-tmpdir": "~1.0.2" } }, + "to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "requires": { + "is-number": "^7.0.0" + } + }, "tough-cookie": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-3.0.1.tgz", @@ -4616,135 +4627,38 @@ } }, "yargs-unparser": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-1.5.0.tgz", - "integrity": "sha512-HK25qidFTCVuj/D1VfNiEndpLIeJN78aqgR23nL3y4N0U/91cOAzqfHlF8n2BvoNDcZmJKin3ddNSvOxSr8flw==", + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-1.6.0.tgz", + "integrity": "sha512-W9tKgmSn0DpSatfri0nx52Joq5hVXgeLiqR/5G0sZNDoLZFOr/xjBUDcShCOGNsBnEMNo1KAMBkTej1Hm62HTw==", "dev": true, "requires": { "flat": "^4.1.0", - "lodash": "^4.17.11", - "yargs": "^12.0.5" + "lodash": "^4.17.15", + "yargs": "^13.3.0" }, "dependencies": { - "ansi-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", - "dev": true - }, - "cliui": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-4.1.0.tgz", - "integrity": "sha512-4FG+RSG9DL7uEwRUZXZn3SS34DiDPfzP0VOiEwtUWlE+AR2EIg+hSyvrIgUUfhdgR/UkAeW2QHgeP+hWrXs7jQ==", - "dev": true, - "requires": { - "string-width": "^2.1.1", - "strip-ansi": "^4.0.0", - "wrap-ansi": "^2.0.0" - } - }, - "get-caller-file": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.3.tgz", - "integrity": "sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w==", - "dev": true - }, - "require-main-filename": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-1.0.1.tgz", - "integrity": "sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE=", - "dev": true - }, - "string-width": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", - "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", - "dev": true, - "requires": { - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^4.0.0" - } - }, - "strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", - "dev": true, - "requires": { - "ansi-regex": "^3.0.0" - } - }, - "wrap-ansi": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz", - "integrity": "sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=", - "dev": true, - "requires": { - "string-width": "^1.0.1", - "strip-ansi": "^3.0.1" - }, - "dependencies": { - "ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", - "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", - "dev": true, - "requires": { - "number-is-nan": "^1.0.0" - } - }, - "string-width": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", - "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", - "dev": true, - "requires": { - "code-point-at": "^1.0.0", - "is-fullwidth-code-point": "^1.0.0", - "strip-ansi": "^3.0.0" - } - }, - "strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", - "dev": true, - "requires": { - "ansi-regex": "^2.0.0" - } - } - } - }, "yargs": { - "version": "12.0.5", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-12.0.5.tgz", - "integrity": "sha512-Lhz8TLaYnxq/2ObqHDql8dX8CJi97oHxrjUcYtzKbbykPtVW9WB+poxI+NM2UIzsMgNCZTIf0AQwsjK5yMAqZw==", + "version": "13.3.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz", + "integrity": "sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==", "dev": true, "requires": { - "cliui": "^4.0.0", - "decamelize": "^1.2.0", + "cliui": "^5.0.0", "find-up": "^3.0.0", - "get-caller-file": "^1.0.1", - "os-locale": "^3.0.0", + "get-caller-file": "^2.0.1", "require-directory": "^2.1.1", - "require-main-filename": "^1.0.1", + "require-main-filename": "^2.0.0", "set-blocking": "^2.0.0", - "string-width": "^2.0.0", + "string-width": "^3.0.0", "which-module": "^2.0.0", - "y18n": "^3.2.1 || ^4.0.0", - "yargs-parser": "^11.1.1" + "y18n": "^4.0.0", + "yargs-parser": "^13.1.2" } }, "yargs-parser": { - "version": "11.1.1", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-11.1.1.tgz", - "integrity": "sha512-C6kB/WJDiaxONLJQnF8ccx9SEeoTTLek8RVbaOIsrAUS8VrBEXfmeSnCZxygc+XC2sNMBIwOOnfcxiynjHsVSQ==", + "version": "13.1.2", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz", + "integrity": "sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==", "dev": true, "requires": { "camelcase": "^5.0.0", diff --git a/package.json b/package.json index 36453769e6..021b11ff16 100644 --- a/package.json +++ b/package.json @@ -23,10 +23,10 @@ }, "types": "types/runtime/index.d.ts", "scripts": { - "test": "mocha --opts mocha.opts", + "test": "mocha --config .mocharc.js", "test:unit": "mocha --require sucrase/register --recursive src/**/__test__.ts", - "quicktest": "mocha --opts mocha.opts", - "precoverage": "c8 mocha --opts mocha.coverage.opts", + "quicktest": "mocha --config .mocharc.js", + "precoverage": "c8 mocha --config .mocharc.coverage.js", "coverage": "c8 report --reporter=text-lcov > coverage.lcov && c8 report --reporter=html", "codecov": "codecov", "precodecov": "npm run coverage", @@ -64,7 +64,7 @@ "@rollup/plugin-typescript": "^2.0.1", "@rollup/plugin-virtual": "^2.0.0", "@sveltejs/eslint-config": "github:sveltejs/eslint-config#v5.0.0", - "@types/mocha": "^5.2.7", + "@types/mocha": "^7.0.0", "@types/node": "^8.10.53", "@typescript-eslint/eslint-plugin": "^3.0.2", "@typescript-eslint/parser": "^3.0.2", @@ -83,7 +83,7 @@ "kleur": "^3.0.3", "locate-character": "^2.0.5", "magic-string": "^0.25.3", - "mocha": "^6.2.0", + "mocha": "^7.0.0", "periscopic": "^2.0.1", "puppeteer": "^2.1.1", "rollup": "^1.27.14", From 6ecc288d94e02c89d21c10cff852b82a9ab34f51 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 10 Sep 2020 12:42:20 -0700 Subject: [PATCH 56/94] Bump node-fetch from 2.6.0 to 2.6.1 (#5376) Bumps [node-fetch](https://github.com/bitinn/node-fetch) from 2.6.0 to 2.6.1. - [Release notes](https://github.com/bitinn/node-fetch/releases) - [Changelog](https://github.com/node-fetch/node-fetch/blob/master/docs/CHANGELOG.md) - [Commits](https://github.com/bitinn/node-fetch/compare/v2.6.0...v2.6.1) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package-lock.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index d3012bbf70..a19de0dba3 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2899,9 +2899,9 @@ } }, "node-fetch": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.0.tgz", - "integrity": "sha512-8dG4H5ujfvFiqDmVu9fQ5bOHUC15JMjMY/Zumv26oOvvVJjM67KF8koCWIabKQ1GJIa9r2mMZscBq/TbdOcmNA==", + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.1.tgz", + "integrity": "sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw==", "dev": true }, "node-modules-regexp": { From d201c5bfb3388259ffc3bb7f5cb717aa43293015 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 10 Sep 2020 12:42:32 -0700 Subject: [PATCH 57/94] Bump node-fetch from 2.6.0 to 2.6.1 in /site (#5377) Bumps [node-fetch](https://github.com/bitinn/node-fetch) from 2.6.0 to 2.6.1. - [Release notes](https://github.com/bitinn/node-fetch/releases) - [Changelog](https://github.com/node-fetch/node-fetch/blob/master/docs/CHANGELOG.md) - [Commits](https://github.com/bitinn/node-fetch/compare/v2.6.0...v2.6.1) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- site/package-lock.json | 6 +++--- site/package.json | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/site/package-lock.json b/site/package-lock.json index da6a8e809d..014535652a 100644 --- a/site/package-lock.json +++ b/site/package-lock.json @@ -2857,9 +2857,9 @@ } }, "node-fetch": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.0.tgz", - "integrity": "sha512-8dG4H5ujfvFiqDmVu9fQ5bOHUC15JMjMY/Zumv26oOvvVJjM67KF8koCWIabKQ1GJIa9r2mMZscBq/TbdOcmNA==", + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.1.tgz", + "integrity": "sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw==", "dev": true }, "node-pg-migrate": { diff --git a/site/package.json b/site/package.json index f760cd871d..b8b08c65e8 100644 --- a/site/package.json +++ b/site/package.json @@ -48,7 +48,7 @@ "esm": "^3.2.25", "jimp": "^0.8.0", "mocha": "^6.2.0", - "node-fetch": "^2.6.0", + "node-fetch": "^2.6.1", "node-pg-migrate": "^3.22.0", "npm-run-all": "^4.1.5", "rollup": "^2.26.10", From 4b59491ea4db972e45b7eff679e73db5857c0006 Mon Sep 17 00:00:00 2001 From: Th0rN13 Date: Fri, 11 Sep 2020 00:49:57 +0500 Subject: [PATCH 58/94] Fix: input type number warning in browsers (#4772) --- src/runtime/internal/dom.ts | 2 +- test/runtime/samples/binding-input-number/_config.js | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/runtime/internal/dom.ts b/src/runtime/internal/dom.ts index 7087336a6b..cc1996abdf 100644 --- a/src/runtime/internal/dom.ts +++ b/src/runtime/internal/dom.ts @@ -138,7 +138,7 @@ export function get_binding_group_value(group, __value, checked) { } export function to_number(value) { - return value === '' ? undefined : +value; + return value === '' ? null : +value; } export function time_ranges_to_array(ranges) { diff --git a/test/runtime/samples/binding-input-number/_config.js b/test/runtime/samples/binding-input-number/_config.js index 3c5919bc64..1a56a75c0c 100644 --- a/test/runtime/samples/binding-input-number/_config.js +++ b/test/runtime/samples/binding-input-number/_config.js @@ -35,14 +35,14 @@ export default {

number 44

`); - // empty string should be treated as undefined + // empty string should be treated as null input.value = ''; await input.dispatchEvent(event); - assert.equal(component.count, undefined); + assert.equal(component.count, null); assert.htmlEqual(target.innerHTML, ` -

undefined undefined

+

object null

`); } }; From daa1c390d5b24cfe381f72ad1552963da19935d0 Mon Sep 17 00:00:00 2001 From: Conduitry Date: Thu, 10 Sep 2020 15:52:25 -0400 Subject: [PATCH 59/94] update changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3227ac382c..63fafd21df 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,7 @@ ## Unreleased +* Use `null` rather than `undefined` for coerced bound value of `` ([#1701](https://github.com/sveltejs/svelte/issues/1701)) * Expose object of which slots have received content in `$$slots` ([#2106](https://github.com/sveltejs/svelte/issues/2106)) * Correctly disallow using lifecycle hooks after synchronous component initialisation ([#4259](https://github.com/sveltejs/svelte/issues/4259), [#4899](https://github.com/sveltejs/svelte/issues/4899)) * Re-throw an unhandled rejection when an `{#await}` block with no `{:catch}` gets a rejection ([#5129](https://github.com/sveltejs/svelte/issues/5129)) From dfb15a6a37ef7bd48e18a69d3b4dcad8690b32a4 Mon Sep 17 00:00:00 2001 From: Conduitry Date: Thu, 10 Sep 2020 15:56:27 -0400 Subject: [PATCH 60/94] fix lint --- test/runtime/samples/onmount-get-current-component/_config.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/runtime/samples/onmount-get-current-component/_config.js b/test/runtime/samples/onmount-get-current-component/_config.js index 727f8a2d8e..8f9529de5c 100644 --- a/test/runtime/samples/onmount-get-current-component/_config.js +++ b/test/runtime/samples/onmount-get-current-component/_config.js @@ -1,4 +1,4 @@ export default { skip_if_ssr: true, - html: `1`, + html: `1` }; From 5bf2d6fadfc14972d35adfef79ef21c21175771f Mon Sep 17 00:00:00 2001 From: Conduitry Date: Thu, 10 Sep 2020 15:56:35 -0400 Subject: [PATCH 61/94] -> v3.25.0 --- CHANGELOG.md | 2 +- package-lock.json | 2 +- package.json | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 63fafd21df..21a9441c41 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,6 @@ # Svelte changelog -## Unreleased +## 3.25.0 * Use `null` rather than `undefined` for coerced bound value of `` ([#1701](https://github.com/sveltejs/svelte/issues/1701)) * Expose object of which slots have received content in `$$slots` ([#2106](https://github.com/sveltejs/svelte/issues/2106)) diff --git a/package-lock.json b/package-lock.json index a19de0dba3..34189b3f63 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "svelte", - "version": "3.24.1", + "version": "3.25.0", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index 021b11ff16..59f35dfa80 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "svelte", - "version": "3.24.1", + "version": "3.25.0", "description": "Cybernetically enhanced web apps", "module": "index.mjs", "main": "index", From 8271658fa8575bf30e4db50d3c1fc1ef9da50691 Mon Sep 17 00:00:00 2001 From: Conduitry Date: Thu, 10 Sep 2020 19:54:50 -0400 Subject: [PATCH 62/94] site: revert to sapper@0.27 --- site/package-lock.json | 15 +++------------ site/package.json | 2 +- 2 files changed, 4 insertions(+), 13 deletions(-) diff --git a/site/package-lock.json b/site/package-lock.json index 014535652a..1dbad52271 100644 --- a/site/package-lock.json +++ b/site/package-lock.json @@ -3597,25 +3597,16 @@ } }, "sapper": { - "version": "0.28.6", - "resolved": "https://registry.npmjs.org/sapper/-/sapper-0.28.6.tgz", - "integrity": "sha512-PLCZXBcXcL2ISBh+CqoUxcT0MwMnA8N71UDNhQig0Em5Z8vqg+g2jpKfYSnnyxqB5Plwc9LipN5ZJr42Vs4hXg==", + "version": "0.27.16", + "resolved": "https://registry.npmjs.org/sapper/-/sapper-0.27.16.tgz", + "integrity": "sha512-q8dohkbhga6xO+0a8h84odFyoilQ0D0vJtF8NHra/DQmSeN2R2MXUfwhw3EyvLms3T1x8H3v+qw642Qf5JXA9g==", "dev": true, "requires": { "html-minifier": "^4.0.0", "http-link-header": "^1.0.2", "shimport": "^1.0.1", - "source-map": "^0.6.1", "sourcemap-codec": "^1.4.6", "string-hash": "^1.1.3" - }, - "dependencies": { - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - } } }, "sax": { diff --git a/site/package.json b/site/package.json index b8b08c65e8..79ba2e6fed 100644 --- a/site/package.json +++ b/site/package.json @@ -54,7 +54,7 @@ "rollup": "^2.26.10", "rollup-plugin-svelte": "^6.0.0", "rollup-plugin-terser": "^7.0.0", - "sapper": "^0.28.6", + "sapper": "^0.27.16", "shelljs": "^0.8.3", "svelte": "^3.12.0" }, From d9364c4e9cf1d0c65f6c1bd74705639f66f24626 Mon Sep 17 00:00:00 2001 From: Ben McCann <322311+benmccann@users.noreply.github.com> Date: Thu, 10 Sep 2020 16:55:41 -0700 Subject: [PATCH 63/94] site: standardize building command (#5380) --- site/Makefile | 2 +- site/README.md | 2 +- site/package.json | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/site/Makefile b/site/Makefile index 6fd08fd8ee..48b3e972e6 100644 --- a/site/Makefile +++ b/site/Makefile @@ -9,7 +9,7 @@ sapper: @echo "\n~> updating template & contributors list" @npm run update @echo "\n~> building Sapper app" - @npm run sapper + @npm run build docker: diff --git a/site/README.md b/site/README.md index 892b8e1249..7d8adbd6c5 100644 --- a/site/README.md +++ b/site/README.md @@ -47,7 +47,7 @@ In order for the REPL's GitHub integration to work properly when running locally ## Building the site -To build the website, run `npm run sapper`. The output can be found in `__sapper__/build`. +To build the website, run `npm run build`. The output can be found in `__sapper__/build`. ## Testing diff --git a/site/package.json b/site/package.json index 79ba2e6fed..d1972c09d2 100644 --- a/site/package.json +++ b/site/package.json @@ -6,7 +6,7 @@ "dev": "npm run copy-workers && sapper dev", "copy-workers": "node scripts/copy-workers.js", "migrate": "node-pg-migrate -r dotenv/config", - "sapper": "npm run copy-workers && sapper build --legacy", + "build": "npm run copy-workers && sapper build --legacy", "update": "node scripts/update_template.js && node scripts/get-contributors.js && node scripts/update_whos_using.js", "start": "node __sapper__/build", "test": "mocha -r esm test/**", From 3255f8b662defe4c655ea47e2fba1d67ed6b8362 Mon Sep 17 00:00:00 2001 From: lonevox <38600896+lonevox@users.noreply.github.com> Date: Sat, 12 Sep 2020 09:51:59 +1200 Subject: [PATCH 64/94] site: change "on to" to "onto" in tutorial 03 (#5386) --- site/content/tutorial/03-props/03-spread-props/text.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/site/content/tutorial/03-props/03-spread-props/text.md b/site/content/tutorial/03-props/03-spread-props/text.md index aa7d4dc831..1480ad8065 100644 --- a/site/content/tutorial/03-props/03-spread-props/text.md +++ b/site/content/tutorial/03-props/03-spread-props/text.md @@ -2,10 +2,10 @@ title: Spread props --- -If you have an object of properties, you can 'spread' them on to a component instead of specifying each one: +If you have an object of properties, you can 'spread' them onto a component instead of specifying each one: ```html ``` -> Conversely, if you need to reference all the props that were passed into a component, including ones that weren't declared with `export`, you can do so by accessing `$$props` directly. It's not generally recommended, as it's difficult for Svelte to optimise, but it's useful in rare cases. \ No newline at end of file +> Conversely, if you need to reference all the props that were passed into a component, including ones that weren't declared with `export`, you can do so by accessing `$$props` directly. It's not generally recommended, as it's difficult for Svelte to optimise, but it's useful in rare cases. From 04498769b5a835dcf6f0ae59f5e194fabf1b2c2a Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Sun, 13 Sep 2020 09:00:16 -0400 Subject: [PATCH 65/94] bump site-kit version --- site/package-lock.json | 6 +++--- site/package.json | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/site/package-lock.json b/site/package-lock.json index 1dbad52271..93932806f8 100644 --- a/site/package-lock.json +++ b/site/package-lock.json @@ -1449,9 +1449,9 @@ } }, "@sveltejs/site-kit": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/@sveltejs/site-kit/-/site-kit-1.2.4.tgz", - "integrity": "sha512-W+/PthWX4R8UvKr+IyWIITGoY3cl/54ePZr3dU9ZlyP9r/weEvvKDBvjmW8tAKQFRfbxyySmXUxEGBoPhF8XAA==", + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/@sveltejs/site-kit/-/site-kit-1.2.5.tgz", + "integrity": "sha512-fA1YWW4tYOxPRVocx+jF4S2LGamku8xeKx/+J5aY7ZCbwuo/c4VF+T0K7WuQRI8U6Dw3pJqdiCra+xH4TnCGRw==", "dev": true, "requires": { "@sindresorhus/slugify": "^0.9.1", diff --git a/site/package.json b/site/package.json index d1972c09d2..6e00636476 100644 --- a/site/package.json +++ b/site/package.json @@ -41,7 +41,7 @@ "@rollup/plugin-node-resolve": "^9.0.0", "@rollup/plugin-replace": "^2.2.0", "@sindresorhus/slugify": "^0.9.1", - "@sveltejs/site-kit": "^1.2.4", + "@sveltejs/site-kit": "^1.2.5", "@sveltejs/svelte-repl": "^0.2.1", "degit": "^2.1.4", "dotenv": "^8.1.0", From 7900e3eafac7a59a9d0af37069faf3e3b720918c Mon Sep 17 00:00:00 2001 From: Tan Li Hau Date: Tue, 15 Sep 2020 20:32:55 +0800 Subject: [PATCH 66/94] fix style scoping with > * (#5400) --- CHANGELOG.md | 4 ++ src/compiler/compile/css/Selector.ts | 4 +- .../_config.js | 45 +++++++++++++++++++ .../expected.css | 1 + .../input.svelte | 23 ++++++++++ 5 files changed, 75 insertions(+), 2 deletions(-) create mode 100644 test/css/samples/unused-selector-child-combinator/_config.js create mode 100644 test/css/samples/unused-selector-child-combinator/expected.css create mode 100644 test/css/samples/unused-selector-child-combinator/input.svelte diff --git a/CHANGELOG.md b/CHANGELOG.md index 21a9441c41..d1481dd850 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Svelte changelog +## Unreleased + +* Fix scoping of styles involving child selector and `*` ([#5370](https://github.com/sveltejs/svelte/issues/5370)) + ## 3.25.0 * Use `null` rather than `undefined` for coerced bound value of `` ([#1701](https://github.com/sveltejs/svelte/issues/1701)) diff --git a/src/compiler/compile/css/Selector.ts b/src/compiler/compile/css/Selector.ts index 6bc046c93e..e3e1fa96bb 100644 --- a/src/compiler/compile/css/Selector.ts +++ b/src/compiler/compile/css/Selector.ts @@ -152,7 +152,7 @@ function apply_selector(blocks: Block[], node: Element, stack: Element[], to_enc if (!block) return false; if (!node) { - return blocks.every(block => block.global); + return block.global && blocks.every(block => block.global); } switch (block_might_apply_to_node(block, node)) { @@ -208,7 +208,7 @@ function apply_selector(blocks: Block[], node: Element, stack: Element[], to_enc return true; } -function block_might_apply_to_node(block, node): BlockAppliesToNode { +function block_might_apply_to_node(block: Block, node: Element): BlockAppliesToNode { let i = block.selectors.length; while (i--) { diff --git a/test/css/samples/unused-selector-child-combinator/_config.js b/test/css/samples/unused-selector-child-combinator/_config.js new file mode 100644 index 0000000000..becf382147 --- /dev/null +++ b/test/css/samples/unused-selector-child-combinator/_config.js @@ -0,0 +1,45 @@ +export default { + warnings: [ + { + code: "css-unused-selector", + message: 'Unused CSS selector "article > *"', + frame: ` + 1: + +
+

+ Svelte REPLs are svelte. +

+
\ No newline at end of file From 46d423d9dbf647e7d8e6d408937312ba694708c1 Mon Sep 17 00:00:00 2001 From: Tan Li Hau Date: Tue, 15 Sep 2020 20:39:57 +0800 Subject: [PATCH 67/94] fix css specificity for child combinator (#5399) --- CHANGELOG.md | 1 + src/compiler/compile/css/Selector.ts | 8 +++----- test/css/samples/child-combinator/expected.css | 1 + test/css/samples/child-combinator/input.svelte | 14 ++++++++++++++ 4 files changed, 19 insertions(+), 5 deletions(-) create mode 100644 test/css/samples/child-combinator/expected.css create mode 100644 test/css/samples/child-combinator/input.svelte diff --git a/CHANGELOG.md b/CHANGELOG.md index d1481dd850..ae228a3b0a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,7 @@ ## Unreleased +* Fix specificity of certain styles involving a child selector ([#4795](https://github.com/sveltejs/svelte/issues/4795)) * Fix scoping of styles involving child selector and `*` ([#5370](https://github.com/sveltejs/svelte/issues/5370)) ## 3.25.0 diff --git a/src/compiler/compile/css/Selector.ts b/src/compiler/compile/css/Selector.ts index e3e1fa96bb..d18a7e7ba6 100644 --- a/src/compiler/compile/css/Selector.ts +++ b/src/compiler/compile/css/Selector.ts @@ -65,9 +65,8 @@ export default class Selector { transform(code: MagicString, attr: string, max_amount_class_specificity_increased: number) { const amount_class_specificity_to_increase = max_amount_class_specificity_increased - this.blocks.filter(block => block.should_encapsulate).length; - attr = attr.repeat(amount_class_specificity_to_increase + 1); - function encapsulate_block(block: Block) { + function encapsulate_block(block: Block, attr: string) { let i = block.selectors.length; while (i--) { @@ -89,15 +88,14 @@ export default class Selector { } } - this.blocks.forEach((block) => { + this.blocks.forEach((block, index) => { if (block.global) { const selector = block.selectors[0]; const first = selector.children[0]; const last = selector.children[selector.children.length - 1]; code.remove(selector.start, first.start).remove(last.end, selector.end); } - - if (block.should_encapsulate) encapsulate_block(block); + if (block.should_encapsulate) encapsulate_block(block, index === this.blocks.length - 1 ? attr.repeat(amount_class_specificity_to_increase + 1) : attr); }); } diff --git a/test/css/samples/child-combinator/expected.css b/test/css/samples/child-combinator/expected.css new file mode 100644 index 0000000000..5d50ae16d7 --- /dev/null +++ b/test/css/samples/child-combinator/expected.css @@ -0,0 +1 @@ +main.svelte-xyz button.svelte-xyz.svelte-xyz{background-color:red}main.svelte-xyz div.svelte-xyz>button.svelte-xyz{background-color:blue} \ No newline at end of file diff --git a/test/css/samples/child-combinator/input.svelte b/test/css/samples/child-combinator/input.svelte new file mode 100644 index 0000000000..9d5d8d27e0 --- /dev/null +++ b/test/css/samples/child-combinator/input.svelte @@ -0,0 +1,14 @@ + +
+
+ +
+
\ No newline at end of file From 338cf877bcd8b53f8418cda86b5685e5cb91b28e Mon Sep 17 00:00:00 2001 From: Tan Li Hau Date: Tue, 15 Sep 2020 20:49:35 +0800 Subject: [PATCH 68/94] maintain context for transition (#5392) --- CHANGELOG.md | 1 + src/compiler/compile/nodes/Transition.ts | 2 +- .../render_dom/wrappers/Element/index.ts | 4 ++++ .../transition-js-args-dynamic/_config.js | 15 +++++++++++++++ .../transition-js-args-dynamic/main.svelte | 17 +++++++++++++++++ 5 files changed, 38 insertions(+), 1 deletion(-) create mode 100644 test/runtime/samples/transition-js-args-dynamic/_config.js create mode 100644 test/runtime/samples/transition-js-args-dynamic/main.svelte diff --git a/CHANGELOG.md b/CHANGELOG.md index ae228a3b0a..b4ffb19d3c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ ## Unreleased * Fix specificity of certain styles involving a child selector ([#4795](https://github.com/sveltejs/svelte/issues/4795)) +* Fix transitions that are parameterised with stores ([#5244](https://github.com/sveltejs/svelte/issues/5244)) * Fix scoping of styles involving child selector and `*` ([#5370](https://github.com/sveltejs/svelte/issues/5370)) ## 3.25.0 diff --git a/src/compiler/compile/nodes/Transition.ts b/src/compiler/compile/nodes/Transition.ts index a680fde46e..983a6ee6c7 100644 --- a/src/compiler/compile/nodes/Transition.ts +++ b/src/compiler/compile/nodes/Transition.ts @@ -34,7 +34,7 @@ export default class Transition extends Node { } this.expression = info.expression - ? new Expression(component, this, scope, info.expression, true) + ? new Expression(component, this, scope, info.expression) : null; } } diff --git a/src/compiler/compile/render_dom/wrappers/Element/index.ts b/src/compiler/compile/render_dom/wrappers/Element/index.ts index 2e35f0271f..f740560bcd 100644 --- a/src/compiler/compile/render_dom/wrappers/Element/index.ts +++ b/src/compiler/compile/render_dom/wrappers/Element/index.ts @@ -868,6 +868,10 @@ export default class ElementWrapper extends Wrapper { block.chunks.destroy.push(b`if (detaching && ${outro_name}) ${outro_name}.end();`); } } + + if ((intro && intro.expression && intro.expression.dependencies.size) || (outro && outro.expression && outro.expression.dependencies.size)) { + block.maintain_context = true; + } } add_animation(block: Block) { diff --git a/test/runtime/samples/transition-js-args-dynamic/_config.js b/test/runtime/samples/transition-js-args-dynamic/_config.js new file mode 100644 index 0000000000..513a17486a --- /dev/null +++ b/test/runtime/samples/transition-js-args-dynamic/_config.js @@ -0,0 +1,15 @@ +export default { + test({ assert, component, target, window, raf }) { + component.visible = true; + + const div = target.querySelector('div'); + + assert.equal(div.value, 0); + + raf.tick(200); + + div.value = 'test'; + component.visible = false; + assert.equal(div.value, 'test'); + } +}; diff --git a/test/runtime/samples/transition-js-args-dynamic/main.svelte b/test/runtime/samples/transition-js-args-dynamic/main.svelte new file mode 100644 index 0000000000..1bb149de32 --- /dev/null +++ b/test/runtime/samples/transition-js-args-dynamic/main.svelte @@ -0,0 +1,17 @@ + + +{#if visible} +
+{/if} \ No newline at end of file From 1ce6ac5d483c12d42096370947ff7ae0bccb2c13 Mon Sep 17 00:00:00 2001 From: Tan Li Hau Date: Tue, 15 Sep 2020 21:03:09 +0800 Subject: [PATCH 69/94] fix destructuring to get multiple stores (#5390) --- CHANGELOG.md | 1 + src/compiler/compile/Component.ts | 10 +++------- src/compiler/compile/render_dom/Renderer.ts | 6 ++++-- src/compiler/compile/render_dom/invalidate.ts | 20 +++++++++++-------- .../_config.js | 3 +++ .../main.svelte | 16 +++++++++++++++ .../main.svelte | 3 +++ .../main.svelte | 15 +++++++++----- .../samples/store-resubscribe-c/_config.js | 3 +++ .../samples/store-resubscribe-c/main.svelte | 16 +++++++++++++++ 10 files changed, 71 insertions(+), 22 deletions(-) create mode 100644 test/runtime/samples/reactive-assignment-in-complex-declaration-with-store/_config.js create mode 100644 test/runtime/samples/reactive-assignment-in-complex-declaration-with-store/main.svelte create mode 100644 test/runtime/samples/store-resubscribe-c/_config.js create mode 100644 test/runtime/samples/store-resubscribe-c/main.svelte diff --git a/CHANGELOG.md b/CHANGELOG.md index b4ffb19d3c..2c9922a086 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ * Fix specificity of certain styles involving a child selector ([#4795](https://github.com/sveltejs/svelte/issues/4795)) * Fix transitions that are parameterised with stores ([#5244](https://github.com/sveltejs/svelte/issues/5244)) * Fix scoping of styles involving child selector and `*` ([#5370](https://github.com/sveltejs/svelte/issues/5370)) +* Fix destructuring which reassigns stores ([#5388](https://github.com/sveltejs/svelte/issues/5388)) ## 3.25.0 diff --git a/src/compiler/compile/Component.ts b/src/compiler/compile/Component.ts index ed2b10e404..078ecb8869 100644 --- a/src/compiler/compile/Component.ts +++ b/src/compiler/compile/Component.ts @@ -947,12 +947,6 @@ export default class Component { const variable = component.var_lookup.get(name); if (variable.export_name && variable.writable) { - const insert = variable.subscribable - ? get_insert(variable) - : null; - - parent[key].splice(index + 1, 0, insert); - declarator.id = { type: 'ObjectPattern', properties: [{ @@ -973,7 +967,9 @@ export default class Component { }; declarator.init = x`$$props`; - } else if (variable.subscribable) { + } + + if (variable.subscribable && declarator.init) { const insert = get_insert(variable); parent[key].splice(index + 1, 0, ...insert); } diff --git a/src/compiler/compile/render_dom/Renderer.ts b/src/compiler/compile/render_dom/Renderer.ts index 6fc026de23..0990281d91 100644 --- a/src/compiler/compile/render_dom/Renderer.ts +++ b/src/compiler/compile/render_dom/Renderer.ts @@ -166,12 +166,14 @@ export default class Renderer { return member; } - invalidate(name: string, value?) { + invalidate(name: string, value?, main_execution_context: boolean = false) { const variable = this.component.var_lookup.get(name); const member = this.context_lookup.get(name); if (variable && (variable.subscribable && (variable.reassigned || variable.export_name))) { - return x`${`$$subscribe_${name}`}($$invalidate(${member.index}, ${value || name}))`; + return main_execution_context + ? x`${`$$subscribe_${name}`}(${value || name})` + : x`${`$$subscribe_${name}`}($$invalidate(${member.index}, ${value || name}))`; } if (name[0] === '$' && name[1] !== '$') { diff --git a/src/compiler/compile/render_dom/invalidate.ts b/src/compiler/compile/render_dom/invalidate.ts index 28e4f37e3f..c7d9759ccd 100644 --- a/src/compiler/compile/render_dom/invalidate.ts +++ b/src/compiler/compile/render_dom/invalidate.ts @@ -31,10 +31,9 @@ export function invalidate(renderer: Renderer, scope: Scope, node: Node, names: function get_invalidated(variable: Var, node?: Expression) { if (main_execution_context && !variable.subscribable && variable.name[0] !== '$') { - return node || x`${variable.name}`; + return node; } - - return renderer.invalidate(variable.name); + return renderer.invalidate(variable.name, undefined, main_execution_context); } if (head) { @@ -44,12 +43,15 @@ export function invalidate(renderer: Renderer, scope: Scope, node: Node, names: return get_invalidated(head, node); } else { const is_store_value = head.name[0] === '$' && head.name[1] !== '$'; - const extra_args = tail.map(variable => get_invalidated(variable)); + const extra_args = tail.map(variable => get_invalidated(variable)).filter(Boolean); const pass_value = ( - extra_args.length > 0 || - (node.type === 'AssignmentExpression' && node.left.type !== 'Identifier') || - (node.type === 'UpdateExpression' && (!node.prefix || node.argument.type !== 'Identifier')) + !main_execution_context && + ( + extra_args.length > 0 || + (node.type === 'AssignmentExpression' && node.left.type !== 'Identifier') || + (node.type === 'UpdateExpression' && (!node.prefix || node.argument.type !== 'Identifier')) + ) ); if (pass_value) { @@ -63,7 +65,9 @@ export function invalidate(renderer: Renderer, scope: Scope, node: Node, names: ? x`@set_store_value(${head.name.slice(1)}, ${node}, ${extra_args})` : !main_execution_context ? x`$$invalidate(${renderer.context_lookup.get(head.name).index}, ${node}, ${extra_args})` - : node; + : extra_args.length + ? [node, ...extra_args] + : node; if (head.subscribable && head.reassigned) { const subscribe = `$$subscribe_${head.name}`; diff --git a/test/runtime/samples/reactive-assignment-in-complex-declaration-with-store/_config.js b/test/runtime/samples/reactive-assignment-in-complex-declaration-with-store/_config.js new file mode 100644 index 0000000000..e74cea70fe --- /dev/null +++ b/test/runtime/samples/reactive-assignment-in-complex-declaration-with-store/_config.js @@ -0,0 +1,3 @@ +export default { + html: `

2 2 xxx 5 6

` +}; \ No newline at end of file diff --git a/test/runtime/samples/reactive-assignment-in-complex-declaration-with-store/main.svelte b/test/runtime/samples/reactive-assignment-in-complex-declaration-with-store/main.svelte new file mode 100644 index 0000000000..5ad442e1da --- /dev/null +++ b/test/runtime/samples/reactive-assignment-in-complex-declaration-with-store/main.svelte @@ -0,0 +1,16 @@ + + +

{foo} {$eid} {u.name} {v} {$w}

diff --git a/test/runtime/samples/reactive-assignment-in-declaration/main.svelte b/test/runtime/samples/reactive-assignment-in-declaration/main.svelte index 8aa05964dd..edac4427bb 100644 --- a/test/runtime/samples/reactive-assignment-in-declaration/main.svelte +++ b/test/runtime/samples/reactive-assignment-in-declaration/main.svelte @@ -1,6 +1,9 @@

{foo} {bar}

diff --git a/test/runtime/samples/reactive-assignment-in-for-loop-head/main.svelte b/test/runtime/samples/reactive-assignment-in-for-loop-head/main.svelte index 1c24f364ac..b007f6fe8b 100644 --- a/test/runtime/samples/reactive-assignment-in-for-loop-head/main.svelte +++ b/test/runtime/samples/reactive-assignment-in-for-loop-head/main.svelte @@ -1,9 +1,14 @@

{foo1} {foo2}

diff --git a/test/runtime/samples/store-resubscribe-c/_config.js b/test/runtime/samples/store-resubscribe-c/_config.js new file mode 100644 index 0000000000..80b4fa702d --- /dev/null +++ b/test/runtime/samples/store-resubscribe-c/_config.js @@ -0,0 +1,3 @@ +export default { + html: `31 42` +}; diff --git a/test/runtime/samples/store-resubscribe-c/main.svelte b/test/runtime/samples/store-resubscribe-c/main.svelte new file mode 100644 index 0000000000..c52a5402bd --- /dev/null +++ b/test/runtime/samples/store-resubscribe-c/main.svelte @@ -0,0 +1,16 @@ + + +{$store1} +{$store2} From 87ed0b2f427fa6552feafcf05c39c40e27ec80fb Mon Sep 17 00:00:00 2001 From: Tan Li Hau Date: Tue, 15 Sep 2020 21:13:50 +0800 Subject: [PATCH 70/94] fix await stuck indefinitely without catch (#5402) --- CHANGELOG.md | 1 + src/runtime/internal/await_block.ts | 6 +++--- test/runtime/samples/await-without-catch/_config.js | 1 + 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2c9922a086..bc8272f84a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,7 @@ * Fix transitions that are parameterised with stores ([#5244](https://github.com/sveltejs/svelte/issues/5244)) * Fix scoping of styles involving child selector and `*` ([#5370](https://github.com/sveltejs/svelte/issues/5370)) * Fix destructuring which reassigns stores ([#5388](https://github.com/sveltejs/svelte/issues/5388)) +* Fix `{#await}`s with no `{:catch}` getting stuck unresolved if the promise rejects ([#5401](https://github.com/sveltejs/svelte/issues/5401)) ## 3.25.0 diff --git a/src/runtime/internal/await_block.ts b/src/runtime/internal/await_block.ts index 3821520837..4b7ca6fd21 100644 --- a/src/runtime/internal/await_block.ts +++ b/src/runtime/internal/await_block.ts @@ -59,12 +59,12 @@ export function handle_promise(promise, info) { update(info.then, 1, info.value, value); set_current_component(null); }, error => { - if (!info.hasCatch) { - throw error; - } set_current_component(current_component); update(info.catch, 2, info.error, error); set_current_component(null); + if (!info.hasCatch) { + throw error; + } }); // if we previously had a then/catch block, destroy it diff --git a/test/runtime/samples/await-without-catch/_config.js b/test/runtime/samples/await-without-catch/_config.js index 2030ed7949..1b7da5c0be 100644 --- a/test/runtime/samples/await-without-catch/_config.js +++ b/test/runtime/samples/await-without-catch/_config.js @@ -39,6 +39,7 @@ export default { }) .catch((err) => { assert.equal(err.message, 'this error should be thrown'); + assert.htmlEqual(target.innerHTML, ''); }); } }; \ No newline at end of file From ccf0bcf4692742457be872e54382b7fc5ca63c23 Mon Sep 17 00:00:00 2001 From: milahu Date: Tue, 15 Sep 2020 15:17:43 +0200 Subject: [PATCH 71/94] merge mocharc.coverage into mocharc (#5385) --- .mocharc.coverage.js | 10 ---------- .mocharc.js | 10 ++++++++++ package.json | 6 +++--- 3 files changed, 13 insertions(+), 13 deletions(-) delete mode 100644 .mocharc.coverage.js diff --git a/.mocharc.coverage.js b/.mocharc.coverage.js deleted file mode 100644 index 91c93518ca..0000000000 --- a/.mocharc.coverage.js +++ /dev/null @@ -1,10 +0,0 @@ -module.exports = Object.assign( - {}, - require('./mocharc.js'), - { - fullTrace: true, - require: [ - 'source-map-support/register' - ] - } -); diff --git a/.mocharc.js b/.mocharc.js index 6159fd937f..de41cdd353 100644 --- a/.mocharc.js +++ b/.mocharc.js @@ -3,3 +3,13 @@ module.exports = { 'test/test.js' ] }; + +// add coverage options when running 'npx c8 mocha' +if (process.env.NODE_V8_COVERAGE) { + Object.assign(module.exports, { + fullTrace: true, + require: [ + 'source-map-support/register' + ] + }); +} diff --git a/package.json b/package.json index 59f35dfa80..8f8ad32911 100644 --- a/package.json +++ b/package.json @@ -23,10 +23,10 @@ }, "types": "types/runtime/index.d.ts", "scripts": { - "test": "mocha --config .mocharc.js", + "test": "mocha", "test:unit": "mocha --require sucrase/register --recursive src/**/__test__.ts", - "quicktest": "mocha --config .mocharc.js", - "precoverage": "c8 mocha --config .mocharc.coverage.js", + "quicktest": "mocha", + "precoverage": "c8 mocha", "coverage": "c8 report --reporter=text-lcov > coverage.lcov && c8 report --reporter=html", "codecov": "codecov", "precodecov": "npm run coverage", From 660114325540e6bb06eec57ae39d743c408ef09e Mon Sep 17 00:00:00 2001 From: Conduitry Date: Tue, 15 Sep 2020 09:31:37 -0400 Subject: [PATCH 72/94] -> v3.25.1 --- CHANGELOG.md | 2 +- package-lock.json | 2 +- package.json | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index bc8272f84a..9569b4ff7b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,6 @@ # Svelte changelog -## Unreleased +## 3.25.1 * Fix specificity of certain styles involving a child selector ([#4795](https://github.com/sveltejs/svelte/issues/4795)) * Fix transitions that are parameterised with stores ([#5244](https://github.com/sveltejs/svelte/issues/5244)) diff --git a/package-lock.json b/package-lock.json index 34189b3f63..d1ec8d275f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "svelte", - "version": "3.25.0", + "version": "3.25.1", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index 8f8ad32911..20325b4fbf 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "svelte", - "version": "3.25.0", + "version": "3.25.1", "description": "Cybernetically enhanced web apps", "module": "index.mjs", "main": "index", From 5f422d8ddbcdb8cebc18f7a66871f24d1fc02108 Mon Sep 17 00:00:00 2001 From: infuzz <39411241+infuzz@users.noreply.github.com> Date: Tue, 15 Sep 2020 17:49:07 +0200 Subject: [PATCH 73/94] Link to more video courses in FAQ (#5396) Co-authored-by: Ben McCann <322311+benmccann@users.noreply.github.com> --- site/content/faq/200-are-there-any-video-courses.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/site/content/faq/200-are-there-any-video-courses.md b/site/content/faq/200-are-there-any-video-courses.md index 1a70cdfcf5..97e0e9d808 100644 --- a/site/content/faq/200-are-there-any-video-courses.md +++ b/site/content/faq/200-are-there-any-video-courses.md @@ -6,9 +6,9 @@ Rich Harris, the creator of Svelte, taught a course: - [Frontend Masters](https://frontendmasters.com/courses/svelte/) -There are also a couple of third-party courses: +There are also a number of third-party courses: -- [Egghead](https://egghead.io/playlists/getting-started-with-svelte-3-05a8541a) -- [Udemy](https://www.udemy.com/sveltejs-the-complete-guide/) +- [Egghead](https://egghead.io/browse/frameworks/svelte) +- [Udemy](https://www.udemy.com/courses/search/?q=sveltejs+svelte) Note that Udemy very frequently has discounts over 90%. From bd2175b67b1b1c3a7a89003aab1a9cd838c649f5 Mon Sep 17 00:00:00 2001 From: Shriji Date: Tue, 15 Sep 2020 21:23:46 +0530 Subject: [PATCH 74/94] Add list of books to FAQ (#5404) --- site/content/faq/250-are-there-any-books.md | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 site/content/faq/250-are-there-any-books.md diff --git a/site/content/faq/250-are-there-any-books.md b/site/content/faq/250-are-there-any-books.md new file mode 100644 index 0000000000..80870428ec --- /dev/null +++ b/site/content/faq/250-are-there-any-books.md @@ -0,0 +1,9 @@ +--- +question: Are there any books? +--- + +There are a few books: + +- [Svelte Handbook](https://flaviocopes.com/page/download-svelte-handbook/) by Flavio Copes +- [Svelte 3 Up and Running](https://www.amazon.com/dp/B08D6T6BKS/) by Alessandro Segala +- [Svelte and Sapper in Action](https://www.manning.com/books/svelte-and-sapper-in-action) by R. Mark Volkmann From 5f938535a1a89232a322fe013bc6dc98c5a3fc67 Mon Sep 17 00:00:00 2001 From: Rohan Kokane Date: Tue, 15 Sep 2020 21:24:42 +0530 Subject: [PATCH 75/94] Fix scrollbar being hidden by header on site (#5342) --- site/src/routes/_layout.svelte | 1 - site/src/routes/repl/[id]/index.svelte | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/site/src/routes/_layout.svelte b/site/src/routes/_layout.svelte index 07445de0a0..55f4861880 100644 --- a/site/src/routes/_layout.svelte +++ b/site/src/routes/_layout.svelte @@ -62,7 +62,6 @@ From 6c8bd6e5aa322b34911d0fedac79447c1ad4badd Mon Sep 17 00:00:00 2001 From: Cal Jacobson Date: Sun, 20 Sep 2020 23:49:18 -0400 Subject: [PATCH 80/94] Include link to VS Code extension in tutorial (#5231) --- site/content/tutorial/01-introduction/07-making-an-app/text.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/site/content/tutorial/01-introduction/07-making-an-app/text.md b/site/content/tutorial/01-introduction/07-making-an-app/text.md index 4d044272b5..d75a9a626c 100644 --- a/site/content/tutorial/01-introduction/07-making-an-app/text.md +++ b/site/content/tutorial/01-introduction/07-making-an-app/text.md @@ -13,7 +13,7 @@ First, you'll need to integrate Svelte with a build tool. There are officially m Don't worry if you're relatively new to web development and haven't used these tools before. We've prepared a simple step-by-step guide, [Svelte for new developers](blog/svelte-for-new-developers), which walks you through the process. -You'll also want to configure your text editor to treat `.svelte` files the same as `.html` for the sake of syntax highlighting. [Read this guide to learn how](blog/setting-up-your-editor). +You'll also want to configure your text editor. If you're using VS Code, install the [Svelte extension](https://marketplace.visualstudio.com/items?itemName=svelte.svelte-vscode), otherwise follow [this guide](blog/setting-up-your-editor) to configure your text editor to treat `.svelte` files the same as `.html` for the sake of syntax highlighting. Then, once you've got your project set up, using Svelte components is easy. The compiler turns each component into a regular JavaScript class — just import it and instantiate with `new`: From e867a4de330e37be46370b036ac817d436985cd0 Mon Sep 17 00:00:00 2001 From: Conduitry Date: Tue, 22 Sep 2020 08:51:22 -0400 Subject: [PATCH 81/94] -> v3.26.0 --- CHANGELOG.md | 2 +- package-lock.json | 2 +- package.json | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ad33840527..3347052e75 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,6 @@ # Svelte changelog -## Unreleased +## 3.26.0 * Support `use:obj.method` as actions ([#3935](https://github.com/sveltejs/svelte/issues/3935)) * Support `_` as numeric separator ([#5407](https://github.com/sveltejs/svelte/issues/5407)) diff --git a/package-lock.json b/package-lock.json index 2e2a95b362..6ea2f97a27 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "svelte", - "version": "3.25.1", + "version": "3.26.0", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index 7ebb41fdfb..6d558f35fc 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "svelte", - "version": "3.25.1", + "version": "3.26.0", "description": "Cybernetically enhanced web apps", "module": "index.mjs", "main": "index", From 4c135b0b8d7bc4cd6c47b2ea96cb3fb9e62165e7 Mon Sep 17 00:00:00 2001 From: Simon H <5968653+dummdidumm@users.noreply.github.com> Date: Wed, 23 Sep 2020 01:24:13 +0200 Subject: [PATCH 82/94] Update editor recommendations of old blog post (#5434) --- .../blog/2019-04-15-setting-up-your-editor.md | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/site/content/blog/2019-04-15-setting-up-your-editor.md b/site/content/blog/2019-04-15-setting-up-your-editor.md index b80223d820..fb8287d0cb 100644 --- a/site/content/blog/2019-04-15-setting-up-your-editor.md +++ b/site/content/blog/2019-04-15-setting-up-your-editor.md @@ -30,7 +30,9 @@ To treat `*.svelte` files as HTML, open *__Edit → Config...__* and add the fol ## Vim/Neovim -To treat all `*.svelte` files as HTML, add the following line to your `init.vim`: +You can use the [coc-svelte extension](https://github.com/coc-extensions/coc-svelte) which utilises the official language-server. + +As an alternative you can treat all `*.svelte` files as HTML. Add the following line to your `init.vim`: ``` au! BufNewFile,BufRead *.svelte set ft=html @@ -50,13 +52,7 @@ To set the filetype for a single file, use a [modeline](https://vim.fandom.com/w ## Visual Studio Code -To treat `*.svelte` files as HTML, add the following lines to your `settings.json` file: - -```cson - "files.associations": { - "*.svelte": "html" - } -``` +We recommend using the official [Svelte for VS Code extension](https://marketplace.visualstudio.com/items?itemName=svelte.svelte-vscode). ## JetBrains WebStorm From 6e0cd9bcbf75645481557da23703eb051f7cec3f Mon Sep 17 00:00:00 2001 From: Tan Li Hau Date: Thu, 24 Sep 2020 21:48:27 +0800 Subject: [PATCH 83/94] fix missing-declaration warning for use:obj.method (#5454) --- CHANGELOG.md | 4 ++++ src/compiler/compile/nodes/Action.ts | 5 +++-- .../samples/action-object/input.svelte | 11 +++++++++++ .../samples/action-object/warnings.json | 17 +++++++++++++++++ 4 files changed, 35 insertions(+), 2 deletions(-) create mode 100644 test/validator/samples/action-object/input.svelte create mode 100644 test/validator/samples/action-object/warnings.json diff --git a/CHANGELOG.md b/CHANGELOG.md index 3347052e75..69edc48b0e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Svelte changelog +## Unreleased + +* Fix erroneous `missing-declaration` warning with `use:obj.method` ([#5451](https://github.com/sveltejs/svelte/issues/5451)) + ## 3.26.0 * Support `use:obj.method` as actions ([#3935](https://github.com/sveltejs/svelte/issues/3935)) diff --git a/src/compiler/compile/nodes/Action.ts b/src/compiler/compile/nodes/Action.ts index 86aefa0ced..dc6f080b71 100644 --- a/src/compiler/compile/nodes/Action.ts +++ b/src/compiler/compile/nodes/Action.ts @@ -11,10 +11,11 @@ export default class Action extends Node { constructor(component: Component, parent, scope, info) { super(component, parent, scope, info); - component.warn_if_undefined(info.name, info, scope); + const object = info.name.split('.')[0]; + component.warn_if_undefined(object, info, scope); this.name = info.name; - component.add_reference(info.name.split('.')[0]); + component.add_reference(object); this.expression = info.expression ? new Expression(component, this, scope, info.expression) diff --git a/test/validator/samples/action-object/input.svelte b/test/validator/samples/action-object/input.svelte new file mode 100644 index 0000000000..e0962fa594 --- /dev/null +++ b/test/validator/samples/action-object/input.svelte @@ -0,0 +1,11 @@ + + + + \ No newline at end of file diff --git a/test/validator/samples/action-object/warnings.json b/test/validator/samples/action-object/warnings.json new file mode 100644 index 0000000000..e1ccbb55a2 --- /dev/null +++ b/test/validator/samples/action-object/warnings.json @@ -0,0 +1,17 @@ +[ + { + "code": "missing-declaration", + "end": { + "character": 217, + "column": 39, + "line": 11 + }, + "message": "'foo' is not defined", + "pos": 186, + "start": { + "character": 186, + "column": 8, + "line": 11 + } + } +] From c3b56a164ec7ec99abb960cfd483754b96041b00 Mon Sep 17 00:00:00 2001 From: Tan Li Hau Date: Fri, 25 Sep 2020 02:55:55 +0800 Subject: [PATCH 84/94] handle destructuring to a store value (#5452) --- CHANGELOG.md | 1 + src/compiler/compile/render_dom/invalidate.ts | 71 +++++++++---------- .../_config.js | 9 +++ .../main.svelte | 29 ++++++++ .../_config.js | 8 ++- .../main.svelte | 15 +++- 6 files changed, 95 insertions(+), 38 deletions(-) create mode 100644 test/runtime/samples/reactive-assignment-in-complex-declaration-with-store-2/_config.js create mode 100644 test/runtime/samples/reactive-assignment-in-complex-declaration-with-store-2/main.svelte diff --git a/CHANGELOG.md b/CHANGELOG.md index 69edc48b0e..f280dc32a3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,7 @@ ## Unreleased +* Fix destructuring into store values ([#5449](https://github.com/sveltejs/svelte/issues/5449)) * Fix erroneous `missing-declaration` warning with `use:obj.method` ([#5451](https://github.com/sveltejs/svelte/issues/5451)) ## 3.26.0 diff --git a/src/compiler/compile/render_dom/invalidate.ts b/src/compiler/compile/render_dom/invalidate.ts index b045db079f..b891b48cb5 100644 --- a/src/compiler/compile/render_dom/invalidate.ts +++ b/src/compiler/compile/render_dom/invalidate.ts @@ -36,47 +36,46 @@ export function invalidate(renderer: Renderer, scope: Scope, node: Node, names: return renderer.invalidate(variable.name, undefined, main_execution_context); } - if (head) { - component.has_reactive_assignments = true; - - if (node.type === 'AssignmentExpression' && node.operator === '=' && nodes_match(node.left, node.right) && tail.length === 0) { - return get_invalidated(head, node); - } else { - const is_store_value = head.name[0] === '$' && head.name[1] !== '$'; - const extra_args = tail.map(variable => get_invalidated(variable)).filter(Boolean); - - const pass_value = ( - !main_execution_context && - ( - extra_args.length > 0 || - (node.type === 'AssignmentExpression' && node.left.type !== 'Identifier') || - (node.type === 'UpdateExpression' && (!node.prefix || node.argument.type !== 'Identifier')) - ) - ); + if (!head) { + return node; + } - if (pass_value) { - extra_args.unshift({ - type: 'Identifier', - name: head.name - }); - } + component.has_reactive_assignments = true; - let invalidate = is_store_value - ? x`@set_store_value(${head.name.slice(1)}, ${node}, ${head.name})` - : !main_execution_context - ? x`$$invalidate(${renderer.context_lookup.get(head.name).index}, ${node}, ${extra_args})` - : extra_args.length - ? [node, ...extra_args] - : node; + if (node.type === 'AssignmentExpression' && node.operator === '=' && nodes_match(node.left, node.right) && tail.length === 0) { + return get_invalidated(head, node); + } - if (head.subscribable && head.reassigned) { - const subscribe = `$$subscribe_${head.name}`; - invalidate = x`${subscribe}(${invalidate})`; - } + const is_store_value = head.name[0] === '$' && head.name[1] !== '$'; + const extra_args = tail.map(variable => get_invalidated(variable)).filter(Boolean); - return invalidate; + if (is_store_value) { + return x`@set_store_value(${head.name.slice(1)}, ${node}, ${head.name}, ${extra_args})`; + } + + let invalidate; + if (!main_execution_context) { + const pass_value = ( + extra_args.length > 0 || + (node.type === 'AssignmentExpression' && node.left.type !== 'Identifier') || + (node.type === 'UpdateExpression' && (!node.prefix || node.argument.type !== 'Identifier')) + ); + if (pass_value) { + extra_args.unshift({ + type: 'Identifier', + name: head.name + }); } + invalidate = x`$$invalidate(${renderer.context_lookup.get(head.name).index}, ${node}, ${extra_args})`; + } else { + // skip `$$invalidate` if it is in the main execution context + invalidate = extra_args.length ? [node, ...extra_args] : node; + } + + if (head.subscribable && head.reassigned) { + const subscribe = `$$subscribe_${head.name}`; + invalidate = x`${subscribe}(${invalidate})`; } - return node; + return invalidate; } \ No newline at end of file diff --git a/test/runtime/samples/reactive-assignment-in-complex-declaration-with-store-2/_config.js b/test/runtime/samples/reactive-assignment-in-complex-declaration-with-store-2/_config.js new file mode 100644 index 0000000000..f737cad2aa --- /dev/null +++ b/test/runtime/samples/reactive-assignment-in-complex-declaration-with-store-2/_config.js @@ -0,0 +1,9 @@ +// destructure to store value +export default { + skip_if_ssr: true, // pending https://github.com/sveltejs/svelte/issues/3582 + html: `

2 2 xxx 5 6 9 10 2

`, + async test({ assert, target, component }) { + await component.update(); + assert.htmlEqual(target.innerHTML, `

11 11 yyy 12 13 14 15 11

`); + } +}; \ No newline at end of file diff --git a/test/runtime/samples/reactive-assignment-in-complex-declaration-with-store-2/main.svelte b/test/runtime/samples/reactive-assignment-in-complex-declaration-with-store-2/main.svelte new file mode 100644 index 0000000000..c1bf63d9cd --- /dev/null +++ b/test/runtime/samples/reactive-assignment-in-complex-declaration-with-store-2/main.svelte @@ -0,0 +1,29 @@ + + +

{foo} {$eid} {$u.name} {$v} {$w} {$x} {$y} {$z}

diff --git a/test/runtime/samples/reactive-assignment-in-complex-declaration-with-store/_config.js b/test/runtime/samples/reactive-assignment-in-complex-declaration-with-store/_config.js index e74cea70fe..0318e63b0a 100644 --- a/test/runtime/samples/reactive-assignment-in-complex-declaration-with-store/_config.js +++ b/test/runtime/samples/reactive-assignment-in-complex-declaration-with-store/_config.js @@ -1,3 +1,9 @@ +// destructure to store export default { - html: `

2 2 xxx 5 6

` + html: `

2 2 xxx 5 6 9 10 2

`, + skip_if_ssr: true, + async test({ assert, target, component }) { + await component.update(); + assert.htmlEqual(target.innerHTML, `

11 11 yyy 12 13 14 15 11

`); + } }; \ No newline at end of file diff --git a/test/runtime/samples/reactive-assignment-in-complex-declaration-with-store/main.svelte b/test/runtime/samples/reactive-assignment-in-complex-declaration-with-store/main.svelte index 5ad442e1da..cd49223535 100644 --- a/test/runtime/samples/reactive-assignment-in-complex-declaration-with-store/main.svelte +++ b/test/runtime/samples/reactive-assignment-in-complex-declaration-with-store/main.svelte @@ -6,11 +6,24 @@ let u; let v; let w; + let x; + let y; [u, v, w] = [ {id: eid = writable(foo = 2), name: 'xxx'}, 5, writable(6) ]; + ({ a: x, b: y } = { a: writable(9), b: writable(10) }); + $: z = u.id; + + export function update() { + [u, v, w] = [ + {id: eid = writable(foo = 11), name: 'yyy'}, + 12, + writable(13) + ]; + ({ a: x, b: y } = { a: writable(14), b: writable(15) }); + } -

{foo} {$eid} {u.name} {v} {$w}

+

{foo} {$eid} {u.name} {v} {$w} {$x} {$y} {$z}

From 41d1656458b8e2643e3751f27f147b58428d6024 Mon Sep 17 00:00:00 2001 From: Tan Li Hau Date: Fri, 25 Sep 2020 03:20:17 +0800 Subject: [PATCH 85/94] update keyed each when key expression changes (#5447) --- CHANGELOG.md | 1 + .../compile/render_dom/wrappers/EachBlock.ts | 5 ++++ .../each-block-keyed-dyanmic-key/_config.js | 27 +++++++++++++++++++ .../each-block-keyed-dyanmic-key/main.svelte | 8 ++++++ 4 files changed, 41 insertions(+) create mode 100644 test/runtime/samples/each-block-keyed-dyanmic-key/_config.js create mode 100644 test/runtime/samples/each-block-keyed-dyanmic-key/main.svelte diff --git a/CHANGELOG.md b/CHANGELOG.md index f280dc32a3..c514152672 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,7 @@ ## Unreleased +* Fix keyed `{#each}` not reacting to key changing ([#5444](https://github.com/sveltejs/svelte/issues/5444)) * Fix destructuring into store values ([#5449](https://github.com/sveltejs/svelte/issues/5449)) * Fix erroneous `missing-declaration` warning with `use:obj.method` ([#5451](https://github.com/sveltejs/svelte/issues/5451)) diff --git a/src/compiler/compile/render_dom/wrappers/EachBlock.ts b/src/compiler/compile/render_dom/wrappers/EachBlock.ts index 2513ea1adc..fe1c21a8df 100644 --- a/src/compiler/compile/render_dom/wrappers/EachBlock.ts +++ b/src/compiler/compile/render_dom/wrappers/EachBlock.ts @@ -239,6 +239,11 @@ export default class EachBlockWrapper extends Wrapper { this.node.expression.dynamic_dependencies().forEach((dependency: string) => { all_dependencies.add(dependency); }); + if (this.node.key) { + this.node.key.dynamic_dependencies().forEach((dependency: string) => { + all_dependencies.add(dependency); + }); + } this.dependencies = all_dependencies; if (this.node.key) { diff --git a/test/runtime/samples/each-block-keyed-dyanmic-key/_config.js b/test/runtime/samples/each-block-keyed-dyanmic-key/_config.js new file mode 100644 index 0000000000..0aed1b0e07 --- /dev/null +++ b/test/runtime/samples/each-block-keyed-dyanmic-key/_config.js @@ -0,0 +1,27 @@ +let count = 0; +let value = 'foo'; + +export default { + props: { + value() { + count++; + return value; + } + }, + + html: ` +
foo
+
foo
+ `, + + test({ assert, component, target }) { + value = 'bar'; + component.id = 1; + + assert.equal(count, 4); + assert.htmlEqual(target.innerHTML, ` +
bar
+
bar
+ `); + } +}; diff --git a/test/runtime/samples/each-block-keyed-dyanmic-key/main.svelte b/test/runtime/samples/each-block-keyed-dyanmic-key/main.svelte new file mode 100644 index 0000000000..9a15c7d98e --- /dev/null +++ b/test/runtime/samples/each-block-keyed-dyanmic-key/main.svelte @@ -0,0 +1,8 @@ + + +{#each ['foo', 'bar'] as key (id + key)} +
{value()}
+{/each} \ No newline at end of file From a1651ca271d65dcb563368a3a8f1dbac211bf36c Mon Sep 17 00:00:00 2001 From: Tan Li Hau Date: Fri, 25 Sep 2020 03:54:54 +0800 Subject: [PATCH 86/94] add nonpassive event modifier (#5442) Co-authored-by: filipot --- CHANGELOG.md | 1 + site/content/docs/02-template-syntax.md | 1 + .../05-events/03-event-modifiers/text.md | 1 + src/compiler/compile/nodes/Element.ts | 10 +++++- .../wrappers/Element/EventHandler.ts | 14 +++++--- test/js/samples/event-modifiers/expected.js | 36 +++++++++++-------- test/js/samples/event-modifiers/input.svelte | 1 + .../errors.json | 15 ++++++++ .../input.svelte | 3 ++ .../event-modifiers-invalid/errors.json | 2 +- 10 files changed, 64 insertions(+), 20 deletions(-) create mode 100644 test/validator/samples/event-modifiers-invalid-nonpassive/errors.json create mode 100644 test/validator/samples/event-modifiers-invalid-nonpassive/input.svelte diff --git a/CHANGELOG.md b/CHANGELOG.md index c514152672..0938d627e5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,7 @@ ## Unreleased +* Add `|nonpassive` event modifier, explicitly passing `passive: false` ([#2068](https://github.com/sveltejs/svelte/issues/2068)) * Fix keyed `{#each}` not reacting to key changing ([#5444](https://github.com/sveltejs/svelte/issues/5444)) * Fix destructuring into store values ([#5449](https://github.com/sveltejs/svelte/issues/5449)) * Fix erroneous `missing-declaration` warning with `use:obj.method` ([#5451](https://github.com/sveltejs/svelte/issues/5451)) diff --git a/site/content/docs/02-template-syntax.md b/site/content/docs/02-template-syntax.md index e93449728b..f7e1ae3517 100644 --- a/site/content/docs/02-template-syntax.md +++ b/site/content/docs/02-template-syntax.md @@ -471,6 +471,7 @@ The following modifiers are available: * `preventDefault` — calls `event.preventDefault()` before running the handler * `stopPropagation` — calls `event.stopPropagation()`, preventing the event reaching the next element * `passive` — improves scrolling performance on touch/wheel events (Svelte will add it automatically where it's safe to do so) +* `nonpassive` — explicitly set `passive: false` * `capture` — fires the handler during the *capture* phase instead of the *bubbling* phase * `once` — remove the handler after the first time it runs * `self` — only trigger handler if event.target is the element itself diff --git a/site/content/tutorial/05-events/03-event-modifiers/text.md b/site/content/tutorial/05-events/03-event-modifiers/text.md index 41154cafcd..2b2d6e6b31 100644 --- a/site/content/tutorial/05-events/03-event-modifiers/text.md +++ b/site/content/tutorial/05-events/03-event-modifiers/text.md @@ -21,6 +21,7 @@ The full list of modifiers: * `preventDefault` — calls `event.preventDefault()` before running the handler. Useful for client-side form handling, for example. * `stopPropagation` — calls `event.stopPropagation()`, preventing the event reaching the next element * `passive` — improves scrolling performance on touch/wheel events (Svelte will add it automatically where it's safe to do so) +* `nonpassive` — explicitly set `passive: false` * `capture` — fires the handler during the *capture* phase instead of the *bubbling* phase ([MDN docs](https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Building_blocks/Events#Event_bubbling_and_capture)) * `once` — remove the handler after the first time it runs * `self` — only trigger handler if event.target is the element itself diff --git a/src/compiler/compile/nodes/Element.ts b/src/compiler/compile/nodes/Element.ts index 6636c6b87b..991f102339 100644 --- a/src/compiler/compile/nodes/Element.ts +++ b/src/compiler/compile/nodes/Element.ts @@ -80,6 +80,7 @@ const valid_modifiers = new Set([ 'capture', 'once', 'passive', + 'nonpassive', 'self' ]); @@ -770,6 +771,13 @@ export default class Element extends Node { }); } + if (handler.modifiers.has('passive') && handler.modifiers.has('nonpassive')) { + component.error(handler, { + code: 'invalid-event-modifier', + message: `The 'passive' and 'nonpassive' modifiers cannot be used together` + }); + } + handler.modifiers.forEach(modifier => { if (!valid_modifiers.has(modifier)) { component.error(handler, { @@ -804,7 +812,7 @@ export default class Element extends Node { } }); - if (passive_events.has(handler.name) && handler.can_make_passive && !handler.modifiers.has('preventDefault')) { + if (passive_events.has(handler.name) && handler.can_make_passive && !handler.modifiers.has('preventDefault') && !handler.modifiers.has('nonpassive')) { // touch/wheel events should be passive by default handler.modifiers.add('passive'); } diff --git a/src/compiler/compile/render_dom/wrappers/Element/EventHandler.ts b/src/compiler/compile/render_dom/wrappers/Element/EventHandler.ts index 157e186ea6..2fa2e9291a 100644 --- a/src/compiler/compile/render_dom/wrappers/Element/EventHandler.ts +++ b/src/compiler/compile/render_dom/wrappers/Element/EventHandler.ts @@ -45,11 +45,17 @@ export default class EventHandlerWrapper { const args = []; - const opts = ['passive', 'once', 'capture'].filter(mod => this.node.modifiers.has(mod)); + const opts = ['nonpassive', 'passive', 'once', 'capture'].filter(mod => this.node.modifiers.has(mod)); if (opts.length) { - args.push((opts.length === 1 && opts[0] === 'capture') - ? TRUE - : x`{ ${opts.map(opt => p`${opt}: true`)} }`); + if (opts.length === 1 && opts[0] === 'capture') { + args.push(TRUE); + } else { + args.push(x`{ ${ opts.map(opt => + opt === 'nonpassive' + ? p`passive: false` + : p`${opt}: true` + ) } }`); + } } else if (block.renderer.options.dev) { args.push(FALSE); } diff --git a/test/js/samples/event-modifiers/expected.js b/test/js/samples/event-modifiers/expected.js index 6aa3c161f9..3901753661 100644 --- a/test/js/samples/event-modifiers/expected.js +++ b/test/js/samples/event-modifiers/expected.js @@ -16,41 +16,49 @@ import { } from "svelte/internal"; function create_fragment(ctx) { - let div; - let button0; + let div1; + let div0; let t1; - let button1; + let button0; let t3; + let button1; + let t5; let button2; let mounted; let dispose; return { c() { - div = element("div"); + div1 = element("div"); + div0 = element("div"); + div0.textContent = "touch me"; + t1 = space(); button0 = element("button"); button0.textContent = "click me"; - t1 = space(); + t3 = space(); button1 = element("button"); button1.textContent = "or me"; - t3 = space(); + t5 = space(); button2 = element("button"); button2.textContent = "or me!"; }, m(target, anchor) { - insert(target, div, anchor); - append(div, button0); - append(div, t1); - append(div, button1); - append(div, t3); - append(div, button2); + insert(target, div1, anchor); + append(div1, div0); + append(div1, t1); + append(div1, button0); + append(div1, t3); + append(div1, button1); + append(div1, t5); + append(div1, button2); if (!mounted) { dispose = [ + listen(div0, "touchstart", handleTouchstart, { passive: false }), listen(button0, "click", stop_propagation(prevent_default(handleClick))), listen(button1, "click", handleClick, { once: true, capture: true }), listen(button2, "click", handleClick, true), - listen(div, "touchstart", handleTouchstart, { passive: true }) + listen(div1, "touchstart", handleTouchstart, { passive: true }) ]; mounted = true; @@ -60,7 +68,7 @@ function create_fragment(ctx) { i: noop, o: noop, d(detaching) { - if (detaching) detach(div); + if (detaching) detach(div1); mounted = false; run_all(dispose); } diff --git a/test/js/samples/event-modifiers/input.svelte b/test/js/samples/event-modifiers/input.svelte index 225134f598..c72d58dabb 100644 --- a/test/js/samples/event-modifiers/input.svelte +++ b/test/js/samples/event-modifiers/input.svelte @@ -9,6 +9,7 @@
+
touch me
diff --git a/test/validator/samples/event-modifiers-invalid-nonpassive/errors.json b/test/validator/samples/event-modifiers-invalid-nonpassive/errors.json new file mode 100644 index 0000000000..a7e5a2a76c --- /dev/null +++ b/test/validator/samples/event-modifiers-invalid-nonpassive/errors.json @@ -0,0 +1,15 @@ +[{ + "message": "The 'passive' and 'nonpassive' modifiers cannot be used together", + "code": "invalid-event-modifier", + "start": { + "line": 1, + "column": 5, + "character": 5 + }, + "end": { + "line": 1, + "column": 51, + "character": 51 + }, + "pos": 5 +}] diff --git a/test/validator/samples/event-modifiers-invalid-nonpassive/input.svelte b/test/validator/samples/event-modifiers-invalid-nonpassive/input.svelte new file mode 100644 index 0000000000..3557aa4b1d --- /dev/null +++ b/test/validator/samples/event-modifiers-invalid-nonpassive/input.svelte @@ -0,0 +1,3 @@ +
+ oops +
\ No newline at end of file diff --git a/test/validator/samples/event-modifiers-invalid/errors.json b/test/validator/samples/event-modifiers-invalid/errors.json index 8be2ca7348..59a142d632 100644 --- a/test/validator/samples/event-modifiers-invalid/errors.json +++ b/test/validator/samples/event-modifiers-invalid/errors.json @@ -1,5 +1,5 @@ [{ - "message": "Valid event modifiers are preventDefault, stopPropagation, capture, once, passive or self", + "message": "Valid event modifiers are preventDefault, stopPropagation, capture, once, passive, nonpassive or self", "code": "invalid-event-modifier", "start": { "line": 1, From 967b88186b0919cf53625eaa959dff48e6f8c509 Mon Sep 17 00:00:00 2001 From: Tan Li Hau Date: Fri, 25 Sep 2020 04:06:32 +0800 Subject: [PATCH 87/94] scope CSS sibling combinators (#5427) --- CHANGELOG.md | 1 + src/compiler/compile/Component.ts | 8 +- src/compiler/compile/css/Selector.ts | 187 +++++++++++++++++- src/compiler/compile/css/Stylesheet.ts | 18 +- src/compiler/compile/nodes/Element.ts | 7 +- .../_config.js | 3 + .../expected.css | 1 + .../expected.html | 4 + .../input.svelte | 41 ++++ .../_config.js | 46 +++++ .../expected.css | 1 + .../expected.html | 3 + .../input.svelte | 30 +++ .../_config.js | 3 + .../expected.css | 1 + .../expected.html | 4 + .../input.svelte | 37 ++++ .../_config.js | 18 ++ .../expected.css | 1 + .../expected.html | 3 + .../input.svelte | 77 ++++++++ .../_config.js | 18 ++ .../expected.css | 1 + .../expected.html | 3 + .../input.svelte | 24 +++ .../_config.js | 3 + .../expected.css | 1 + .../expected.html | 15 ++ .../input.svelte | 113 +++++++++++ .../expected.css | 1 + .../expected.html | 6 + .../input.svelte | 20 ++ .../_config.js | 18 ++ .../expected.css | 1 + .../expected.html | 3 + .../input.svelte | 31 +++ .../_config.js | 18 ++ .../expected.css | 1 + .../expected.html | 3 + .../input.svelte | 25 +++ .../general-siblings-combinator-if/_config.js | 46 +++++ .../expected.css | 1 + .../expected.html | 3 + .../input.svelte | 31 +++ .../_config.js | 88 +++++++++ .../expected.css | 1 + .../input.svelte | 30 +++ .../_config.js | 18 ++ .../expected.css | 1 + .../expected.html | 7 + .../input.svelte | 17 ++ .../general-siblings-combinator/_config.js | 60 ++++++ .../general-siblings-combinator/expected.css | 1 + .../general-siblings-combinator/expected.html | 7 + .../general-siblings-combinator/input.svelte | 24 +++ .../_config.js | 3 + .../expected.css | 1 + .../expected.html | 4 + .../input.svelte | 41 ++++ .../siblings-combinator-await/_config.js | 60 ++++++ .../siblings-combinator-await/expected.css | 1 + .../siblings-combinator-await/expected.html | 3 + .../siblings-combinator-await/input.svelte | 30 +++ .../siblings-combinator-each-2/_config.js | 18 ++ .../siblings-combinator-each-2/expected.css | 1 + .../siblings-combinator-each-2/expected.html | 4 + .../siblings-combinator-each-2/input.svelte | 38 ++++ .../_config.js | 144 ++++++++++++++ .../expected.css | 1 + .../expected.html | 3 + .../input.svelte | 74 +++++++ .../siblings-combinator-each-else/_config.js | 32 +++ .../expected.css | 1 + .../expected.html | 3 + .../input.svelte | 24 +++ .../_config.js | 116 +++++++++++ .../expected.css | 1 + .../expected.html | 15 ++ .../input.svelte | 113 +++++++++++ .../siblings-combinator-each/expected.css | 1 + .../siblings-combinator-each/expected.html | 6 + .../siblings-combinator-each/input.svelte | 20 ++ .../_config.js | 18 ++ .../expected.css | 1 + .../expected.html | 3 + .../input.svelte | 31 +++ .../_config.js | 18 ++ .../expected.css | 1 + .../expected.html | 3 + .../input.svelte | 25 +++ .../samples/siblings-combinator-if/_config.js | 60 ++++++ .../siblings-combinator-if/expected.css | 1 + .../siblings-combinator-if/expected.html | 3 + .../siblings-combinator-if/input.svelte | 31 +++ .../siblings-combinator-slot/_config.js | 46 +++++ .../siblings-combinator-slot/expected.css | 1 + .../siblings-combinator-slot/input.svelte | 24 +++ .../siblings-combinator-star/_config.js | 18 ++ .../siblings-combinator-star/expected.css | 1 + .../siblings-combinator-star/expected.html | 7 + .../siblings-combinator-star/input.svelte | 17 ++ .../samples/siblings-combinator/_config.js | 62 ++++++ .../samples/siblings-combinator/expected.css | 1 + .../samples/siblings-combinator/expected.html | 5 + .../samples/siblings-combinator/input.svelte | 35 ++++ 105 files changed, 2280 insertions(+), 24 deletions(-) create mode 100644 test/css/samples/general-siblings-combinator-await-not-exhaustive/_config.js create mode 100644 test/css/samples/general-siblings-combinator-await-not-exhaustive/expected.css create mode 100644 test/css/samples/general-siblings-combinator-await-not-exhaustive/expected.html create mode 100644 test/css/samples/general-siblings-combinator-await-not-exhaustive/input.svelte create mode 100644 test/css/samples/general-siblings-combinator-await/_config.js create mode 100644 test/css/samples/general-siblings-combinator-await/expected.css create mode 100644 test/css/samples/general-siblings-combinator-await/expected.html create mode 100644 test/css/samples/general-siblings-combinator-await/input.svelte create mode 100644 test/css/samples/general-siblings-combinator-each-2/_config.js create mode 100644 test/css/samples/general-siblings-combinator-each-2/expected.css create mode 100644 test/css/samples/general-siblings-combinator-each-2/expected.html create mode 100644 test/css/samples/general-siblings-combinator-each-2/input.svelte create mode 100644 test/css/samples/general-siblings-combinator-each-else-nested/_config.js create mode 100644 test/css/samples/general-siblings-combinator-each-else-nested/expected.css create mode 100644 test/css/samples/general-siblings-combinator-each-else-nested/expected.html create mode 100644 test/css/samples/general-siblings-combinator-each-else-nested/input.svelte create mode 100644 test/css/samples/general-siblings-combinator-each-else/_config.js create mode 100644 test/css/samples/general-siblings-combinator-each-else/expected.css create mode 100644 test/css/samples/general-siblings-combinator-each-else/expected.html create mode 100644 test/css/samples/general-siblings-combinator-each-else/input.svelte create mode 100644 test/css/samples/general-siblings-combinator-each-nested/_config.js create mode 100644 test/css/samples/general-siblings-combinator-each-nested/expected.css create mode 100644 test/css/samples/general-siblings-combinator-each-nested/expected.html create mode 100644 test/css/samples/general-siblings-combinator-each-nested/input.svelte create mode 100644 test/css/samples/general-siblings-combinator-each/expected.css create mode 100644 test/css/samples/general-siblings-combinator-each/expected.html create mode 100644 test/css/samples/general-siblings-combinator-each/input.svelte create mode 100644 test/css/samples/general-siblings-combinator-if-not-exhaustive-with-each/_config.js create mode 100644 test/css/samples/general-siblings-combinator-if-not-exhaustive-with-each/expected.css create mode 100644 test/css/samples/general-siblings-combinator-if-not-exhaustive-with-each/expected.html create mode 100644 test/css/samples/general-siblings-combinator-if-not-exhaustive-with-each/input.svelte create mode 100644 test/css/samples/general-siblings-combinator-if-not-exhaustive/_config.js create mode 100644 test/css/samples/general-siblings-combinator-if-not-exhaustive/expected.css create mode 100644 test/css/samples/general-siblings-combinator-if-not-exhaustive/expected.html create mode 100644 test/css/samples/general-siblings-combinator-if-not-exhaustive/input.svelte create mode 100644 test/css/samples/general-siblings-combinator-if/_config.js create mode 100644 test/css/samples/general-siblings-combinator-if/expected.css create mode 100644 test/css/samples/general-siblings-combinator-if/expected.html create mode 100644 test/css/samples/general-siblings-combinator-if/input.svelte create mode 100644 test/css/samples/general-siblings-combinator-slot/_config.js create mode 100644 test/css/samples/general-siblings-combinator-slot/expected.css create mode 100644 test/css/samples/general-siblings-combinator-slot/input.svelte create mode 100644 test/css/samples/general-siblings-combinator-star/_config.js create mode 100644 test/css/samples/general-siblings-combinator-star/expected.css create mode 100644 test/css/samples/general-siblings-combinator-star/expected.html create mode 100644 test/css/samples/general-siblings-combinator-star/input.svelte create mode 100644 test/css/samples/general-siblings-combinator/_config.js create mode 100644 test/css/samples/general-siblings-combinator/expected.css create mode 100644 test/css/samples/general-siblings-combinator/expected.html create mode 100644 test/css/samples/general-siblings-combinator/input.svelte create mode 100644 test/css/samples/siblings-combinator-await-not-exhaustive/_config.js create mode 100644 test/css/samples/siblings-combinator-await-not-exhaustive/expected.css create mode 100644 test/css/samples/siblings-combinator-await-not-exhaustive/expected.html create mode 100644 test/css/samples/siblings-combinator-await-not-exhaustive/input.svelte create mode 100644 test/css/samples/siblings-combinator-await/_config.js create mode 100644 test/css/samples/siblings-combinator-await/expected.css create mode 100644 test/css/samples/siblings-combinator-await/expected.html create mode 100644 test/css/samples/siblings-combinator-await/input.svelte create mode 100644 test/css/samples/siblings-combinator-each-2/_config.js create mode 100644 test/css/samples/siblings-combinator-each-2/expected.css create mode 100644 test/css/samples/siblings-combinator-each-2/expected.html create mode 100644 test/css/samples/siblings-combinator-each-2/input.svelte create mode 100644 test/css/samples/siblings-combinator-each-else-nested/_config.js create mode 100644 test/css/samples/siblings-combinator-each-else-nested/expected.css create mode 100644 test/css/samples/siblings-combinator-each-else-nested/expected.html create mode 100644 test/css/samples/siblings-combinator-each-else-nested/input.svelte create mode 100644 test/css/samples/siblings-combinator-each-else/_config.js create mode 100644 test/css/samples/siblings-combinator-each-else/expected.css create mode 100644 test/css/samples/siblings-combinator-each-else/expected.html create mode 100644 test/css/samples/siblings-combinator-each-else/input.svelte create mode 100644 test/css/samples/siblings-combinator-each-nested/_config.js create mode 100644 test/css/samples/siblings-combinator-each-nested/expected.css create mode 100644 test/css/samples/siblings-combinator-each-nested/expected.html create mode 100644 test/css/samples/siblings-combinator-each-nested/input.svelte create mode 100644 test/css/samples/siblings-combinator-each/expected.css create mode 100644 test/css/samples/siblings-combinator-each/expected.html create mode 100644 test/css/samples/siblings-combinator-each/input.svelte create mode 100644 test/css/samples/siblings-combinator-if-not-exhaustive-with-each/_config.js create mode 100644 test/css/samples/siblings-combinator-if-not-exhaustive-with-each/expected.css create mode 100644 test/css/samples/siblings-combinator-if-not-exhaustive-with-each/expected.html create mode 100644 test/css/samples/siblings-combinator-if-not-exhaustive-with-each/input.svelte create mode 100644 test/css/samples/siblings-combinator-if-not-exhaustive/_config.js create mode 100644 test/css/samples/siblings-combinator-if-not-exhaustive/expected.css create mode 100644 test/css/samples/siblings-combinator-if-not-exhaustive/expected.html create mode 100644 test/css/samples/siblings-combinator-if-not-exhaustive/input.svelte create mode 100644 test/css/samples/siblings-combinator-if/_config.js create mode 100644 test/css/samples/siblings-combinator-if/expected.css create mode 100644 test/css/samples/siblings-combinator-if/expected.html create mode 100644 test/css/samples/siblings-combinator-if/input.svelte create mode 100644 test/css/samples/siblings-combinator-slot/_config.js create mode 100644 test/css/samples/siblings-combinator-slot/expected.css create mode 100644 test/css/samples/siblings-combinator-slot/input.svelte create mode 100644 test/css/samples/siblings-combinator-star/_config.js create mode 100644 test/css/samples/siblings-combinator-star/expected.css create mode 100644 test/css/samples/siblings-combinator-star/expected.html create mode 100644 test/css/samples/siblings-combinator-star/input.svelte create mode 100644 test/css/samples/siblings-combinator/_config.js create mode 100644 test/css/samples/siblings-combinator/expected.css create mode 100644 test/css/samples/siblings-combinator/expected.html create mode 100644 test/css/samples/siblings-combinator/input.svelte diff --git a/CHANGELOG.md b/CHANGELOG.md index 0938d627e5..a18cfac6c3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ ## Unreleased * Add `|nonpassive` event modifier, explicitly passing `passive: false` ([#2068](https://github.com/sveltejs/svelte/issues/2068)) +* Scope CSS selectors with `~` and `+` combinators ([#3104](https://github.com/sveltejs/svelte/issues/3104)) * Fix keyed `{#each}` not reacting to key changing ([#5444](https://github.com/sveltejs/svelte/issues/5444)) * Fix destructuring into store values ([#5449](https://github.com/sveltejs/svelte/issues/5449)) * Fix erroneous `missing-declaration` warning with `use:obj.method` ([#5451](https://github.com/sveltejs/svelte/issues/5451)) diff --git a/src/compiler/compile/Component.ts b/src/compiler/compile/Component.ts index 078ecb8869..6c1fe89823 100644 --- a/src/compiler/compile/Component.ts +++ b/src/compiler/compile/Component.ts @@ -29,6 +29,7 @@ import add_to_set from './utils/add_to_set'; import check_graph_for_cycles from './utils/check_graph_for_cycles'; import { print, x, b } from 'code-red'; import { is_reserved_keyword } from './utils/reserved_keywords'; +import Element from './nodes/Element'; interface ComponentOptions { namespace?: string; @@ -85,6 +86,7 @@ export default class Component { file: string; locate: (c: number) => { line: number; column: number }; + elements: Element[] = []; stylesheet: Stylesheet; aliases: Map = new Map(); @@ -171,8 +173,8 @@ export default class Component { this.walk_instance_js_post_template(); + this.elements.forEach(element => this.stylesheet.apply(element)); if (!compile_options.customElement) this.stylesheet.reify(); - this.stylesheet.warn_on_unused_selectors(this); } @@ -221,6 +223,10 @@ export default class Component { return this.aliases.get(name); } + apply_stylesheet(element: Element) { + this.elements.push(element); + } + global(name: string) { const alias = this.alias(name); this.globals.set(name, alias); diff --git a/src/compiler/compile/css/Selector.ts b/src/compiler/compile/css/Selector.ts index c45cda57e9..c141f6b481 100644 --- a/src/compiler/compile/css/Selector.ts +++ b/src/compiler/compile/css/Selector.ts @@ -4,12 +4,20 @@ import { gather_possible_values, UNKNOWN } from './gather_possible_values'; import { CssNode } from './interfaces'; import Component from '../Component'; import Element from '../nodes/Element'; +import { INode } from '../nodes/interfaces'; +import EachBlock from '../nodes/EachBlock'; +import IfBlock from '../nodes/IfBlock'; +import AwaitBlock from '../nodes/AwaitBlock'; enum BlockAppliesToNode { NotPossible, Possible, UnknownSelectorType } +enum NodeExist { + Probably = 1, + Definitely = 2, +} const whitelist_attribute_selector = new Map([ ['details', new Set(['open'])] @@ -39,10 +47,10 @@ export default class Selector { this.used = this.local_blocks.length === 0; } - apply(node: Element, stack: Element[]) { + apply(node: Element) { const to_encapsulate: any[] = []; - apply_selector(this.local_blocks.slice(), node, stack.slice(), to_encapsulate); + apply_selector(this.local_blocks.slice(), node, to_encapsulate); if (to_encapsulate.length > 0) { to_encapsulate.forEach(({ node, block }) => { @@ -149,7 +157,7 @@ export default class Selector { } } -function apply_selector(blocks: Block[], node: Element, stack: Element[], to_encapsulate: any[]): boolean { +function apply_selector(blocks: Block[], node: Element, to_encapsulate: any[]): boolean { const block = blocks.pop(); if (!block) return false; @@ -162,7 +170,7 @@ function apply_selector(blocks: Block[], node: Element, stack: Element[], to_enc return false; case BlockAppliesToNode.UnknownSelectorType: - // bail. TODO figure out what these could be + // bail. TODO figure out what these could be to_encapsulate.push({ node, block }); return true; } @@ -174,9 +182,10 @@ function apply_selector(blocks: Block[], node: Element, stack: Element[], to_enc continue; } - for (const stack_node of stack) { - if (block_might_apply_to_node(ancestor_block, stack_node) !== BlockAppliesToNode.NotPossible) { - to_encapsulate.push({ node: stack_node, block: ancestor_block }); + let parent = node; + while (parent = get_element_parent(parent)) { + if (block_might_apply_to_node(ancestor_block, parent) !== BlockAppliesToNode.NotPossible) { + to_encapsulate.push({ node: parent, block: ancestor_block }); } } @@ -193,12 +202,22 @@ function apply_selector(blocks: Block[], node: Element, stack: Element[], to_enc return false; } else if (block.combinator.name === '>') { - if (apply_selector(blocks, stack.pop(), stack, to_encapsulate)) { + if (apply_selector(blocks, get_element_parent(node), to_encapsulate)) { to_encapsulate.push({ node, block }); return true; } return false; + } else if (block.combinator.name === '+' || block.combinator.name === '~') { + const siblings = get_possible_element_siblings(node, block.combinator.name === '+'); + let has_match = false; + for (const possible_sibling of siblings.keys()) { + if (apply_selector(blocks.slice(), possible_sibling, to_encapsulate)) { + to_encapsulate.push({ node, block }); + has_match = true; + } + } + return has_match; } // TODO other combinators @@ -376,6 +395,158 @@ function unquote(value: CssNode) { return str; } +function get_element_parent(node: Element): Element | null { + let parent: INode = node; + while ((parent = parent.parent) && parent.type !== 'Element'); + return parent as Element | null; +} + +function get_possible_element_siblings(node: INode, adjacent_only: boolean): Map { + const result: Map = new Map(); + let prev: INode = node; + while (prev = prev.prev) { + if (prev.type === 'Element') { + if (!prev.attributes.find(attr => attr.name.toLowerCase() === 'slot')) { + result.set(prev, NodeExist.Definitely); + } + + if (adjacent_only) { + break; + } + } else if (prev.type === 'EachBlock' || prev.type === 'IfBlock' || prev.type === 'AwaitBlock') { + const possible_last_child = get_possible_last_child(prev, adjacent_only); + + add_to_map(possible_last_child, result); + if (adjacent_only && has_definite_elements(possible_last_child)) { + return result; + } + } + } + + if (!prev || !adjacent_only) { + let parent: INode = node; + let skip_each_for_last_child = node.type === 'ElseBlock'; + while ((parent = parent.parent) && (parent.type === 'EachBlock' || parent.type === 'IfBlock' || parent.type === 'ElseBlock' || parent.type === 'AwaitBlock')) { + const possible_siblings = get_possible_element_siblings(parent, adjacent_only); + add_to_map(possible_siblings, result); + + if (parent.type === 'EachBlock') { + // first child of each block can select the last child of each block as previous sibling + if (skip_each_for_last_child) { + skip_each_for_last_child = false; + } else { + add_to_map(get_possible_last_child(parent, adjacent_only), result); + } + } else if (parent.type === 'ElseBlock') { + skip_each_for_last_child = true; + parent = parent.parent; + } + + if (adjacent_only && has_definite_elements(possible_siblings)) { + break; + } + } + } + + return result; +} + +function get_possible_last_child(block: EachBlock | IfBlock | AwaitBlock, adjacent_only: boolean): Map { + const result: Map = new Map(); + + if (block.type === 'EachBlock') { + const each_result: Map = loop_child(block.children, adjacent_only); + const else_result: Map = block.else ? loop_child(block.else.children, adjacent_only) : new Map(); + + const not_exhaustive = !has_definite_elements(else_result); + + if (not_exhaustive) { + mark_as_probably(each_result); + mark_as_probably(else_result); + } + add_to_map(each_result, result); + add_to_map(else_result, result); + } else if (block.type === 'IfBlock') { + const if_result: Map = loop_child(block.children, adjacent_only); + const else_result: Map = block.else ? loop_child(block.else.children, adjacent_only) : new Map(); + + const not_exhaustive = !has_definite_elements(if_result) || !has_definite_elements(else_result); + + if (not_exhaustive) { + mark_as_probably(if_result); + mark_as_probably(else_result); + } + + add_to_map(if_result, result); + add_to_map(else_result, result); + } else if (block.type === 'AwaitBlock') { + const pending_result: Map = block.pending ? loop_child(block.pending.children, adjacent_only) : new Map(); + const then_result: Map = block.then ? loop_child(block.then.children, adjacent_only) : new Map(); + const catch_result: Map = block.catch ? loop_child(block.catch.children, adjacent_only) : new Map(); + + const not_exhaustive = !has_definite_elements(pending_result) || !has_definite_elements(then_result) || !has_definite_elements(catch_result); + + if (not_exhaustive) { + mark_as_probably(pending_result); + mark_as_probably(then_result); + mark_as_probably(catch_result); + } + + add_to_map(pending_result, result); + add_to_map(then_result, result); + add_to_map(catch_result, result); + } + + return result; +} + +function has_definite_elements(result: Map): boolean { + if (result.size === 0) return false; + for (const exist of result.values()) { + if (exist === NodeExist.Definitely) { + return true; + } + } + return false; +} + +function add_to_map(from: Map, to: Map) { + from.forEach((exist, element) => { + to.set(element, higher_existance(exist, to.get(element))); + }); +} + +function higher_existance(exist1: NodeExist | null, exist2: NodeExist | null): NodeExist { + if (exist1 === undefined || exist2 === undefined) return exist1 || exist2; + return exist1 > exist2 ? exist1 : exist2; +} + +function mark_as_probably(result: Map) { + for (const key of result.keys()) { + result.set(key, NodeExist.Probably); + } +} + +function loop_child(children: INode[], adjacent_only: boolean) { + const result: Map = new Map(); + for (let i = children.length - 1; i >= 0; i--) { + const child = children[i]; + if (child.type === 'Element') { + result.set(child, NodeExist.Definitely); + if (adjacent_only) { + break; + } + } else if (child.type === 'EachBlock' || child.type === 'IfBlock' || child.type === 'AwaitBlock') { + const child_result = get_possible_last_child(child, adjacent_only); + add_to_map(child_result, result); + if (adjacent_only && has_definite_elements(child_result)) { + break; + } + } + } + return result; +} + class Block { global: boolean; combinator: CssNode; diff --git a/src/compiler/compile/css/Stylesheet.ts b/src/compiler/compile/css/Stylesheet.ts index 27438947ff..dc464d7df8 100644 --- a/src/compiler/compile/css/Stylesheet.ts +++ b/src/compiler/compile/css/Stylesheet.ts @@ -2,7 +2,7 @@ import MagicString from 'magic-string'; import { walk } from 'estree-walker'; import Selector from './Selector'; import Element from '../nodes/Element'; -import { Ast, TemplateNode } from '../../interfaces'; +import { Ast } from '../../interfaces'; import Component from '../Component'; import { CssNode } from './interfaces'; import hash from "../utils/hash"; @@ -51,8 +51,8 @@ class Rule { this.declarations = node.block.children.map((node: CssNode) => new Declaration(node)); } - apply(node: Element, stack: Element[]) { - this.selectors.forEach(selector => selector.apply(node, stack)); // TODO move the logic in here? + apply(node: Element) { + this.selectors.forEach(selector => selector.apply(node)); // TODO move the logic in here? } is_used(dev: boolean) { @@ -162,10 +162,10 @@ class Atrule { this.declarations = []; } - apply(node: Element, stack: Element[]) { + apply(node: Element) { if (this.node.name === 'media' || this.node.name === 'supports') { this.children.forEach(child => { - child.apply(node, stack); + child.apply(node); }); } @@ -364,15 +364,9 @@ export default class Stylesheet { apply(node: Element) { if (!this.has_styles) return; - const stack: Element[] = []; - let parent: TemplateNode = node; - while (parent = parent.parent) { - if (parent.type === 'Element') stack.unshift(parent as Element); - } - for (let i = 0; i < this.children.length; i += 1) { const child = this.children[i]; - child.apply(node, stack); + child.apply(node); } } diff --git a/src/compiler/compile/nodes/Element.ts b/src/compiler/compile/nodes/Element.ts index 991f102339..7c9272e5d3 100644 --- a/src/compiler/compile/nodes/Element.ts +++ b/src/compiler/compile/nodes/Element.ts @@ -16,6 +16,7 @@ import list from '../../utils/list'; import Let from './Let'; import TemplateScope from './shared/TemplateScope'; import { INode } from './interfaces'; +import Component from '../Component'; const svg = /^(?:altGlyph|altGlyphDef|altGlyphItem|animate|animateColor|animateMotion|animateTransform|circle|clipPath|color-profile|cursor|defs|desc|discard|ellipse|feBlend|feColorMatrix|feComponentTransfer|feComposite|feConvolveMatrix|feDiffuseLighting|feDisplacementMap|feDistantLight|feDropShadow|feFlood|feFuncA|feFuncB|feFuncG|feFuncR|feGaussianBlur|feImage|feMerge|feMergeNode|feMorphology|feOffset|fePointLight|feSpecularLighting|feSpotLight|feTile|feTurbulence|filter|font|font-face|font-face-format|font-face-name|font-face-src|font-face-uri|foreignObject|g|glyph|glyphRef|hatch|hatchpath|hkern|image|line|linearGradient|marker|mask|mesh|meshgradient|meshpatch|meshrow|metadata|missing-glyph|mpath|path|pattern|polygon|polyline|radialGradient|rect|set|solidcolor|stop|svg|switch|symbol|text|textPath|tref|tspan|unknown|use|view|vkern)$/; @@ -124,7 +125,7 @@ export default class Element extends Node { namespace: string; needs_manual_style_scoping: boolean; - constructor(component, parent, scope, info: any) { + constructor(component: Component, parent, scope, info: any) { super(component, parent, scope, info); this.name = info.name; @@ -185,7 +186,7 @@ export default class Element extends Node { case 'Attribute': case 'Spread': - // special case + // special case if (node.name === 'xmlns') this.namespace = node.value[0].data; this.attributes.push(new Attribute(component, this, scope, node)); @@ -236,7 +237,7 @@ export default class Element extends Node { this.validate(); - component.stylesheet.apply(this); + component.apply_stylesheet(this); } validate() { diff --git a/test/css/samples/general-siblings-combinator-await-not-exhaustive/_config.js b/test/css/samples/general-siblings-combinator-await-not-exhaustive/_config.js new file mode 100644 index 0000000000..c81f1a9f82 --- /dev/null +++ b/test/css/samples/general-siblings-combinator-await-not-exhaustive/_config.js @@ -0,0 +1,3 @@ +export default { + warnings: [] +}; diff --git a/test/css/samples/general-siblings-combinator-await-not-exhaustive/expected.css b/test/css/samples/general-siblings-combinator-await-not-exhaustive/expected.css new file mode 100644 index 0000000000..54eefc6088 --- /dev/null +++ b/test/css/samples/general-siblings-combinator-await-not-exhaustive/expected.css @@ -0,0 +1 @@ +.a.svelte-xyz~.b.svelte-xyz.svelte-xyz.svelte-xyz{color:green}.a.svelte-xyz~.c.svelte-xyz.svelte-xyz.svelte-xyz{color:green}.a.svelte-xyz~.d.svelte-xyz.svelte-xyz.svelte-xyz{color:green}.a.svelte-xyz~.e.svelte-xyz.svelte-xyz.svelte-xyz{color:green}.a.svelte-xyz~.f.svelte-xyz.svelte-xyz.svelte-xyz{color:green}.a.svelte-xyz~.g.svelte-xyz.svelte-xyz.svelte-xyz{color:green}.a.svelte-xyz~.h.svelte-xyz.svelte-xyz.svelte-xyz{color:green}.b.svelte-xyz~.d.svelte-xyz.svelte-xyz.svelte-xyz{color:green}.c.svelte-xyz~.d.svelte-xyz.svelte-xyz.svelte-xyz{color:green}.b.svelte-xyz~.e.svelte-xyz~.f.svelte-xyz~.h.svelte-xyz{color:green}.b.svelte-xyz~.d.svelte-xyz~.h.svelte-xyz.svelte-xyz{color:green}.c.svelte-xyz~.g.svelte-xyz.svelte-xyz.svelte-xyz{color:green} \ No newline at end of file diff --git a/test/css/samples/general-siblings-combinator-await-not-exhaustive/expected.html b/test/css/samples/general-siblings-combinator-await-not-exhaustive/expected.html new file mode 100644 index 0000000000..de97b02a5e --- /dev/null +++ b/test/css/samples/general-siblings-combinator-await-not-exhaustive/expected.html @@ -0,0 +1,4 @@ +
+
+
+
\ No newline at end of file diff --git a/test/css/samples/general-siblings-combinator-await-not-exhaustive/input.svelte b/test/css/samples/general-siblings-combinator-await-not-exhaustive/input.svelte new file mode 100644 index 0000000000..a677077c33 --- /dev/null +++ b/test/css/samples/general-siblings-combinator-await-not-exhaustive/input.svelte @@ -0,0 +1,41 @@ + + + + +
+ +{#await promise then value} +
+{:catch error} +
+{/await} + +{#await promise} +
+{:catch error} +
+{/await} + +{#await promise} +
+{:then error} +
+{/await} + +
\ No newline at end of file diff --git a/test/css/samples/general-siblings-combinator-await/_config.js b/test/css/samples/general-siblings-combinator-await/_config.js new file mode 100644 index 0000000000..b4ebe41828 --- /dev/null +++ b/test/css/samples/general-siblings-combinator-await/_config.js @@ -0,0 +1,46 @@ +export default { + warnings: [ + { + code: "css-unused-selector", + frame: ` + 13: + 14: /* no match */ + 15: .b ~ .c { color: green; } + ^ + 16: .c ~ .d { color: green; } + 17: .b ~ .d { color: green; }`, + message: 'Unused CSS selector ".b ~ .c"', + pos: 269, + start: { character: 269, column: 1, line: 15 }, + end: { character: 276, column: 8, line: 15 } + }, + { + code: "css-unused-selector", + frame: ` + 14: /* no match */ + 15: .b ~ .c { color: green; } + 16: .c ~ .d { color: green; } + ^ + 17: .b ~ .d { color: green; } + 18: `, + message: 'Unused CSS selector ".c ~ .d"', + pos: 296, + start: { character: 296, column: 1, line: 16 }, + end: { character: 303, column: 8, line: 16 } + }, + { + code: "css-unused-selector", + frame: ` + 15: .b ~ .c { color: green; } + 16: .c ~ .d { color: green; } + 17: .b ~ .d { color: green; } + ^ + 18: + 19:`, + message: 'Unused CSS selector ".b ~ .d"', + pos: 323, + start: { character: 323, column: 1, line: 17 }, + end: { character: 330, column: 8, line: 17 } + } + ] +}; diff --git a/test/css/samples/general-siblings-combinator-await/expected.css b/test/css/samples/general-siblings-combinator-await/expected.css new file mode 100644 index 0000000000..94a5494597 --- /dev/null +++ b/test/css/samples/general-siblings-combinator-await/expected.css @@ -0,0 +1 @@ +.a.svelte-xyz~.b.svelte-xyz{color:green}.a.svelte-xyz~.c.svelte-xyz{color:green}.a.svelte-xyz~.d.svelte-xyz{color:green}.b.svelte-xyz~.e.svelte-xyz{color:green}.c.svelte-xyz~.e.svelte-xyz{color:green}.d.svelte-xyz~.e.svelte-xyz{color:green}.a.svelte-xyz~.e.svelte-xyz{color:green} \ No newline at end of file diff --git a/test/css/samples/general-siblings-combinator-await/expected.html b/test/css/samples/general-siblings-combinator-await/expected.html new file mode 100644 index 0000000000..3d8ac9f966 --- /dev/null +++ b/test/css/samples/general-siblings-combinator-await/expected.html @@ -0,0 +1,3 @@ +
+
+
\ No newline at end of file diff --git a/test/css/samples/general-siblings-combinator-await/input.svelte b/test/css/samples/general-siblings-combinator-await/input.svelte new file mode 100644 index 0000000000..8aeadab170 --- /dev/null +++ b/test/css/samples/general-siblings-combinator-await/input.svelte @@ -0,0 +1,30 @@ + + + + +
+ +{#await promise} +
+{:then value} +
+{:catch error} +
+{/await} + +
\ No newline at end of file diff --git a/test/css/samples/general-siblings-combinator-each-2/_config.js b/test/css/samples/general-siblings-combinator-each-2/_config.js new file mode 100644 index 0000000000..c81f1a9f82 --- /dev/null +++ b/test/css/samples/general-siblings-combinator-each-2/_config.js @@ -0,0 +1,3 @@ +export default { + warnings: [] +}; diff --git a/test/css/samples/general-siblings-combinator-each-2/expected.css b/test/css/samples/general-siblings-combinator-each-2/expected.css new file mode 100644 index 0000000000..d197058b24 --- /dev/null +++ b/test/css/samples/general-siblings-combinator-each-2/expected.css @@ -0,0 +1 @@ +.a.svelte-xyz~.b.svelte-xyz{color:green}.c.svelte-xyz~.d.svelte-xyz{color:green}.a.svelte-xyz~.d.svelte-xyz{color:green}.c.svelte-xyz~.b.svelte-xyz{color:green}.b.svelte-xyz~.c.svelte-xyz{color:green}.a.svelte-xyz~.c.svelte-xyz{color:green} \ No newline at end of file diff --git a/test/css/samples/general-siblings-combinator-each-2/expected.html b/test/css/samples/general-siblings-combinator-each-2/expected.html new file mode 100644 index 0000000000..331a5e4317 --- /dev/null +++ b/test/css/samples/general-siblings-combinator-each-2/expected.html @@ -0,0 +1,4 @@ +
+
+
+
\ No newline at end of file diff --git a/test/css/samples/general-siblings-combinator-each-2/input.svelte b/test/css/samples/general-siblings-combinator-each-2/input.svelte new file mode 100644 index 0000000000..5bbdbdef66 --- /dev/null +++ b/test/css/samples/general-siblings-combinator-each-2/input.svelte @@ -0,0 +1,37 @@ + + + + +
+ +{#each array as item} +
+
+{/each} + +
\ No newline at end of file diff --git a/test/css/samples/general-siblings-combinator-each-else-nested/_config.js b/test/css/samples/general-siblings-combinator-each-else-nested/_config.js new file mode 100644 index 0000000000..cf241d856d --- /dev/null +++ b/test/css/samples/general-siblings-combinator-each-else-nested/_config.js @@ -0,0 +1,18 @@ +export default { + warnings: [ + { + code: "css-unused-selector", + frame: ` + 33: + 34: /* no match */ + 35: .e ~ .f { color: green; } + ^ + 36: + 37:`, + message: 'Unused CSS selector ".e ~ .f"', + pos: 812, + start: { character: 812, column: 1, line: 35 }, + end: { character: 819, column: 8, line: 35 } + } + ] +}; diff --git a/test/css/samples/general-siblings-combinator-each-else-nested/expected.css b/test/css/samples/general-siblings-combinator-each-else-nested/expected.css new file mode 100644 index 0000000000..b055f35ecd --- /dev/null +++ b/test/css/samples/general-siblings-combinator-each-else-nested/expected.css @@ -0,0 +1 @@ +.a.svelte-xyz~.e.svelte-xyz.svelte-xyz.svelte-xyz{color:green}.a.svelte-xyz~.f.svelte-xyz.svelte-xyz.svelte-xyz{color:green}.b.svelte-xyz~.c.svelte-xyz.svelte-xyz.svelte-xyz{color:green}.b.svelte-xyz~.d.svelte-xyz.svelte-xyz.svelte-xyz{color:green}.c.svelte-xyz~.e.svelte-xyz.svelte-xyz.svelte-xyz{color:green}.c.svelte-xyz~.f.svelte-xyz.svelte-xyz.svelte-xyz{color:green}.d.svelte-xyz~.e.svelte-xyz.svelte-xyz.svelte-xyz{color:green}.d.svelte-xyz~.f.svelte-xyz.svelte-xyz.svelte-xyz{color:green}.e.svelte-xyz~.e.svelte-xyz.svelte-xyz.svelte-xyz{color:green}.i.svelte-xyz~.j.svelte-xyz.svelte-xyz.svelte-xyz{color:green}.g.svelte-xyz~.h.svelte-xyz~.j.svelte-xyz.svelte-xyz{color:green}.g.svelte-xyz~.i.svelte-xyz~.j.svelte-xyz.svelte-xyz{color:green}.m.svelte-xyz~.m.svelte-xyz.svelte-xyz.svelte-xyz{color:green}.m.svelte-xyz~.l.svelte-xyz.svelte-xyz.svelte-xyz{color:green}.l.svelte-xyz~.m.svelte-xyz.svelte-xyz.svelte-xyz{color:green}.a.svelte-xyz~.c.svelte-xyz.svelte-xyz.svelte-xyz{color:green}.a.svelte-xyz~.g.svelte-xyz.svelte-xyz.svelte-xyz{color:green}.b.svelte-xyz~.e.svelte-xyz.svelte-xyz.svelte-xyz{color:green}.c.svelte-xyz~.g.svelte-xyz.svelte-xyz.svelte-xyz{color:green}.c.svelte-xyz~.k.svelte-xyz.svelte-xyz.svelte-xyz{color:green}.d.svelte-xyz~.d.svelte-xyz.svelte-xyz.svelte-xyz{color:green}.g.svelte-xyz~.g.svelte-xyz.svelte-xyz.svelte-xyz{color:green}.h.svelte-xyz~.h.svelte-xyz.svelte-xyz.svelte-xyz{color:green}.i.svelte-xyz~.i.svelte-xyz.svelte-xyz.svelte-xyz{color:green}.j.svelte-xyz~.j.svelte-xyz.svelte-xyz.svelte-xyz{color:green}.g.svelte-xyz~.j.svelte-xyz.svelte-xyz.svelte-xyz{color:green}.g.svelte-xyz~.h.svelte-xyz~.i.svelte-xyz~.j.svelte-xyz{color:green} \ No newline at end of file diff --git a/test/css/samples/general-siblings-combinator-each-else-nested/expected.html b/test/css/samples/general-siblings-combinator-each-else-nested/expected.html new file mode 100644 index 0000000000..67dd05f677 --- /dev/null +++ b/test/css/samples/general-siblings-combinator-each-else-nested/expected.html @@ -0,0 +1,3 @@ +
+
+
\ No newline at end of file diff --git a/test/css/samples/general-siblings-combinator-each-else-nested/input.svelte b/test/css/samples/general-siblings-combinator-each-else-nested/input.svelte new file mode 100644 index 0000000000..63a1123708 --- /dev/null +++ b/test/css/samples/general-siblings-combinator-each-else-nested/input.svelte @@ -0,0 +1,77 @@ + + + + +
+ +{#each array as a} +
+ {#each array as b} +
+ {:else} +
+ {/each} +{/each} + +{#each array as c} + {#each array as d} +
+ {/each} +{:else} +
+{/each} + +{#each array as x} +
+ {#each array as y} + {#each array as z} +
+ {/each} + {:else} +
+ {/each} +
+{/each} + +
+ +{#each array as item} + {#each array as item} +
+ {:else} +
+ {/each} +{/each} \ No newline at end of file diff --git a/test/css/samples/general-siblings-combinator-each-else/_config.js b/test/css/samples/general-siblings-combinator-each-else/_config.js new file mode 100644 index 0000000000..4d9beceeb2 --- /dev/null +++ b/test/css/samples/general-siblings-combinator-each-else/_config.js @@ -0,0 +1,18 @@ +export default { + warnings: [ + { + code: "css-unused-selector", + frame: ` + 11: + 12: /* no match */ + 13: .b ~ .c { color: green; } + ^ + 14: + 15:`, + message: 'Unused CSS selector ".b ~ .c"', + pos: 199, + start: { character: 199, column: 1, line: 13 }, + end: { character: 206, column: 8, line: 13 } + } + ] +}; diff --git a/test/css/samples/general-siblings-combinator-each-else/expected.css b/test/css/samples/general-siblings-combinator-each-else/expected.css new file mode 100644 index 0000000000..31fafa3243 --- /dev/null +++ b/test/css/samples/general-siblings-combinator-each-else/expected.css @@ -0,0 +1 @@ +.a.svelte-xyz~.b.svelte-xyz{color:green}.a.svelte-xyz~.c.svelte-xyz{color:green}.b.svelte-xyz~.d.svelte-xyz{color:green}.c.svelte-xyz~.d.svelte-xyz{color:green}.a.svelte-xyz~.d.svelte-xyz{color:green} \ No newline at end of file diff --git a/test/css/samples/general-siblings-combinator-each-else/expected.html b/test/css/samples/general-siblings-combinator-each-else/expected.html new file mode 100644 index 0000000000..fb838a55fd --- /dev/null +++ b/test/css/samples/general-siblings-combinator-each-else/expected.html @@ -0,0 +1,3 @@ +
+
+
\ No newline at end of file diff --git a/test/css/samples/general-siblings-combinator-each-else/input.svelte b/test/css/samples/general-siblings-combinator-each-else/input.svelte new file mode 100644 index 0000000000..5cd78853ca --- /dev/null +++ b/test/css/samples/general-siblings-combinator-each-else/input.svelte @@ -0,0 +1,24 @@ + + + + +
+ +{#each array as item} +
+{:else} +
+{/each} + +
\ No newline at end of file diff --git a/test/css/samples/general-siblings-combinator-each-nested/_config.js b/test/css/samples/general-siblings-combinator-each-nested/_config.js new file mode 100644 index 0000000000..c81f1a9f82 --- /dev/null +++ b/test/css/samples/general-siblings-combinator-each-nested/_config.js @@ -0,0 +1,3 @@ +export default { + warnings: [] +}; diff --git a/test/css/samples/general-siblings-combinator-each-nested/expected.css b/test/css/samples/general-siblings-combinator-each-nested/expected.css new file mode 100644 index 0000000000..5bf1f832ae --- /dev/null +++ b/test/css/samples/general-siblings-combinator-each-nested/expected.css @@ -0,0 +1 @@ +.a.svelte-xyz~.d.svelte-xyz.svelte-xyz{color:green}.a.svelte-xyz~.e.svelte-xyz.svelte-xyz{color:green}.a.svelte-xyz~.f.svelte-xyz.svelte-xyz{color:green}.a.svelte-xyz~.g.svelte-xyz.svelte-xyz{color:green}.c.svelte-xyz~.d.svelte-xyz.svelte-xyz{color:green}.c.svelte-xyz~.e.svelte-xyz.svelte-xyz{color:green}.c.svelte-xyz~.f.svelte-xyz.svelte-xyz{color:green}.c.svelte-xyz~.g.svelte-xyz.svelte-xyz{color:green}.j.svelte-xyz~.m.svelte-xyz.svelte-xyz{color:green}.j.svelte-xyz~.n.svelte-xyz.svelte-xyz{color:green}.j.svelte-xyz~.o.svelte-xyz.svelte-xyz{color:green}.k.svelte-xyz~.m.svelte-xyz.svelte-xyz{color:green}.k.svelte-xyz~.n.svelte-xyz.svelte-xyz{color:green}.k.svelte-xyz~.o.svelte-xyz.svelte-xyz{color:green}.l.svelte-xyz~.m.svelte-xyz.svelte-xyz{color:green}.l.svelte-xyz~.n.svelte-xyz.svelte-xyz{color:green}.l.svelte-xyz~.o.svelte-xyz.svelte-xyz{color:green}.d.svelte-xyz~.e.svelte-xyz.svelte-xyz{color:green}.e.svelte-xyz~.f.svelte-xyz.svelte-xyz{color:green}.g.svelte-xyz~.h.svelte-xyz.svelte-xyz{color:green}.f.svelte-xyz~.d.svelte-xyz.svelte-xyz{color:green}.f.svelte-xyz~.e.svelte-xyz.svelte-xyz{color:green}.f.svelte-xyz~.f.svelte-xyz.svelte-xyz{color:green}.h.svelte-xyz~.g.svelte-xyz.svelte-xyz{color:green}.i.svelte-xyz~.h.svelte-xyz.svelte-xyz{color:green}.i.svelte-xyz~.g.svelte-xyz.svelte-xyz{color:green}.d.svelte-xyz~.d.svelte-xyz.svelte-xyz{color:green}.e.svelte-xyz~.e.svelte-xyz.svelte-xyz{color:green}.f.svelte-xyz~.f.svelte-xyz.svelte-xyz{color:green}.g.svelte-xyz~.g.svelte-xyz.svelte-xyz{color:green}.h.svelte-xyz~.h.svelte-xyz.svelte-xyz{color:green}.i.svelte-xyz~.i.svelte-xyz.svelte-xyz{color:green}.e.svelte-xyz~.e.svelte-xyz~.f.svelte-xyz{color:green}.e.svelte-xyz~.e.svelte-xyz~.d.svelte-xyz{color:green}.h.svelte-xyz~.h.svelte-xyz~.i.svelte-xyz{color:green}.h.svelte-xyz~.h.svelte-xyz~.g.svelte-xyz{color:green}.a.svelte-xyz~.h.svelte-xyz.svelte-xyz{color:green}.a.svelte-xyz~.i.svelte-xyz.svelte-xyz{color:green}.c.svelte-xyz~.h.svelte-xyz.svelte-xyz{color:green}.c.svelte-xyz~.i.svelte-xyz.svelte-xyz{color:green}.d.svelte-xyz~.f.svelte-xyz.svelte-xyz{color:green}.d.svelte-xyz~.g.svelte-xyz.svelte-xyz{color:green}.e.svelte-xyz~.g.svelte-xyz.svelte-xyz{color:green}.g.svelte-xyz~.i.svelte-xyz.svelte-xyz{color:green} \ No newline at end of file diff --git a/test/css/samples/general-siblings-combinator-each-nested/expected.html b/test/css/samples/general-siblings-combinator-each-nested/expected.html new file mode 100644 index 0000000000..340d6fc4c8 --- /dev/null +++ b/test/css/samples/general-siblings-combinator-each-nested/expected.html @@ -0,0 +1,15 @@ +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file diff --git a/test/css/samples/general-siblings-combinator-each-nested/input.svelte b/test/css/samples/general-siblings-combinator-each-nested/input.svelte new file mode 100644 index 0000000000..b7c7377015 --- /dev/null +++ b/test/css/samples/general-siblings-combinator-each-nested/input.svelte @@ -0,0 +1,113 @@ + + + + +
+ +{#each array as item} +
+
+{/each} + +{#each array as item} + {#each array as item} + {#each array as item} +
+ {/each} +
+ {/each} +
+{/each} + +{#each array as item} +
+ {#each array as item} +
+ {#each array as item} +
+ {/each} + {/each} +{/each} + +{#each array as item} +
+ {#each array as item} +
+ {#each array as item} +
+ {/each} + {/each} +{/each} + +{#each array as item} + {#each array as item} + {#each array as item} +
+ {/each} +
+ {/each} +
+{/each} \ No newline at end of file diff --git a/test/css/samples/general-siblings-combinator-each/expected.css b/test/css/samples/general-siblings-combinator-each/expected.css new file mode 100644 index 0000000000..8c48251bdd --- /dev/null +++ b/test/css/samples/general-siblings-combinator-each/expected.css @@ -0,0 +1 @@ +div.svelte-xyz~span.svelte-xyz{color:green} \ No newline at end of file diff --git a/test/css/samples/general-siblings-combinator-each/expected.html b/test/css/samples/general-siblings-combinator-each/expected.html new file mode 100644 index 0000000000..9d0416f01b --- /dev/null +++ b/test/css/samples/general-siblings-combinator-each/expected.html @@ -0,0 +1,6 @@ +
+ +
+ +
+ diff --git a/test/css/samples/general-siblings-combinator-each/input.svelte b/test/css/samples/general-siblings-combinator-each/input.svelte new file mode 100644 index 0000000000..ce65da109d --- /dev/null +++ b/test/css/samples/general-siblings-combinator-each/input.svelte @@ -0,0 +1,20 @@ + + + + +
+ +{#each array as item} + +
+ +
+{/each} + + \ No newline at end of file diff --git a/test/css/samples/general-siblings-combinator-if-not-exhaustive-with-each/_config.js b/test/css/samples/general-siblings-combinator-if-not-exhaustive-with-each/_config.js new file mode 100644 index 0000000000..0b5d391f50 --- /dev/null +++ b/test/css/samples/general-siblings-combinator-if-not-exhaustive-with-each/_config.js @@ -0,0 +1,18 @@ +export default { + warnings: [ + { + code: "css-unused-selector", + frame: ` + 16: + 17: /* no match */ + 18: .b ~ .c { color: green; } + ^ + 19: + 20:`, + message: 'Unused CSS selector ".b ~ .c"', + pos: 319, + start: { character: 319, column: 1, line: 18 }, + end: { character: 326, column: 8, line: 18 } + } + ] +}; diff --git a/test/css/samples/general-siblings-combinator-if-not-exhaustive-with-each/expected.css b/test/css/samples/general-siblings-combinator-if-not-exhaustive-with-each/expected.css new file mode 100644 index 0000000000..e6a974efca --- /dev/null +++ b/test/css/samples/general-siblings-combinator-if-not-exhaustive-with-each/expected.css @@ -0,0 +1 @@ +.a.svelte-xyz~.b.svelte-xyz.svelte-xyz.svelte-xyz{color:green}.a.svelte-xyz~.c.svelte-xyz.svelte-xyz.svelte-xyz{color:green}.a.svelte-xyz~.d.svelte-xyz.svelte-xyz.svelte-xyz{color:green}.b.svelte-xyz~.d.svelte-xyz.svelte-xyz.svelte-xyz{color:green}.c.svelte-xyz~.d.svelte-xyz.svelte-xyz.svelte-xyz{color:green}.a.svelte-xyz~.c.svelte-xyz~.c.svelte-xyz.svelte-xyz{color:green}.c.svelte-xyz~.c.svelte-xyz~.d.svelte-xyz.svelte-xyz{color:green}.a.svelte-xyz~.c.svelte-xyz~.c.svelte-xyz~.d.svelte-xyz{color:green} \ No newline at end of file diff --git a/test/css/samples/general-siblings-combinator-if-not-exhaustive-with-each/expected.html b/test/css/samples/general-siblings-combinator-if-not-exhaustive-with-each/expected.html new file mode 100644 index 0000000000..fb838a55fd --- /dev/null +++ b/test/css/samples/general-siblings-combinator-if-not-exhaustive-with-each/expected.html @@ -0,0 +1,3 @@ +
+
+
\ No newline at end of file diff --git a/test/css/samples/general-siblings-combinator-if-not-exhaustive-with-each/input.svelte b/test/css/samples/general-siblings-combinator-if-not-exhaustive-with-each/input.svelte new file mode 100644 index 0000000000..2b53f7b5b8 --- /dev/null +++ b/test/css/samples/general-siblings-combinator-if-not-exhaustive-with-each/input.svelte @@ -0,0 +1,31 @@ + + + + +
+ +{#if foo} +
+{:else} + {#each array as item} +
+ {/each} +{/if} + +
\ No newline at end of file diff --git a/test/css/samples/general-siblings-combinator-if-not-exhaustive/_config.js b/test/css/samples/general-siblings-combinator-if-not-exhaustive/_config.js new file mode 100644 index 0000000000..81fb595d68 --- /dev/null +++ b/test/css/samples/general-siblings-combinator-if-not-exhaustive/_config.js @@ -0,0 +1,18 @@ +export default { + warnings: [ + { + code: "css-unused-selector", + frame: ` + 12: + 13: /* no match */ + 14: .b ~ .c { color: green; } + ^ + 15: + 16:`, + message: 'Unused CSS selector ".b ~ .c"', + pos: 215, + start: { character: 215, column: 1, line: 14 }, + end: { character: 222, column: 8, line: 14 } + } + ] +}; diff --git a/test/css/samples/general-siblings-combinator-if-not-exhaustive/expected.css b/test/css/samples/general-siblings-combinator-if-not-exhaustive/expected.css new file mode 100644 index 0000000000..dc7ee1b62b --- /dev/null +++ b/test/css/samples/general-siblings-combinator-if-not-exhaustive/expected.css @@ -0,0 +1 @@ +.a.svelte-xyz~.b.svelte-xyz{color:green}.a.svelte-xyz~.c.svelte-xyz{color:green}.a.svelte-xyz~.d.svelte-xyz{color:green}.b.svelte-xyz~.d.svelte-xyz{color:green}.c.svelte-xyz~.d.svelte-xyz{color:green} \ No newline at end of file diff --git a/test/css/samples/general-siblings-combinator-if-not-exhaustive/expected.html b/test/css/samples/general-siblings-combinator-if-not-exhaustive/expected.html new file mode 100644 index 0000000000..813e778dc6 --- /dev/null +++ b/test/css/samples/general-siblings-combinator-if-not-exhaustive/expected.html @@ -0,0 +1,3 @@ +
+
+
\ No newline at end of file diff --git a/test/css/samples/general-siblings-combinator-if-not-exhaustive/input.svelte b/test/css/samples/general-siblings-combinator-if-not-exhaustive/input.svelte new file mode 100644 index 0000000000..3e5c5af7a2 --- /dev/null +++ b/test/css/samples/general-siblings-combinator-if-not-exhaustive/input.svelte @@ -0,0 +1,25 @@ + + + + +
+ +{#if foo} +
+{:else if bar} +
+{/if} + +
\ No newline at end of file diff --git a/test/css/samples/general-siblings-combinator-if/_config.js b/test/css/samples/general-siblings-combinator-if/_config.js new file mode 100644 index 0000000000..cbc3d8a784 --- /dev/null +++ b/test/css/samples/general-siblings-combinator-if/_config.js @@ -0,0 +1,46 @@ +export default { + warnings: [ + { + code: "css-unused-selector", + frame: ` + 14: + 15: /* no match */ + 16: .b ~ .c { color: green; } + ^ + 17: .b ~ .d { color: green; } + 18: .c ~ .d { color: green; }`, + message: 'Unused CSS selector ".b ~ .c"', + pos: 269, + start: { character: 269, column: 1, line: 16 }, + end: { character: 276, column: 8, line: 16 } + }, + { + code: "css-unused-selector", + frame: ` + 15: /* no match */ + 16: .b ~ .c { color: green; } + 17: .b ~ .d { color: green; } + ^ + 18: .c ~ .d { color: green; } + 19: `, + message: 'Unused CSS selector ".b ~ .d"', + pos: 296, + start: { character: 296, column: 1, line: 17 }, + end: { character: 303, column: 8, line: 17 } + }, + { + code: "css-unused-selector", + frame: ` + 16: .b ~ .c { color: green; } + 17: .b ~ .d { color: green; } + 18: .c ~ .d { color: green; } + ^ + 19: + 20:`, + message: 'Unused CSS selector ".c ~ .d"', + pos: 323, + start: { character: 323, column: 1, line: 18 }, + end: { character: 330, column: 8, line: 18 } + } + ] +}; diff --git a/test/css/samples/general-siblings-combinator-if/expected.css b/test/css/samples/general-siblings-combinator-if/expected.css new file mode 100644 index 0000000000..94a5494597 --- /dev/null +++ b/test/css/samples/general-siblings-combinator-if/expected.css @@ -0,0 +1 @@ +.a.svelte-xyz~.b.svelte-xyz{color:green}.a.svelte-xyz~.c.svelte-xyz{color:green}.a.svelte-xyz~.d.svelte-xyz{color:green}.b.svelte-xyz~.e.svelte-xyz{color:green}.c.svelte-xyz~.e.svelte-xyz{color:green}.d.svelte-xyz~.e.svelte-xyz{color:green}.a.svelte-xyz~.e.svelte-xyz{color:green} \ No newline at end of file diff --git a/test/css/samples/general-siblings-combinator-if/expected.html b/test/css/samples/general-siblings-combinator-if/expected.html new file mode 100644 index 0000000000..3d8ac9f966 --- /dev/null +++ b/test/css/samples/general-siblings-combinator-if/expected.html @@ -0,0 +1,3 @@ +
+
+
\ No newline at end of file diff --git a/test/css/samples/general-siblings-combinator-if/input.svelte b/test/css/samples/general-siblings-combinator-if/input.svelte new file mode 100644 index 0000000000..fca5499f2e --- /dev/null +++ b/test/css/samples/general-siblings-combinator-if/input.svelte @@ -0,0 +1,31 @@ + + + + +
+ +{#if foo} +
+{:else if bar} +
+{:else} +
+{/if} + +
\ No newline at end of file diff --git a/test/css/samples/general-siblings-combinator-slot/_config.js b/test/css/samples/general-siblings-combinator-slot/_config.js new file mode 100644 index 0000000000..4cf743c0a0 --- /dev/null +++ b/test/css/samples/general-siblings-combinator-slot/_config.js @@ -0,0 +1,88 @@ +export default { + warnings: [ + { + code: "css-unused-selector", + frame: ` + 8: + 9: /* no match */ + 10: .a ~ .b { color: green; } + ^ + 11: .b ~ .c { color: green; } + 12: .c ~ .f { color: green; }`, + message: 'Unused CSS selector ".a ~ .b"', + pos: 111, + start: { character: 111, column: 1, line: 10 }, + end: { character: 118, column: 8, line: 10 } + }, + { + code: "css-unused-selector", + frame: ` + 9: /* no match */ + 10: .a ~ .b { color: green; } + 11: .b ~ .c { color: green; } + ^ + 12: .c ~ .f { color: green; } + 13: .f ~ .g { color: green; }`, + message: 'Unused CSS selector ".b ~ .c"', + pos: 138, + start: { character: 138, column: 1, line: 11 }, + end: { character: 145, column: 8, line: 11 } + }, + { + code: "css-unused-selector", + frame: ` + 10: .a ~ .b { color: green; } + 11: .b ~ .c { color: green; } + 12: .c ~ .f { color: green; } + ^ + 13: .f ~ .g { color: green; } + 14: .b ~ .f { color: green; }`, + message: 'Unused CSS selector ".c ~ .f"', + pos: 165, + start: { character: 165, column: 1, line: 12 }, + end: { character: 172, column: 8, line: 12 } + }, + { + code: "css-unused-selector", + frame: ` + 11: .b ~ .c { color: green; } + 12: .c ~ .f { color: green; } + 13: .f ~ .g { color: green; } + ^ + 14: .b ~ .f { color: green; } + 15: .b ~ .g { color: green; }`, + message: 'Unused CSS selector ".f ~ .g"', + pos: 192, + start: { character: 192, column: 1, line: 13 }, + end: { character: 199, column: 8, line: 13 } + }, + { + code: "css-unused-selector", + frame: ` + 12: .c ~ .f { color: green; } + 13: .f ~ .g { color: green; } + 14: .b ~ .f { color: green; } + ^ + 15: .b ~ .g { color: green; } + 16: `, + message: 'Unused CSS selector ".b ~ .f"', + pos: 219, + start: { character: 219, column: 1, line: 14 }, + end: { character: 226, column: 8, line: 14 } + }, + { + code: "css-unused-selector", + frame: ` + 13: .f ~ .g { color: green; } + 14: .b ~ .f { color: green; } + 15: .b ~ .g { color: green; } + ^ + 16: + 17:`, + message: 'Unused CSS selector ".b ~ .g"', + pos: 246, + start: { character: 246, column: 1, line: 15 }, + end: { character: 253, column: 8, line: 15 } + } + ] +}; diff --git a/test/css/samples/general-siblings-combinator-slot/expected.css b/test/css/samples/general-siblings-combinator-slot/expected.css new file mode 100644 index 0000000000..29325e0cef --- /dev/null +++ b/test/css/samples/general-siblings-combinator-slot/expected.css @@ -0,0 +1 @@ +.d.svelte-xyz~.e.svelte-xyz{color:green}.a.svelte-xyz~.g.svelte-xyz{color:green} \ No newline at end of file diff --git a/test/css/samples/general-siblings-combinator-slot/input.svelte b/test/css/samples/general-siblings-combinator-slot/input.svelte new file mode 100644 index 0000000000..e5af4c0962 --- /dev/null +++ b/test/css/samples/general-siblings-combinator-slot/input.svelte @@ -0,0 +1,30 @@ + + + + +
+ +
+ +
+
+
+
+ +
+ + +
\ No newline at end of file diff --git a/test/css/samples/general-siblings-combinator-star/_config.js b/test/css/samples/general-siblings-combinator-star/_config.js new file mode 100644 index 0000000000..64e5baad19 --- /dev/null +++ b/test/css/samples/general-siblings-combinator-star/_config.js @@ -0,0 +1,18 @@ +export default { + warnings: [ + { + code: "css-unused-selector", + frame: ` + 3: margin-left: 4px; + 4: } + 5: .not-match > * ~ * { + ^ + 6: margin-left: 4px; + 7: }`, + message: 'Unused CSS selector ".not-match > * ~ *"', + pos: 50, + start: { character: 50, column: 1, line: 5 }, + end: { character: 68, column: 19, line: 5 } + } + ] +}; diff --git a/test/css/samples/general-siblings-combinator-star/expected.css b/test/css/samples/general-siblings-combinator-star/expected.css new file mode 100644 index 0000000000..de947fa47e --- /dev/null +++ b/test/css/samples/general-siblings-combinator-star/expected.css @@ -0,0 +1 @@ +.match.svelte-xyz>.svelte-xyz~.svelte-xyz{margin-left:4px} \ No newline at end of file diff --git a/test/css/samples/general-siblings-combinator-star/expected.html b/test/css/samples/general-siblings-combinator-star/expected.html new file mode 100644 index 0000000000..1cfae6e6f7 --- /dev/null +++ b/test/css/samples/general-siblings-combinator-star/expected.html @@ -0,0 +1,7 @@ +
+
+
+
+
+
+
\ No newline at end of file diff --git a/test/css/samples/general-siblings-combinator-star/input.svelte b/test/css/samples/general-siblings-combinator-star/input.svelte new file mode 100644 index 0000000000..a069685d4f --- /dev/null +++ b/test/css/samples/general-siblings-combinator-star/input.svelte @@ -0,0 +1,17 @@ + + +
+
+
+ +
+
+
+
\ No newline at end of file diff --git a/test/css/samples/general-siblings-combinator/_config.js b/test/css/samples/general-siblings-combinator/_config.js new file mode 100644 index 0000000000..6513366549 --- /dev/null +++ b/test/css/samples/general-siblings-combinator/_config.js @@ -0,0 +1,60 @@ +export default { + warnings: [ + { + code: "css-unused-selector", + frame: ` + 10: + 11: /* no match */ + 12: article ~ div { color: green; } + ^ + 13: span ~ article { color: green; } + 14: b ~ article { color: green; }`, + message: 'Unused CSS selector "article ~ div"', + pos: 275, + start: { character: 275, column: 1, line: 12 }, + end: { character: 288, column: 14, line: 12 } + }, + { + code: "css-unused-selector", + frame: ` + 11: /* no match */ + 12: article ~ div { color: green; } + 13: span ~ article { color: green; } + ^ + 14: b ~ article { color: green; } + 15: span ~ div { color: green; }`, + message: 'Unused CSS selector "span ~ article"', + pos: 308, + start: { character: 308, column: 1, line: 13 }, + end: { character: 322, column: 15, line: 13 } + }, + { + code: "css-unused-selector", + frame: ` + 12: article ~ div { color: green; } + 13: span ~ article { color: green; } + 14: b ~ article { color: green; } + ^ + 15: span ~ div { color: green; } + 16: `, + message: 'Unused CSS selector "b ~ article"', + pos: 342, + start: { character: 342, column: 1, line: 14 }, + end: { character: 353, column: 12, line: 14 } + }, + { + code: "css-unused-selector", + frame: ` + 13: span ~ article { color: green; } + 14: b ~ article { color: green; } + 15: span ~ div { color: green; } + ^ + 16: + 17:`, + message: 'Unused CSS selector "span ~ div"', + pos: 373, + start: { character: 373, column: 1, line: 15 }, + end: { character: 383, column: 11, line: 15 } + } + ] +}; diff --git a/test/css/samples/general-siblings-combinator/expected.css b/test/css/samples/general-siblings-combinator/expected.css new file mode 100644 index 0000000000..647a53f778 --- /dev/null +++ b/test/css/samples/general-siblings-combinator/expected.css @@ -0,0 +1 @@ +div.svelte-xyz~article.svelte-xyz.svelte-xyz{color:green}span.svelte-xyz~b.svelte-xyz.svelte-xyz{color:green}div.svelte-xyz span.svelte-xyz~b.svelte-xyz{color:green}.a.svelte-xyz~article.svelte-xyz.svelte-xyz{color:green}div.svelte-xyz~.b.svelte-xyz.svelte-xyz{color:green}.a.svelte-xyz~.c.svelte-xyz.svelte-xyz{color:green}article.svelte-xyz~details.svelte-xyz.svelte-xyz{color:green}.a.svelte-xyz~details.svelte-xyz.svelte-xyz{color:green} \ No newline at end of file diff --git a/test/css/samples/general-siblings-combinator/expected.html b/test/css/samples/general-siblings-combinator/expected.html new file mode 100644 index 0000000000..01fbffcae4 --- /dev/null +++ b/test/css/samples/general-siblings-combinator/expected.html @@ -0,0 +1,7 @@ +
+ + +
+
+

+
\ No newline at end of file diff --git a/test/css/samples/general-siblings-combinator/input.svelte b/test/css/samples/general-siblings-combinator/input.svelte new file mode 100644 index 0000000000..533702a3a3 --- /dev/null +++ b/test/css/samples/general-siblings-combinator/input.svelte @@ -0,0 +1,24 @@ + + +
+ + +
+
+

+
\ No newline at end of file diff --git a/test/css/samples/siblings-combinator-await-not-exhaustive/_config.js b/test/css/samples/siblings-combinator-await-not-exhaustive/_config.js new file mode 100644 index 0000000000..c81f1a9f82 --- /dev/null +++ b/test/css/samples/siblings-combinator-await-not-exhaustive/_config.js @@ -0,0 +1,3 @@ +export default { + warnings: [] +}; diff --git a/test/css/samples/siblings-combinator-await-not-exhaustive/expected.css b/test/css/samples/siblings-combinator-await-not-exhaustive/expected.css new file mode 100644 index 0000000000..60bb8e92dc --- /dev/null +++ b/test/css/samples/siblings-combinator-await-not-exhaustive/expected.css @@ -0,0 +1 @@ +.a.svelte-xyz+.b.svelte-xyz.svelte-xyz.svelte-xyz{color:green}.a.svelte-xyz+.c.svelte-xyz.svelte-xyz.svelte-xyz{color:green}.a.svelte-xyz+.d.svelte-xyz.svelte-xyz.svelte-xyz{color:green}.a.svelte-xyz+.e.svelte-xyz.svelte-xyz.svelte-xyz{color:green}.a.svelte-xyz+.f.svelte-xyz.svelte-xyz.svelte-xyz{color:green}.a.svelte-xyz+.g.svelte-xyz.svelte-xyz.svelte-xyz{color:green}.a.svelte-xyz+.h.svelte-xyz.svelte-xyz.svelte-xyz{color:green}.b.svelte-xyz+.d.svelte-xyz.svelte-xyz.svelte-xyz{color:green}.c.svelte-xyz+.d.svelte-xyz.svelte-xyz.svelte-xyz{color:green}.b.svelte-xyz+.e.svelte-xyz+.f.svelte-xyz+.h.svelte-xyz{color:green}.b.svelte-xyz+.d.svelte-xyz+.h.svelte-xyz.svelte-xyz{color:green}.c.svelte-xyz+.g.svelte-xyz.svelte-xyz.svelte-xyz{color:green} \ No newline at end of file diff --git a/test/css/samples/siblings-combinator-await-not-exhaustive/expected.html b/test/css/samples/siblings-combinator-await-not-exhaustive/expected.html new file mode 100644 index 0000000000..de97b02a5e --- /dev/null +++ b/test/css/samples/siblings-combinator-await-not-exhaustive/expected.html @@ -0,0 +1,4 @@ +
+
+
+
\ No newline at end of file diff --git a/test/css/samples/siblings-combinator-await-not-exhaustive/input.svelte b/test/css/samples/siblings-combinator-await-not-exhaustive/input.svelte new file mode 100644 index 0000000000..d3345c6edc --- /dev/null +++ b/test/css/samples/siblings-combinator-await-not-exhaustive/input.svelte @@ -0,0 +1,41 @@ + + + + +
+ +{#await promise then value} +
+{:catch error} +
+{/await} + +{#await promise} +
+{:catch error} +
+{/await} + +{#await promise} +
+{:then error} +
+{/await} + +
\ No newline at end of file diff --git a/test/css/samples/siblings-combinator-await/_config.js b/test/css/samples/siblings-combinator-await/_config.js new file mode 100644 index 0000000000..5af12d38e5 --- /dev/null +++ b/test/css/samples/siblings-combinator-await/_config.js @@ -0,0 +1,60 @@ +export default { + warnings: [ + { + code: "css-unused-selector", + frame: ` + 12: + 13: /* no match */ + 14: .a + .e { color: green; } + ^ + 15: .b + .c { color: green; } + 16: .c + .d { color: green; }`, + message: 'Unused CSS selector ".a + .e"', + pos: 242, + start: { character: 242, column: 1, line: 14 }, + end: { character: 249, column: 8, line: 14 } + }, + { + code: "css-unused-selector", + frame: ` + 13: /* no match */ + 14: .a + .e { color: green; } + 15: .b + .c { color: green; } + ^ + 16: .c + .d { color: green; } + 17: .b + .d { color: green; }`, + message: 'Unused CSS selector ".b + .c"', + pos: 269, + start: { character: 269, column: 1, line: 15 }, + end: { character: 276, column: 8, line: 15 } + }, + { + code: "css-unused-selector", + frame: ` + 14: .a + .e { color: green; } + 15: .b + .c { color: green; } + 16: .c + .d { color: green; } + ^ + 17: .b + .d { color: green; } + 18: `, + message: 'Unused CSS selector ".c + .d"', + pos: 296, + start: { character: 296, column: 1, line: 16 }, + end: { character: 303, column: 8, line: 16 } + }, + { + code: "css-unused-selector", + frame: ` + 15: .b + .c { color: green; } + 16: .c + .d { color: green; } + 17: .b + .d { color: green; } + ^ + 18: + 19:`, + message: 'Unused CSS selector ".b + .d"', + pos: 323, + start: { character: 323, column: 1, line: 17 }, + end: { character: 330, column: 8, line: 17 } + } + ] +}; diff --git a/test/css/samples/siblings-combinator-await/expected.css b/test/css/samples/siblings-combinator-await/expected.css new file mode 100644 index 0000000000..5ea39be7c2 --- /dev/null +++ b/test/css/samples/siblings-combinator-await/expected.css @@ -0,0 +1 @@ +.a.svelte-xyz+.b.svelte-xyz{color:green}.a.svelte-xyz+.c.svelte-xyz{color:green}.a.svelte-xyz+.d.svelte-xyz{color:green}.b.svelte-xyz+.e.svelte-xyz{color:green}.c.svelte-xyz+.e.svelte-xyz{color:green}.d.svelte-xyz+.e.svelte-xyz{color:green} \ No newline at end of file diff --git a/test/css/samples/siblings-combinator-await/expected.html b/test/css/samples/siblings-combinator-await/expected.html new file mode 100644 index 0000000000..3d8ac9f966 --- /dev/null +++ b/test/css/samples/siblings-combinator-await/expected.html @@ -0,0 +1,3 @@ +
+
+
\ No newline at end of file diff --git a/test/css/samples/siblings-combinator-await/input.svelte b/test/css/samples/siblings-combinator-await/input.svelte new file mode 100644 index 0000000000..07698c2a30 --- /dev/null +++ b/test/css/samples/siblings-combinator-await/input.svelte @@ -0,0 +1,30 @@ + + + + +
+ +{#await promise} +
+{:then value} +
+{:catch error} +
+{/await} + +
\ No newline at end of file diff --git a/test/css/samples/siblings-combinator-each-2/_config.js b/test/css/samples/siblings-combinator-each-2/_config.js new file mode 100644 index 0000000000..e4799f1055 --- /dev/null +++ b/test/css/samples/siblings-combinator-each-2/_config.js @@ -0,0 +1,18 @@ +export default { + warnings: [ + { + code: "css-unused-selector", + frame: ` + 24: } + 25: /* not match */ + 26: .a + .c { + ^ + 27: color: green; + 28: }`, + message: 'Unused CSS selector ".a + .c"', + pos: 320, + start: { character: 320, column: 1, line: 26 }, + end: { character: 327, column: 8, line: 26 } + } + ] +}; diff --git a/test/css/samples/siblings-combinator-each-2/expected.css b/test/css/samples/siblings-combinator-each-2/expected.css new file mode 100644 index 0000000000..60fa224269 --- /dev/null +++ b/test/css/samples/siblings-combinator-each-2/expected.css @@ -0,0 +1 @@ +.a.svelte-xyz+.b.svelte-xyz{color:green}.c.svelte-xyz+.d.svelte-xyz{color:green}.a.svelte-xyz+.d.svelte-xyz{color:green}.c.svelte-xyz+.b.svelte-xyz{color:green}.b.svelte-xyz+.c.svelte-xyz{color:green} \ No newline at end of file diff --git a/test/css/samples/siblings-combinator-each-2/expected.html b/test/css/samples/siblings-combinator-each-2/expected.html new file mode 100644 index 0000000000..331a5e4317 --- /dev/null +++ b/test/css/samples/siblings-combinator-each-2/expected.html @@ -0,0 +1,4 @@ +
+
+
+
\ No newline at end of file diff --git a/test/css/samples/siblings-combinator-each-2/input.svelte b/test/css/samples/siblings-combinator-each-2/input.svelte new file mode 100644 index 0000000000..bbad045fbc --- /dev/null +++ b/test/css/samples/siblings-combinator-each-2/input.svelte @@ -0,0 +1,38 @@ + + + + +
+ +{#each array as item} +
+
+{/each} + +
\ No newline at end of file diff --git a/test/css/samples/siblings-combinator-each-else-nested/_config.js b/test/css/samples/siblings-combinator-each-else-nested/_config.js new file mode 100644 index 0000000000..ab3fac6abe --- /dev/null +++ b/test/css/samples/siblings-combinator-each-else-nested/_config.js @@ -0,0 +1,144 @@ +export default { + warnings: [ + { + code: "css-unused-selector", + frame: ` + 21: + 22: /* no match */ + 23: .a + .c { color: green; } + ^ + 24: .a + .g { color: green; } + 25: .b + .e { color: green; }`, + message: 'Unused CSS selector ".a + .c"', + pos: 479, + start: { character: 479, column: 1, line: 23 }, + end: { character: 486, column: 8, line: 23 } + }, + { + code: "css-unused-selector", + frame: ` + 22: /* no match */ + 23: .a + .c { color: green; } + 24: .a + .g { color: green; } + ^ + 25: .b + .e { color: green; } + 26: .c + .g { color: green; }`, + message: 'Unused CSS selector ".a + .g"', + pos: 506, + start: { character: 506, column: 1, line: 24 }, + end: { character: 513, column: 8, line: 24 } + }, + { + code: "css-unused-selector", + frame: ` + 23: .a + .c { color: green; } + 24: .a + .g { color: green; } + 25: .b + .e { color: green; } + ^ + 26: .c + .g { color: green; } + 27: .c + .k { color: green; }`, + message: 'Unused CSS selector ".b + .e"', + pos: 533, + start: { character: 533, column: 1, line: 25 }, + end: { character: 540, column: 8, line: 25 } + }, + { + code: "css-unused-selector", + frame: ` + 24: .a + .g { color: green; } + 25: .b + .e { color: green; } + 26: .c + .g { color: green; } + ^ + 27: .c + .k { color: green; } + 28: .d + .d { color: green; }`, + message: 'Unused CSS selector ".c + .g"', + pos: 560, + start: { character: 560, column: 1, line: 26 }, + end: { character: 567, column: 8, line: 26 } + }, + { + code: "css-unused-selector", + frame: ` + 25: .b + .e { color: green; } + 26: .c + .g { color: green; } + 27: .c + .k { color: green; } + ^ + 28: .d + .d { color: green; } + 29: .e + .f { color: green; }`, + message: 'Unused CSS selector ".c + .k"', + pos: 587, + start: { character: 587, column: 1, line: 27 }, + end: { character: 594, column: 8, line: 27 } + }, + { + code: "css-unused-selector", + frame: ` + 26: .c + .g { color: green; } + 27: .c + .k { color: green; } + 28: .d + .d { color: green; } + ^ + 29: .e + .f { color: green; } + 30: .f + .f { color: green; }`, + message: 'Unused CSS selector ".d + .d"', + pos: 614, + start: { character: 614, column: 1, line: 28 }, + end: { character: 621, column: 8, line: 28 } + }, + { + code: "css-unused-selector", + frame: ` + 27: .c + .k { color: green; } + 28: .d + .d { color: green; } + 29: .e + .f { color: green; } + ^ + 30: .f + .f { color: green; } + 31: .g + .j { color: green; }`, + message: 'Unused CSS selector ".e + .f"', + pos: 641, + start: { character: 641, column: 1, line: 29 }, + end: { character: 648, column: 8, line: 29 } + }, + { + code: "css-unused-selector", + frame: ` + 28: .d + .d { color: green; } + 29: .e + .f { color: green; } + 30: .f + .f { color: green; } + ^ + 31: .g + .j { color: green; } + 32: .g + .h + .i + .j { color: green; }`, + message: 'Unused CSS selector ".f + .f"', + pos: 668, + start: { character: 668, column: 1, line: 30 }, + end: { character: 675, column: 8, line: 30 } + }, + { + code: "css-unused-selector", + frame: ` + 29: .e + .f { color: green; } + 30: .f + .f { color: green; } + 31: .g + .j { color: green; } + ^ + 32: .g + .h + .i + .j { color: green; } + 33: `, + message: 'Unused CSS selector ".g + .j"', + pos: 695, + start: { character: 695, column: 1, line: 31 }, + end: { character: 702, column: 8, line: 31 } + }, + { + code: "css-unused-selector", + frame: ` + 30: .f + .f { color: green; } + 31: .g + .j { color: green; } + 32: .g + .h + .i + .j { color: green; } + ^ + 33: + 34:`, + message: 'Unused CSS selector ".g + .h + .i + .j"', + pos: 722, + start: { character: 722, column: 1, line: 32 }, + end: { character: 739, column: 18, line: 32 } + } + ] +}; diff --git a/test/css/samples/siblings-combinator-each-else-nested/expected.css b/test/css/samples/siblings-combinator-each-else-nested/expected.css new file mode 100644 index 0000000000..aa4e04081d --- /dev/null +++ b/test/css/samples/siblings-combinator-each-else-nested/expected.css @@ -0,0 +1 @@ +.a.svelte-xyz+.e.svelte-xyz.svelte-xyz{color:green}.a.svelte-xyz+.f.svelte-xyz.svelte-xyz{color:green}.b.svelte-xyz+.c.svelte-xyz.svelte-xyz{color:green}.b.svelte-xyz+.d.svelte-xyz.svelte-xyz{color:green}.c.svelte-xyz+.e.svelte-xyz.svelte-xyz{color:green}.c.svelte-xyz+.f.svelte-xyz.svelte-xyz{color:green}.d.svelte-xyz+.e.svelte-xyz.svelte-xyz{color:green}.d.svelte-xyz+.f.svelte-xyz.svelte-xyz{color:green}.e.svelte-xyz+.e.svelte-xyz.svelte-xyz{color:green}.i.svelte-xyz+.j.svelte-xyz.svelte-xyz{color:green}.g.svelte-xyz+.h.svelte-xyz+.j.svelte-xyz{color:green}.g.svelte-xyz+.i.svelte-xyz+.j.svelte-xyz{color:green}.m.svelte-xyz+.m.svelte-xyz.svelte-xyz{color:green}.m.svelte-xyz+.l.svelte-xyz.svelte-xyz{color:green}.l.svelte-xyz+.m.svelte-xyz.svelte-xyz{color:green} \ No newline at end of file diff --git a/test/css/samples/siblings-combinator-each-else-nested/expected.html b/test/css/samples/siblings-combinator-each-else-nested/expected.html new file mode 100644 index 0000000000..5f25a2d38a --- /dev/null +++ b/test/css/samples/siblings-combinator-each-else-nested/expected.html @@ -0,0 +1,3 @@ +
+
+
\ No newline at end of file diff --git a/test/css/samples/siblings-combinator-each-else-nested/input.svelte b/test/css/samples/siblings-combinator-each-else-nested/input.svelte new file mode 100644 index 0000000000..bee9c6b1dc --- /dev/null +++ b/test/css/samples/siblings-combinator-each-else-nested/input.svelte @@ -0,0 +1,74 @@ + + + + +
+ +{#each array as a} +
+ {#each array as b} +
+ {:else} +
+ {/each} +{/each} + +{#each array as c} + {#each array as d} +
+ {/each} +{:else} +
+{/each} + +{#each array as item} +
+ {#each array as item} + {#each array as item} +
+ {/each} + {:else} +
+ {/each} +
+{/each} + +
+ +{#each array as item} + {#each array as item} +
+ {:else} +
+ {/each} +{/each} \ No newline at end of file diff --git a/test/css/samples/siblings-combinator-each-else/_config.js b/test/css/samples/siblings-combinator-each-else/_config.js new file mode 100644 index 0000000000..fcd961d5fe --- /dev/null +++ b/test/css/samples/siblings-combinator-each-else/_config.js @@ -0,0 +1,32 @@ +export default { + warnings: [ + { + code: "css-unused-selector", + frame: ` + 10: + 11: /* no match */ + 12: .a + .d { color: green; } + ^ + 13: .b + .c { color: green; } + 14: `, + message: 'Unused CSS selector ".a + .d"', + pos: 172, + start: { character: 172, column: 1, line: 12 }, + end: { character: 179, column: 8, line: 12 } + }, + { + code: "css-unused-selector", + frame: ` + 11: /* no match */ + 12: .a + .d { color: green; } + 13: .b + .c { color: green; } + ^ + 14: + 15:`, + message: 'Unused CSS selector ".b + .c"', + pos: 199, + start: { character: 199, column: 1, line: 13 }, + end: { character: 206, column: 8, line: 13 } + } + ] +}; diff --git a/test/css/samples/siblings-combinator-each-else/expected.css b/test/css/samples/siblings-combinator-each-else/expected.css new file mode 100644 index 0000000000..f82bca8215 --- /dev/null +++ b/test/css/samples/siblings-combinator-each-else/expected.css @@ -0,0 +1 @@ +.a.svelte-xyz+.b.svelte-xyz{color:green}.a.svelte-xyz+.c.svelte-xyz{color:green}.b.svelte-xyz+.d.svelte-xyz{color:green}.c.svelte-xyz+.d.svelte-xyz{color:green} \ No newline at end of file diff --git a/test/css/samples/siblings-combinator-each-else/expected.html b/test/css/samples/siblings-combinator-each-else/expected.html new file mode 100644 index 0000000000..fb838a55fd --- /dev/null +++ b/test/css/samples/siblings-combinator-each-else/expected.html @@ -0,0 +1,3 @@ +
+
+
\ No newline at end of file diff --git a/test/css/samples/siblings-combinator-each-else/input.svelte b/test/css/samples/siblings-combinator-each-else/input.svelte new file mode 100644 index 0000000000..ecd48968c2 --- /dev/null +++ b/test/css/samples/siblings-combinator-each-else/input.svelte @@ -0,0 +1,24 @@ + + + + +
+ +{#each array as item} +
+{:else} +
+{/each} + +
\ No newline at end of file diff --git a/test/css/samples/siblings-combinator-each-nested/_config.js b/test/css/samples/siblings-combinator-each-nested/_config.js new file mode 100644 index 0000000000..ce9c46fb06 --- /dev/null +++ b/test/css/samples/siblings-combinator-each-nested/_config.js @@ -0,0 +1,116 @@ +export default { + warnings: [ + { + code: "css-unused-selector", + frame: ` + 56: + 57: /* no match */ + 58: .a + .h { color: green; } + ^ + 59: .a + .i { color: green; } + 60: .c + .h { color: green; }`, + message: 'Unused CSS selector ".a + .h"', + pos: 1229, + start: { character: 1229, column: 1, line: 58 }, + end: { character: 1236, column: 8, line: 58 } + }, + { + code: "css-unused-selector", + frame: ` + 57: /* no match */ + 58: .a + .h { color: green; } + 59: .a + .i { color: green; } + ^ + 60: .c + .h { color: green; } + 61: .c + .i { color: green; }`, + message: 'Unused CSS selector ".a + .i"', + pos: 1256, + start: { character: 1256, column: 1, line: 59 }, + end: { character: 1263, column: 8, line: 59 } + }, + { + code: "css-unused-selector", + frame: ` + 58: .a + .h { color: green; } + 59: .a + .i { color: green; } + 60: .c + .h { color: green; } + ^ + 61: .c + .i { color: green; } + 62: .d + .f { color: green; }`, + message: 'Unused CSS selector ".c + .h"', + pos: 1283, + start: { character: 1283, column: 1, line: 60 }, + end: { character: 1290, column: 8, line: 60 } + }, + { + code: "css-unused-selector", + frame: ` + 59: .a + .i { color: green; } + 60: .c + .h { color: green; } + 61: .c + .i { color: green; } + ^ + 62: .d + .f { color: green; } + 63: .d + .g { color: green; }`, + message: 'Unused CSS selector ".c + .i"', + pos: 1310, + start: { character: 1310, column: 1, line: 61 }, + end: { character: 1317, column: 8, line: 61 } + }, + { + code: "css-unused-selector", + frame: ` + 60: .c + .h { color: green; } + 61: .c + .i { color: green; } + 62: .d + .f { color: green; } + ^ + 63: .d + .g { color: green; } + 64: .e + .g { color: green; }`, + message: 'Unused CSS selector ".d + .f"', + pos: 1337, + start: { character: 1337, column: 1, line: 62 }, + end: { character: 1344, column: 8, line: 62 } + }, + { + code: "css-unused-selector", + frame: ` + 61: .c + .i { color: green; } + 62: .d + .f { color: green; } + 63: .d + .g { color: green; } + ^ + 64: .e + .g { color: green; } + 65: .g + .i { color: green; }`, + message: 'Unused CSS selector ".d + .g"', + pos: 1364, + start: { character: 1364, column: 1, line: 63 }, + end: { character: 1371, column: 8, line: 63 } + }, + { + code: "css-unused-selector", + frame: ` + 62: .d + .f { color: green; } + 63: .d + .g { color: green; } + 64: .e + .g { color: green; } + ^ + 65: .g + .i { color: green; } + 66: `, + message: 'Unused CSS selector ".e + .g"', + pos: 1391, + start: { character: 1391, column: 1, line: 64 }, + end: { character: 1398, column: 8, line: 64 } + }, + { + code: "css-unused-selector", + frame: ` + 63: .d + .g { color: green; } + 64: .e + .g { color: green; } + 65: .g + .i { color: green; } + ^ + 66: + 67:`, + message: 'Unused CSS selector ".g + .i"', + pos: 1418, + start: { character: 1418, column: 1, line: 65 }, + end: { character: 1425, column: 8, line: 65 } + } + ] +}; diff --git a/test/css/samples/siblings-combinator-each-nested/expected.css b/test/css/samples/siblings-combinator-each-nested/expected.css new file mode 100644 index 0000000000..616d739670 --- /dev/null +++ b/test/css/samples/siblings-combinator-each-nested/expected.css @@ -0,0 +1 @@ +.a.svelte-xyz+.d.svelte-xyz.svelte-xyz{color:green}.a.svelte-xyz+.e.svelte-xyz.svelte-xyz{color:green}.a.svelte-xyz+.f.svelte-xyz.svelte-xyz{color:green}.a.svelte-xyz+.g.svelte-xyz.svelte-xyz{color:green}.c.svelte-xyz+.d.svelte-xyz.svelte-xyz{color:green}.c.svelte-xyz+.e.svelte-xyz.svelte-xyz{color:green}.c.svelte-xyz+.f.svelte-xyz.svelte-xyz{color:green}.c.svelte-xyz+.g.svelte-xyz.svelte-xyz{color:green}.j.svelte-xyz+.m.svelte-xyz.svelte-xyz{color:green}.j.svelte-xyz+.n.svelte-xyz.svelte-xyz{color:green}.j.svelte-xyz+.o.svelte-xyz.svelte-xyz{color:green}.k.svelte-xyz+.m.svelte-xyz.svelte-xyz{color:green}.k.svelte-xyz+.n.svelte-xyz.svelte-xyz{color:green}.k.svelte-xyz+.o.svelte-xyz.svelte-xyz{color:green}.l.svelte-xyz+.m.svelte-xyz.svelte-xyz{color:green}.l.svelte-xyz+.n.svelte-xyz.svelte-xyz{color:green}.l.svelte-xyz+.o.svelte-xyz.svelte-xyz{color:green}.d.svelte-xyz+.e.svelte-xyz.svelte-xyz{color:green}.e.svelte-xyz+.f.svelte-xyz.svelte-xyz{color:green}.g.svelte-xyz+.h.svelte-xyz.svelte-xyz{color:green}.f.svelte-xyz+.d.svelte-xyz.svelte-xyz{color:green}.f.svelte-xyz+.e.svelte-xyz.svelte-xyz{color:green}.f.svelte-xyz+.f.svelte-xyz.svelte-xyz{color:green}.h.svelte-xyz+.g.svelte-xyz.svelte-xyz{color:green}.i.svelte-xyz+.h.svelte-xyz.svelte-xyz{color:green}.i.svelte-xyz+.g.svelte-xyz.svelte-xyz{color:green}.d.svelte-xyz+.d.svelte-xyz.svelte-xyz{color:green}.e.svelte-xyz+.e.svelte-xyz.svelte-xyz{color:green}.f.svelte-xyz+.f.svelte-xyz.svelte-xyz{color:green}.g.svelte-xyz+.g.svelte-xyz.svelte-xyz{color:green}.h.svelte-xyz+.h.svelte-xyz.svelte-xyz{color:green}.i.svelte-xyz+.i.svelte-xyz.svelte-xyz{color:green}.e.svelte-xyz+.e.svelte-xyz+.f.svelte-xyz{color:green}.e.svelte-xyz+.e.svelte-xyz+.d.svelte-xyz{color:green}.h.svelte-xyz+.h.svelte-xyz+.i.svelte-xyz{color:green}.h.svelte-xyz+.h.svelte-xyz+.g.svelte-xyz{color:green} \ No newline at end of file diff --git a/test/css/samples/siblings-combinator-each-nested/expected.html b/test/css/samples/siblings-combinator-each-nested/expected.html new file mode 100644 index 0000000000..340d6fc4c8 --- /dev/null +++ b/test/css/samples/siblings-combinator-each-nested/expected.html @@ -0,0 +1,15 @@ +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file diff --git a/test/css/samples/siblings-combinator-each-nested/input.svelte b/test/css/samples/siblings-combinator-each-nested/input.svelte new file mode 100644 index 0000000000..b5b9242675 --- /dev/null +++ b/test/css/samples/siblings-combinator-each-nested/input.svelte @@ -0,0 +1,113 @@ + + + + +
+ +{#each array as item} +
+
+{/each} + +{#each array as item} + {#each array as item} + {#each array as item} +
+ {/each} +
+ {/each} +
+{/each} + +{#each array as item} +
+ {#each array as item} +
+ {#each array as item} +
+ {/each} + {/each} +{/each} + +{#each array as item} +
+ {#each array as item} +
+ {#each array as item} +
+ {/each} + {/each} +{/each} + +{#each array as item} + {#each array as item} + {#each array as item} +
+ {/each} +
+ {/each} +
+{/each} \ No newline at end of file diff --git a/test/css/samples/siblings-combinator-each/expected.css b/test/css/samples/siblings-combinator-each/expected.css new file mode 100644 index 0000000000..a46fc4ed4e --- /dev/null +++ b/test/css/samples/siblings-combinator-each/expected.css @@ -0,0 +1 @@ +div.svelte-xyz+span.svelte-xyz{color:green} \ No newline at end of file diff --git a/test/css/samples/siblings-combinator-each/expected.html b/test/css/samples/siblings-combinator-each/expected.html new file mode 100644 index 0000000000..9d0416f01b --- /dev/null +++ b/test/css/samples/siblings-combinator-each/expected.html @@ -0,0 +1,6 @@ +
+ +
+ +
+ diff --git a/test/css/samples/siblings-combinator-each/input.svelte b/test/css/samples/siblings-combinator-each/input.svelte new file mode 100644 index 0000000000..de77a25180 --- /dev/null +++ b/test/css/samples/siblings-combinator-each/input.svelte @@ -0,0 +1,20 @@ + + + + +
+ +{#each array as item} + +
+ +
+{/each} + + \ No newline at end of file diff --git a/test/css/samples/siblings-combinator-if-not-exhaustive-with-each/_config.js b/test/css/samples/siblings-combinator-if-not-exhaustive-with-each/_config.js new file mode 100644 index 0000000000..0155bf0cf1 --- /dev/null +++ b/test/css/samples/siblings-combinator-if-not-exhaustive-with-each/_config.js @@ -0,0 +1,18 @@ +export default { + warnings: [ + { + code: "css-unused-selector", + frame: ` + 16: + 17: /* no match */ + 18: .b + .c { color: green; } + ^ + 19: + 20:`, + message: 'Unused CSS selector ".b + .c"', + pos: 319, + start: { character: 319, column: 1, line: 18 }, + end: { character: 326, column: 8, line: 18 } + } + ] +}; diff --git a/test/css/samples/siblings-combinator-if-not-exhaustive-with-each/expected.css b/test/css/samples/siblings-combinator-if-not-exhaustive-with-each/expected.css new file mode 100644 index 0000000000..93cd539f00 --- /dev/null +++ b/test/css/samples/siblings-combinator-if-not-exhaustive-with-each/expected.css @@ -0,0 +1 @@ +.a.svelte-xyz+.b.svelte-xyz.svelte-xyz.svelte-xyz{color:green}.a.svelte-xyz+.c.svelte-xyz.svelte-xyz.svelte-xyz{color:green}.a.svelte-xyz+.d.svelte-xyz.svelte-xyz.svelte-xyz{color:green}.b.svelte-xyz+.d.svelte-xyz.svelte-xyz.svelte-xyz{color:green}.c.svelte-xyz+.d.svelte-xyz.svelte-xyz.svelte-xyz{color:green}.a.svelte-xyz+.c.svelte-xyz+.c.svelte-xyz.svelte-xyz{color:green}.c.svelte-xyz+.c.svelte-xyz+.d.svelte-xyz.svelte-xyz{color:green}.a.svelte-xyz+.c.svelte-xyz+.c.svelte-xyz+.d.svelte-xyz{color:green} \ No newline at end of file diff --git a/test/css/samples/siblings-combinator-if-not-exhaustive-with-each/expected.html b/test/css/samples/siblings-combinator-if-not-exhaustive-with-each/expected.html new file mode 100644 index 0000000000..fb838a55fd --- /dev/null +++ b/test/css/samples/siblings-combinator-if-not-exhaustive-with-each/expected.html @@ -0,0 +1,3 @@ +
+
+
\ No newline at end of file diff --git a/test/css/samples/siblings-combinator-if-not-exhaustive-with-each/input.svelte b/test/css/samples/siblings-combinator-if-not-exhaustive-with-each/input.svelte new file mode 100644 index 0000000000..ff9f10dc1c --- /dev/null +++ b/test/css/samples/siblings-combinator-if-not-exhaustive-with-each/input.svelte @@ -0,0 +1,31 @@ + + + + +
+ +{#if foo} +
+{:else} + {#each array as item} +
+ {/each} +{/if} + +
\ No newline at end of file diff --git a/test/css/samples/siblings-combinator-if-not-exhaustive/_config.js b/test/css/samples/siblings-combinator-if-not-exhaustive/_config.js new file mode 100644 index 0000000000..e01c358eff --- /dev/null +++ b/test/css/samples/siblings-combinator-if-not-exhaustive/_config.js @@ -0,0 +1,18 @@ +export default { + warnings: [ + { + code: "css-unused-selector", + frame: ` + 12: + 13: /* no match */ + 14: .b + .c { color: green; } + ^ + 15: + 16:`, + message: 'Unused CSS selector ".b + .c"', + pos: 215, + start: { character: 215, column: 1, line: 14 }, + end: { character: 222, column: 8, line: 14 } + } + ] +}; diff --git a/test/css/samples/siblings-combinator-if-not-exhaustive/expected.css b/test/css/samples/siblings-combinator-if-not-exhaustive/expected.css new file mode 100644 index 0000000000..b1225e36a1 --- /dev/null +++ b/test/css/samples/siblings-combinator-if-not-exhaustive/expected.css @@ -0,0 +1 @@ +.a.svelte-xyz+.b.svelte-xyz{color:green}.a.svelte-xyz+.c.svelte-xyz{color:green}.a.svelte-xyz+.d.svelte-xyz{color:green}.b.svelte-xyz+.d.svelte-xyz{color:green}.c.svelte-xyz+.d.svelte-xyz{color:green} \ No newline at end of file diff --git a/test/css/samples/siblings-combinator-if-not-exhaustive/expected.html b/test/css/samples/siblings-combinator-if-not-exhaustive/expected.html new file mode 100644 index 0000000000..813e778dc6 --- /dev/null +++ b/test/css/samples/siblings-combinator-if-not-exhaustive/expected.html @@ -0,0 +1,3 @@ +
+
+
\ No newline at end of file diff --git a/test/css/samples/siblings-combinator-if-not-exhaustive/input.svelte b/test/css/samples/siblings-combinator-if-not-exhaustive/input.svelte new file mode 100644 index 0000000000..4f832b3b47 --- /dev/null +++ b/test/css/samples/siblings-combinator-if-not-exhaustive/input.svelte @@ -0,0 +1,25 @@ + + + + +
+ +{#if foo} +
+{:else if bar} +
+{/if} + +
\ No newline at end of file diff --git a/test/css/samples/siblings-combinator-if/_config.js b/test/css/samples/siblings-combinator-if/_config.js new file mode 100644 index 0000000000..c2396f08ef --- /dev/null +++ b/test/css/samples/siblings-combinator-if/_config.js @@ -0,0 +1,60 @@ +export default { + warnings: [ + { + code: "css-unused-selector", + frame: ` + 13: + 14: /* no match */ + 15: .a + .e { color: green; } + ^ + 16: .b + .c { color: green; } + 17: .b + .d { color: green; }`, + message: 'Unused CSS selector ".a + .e"', + pos: 242, + start: { character: 242, column: 1, line: 15 }, + end: { character: 249, column: 8, line: 15 } + }, + { + code: "css-unused-selector", + frame: ` + 14: /* no match */ + 15: .a + .e { color: green; } + 16: .b + .c { color: green; } + ^ + 17: .b + .d { color: green; } + 18: .c + .d { color: green; }`, + message: 'Unused CSS selector ".b + .c"', + pos: 269, + start: { character: 269, column: 1, line: 16 }, + end: { character: 276, column: 8, line: 16 } + }, + { + code: "css-unused-selector", + frame: ` + 15: .a + .e { color: green; } + 16: .b + .c { color: green; } + 17: .b + .d { color: green; } + ^ + 18: .c + .d { color: green; } + 19: `, + message: 'Unused CSS selector ".b + .d"', + pos: 296, + start: { character: 296, column: 1, line: 17 }, + end: { character: 303, column: 8, line: 17 } + }, + { + code: "css-unused-selector", + frame: ` + 16: .b + .c { color: green; } + 17: .b + .d { color: green; } + 18: .c + .d { color: green; } + ^ + 19: + 20:`, + message: 'Unused CSS selector ".c + .d"', + pos: 323, + start: { character: 323, column: 1, line: 18 }, + end: { character: 330, column: 8, line: 18 } + } + ] +}; diff --git a/test/css/samples/siblings-combinator-if/expected.css b/test/css/samples/siblings-combinator-if/expected.css new file mode 100644 index 0000000000..5ea39be7c2 --- /dev/null +++ b/test/css/samples/siblings-combinator-if/expected.css @@ -0,0 +1 @@ +.a.svelte-xyz+.b.svelte-xyz{color:green}.a.svelte-xyz+.c.svelte-xyz{color:green}.a.svelte-xyz+.d.svelte-xyz{color:green}.b.svelte-xyz+.e.svelte-xyz{color:green}.c.svelte-xyz+.e.svelte-xyz{color:green}.d.svelte-xyz+.e.svelte-xyz{color:green} \ No newline at end of file diff --git a/test/css/samples/siblings-combinator-if/expected.html b/test/css/samples/siblings-combinator-if/expected.html new file mode 100644 index 0000000000..3d8ac9f966 --- /dev/null +++ b/test/css/samples/siblings-combinator-if/expected.html @@ -0,0 +1,3 @@ +
+
+
\ No newline at end of file diff --git a/test/css/samples/siblings-combinator-if/input.svelte b/test/css/samples/siblings-combinator-if/input.svelte new file mode 100644 index 0000000000..6cfc436876 --- /dev/null +++ b/test/css/samples/siblings-combinator-if/input.svelte @@ -0,0 +1,31 @@ + + + + +
+ +{#if foo} +
+{:else if bar} +
+{:else} +
+{/if} + +
\ No newline at end of file diff --git a/test/css/samples/siblings-combinator-slot/_config.js b/test/css/samples/siblings-combinator-slot/_config.js new file mode 100644 index 0000000000..c0a00500d4 --- /dev/null +++ b/test/css/samples/siblings-combinator-slot/_config.js @@ -0,0 +1,46 @@ +export default { + warnings: [ + { + code: "css-unused-selector", + frame: ` + 7: + 8: /* no match */ + 9: .a + .b { color: green; } + ^ + 10: .b + .c { color: green; } + 11: .c + .f { color: green; }`, + message: 'Unused CSS selector ".a + .b"', + pos: 84, + start: { character: 84, column: 1, line: 9 }, + end: { character: 91, column: 8, line: 9 } + }, + { + code: "css-unused-selector", + frame: ` + 8: /* no match */ + 9: .a + .b { color: green; } + 10: .b + .c { color: green; } + ^ + 11: .c + .f { color: green; } + 12: `, + message: 'Unused CSS selector ".b + .c"', + pos: 111, + start: { character: 111, column: 1, line: 10 }, + end: { character: 118, column: 8, line: 10 } + }, + { + code: "css-unused-selector", + frame: ` + 9: .a + .b { color: green; } + 10: .b + .c { color: green; } + 11: .c + .f { color: green; } + ^ + 12: + 13:`, + message: 'Unused CSS selector ".c + .f"', + pos: 138, + start: { character: 138, column: 1, line: 11 }, + end: { character: 145, column: 8, line: 11 } + } + ] +}; diff --git a/test/css/samples/siblings-combinator-slot/expected.css b/test/css/samples/siblings-combinator-slot/expected.css new file mode 100644 index 0000000000..bbdd03f274 --- /dev/null +++ b/test/css/samples/siblings-combinator-slot/expected.css @@ -0,0 +1 @@ +.d.svelte-xyz+.e.svelte-xyz{color:green} \ No newline at end of file diff --git a/test/css/samples/siblings-combinator-slot/input.svelte b/test/css/samples/siblings-combinator-slot/input.svelte new file mode 100644 index 0000000000..42fe0e4c30 --- /dev/null +++ b/test/css/samples/siblings-combinator-slot/input.svelte @@ -0,0 +1,24 @@ + + + + +
+ +
+ +
+
+
+
+ + +
\ No newline at end of file diff --git a/test/css/samples/siblings-combinator-star/_config.js b/test/css/samples/siblings-combinator-star/_config.js new file mode 100644 index 0000000000..32ff416981 --- /dev/null +++ b/test/css/samples/siblings-combinator-star/_config.js @@ -0,0 +1,18 @@ +export default { + warnings: [ + { + code: "css-unused-selector", + frame: ` + 3: margin-left: 4px; + 4: } + 5: .not-match > * + * { + ^ + 6: margin-left: 4px; + 7: }`, + message: 'Unused CSS selector ".not-match > * + *"', + pos: 50, + start: { character: 50, column: 1, line: 5 }, + end: { character: 68, column: 19, line: 5 } + } + ] +}; diff --git a/test/css/samples/siblings-combinator-star/expected.css b/test/css/samples/siblings-combinator-star/expected.css new file mode 100644 index 0000000000..c1a06945f9 --- /dev/null +++ b/test/css/samples/siblings-combinator-star/expected.css @@ -0,0 +1 @@ +.match.svelte-xyz>.svelte-xyz+.svelte-xyz{margin-left:4px} \ No newline at end of file diff --git a/test/css/samples/siblings-combinator-star/expected.html b/test/css/samples/siblings-combinator-star/expected.html new file mode 100644 index 0000000000..1cfae6e6f7 --- /dev/null +++ b/test/css/samples/siblings-combinator-star/expected.html @@ -0,0 +1,7 @@ +
+
+
+
+
+
+
\ No newline at end of file diff --git a/test/css/samples/siblings-combinator-star/input.svelte b/test/css/samples/siblings-combinator-star/input.svelte new file mode 100644 index 0000000000..ca837f2239 --- /dev/null +++ b/test/css/samples/siblings-combinator-star/input.svelte @@ -0,0 +1,17 @@ + + +
+
+
+ +
+
+
+
\ No newline at end of file diff --git a/test/css/samples/siblings-combinator/_config.js b/test/css/samples/siblings-combinator/_config.js new file mode 100644 index 0000000000..2285b5a837 --- /dev/null +++ b/test/css/samples/siblings-combinator/_config.js @@ -0,0 +1,62 @@ +export default { + warnings: [ + { + code: "css-unused-selector", + frame: ` + 3: color: green; + 4: } + 5: article + div { + ^ + 6: color: green; + 7: }`, + message: 'Unused CSS selector "article + div"', + pos: 45, + start: { character: 45, column: 1, line: 5 }, + end: { character: 58, column: 14, line: 5 } + }, + { + code: "css-unused-selector", + + frame:` + 6: color: green; + 7: } + 8: span + article { + ^ + 9: color: green; + 10: }`, + message: 'Unused CSS selector "span + article"', + pos: 81, + start: { character: 81, column: 1, line: 8 }, + end: { character: 95, column: 15, line: 8 } + }, + { + code: "css-unused-selector", + + frame: ` + 9: color: green; + 10: } + 11: b + article { + ^ + 12: color: green; + 13: }`, + message: 'Unused CSS selector "b + article"', + pos: 118, + start: { character: 118, column: 1, line: 11 }, + end: { character: 129, column: 12, line: 11 } + }, + { + code: "css-unused-selector", + frame: ` + 12: color: green; + 13: } + 14: span + div { + ^ + 15: color: green; + 16: }`, + message: 'Unused CSS selector "span + div"', + pos: 152, + start: { character: 152, column: 1, line: 14 }, + end: { character: 162, column: 11, line: 14 } + } + ] +}; diff --git a/test/css/samples/siblings-combinator/expected.css b/test/css/samples/siblings-combinator/expected.css new file mode 100644 index 0000000000..be01048cf1 --- /dev/null +++ b/test/css/samples/siblings-combinator/expected.css @@ -0,0 +1 @@ +div.svelte-xyz+article.svelte-xyz.svelte-xyz{color:green}span.svelte-xyz+b.svelte-xyz.svelte-xyz{color:green}div.svelte-xyz span.svelte-xyz+b.svelte-xyz{color:green}.a.svelte-xyz+article.svelte-xyz.svelte-xyz{color:green}div.svelte-xyz+.b.svelte-xyz.svelte-xyz{color:green} \ No newline at end of file diff --git a/test/css/samples/siblings-combinator/expected.html b/test/css/samples/siblings-combinator/expected.html new file mode 100644 index 0000000000..f4692365dd --- /dev/null +++ b/test/css/samples/siblings-combinator/expected.html @@ -0,0 +1,5 @@ +
+ + +
+
\ No newline at end of file diff --git a/test/css/samples/siblings-combinator/input.svelte b/test/css/samples/siblings-combinator/input.svelte new file mode 100644 index 0000000000..3e22076d52 --- /dev/null +++ b/test/css/samples/siblings-combinator/input.svelte @@ -0,0 +1,35 @@ + + +
+ + +
+
\ No newline at end of file From 0ca1dcd33c598dafc87e41cf363e723b9b7b6f8f Mon Sep 17 00:00:00 2001 From: Conduitry Date: Thu, 24 Sep 2020 16:07:33 -0400 Subject: [PATCH 88/94] -> v3.27.0 --- CHANGELOG.md | 2 +- package-lock.json | 2 +- package.json | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a18cfac6c3..2734f9dcc4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,6 @@ # Svelte changelog -## Unreleased +## 3.27.0 * Add `|nonpassive` event modifier, explicitly passing `passive: false` ([#2068](https://github.com/sveltejs/svelte/issues/2068)) * Scope CSS selectors with `~` and `+` combinators ([#3104](https://github.com/sveltejs/svelte/issues/3104)) diff --git a/package-lock.json b/package-lock.json index 6ea2f97a27..3ddddec683 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "svelte", - "version": "3.26.0", + "version": "3.27.0", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index 6d558f35fc..62b15efb5f 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "svelte", - "version": "3.26.0", + "version": "3.27.0", "description": "Cybernetically enhanced web apps", "module": "index.mjs", "main": "index", From fa7c780bad5a71ab1c3e946ae0ad150fb182b0d3 Mon Sep 17 00:00:00 2001 From: Tan Li Hau Date: Fri, 25 Sep 2020 22:12:49 +0800 Subject: [PATCH 89/94] {#key} block (#5397) Co-authored-by: Conduitry --- CHANGELOG.md | 4 + site/content/docs/02-template-syntax.md | 27 ++++ src/compiler/compile/nodes/KeyBlock.ts | 19 +++ src/compiler/compile/nodes/interfaces.ts | 2 + .../compile/nodes/shared/map_children.ts | 2 + .../compile/render_dom/wrappers/Fragment.ts | 2 + .../compile/render_dom/wrappers/KeyBlock.ts | 136 ++++++++++++++++++ src/compiler/compile/render_ssr/Renderer.ts | 2 + .../compile/render_ssr/handlers/KeyBlock.ts | 6 + src/compiler/parse/state/mustache.ts | 8 +- test/runtime/samples/key-block-2/_config.js | 14 ++ test/runtime/samples/key-block-2/main.svelte | 8 ++ test/runtime/samples/key-block-3/_config.js | 11 ++ test/runtime/samples/key-block-3/main.svelte | 7 + .../key-block-array-immutable/_config.js | 15 ++ .../key-block-array-immutable/main.svelte | 14 ++ .../samples/key-block-array/_config.js | 15 ++ .../samples/key-block-array/main.svelte | 12 ++ .../samples/key-block-expression-2/_config.js | 18 +++ .../key-block-expression-2/main.svelte | 17 +++ .../samples/key-block-expression/_config.js | 28 ++++ .../samples/key-block-expression/main.svelte | 9 ++ .../samples/key-block-static/_config.js | 9 ++ .../samples/key-block-static/main.svelte | 8 ++ .../samples/key-block-transition/_config.js | 24 ++++ .../samples/key-block-transition/main.svelte | 17 +++ test/runtime/samples/key-block/_config.js | 17 +++ test/runtime/samples/key-block/main.svelte | 10 ++ 28 files changed, 459 insertions(+), 2 deletions(-) create mode 100644 src/compiler/compile/nodes/KeyBlock.ts create mode 100644 src/compiler/compile/render_dom/wrappers/KeyBlock.ts create mode 100644 src/compiler/compile/render_ssr/handlers/KeyBlock.ts create mode 100644 test/runtime/samples/key-block-2/_config.js create mode 100644 test/runtime/samples/key-block-2/main.svelte create mode 100644 test/runtime/samples/key-block-3/_config.js create mode 100644 test/runtime/samples/key-block-3/main.svelte create mode 100644 test/runtime/samples/key-block-array-immutable/_config.js create mode 100644 test/runtime/samples/key-block-array-immutable/main.svelte create mode 100644 test/runtime/samples/key-block-array/_config.js create mode 100644 test/runtime/samples/key-block-array/main.svelte create mode 100644 test/runtime/samples/key-block-expression-2/_config.js create mode 100644 test/runtime/samples/key-block-expression-2/main.svelte create mode 100644 test/runtime/samples/key-block-expression/_config.js create mode 100644 test/runtime/samples/key-block-expression/main.svelte create mode 100644 test/runtime/samples/key-block-static/_config.js create mode 100644 test/runtime/samples/key-block-static/main.svelte create mode 100644 test/runtime/samples/key-block-transition/_config.js create mode 100644 test/runtime/samples/key-block-transition/main.svelte create mode 100644 test/runtime/samples/key-block/_config.js create mode 100644 test/runtime/samples/key-block/main.svelte diff --git a/CHANGELOG.md b/CHANGELOG.md index 2734f9dcc4..98fe7b876c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Svelte changelog +## Unreleased + +* Add `{#key}` block for keying arbitrary content on an expression ([#1469](https://github.com/sveltejs/svelte/issues/1469)) + ## 3.27.0 * Add `|nonpassive` event modifier, explicitly passing `passive: false` ([#2068](https://github.com/sveltejs/svelte/issues/2068)) diff --git a/site/content/docs/02-template-syntax.md b/site/content/docs/02-template-syntax.md index f7e1ae3517..d955f650e2 100644 --- a/site/content/docs/02-template-syntax.md +++ b/site/content/docs/02-template-syntax.md @@ -342,6 +342,33 @@ If you don't care about the pending state, you can also omit the initial block. {/await} ``` +### {#key ...} + +```sv +{#key expression}...{/key} +``` + +Key blocks destroy and recreate their contents when the value of an expression changes. + +--- + +This is useful if you want an element to play its transition whenever a value changes. + +```sv +{#key value} +
{value}
+{/key} +``` + +--- + +When used around components, this will cause them to be reinstantiated and reinitialised. + +```sv +{#key value} + +{/key} +``` ### {@html ...} diff --git a/src/compiler/compile/nodes/KeyBlock.ts b/src/compiler/compile/nodes/KeyBlock.ts new file mode 100644 index 0000000000..356210b6b0 --- /dev/null +++ b/src/compiler/compile/nodes/KeyBlock.ts @@ -0,0 +1,19 @@ +import Expression from "./shared/Expression"; +import map_children from "./shared/map_children"; +import AbstractBlock from "./shared/AbstractBlock"; + +export default class KeyBlock extends AbstractBlock { + type: "KeyBlock"; + + expression: Expression; + + constructor(component, parent, scope, info) { + super(component, parent, scope, info); + + this.expression = new Expression(component, this, scope, info.expression); + + this.children = map_children(component, this, scope, info.children); + + this.warn_if_empty_block(); + } +} diff --git a/src/compiler/compile/nodes/interfaces.ts b/src/compiler/compile/nodes/interfaces.ts index 752168a49d..51d7b17e07 100644 --- a/src/compiler/compile/nodes/interfaces.ts +++ b/src/compiler/compile/nodes/interfaces.ts @@ -18,6 +18,7 @@ import Fragment from './Fragment'; import Head from './Head'; import IfBlock from './IfBlock'; import InlineComponent from './InlineComponent'; +import KeyBlock from './KeyBlock'; import Let from './Let'; import MustacheTag from './MustacheTag'; import Options from './Options'; @@ -50,6 +51,7 @@ export type INode = Action | Head | IfBlock | InlineComponent +| KeyBlock | Let | MustacheTag | Options diff --git a/src/compiler/compile/nodes/shared/map_children.ts b/src/compiler/compile/nodes/shared/map_children.ts index dcdc52f86d..5d5da223fb 100644 --- a/src/compiler/compile/nodes/shared/map_children.ts +++ b/src/compiler/compile/nodes/shared/map_children.ts @@ -6,6 +6,7 @@ import Element from '../Element'; import Head from '../Head'; import IfBlock from '../IfBlock'; import InlineComponent from '../InlineComponent'; +import KeyBlock from '../KeyBlock'; import MustacheTag from '../MustacheTag'; import Options from '../Options'; import RawMustacheTag from '../RawMustacheTag'; @@ -28,6 +29,7 @@ function get_constructor(type) { case 'Head': return Head; case 'IfBlock': return IfBlock; case 'InlineComponent': return InlineComponent; + case 'KeyBlock': return KeyBlock; case 'MustacheTag': return MustacheTag; case 'Options': return Options; case 'RawMustacheTag': return RawMustacheTag; diff --git a/src/compiler/compile/render_dom/wrappers/Fragment.ts b/src/compiler/compile/render_dom/wrappers/Fragment.ts index a0984b69b9..853a41f3cc 100644 --- a/src/compiler/compile/render_dom/wrappers/Fragment.ts +++ b/src/compiler/compile/render_dom/wrappers/Fragment.ts @@ -6,6 +6,7 @@ import EachBlock from './EachBlock'; import Element from './Element/index'; import Head from './Head'; import IfBlock from './IfBlock'; +import KeyBlock from './KeyBlock'; import InlineComponent from './InlineComponent/index'; import MustacheTag from './MustacheTag'; import RawMustacheTag from './RawMustacheTag'; @@ -30,6 +31,7 @@ const wrappers = { Head, IfBlock, InlineComponent, + KeyBlock, MustacheTag, Options: null, RawMustacheTag, diff --git a/src/compiler/compile/render_dom/wrappers/KeyBlock.ts b/src/compiler/compile/render_dom/wrappers/KeyBlock.ts new file mode 100644 index 0000000000..359fb6946f --- /dev/null +++ b/src/compiler/compile/render_dom/wrappers/KeyBlock.ts @@ -0,0 +1,136 @@ +import Wrapper from "./shared/Wrapper"; +import Renderer from "../Renderer"; +import Block from "../Block"; +import EachBlock from "../../nodes/EachBlock"; +import KeyBlock from "../../nodes/KeyBlock"; +import create_debugging_comment from "./shared/create_debugging_comment"; +import FragmentWrapper from "./Fragment"; +import { b, x } from "code-red"; +import { Identifier } from "estree"; + +export default class KeyBlockWrapper extends Wrapper { + node: KeyBlock; + fragment: FragmentWrapper; + block: Block; + dependencies: string[]; + var: Identifier = { type: "Identifier", name: "key_block" }; + + constructor( + renderer: Renderer, + block: Block, + parent: Wrapper, + node: EachBlock, + strip_whitespace: boolean, + next_sibling: Wrapper + ) { + super(renderer, block, parent, node); + + this.cannot_use_innerhtml(); + this.not_static_content(); + + this.dependencies = node.expression.dynamic_dependencies(); + + if (this.dependencies.length) { + block = block.child({ + comment: create_debugging_comment(node, renderer.component), + name: renderer.component.get_unique_name("create_key_block"), + type: "key" + }); + renderer.blocks.push(block); + } + + this.block = block; + this.fragment = new FragmentWrapper( + renderer, + this.block, + node.children, + parent, + strip_whitespace, + next_sibling + ); + } + + render(block: Block, parent_node: Identifier, parent_nodes: Identifier) { + if (this.dependencies.length === 0) { + this.render_static_key(block, parent_node, parent_nodes); + } else { + this.render_dynamic_key(block, parent_node, parent_nodes); + } + } + + render_static_key(_block: Block, parent_node: Identifier, parent_nodes: Identifier) { + this.fragment.render(this.block, parent_node, parent_nodes); + } + + render_dynamic_key(block: Block, parent_node: Identifier, parent_nodes: Identifier) { + this.fragment.render( + this.block, + null, + (x`#nodes` as unknown) as Identifier + ); + + const has_transitions = !!( + this.block.has_intro_method || this.block.has_outro_method + ); + const dynamic = this.block.has_update_method; + + const previous_key = block.get_unique_name('previous_key'); + const snippet = this.node.expression.manipulate(block); + block.add_variable(previous_key, snippet); + + const not_equal = this.renderer.component.component_options.immutable ? x`@not_equal` : x`@safe_not_equal`; + const condition = x`${this.renderer.dirty(this.dependencies)} && ${not_equal}(${previous_key}, ${previous_key} = ${snippet})`; + + block.chunks.init.push(b` + let ${this.var} = ${this.block.name}(#ctx); + `); + block.chunks.create.push(b`${this.var}.c();`); + if (this.renderer.options.hydratable) { + block.chunks.claim.push(b`${this.var}.l(${parent_nodes});`); + } + block.chunks.mount.push( + b`${this.var}.m(${parent_node || "#target"}, ${ + parent_node ? "null" : "#anchor" + });` + ); + const anchor = this.get_or_create_anchor(block, parent_node, parent_nodes); + const body = b` + ${ + has_transitions + ? b` + @group_outros(); + @transition_out(${this.var}, 1, 1, @noop); + @check_outros(); + ` + : b`${this.var}.d(1);` + } + ${this.var} = ${this.block.name}(#ctx); + ${this.var}.c(); + ${has_transitions && b`@transition_in(${this.var})`} + ${this.var}.m(${this.get_update_mount_node(anchor)}, ${anchor}); + `; + + if (dynamic) { + block.chunks.update.push(b` + if (${condition}) { + ${body} + } else { + ${this.var}.p(#ctx, #dirty); + } + `); + } else { + block.chunks.update.push(b` + if (${condition}) { + ${body} + } + `); + } + + if (has_transitions) { + block.chunks.intro.push(b`@transition_in(${this.var})`); + block.chunks.outro.push(b`@transition_out(${this.var})`); + } + + block.chunks.destroy.push(b`${this.var}.d(detaching)`); + } +} diff --git a/src/compiler/compile/render_ssr/Renderer.ts b/src/compiler/compile/render_ssr/Renderer.ts index fb9216327c..c633ff8b0a 100644 --- a/src/compiler/compile/render_ssr/Renderer.ts +++ b/src/compiler/compile/render_ssr/Renderer.ts @@ -7,6 +7,7 @@ import Head from './handlers/Head'; import HtmlTag from './handlers/HtmlTag'; import IfBlock from './handlers/IfBlock'; import InlineComponent from './handlers/InlineComponent'; +import KeyBlock from './handlers/KeyBlock'; import Slot from './handlers/Slot'; import Tag from './handlers/Tag'; import Text from './handlers/Text'; @@ -30,6 +31,7 @@ const handlers: Record = { Head, IfBlock, InlineComponent, + KeyBlock, MustacheTag: Tag, // TODO MustacheTag is an anachronism Options: noop, RawMustacheTag: HtmlTag, diff --git a/src/compiler/compile/render_ssr/handlers/KeyBlock.ts b/src/compiler/compile/render_ssr/handlers/KeyBlock.ts new file mode 100644 index 0000000000..33a6681280 --- /dev/null +++ b/src/compiler/compile/render_ssr/handlers/KeyBlock.ts @@ -0,0 +1,6 @@ +import KeyBlock from '../../nodes/KeyBlock'; +import Renderer, { RenderOptions } from '../Renderer'; + +export default function(node: KeyBlock, renderer: Renderer, options: RenderOptions) { + renderer.render(node.children, options); +} diff --git a/src/compiler/parse/state/mustache.ts b/src/compiler/parse/state/mustache.ts index dc26d994df..b72b77c30b 100644 --- a/src/compiler/parse/state/mustache.ts +++ b/src/compiler/parse/state/mustache.ts @@ -38,7 +38,7 @@ export default function mustache(parser: Parser) { parser.allow_whitespace(); - // {/if}, {/each} or {/await} + // {/if}, {/each}, {/await} or {/key} if (parser.eat('/')) { let block = parser.current(); let expected; @@ -63,6 +63,8 @@ export default function mustache(parser: Parser) { expected = 'each'; } else if (block.type === 'AwaitBlock') { expected = 'await'; + } else if (block.type === 'KeyBlock') { + expected = 'key'; } else { parser.error({ code: `unexpected-block-close`, @@ -221,10 +223,12 @@ export default function mustache(parser: Parser) { type = 'EachBlock'; } else if (parser.eat('await')) { type = 'AwaitBlock'; + } else if (parser.eat('key')) { + type = 'KeyBlock'; } else { parser.error({ code: `expected-block-type`, - message: `Expected if, each or await` + message: `Expected if, each, await or key` }); } diff --git a/test/runtime/samples/key-block-2/_config.js b/test/runtime/samples/key-block-2/_config.js new file mode 100644 index 0000000000..a7c53bd91f --- /dev/null +++ b/test/runtime/samples/key-block-2/_config.js @@ -0,0 +1,14 @@ +// with reactive content beside `key` +export default { + html: `
00
`, + async test({ assert, component, target, window }) { + const div = target.querySelector('div'); + component.reactive = 2; + assert.htmlEqual(target.innerHTML, `
02
`); + assert.strictEqual(div, target.querySelector('div')); + + component.value = 5; + assert.htmlEqual(target.innerHTML, `
52
`); + assert.notStrictEqual(div, target.querySelector('div')); + } +}; diff --git a/test/runtime/samples/key-block-2/main.svelte b/test/runtime/samples/key-block-2/main.svelte new file mode 100644 index 0000000000..466d20b10a --- /dev/null +++ b/test/runtime/samples/key-block-2/main.svelte @@ -0,0 +1,8 @@ + + +{#key value} +
{value}{reactive}
+{/key} \ No newline at end of file diff --git a/test/runtime/samples/key-block-3/_config.js b/test/runtime/samples/key-block-3/_config.js new file mode 100644 index 0000000000..4290599cb3 --- /dev/null +++ b/test/runtime/samples/key-block-3/_config.js @@ -0,0 +1,11 @@ +// key is not used in the template +export default { + html: `
`, + async test({ assert, component, target, window }) { + const div = target.querySelector('div'); + + component.value = 5; + assert.htmlEqual(target.innerHTML, `
`); + assert.notStrictEqual(div, target.querySelector('div')); + } +}; diff --git a/test/runtime/samples/key-block-3/main.svelte b/test/runtime/samples/key-block-3/main.svelte new file mode 100644 index 0000000000..1ed185c732 --- /dev/null +++ b/test/runtime/samples/key-block-3/main.svelte @@ -0,0 +1,7 @@ + + +{#key value} +
+{/key} \ No newline at end of file diff --git a/test/runtime/samples/key-block-array-immutable/_config.js b/test/runtime/samples/key-block-array-immutable/_config.js new file mode 100644 index 0000000000..fb94556c0f --- /dev/null +++ b/test/runtime/samples/key-block-array-immutable/_config.js @@ -0,0 +1,15 @@ +export default { + html: `
1
`, + async test({ assert, component, target, window }) { + let div = target.querySelector("div"); + await component.append(2); + assert.htmlEqual(target.innerHTML, `
1
`); + assert.strictEqual(div, target.querySelector("div")); + + div = target.querySelector("div"); + + component.array = [3, 4]; + assert.htmlEqual(target.innerHTML, `
3,4
`); + assert.notStrictEqual(div, target.querySelector("div")); + } +}; diff --git a/test/runtime/samples/key-block-array-immutable/main.svelte b/test/runtime/samples/key-block-array-immutable/main.svelte new file mode 100644 index 0000000000..e666275af4 --- /dev/null +++ b/test/runtime/samples/key-block-array-immutable/main.svelte @@ -0,0 +1,14 @@ + + + + +{#key array} +
{array.join(',')}
+{/key} \ No newline at end of file diff --git a/test/runtime/samples/key-block-array/_config.js b/test/runtime/samples/key-block-array/_config.js new file mode 100644 index 0000000000..05d5fe9995 --- /dev/null +++ b/test/runtime/samples/key-block-array/_config.js @@ -0,0 +1,15 @@ +export default { + html: `
1
`, + async test({ assert, component, target, window }) { + let div = target.querySelector("div"); + await component.append(2); + assert.htmlEqual(target.innerHTML, `
1,2
`); + assert.notStrictEqual(div, target.querySelector("div")); + + div = target.querySelector("div"); + + component.array = [3, 4]; + assert.htmlEqual(target.innerHTML, `
3,4
`); + assert.notStrictEqual(div, target.querySelector("div")); + } +}; diff --git a/test/runtime/samples/key-block-array/main.svelte b/test/runtime/samples/key-block-array/main.svelte new file mode 100644 index 0000000000..5a4054b043 --- /dev/null +++ b/test/runtime/samples/key-block-array/main.svelte @@ -0,0 +1,12 @@ + + +{#key array} +
{array.join(',')}
+{/key} \ No newline at end of file diff --git a/test/runtime/samples/key-block-expression-2/_config.js b/test/runtime/samples/key-block-expression-2/_config.js new file mode 100644 index 0000000000..236c72fa3d --- /dev/null +++ b/test/runtime/samples/key-block-expression-2/_config.js @@ -0,0 +1,18 @@ +export default { + html: `
3
`, + async test({ assert, component, target, window }) { + const div = target.querySelector("div"); + + await component.mutate(); + assert.htmlEqual(target.innerHTML, `
5
`); + assert.strictEqual(div, target.querySelector("div")); + + await component.reassign(); + assert.htmlEqual(target.innerHTML, `
7
`); + assert.strictEqual(div, target.querySelector("div")); + + await component.changeKey(); + assert.htmlEqual(target.innerHTML, `
7
`); + assert.notStrictEqual(div, target.querySelector("div")); + } +}; diff --git a/test/runtime/samples/key-block-expression-2/main.svelte b/test/runtime/samples/key-block-expression-2/main.svelte new file mode 100644 index 0000000000..5525f63761 --- /dev/null +++ b/test/runtime/samples/key-block-expression-2/main.svelte @@ -0,0 +1,17 @@ + + +{#key obj.key} +
{obj.value}
+{/key} \ No newline at end of file diff --git a/test/runtime/samples/key-block-expression/_config.js b/test/runtime/samples/key-block-expression/_config.js new file mode 100644 index 0000000000..78890988ea --- /dev/null +++ b/test/runtime/samples/key-block-expression/_config.js @@ -0,0 +1,28 @@ +export default { + html: `
000
`, + async test({ assert, component, target, window }) { + let div = target.querySelector("div"); + component.value = 2; + assert.htmlEqual(target.innerHTML, `
200
`); + assert.notStrictEqual(div, target.querySelector("div")); + + div = target.querySelector("div"); + + component.anotherValue = 5; + assert.htmlEqual(target.innerHTML, `
250
`); + assert.notStrictEqual(div, target.querySelector("div")); + + div = target.querySelector("div"); + + component.thirdValue = 9; + assert.htmlEqual(target.innerHTML, `
259
`); + assert.strictEqual(div, target.querySelector("div")); + + // make dirty while maintain the value of `value + anotherValue` + // should update the content, but not recreate the elements + await component.$set({ value: 4, anotherValue: 3 }); + + assert.htmlEqual(target.innerHTML, `
439
`); + assert.strictEqual(div, target.querySelector("div")); + } +}; diff --git a/test/runtime/samples/key-block-expression/main.svelte b/test/runtime/samples/key-block-expression/main.svelte new file mode 100644 index 0000000000..dd752e8b8f --- /dev/null +++ b/test/runtime/samples/key-block-expression/main.svelte @@ -0,0 +1,9 @@ + + +{#key value + anotherValue} +
{value}{anotherValue}{thirdValue}
+{/key} \ No newline at end of file diff --git a/test/runtime/samples/key-block-static/_config.js b/test/runtime/samples/key-block-static/_config.js new file mode 100644 index 0000000000..d5ea0bf687 --- /dev/null +++ b/test/runtime/samples/key-block-static/_config.js @@ -0,0 +1,9 @@ +export default { + html: `
00
`, + async test({ assert, component, target, window }) { + const div = target.querySelector('div'); + component.anotherValue = 2; + assert.htmlEqual(target.innerHTML, `
02
`); + assert.strictEqual(div, target.querySelector('div')); + } +}; diff --git a/test/runtime/samples/key-block-static/main.svelte b/test/runtime/samples/key-block-static/main.svelte new file mode 100644 index 0000000000..e4ee6b5d71 --- /dev/null +++ b/test/runtime/samples/key-block-static/main.svelte @@ -0,0 +1,8 @@ + + +{#key value} +
{value}{anotherValue}
+{/key} \ No newline at end of file diff --git a/test/runtime/samples/key-block-transition/_config.js b/test/runtime/samples/key-block-transition/_config.js new file mode 100644 index 0000000000..53de6b333c --- /dev/null +++ b/test/runtime/samples/key-block-transition/_config.js @@ -0,0 +1,24 @@ +export default { + html: '
0
', + async test({ assert, component, target, window, raf }) { + component.value = 2; + + const [div1, div2] = target.querySelectorAll('div'); + + assert.htmlEqual(div1.outerHTML, '
0
'); + assert.htmlEqual(div2.outerHTML, '
2
'); + + raf.tick(0); + + assert.equal(div1.foo, 1); + assert.equal(div1.oof, 0); + + assert.equal(div2.foo, 0); + assert.equal(div2.oof, 1); + + raf.tick(200); + + assert.htmlEqual(target.innerHTML, '
2
'); + assert.equal(div2, target.querySelector('div')); + } +}; diff --git a/test/runtime/samples/key-block-transition/main.svelte b/test/runtime/samples/key-block-transition/main.svelte new file mode 100644 index 0000000000..d7fb6ec024 --- /dev/null +++ b/test/runtime/samples/key-block-transition/main.svelte @@ -0,0 +1,17 @@ + + +{#key value} +
{value}
+{/key} \ No newline at end of file diff --git a/test/runtime/samples/key-block/_config.js b/test/runtime/samples/key-block/_config.js new file mode 100644 index 0000000000..ad206c3b06 --- /dev/null +++ b/test/runtime/samples/key-block/_config.js @@ -0,0 +1,17 @@ +export default { + html: `
0
0
`, + async test({ assert, component, target, window }) { + let [div1, div2] = target.querySelectorAll('div'); + + component.value = 5; + assert.htmlEqual(target.innerHTML, `
5
0
`); + assert.notStrictEqual(div1, target.querySelectorAll('div')[0]); + assert.strictEqual(div2, target.querySelectorAll('div')[1]); + [div1, div2] = target.querySelectorAll('div'); + + component.reactive = 10; + assert.htmlEqual(target.innerHTML, `
5
10
`); + assert.strictEqual(div1, target.querySelectorAll('div')[0]); + assert.strictEqual(div2, target.querySelectorAll('div')[1]); + } +}; diff --git a/test/runtime/samples/key-block/main.svelte b/test/runtime/samples/key-block/main.svelte new file mode 100644 index 0000000000..ac3c340770 --- /dev/null +++ b/test/runtime/samples/key-block/main.svelte @@ -0,0 +1,10 @@ + + +{#key value} +
{value}
+{/key} + +
{reactive}
\ No newline at end of file From 46a83a50e3ed8f90b188cb152901cc579b189cd2 Mon Sep 17 00:00:00 2001 From: Conduitry Date: Fri, 25 Sep 2020 10:13:32 -0400 Subject: [PATCH 90/94] -> v3.28.0 --- CHANGELOG.md | 2 +- package-lock.json | 2 +- package.json | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 98fe7b876c..a557769607 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,6 @@ # Svelte changelog -## Unreleased +## 3.28.0 * Add `{#key}` block for keying arbitrary content on an expression ([#1469](https://github.com/sveltejs/svelte/issues/1469)) diff --git a/package-lock.json b/package-lock.json index 3ddddec683..4d6b1f8b6a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "svelte", - "version": "3.27.0", + "version": "3.28.0", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index 62b15efb5f..7be5b19819 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "svelte", - "version": "3.27.0", + "version": "3.28.0", "description": "Cybernetically enhanced web apps", "module": "index.mjs", "main": "index", From 296e81af4d26050f9b45fab1291f533e76e4dc2d Mon Sep 17 00:00:00 2001 From: Tan Li Hau Date: Tue, 29 Sep 2020 22:58:00 +0800 Subject: [PATCH 91/94] add EventSource to the known globals (#5468) --- CHANGELOG.md | 4 ++++ src/compiler/utils/names.ts | 1 + 2 files changed, 5 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index a557769607..b0c5414f11 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Svelte changelog +## Unreleased + +* Add `EventSource` to known globals ([#5463](https://github.com/sveltejs/svelte/issues/5463)) + ## 3.28.0 * Add `{#key}` block for keying arbitrary content on an expression ([#1469](https://github.com/sveltejs/svelte/issues/1469)) diff --git a/src/compiler/utils/names.ts b/src/compiler/utils/names.ts index 1fa37660f4..7b6a6f55e0 100644 --- a/src/compiler/utils/names.ts +++ b/src/compiler/utils/names.ts @@ -18,6 +18,7 @@ export const globals = new Set([ 'Error', 'EvalError', 'Event', + 'EventSource', 'fetch', 'global', 'globalThis', From 3970def5eba83d3b9086fa50fe1e9cffe478fe4d Mon Sep 17 00:00:00 2001 From: Tan Li Hau Date: Tue, 29 Sep 2020 23:06:27 +0800 Subject: [PATCH 92/94] fix sibling combinators with spread attributes (#5467) --- CHANGELOG.md | 1 + src/compiler/compile/css/Selector.ts | 2 +- .../siblings-combinator-with-spread/_config.js | 3 +++ .../siblings-combinator-with-spread/expected.css | 1 + .../siblings-combinator-with-spread/expected.html | 2 ++ .../siblings-combinator-with-spread/input.svelte | 11 +++++++++++ 6 files changed, 19 insertions(+), 1 deletion(-) create mode 100644 test/css/samples/siblings-combinator-with-spread/_config.js create mode 100644 test/css/samples/siblings-combinator-with-spread/expected.css create mode 100644 test/css/samples/siblings-combinator-with-spread/expected.html create mode 100644 test/css/samples/siblings-combinator-with-spread/input.svelte diff --git a/CHANGELOG.md b/CHANGELOG.md index b0c5414f11..106d091cee 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ ## Unreleased * Add `EventSource` to known globals ([#5463](https://github.com/sveltejs/svelte/issues/5463)) +* Fix compiler exception with `~`/`+` combinators and `{...spread}` attributes ([#5465](https://github.com/sveltejs/svelte/issues/5465)) ## 3.28.0 diff --git a/src/compiler/compile/css/Selector.ts b/src/compiler/compile/css/Selector.ts index c141f6b481..46e9b4c4f0 100644 --- a/src/compiler/compile/css/Selector.ts +++ b/src/compiler/compile/css/Selector.ts @@ -406,7 +406,7 @@ function get_possible_element_siblings(node: INode, adjacent_only: boolean): Map let prev: INode = node; while (prev = prev.prev) { if (prev.type === 'Element') { - if (!prev.attributes.find(attr => attr.name.toLowerCase() === 'slot')) { + if (!prev.attributes.find(attr => attr.type === 'Attribute' && attr.name.toLowerCase() === 'slot')) { result.set(prev, NodeExist.Definitely); } diff --git a/test/css/samples/siblings-combinator-with-spread/_config.js b/test/css/samples/siblings-combinator-with-spread/_config.js new file mode 100644 index 0000000000..c81f1a9f82 --- /dev/null +++ b/test/css/samples/siblings-combinator-with-spread/_config.js @@ -0,0 +1,3 @@ +export default { + warnings: [] +}; diff --git a/test/css/samples/siblings-combinator-with-spread/expected.css b/test/css/samples/siblings-combinator-with-spread/expected.css new file mode 100644 index 0000000000..aacf6e7db5 --- /dev/null +++ b/test/css/samples/siblings-combinator-with-spread/expected.css @@ -0,0 +1 @@ +input.svelte-xyz:focus+div.svelte-xyz{color:red}input.svelte-xyz:focus~div.svelte-xyz{color:red} \ No newline at end of file diff --git a/test/css/samples/siblings-combinator-with-spread/expected.html b/test/css/samples/siblings-combinator-with-spread/expected.html new file mode 100644 index 0000000000..d732739701 --- /dev/null +++ b/test/css/samples/siblings-combinator-with-spread/expected.html @@ -0,0 +1,2 @@ + +
Should be red, when input is focused
\ No newline at end of file diff --git a/test/css/samples/siblings-combinator-with-spread/input.svelte b/test/css/samples/siblings-combinator-with-spread/input.svelte new file mode 100644 index 0000000000..45c889c1ae --- /dev/null +++ b/test/css/samples/siblings-combinator-with-spread/input.svelte @@ -0,0 +1,11 @@ + + + + + +
Should be red, when input is focused
\ No newline at end of file From 0645631b28bc9d3429268ef5d2d1ead0feee77f9 Mon Sep 17 00:00:00 2001 From: Ben McCann <322311+benmccann@users.noreply.github.com> Date: Tue, 29 Sep 2020 08:19:21 -0700 Subject: [PATCH 93/94] Use TypeScript in tests (#5433) --- .mocharc.js | 13 ++++++------- test/.eslintrc.json | 3 ++- test/css/{index.js => index.ts} | 3 +-- test/custom-elements/{index.js => index.ts} | 6 +++--- test/{helpers.js => helpers.ts} | 7 ++++--- test/hydration/{index.js => index.ts} | 16 ++++++---------- test/js/{index.js => index.ts} | 2 +- test/motion/{index.js => index.ts} | 0 test/parser/{index.js => index.ts} | 4 ++-- test/parser/{update.js => update.ts} | 0 test/preprocess/{index.js => index.ts} | 2 +- test/runtime/{index.js => index.ts} | 8 ++++---- .../server-side-rendering/{index.js => index.ts} | 6 +++--- test/sourcemaps/{index.js => index.ts} | 2 +- test/stats/{index.js => index.ts} | 2 +- test/{test.js => test.ts} | 4 ++-- test/validator/{index.js => index.ts} | 4 ++-- test/vars/{index.js => index.ts} | 2 +- 18 files changed, 40 insertions(+), 44 deletions(-) rename test/css/{index.js => index.ts} (97%) rename test/custom-elements/{index.js => index.ts} (96%) rename test/{helpers.js => helpers.ts} (95%) rename test/hydration/{index.js => index.ts} (93%) rename test/js/{index.js => index.ts} (99%) rename test/motion/{index.js => index.ts} (100%) rename test/parser/{index.js => index.ts} (96%) rename test/parser/{update.js => update.ts} (100%) rename test/preprocess/{index.js => index.ts} (94%) rename test/runtime/{index.js => index.ts} (97%) rename test/server-side-rendering/{index.js => index.ts} (98%) rename test/sourcemaps/{index.js => index.ts} (98%) rename test/stats/{index.js => index.ts} (95%) rename test/{test.js => test.ts} (84%) rename test/validator/{index.js => index.ts} (97%) rename test/vars/{index.js => index.ts} (95%) diff --git a/.mocharc.js b/.mocharc.js index de41cdd353..e55f26099e 100644 --- a/.mocharc.js +++ b/.mocharc.js @@ -1,15 +1,14 @@ module.exports = { file: [ - 'test/test.js' + 'test/test.ts' + ], + require: [ + 'sucrase/register' ] }; // add coverage options when running 'npx c8 mocha' if (process.env.NODE_V8_COVERAGE) { - Object.assign(module.exports, { - fullTrace: true, - require: [ - 'source-map-support/register' - ] - }); + module.exports.fullTrace = true; + module.exports.require.push('source-map-support/register'); } diff --git a/test/.eslintrc.json b/test/.eslintrc.json index d5ba8f9d9c..fc493fa889 100644 --- a/test/.eslintrc.json +++ b/test/.eslintrc.json @@ -1,5 +1,6 @@ { "rules": { - "no-console": "off" + "no-console": "off", + "@typescript-eslint/no-var-requires": "off" } } diff --git a/test/css/index.js b/test/css/index.ts similarity index 97% rename from test/css/index.js rename to test/css/index.ts index 81d27a94bf..c12418353d 100644 --- a/test/css/index.js +++ b/test/css/index.ts @@ -1,6 +1,5 @@ -import * as assert from 'assert'; import * as fs from 'fs'; -import { env, svelte, setupHtmlEqual, shouldUpdateExpected } from '../helpers.js'; +import { assert, env, svelte, setupHtmlEqual, shouldUpdateExpected } from '../helpers'; function try_require(file) { try { diff --git a/test/custom-elements/index.js b/test/custom-elements/index.ts similarity index 96% rename from test/custom-elements/index.js rename to test/custom-elements/index.ts index 1329dbd2cf..25cef932d8 100644 --- a/test/custom-elements/index.js +++ b/test/custom-elements/index.ts @@ -2,9 +2,9 @@ import * as fs from 'fs'; import * as path from 'path'; import * as http from 'http'; import { rollup } from 'rollup'; -import * as virtual from '@rollup/plugin-virtual'; -import * as puppeteer from 'puppeteer'; -import { addLineNumbers, loadConfig, loadSvelte } from "../helpers.js"; +import virtual from '@rollup/plugin-virtual'; +import puppeteer from 'puppeteer'; +import { addLineNumbers, loadConfig, loadSvelte } from "../helpers"; import { deepEqual } from 'assert'; const page = ` diff --git a/test/helpers.js b/test/helpers.ts similarity index 95% rename from test/helpers.js rename to test/helpers.ts index 9ffc4c4764..6452dbae1a 100644 --- a/test/helpers.js +++ b/test/helpers.ts @@ -1,9 +1,10 @@ +import * as assert$1 from 'assert'; import * as jsdom from 'jsdom'; -import * as assert from 'assert'; -import * as glob from 'tiny-glob/sync.js'; +import glob from 'tiny-glob/sync'; import * as path from 'path'; import * as fs from 'fs'; import * as colors from 'kleur'; +export const assert = (assert$1 as unknown) as typeof assert$1 & { htmlEqual: (actual, expected, message?) => void }; // for coverage purposes, we need to test source files, // but for sanity purposes, we need to test dist files @@ -63,7 +64,7 @@ global.window = window; // add missing ecmascript globals to window for (const key of Object.getOwnPropertyNames(global)) { - window[key] = window[key] || global[key]; + if (!(key in window)) window[key] = global[key]; } // implement mock scroll diff --git a/test/hydration/index.js b/test/hydration/index.ts similarity index 93% rename from test/hydration/index.js rename to test/hydration/index.ts index f57a0cdc1a..e50351c56e 100644 --- a/test/hydration/index.js +++ b/test/hydration/index.ts @@ -1,15 +1,15 @@ -import * as assert from 'assert'; import * as path from 'path'; import * as fs from 'fs'; import { + assert, showOutput, loadConfig, loadSvelte, env, setupHtmlEqual, shouldUpdateExpected -} from '../helpers.js'; +} from '../helpers'; let compileOptions = null; @@ -58,13 +58,7 @@ describe('hydration', () => { try { global.window = window; - let SvelteComponent; - - try { - SvelteComponent = require(`${cwd}/main.svelte`).default; - } catch (err) { - throw err; - } + const SvelteComponent = require(`${cwd}/main.svelte`).default; const target = window.document.body; const head = window.document.head; @@ -75,7 +69,9 @@ describe('hydration', () => { try { before_head = fs.readFileSync(`${cwd}/_before_head.html`, 'utf-8'); head.innerHTML = before_head; - } catch (err) {} + } catch (err) { + // continue regardless of error + } const snapshot = config.snapshot ? config.snapshot(target) : {}; diff --git a/test/js/index.js b/test/js/index.ts similarity index 99% rename from test/js/index.js rename to test/js/index.ts index 8aa4cc76a9..3a3643de47 100644 --- a/test/js/index.js +++ b/test/js/index.ts @@ -2,7 +2,7 @@ import * as assert from "assert"; import * as fs from "fs"; import * as path from "path"; import * as colors from "kleur"; -import { loadConfig, svelte, shouldUpdateExpected } from "../helpers.js"; +import { loadConfig, svelte, shouldUpdateExpected } from "../helpers"; describe("js", () => { fs.readdirSync(`${__dirname}/samples`).forEach(dir => { diff --git a/test/motion/index.js b/test/motion/index.ts similarity index 100% rename from test/motion/index.js rename to test/motion/index.ts diff --git a/test/parser/index.js b/test/parser/index.ts similarity index 96% rename from test/parser/index.js rename to test/parser/index.ts index 2c8d516a7d..32afcbbafc 100644 --- a/test/parser/index.js +++ b/test/parser/index.ts @@ -1,6 +1,6 @@ import * as assert from 'assert'; import * as fs from 'fs'; -import { svelte, tryToLoadJson, shouldUpdateExpected } from '../helpers.js'; +import { svelte, tryToLoadJson, shouldUpdateExpected } from '../helpers'; describe('parse', () => { fs.readdirSync(`${__dirname}/samples`).forEach(dir => { @@ -38,7 +38,7 @@ describe('parse', () => { } catch (err) { if (err.name !== 'ParseError') throw err; if (!expectedError) throw err; - const { code, message, pos, start } = err + const { code, message, pos, start } = err; try { assert.deepEqual({ code, message, pos, start }, expectedError); } catch (err2) { diff --git a/test/parser/update.js b/test/parser/update.ts similarity index 100% rename from test/parser/update.js rename to test/parser/update.ts diff --git a/test/preprocess/index.js b/test/preprocess/index.ts similarity index 94% rename from test/preprocess/index.js rename to test/preprocess/index.ts index 5d83bb6059..abb45012ce 100644 --- a/test/preprocess/index.js +++ b/test/preprocess/index.ts @@ -1,6 +1,6 @@ import * as fs from 'fs'; import * as assert from 'assert'; -import { loadConfig, svelte } from '../helpers.js'; +import { loadConfig, svelte } from '../helpers'; describe('preprocess', () => { fs.readdirSync(`${__dirname}/samples`).forEach(dir => { diff --git a/test/runtime/index.js b/test/runtime/index.ts similarity index 97% rename from test/runtime/index.js rename to test/runtime/index.ts index 65157196c9..9e0ba6568f 100644 --- a/test/runtime/index.js +++ b/test/runtime/index.ts @@ -1,12 +1,12 @@ -import * as assert from "assert"; import * as path from "path"; import * as fs from "fs"; import { rollup } from 'rollup'; -import * as virtual from '@rollup/plugin-virtual'; -import * as glob from 'tiny-glob/sync.js'; +import virtual from '@rollup/plugin-virtual'; +import glob from 'tiny-glob/sync.js'; import { clear_loops, flush, set_now, set_raf } from "../../internal"; import { + assert, showOutput, loadConfig, loadSvelte, @@ -14,7 +14,7 @@ import { env, setupHtmlEqual, mkdirp -} from "../helpers.js"; +} from "../helpers"; let svelte$; let svelte; diff --git a/test/server-side-rendering/index.js b/test/server-side-rendering/index.ts similarity index 98% rename from test/server-side-rendering/index.js rename to test/server-side-rendering/index.ts index 2d539782ff..94ab405895 100644 --- a/test/server-side-rendering/index.js +++ b/test/server-side-rendering/index.ts @@ -1,9 +1,9 @@ -import * as assert from "assert"; import * as fs from "fs"; import * as path from "path"; -import * as glob from 'tiny-glob/sync.js'; +import glob from 'tiny-glob/sync.js'; import { + assert, showOutput, loadConfig, loadSvelte, @@ -12,7 +12,7 @@ import { cleanRequireCache, shouldUpdateExpected, mkdirp -} from "../helpers.js"; +} from "../helpers"; function tryToReadFile(file) { try { diff --git a/test/sourcemaps/index.js b/test/sourcemaps/index.ts similarity index 98% rename from test/sourcemaps/index.js rename to test/sourcemaps/index.ts index 0b0424a764..da2d79295c 100644 --- a/test/sourcemaps/index.js +++ b/test/sourcemaps/index.ts @@ -1,7 +1,7 @@ import * as fs from "fs"; import * as path from "path"; import * as assert from "assert"; -import { svelte } from "../helpers.js"; +import { svelte } from "../helpers"; import { SourceMapConsumer } from "source-map"; import { getLocator } from "locate-character"; diff --git a/test/stats/index.js b/test/stats/index.ts similarity index 95% rename from test/stats/index.js rename to test/stats/index.ts index acea7a4663..a6efd93d22 100644 --- a/test/stats/index.js +++ b/test/stats/index.ts @@ -1,6 +1,6 @@ import * as fs from 'fs'; import * as assert from 'assert'; -import { svelte, loadConfig, tryToLoadJson } from '../helpers.js'; +import { svelte, loadConfig, tryToLoadJson } from '../helpers'; describe('stats', () => { fs.readdirSync(`${__dirname}/samples`).forEach(dir => { diff --git a/test/test.js b/test/test.ts similarity index 84% rename from test/test.js rename to test/test.ts index 6ea4bd60ab..181e9351c1 100644 --- a/test/test.js +++ b/test/test.ts @@ -3,12 +3,12 @@ const glob = require('tiny-glob/sync.js'); require('./setup'); // bind internal to jsdom -require('./helpers'); +require('./helpers.ts'); require('../internal'); console.clear(); -const test_folders = glob('*/index.js', { cwd: 'test' }); +const test_folders = glob('*/index.ts', { cwd: 'test' }); const solo_folders = test_folders.filter(folder => /\.solo/.test(folder)); if (solo_folders.length) { diff --git a/test/validator/index.js b/test/validator/index.ts similarity index 97% rename from test/validator/index.js rename to test/validator/index.ts index 433e1a94ae..e93cf1a4bb 100644 --- a/test/validator/index.js +++ b/test/validator/index.ts @@ -1,6 +1,6 @@ import * as fs from "fs"; import * as assert from "assert"; -import { svelte, loadConfig, tryToLoadJson } from "../helpers.js"; +import { svelte, loadConfig, tryToLoadJson } from "../helpers"; describe("validate", () => { fs.readdirSync(`${__dirname}/samples`).forEach(dir => { @@ -30,7 +30,7 @@ describe("validate", () => { legacy: config.legacy, generate: false, customElement: config.customElement, - ...options, + ...options }); assert.deepEqual(warnings.map(w => ({ diff --git a/test/vars/index.js b/test/vars/index.ts similarity index 95% rename from test/vars/index.js rename to test/vars/index.ts index a12ac177f2..4cebf7fbb4 100644 --- a/test/vars/index.js +++ b/test/vars/index.ts @@ -1,6 +1,6 @@ import * as fs from 'fs'; import * as assert from 'assert'; -import { svelte, loadConfig, tryToLoadJson } from '../helpers.js'; +import { svelte, loadConfig, tryToLoadJson } from '../helpers'; describe('vars', () => { fs.readdirSync(`${__dirname}/samples`).forEach(dir => { From 8056829a9163a09930a453aff42dacf711943549 Mon Sep 17 00:00:00 2001 From: Tan Li Hau Date: Tue, 29 Sep 2020 23:55:44 +0800 Subject: [PATCH 94/94] allow to be part of a slot (#4295) --- CHANGELOG.md | 1 + .../wrappers/Element/create_slot_block.ts | 61 +++++++++++++++++++ .../render_dom/wrappers/Element/index.ts | 48 +-------------- .../compile/render_dom/wrappers/Slot.ts | 10 +++ .../compile/render_ssr/handlers/Slot.ts | 24 +++++++- .../component-slot-nested-in-slot/One.svelte | 8 +++ .../component-slot-nested-in-slot/Two.svelte | 4 ++ .../component-slot-nested-in-slot/_config.js | 18 ++++++ .../component-slot-nested-in-slot/main.svelte | 9 +++ 9 files changed, 137 insertions(+), 46 deletions(-) create mode 100644 src/compiler/compile/render_dom/wrappers/Element/create_slot_block.ts create mode 100644 test/runtime/samples/component-slot-nested-in-slot/One.svelte create mode 100644 test/runtime/samples/component-slot-nested-in-slot/Two.svelte create mode 100644 test/runtime/samples/component-slot-nested-in-slot/_config.js create mode 100644 test/runtime/samples/component-slot-nested-in-slot/main.svelte diff --git a/CHANGELOG.md b/CHANGELOG.md index 106d091cee..896a550c3f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,7 @@ ## Unreleased +* Support `` ([#2079](https://github.com/sveltejs/svelte/issues/2079)) * Add `EventSource` to known globals ([#5463](https://github.com/sveltejs/svelte/issues/5463)) * Fix compiler exception with `~`/`+` combinators and `{...spread}` attributes ([#5465](https://github.com/sveltejs/svelte/issues/5465)) diff --git a/src/compiler/compile/render_dom/wrappers/Element/create_slot_block.ts b/src/compiler/compile/render_dom/wrappers/Element/create_slot_block.ts new file mode 100644 index 0000000000..7078d4eee7 --- /dev/null +++ b/src/compiler/compile/render_dom/wrappers/Element/create_slot_block.ts @@ -0,0 +1,61 @@ +import ElementWrapper from './index'; +import SlotWrapper from '../Slot'; +import Block from '../../Block'; +import { sanitize } from '../../../../utils/names'; +import InlineComponentWrapper from '../InlineComponent'; +import create_debugging_comment from '../shared/create_debugging_comment'; +import { get_slot_definition } from '../shared/get_slot_definition'; + +export default function create_slot_block(attribute, element: ElementWrapper | SlotWrapper, block: Block) { + const owner = find_slot_owner(element.parent); + + if (owner && owner.node.type === 'InlineComponent') { + const name = attribute.get_static_value() as string; + + if (!((owner as unknown) as InlineComponentWrapper).slots.has(name)) { + const child_block = block.child({ + comment: create_debugging_comment(element.node, element.renderer.component), + name: element.renderer.component.get_unique_name( + `create_${sanitize(name)}_slot` + ), + type: 'slot' + }); + + const { scope, lets } = element.node; + const seen = new Set(lets.map(l => l.name.name)); + + ((owner as unknown) as InlineComponentWrapper).node.lets.forEach(l => { + if (!seen.has(l.name.name)) lets.push(l); + }); + + ((owner as unknown) as InlineComponentWrapper).slots.set( + name, + get_slot_definition(child_block, scope, lets) + ); + element.renderer.blocks.push(child_block); + } + + element.slot_block = ((owner as unknown) as InlineComponentWrapper).slots.get( + name + ).block; + + return element.slot_block; + } + + return block; +} + +function find_slot_owner(owner) { + while (owner) { + if (owner.node.type === 'InlineComponent') { + break; + } + + if (owner.node.type === 'Element' && /-/.test(owner.node.name)) { + break; + } + + owner = owner.parent; + } + return owner; +} diff --git a/src/compiler/compile/render_dom/wrappers/Element/index.ts b/src/compiler/compile/render_dom/wrappers/Element/index.ts index f740560bcd..b99df5242c 100644 --- a/src/compiler/compile/render_dom/wrappers/Element/index.ts +++ b/src/compiler/compile/render_dom/wrappers/Element/index.ts @@ -2,7 +2,7 @@ import Renderer from '../../Renderer'; import Element from '../../../nodes/Element'; import Wrapper from '../shared/Wrapper'; import Block from '../../Block'; -import { is_void, sanitize } from '../../../../utils/names'; +import { is_void } from '../../../../utils/names'; import FragmentWrapper from '../Fragment'; import { escape_html, string_literal } from '../../../utils/stringify'; import TextWrapper from '../Text'; @@ -14,12 +14,9 @@ import StyleAttributeWrapper from './StyleAttribute'; import SpreadAttributeWrapper from './SpreadAttribute'; import { dimensions } from '../../../../utils/patterns'; import Binding from './Binding'; -import InlineComponentWrapper from '../InlineComponent'; import add_to_set from '../../../utils/add_to_set'; import { add_event_handler } from '../shared/add_event_handlers'; import { add_action } from '../shared/add_actions'; -import create_debugging_comment from '../shared/create_debugging_comment'; -import { get_slot_definition } from '../shared/get_slot_definition'; import bind_this from '../shared/bind_this'; import { is_head } from '../shared/is_head'; import { Identifier } from 'estree'; @@ -28,6 +25,7 @@ import { extract_names } from 'periscopic'; import Action from '../../../nodes/Action'; import MustacheTagWrapper from '../MustacheTag'; import RawMustacheTagWrapper from '../RawMustacheTag'; +import create_slot_block from './create_slot_block'; interface BindingGroup { events: string[]; @@ -177,47 +175,7 @@ export default class ElementWrapper extends Wrapper { this.attributes = this.node.attributes.map(attribute => { if (attribute.name === 'slot') { - // TODO make separate subclass for this? - let owner = this.parent; - while (owner) { - if (owner.node.type === 'InlineComponent') { - break; - } - - if (owner.node.type === 'Element' && /-/.test(owner.node.name)) { - break; - } - - owner = owner.parent; - } - - if (owner && owner.node.type === 'InlineComponent') { - const name = attribute.get_static_value() as string; - - if (!(owner as unknown as InlineComponentWrapper).slots.has(name)) { - const child_block = block.child({ - comment: create_debugging_comment(node, this.renderer.component), - name: this.renderer.component.get_unique_name(`create_${sanitize(name)}_slot`), - type: 'slot' - }); - - const { scope, lets } = this.node; - const seen = new Set(lets.map(l => l.name.name)); - - (owner as unknown as InlineComponentWrapper).node.lets.forEach(l => { - if (!seen.has(l.name.name)) lets.push(l); - }); - - (owner as unknown as InlineComponentWrapper).slots.set( - name, - get_slot_definition(child_block, scope, lets) - ); - this.renderer.blocks.push(child_block); - } - - this.slot_block = (owner as unknown as InlineComponentWrapper).slots.get(name).block; - block = this.slot_block; - } + block = create_slot_block(attribute, this, block); } if (attribute.name === 'style') { return new StyleAttributeWrapper(this, block, attribute); diff --git a/src/compiler/compile/render_dom/wrappers/Slot.ts b/src/compiler/compile/render_dom/wrappers/Slot.ts index 5c02e78158..4f8e0c8e57 100644 --- a/src/compiler/compile/render_dom/wrappers/Slot.ts +++ b/src/compiler/compile/render_dom/wrappers/Slot.ts @@ -12,11 +12,13 @@ import Expression from '../../nodes/shared/Expression'; import is_dynamic from './shared/is_dynamic'; import { Identifier, ObjectExpression } from 'estree'; import create_debugging_comment from './shared/create_debugging_comment'; +import create_slot_block from './Element/create_slot_block'; export default class SlotWrapper extends Wrapper { node: Slot; fragment: FragmentWrapper; fallback: Block | null = null; + slot_block: Block; var: Identifier = { type: 'Identifier', name: 'slot' }; dependencies: Set = new Set(['$$scope']); @@ -42,6 +44,10 @@ export default class SlotWrapper extends Wrapper { renderer.blocks.push(this.fallback); } + if (this.node.values.has('slot')) { + block = create_slot_block(this.node.values.get('slot'), this, block); + } + this.fragment = new FragmentWrapper( renderer, this.fallback, @@ -71,6 +77,10 @@ export default class SlotWrapper extends Wrapper { const { slot_name } = this.node; + if (this.slot_block) { + block = this.slot_block; + } + let get_slot_changes_fn; let get_slot_context_fn; diff --git a/src/compiler/compile/render_ssr/handlers/Slot.ts b/src/compiler/compile/render_ssr/handlers/Slot.ts index 32b6246e64..f89b619c46 100644 --- a/src/compiler/compile/render_ssr/handlers/Slot.ts +++ b/src/compiler/compile/render_ssr/handlers/Slot.ts @@ -2,9 +2,18 @@ import Renderer, { RenderOptions } from '../Renderer'; import Slot from '../../nodes/Slot'; import { x } from 'code-red'; import get_slot_data from '../../utils/get_slot_data'; +import { get_slot_scope } from './shared/get_slot_scope'; -export default function(node: Slot, renderer: Renderer, options: RenderOptions) { +export default function(node: Slot, renderer: Renderer, options: RenderOptions & { + slot_scopes: Map; +}) { const slot_data = get_slot_data(node.values); + const slot = node.get_static_attribute_value('slot'); + const nearest_inline_component = node.find_nearest(/InlineComponent/); + + if (slot && nearest_inline_component) { + renderer.push(); + } renderer.push(); renderer.render(node.children, options); @@ -15,4 +24,17 @@ export default function(node: Slot, renderer: Renderer, options: RenderOptions) ? #slots.${node.slot_name}(${slot_data}) : ${result} `); + + if (slot && nearest_inline_component) { + const lets = node.lets; + const seen = new Set(lets.map(l => l.name.name)); + + nearest_inline_component.lets.forEach(l => { + if (!seen.has(l.name.name)) lets.push(l); + }); + options.slot_scopes.set(slot, { + input: get_slot_scope(node.lets), + output: renderer.pop() + }); + } } diff --git a/test/runtime/samples/component-slot-nested-in-slot/One.svelte b/test/runtime/samples/component-slot-nested-in-slot/One.svelte new file mode 100644 index 0000000000..e27437c450 --- /dev/null +++ b/test/runtime/samples/component-slot-nested-in-slot/One.svelte @@ -0,0 +1,8 @@ + + + + + diff --git a/test/runtime/samples/component-slot-nested-in-slot/Two.svelte b/test/runtime/samples/component-slot-nested-in-slot/Two.svelte new file mode 100644 index 0000000000..3f21e2d16f --- /dev/null +++ b/test/runtime/samples/component-slot-nested-in-slot/Two.svelte @@ -0,0 +1,4 @@ + + \ No newline at end of file diff --git a/test/runtime/samples/component-slot-nested-in-slot/_config.js b/test/runtime/samples/component-slot-nested-in-slot/_config.js new file mode 100644 index 0000000000..56a9ef2668 --- /dev/null +++ b/test/runtime/samples/component-slot-nested-in-slot/_config.js @@ -0,0 +1,18 @@ +export default { + html: ` +

one: 1 two: 2

+ `, + test({ assert, component, target }) { + component.a = 3; + component.b = 4; + assert.htmlEqual(target.innerHTML, ` +

one: 3 two: 4

+ `); + + component.a = 5; + component.b = 6; + assert.htmlEqual(target.innerHTML, ` +

one: 5 two: 6

+ `); + } +}; diff --git a/test/runtime/samples/component-slot-nested-in-slot/main.svelte b/test/runtime/samples/component-slot-nested-in-slot/main.svelte new file mode 100644 index 0000000000..38a172e668 --- /dev/null +++ b/test/runtime/samples/component-slot-nested-in-slot/main.svelte @@ -0,0 +1,9 @@ + + + +

one: {one} two: {two}

+
\ No newline at end of file