` value
diff --git a/site/content/examples/05-bindings/05-file-inputs/App.svelte b/site/content/examples/05-bindings/05-file-inputs/App.svelte
new file mode 100644
index 0000000000..a3334dbd01
--- /dev/null
+++ b/site/content/examples/05-bindings/05-file-inputs/App.svelte
@@ -0,0 +1,37 @@
+
+
+Upload a picture:
+
+
+Upload multiple files of any type:
+
+
+{#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/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/)
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"
},
diff --git a/site/static/examples/thumbnails/file-inputs.jpg b/site/static/examples/thumbnails/file-inputs.jpg
new file mode 100644
index 0000000000..d302633f6b
Binary files /dev/null and b/site/static/examples/thumbnails/file-inputs.jpg differ
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/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/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/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/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
+}
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,
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
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