From 6d59a40a626edb859f454af2ce3e149af9c66d68 Mon Sep 17 00:00:00 2001 From: Karsten 7 Date: Mon, 27 May 2019 13:49:20 +0200 Subject: [PATCH 01/49] Add implementation for the given tutorial example --- .../02-reactivity/04-updating-arrays-and-objects/text.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/site/content/tutorial/02-reactivity/04-updating-arrays-and-objects/text.md b/site/content/tutorial/02-reactivity/04-updating-arrays-and-objects/text.md index 0a78c7ca32..9cc875bc73 100644 --- a/site/content/tutorial/02-reactivity/04-updating-arrays-and-objects/text.md +++ b/site/content/tutorial/02-reactivity/04-updating-arrays-and-objects/text.md @@ -24,3 +24,9 @@ function addNumber() { You can use similar patterns to replace `pop`, `shift`, `unshift` and `splice`. > Assignments to *properties* of arrays and objects — e.g. `obj.foo += 1` or `array[i] = x` — work the same way as assignments to the values themselves. +> +> ```js +> function addNumber() { +> numbers[numbers.length] = numbers.length + 1; +> } +> ``` From f9c3d99b34a30afa63b2cd744746bb428f7f08b0 Mon Sep 17 00:00:00 2001 From: gabysantosw <44228131+gabysantosw@users.noreply.github.com> Date: Sat, 1 Jun 2019 11:59:21 +0200 Subject: [PATCH 02/49] Ending alt text with a period Added a period at the end of the alt text example, recently learned that it improves UX for screen-reader users as it provides a pause. --- .../tutorial/01-introduction/03-dynamic-attributes/text.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/site/content/tutorial/01-introduction/03-dynamic-attributes/text.md b/site/content/tutorial/01-introduction/03-dynamic-attributes/text.md index 1fd6774b8a..7c75f25168 100644 --- a/site/content/tutorial/01-introduction/03-dynamic-attributes/text.md +++ b/site/content/tutorial/01-introduction/03-dynamic-attributes/text.md @@ -19,10 +19,10 @@ When building web apps, it's important to make sure that they're *accessible* to In this case, we're missing the `alt` attribute that describes the image for people using screenreaders, or people with slow or flaky internet connections that can't download the image. Let's add one: ```html -A man dancing +A man dancing. ``` -We can use curly braces *inside* attributes. Try changing it to `"{name} dancing"` — remember to declare a `name` variable in the ` -{name} dancing \ No newline at end of file +{name} dancing. From 450464f014cf2544e701f882b45df2dcf0a9c492 Mon Sep 17 00:00:00 2001 From: Vlad Glushchuk Date: Mon, 8 Apr 2019 20:28:16 +0200 Subject: [PATCH 04/49] Add bind:text and bind:html support for contenteditable elements Fixes #310 --- src/compiler/compile/nodes/Element.ts | 21 ++++++++- .../render-dom/wrappers/Element/Binding.ts | 16 +++++++ .../render-dom/wrappers/Element/index.ts | 6 +++ .../compile/render-ssr/handlers/Element.ts | 23 +++++++--- .../samples/contenteditable-html/_config.js | 43 +++++++++++++++++++ .../samples/contenteditable-html/main.svelte | 6 +++ .../samples/contenteditable-text/_config.js | 37 ++++++++++++++++ .../samples/contenteditable-text/main.svelte | 6 +++ .../contenteditable-dynamic/errors.json | 15 +++++++ .../contenteditable-dynamic/input.svelte | 6 +++ .../contenteditable-missing/errors.json | 15 +++++++ .../contenteditable-missing/input.svelte | 4 ++ 12 files changed, 192 insertions(+), 6 deletions(-) create mode 100644 test/runtime/samples/contenteditable-html/_config.js create mode 100644 test/runtime/samples/contenteditable-html/main.svelte create mode 100644 test/runtime/samples/contenteditable-text/_config.js create mode 100644 test/runtime/samples/contenteditable-text/main.svelte create mode 100644 test/validator/samples/contenteditable-dynamic/errors.json create mode 100644 test/validator/samples/contenteditable-dynamic/input.svelte create mode 100644 test/validator/samples/contenteditable-missing/errors.json create mode 100644 test/validator/samples/contenteditable-missing/input.svelte diff --git a/src/compiler/compile/nodes/Element.ts b/src/compiler/compile/nodes/Element.ts index 1b2d82188c..757157d9b4 100644 --- a/src/compiler/compile/nodes/Element.ts +++ b/src/compiler/compile/nodes/Element.ts @@ -605,7 +605,26 @@ export default class Element extends Node { message: `'${binding.name}' is not a valid binding on void elements like <${this.name}>. Use a wrapper element instead` }); } - } else if (name !== 'this') { + } else if ( + name === 'text' || + name === 'html' + ){ + const contenteditable = this.attributes.find( + (attribute: Attribute) => attribute.name === 'contenteditable' + ); + + if (!contenteditable) { + component.error(binding, { + code: `missing-contenteditable-attribute`, + message: `'contenteditable' attribute is required for text and html two-way bindings` + }); + } else if (contenteditable && !contenteditable.is_static) { + component.error(contenteditable, { + code: `dynamic-contenteditable-attribute`, + message: `'contenteditable' attribute cannot be dynamic if element uses two-way binding` + }); + } + } else if (name !== 'this') { component.error(binding, { code: `invalid-binding`, message: `'${binding.name}' is not a valid binding` diff --git a/src/compiler/compile/render-dom/wrappers/Element/Binding.ts b/src/compiler/compile/render-dom/wrappers/Element/Binding.ts index 70123fa10c..8eb5ba8097 100644 --- a/src/compiler/compile/render-dom/wrappers/Element/Binding.ts +++ b/src/compiler/compile/render-dom/wrappers/Element/Binding.ts @@ -195,6 +195,14 @@ function get_dom_updater( return `${element.var}.checked = ${condition};` } + if (binding.node.name === 'text') { + return `${element.var}.textContent = ${binding.snippet};`; + } + + if (binding.node.name === 'html') { + return `${element.var}.innerHTML = ${binding.snippet};`; + } + return `${element.var}.${binding.node.name} = ${binding.snippet};`; } @@ -307,6 +315,14 @@ function get_value_from_dom( return `@time_ranges_to_array(this.${name})` } + if (name === 'text') { + return `this.textContent`; + } + + if (name === 'html') { + return `this.innerHTML`; + } + // everything else return `this.${name}`; } diff --git a/src/compiler/compile/render-dom/wrappers/Element/index.ts b/src/compiler/compile/render-dom/wrappers/Element/index.ts index 7d458481f1..a86b45dbb5 100644 --- a/src/compiler/compile/render-dom/wrappers/Element/index.ts +++ b/src/compiler/compile/render-dom/wrappers/Element/index.ts @@ -28,6 +28,12 @@ const events = [ node.name === 'textarea' || node.name === 'input' && !/radio|checkbox|range/.test(node.get_static_attribute_value('type') as string) }, + { + event_names: ['input'], + filter: (node: Element, name: string) => + (name === 'text' || name === 'html') && + node.attributes.some(attribute => attribute.name === 'contenteditable') + }, { event_names: ['change'], filter: (node: Element, name: string) => diff --git a/src/compiler/compile/render-ssr/handlers/Element.ts b/src/compiler/compile/render-ssr/handlers/Element.ts index 5ed6875dec..36ae121b53 100644 --- a/src/compiler/compile/render-ssr/handlers/Element.ts +++ b/src/compiler/compile/render-ssr/handlers/Element.ts @@ -54,7 +54,12 @@ export default function(node: Element, renderer: Renderer, options: RenderOption slot_scopes: Map; }) { let opening_tag = `<${node.name}`; - let textarea_contents; // awkward special case + let node_contents; // awkward special case + const contenteditable = ( + node.name !== 'textarea' && + node.name !== 'input' && + node.attributes.some((attribute: Node) => attribute.name === 'contenteditable') + ); const slot = node.get_static_attribute_value('slot'); const component = node.find_nearest(/InlineComponent/); @@ -91,7 +96,7 @@ export default function(node: Element, renderer: Renderer, options: RenderOption args.push(snip(attribute.expression)); } else { if (attribute.name === 'value' && node.name === 'textarea') { - textarea_contents = stringify_attribute(attribute, true); + node_contents = stringify_attribute(attribute, true); } else if (attribute.is_true) { args.push(`{ ${quote_name_if_necessary(attribute.name)}: true }`); } else if ( @@ -113,7 +118,7 @@ export default function(node: Element, renderer: Renderer, options: RenderOption if (attribute.type !== 'Attribute') return; if (attribute.name === 'value' && node.name === 'textarea') { - textarea_contents = stringify_attribute(attribute, true); + node_contents = stringify_attribute(attribute, true); } else if (attribute.is_true) { opening_tag += ` ${attribute.name}`; } else if ( @@ -146,6 +151,14 @@ export default function(node: Element, renderer: Renderer, options: RenderOption if (name === 'group') { // TODO server-render group bindings + } else if (contenteditable && (node === 'text' || node === 'html')) { + const snippet = snip(expression) + if (name == 'text') { + node_contents = '${@escape(' + snippet + ')}' + } else { + // Do not escape HTML content + node_contents = '${' + snippet + '}' + } } else { const snippet = snip(expression); opening_tag += ' ${(v => v ? ("' + name + '" + (v === true ? "" : "=" + JSON.stringify(v))) : "")(' + snippet + ')}'; @@ -160,8 +173,8 @@ export default function(node: Element, renderer: Renderer, options: RenderOption renderer.append(opening_tag); - if (node.name === 'textarea' && textarea_contents !== undefined) { - renderer.append(textarea_contents); + if ((node.name === 'textarea' || contenteditable) && node_contents !== undefined) { + renderer.append(node_contents); } else { renderer.render(node.children, options); } diff --git a/test/runtime/samples/contenteditable-html/_config.js b/test/runtime/samples/contenteditable-html/_config.js new file mode 100644 index 0000000000..cd2a822655 --- /dev/null +++ b/test/runtime/samples/contenteditable-html/_config.js @@ -0,0 +1,43 @@ +export default { + props: { + name: 'world', + }, + + html: ` + world +

hello world

+ `, + + ssrHtml: ` + world +

hello world

+ `, + + async test({ assert, component, target, window }) { + const el = target.querySelector('editor'); + assert.equal(el.innerHTML, 'world'); + + el.innerHTML = 'everybody'; + + // No updates to data yet + assert.htmlEqual(target.innerHTML, ` + everybody +

hello world

+ `); + + // Handle user input + const event = new window.Event('input'); + await el.dispatchEvent(event); + assert.htmlEqual(target.innerHTML, ` + everybody +

hello everybody

+ `); + + component.name = 'goodbye'; + assert.equal(el.innerHTML, 'goodbye'); + assert.htmlEqual(target.innerHTML, ` + goodbye +

hello goodbye

+ `); + }, +}; diff --git a/test/runtime/samples/contenteditable-html/main.svelte b/test/runtime/samples/contenteditable-html/main.svelte new file mode 100644 index 0000000000..53b4e81c88 --- /dev/null +++ b/test/runtime/samples/contenteditable-html/main.svelte @@ -0,0 +1,6 @@ + + + +

hello {@html name}

\ No newline at end of file diff --git a/test/runtime/samples/contenteditable-text/_config.js b/test/runtime/samples/contenteditable-text/_config.js new file mode 100644 index 0000000000..4935a3a9a7 --- /dev/null +++ b/test/runtime/samples/contenteditable-text/_config.js @@ -0,0 +1,37 @@ +export default { + props: { + name: 'world', + }, + + html: ` + world +

hello world

+ `, + + ssrHtml: ` + world +

hello world

+ `, + + async test({ assert, component, target, window }) { + const el = target.querySelector('editor'); + assert.equal(el.textContent, 'world'); + + const event = new window.Event('input'); + + el.textContent = 'everybody'; + await el.dispatchEvent(event); + + assert.htmlEqual(target.innerHTML, ` + everybody +

hello everybody

+ `); + + component.name = 'goodbye'; + assert.equal(el.textContent, 'goodbye'); + assert.htmlEqual(target.innerHTML, ` + goodbye +

hello goodbye

+ `); + }, +}; diff --git a/test/runtime/samples/contenteditable-text/main.svelte b/test/runtime/samples/contenteditable-text/main.svelte new file mode 100644 index 0000000000..a71d9f0c5b --- /dev/null +++ b/test/runtime/samples/contenteditable-text/main.svelte @@ -0,0 +1,6 @@ + + + +

hello {name}

\ No newline at end of file diff --git a/test/validator/samples/contenteditable-dynamic/errors.json b/test/validator/samples/contenteditable-dynamic/errors.json new file mode 100644 index 0000000000..0c4c5585a6 --- /dev/null +++ b/test/validator/samples/contenteditable-dynamic/errors.json @@ -0,0 +1,15 @@ +[{ + "code": "dynamic-contenteditable-attribute", + "message": "'contenteditable' attribute cannot be dynamic if element uses two-way binding", + "start": { + "line": 6, + "column": 8, + "character": 73 + }, + "end": { + "line": 6, + "column": 32, + "character": 97 + }, + "pos": 73 +}] \ No newline at end of file diff --git a/test/validator/samples/contenteditable-dynamic/input.svelte b/test/validator/samples/contenteditable-dynamic/input.svelte new file mode 100644 index 0000000000..97d2c9228c --- /dev/null +++ b/test/validator/samples/contenteditable-dynamic/input.svelte @@ -0,0 +1,6 @@ + + diff --git a/test/validator/samples/contenteditable-missing/errors.json b/test/validator/samples/contenteditable-missing/errors.json new file mode 100644 index 0000000000..9cadb20629 --- /dev/null +++ b/test/validator/samples/contenteditable-missing/errors.json @@ -0,0 +1,15 @@ +[{ + "code": "missing-contenteditable-attribute", + "message": "'contenteditable' attribute is required for text and html two-way bindings", + "start": { + "line": 4, + "column": 8, + "character": 48 + }, + "end": { + "line": 4, + "column": 24, + "character": 64 + }, + "pos": 48 +}] \ No newline at end of file diff --git a/test/validator/samples/contenteditable-missing/input.svelte b/test/validator/samples/contenteditable-missing/input.svelte new file mode 100644 index 0000000000..47f125894a --- /dev/null +++ b/test/validator/samples/contenteditable-missing/input.svelte @@ -0,0 +1,4 @@ + + From b1dc46d4f44d9d04f963f0829da4eb8cf5fd28f6 Mon Sep 17 00:00:00 2001 From: Vlad Glushchuk Date: Mon, 8 Apr 2019 20:56:52 +0200 Subject: [PATCH 05/49] Fix a typo --- src/compiler/compile/render-ssr/handlers/Element.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/compiler/compile/render-ssr/handlers/Element.ts b/src/compiler/compile/render-ssr/handlers/Element.ts index 36ae121b53..fc7f7df1a6 100644 --- a/src/compiler/compile/render-ssr/handlers/Element.ts +++ b/src/compiler/compile/render-ssr/handlers/Element.ts @@ -151,7 +151,7 @@ export default function(node: Element, renderer: Renderer, options: RenderOption if (name === 'group') { // TODO server-render group bindings - } else if (contenteditable && (node === 'text' || node === 'html')) { + } else if (contenteditable && (name === 'text' || name === 'html')) { const snippet = snip(expression) if (name == 'text') { node_contents = '${@escape(' + snippet + ')}' From 2cd66c0447cdcf7d1a0f42de513047d553467bcc Mon Sep 17 00:00:00 2001 From: Vlad Glushchuk Date: Sat, 20 Apr 2019 08:11:57 +0200 Subject: [PATCH 06/49] Fix the cursor reset issue --- src/compiler/compile/render-dom/wrappers/Element/Binding.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/compiler/compile/render-dom/wrappers/Element/Binding.ts b/src/compiler/compile/render-dom/wrappers/Element/Binding.ts index 8eb5ba8097..74a7bd86ab 100644 --- a/src/compiler/compile/render-dom/wrappers/Element/Binding.ts +++ b/src/compiler/compile/render-dom/wrappers/Element/Binding.ts @@ -196,11 +196,11 @@ function get_dom_updater( } if (binding.node.name === 'text') { - return `${element.var}.textContent = ${binding.snippet};`; + return `if (${binding.snippet} !== ${element.var}.textContent) ${element.var}.textContent = ${binding.snippet};`; } if (binding.node.name === 'html') { - return `${element.var}.innerHTML = ${binding.snippet};`; + return `if (${binding.snippet} !== ${element.var}.innerHTML) ${element.var}.innerHTML = ${binding.snippet};`; } return `${element.var}.${binding.node.name} = ${binding.snippet};`; From f5dde02b9912287cdd4f53fd5af0935af80b57a0 Mon Sep 17 00:00:00 2001 From: Vlad Glushchuk Date: Thu, 6 Jun 2019 10:57:41 +0200 Subject: [PATCH 07/49] Rebase and fix linter warning --- src/compiler/compile/render-ssr/handlers/Element.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/compiler/compile/render-ssr/handlers/Element.ts b/src/compiler/compile/render-ssr/handlers/Element.ts index fc7f7df1a6..8b901853d1 100644 --- a/src/compiler/compile/render-ssr/handlers/Element.ts +++ b/src/compiler/compile/render-ssr/handlers/Element.ts @@ -58,7 +58,7 @@ export default function(node: Element, renderer: Renderer, options: RenderOption const contenteditable = ( node.name !== 'textarea' && node.name !== 'input' && - node.attributes.some((attribute: Node) => attribute.name === 'contenteditable') + node.attributes.some((attribute) => attribute.name === 'contenteditable') ); const slot = node.get_static_attribute_value('slot'); From 535d66851677ada16410dc7e567d1b3e170bab32 Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Thu, 6 Jun 2019 08:20:46 -0400 Subject: [PATCH 08/49] Change text to a sentence, since we're ending it with a period --- .../tutorial/01-introduction/03-dynamic-attributes/text.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/site/content/tutorial/01-introduction/03-dynamic-attributes/text.md b/site/content/tutorial/01-introduction/03-dynamic-attributes/text.md index 7c75f25168..c503b4f548 100644 --- a/site/content/tutorial/01-introduction/03-dynamic-attributes/text.md +++ b/site/content/tutorial/01-introduction/03-dynamic-attributes/text.md @@ -19,10 +19,10 @@ When building web apps, it's important to make sure that they're *accessible* to In this case, we're missing the `alt` attribute that describes the image for people using screenreaders, or people with slow or flaky internet connections that can't download the image. Let's add one: ```html -A man dancing. +A man dances. ``` -We can use curly braces *inside* attributes. Try changing it to `"{name} dancing."` — remember to declare a `name` variable in the ` -{name} dancing. +{name} dances. From c2c1791317429ba51e9814605c9d99128344c02a Mon Sep 17 00:00:00 2001 From: Conduitry Date: Fri, 7 Jun 2019 05:05:15 -0400 Subject: [PATCH 10/49] site: update Dockerfile to Node 12 --- site/Dockerfile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/site/Dockerfile b/site/Dockerfile index f53e6a0c4a..c2a65122d9 100644 --- a/site/Dockerfile +++ b/site/Dockerfile @@ -1,4 +1,4 @@ -FROM mhart/alpine-node:11.14 +FROM mhart/alpine-node:12 # install dependencies WORKDIR /app @@ -9,7 +9,7 @@ RUN npm ci --production # Only copy over the Node pieces we need # ~> Saves 35MB ### -FROM mhart/alpine-node:base-11.14 +FROM mhart/alpine-node:slim-12 WORKDIR /app COPY --from=0 /app . From 02dd05d2774dfa9f23a98e96f5245a73c92498bc Mon Sep 17 00:00:00 2001 From: Josh Duff Date: Fri, 7 Jun 2019 09:05:59 -0500 Subject: [PATCH 11/49] Explicitly support node 8+ --- .travis.yml | 5 +++-- package.json | 3 +++ 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index aeadd48f8d..a4603a26e2 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,7 +1,8 @@ language: node_js node_js: - - "node" - + - "8" + - "10" + - "12" env: global: - BUILD_TIMEOUT=20000 diff --git a/package.json b/package.json index 6d4bfb134e..71deaeec90 100644 --- a/package.json +++ b/package.json @@ -18,6 +18,9 @@ "svelte", "README.md" ], + "engines": { + "node": "^8" + }, "types": "types/runtime", "scripts": { "test": "mocha --opts mocha.opts", From 946d63895c96d43f09967bb37824fdfcfe049ef2 Mon Sep 17 00:00:00 2001 From: Josh Duff Date: Fri, 7 Jun 2019 16:35:29 -0500 Subject: [PATCH 12/49] Fix engine range --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 71deaeec90..73b2bb46f2 100644 --- a/package.json +++ b/package.json @@ -19,7 +19,7 @@ "README.md" ], "engines": { - "node": "^8" + "node": ">8" }, "types": "types/runtime", "scripts": { From 6c772597065630f4fc9f2d5ad29eab272d14db10 Mon Sep 17 00:00:00 2001 From: Josh Duff Date: Fri, 7 Jun 2019 16:45:40 -0500 Subject: [PATCH 13/49] Fix the bad fix Co-Authored-By: Watanabe Shinnosuke --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 73b2bb46f2..d45b37724f 100644 --- a/package.json +++ b/package.json @@ -19,7 +19,7 @@ "README.md" ], "engines": { - "node": ">8" + "node": ">= 8" }, "types": "types/runtime", "scripts": { From 17c4a25016892ea542a2c3412e9b2c40d0e1a850 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Efe=20K=C3=BC=C3=A7=C3=BCk?= Date: Sun, 9 Jun 2019 18:00:44 +0300 Subject: [PATCH 14/49] Render textarea binding values inside element * ssr-textarea-bind-fix * oops * trying again * Fixing an old test * avoid creating extra function expression --- src/compiler/compile/render-ssr/handlers/Element.ts | 3 +++ test/runtime/samples/binding-textarea/_config.js | 2 +- .../samples/text-area-bind/_expected.html | 1 + .../server-side-rendering/samples/text-area-bind/main.svelte | 5 +++++ 4 files changed, 10 insertions(+), 1 deletion(-) create mode 100644 test/server-side-rendering/samples/text-area-bind/_expected.html create mode 100644 test/server-side-rendering/samples/text-area-bind/main.svelte diff --git a/src/compiler/compile/render-ssr/handlers/Element.ts b/src/compiler/compile/render-ssr/handlers/Element.ts index 5ed6875dec..9314f3007f 100644 --- a/src/compiler/compile/render-ssr/handlers/Element.ts +++ b/src/compiler/compile/render-ssr/handlers/Element.ts @@ -146,6 +146,9 @@ export default function(node: Element, renderer: Renderer, options: RenderOption if (name === 'group') { // TODO server-render group bindings + } else if (binding.name === 'value' && node.name === 'textarea') { + const snippet = snip(expression); + textarea_contents='${(' + snippet + ') || ""}'; } else { const snippet = snip(expression); opening_tag += ' ${(v => v ? ("' + name + '" + (v === true ? "" : "=" + JSON.stringify(v))) : "")(' + snippet + ')}'; diff --git a/test/runtime/samples/binding-textarea/_config.js b/test/runtime/samples/binding-textarea/_config.js index c09256e059..ac092096e6 100644 --- a/test/runtime/samples/binding-textarea/_config.js +++ b/test/runtime/samples/binding-textarea/_config.js @@ -9,7 +9,7 @@ export default { `, ssrHtml: ` - +

some text

`, diff --git a/test/server-side-rendering/samples/text-area-bind/_expected.html b/test/server-side-rendering/samples/text-area-bind/_expected.html new file mode 100644 index 0000000000..c3c8441f56 --- /dev/null +++ b/test/server-side-rendering/samples/text-area-bind/_expected.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/test/server-side-rendering/samples/text-area-bind/main.svelte b/test/server-side-rendering/samples/text-area-bind/main.svelte new file mode 100644 index 0000000000..7126e09375 --- /dev/null +++ b/test/server-side-rendering/samples/text-area-bind/main.svelte @@ -0,0 +1,5 @@ + + + \ No newline at end of file From 0dde4f51e0b1c9231d8b696a191fa46f8a473d5d Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Sun, 9 Jun 2019 11:08:49 -0400 Subject: [PATCH 15/49] Update text.md --- site/content/tutorial/03-props/02-default-values/text.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/site/content/tutorial/03-props/02-default-values/text.md b/site/content/tutorial/03-props/02-default-values/text.md index dda6a370fe..1532407380 100644 --- a/site/content/tutorial/03-props/02-default-values/text.md +++ b/site/content/tutorial/03-props/02-default-values/text.md @@ -10,9 +10,9 @@ We can easily specify default values for props: ``` -If we now instantiate the component without an `answer` prop, it will fall back to the default: +If we now add a second component *without* an `answer` prop, it will fall back to the default: ```html -``` \ No newline at end of file +``` From caebe0deb80d959ad7c7b5276d7e017be71769c7 Mon Sep 17 00:00:00 2001 From: James Garbutt <43081j@users.noreply.github.com> Date: Sun, 9 Jun 2019 16:31:28 +0100 Subject: [PATCH 16/49] Introduce ESLint to svelte sources (#2958) * introduce eslint * add lint npm script * first eslint run * use tsc stronger checks for unused vars * fix strict typescript unused checks * reintroduce unicode oddities * revert ordering changes * revert whitespace changes * set indent lint rule as error and ignore outliers * revert some more unicode * reintroduce scissors unicode again --- .eslintignore | 8 +- .eslintrc.json | 115 ++- package-lock.json | 941 ++++++++++++++++++ package.json | 7 +- src/compiler/Stats.ts | 2 +- src/compiler/compile/Component.ts | 77 +- src/compiler/compile/create_module.ts | 16 +- src/compiler/compile/css/Selector.ts | 6 +- src/compiler/compile/css/Stylesheet.ts | 12 +- src/compiler/compile/index.ts | 7 +- src/compiler/compile/nodes/Attribute.ts | 2 +- src/compiler/compile/nodes/EachBlock.ts | 16 +- src/compiler/compile/nodes/Element.ts | 6 +- src/compiler/compile/nodes/InlineComponent.ts | 2 + src/compiler/compile/nodes/PendingBlock.ts | 2 +- src/compiler/compile/nodes/Window.ts | 4 +- src/compiler/compile/nodes/interfaces.ts | 58 +- .../compile/nodes/shared/Expression.ts | 10 +- src/compiler/compile/nodes/shared/Node.ts | 2 +- src/compiler/compile/render-dom/Block.ts | 10 +- src/compiler/compile/render-dom/Renderer.ts | 4 +- src/compiler/compile/render-dom/index.ts | 10 +- .../compile/render-dom/wrappers/Body.ts | 2 +- .../compile/render-dom/wrappers/DebugTag.ts | 6 +- .../compile/render-dom/wrappers/EachBlock.ts | 2 +- .../render-dom/wrappers/Element/Attribute.ts | 6 +- .../render-dom/wrappers/Element/Binding.ts | 23 +- .../wrappers/Element/StyleAttribute.ts | 12 +- .../render-dom/wrappers/Element/index.ts | 20 +- .../compile/render-dom/wrappers/Fragment.ts | 7 +- .../compile/render-dom/wrappers/Head.ts | 2 +- .../compile/render-dom/wrappers/IfBlock.ts | 10 +- .../wrappers/InlineComponent/index.ts | 12 +- .../compile/render-dom/wrappers/Slot.ts | 4 +- .../compile/render-dom/wrappers/Title.ts | 9 +- .../compile/render-dom/wrappers/Window.ts | 5 +- .../render-dom/wrappers/shared/Wrapper.ts | 2 +- .../render-dom/wrappers/shared/add_actions.ts | 5 +- src/compiler/compile/render-ssr/Renderer.ts | 6 +- .../compile/render-ssr/handlers/EachBlock.ts | 2 +- .../compile/render-ssr/handlers/Element.ts | 1 - .../compile/render-ssr/handlers/HtmlTag.ts | 2 +- .../compile/render-ssr/handlers/Tag.ts | 2 +- .../compile/render-ssr/handlers/Text.ts | 2 +- src/compiler/compile/utils/add_to_set.ts | 2 +- src/compiler/compile/utils/scope.ts | 4 +- src/compiler/interfaces.ts | 36 +- src/compiler/parse/index.ts | 4 +- src/compiler/parse/read/context.ts | 14 +- src/compiler/parse/read/expression.ts | 2 + src/compiler/parse/state/mustache.ts | 2 +- src/compiler/parse/state/tag.ts | 10 +- src/compiler/parse/state/text.ts | 2 +- src/compiler/preprocess/index.ts | 22 +- src/compiler/utils/error.ts | 16 +- src/compiler/utils/full_char_code_at.ts | 4 +- src/compiler/utils/fuzzymatch.ts | 6 +- src/runtime/animate/index.ts | 16 +- src/runtime/internal/Component.ts | 7 +- src/runtime/internal/animations.ts | 2 +- src/runtime/internal/dom.ts | 17 +- src/runtime/internal/loop.ts | 2 +- src/runtime/internal/transitions.ts | 8 +- src/runtime/internal/utils.ts | 2 +- src/runtime/motion/spring.ts | 24 +- src/runtime/motion/tweened.ts | 8 +- src/runtime/store/index.ts | 4 +- src/runtime/transition/index.ts | 26 +- test/.eslintrc.json | 5 + test/runtime/samples/animation-css/_config.js | 4 +- .../samples/animation-js-delay/_config.js | 4 +- .../samples/animation-js-easing/_config.js | 4 +- test/runtime/samples/animation-js/_config.js | 2 +- .../samples/await-containing-if/_config.js | 2 +- test/runtime/samples/await-in-each/_config.js | 2 +- .../samples/await-then-catch-order/_config.js | 2 +- .../samples/await-with-components/_config.js | 3 +- .../_config.js | 2 +- .../samples/element-invalid-name/_config.js | 2 +- .../export-function-hoisting/_config.js | 4 +- .../samples/function-hoisting/_config.js | 10 +- .../samples/get-after-destroy/_config.js | 2 +- .../samples/immutable-nested/_config.js | 3 +- .../samples/immutable-option/_config.js | 1 + .../immutable-svelte-meta-false/_config.js | 1 + .../samples/immutable-svelte-meta/_config.js | 1 + .../runtime/samples/internal-state/_config.js | 28 +- .../samples/mixed-let-export/_config.js | 14 +- test/runtime/samples/prop-exports/_config.js | 46 +- test/runtime/samples/spring/_config.js | 2 +- .../transition-js-await-block/_config.js | 6 +- test/server-side-rendering/index.js | 1 - test/setup.js | 4 +- test/sourcemaps/index.js | 4 +- test/store/index.ts | 2 +- test/test.js | 4 +- test/validator/index.js | 4 +- tsconfig.json | 2 + 98 files changed, 1442 insertions(+), 428 deletions(-) create mode 100644 test/.eslintrc.json diff --git a/.eslintignore b/.eslintignore index 4a113378ce..97a855e951 100644 --- a/.eslintignore +++ b/.eslintignore @@ -1,7 +1,3 @@ -src/shared -shared.js -store.js -test/test.js -test/setup.js **/_actual.js -**/expected.js \ No newline at end of file +**/expected.js +test/*/samples/*/output.js diff --git a/.eslintrc.json b/.eslintrc.json index 3d2c0f6869..c821993c40 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -1,43 +1,76 @@ { - "root": true, - "rules": { - "indent": [2, "tab", { "SwitchCase": 1 }], - "semi": [2, "always"], - "keyword-spacing": [2, { "before": true, "after": true }], - "space-before-blocks": [2, "always"], - "no-mixed-spaces-and-tabs": [2, "smart-tabs"], - "no-cond-assign": 0, - "no-unused-vars": 2, - "object-shorthand": [2, "always"], - "no-const-assign": 2, - "no-class-assign": 2, - "no-this-before-super": 2, - "no-var": 2, - "no-unreachable": 2, - "valid-typeof": 2, - "quote-props": [2, "as-needed"], - "one-var": [2, "never"], - "prefer-arrow-callback": 2, - "prefer-const": [2, { "destructuring": "all" }], - "arrow-spacing": 2, - "no-inner-declarations": 0 - }, - "env": { - "es6": true, - "browser": true, - "node": true, - "mocha": true - }, - "extends": [ - "eslint:recommended", - "plugin:import/errors", - "plugin:import/warnings" - ], - "parserOptions": { - "ecmaVersion": 9, - "sourceType": "module" - }, - "settings": { - "import/core-modules": ["svelte"] - } + "root": true, + "rules": { + "indent": "off", + "no-unused-vars": "off", + "semi": [2, "always"], + "keyword-spacing": [2, { "before": true, "after": true }], + "space-before-blocks": [2, "always"], + "no-mixed-spaces-and-tabs": [2, "smart-tabs"], + "no-cond-assign": 0, + "object-shorthand": [2, "always"], + "no-const-assign": 2, + "no-class-assign": 2, + "no-this-before-super": 2, + "no-var": 2, + "no-unreachable": 2, + "valid-typeof": 2, + "quote-props": [2, "as-needed"], + "one-var": [2, "never"], + "prefer-arrow-callback": 2, + "prefer-const": [2, { "destructuring": "all" }], + "arrow-spacing": 2, + "no-inner-declarations": 0, + "@typescript-eslint/indent": ["error", "tab", { + "SwitchCase": 1, + "ignoredNodes": ["TemplateLiteral"] + }], + "@typescript-eslint/camelcase": "off", + "@typescript-eslint/no-use-before-define": "off", + "@typescript-eslint/array-type": ["error", "array-simple"], + "@typescript-eslint/explicit-function-return-type": "off", + "@typescript-eslint/no-explicit-any": "off", + "@typescript-eslint/explicit-member-accessibility": "off", + "@typescript-eslint/no-unused-vars": ["error", { + "argsIgnorePattern": "^_" + }], + "@typescript-eslint/no-object-literal-type-assertion": ["error", { + "allowAsParameter": true + }], + "@typescript-eslint/no-unused-vars": "off" + }, + "env": { + "es6": true, + "browser": true, + "node": true, + "mocha": true + }, + "extends": [ + "eslint:recommended", + "plugin:import/errors", + "plugin:import/warnings", + "plugin:import/typescript", + "plugin:@typescript-eslint/recommended" + ], + "parserOptions": { + "ecmaVersion": 9, + "sourceType": "module" + }, + "settings": { + "import/core-modules": [ + "svelte", + "svelte/internal", + "svelte/store", + "svelte/easing", + "estree" + ] + }, + "overrides": [ + { + "files": ["*.js"], + "rules": { + "@typescript-eslint/no-var-requires": "off" + } + } + ] } diff --git a/package-lock.json b/package-lock.json index 1c6ced1a92..f1e8bf1d32 100644 --- a/package-lock.json +++ b/package-lock.json @@ -4,6 +4,26 @@ "lockfileVersion": 1, "requires": true, "dependencies": { + "@babel/code-frame": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.0.0.tgz", + "integrity": "sha512-OfC2uemaknXr87bdLUkWog7nYuliM9Ij5HUcajsVcMCpQrcLmtxRbVFTIqmcSkSeYRBFBRxs2FiUqFJDLdiebA==", + "dev": true, + "requires": { + "@babel/highlight": "^7.0.0" + } + }, + "@babel/highlight": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.0.0.tgz", + "integrity": "sha512-UFMC4ZeFC48Tpvj7C8UgLvtkaUuovQX+5xNWrsIoMG8o2z+XFKjKaN9iVmS84dPwVN00W4wPmqvYoZF3EGAsfw==", + "dev": true, + "requires": { + "chalk": "^2.0.0", + "esutils": "^2.0.2", + "js-tokens": "^4.0.0" + } + }, "@bcoe/v8-coverage": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.1.0.tgz", @@ -44,6 +64,60 @@ "integrity": "sha512-fh+pAqt4xRzPfqA6eh3Z2y6fyZavRIumvjhaCL753+TVkGKGhpPeyrJG2JftD0T9q4GF00KjefsQ+PQNDdWQaQ==", "dev": true }, + "@typescript-eslint/eslint-plugin": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-1.9.0.tgz", + "integrity": "sha512-FOgfBorxjlBGpDIw+0LaZIXRX6GEEUfzj8LXwaQIUCp+gDOvkI+1WgugJ7SmWiISqK9Vj5r8S7NDKO/LB+6X9A==", + "dev": true, + "requires": { + "@typescript-eslint/experimental-utils": "1.9.0", + "@typescript-eslint/parser": "1.9.0", + "eslint-utils": "^1.3.1", + "functional-red-black-tree": "^1.0.1", + "regexpp": "^2.0.1", + "requireindex": "^1.2.0", + "tsutils": "^3.7.0" + } + }, + "@typescript-eslint/experimental-utils": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-1.9.0.tgz", + "integrity": "sha512-1s2dY9XxBwtS9IlSnRIlzqILPyeMly5tz1bfAmQ84Ul687xBBve5YsH5A5EKeIcGurYYqY2w6RkHETXIwnwV0A==", + "dev": true, + "requires": { + "@typescript-eslint/typescript-estree": "1.9.0" + } + }, + "@typescript-eslint/parser": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-1.9.0.tgz", + "integrity": "sha512-CWgC1XrQ34H/+LwAU7vY5xteZDkNqeAkeidEpJnJgkKu0yqQ3ZhQ7S+dI6MX4vmmM1TKRbOrKuXc6W0fIHhdbA==", + "dev": true, + "requires": { + "@typescript-eslint/experimental-utils": "1.9.0", + "@typescript-eslint/typescript-estree": "1.9.0", + "eslint-scope": "^4.0.0", + "eslint-visitor-keys": "^1.0.0" + } + }, + "@typescript-eslint/typescript-estree": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-1.9.0.tgz", + "integrity": "sha512-7Eg0TEQpCkTsEwsl1lIzd6i7L3pJLQFWesV08dS87bNz0NeSjbL78gNAP1xCKaCejkds4PhpLnZkaAjx9SU8OA==", + "dev": true, + "requires": { + "lodash.unescape": "4.0.1", + "semver": "5.5.0" + }, + "dependencies": { + "semver": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.5.0.tgz", + "integrity": "sha512-4SJ3dm0WAwWy/NVeioZh5AntkdJoWKxHxcmyP622fOkgHa4z3R0TdBJICINyaSDE6uNwVc8gZr+ZinwZAH4xIA==", + "dev": true + } + } + }, "abab": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.0.tgz", @@ -72,6 +146,12 @@ "acorn-walk": "^6.0.1" } }, + "acorn-jsx": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.0.1.tgz", + "integrity": "sha512-HJ7CfNHrfJLlNTzIEUTj43LNWGkqpRLxm3YjAlcD0ACydk9XynzYsCBHxut+iqt+1aBXkx9UP/w/ZqMr13XIzg==", + "dev": true + }, "acorn-walk": { "version": "6.1.1", "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-6.1.1.tgz", @@ -121,12 +201,27 @@ "uri-js": "^4.2.2" } }, + "ansi-escapes": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.2.0.tgz", + "integrity": "sha512-cBhpre4ma+U0T1oM5fXg7Dy1Jw7zzwv7lt/GoCpr+hDQJoYnKVPLL4dCvSEFMmQurOQvSrwT7SL/DAlhBI97RQ==", + "dev": true + }, "ansi-regex": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", "dev": true }, + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, "any-promise": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz", @@ -172,6 +267,16 @@ "integrity": "sha1-jCpe8kcv2ep0KwTHenUJO6J1fJM=", "dev": true }, + "array-includes": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.0.3.tgz", + "integrity": "sha1-GEtI9i2S10UrsxsyMWXH+L0CJm0=", + "dev": true, + "requires": { + "define-properties": "^1.1.2", + "es-abstract": "^1.7.0" + } + }, "arrify": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", @@ -199,6 +304,12 @@ "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=", "dev": true }, + "astral-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-1.0.0.tgz", + "integrity": "sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg==", + "dev": true + }, "async-limiter": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.0.tgz", @@ -436,12 +547,35 @@ } } }, + "callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true + }, "caseless": { "version": "0.12.0", "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=", "dev": true }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "chardet": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz", + "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==", + "dev": true + }, "class-utils": { "version": "0.3.6", "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz", @@ -471,6 +605,21 @@ } } }, + "cli-cursor": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz", + "integrity": "sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU=", + "dev": true, + "requires": { + "restore-cursor": "^2.0.0" + } + }, + "cli-width": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.0.tgz", + "integrity": "sha1-/xnt6Kml5XkyQUewwR8PvLq+1jk=", + "dev": true + }, "cliui": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/cliui/-/cliui-4.1.0.tgz", @@ -517,6 +666,21 @@ "object-visit": "^1.0.0" } }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true + }, "combined-stream": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.7.tgz", @@ -582,6 +746,12 @@ } } }, + "contains-path": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/contains-path/-/contains-path-0.1.0.tgz", + "integrity": "sha1-/ozxhP9mcLa67wGp1IYaXL7EEgo=", + "dev": true + }, "copy-descriptor": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz", @@ -687,6 +857,15 @@ "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=", "dev": true }, + "define-properties": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", + "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", + "dev": true, + "requires": { + "object-keys": "^1.0.12" + } + }, "define-property": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", @@ -752,6 +931,15 @@ "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==", "dev": true }, + "doctrine": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", + "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", + "dev": true, + "requires": { + "esutils": "^2.0.2" + } + }, "domexception": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/domexception/-/domexception-1.0.1.tgz", @@ -771,6 +959,12 @@ "safer-buffer": "^2.1.0" } }, + "emoji-regex": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", + "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", + "dev": true + }, "end-of-stream": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.1.tgz", @@ -789,6 +983,31 @@ "is-arrayish": "^0.2.1" } }, + "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==", + "dev": true, + "requires": { + "es-to-primitive": "^1.2.0", + "function-bind": "^1.1.1", + "has": "^1.0.3", + "is-callable": "^1.1.4", + "is-regex": "^1.0.4", + "object-keys": "^1.0.12" + } + }, + "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==", + "dev": true, + "requires": { + "is-callable": "^1.1.4", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.2" + } + }, "es6-promise": { "version": "4.2.6", "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.6.tgz", @@ -831,12 +1050,230 @@ } } }, + "eslint": { + "version": "5.16.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-5.16.0.tgz", + "integrity": "sha512-S3Rz11i7c8AA5JPv7xAH+dOyq/Cu/VXHiHXBPOU1k/JAM5dXqQPt3qcrhpHSorXmrpu2g0gkIBVXAqCpzfoZIg==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.0.0", + "ajv": "^6.9.1", + "chalk": "^2.1.0", + "cross-spawn": "^6.0.5", + "debug": "^4.0.1", + "doctrine": "^3.0.0", + "eslint-scope": "^4.0.3", + "eslint-utils": "^1.3.1", + "eslint-visitor-keys": "^1.0.0", + "espree": "^5.0.1", + "esquery": "^1.0.1", + "esutils": "^2.0.2", + "file-entry-cache": "^5.0.1", + "functional-red-black-tree": "^1.0.1", + "glob": "^7.1.2", + "globals": "^11.7.0", + "ignore": "^4.0.6", + "import-fresh": "^3.0.0", + "imurmurhash": "^0.1.4", + "inquirer": "^6.2.2", + "js-yaml": "^3.13.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.3.0", + "lodash": "^4.17.11", + "minimatch": "^3.0.4", + "mkdirp": "^0.5.1", + "natural-compare": "^1.4.0", + "optionator": "^0.8.2", + "path-is-inside": "^1.0.2", + "progress": "^2.0.0", + "regexpp": "^2.0.1", + "semver": "^5.5.1", + "strip-ansi": "^4.0.0", + "strip-json-comments": "^2.0.1", + "table": "^5.2.3", + "text-table": "^0.2.0" + }, + "dependencies": { + "ajv": { + "version": "6.10.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.10.0.tgz", + "integrity": "sha512-nffhOpkymDECQyR0mnsUtoCE8RlX38G0rYP+wgLWFyZuUyuuojSSvi/+euOiQBIn63whYwYVIIH1TvE3tu4OEg==", + "dev": true, + "requires": { + "fast-deep-equal": "^2.0.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + } + } + }, + "eslint-import-resolver-node": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.2.tgz", + "integrity": "sha512-sfmTqJfPSizWu4aymbPr4Iidp5yKm8yDkHp+Ir3YiTHiiDfxh69mOUsmiqW6RZ9zRXFaF64GtYmN7e+8GHBv6Q==", + "dev": true, + "requires": { + "debug": "^2.6.9", + "resolve": "^1.5.0" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + } + } + }, + "eslint-module-utils": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.4.0.tgz", + "integrity": "sha512-14tltLm38Eu3zS+mt0KvILC3q8jyIAH518MlG+HO0p+yK885Lb1UHTY/UgR91eOyGdmxAPb+OLoW4znqIT6Ndw==", + "dev": true, + "requires": { + "debug": "^2.6.8", + "pkg-dir": "^2.0.0" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + } + } + }, + "eslint-plugin-import": { + "version": "2.17.3", + "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.17.3.tgz", + "integrity": "sha512-qeVf/UwXFJbeyLbxuY8RgqDyEKCkqV7YC+E5S5uOjAp4tOc8zj01JP3ucoBM8JcEqd1qRasJSg6LLlisirfy0Q==", + "dev": true, + "requires": { + "array-includes": "^3.0.3", + "contains-path": "^0.1.0", + "debug": "^2.6.9", + "doctrine": "1.5.0", + "eslint-import-resolver-node": "^0.3.2", + "eslint-module-utils": "^2.4.0", + "has": "^1.0.3", + "lodash": "^4.17.11", + "minimatch": "^3.0.4", + "read-pkg-up": "^2.0.0", + "resolve": "^1.11.0" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "doctrine": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-1.5.0.tgz", + "integrity": "sha1-N53Ocw9hZvds76TmcHoVmwLFpvo=", + "dev": true, + "requires": { + "esutils": "^2.0.2", + "isarray": "^1.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + }, + "resolve": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.11.1.tgz", + "integrity": "sha512-vIpgF6wfuJOZI7KKKSP+HmiKggadPQAdsp5HiC1mvqnfp0gF1vdwgBWZIdrVft9pgqoMFQN+R7BSWZiBxx+BBw==", + "dev": true, + "requires": { + "path-parse": "^1.0.6" + } + } + } + }, + "eslint-scope": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-4.0.3.tgz", + "integrity": "sha512-p7VutNr1O/QrxysMo3E45FjYDTeXBy0iTltPFNSqKAIfjDSXC+4dj+qfyuD8bfAXrW/y6lW3O76VaYNPKfpKrg==", + "dev": true, + "requires": { + "esrecurse": "^4.1.0", + "estraverse": "^4.1.1" + } + }, + "eslint-utils": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-1.3.1.tgz", + "integrity": "sha512-Z7YjnIldX+2XMcjr7ZkgEsOj/bREONV60qYeB/bjMAqqqZ4zxKyWX+BOUkdmRmA9riiIPVvo5x86m5elviOk0Q==", + "dev": true + }, + "eslint-visitor-keys": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz", + "integrity": "sha512-qzm/XxIbxm/FHyH341ZrbnMUpe+5Bocte9xkmFMzPMjRaZMcXww+MpBptFvtU+79L362nqiLhekCxCxDPaUMBQ==", + "dev": true + }, + "espree": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-5.0.1.tgz", + "integrity": "sha512-qWAZcWh4XE/RwzLJejfcofscgMc9CamR6Tn1+XRXNzrvUSSbiAjGOI/fggztjIi7y9VLPqnICMIPiGyr8JaZ0A==", + "dev": true, + "requires": { + "acorn": "^6.0.7", + "acorn-jsx": "^5.0.0", + "eslint-visitor-keys": "^1.0.0" + } + }, "esprima": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", "dev": true }, + "esquery": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.0.1.tgz", + "integrity": "sha512-SmiyZ5zIWH9VM+SRUReLS5Q8a7GxtRdxEBVZpm98rJM7Sb+A9DVCndXfkeFUd3byderg+EbDkfnevfCwynWaNA==", + "dev": true, + "requires": { + "estraverse": "^4.0.0" + } + }, + "esrecurse": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.1.tgz", + "integrity": "sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ==", + "dev": true, + "requires": { + "estraverse": "^4.1.0" + } + }, "estraverse": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.2.0.tgz", @@ -897,6 +1334,17 @@ } } }, + "external-editor": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.0.3.tgz", + "integrity": "sha512-bn71H9+qWoOQKyZDo25mOMVpSmXROAsTJVVVYzrrtol3d4y+AsKjf4Iwl2Q+IuT0kFSQ1qo166UuIwqYq7mGnA==", + "dev": true, + "requires": { + "chardet": "^0.7.0", + "iconv-lite": "^0.4.24", + "tmp": "^0.0.33" + } + }, "extract-zip": { "version": "1.6.7", "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-1.6.7.tgz", @@ -959,6 +1407,50 @@ "pend": "~1.2.0" } }, + "figures": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz", + "integrity": "sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI=", + "dev": true, + "requires": { + "escape-string-regexp": "^1.0.5" + } + }, + "file-entry-cache": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-5.0.1.tgz", + "integrity": "sha512-bCg29ictuBaKUwwArK4ouCaqDgLZcysCFLmM/Yn/FDoqndh/9vNuQfXRDvTuXKLxfD/JtZQGKFT8MGcJBK644g==", + "dev": true, + "requires": { + "flat-cache": "^2.0.1" + } + }, + "find-up": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", + "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", + "dev": true, + "requires": { + "locate-path": "^2.0.0" + } + }, + "flat-cache": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-2.0.1.tgz", + "integrity": "sha512-LoQe6yDuUMDzQAEH8sgmh4Md6oZnc/7PjtwjNFSzveXqSHt6ka9fPBuso7IGf9Rz4uqnSnWiFH2B/zj24a5ReA==", + "dev": true, + "requires": { + "flatted": "^2.0.0", + "rimraf": "2.6.3", + "write": "1.0.3" + } + }, + "flatted": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-2.0.0.tgz", + "integrity": "sha512-R+H8IZclI8AAkSBRQJLVOsxwAoHd6WC40b4QTNWIjzAa6BXOBfQcM587MXDTVPeYaopFNWHUFLx7eNmHDSxMWg==", + "dev": true + }, "for-in": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", @@ -1019,6 +1511,18 @@ "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", "dev": true }, + "function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", + "dev": true + }, + "functional-red-black-tree": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", + "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", + "dev": true + }, "furi": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/furi/-/furi-1.3.0.tgz", @@ -1073,6 +1577,12 @@ "path-is-absolute": "^1.0.0" } }, + "globals": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "dev": true + }, "globalyzer": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/globalyzer/-/globalyzer-0.1.0.tgz", @@ -1125,12 +1635,27 @@ "har-schema": "^2.0.0" } }, + "has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "dev": true, + "requires": { + "function-bind": "^1.1.1" + } + }, "has-flag": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", "dev": true }, + "has-symbols": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.0.tgz", + "integrity": "sha1-uhqPGvKg/DllD1yFA2dwQSIGO0Q=", + "dev": true + }, "has-value": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz", @@ -1253,6 +1778,12 @@ "safer-buffer": ">= 2.1.2 < 3" } }, + "ignore": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", + "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", + "dev": true + }, "ignore-walk": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/ignore-walk/-/ignore-walk-3.0.1.tgz", @@ -1262,6 +1793,22 @@ "minimatch": "^3.0.4" } }, + "import-fresh": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.0.0.tgz", + "integrity": "sha512-pOnA9tfM3Uwics+SaBLCNyZZZbK+4PTu0OPZtLlMIrv17EdBoC15S9Kn8ckJ9TZTyKb3ywNE5y1yeDxxGA7nTQ==", + "dev": true, + "requires": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + } + }, + "imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", + "dev": true + }, "inflight": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", @@ -1278,6 +1825,44 @@ "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", "dev": true }, + "inquirer": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-6.3.1.tgz", + "integrity": "sha512-MmL624rfkFt4TG9y/Jvmt8vdmOo836U7Y0Hxr2aFk3RelZEGX4Igk0KabWrcaaZaTv9uzglOqWh1Vly+FAWAXA==", + "dev": true, + "requires": { + "ansi-escapes": "^3.2.0", + "chalk": "^2.4.2", + "cli-cursor": "^2.1.0", + "cli-width": "^2.0.0", + "external-editor": "^3.0.3", + "figures": "^2.0.0", + "lodash": "^4.17.11", + "mute-stream": "0.0.7", + "run-async": "^2.2.0", + "rxjs": "^6.4.0", + "string-width": "^2.1.0", + "strip-ansi": "^5.1.0", + "through": "^2.3.6" + }, + "dependencies": { + "ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "dev": true + }, + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, + "requires": { + "ansi-regex": "^4.1.0" + } + } + } + }, "invert-kv": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-2.0.0.tgz", @@ -1314,6 +1899,12 @@ "builtin-modules": "^1.0.0" } }, + "is-callable": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.4.tgz", + "integrity": "sha512-r5p9sxJjYnArLjObpjA4xu5EKI3CuKHkJXMhT7kwbpUyIFD1n5PMAsoPvWnvtZiNz7LjkYDRZhd7FlI0eMijEA==", + "dev": true + }, "is-data-descriptor": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", @@ -1323,6 +1914,12 @@ "kind-of": "^3.0.2" } }, + "is-date-object": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.1.tgz", + "integrity": "sha1-mqIOtq7rv/d/vTPnTKAbM1gdOhY=", + "dev": true + }, "is-descriptor": { "version": "0.1.6", "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", @@ -1377,6 +1974,12 @@ } } }, + "is-promise": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.1.0.tgz", + "integrity": "sha1-eaKp7OfwlugPNtKy87wWwf9L8/o=", + "dev": true + }, "is-reference": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/is-reference/-/is-reference-1.1.1.tgz", @@ -1386,12 +1989,30 @@ "@types/estree": "0.0.39" } }, + "is-regex": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.4.tgz", + "integrity": "sha1-VRdIm1RwkbCTDglWVM7SXul+lJE=", + "dev": true, + "requires": { + "has": "^1.0.1" + } + }, "is-stream": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=", "dev": true }, + "is-symbol": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.2.tgz", + "integrity": "sha512-HS8bZ9ox60yCJLH9snBpIwv9pYUAkcuLhSA1oero1UB5y9aiQpRA8y2ex945AOtCZL1lJDeIk3G5LthswI46Lw==", + "dev": true, + "requires": { + "has-symbols": "^1.0.0" + } + }, "is-typedarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", @@ -1448,6 +2069,12 @@ "handlebars": "^4.0.11" } }, + "js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true + }, "js-yaml": { "version": "3.13.1", "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", @@ -1515,6 +2142,12 @@ "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", "dev": true }, + "json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", + "dev": true + }, "json-stringify-safe": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", @@ -1573,12 +2206,34 @@ "integrity": "sha1-HADHQ7QzzQpOgHWPe2SldEDZ/wA=", "dev": true }, + "load-json-file": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-2.0.0.tgz", + "integrity": "sha1-eUfkIUmvgNaWy/eXvKq8/h/inKg=", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "parse-json": "^2.2.0", + "pify": "^2.0.0", + "strip-bom": "^3.0.0" + } + }, "locate-character": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/locate-character/-/locate-character-2.0.5.tgz", "integrity": "sha512-n2GmejDXtOPBAZdIiEFy5dJ5N38xBCXLNOtw2WpB9kGh6pnrEuKlwYI+Tkpofc4wDtVXHtoAOJaMRlYG/oYaxg==", "dev": true }, + "locate-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", + "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", + "dev": true, + "requires": { + "p-locate": "^2.0.0", + "path-exists": "^3.0.0" + } + }, "lodash": { "version": "4.17.11", "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.11.tgz", @@ -1591,6 +2246,12 @@ "integrity": "sha1-7dFMgk4sycHgsKG0K7UhBRakJDg=", "dev": true }, + "lodash.unescape": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/lodash.unescape/-/lodash.unescape-4.0.1.tgz", + "integrity": "sha1-vyJJiGzlFM2hEvrpIYzcBlIR/Jw=", + "dev": true + }, "lru-cache": { "version": "4.1.5", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz", @@ -1811,6 +2472,12 @@ "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", "dev": true }, + "mute-stream": { + "version": "0.0.7", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.7.tgz", + "integrity": "sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s=", + "dev": true + }, "mz": { "version": "2.7.0", "resolved": "https://registry.npmjs.org/mz/-/mz-2.7.0.tgz", @@ -1861,6 +2528,12 @@ } } }, + "natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", + "dev": true + }, "neo-async": { "version": "2.6.1", "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.1.tgz", @@ -1946,6 +2619,12 @@ } } }, + "object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "dev": true + }, "object-visit": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz", @@ -1989,6 +2668,15 @@ "wrappy": "1" } }, + "onetime": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz", + "integrity": "sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ=", + "dev": true, + "requires": { + "mimic-fn": "^1.0.0" + } + }, "optimist": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/optimist/-/optimist-0.6.1.tgz", @@ -2032,6 +2720,12 @@ "mem": "^4.0.0" } }, + "os-tmpdir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", + "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", + "dev": true + }, "p-defer": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/p-defer/-/p-defer-1.0.0.tgz", @@ -2050,6 +2744,48 @@ "integrity": "sha1-nJRWmJ6fZYgBewQ01WCXZ1w9oF4=", "dev": true }, + "p-limit": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", + "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", + "dev": true, + "requires": { + "p-try": "^1.0.0" + } + }, + "p-locate": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", + "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", + "dev": true, + "requires": { + "p-limit": "^1.1.0" + } + }, + "p-try": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", + "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", + "dev": true + }, + "parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "dev": true, + "requires": { + "callsites": "^3.0.0" + } + }, + "parse-json": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", + "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", + "dev": true, + "requires": { + "error-ex": "^1.2.0" + } + }, "parse5": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/parse5/-/parse5-5.1.0.tgz", @@ -2074,6 +2810,12 @@ "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", "dev": true }, + "path-is-inside": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", + "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=", + "dev": true + }, "path-key": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", @@ -2086,6 +2828,15 @@ "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==", "dev": true }, + "path-type": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-2.0.0.tgz", + "integrity": "sha1-8BLMuEFbcJb8LaoQVMPXI4lZTHM=", + "dev": true, + "requires": { + "pify": "^2.0.0" + } + }, "pend": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", @@ -2098,6 +2849,12 @@ "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=", "dev": true }, + "pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "dev": true + }, "pirates": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.0.tgz", @@ -2107,6 +2864,15 @@ "node-modules-regexp": "^1.0.0" } }, + "pkg-dir": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-2.0.0.tgz", + "integrity": "sha1-9tXREJ4Z1j7fQo4L1X4Sd3YVM0s=", + "dev": true, + "requires": { + "find-up": "^2.1.0" + } + }, "pn": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/pn/-/pn-1.1.0.tgz", @@ -2193,6 +2959,27 @@ "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==", "dev": true }, + "read-pkg": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-2.0.0.tgz", + "integrity": "sha1-jvHAYjxqbbDcZxPEv6xGMysjaPg=", + "dev": true, + "requires": { + "load-json-file": "^2.0.0", + "normalize-package-data": "^2.3.2", + "path-type": "^2.0.0" + } + }, + "read-pkg-up": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-2.0.0.tgz", + "integrity": "sha1-a3KoBImE4MQeeVEP1en6mbO1Sb4=", + "dev": true, + "requires": { + "find-up": "^2.0.0", + "read-pkg": "^2.0.0" + } + }, "regex-not": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz", @@ -2203,6 +2990,12 @@ "safe-regex": "^1.1.0" } }, + "regexpp": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-2.0.1.tgz", + "integrity": "sha512-lv0M6+TkDVniA3aD1Eg0DVpfU/booSu7Eev3TDO/mZKHBfVjgCGTV4t4buppESEYDtkArYFOxTJWv6S5C+iaNw==", + "dev": true + }, "repeat-element": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.3.tgz", @@ -2275,6 +3068,12 @@ "integrity": "sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE=", "dev": true }, + "requireindex": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/requireindex/-/requireindex-1.2.0.tgz", + "integrity": "sha512-L9jEkOi3ASd9PYit2cwRfyppc9NoABujTP8/5gFcbERmo5jUoAKovIC3fsF17pkTnGsrByysqX+Kxd2OTNI1ww==", + "dev": true + }, "resolve": { "version": "1.10.0", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.10.0.tgz", @@ -2284,12 +3083,28 @@ "path-parse": "^1.0.6" } }, + "resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true + }, "resolve-url": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=", "dev": true }, + "restore-cursor": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz", + "integrity": "sha1-n37ih/gv0ybU/RYpI9YhKe7g368=", + "dev": true, + "requires": { + "onetime": "^2.0.0", + "signal-exit": "^3.0.2" + } + }, "ret": { "version": "0.1.15", "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz", @@ -2702,6 +3517,24 @@ } } }, + "run-async": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.3.0.tgz", + "integrity": "sha1-A3GrSuC91yDUFm19/aZP96RFpsA=", + "dev": true, + "requires": { + "is-promise": "^2.1.0" + } + }, + "rxjs": { + "version": "6.5.2", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.5.2.tgz", + "integrity": "sha512-HUb7j3kvb7p7eCUHE3FqjoDsC1xfZQ4AHFWfTKSpZ+sAhhz5X1WX0ZuUqWbzB2QhSLp3DoLUG+hMdEDKqWo2Zg==", + "dev": true, + "requires": { + "tslib": "^1.9.0" + } + }, "safe-buffer": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", @@ -2788,6 +3621,17 @@ "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=", "dev": true }, + "slice-ansi": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-2.1.0.tgz", + "integrity": "sha512-Qu+VC3EwYLldKa1fCxuuvULvSJOKEgk9pi8dZeCVK7TqBfUNTH4sFkk4joj8afVSfAYgJoSOetjx9QWOJ5mYoQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.0", + "astral-regex": "^1.0.0", + "is-fullwidth-code-point": "^2.0.0" + } + }, "snapdragon": { "version": "0.8.2", "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz", @@ -3080,6 +3924,12 @@ "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=", "dev": true }, + "strip-json-comments": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", + "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", + "dev": true + }, "sucrase": { "version": "3.9.5", "resolved": "https://registry.npmjs.org/sucrase/-/sucrase-3.9.5.tgz", @@ -3115,6 +3965,58 @@ "integrity": "sha1-rifbOPZgp64uHDt9G8KQgZuFGeY=", "dev": true }, + "table": { + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/table/-/table-5.4.0.tgz", + "integrity": "sha512-nHFDrxmbrkU7JAFKqKbDJXfzrX2UBsWmrieXFTGxiI5e4ncg3VqsZeI4EzNmX0ncp4XNGVeoxIWJXfCIXwrsvw==", + "dev": true, + "requires": { + "ajv": "^6.9.1", + "lodash": "^4.17.11", + "slice-ansi": "^2.1.0", + "string-width": "^3.0.0" + }, + "dependencies": { + "ajv": { + "version": "6.10.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.10.0.tgz", + "integrity": "sha512-nffhOpkymDECQyR0mnsUtoCE8RlX38G0rYP+wgLWFyZuUyuuojSSvi/+euOiQBIn63whYwYVIIH1TvE3tu4OEg==", + "dev": true, + "requires": { + "fast-deep-equal": "^2.0.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + }, + "ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "dev": true + }, + "string-width": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", + "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "dev": true, + "requires": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + } + }, + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, + "requires": { + "ansi-regex": "^4.1.0" + } + } + } + }, "test-exclude": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-5.0.0.tgz", @@ -3230,6 +4132,12 @@ } } }, + "text-table": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", + "dev": true + }, "thenify": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.0.tgz", @@ -3248,6 +4156,12 @@ "thenify": ">= 3.1.0 < 4" } }, + "through": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=", + "dev": true + }, "tiny-glob": { "version": "0.2.6", "resolved": "https://registry.npmjs.org/tiny-glob/-/tiny-glob-0.2.6.tgz", @@ -3258,6 +4172,15 @@ "globrex": "^0.1.1" } }, + "tmp": { + "version": "0.0.33", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", + "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", + "dev": true, + "requires": { + "os-tmpdir": "~1.0.2" + } + }, "to-object-path": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz", @@ -3346,6 +4269,15 @@ "integrity": "sha512-4krF8scpejhaOgqzBEcGM7yDIEfi0/8+8zDRZhNZZ2kjmHJ4hv3zCbQWxoJGz1iw5U0Jl0nma13xzHXcncMavQ==", "dev": true }, + "tsutils": { + "version": "3.14.0", + "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.14.0.tgz", + "integrity": "sha512-SmzGbB0l+8I0QwsPgjooFRaRvHLBLNYM8SeQ0k6rtNDru5sCGeLJcZdwilNndN+GysuFjF5EIYgN8GfFG6UeUw==", + "dev": true, + "requires": { + "tslib": "^1.8.1" + } + }, "tunnel-agent": { "version": "0.6.0", "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", @@ -3664,6 +4596,15 @@ "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", "dev": true }, + "write": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/write/-/write-1.0.3.tgz", + "integrity": "sha512-/lg70HAjtkUgWPVZhZcm+T4hkL8Zbtp1nFNOn3lRrxnlv50SRBv7cR7RqR+GMsd3hUXy9hWBo4CHTbFTcOYwig==", + "dev": true, + "requires": { + "mkdirp": "^0.5.1" + } + }, "ws": { "version": "6.1.3", "resolved": "https://registry.npmjs.org/ws/-/ws-6.1.3.tgz", diff --git a/package.json b/package.json index d45b37724f..5004c27cfb 100644 --- a/package.json +++ b/package.json @@ -38,7 +38,8 @@ "prepublishOnly": "export PUBLISH=true && npm test && npm run create-stubs", "create-stubs": "node scripts/create-stubs.js", "tsd": "tsc -p . --emitDeclarationOnly", - "typecheck": "tsc -p . --noEmit" + "typecheck": "tsc -p . --noEmit", + "lint": "eslint \"{src,test}/**/*.{ts,js}\"" }, "repository": { "type": "git", @@ -60,12 +61,16 @@ "@sveltejs/svelte-repl": "0.0.5", "@types/mocha": "^5.2.0", "@types/node": "^10.5.5", + "@typescript-eslint/eslint-plugin": "^1.9.0", + "@typescript-eslint/parser": "^1.9.0", "acorn": "^6.1.1", "acorn-dynamic-import": "^4.0.0", "agadoo": "^1.0.1", "c8": "^3.4.0", "codecov": "^3.0.0", "css-tree": "1.0.0-alpha22", + "eslint": "^5.16.0", + "eslint-plugin-import": "^2.17.3", "estree-walker": "^0.6.1", "is-reference": "^1.1.1", "jsdom": "^12.2.0", diff --git a/src/compiler/Stats.ts b/src/compiler/Stats.ts index c54f1e8ea9..200fa448e9 100644 --- a/src/compiler/Stats.ts +++ b/src/compiler/Stats.ts @@ -5,7 +5,7 @@ const now = (typeof process !== 'undefined' && process.hrtime) } : () => self.performance.now(); -type Timing = { +interface Timing { label: string; start: number; end: number; diff --git a/src/compiler/compile/Component.ts b/src/compiler/compile/Component.ts index e5f3501716..89c1e6b4f6 100644 --- a/src/compiler/compile/Component.ts +++ b/src/compiler/compile/Component.ts @@ -24,13 +24,13 @@ import unwrap_parens from './utils/unwrap_parens'; import Slot from './nodes/Slot'; import { Node as ESTreeNode } from 'estree'; -type ComponentOptions = { +interface ComponentOptions { namespace?: string; tag?: string; immutable?: boolean; accessors?: boolean; preserveWhitespace?: boolean; -}; +} // We need to tell estree-walker that it should always // look for an `else` block, otherwise it might get @@ -97,7 +97,7 @@ export default class Component { node_for_declaration: Map = new Map(); partly_hoisted: string[] = []; fully_hoisted: string[] = []; - reactive_declarations: Array<{ assignees: Set, dependencies: Set, node: Node, declaration: Node }> = []; + reactive_declarations: Array<{ assignees: Set; dependencies: Set; node: Node; declaration: Node }> = []; reactive_declaration_nodes: Set = new Set(); has_reactive_assignments = false; injected_reactive_declaration_vars: Set = new Set(); @@ -106,12 +106,12 @@ export default class Component { indirect_dependencies: Map> = new Map(); file: string; - locate: (c: number) => { line: number, column: number }; + locate: (c: number) => { line: number; column: number }; // TODO this does the same as component.locate! remove one or the other locator: (search: number, startIndex?: number) => { - line: number, - column: number + line: number; + column: number; }; stylesheet: Stylesheet; @@ -140,6 +140,7 @@ export default class Component { this.compile_options = compile_options; this.file = compile_options.filename && ( + // eslint-disable-next-line no-useless-escape typeof process !== 'undefined' ? compile_options.filename.replace(process.cwd(), '').replace(/^[\/\\]/, '') : compile_options.filename ); this.locate = getLocator(this.source); @@ -248,7 +249,7 @@ export default class Component { result = result .replace(/__svelte:self__/g, this.name) - .replace(compile_options.generate === 'ssr' ? /(@+|#+)(\w*(?:-\w*)?)/g : /(@+)(\w*(?:-\w*)?)/g, (match: string, sigil: string, name: string) => { + .replace(compile_options.generate === 'ssr' ? /(@+|#+)(\w*(?:-\w*)?)/g : /(@+)(\w*(?:-\w*)?)/g, (_match: string, sigil: string, name: string) => { if (sigil === '@') { if (internal_exports.has(name)) { if (compile_options.dev && internal_exports.has(`${name}Dev`)) name = `${name}Dev`; @@ -379,7 +380,7 @@ export default class Component { reserved.forEach(add); internal_exports.forEach(add); - this.var_lookup.forEach((value, key) => add(key)); + this.var_lookup.forEach((_value, key) => add(key)); return (name: string) => { if (test) name = `${name}$`; @@ -398,12 +399,12 @@ export default class Component { error( pos: { - start: number, - end: number + start: number; + end: number; }, - e : { - code: string, - message: string + e: { + code: string; + message: string; } ) { error(e.message, { @@ -418,12 +419,12 @@ export default class Component { warn( pos: { - start: number, - end: number + start: number; + end: number; }, warning: { - code: string, - message: string + code: string; + message: string; } ) { if (!this.locator) { @@ -527,7 +528,7 @@ export default class Component { let result = ''; - script.content.body.forEach((node, i) => { + script.content.body.forEach((node) => { if (this.hoistable_nodes.has(node) || this.reactive_declaration_nodes.has(node)) { if (a !== b) result += `[✂${a}-${b}✂]`; a = node.end; @@ -564,7 +565,7 @@ export default class Component { this.add_sourcemap_locations(script.content); - let { scope, globals } = create_scopes(script.content); + const { scope, globals } = create_scopes(script.content); this.module_scope = scope; scope.declarations.forEach((node, name) => { @@ -588,7 +589,7 @@ export default class Component { this.error(node, { code: 'illegal-subscription', message: `Cannot reference store value inside + + \ No newline at end of file diff --git a/test/validator/samples/component-event-modifiers-invalid/errors.json b/test/validator/samples/component-event-modifiers-invalid/errors.json new file mode 100644 index 0000000000..da608063fe --- /dev/null +++ b/test/validator/samples/component-event-modifiers-invalid/errors.json @@ -0,0 +1,15 @@ +[{ + "message": "Event modifiers other than 'once' can only be used on DOM elements", + "code": "invalid-event-modifier", + "start": { + "line": 6, + "column": 8, + "character": 93 + }, + "end": { + "line": 6, + "column": 40, + "character": 125 + }, + "pos": 93 +}] diff --git a/test/validator/samples/component-event-modifiers-invalid/input.svelte b/test/validator/samples/component-event-modifiers-invalid/input.svelte new file mode 100644 index 0000000000..8f7ce54d7a --- /dev/null +++ b/test/validator/samples/component-event-modifiers-invalid/input.svelte @@ -0,0 +1,6 @@ + + + \ No newline at end of file From a43bcfdccd19667d0d1c2d4f4c8d10a4176fca15 Mon Sep 17 00:00:00 2001 From: Richard Harris Date: Sun, 9 Jun 2019 17:34:57 -0400 Subject: [PATCH 19/49] move tsd to npm run build --- package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index 5004c27cfb..ee6d1757a5 100644 --- a/package.json +++ b/package.json @@ -30,8 +30,8 @@ "coverage": "c8 report --reporter=text-lcov > coverage.lcov && c8 report --reporter=html", "codecov": "codecov", "precodecov": "npm run coverage", - "build": "rollup -c", - "prepare": "npm run build && npm run tsd", + "build": "rollup -c && npm run tsd", + "prepare": "npm run build", "dev": "rollup -cw", "pretest": "npm run build", "posttest": "agadoo internal/index.mjs", From 658290546a546c751cf4cb3b282647c75b57c13a Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Sun, 9 Jun 2019 17:35:36 -0400 Subject: [PATCH 20/49] allow empty tags - fixes #2980 (#2988) --- src/compiler/compile/render-dom/wrappers/Title.ts | 5 ++++- test/runtime/samples/head-title-empty/_config.js | 5 +++++ test/runtime/samples/head-title-empty/main.svelte | 3 +++ 3 files changed, 12 insertions(+), 1 deletion(-) create mode 100644 test/runtime/samples/head-title-empty/_config.js create mode 100644 test/runtime/samples/head-title-empty/main.svelte diff --git a/src/compiler/compile/render-dom/wrappers/Title.ts b/src/compiler/compile/render-dom/wrappers/Title.ts index 75dbc44202..456a833a8f 100644 --- a/src/compiler/compile/render-dom/wrappers/Title.ts +++ b/src/compiler/compile/render-dom/wrappers/Title.ts @@ -91,7 +91,10 @@ export default class TitleWrapper extends Wrapper { ); } } else { - const value = stringify((this.node.children[0] as Text).data); + const value = this.node.children.length > 0 + ? stringify((this.node.children[0] as Text).data) + : '""'; + block.builders.hydrate.add_line(`document.title = ${value};`); } } diff --git a/test/runtime/samples/head-title-empty/_config.js b/test/runtime/samples/head-title-empty/_config.js new file mode 100644 index 0000000000..497855156c --- /dev/null +++ b/test/runtime/samples/head-title-empty/_config.js @@ -0,0 +1,5 @@ +export default { + test({ assert, window }) { + assert.equal(window.document.title, ''); + } +}; \ No newline at end of file diff --git a/test/runtime/samples/head-title-empty/main.svelte b/test/runtime/samples/head-title-empty/main.svelte new file mode 100644 index 0000000000..3f81715df5 --- /dev/null +++ b/test/runtime/samples/head-title-empty/main.svelte @@ -0,0 +1,3 @@ +<svelte:head> + <title> + \ No newline at end of file From 820cce8523c34ec576bbe6e81958598f3007761b Mon Sep 17 00:00:00 2001 From: Richard Harris Date: Sun, 9 Jun 2019 18:01:10 -0400 Subject: [PATCH 21/49] -> v3.5.0 --- CHANGELOG.md | 13 +++++++++++++ package.json | 2 +- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 766a1634e4..d82740b998 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,18 @@ # Svelte changelog +## 3.5.0 + +* Update package folder structure ([#2887](https://github.com/sveltejs/svelte/pull/2887)) +* Support `once` modifier on component events ([#2654](https://github.com/sveltejs/svelte/issues/2654)) +* Allow empty `` tags ([#2980](https://github.com/sveltejs/svelte/issues/2980)) +* Render textarea binding values inside element ([#2975](https://github.com/sveltejs/svelte/pull/2975)) +* Fix delayed animation glitch ([#2871](https://github.com/sveltejs/svelte/issues/2871)) +* Solve diamond dependencies problem with stores ([#2660](https://github.com/sveltejs/svelte/issues/2660)) +* Fix missing outros inside each blocks ([#2689](https://github.com/sveltejs/svelte/issues/2689)) +* Support animations without transitions ([#2908](https://github.com/sveltejs/svelte/issues/2908)) +* Add missing transition events ([#2912](https://github.com/sveltejs/svelte/pull/2912)) + + ## 3.4.4 * Publish type declaration files ([#2874](https://github.com/sveltejs/svelte/issues/2874)) diff --git a/package.json b/package.json index ee6d1757a5..2b1e920869 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "svelte", - "version": "3.4.4", + "version": "3.5.0", "description": "Cybernetically enhanced web apps", "module": "index.mjs", "main": "index", From 05c5132e007f723df9c052000485a1672cac7771 Mon Sep 17 00:00:00 2001 From: Conduitry <git@chor.date> Date: Sun, 9 Jun 2019 18:28:12 -0400 Subject: [PATCH 22/49] site: actually support new package structure in REPL --- 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 b4cbd4f13a..7b2f8929a4 100644 --- a/site/package-lock.json +++ b/site/package-lock.json @@ -1362,9 +1362,9 @@ } }, "@sveltejs/svelte-repl": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/@sveltejs/svelte-repl/-/svelte-repl-0.1.5.tgz", - "integrity": "sha512-gk7Ny/i19g3njob9lGGV5JzDed8eAaFphHidxquFGW5QgMCScEu+YgweBo+tRkRE0sJObFzMz3MjudH5o+KdIw==", + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/@sveltejs/svelte-repl/-/svelte-repl-0.1.6.tgz", + "integrity": "sha512-3BH30SlzdSQzs1qiLr+kNXw1u81e31RiBtYXJ5YMq0d64VBXKNbP6TYOLQuCN5Ibe86wnPhJUHyIesMWIjyS6w==", "dev": true, "requires": { "codemirror": "^5.45.0", diff --git a/site/package.json b/site/package.json index 3f7172b8a8..6689a926f6 100644 --- a/site/package.json +++ b/site/package.json @@ -39,7 +39,7 @@ "@babel/runtime": "^7.4.4", "@sindresorhus/slugify": "^0.9.1", "@sveltejs/site-kit": "^1.0.4", - "@sveltejs/svelte-repl": "^0.1.5", + "@sveltejs/svelte-repl": "^0.1.6", "degit": "^2.1.3", "dotenv": "^8.0.0", "eslint-plugin-svelte3": "^1.0.0", From 68b1aeff9d854266ab1f45968b384afa888e1221 Mon Sep 17 00:00:00 2001 From: mrkishi <mauriciokishi@gmail.com> Date: Sun, 9 Jun 2019 15:36:56 -0300 Subject: [PATCH 23/49] replicate travis' configuration onto appveyor's --- appveyor.yml | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/appveyor.yml b/appveyor.yml index 249f61abf4..23a3ac3505 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -9,12 +9,13 @@ init: environment: matrix: - # node.js + - nodejs_version: 8 - nodejs_version: 10 + - nodejs_version: 12 install: - - ps: Install-Product node $env:nodejs_version - - npm install + - ps: Update-NodeJsInstallation (Get-NodeJsLatestBuild $env:nodejs_version) + - npm ci || npm install build: off From d3634d32c13c1ee8c3b0c1e8510591e6381d1bed Mon Sep 17 00:00:00 2001 From: Richard Harris <richard.a.harris@gmail.com> Date: Sun, 9 Jun 2019 19:33:48 -0400 Subject: [PATCH 24/49] dont even know how to summarise this --- scripts/create-stubs.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/create-stubs.js b/scripts/create-stubs.js index 191b86cbfd..e69e3f5e20 100644 --- a/scripts/create-stubs.js +++ b/scripts/create-stubs.js @@ -4,7 +4,7 @@ fs.readdirSync('src/runtime') .filter(dir => fs.statSync(`src/runtime/${dir}`).isDirectory()) .forEach(dir => { fs.writeFileSync(`${dir}/package.json`, JSON.stringify({ - main: './index.js', + main: './index', module: './index.mjs' }, null, ' ')); From 8c42cf62579fb218af7662d010d4adcfeff12fcd Mon Sep 17 00:00:00 2001 From: Richard Harris <richard.a.harris@gmail.com> Date: Sun, 9 Jun 2019 19:51:57 -0400 Subject: [PATCH 25/49] -> v3.5.1 --- CHANGELOG.md | 4 ++++ package.json | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d82740b998..c1adaf0b76 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Svelte changelog +## 3.5.1 + +* Accommodate webpack idiosyncracies + ## 3.5.0 * Update package folder structure ([#2887](https://github.com/sveltejs/svelte/pull/2887)) diff --git a/package.json b/package.json index 2b1e920869..48f2c41d85 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "svelte", - "version": "3.5.0", + "version": "3.5.1", "description": "Cybernetically enhanced web apps", "module": "index.mjs", "main": "index", From 2046780a4880545541ca06d85b8bf6e0b023b014 Mon Sep 17 00:00:00 2001 From: Rich Harris <richard.a.harris@gmail.com> Date: Sun, 9 Jun 2019 20:36:53 -0400 Subject: [PATCH 26/49] =?UTF-8?q?Delete=20gitattributes=20=E2=80=94=20GitH?= =?UTF-8?q?ub=20now=20syntax=20highlights=20Svelte=20files=20automatically?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitattributes | 1 - 1 file changed, 1 deletion(-) delete mode 100644 .gitattributes diff --git a/.gitattributes b/.gitattributes deleted file mode 100644 index eb49e78156..0000000000 --- a/.gitattributes +++ /dev/null @@ -1 +0,0 @@ -*.svelte linguist-language=HTML From 181f60d4f80a8b894a150caad0efd4162d10ed0a Mon Sep 17 00:00:00 2001 From: Ilya Semenov <semenov@inetss.com> Date: Mon, 10 Jun 2019 17:53:10 +0700 Subject: [PATCH 27/49] Improve file name to component name conversion, fix #2843 --- src/compiler/compile/index.ts | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/src/compiler/compile/index.ts b/src/compiler/compile/index.ts index 3f4a3eeb32..896f235c61 100644 --- a/src/compiler/compile/index.ts +++ b/src/compiler/compile/index.ts @@ -60,17 +60,25 @@ function get_name(filename: string) { // eslint-disable-next-line no-useless-escape const parts = filename.split(/[\/\\]/); - if (parts.length > 1 && /^index\.\w+/.test(parts[parts.length - 1])) { - parts.pop(); + if (parts.length > 1) { + const index_match = parts[parts.length - 1].match(/^index(\.\w+)/); + if (index_match) { + parts.pop(); + parts[parts.length - 1] += index_match[1]; + } } const base = parts.pop() - .replace(/\..+/, "") + .replace(/\.[^.]+$/, "") .replace(/[^a-zA-Z_$0-9]+/g, '_') .replace(/^_/, '') .replace(/_$/, '') .replace(/^(\d)/, '_$1'); + if (!base) { + throw new Error(`Could not derive component name from file ${filename}`); + } + return base[0].toUpperCase() + base.slice(1); } From 632a30ffe0b321b02060bfc5bb86d018fa778211 Mon Sep 17 00:00:00 2001 From: Conduitry <git@chor.date> Date: Mon, 10 Jun 2019 07:05:24 -0400 Subject: [PATCH 28/49] site: bump deps --- site/package-lock.json | 24 ++++++++++++------------ site/package.json | 6 +++--- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/site/package-lock.json b/site/package-lock.json index 7b2f8929a4..34edfd33d9 100644 --- a/site/package-lock.json +++ b/site/package-lock.json @@ -1362,9 +1362,9 @@ } }, "@sveltejs/svelte-repl": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/@sveltejs/svelte-repl/-/svelte-repl-0.1.6.tgz", - "integrity": "sha512-3BH30SlzdSQzs1qiLr+kNXw1u81e31RiBtYXJ5YMq0d64VBXKNbP6TYOLQuCN5Ibe86wnPhJUHyIesMWIjyS6w==", + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/@sveltejs/svelte-repl/-/svelte-repl-0.1.7.tgz", + "integrity": "sha512-/023rff9mUtF+RqRbYUbMCwAMcvxkWc97Q8i+77G3LUVQSR44TR84lvdsnCHJwj1C+RhF/Npncd2GJSskRmgbQ==", "dev": true, "requires": { "codemirror": "^5.45.0", @@ -4204,9 +4204,9 @@ } }, "sapper": { - "version": "0.27.1", - "resolved": "https://registry.npmjs.org/sapper/-/sapper-0.27.1.tgz", - "integrity": "sha512-RH0K1uQ3zJ1IXvowxr2SuboGXV69q22KaPMhhoM5VNDv9fsUlVHtluZE8WTcGxckiO2L1xFfgM7v/aINkSZpcw==", + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/sapper/-/sapper-0.27.3.tgz", + "integrity": "sha512-JOSrQEw5bD3770edZ+gwdZxS/69sySl+0KuJyMiBQKRnb85cb55w/fBYg2SMhKDa/BlaXg14aL19OiBRpXGZLQ==", "dev": true, "requires": { "html-minifier": "^4.0.0", @@ -4671,9 +4671,9 @@ } }, "svelte": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/svelte/-/svelte-3.3.0.tgz", - "integrity": "sha512-iJYkIJDvAak1kizEYnE4b4eJ17D25fU0adW7GjDgO0klbjcAFlqtWEGFJa9kpJOlUtNLilcF09k4Y9TDmK/vjg==", + "version": "3.5.1", + "resolved": "https://registry.npmjs.org/svelte/-/svelte-3.5.1.tgz", + "integrity": "sha512-iMnuyteFGQ8Yl68G/DHTHY1sLwoAMya1eS0ZOHIm/dqn2etR8WEe8hUAoluLryde4Cft4gvMhtHV3NhE60nBmQ==", "dev": true }, "tar": { @@ -4802,9 +4802,9 @@ } }, "uglify-js": { - "version": "3.5.14", - "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.5.14.tgz", - "integrity": "sha512-dgyjIw8KFK6AyVl5vm2tEqPewv5TKGEiiVFLI1LbF+oHua/Njd8tZk3lIbF1AWU1rNdEg7scaceADb4zqCcWXg==", + "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", diff --git a/site/package.json b/site/package.json index 6689a926f6..c4ca323fea 100644 --- a/site/package.json +++ b/site/package.json @@ -39,7 +39,7 @@ "@babel/runtime": "^7.4.4", "@sindresorhus/slugify": "^0.9.1", "@sveltejs/site-kit": "^1.0.4", - "@sveltejs/svelte-repl": "^0.1.6", + "@sveltejs/svelte-repl": "^0.1.7", "degit": "^2.1.3", "dotenv": "^8.0.0", "eslint-plugin-svelte3": "^1.0.0", @@ -57,9 +57,9 @@ "rollup-plugin-replace": "^2.2.0", "rollup-plugin-svelte": "^5.0.3", "rollup-plugin-terser": "^4.0.4", - "sapper": "^0.27.1", + "sapper": "^0.27.3", "shelljs": "^0.8.3", - "svelte": "^3.0.0" + "svelte": "^3.5.1" }, "engines": { "node": ">=10.0.0" From 7e7d495d493513f7a1749c46e30efb4eb1924904 Mon Sep 17 00:00:00 2001 From: Conduitry <git@chor.date> Date: Mon, 10 Jun 2019 07:29:47 -0400 Subject: [PATCH 29/49] remove unneeded svelte-repl dep --- package-lock.json | 24 +----------------------- package.json | 1 - 2 files changed, 1 insertion(+), 24 deletions(-) diff --git a/package-lock.json b/package-lock.json index f1e8bf1d32..f65fcc07e5 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "svelte", - "version": "3.4.4", + "version": "3.5.1", "lockfileVersion": 1, "requires": true, "dependencies": { @@ -30,16 +30,6 @@ "integrity": "sha512-UdVB1rSL7H8TS8674fH02p5lRbhfIqQ18YKLxLKEnHFztHUH6bhMqjebMxgSTmWVrs5raS5JSLJIKKHFT4WfPg==", "dev": true }, - "@sveltejs/svelte-repl": { - "version": "0.0.5", - "resolved": "https://registry.npmjs.org/@sveltejs/svelte-repl/-/svelte-repl-0.0.5.tgz", - "integrity": "sha512-SKSX4xkqwH0XcUHQozwTNm3OCqatk66CXYZnqOW9Jf4E1B6opyQUb9f96KwAxh7ghZMbeePRv51oOWsw6n0Yww==", - "dev": true, - "requires": { - "codemirror": "^5.45.0", - "yootils": "0.0.15" - } - }, "@types/estree": { "version": "0.0.39", "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.39.tgz", @@ -650,12 +640,6 @@ "urlgrey": "^0.4.4" } }, - "codemirror": { - "version": "5.45.0", - "resolved": "https://registry.npmjs.org/codemirror/-/codemirror-5.45.0.tgz", - "integrity": "sha512-c19j644usCE8gQaXa0jqn2B/HN9MnB2u6qPIrrhrMkB+QAP42y8G4QnTwuwbVSoUS1jEl7JU9HZMGhCDL0nsAw==", - "dev": true - }, "collection-visit": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz", @@ -4750,12 +4734,6 @@ "resolved": "https://registry.npmjs.org/yn/-/yn-3.0.0.tgz", "integrity": "sha512-+Wo/p5VRfxUgBUGy2j/6KX2mj9AYJWOHuhMjMcbBFc3y54o9/4buK1ksBvuiK01C3kby8DH9lSmJdSxw+4G/2Q==", "dev": true - }, - "yootils": { - "version": "0.0.15", - "resolved": "https://registry.npmjs.org/yootils/-/yootils-0.0.15.tgz", - "integrity": "sha512-GvGLuJ7XHJPGEUQ52vh8fh+vPjfikuGcu7yBswfrsNsHqnAoytOVuSb69eM0j8wQIjMz0U3kY3YsfwMhJgfG9w==", - "dev": true } } } diff --git a/package.json b/package.json index 48f2c41d85..7106e60d69 100644 --- a/package.json +++ b/package.json @@ -58,7 +58,6 @@ }, "homepage": "https://github.com/sveltejs/svelte#README", "devDependencies": { - "@sveltejs/svelte-repl": "0.0.5", "@types/mocha": "^5.2.0", "@types/node": "^10.5.5", "@typescript-eslint/eslint-plugin": "^1.9.0", From 32107d81029089100901f92565a125cff7ab0e44 Mon Sep 17 00:00:00 2001 From: Conduitry <git@chor.date> Date: Mon, 10 Jun 2019 16:28:15 -0400 Subject: [PATCH 30/49] site: add FAQ link to nav --- site/src/routes/_layout.svelte | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/site/src/routes/_layout.svelte b/site/src/routes/_layout.svelte index 18c1d2a8b7..4adbb9b0dc 100644 --- a/site/src/routes/_layout.svelte +++ b/site/src/routes/_layout.svelte @@ -21,6 +21,7 @@ <NavItem segment="examples">Examples</NavItem> <NavItem segment="repl">REPL</NavItem> <NavItem segment="blog">Blog</NavItem> + <NavItem segment="faq">FAQ</NavItem> <NavItem external="https://sapper.svelte.dev">Sapper</NavItem> @@ -46,4 +47,4 @@ padding: var(--nav-h) 0 0 0; overflow-x: hidden; } -</style> \ No newline at end of file +</style> From 52b5e05ead9a1265129677be69bd9a3b4a8ba601 Mon Sep 17 00:00:00 2001 From: Jacob Wright <jacwright@gmail.com> Date: Mon, 10 Jun 2019 15:44:50 -0600 Subject: [PATCH 31/49] Fix 7 GUIs crud example for delete when filtered This example could delete the incorrect person when a filter was applied. Just an example, but the behavior was confusing when I played with it, so I thought it worth fixing. --- site/content/examples/19-7guis/05-7guis-crud/App.svelte | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/site/content/examples/19-7guis/05-7guis-crud/App.svelte b/site/content/examples/19-7guis/05-7guis-crud/App.svelte index a0d6ef7f3e..f55aeb0d83 100644 --- a/site/content/examples/19-7guis/05-7guis-crud/App.svelte +++ b/site/content/examples/19-7guis/05-7guis-crud/App.svelte @@ -43,10 +43,12 @@ } function remove() { - people = [...people.slice(0, i), ...people.slice(i + 1)]; + // Remove selected person from the source array (people), not the filtered array + const index = people.indexOf(selected); + people = [...people.slice(0, index), ...people.slice(index + 1)]; first = last = ''; - i = Math.min(i, people.length - 1); + i = Math.min(i, filteredPeople.length - 2); } function reset_inputs(person) { From 68e1f2830e9f4a2ca19ecbdf811d02e080e354b4 Mon Sep 17 00:00:00 2001 From: Conduitry <git@chor.date> Date: Thu, 13 Jun 2019 11:43:19 -0400 Subject: [PATCH 32/49] site: bump repl --- 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 34edfd33d9..0d85755c33 100644 --- a/site/package-lock.json +++ b/site/package-lock.json @@ -1362,9 +1362,9 @@ } }, "@sveltejs/svelte-repl": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/@sveltejs/svelte-repl/-/svelte-repl-0.1.7.tgz", - "integrity": "sha512-/023rff9mUtF+RqRbYUbMCwAMcvxkWc97Q8i+77G3LUVQSR44TR84lvdsnCHJwj1C+RhF/Npncd2GJSskRmgbQ==", + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/@sveltejs/svelte-repl/-/svelte-repl-0.1.8.tgz", + "integrity": "sha512-RSKsuiQE3DrdT7B7DNhd5DK+DkYGLT5m6Ugchxc8iN+5v/hfVTbeNb+KJtItXLpDxiYdbb0HIiQPEdy0M+HThw==", "dev": true, "requires": { "codemirror": "^5.45.0", diff --git a/site/package.json b/site/package.json index c4ca323fea..6e51a63491 100644 --- a/site/package.json +++ b/site/package.json @@ -39,7 +39,7 @@ "@babel/runtime": "^7.4.4", "@sindresorhus/slugify": "^0.9.1", "@sveltejs/site-kit": "^1.0.4", - "@sveltejs/svelte-repl": "^0.1.7", + "@sveltejs/svelte-repl": "^0.1.8", "degit": "^2.1.3", "dotenv": "^8.0.0", "eslint-plugin-svelte3": "^1.0.0", From 7b4af88ec6587aab0e27cce0da01015532165484 Mon Sep 17 00:00:00 2001 From: Conduitry <git@chor.date> Date: Thu, 13 Jun 2019 17:35:43 -0400 Subject: [PATCH 33/49] site: remove unused pkg scripts --- site/cypress/fixtures/example.json | 5 ----- site/cypress/integration/spec.js | 19 ------------------- site/cypress/plugins/index.js | 17 ----------------- site/cypress/support/commands.js | 25 ------------------------- site/cypress/support/index.js | 20 -------------------- site/package.json | 6 +----- 6 files changed, 1 insertion(+), 91 deletions(-) delete mode 100644 site/cypress/fixtures/example.json delete mode 100644 site/cypress/integration/spec.js delete mode 100644 site/cypress/plugins/index.js delete mode 100644 site/cypress/support/commands.js delete mode 100644 site/cypress/support/index.js diff --git a/site/cypress/fixtures/example.json b/site/cypress/fixtures/example.json deleted file mode 100644 index da18d9352a..0000000000 --- a/site/cypress/fixtures/example.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "name": "Using fixtures to represent data", - "email": "hello@cypress.io", - "body": "Fixtures are a great way to mock data for responses to routes" -} \ No newline at end of file diff --git a/site/cypress/integration/spec.js b/site/cypress/integration/spec.js deleted file mode 100644 index 9a7140ddae..0000000000 --- a/site/cypress/integration/spec.js +++ /dev/null @@ -1,19 +0,0 @@ -describe('Sapper template app', () => { - beforeEach(() => { - cy.visit('/') - }); - - it('has the correct <h1>', () => { - cy.contains('h1', 'Great success!') - }); - - it('navigates to /about', () => { - cy.get('nav a').contains('about').click(); - cy.url().should('include', '/about'); - }); - - it('navigates to /blog', () => { - cy.get('nav a').contains('blog').click(); - cy.url().should('include', '/blog'); - }); -}); \ No newline at end of file diff --git a/site/cypress/plugins/index.js b/site/cypress/plugins/index.js deleted file mode 100644 index fd170fba69..0000000000 --- a/site/cypress/plugins/index.js +++ /dev/null @@ -1,17 +0,0 @@ -// *********************************************************** -// This example plugins/index.js can be used to load plugins -// -// You can change the location of this file or turn off loading -// the plugins file with the 'pluginsFile' configuration option. -// -// You can read more here: -// https://on.cypress.io/plugins-guide -// *********************************************************** - -// This function is called when a project is opened or re-opened (e.g. due to -// the project's config changing) - -module.exports = (on, config) => { - // `on` is used to hook into various events Cypress emits - // `config` is the resolved Cypress config -} diff --git a/site/cypress/support/commands.js b/site/cypress/support/commands.js deleted file mode 100644 index c1f5a772e2..0000000000 --- a/site/cypress/support/commands.js +++ /dev/null @@ -1,25 +0,0 @@ -// *********************************************** -// This example commands.js shows you how to -// create various custom commands and overwrite -// existing commands. -// -// For more comprehensive examples of custom -// commands please read more here: -// https://on.cypress.io/custom-commands -// *********************************************** -// -// -// -- This is a parent command -- -// Cypress.Commands.add("login", (email, password) => { ... }) -// -// -// -- This is a child command -- -// Cypress.Commands.add("drag", { prevSubject: 'element'}, (subject, options) => { ... }) -// -// -// -- This is a dual command -- -// Cypress.Commands.add("dismiss", { prevSubject: 'optional'}, (subject, options) => { ... }) -// -// -// -- This is will overwrite an existing command -- -// Cypress.Commands.overwrite("visit", (originalFn, url, options) => { ... }) diff --git a/site/cypress/support/index.js b/site/cypress/support/index.js deleted file mode 100644 index d68db96df2..0000000000 --- a/site/cypress/support/index.js +++ /dev/null @@ -1,20 +0,0 @@ -// *********************************************************** -// This example support/index.js is processed and -// loaded automatically before your test files. -// -// This is a great place to put global configuration and -// behavior that modifies Cypress. -// -// You can change the location of this file or turn off -// automatically serving support files with the -// 'supportFile' configuration option. -// -// You can read more here: -// https://on.cypress.io/configuration -// *********************************************************** - -// Import commands.js using ES2015 syntax: -import './commands' - -// Alternatively you can use CommonJS syntax: -// require('./commands') diff --git a/site/package.json b/site/package.json index 6e51a63491..cd34daf987 100644 --- a/site/package.json +++ b/site/package.json @@ -7,13 +7,9 @@ "copy-workers": "rm -rf static/workers && cp -r node_modules/@sveltejs/svelte-repl/workers static", "migrate": "node-pg-migrate -r dotenv/config", "sapper": "npm run copy-workers && sapper build --legacy", - "update_shimport": "cp node_modules/shimport/index.js __sapper__/build/client/shimport@0.0.14.js", "update": "node scripts/update_template.js && node scripts/get-contributors.js", "start": "node __sapper__/build", - "cy:run": "cypress run", - "cy:open": "cypress open", - "test": "run-p --race dev cy:run", - "testsrc": "mocha -r esm test/**", + "test": "mocha -r esm test/**", "deploy": "make deploy" }, "dependencies": { From ac185052a5d33dbdfcda89903685e929535a2754 Mon Sep 17 00:00:00 2001 From: Jungle <devex.soft@gmail.com> Date: Tue, 11 Jun 2019 18:25:32 +0500 Subject: [PATCH 34/49] fix(create-stubs): Fix import '.d.ts' --- scripts/create-stubs.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/create-stubs.js b/scripts/create-stubs.js index e69e3f5e20..6b9c9e3f4b 100644 --- a/scripts/create-stubs.js +++ b/scripts/create-stubs.js @@ -8,5 +8,5 @@ fs.readdirSync('src/runtime') module: './index.mjs' }, null, ' ')); - fs.writeFileSync(`${dir}/index.d.ts`, `export * from '../types/runtime/${dir}/index.d.ts';`); - }); \ No newline at end of file + fs.writeFileSync(`${dir}/index.d.ts`, `export * from '../types/runtime/${dir}/index';`); + }); From be783c5c67a0c8c5b8a02cecca5589ff508fabfb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Efe=20K=C3=BC=C3=A7=C3=BCk?= <qintarp@gmail.com> Date: Sun, 16 Jun 2019 01:13:06 +0300 Subject: [PATCH 35/49] do not collapse whitespace containing nbsp (#3014) --- src/compiler/compile/nodes/Text.ts | 2 +- test/runtime/samples/nbsp-div/_config.js | 19 +++++++++++++++++++ test/runtime/samples/nbsp-div/main.svelte | 7 +++++++ 3 files changed, 27 insertions(+), 1 deletion(-) create mode 100644 test/runtime/samples/nbsp-div/_config.js create mode 100644 test/runtime/samples/nbsp-div/main.svelte diff --git a/src/compiler/compile/nodes/Text.ts b/src/compiler/compile/nodes/Text.ts index 7500f5ff30..a4514f56f2 100644 --- a/src/compiler/compile/nodes/Text.ts +++ b/src/compiler/compile/nodes/Text.ts @@ -12,7 +12,7 @@ export default class Text extends Node { super(component, parent, scope, info); this.data = info.data; - if (!component.component_options.preserveWhitespace && !/\S/.test(info.data)) { + if (!component.component_options.preserveWhitespace && !/[\S\u00A0]/.test(info.data)) { let node = parent; while (node) { if (node.type === 'Element' && node.name === 'pre') { diff --git a/test/runtime/samples/nbsp-div/_config.js b/test/runtime/samples/nbsp-div/_config.js new file mode 100644 index 0000000000..6026af2c90 --- /dev/null +++ b/test/runtime/samples/nbsp-div/_config.js @@ -0,0 +1,19 @@ +export default { + html: `<div> hello</div> + <div> hello  </div> + <div> hello   hello</div>`, + + test({ assert, component, target }) { + var divList = target.querySelectorAll('div') + assert.equal( divList[0].textContent.charCodeAt( 0 ), 160 ); + assert.equal( divList[1].textContent.charCodeAt( 0 ), 160 ); + assert.equal( divList[1].textContent.charCodeAt( 6 ), 160 ); + assert.equal( divList[1].textContent.charCodeAt( 7 ), 160 ); + assert.equal( divList[2].textContent.charCodeAt( 0 ), 160 ); + assert.equal( divList[2].textContent.charCodeAt( 6 ), 160 ); + assert.equal( divList[2].textContent.charCodeAt( 7 ), 32 );//normal space + assert.equal( divList[2].textContent.charCodeAt( 8 ), 160 ); + + + } +}; \ No newline at end of file diff --git a/test/runtime/samples/nbsp-div/main.svelte b/test/runtime/samples/nbsp-div/main.svelte new file mode 100644 index 0000000000..64557bfeb1 --- /dev/null +++ b/test/runtime/samples/nbsp-div/main.svelte @@ -0,0 +1,7 @@ +<script> + let name = 'hello'; +</script> + +<div> {name}</div> +<div> {name}  </div> +<div> {name}   {name}</div> \ No newline at end of file From acdcaa41bfde4fc1b74dca33e48a6e4d3895667d Mon Sep 17 00:00:00 2001 From: Johan <johman10@users.noreply.github.com> Date: Sun, 16 Jun 2019 11:14:39 +0200 Subject: [PATCH 36/49] ensure correct requestAnimationFrame context (#2933) --- src/runtime/internal/utils.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/runtime/internal/utils.ts b/src/runtime/internal/utils.ts index 152c0e79b0..097a7df74b 100644 --- a/src/runtime/internal/utils.ts +++ b/src/runtime/internal/utils.ts @@ -87,7 +87,7 @@ export function once(fn) { if (ran) return; ran = true; fn.call(this, ...args); - } + }; } const is_client = typeof window !== 'undefined'; @@ -96,7 +96,7 @@ export let now: () => number = is_client ? () => window.performance.now() : () => Date.now(); -export let raf = is_client ? requestAnimationFrame : noop; +export let raf = cb => requestAnimationFrame(cb); // used internally for testing export function set_now(fn) { From ea74bfec554a9fba50d5d5ab803f96bd63fe83ba Mon Sep 17 00:00:00 2001 From: Mikhail Korepanov <panyakor@gmail.com> Date: Sun, 16 Jun 2019 13:37:28 +0300 Subject: [PATCH 37/49] Allow whitespace after = in attributes (#3026) --- src/compiler/parse/state/tag.ts | 1 + .../attribute-with-whitespace/input.svelte | 1 + .../attribute-with-whitespace/output.json | 39 +++++++++++++++++++ 3 files changed, 41 insertions(+) create mode 100644 test/parser/samples/attribute-with-whitespace/input.svelte create mode 100644 test/parser/samples/attribute-with-whitespace/output.json diff --git a/src/compiler/parse/state/tag.ts b/src/compiler/parse/state/tag.ts index 2fb82b4d2e..907233fdc7 100644 --- a/src/compiler/parse/state/tag.ts +++ b/src/compiler/parse/state/tag.ts @@ -385,6 +385,7 @@ function read_attribute(parser: Parser, unique_names: Set<string>) { let value: any[] | true = true; if (parser.eat('=')) { + parser.allow_whitespace(); value = read_attribute_value(parser); end = parser.index; } else if (parser.match_regex(/["']/)) { diff --git a/test/parser/samples/attribute-with-whitespace/input.svelte b/test/parser/samples/attribute-with-whitespace/input.svelte new file mode 100644 index 0000000000..2743a89ed0 --- /dev/null +++ b/test/parser/samples/attribute-with-whitespace/input.svelte @@ -0,0 +1 @@ +<button on:click= {foo}>Click</button> diff --git a/test/parser/samples/attribute-with-whitespace/output.json b/test/parser/samples/attribute-with-whitespace/output.json new file mode 100644 index 0000000000..eab6054f2a --- /dev/null +++ b/test/parser/samples/attribute-with-whitespace/output.json @@ -0,0 +1,39 @@ +{ + "html": { + "start": 0, + "end": 38, + "type": "Fragment", + "children": [ + { + "start": 0, + "end": 38, + "type": "Element", + "name": "button", + "attributes": [ + { + "start": 8, + "end": 23, + "type": "EventHandler", + "name": "click", + "modifiers": [], + "expression": { + "type": "Identifier", + "start": 19, + "end": 22, + "name": "foo" + } + } + ], + "children": [ + { + "start": 24, + "end": 29, + "type": "Text", + "raw": "Click", + "data": "Click" + } + ] + } + ] + } +} From c24fc92d2fe6cb3cd3a391eb8713fac15ec7bb7b Mon Sep 17 00:00:00 2001 From: Conduitry <git@chor.date> Date: Sun, 16 Jun 2019 09:17:40 -0400 Subject: [PATCH 38/49] site: fix css-in-js blog embed --- .../99-embeds/20181225-blog-svelte-css-in-js/App.svelte | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/site/content/examples/99-embeds/20181225-blog-svelte-css-in-js/App.svelte b/site/content/examples/99-embeds/20181225-blog-svelte-css-in-js/App.svelte index c8487abefe..ccb1ad8834 100644 --- a/site/content/examples/99-embeds/20181225-blog-svelte-css-in-js/App.svelte +++ b/site/content/examples/99-embeds/20181225-blog-svelte-css-in-js/App.svelte @@ -1,6 +1,6 @@ <script> import { comicSans, link } from './styles.js'; - import Hero from './Hero.html'; + import Hero from './Hero.svelte'; </script> <Hero/> From 87d4ac55c9f892da4d0aa7c786cabde1b35e2403 Mon Sep 17 00:00:00 2001 From: Conduitry <git@chor.date> Date: Sun, 16 Jun 2019 09:38:55 -0400 Subject: [PATCH 39/49] site: fix css-in-js blog embed, pt II --- .../99-embeds/20181225-blog-svelte-css-in-js/styles.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/site/content/examples/99-embeds/20181225-blog-svelte-css-in-js/styles.js b/site/content/examples/99-embeds/20181225-blog-svelte-css-in-js/styles.js index faf91b13d4..c7e10606c5 100644 --- a/site/content/examples/99-embeds/20181225-blog-svelte-css-in-js/styles.js +++ b/site/content/examples/99-embeds/20181225-blog-svelte-css-in-js/styles.js @@ -1,4 +1,6 @@ -import { css } from 'emotion/dist/emotion.umd.min.js'; +import emotion from 'emotion/dist/emotion.umd.min.js'; + +const { css } = emotion; const brand = '#74D900'; @@ -30,4 +32,4 @@ export const link = css` text-decoration: none; background: ${brand}; } -`; \ No newline at end of file +`; From 52618594f439f7bf09b696dd9f1aff52dfe796e9 Mon Sep 17 00:00:00 2001 From: mrkishi <mauriciokishi@gmail.com> Date: Fri, 7 Jun 2019 22:23:48 -0300 Subject: [PATCH 40/49] fix .gitignore'd files --- .gitignore | 1 + compiler.d.ts | 1 - rollup.config.js | 2 ++ test/server-side-rendering/samples/styles-nested/_actual.css | 2 -- test/server-side-rendering/samples/styles/_actual.css | 1 - 5 files changed, 3 insertions(+), 4 deletions(-) delete mode 100644 compiler.d.ts delete mode 100644 test/server-side-rendering/samples/styles-nested/_actual.css delete mode 100644 test/server-side-rendering/samples/styles/_actual.css diff --git a/.gitignore b/.gitignore index 4d7bbc7ac3..923dd5901e 100644 --- a/.gitignore +++ b/.gitignore @@ -4,6 +4,7 @@ node_modules *.map /src/compiler/compile/internal-exports.ts +/compiler.d.ts /compiler.*js /index.*js /internal diff --git a/compiler.d.ts b/compiler.d.ts deleted file mode 100644 index e2a3820bc5..0000000000 --- a/compiler.d.ts +++ /dev/null @@ -1 +0,0 @@ -export * from './types/compiler'; diff --git a/rollup.config.js b/rollup.config.js index 8907ae4e6c..f21fa0bdea 100644 --- a/rollup.config.js +++ b/rollup.config.js @@ -20,6 +20,8 @@ const ts_plugin = is_publish const external = id => id.startsWith('svelte/'); +fs.writeFileSync(`./compiler.d.ts`, `export * from './types/compiler/index';`); + export default [ /* runtime */ { diff --git a/test/server-side-rendering/samples/styles-nested/_actual.css b/test/server-side-rendering/samples/styles-nested/_actual.css deleted file mode 100644 index 775ae8a91c..0000000000 --- a/test/server-side-rendering/samples/styles-nested/_actual.css +++ /dev/null @@ -1,2 +0,0 @@ -div.svelte-bzh57p{color:red} -div.svelte-4yw8vx{color:green} \ No newline at end of file diff --git a/test/server-side-rendering/samples/styles/_actual.css b/test/server-side-rendering/samples/styles/_actual.css deleted file mode 100644 index 2025c64f84..0000000000 --- a/test/server-side-rendering/samples/styles/_actual.css +++ /dev/null @@ -1 +0,0 @@ -div.svelte-bzh57p{color:red} \ No newline at end of file From 453b9ac2da17b5a7330f65821b1123f25591157d Mon Sep 17 00:00:00 2001 From: mrkishi <mauriciokishi@gmail.com> Date: Sun, 9 Jun 2019 17:35:44 -0300 Subject: [PATCH 41/49] fix `package.json` types field --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 7106e60d69..9e2d17bd49 100644 --- a/package.json +++ b/package.json @@ -21,7 +21,7 @@ "engines": { "node": ">= 8" }, - "types": "types/runtime", + "types": "types/runtime/index.d.ts", "scripts": { "test": "mocha --opts mocha.opts", "test:unit": "mocha --require sucrase/register --recursive ./**/__test__.ts", From b0604b52a3bf38e13f32a13f151956db10599176 Mon Sep 17 00:00:00 2001 From: mrkishi <mauriciokishi@gmail.com> Date: Thu, 13 Jun 2019 03:11:52 -0300 Subject: [PATCH 42/49] split typescript projects --- package.json | 3 +- src/compiler/compile/index.ts | 2 +- src/compiler/tsconfig.json | 11 ++++++ src/runtime/internal/animations.ts | 3 +- src/runtime/internal/environment.ts | 16 +++++++++ src/runtime/internal/index.ts | 1 + src/runtime/internal/loop.ts | 2 +- src/runtime/internal/style_manager.ts | 2 +- src/runtime/internal/transitions.ts | 3 +- src/runtime/internal/utils.ts | 17 ---------- src/runtime/tsconfig.json | 15 ++++++++ test/tsconfig.json | 10 ++++++ tsconfig.json | 49 +++++++++++++-------------- 13 files changed, 84 insertions(+), 50 deletions(-) create mode 100644 src/compiler/tsconfig.json create mode 100644 src/runtime/internal/environment.ts create mode 100644 src/runtime/tsconfig.json create mode 100644 test/tsconfig.json diff --git a/package.json b/package.json index 9e2d17bd49..5cfdf383de 100644 --- a/package.json +++ b/package.json @@ -37,8 +37,7 @@ "posttest": "agadoo internal/index.mjs", "prepublishOnly": "export PUBLISH=true && npm test && npm run create-stubs", "create-stubs": "node scripts/create-stubs.js", - "tsd": "tsc -p . --emitDeclarationOnly", - "typecheck": "tsc -p . --noEmit", + "tsd": "tsc -p src/compiler --emitDeclarationOnly && tsc -p src/runtime --emitDeclarationOnly", "lint": "eslint \"{src,test}/**/*.{ts,js}\"" }, "repository": { diff --git a/src/compiler/compile/index.ts b/src/compiler/compile/index.ts index 3f4a3eeb32..f75a4390ec 100644 --- a/src/compiler/compile/index.ts +++ b/src/compiler/compile/index.ts @@ -1,4 +1,4 @@ -import { assign } from '../../runtime/internal/index'; +import { assign } from '../../runtime/internal/utils'; import Stats from '../Stats'; import parse from '../parse/index'; import render_dom from './render-dom/index'; diff --git a/src/compiler/tsconfig.json b/src/compiler/tsconfig.json new file mode 100644 index 0000000000..c5939a0fdc --- /dev/null +++ b/src/compiler/tsconfig.json @@ -0,0 +1,11 @@ +{ + "extends": "../../tsconfig.json", + "include": ["."], + + "compilerOptions": { + "lib": ["es2017", "webworker"] + + // TODO: remove mocha types from the whole project + // "types": ["node", "estree"] + } +} diff --git a/src/runtime/internal/animations.ts b/src/runtime/internal/animations.ts index 77c86aff0e..6dc6a446f6 100644 --- a/src/runtime/internal/animations.ts +++ b/src/runtime/internal/animations.ts @@ -1,4 +1,5 @@ -import { identity as linear, noop, now } from './utils'; +import { identity as linear, noop } from './utils'; +import { now } from './environment'; import { loop } from './loop'; import { create_rule, delete_rule } from './style_manager'; import { AnimationConfig } from '../animate'; diff --git a/src/runtime/internal/environment.ts b/src/runtime/internal/environment.ts new file mode 100644 index 0000000000..a1d50b5521 --- /dev/null +++ b/src/runtime/internal/environment.ts @@ -0,0 +1,16 @@ +export const is_client = typeof window !== 'undefined'; + +export let now: () => number = is_client + ? () => window.performance.now() + : () => Date.now(); + +export let raf = cb => requestAnimationFrame(cb); + +// used internally for testing +export function set_now(fn) { + now = fn; +} + +export function set_raf(fn) { + raf = fn; +} diff --git a/src/runtime/internal/index.ts b/src/runtime/internal/index.ts index 6487f04525..d9d95541eb 100644 --- a/src/runtime/internal/index.ts +++ b/src/runtime/internal/index.ts @@ -1,6 +1,7 @@ export * from './animations'; export * from './await-block'; export * from './dom'; +export * from './environment'; export * from './keyed-each'; export * from './lifecycle'; export * from './loop'; diff --git a/src/runtime/internal/loop.ts b/src/runtime/internal/loop.ts index cc6161105d..c1a42aa724 100644 --- a/src/runtime/internal/loop.ts +++ b/src/runtime/internal/loop.ts @@ -1,4 +1,4 @@ -import { now, raf } from './utils'; +import { now, raf } from './environment'; export interface Task { abort(): void; promise: Promise<void> } diff --git a/src/runtime/internal/style_manager.ts b/src/runtime/internal/style_manager.ts index 2721200627..d9264e3c08 100644 --- a/src/runtime/internal/style_manager.ts +++ b/src/runtime/internal/style_manager.ts @@ -1,5 +1,5 @@ import { element } from './dom'; -import { raf } from './utils'; +import { raf } from './environment'; let stylesheet; let active = 0; diff --git a/src/runtime/internal/transitions.ts b/src/runtime/internal/transitions.ts index 5591ca1d51..80c76ffec5 100644 --- a/src/runtime/internal/transitions.ts +++ b/src/runtime/internal/transitions.ts @@ -1,4 +1,5 @@ -import { identity as linear, is_function, noop, now, run_all } from './utils'; +import { identity as linear, is_function, noop, run_all } from './utils'; +import { now } from "./environment"; import { loop } from './loop'; import { create_rule, delete_rule } from './style_manager'; import { custom_event } from './dom'; diff --git a/src/runtime/internal/utils.ts b/src/runtime/internal/utils.ts index 097a7df74b..08410ec33a 100644 --- a/src/runtime/internal/utils.ts +++ b/src/runtime/internal/utils.ts @@ -89,20 +89,3 @@ export function once(fn) { fn.call(this, ...args); }; } - -const is_client = typeof window !== 'undefined'; - -export let now: () => number = is_client - ? () => window.performance.now() - : () => Date.now(); - -export let raf = cb => requestAnimationFrame(cb); - -// used internally for testing -export function set_now(fn) { - now = fn; -} - -export function set_raf(fn) { - raf = fn; -} diff --git a/src/runtime/tsconfig.json b/src/runtime/tsconfig.json new file mode 100644 index 0000000000..f3b4691b41 --- /dev/null +++ b/src/runtime/tsconfig.json @@ -0,0 +1,15 @@ +{ + "extends": "../../tsconfig.json", + "include": ["."], + + "compilerOptions": { + "lib": ["es2015", "dom", "dom.iterable"], + "target": "es2015", + "types": [], + + "baseUrl": ".", + "paths": { + "svelte/*": ["*"] + } + } +} diff --git a/test/tsconfig.json b/test/tsconfig.json new file mode 100644 index 0000000000..82eaf0245e --- /dev/null +++ b/test/tsconfig.json @@ -0,0 +1,10 @@ +{ + "extends": "../tsconfig.json", + "include": ["."], + + "compilerOptions": { + "allowJs": true, + "checkJs": true, + "noEmit": true + } +} diff --git a/tsconfig.json b/tsconfig.json index 07bc24acaf..39476f3dd1 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,33 +1,30 @@ { + "include": [], + "compilerOptions": { - "target": "es2015", - "module": "es6", + "rootDir": "src", + + // target node v8+ (https://node.green/) + // the only missing feature is Array.prototype.values + "lib": ["es2017"], + "target": "es2017", + "declaration": true, "declarationDir": "types", - "noImplicitThis": true, - "noUnusedLocals": true, - "noUnusedParameters": true, + "noEmitOnError": true, - "lib": [ - "es5", - "es6", - "dom", - "es2015" - ], - "importHelpers": true, + "noErrorTruncation": true, + + // rollup takes care of these + "module": "esnext", "moduleResolution": "node", - "baseUrl": ".", - "paths": { - "svelte/internal": ["./src/runtime/internal/index"], - "svelte/easing": ["./src/runtime/easing/index"], - "svelte/motion": ["./src/runtime/motion/index"], - "svelte/store": ["./src/runtime/store/index"] - }, - "typeRoots": [ - "node_modules/@types" - ] - }, - "include": [ - "src/**/*" - ] + "resolveJsonModule": true, + "allowSyntheticDefaultImports": true, + + // TODO: error all the things + //"strict": true, + "noImplicitThis": true, + "noUnusedLocals": true, + "noUnusedParameters": true + } } From 457cdf6acf65bed70e65840a7df7a239c7ec1ff5 Mon Sep 17 00:00:00 2001 From: mrkishi <mauriciokishi@gmail.com> Date: Sun, 9 Jun 2019 19:50:46 -0300 Subject: [PATCH 43/49] create `package.json` stubs on build --- package.json | 3 +-- rollup.config.js | 20 +++++++++++++++----- scripts/create-stubs.js | 12 ------------ 3 files changed, 16 insertions(+), 19 deletions(-) delete mode 100644 scripts/create-stubs.js diff --git a/package.json b/package.json index 5cfdf383de..e0bbe252d4 100644 --- a/package.json +++ b/package.json @@ -35,8 +35,7 @@ "dev": "rollup -cw", "pretest": "npm run build", "posttest": "agadoo internal/index.mjs", - "prepublishOnly": "export PUBLISH=true && npm test && npm run create-stubs", - "create-stubs": "node scripts/create-stubs.js", + "prepublishOnly": "PUBLISH=true npm test", "tsd": "tsc -p src/compiler --emitDeclarationOnly && tsc -p src/runtime --emitDeclarationOnly", "lint": "eslint \"{src,test}/**/*.{ts,js}\"" }, diff --git a/rollup.config.js b/rollup.config.js index f21fa0bdea..fb329534a2 100644 --- a/rollup.config.js +++ b/rollup.config.js @@ -61,12 +61,22 @@ export default [ external, plugins: [ ts_plugin, - dir === 'internal' && { - generateBundle(options, bundle) { - const mod = bundle['index.mjs']; - if (mod) { - fs.writeFileSync('src/compiler/compile/internal-exports.ts', `// This file is automatically generated\nexport default new Set(${JSON.stringify(mod.exports)});`); + { + writeBundle(bundle) { + if (dir === 'internal') { + const mod = bundle['index.mjs']; + if (mod) { + fs.writeFileSync('src/compiler/compile/internal-exports.ts', `// This file is automatically generated\nexport default new Set(${JSON.stringify(mod.exports)});`); + } } + + fs.writeFileSync(`${dir}/package.json`, JSON.stringify({ + main: './index', + module: './index.mjs', + types: './index.d.ts' + }, null, ' ')); + + fs.writeFileSync(`${dir}/index.d.ts`, `export * from '../types/runtime/${dir}/index';`); } } ] diff --git a/scripts/create-stubs.js b/scripts/create-stubs.js deleted file mode 100644 index 6b9c9e3f4b..0000000000 --- a/scripts/create-stubs.js +++ /dev/null @@ -1,12 +0,0 @@ -const fs = require('fs'); - -fs.readdirSync('src/runtime') - .filter(dir => fs.statSync(`src/runtime/${dir}`).isDirectory()) - .forEach(dir => { - fs.writeFileSync(`${dir}/package.json`, JSON.stringify({ - main: './index', - module: './index.mjs' - }, null, ' ')); - - fs.writeFileSync(`${dir}/index.d.ts`, `export * from '../types/runtime/${dir}/index';`); - }); From e90feb11f946948d79fa970f67d07a992838e9ea Mon Sep 17 00:00:00 2001 From: mrkishi <mauriciokishi@gmail.com> Date: Sun, 9 Jun 2019 17:48:16 -0300 Subject: [PATCH 44/49] pin `@types/node` to v8 --- package-lock.json | 6 +++--- package.json | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/package-lock.json b/package-lock.json index f65fcc07e5..aea08689b1 100644 --- a/package-lock.json +++ b/package-lock.json @@ -49,9 +49,9 @@ "dev": true }, "@types/node": { - "version": "10.12.18", - "resolved": "https://registry.npmjs.org/@types/node/-/node-10.12.18.tgz", - "integrity": "sha512-fh+pAqt4xRzPfqA6eh3Z2y6fyZavRIumvjhaCL753+TVkGKGhpPeyrJG2JftD0T9q4GF00KjefsQ+PQNDdWQaQ==", + "version": "8.10.49", + "resolved": "https://registry.npmjs.org/@types/node/-/node-8.10.49.tgz", + "integrity": "sha512-YX30JVx0PvSmJ3Eqr74fYLGeBxD+C7vIL20ek+GGGLJeUbVYRUW3EzyAXpIRA0K8c8o0UWqR/GwEFYiFoz1T8w==", "dev": true }, "@typescript-eslint/eslint-plugin": { diff --git a/package.json b/package.json index e0bbe252d4..140b60c6c6 100644 --- a/package.json +++ b/package.json @@ -57,7 +57,7 @@ "homepage": "https://github.com/sveltejs/svelte#README", "devDependencies": { "@types/mocha": "^5.2.0", - "@types/node": "^10.5.5", + "@types/node": "=8", "@typescript-eslint/eslint-plugin": "^1.9.0", "@typescript-eslint/parser": "^1.9.0", "acorn": "^6.1.1", From 07f65c0e523e327201073fa090c3b1ebc451edb9 Mon Sep 17 00:00:00 2001 From: mrkishi <mauriciokishi@gmail.com> Date: Sun, 9 Jun 2019 19:31:44 -0300 Subject: [PATCH 45/49] remove unused `.flowconfig` --- .flowconfig | 9 --------- 1 file changed, 9 deletions(-) delete mode 100644 .flowconfig diff --git a/.flowconfig b/.flowconfig deleted file mode 100644 index c1961b7a6b..0000000000 --- a/.flowconfig +++ /dev/null @@ -1,9 +0,0 @@ -[ignore] -<PROJECT_ROOT>/types/.* - -[include] - -[libs] - -[options] -strip_root=true From d4db3ed936ae92d6cfd3f1cc6e05c612267436c3 Mon Sep 17 00:00:00 2001 From: mrkishi <mauriciokishi@gmail.com> Date: Sun, 9 Jun 2019 22:49:12 -0300 Subject: [PATCH 46/49] make eslint happy --- src/compiler/compile/nodes/Element.ts | 4 ++-- src/compiler/compile/render-ssr/handlers/Element.ts | 6 +++--- test/runtime/samples/contenteditable-html/_config.js | 6 +++--- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/compiler/compile/nodes/Element.ts b/src/compiler/compile/nodes/Element.ts index c37ea5020a..3e883200a7 100644 --- a/src/compiler/compile/nodes/Element.ts +++ b/src/compiler/compile/nodes/Element.ts @@ -610,7 +610,7 @@ export default class Element extends Node { } else if ( name === 'text' || name === 'html' - ){ + ) { const contenteditable = this.attributes.find( (attribute: Attribute) => attribute.name === 'contenteditable' ); @@ -626,7 +626,7 @@ export default class Element extends Node { message: `'contenteditable' attribute cannot be dynamic if element uses two-way binding` }); } - } else if (name !== 'this') { + } else if (name !== 'this') { component.error(binding, { code: `invalid-binding`, message: `'${binding.name}' is not a valid binding` diff --git a/src/compiler/compile/render-ssr/handlers/Element.ts b/src/compiler/compile/render-ssr/handlers/Element.ts index 681e0d4c7b..0fbb4d3410 100644 --- a/src/compiler/compile/render-ssr/handlers/Element.ts +++ b/src/compiler/compile/render-ssr/handlers/Element.ts @@ -151,12 +151,12 @@ export default function(node: Element, renderer: Renderer, options: RenderOption if (name === 'group') { // TODO server-render group bindings } else if (contenteditable && (name === 'text' || name === 'html')) { - const snippet = snip(expression) + const snippet = snip(expression); if (name == 'text') { - node_contents = '${@escape(' + snippet + ')}' + node_contents = '${@escape(' + snippet + ')}'; } else { // Do not escape HTML content - node_contents = '${' + snippet + '}' + node_contents = '${' + snippet + '}'; } } else if (binding.name === 'value' && node.name === 'textarea') { const snippet = snip(expression); diff --git a/test/runtime/samples/contenteditable-html/_config.js b/test/runtime/samples/contenteditable-html/_config.js index cd2a822655..013fa30f39 100644 --- a/test/runtime/samples/contenteditable-html/_config.js +++ b/test/runtime/samples/contenteditable-html/_config.js @@ -19,14 +19,14 @@ export default { el.innerHTML = 'every<span>body</span>'; - // No updates to data yet + // No updates to data yet assert.htmlEqual(target.innerHTML, ` <editor>every<span>body</span></editor> <p>hello <b>world</b></p> `); - // Handle user input - const event = new window.Event('input'); + // Handle user input + const event = new window.Event('input'); await el.dispatchEvent(event); assert.htmlEqual(target.innerHTML, ` <editor>every<span>body</span></editor> From 552ea4b9ed44fc587f056d0231adc6e84c2be638 Mon Sep 17 00:00:00 2001 From: Conduitry <git@chor.date> Date: Tue, 11 Jun 2019 20:41:46 -0400 Subject: [PATCH 47/49] only set attributes via properties when truly necessary (#1434) --- .../render-dom/wrappers/Element/Attribute.ts | 179 +----------------- 1 file changed, 8 insertions(+), 171 deletions(-) diff --git a/src/compiler/compile/render-dom/wrappers/Element/Attribute.ts b/src/compiler/compile/render-dom/wrappers/Element/Attribute.ts index 669a3774e3..f55e731fdb 100644 --- a/src/compiler/compile/render-dom/wrappers/Element/Attribute.ts +++ b/src/compiler/compile/render-dom/wrappers/Element/Attribute.ts @@ -224,79 +224,20 @@ export default class AttributeWrapper { } } -// source: https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes +// source: https://html.spec.whatwg.org/multipage/indices.html const attribute_lookup = { - accept: { applies_to: ['form', 'input'] }, - 'accept-charset': { property_name: 'acceptCharset', applies_to: ['form'] }, - accesskey: { property_name: 'accessKey' }, - action: { applies_to: ['form'] }, - align: { - applies_to: [ - 'applet', - 'caption', - 'col', - 'colgroup', - 'hr', - 'iframe', - 'img', - 'table', - 'tbody', - 'td', - 'tfoot', - 'th', - 'thead', - 'tr', - ], - }, allowfullscreen: { property_name: 'allowFullscreen', applies_to: ['iframe'] }, - alt: { applies_to: ['applet', 'area', 'img', 'input'] }, + allowpaymentrequest: { property_name: 'allowPaymentRequest', applies_to: ['iframe'] }, async: { applies_to: ['script'] }, - autocomplete: { applies_to: ['form', 'input'] }, autofocus: { applies_to: ['button', 'input', 'keygen', 'select', 'textarea'] }, autoplay: { applies_to: ['audio', 'video'] }, - autosave: { applies_to: ['input'] }, - bgcolor: { - property_name: 'bgColor', - applies_to: [ - 'body', - 'col', - 'colgroup', - 'marquee', - 'table', - 'tbody', - 'tfoot', - 'td', - 'th', - 'tr', - ], - }, - border: { applies_to: ['img', 'object', 'table'] }, - buffered: { applies_to: ['audio', 'video'] }, - challenge: { applies_to: ['keygen'] }, - charset: { applies_to: ['meta', 'script'] }, - checked: { applies_to: ['command', 'input'] }, - cite: { applies_to: ['blockquote', 'del', 'ins', 'q'] }, - class: { property_name: 'className' }, - code: { applies_to: ['applet'] }, - codebase: { property_name: 'codeBase', applies_to: ['applet'] }, - color: { applies_to: ['basefont', 'font', 'hr'] }, - cols: { applies_to: ['textarea'] }, - colspan: { property_name: 'colSpan', applies_to: ['td', 'th'] }, - content: { applies_to: ['meta'] }, - contenteditable: { property_name: 'contentEditable' }, - contextmenu: {}, + checked: { applies_to: ['input'] }, controls: { applies_to: ['audio', 'video'] }, - coords: { applies_to: ['area'] }, - data: { applies_to: ['object'] }, - datetime: { property_name: 'dateTime', applies_to: ['del', 'ins', 'time'] }, default: { applies_to: ['track'] }, defer: { applies_to: ['script'] }, - dir: {}, - dirname: { property_name: 'dirName', applies_to: ['input', 'textarea'] }, disabled: { applies_to: [ 'button', - 'command', 'fieldset', 'input', 'keygen', @@ -306,119 +247,21 @@ const attribute_lookup = { 'textarea', ], }, - download: { applies_to: ['a', 'area'] }, - draggable: {}, - dropzone: {}, - enctype: { applies_to: ['form'] }, - for: { property_name: 'htmlFor', applies_to: ['label', 'output'] }, - formaction: { applies_to: ['input', 'button'] }, - headers: { applies_to: ['td', 'th'] }, - height: { - applies_to: ['canvas', 'embed', 'iframe', 'img', 'input', 'object', 'video'], - }, + formnovalidate: { property_name: 'formNoValidate', applies_to: ['button', 'input'] }, hidden: {}, - high: { applies_to: ['meter'] }, - href: { applies_to: ['a', 'area', 'base', 'link'] }, - hreflang: { applies_to: ['a', 'area', 'link'] }, - 'http-equiv': { property_name: 'httpEquiv', applies_to: ['meta'] }, - icon: { applies_to: ['command'] }, - id: {}, indeterminate: { applies_to: ['input'] }, ismap: { property_name: 'isMap', applies_to: ['img'] }, - itemprop: {}, - keytype: { applies_to: ['keygen'] }, - kind: { applies_to: ['track'] }, - label: { applies_to: ['track'] }, - lang: {}, - language: { applies_to: ['script'] }, - loop: { applies_to: ['audio', 'bgsound', 'marquee', 'video'] }, - low: { applies_to: ['meter'] }, - manifest: { applies_to: ['html'] }, - max: { applies_to: ['input', 'meter', 'progress'] }, - maxlength: { property_name: 'maxLength', applies_to: ['input', 'textarea'] }, - media: { applies_to: ['a', 'area', 'link', 'source', 'style'] }, - method: { applies_to: ['form'] }, - min: { applies_to: ['input', 'meter'] }, + loop: { applies_to: ['audio', 'bgsound', 'video'] }, multiple: { applies_to: ['input', 'select'] }, muted: { applies_to: ['audio', 'video'] }, - name: { - applies_to: [ - 'button', - 'form', - 'fieldset', - 'iframe', - 'input', - 'keygen', - 'object', - 'output', - 'select', - 'textarea', - 'map', - 'meta', - 'param', - ], - }, + nomodule: { property_name: 'noModule', applies_to: ['script'] }, novalidate: { property_name: 'noValidate', applies_to: ['form'] }, - open: { applies_to: ['details'] }, - optimum: { applies_to: ['meter'] }, - pattern: { applies_to: ['input'] }, - ping: { applies_to: ['a', 'area'] }, - placeholder: { applies_to: ['input', 'textarea'] }, - poster: { applies_to: ['video'] }, - preload: { applies_to: ['audio', 'video'] }, - radiogroup: { applies_to: ['command'] }, + open: { applies_to: ['details', 'dialog'] }, + playsinline: { property_name: 'playsInline', applies_to: ['video'] }, readonly: { property_name: 'readOnly', applies_to: ['input', 'textarea'] }, - rel: { applies_to: ['a', 'area', 'link'] }, required: { applies_to: ['input', 'select', 'textarea'] }, reversed: { applies_to: ['ol'] }, - rows: { applies_to: ['textarea'] }, - rowspan: { property_name: 'rowSpan', applies_to: ['td', 'th'] }, - sandbox: { applies_to: ['iframe'] }, - scope: { applies_to: ['th'] }, - scoped: { applies_to: ['style'] }, - seamless: { applies_to: ['iframe'] }, selected: { applies_to: ['option'] }, - shape: { applies_to: ['a', 'area'] }, - size: { applies_to: ['input', 'select'] }, - sizes: { applies_to: ['link', 'img', 'source'] }, - span: { applies_to: ['col', 'colgroup'] }, - spellcheck: {}, - src: { - applies_to: [ - 'audio', - 'embed', - 'iframe', - 'img', - 'input', - 'script', - 'source', - 'track', - 'video', - ], - }, - srcdoc: { applies_to: ['iframe'] }, - srclang: { applies_to: ['track'] }, - srcset: { applies_to: ['img'] }, - start: { applies_to: ['ol'] }, - step: { applies_to: ['input'] }, - style: { property_name: 'style.cssText' }, - summary: { applies_to: ['table'] }, - tabindex: { property_name: 'tabIndex' }, - target: { applies_to: ['a', 'area', 'base', 'form'] }, - title: {}, - type: { - applies_to: [ - 'button', - 'command', - 'embed', - 'object', - 'script', - 'source', - 'style', - 'menu', - ], - }, - usemap: { property_name: 'useMap', applies_to: ['img', 'input', 'object'] }, value: { applies_to: [ 'button', @@ -432,12 +275,6 @@ const attribute_lookup = { 'textarea', ], }, - volume: { applies_to: ['audio', 'video'] }, - playbackRate: { applies_to: ['audio', 'video'] }, - width: { - applies_to: ['canvas', 'embed', 'iframe', 'img', 'input', 'object', 'video'], - }, - wrap: { applies_to: ['textarea'] }, }; Object.keys(attribute_lookup).forEach(name => { From a332b648e937d4776069489e7ca6ba9e7899d692 Mon Sep 17 00:00:00 2001 From: Conduitry <git@chor.date> Date: Tue, 11 Jun 2019 20:42:37 -0400 Subject: [PATCH 48/49] update tests (#1434) (#2935) --- test/js/samples/action/expected.js | 3 ++- .../samples/collapses-text-around-comments/expected.js | 3 ++- test/js/samples/css-media-query/expected.js | 3 ++- test/js/samples/each-block-changed-check/expected.js | 5 +++-- test/js/samples/event-handler-no-passive/expected.js | 3 ++- test/js/samples/head-no-whitespace/expected.js | 9 +++++---- test/js/samples/inline-style-unoptimized/expected.js | 9 +++++---- test/runtime/samples/contenteditable-html/_config.js | 8 ++++---- test/runtime/samples/contenteditable-text/_config.js | 6 +++--- test/runtime/samples/set-undefined-attr/_config.js | 4 ++-- test/runtime/samples/set-undefined-attr/main.svelte | 3 ++- 11 files changed, 32 insertions(+), 24 deletions(-) diff --git a/test/js/samples/action/expected.js b/test/js/samples/action/expected.js index cbbcb0d317..ed0a0a7430 100644 --- a/test/js/samples/action/expected.js +++ b/test/js/samples/action/expected.js @@ -1,6 +1,7 @@ /* generated by Svelte vX.Y.Z */ import { SvelteComponent, + attr, detach, element, init, @@ -16,7 +17,7 @@ function create_fragment(ctx) { c() { a = element("a"); a.textContent = "Test"; - a.href = "#"; + attr(a, "href", "#"); }, m(target, anchor) { diff --git a/test/js/samples/collapses-text-around-comments/expected.js b/test/js/samples/collapses-text-around-comments/expected.js index 12164d0579..09b40a1e98 100644 --- a/test/js/samples/collapses-text-around-comments/expected.js +++ b/test/js/samples/collapses-text-around-comments/expected.js @@ -2,6 +2,7 @@ import { SvelteComponent, append, + attr, detach, element, init, @@ -26,7 +27,7 @@ function create_fragment(ctx) { c() { p = element("p"); t = text(ctx.foo); - p.className = "svelte-1a7i8ec"; + attr(p, "class", "svelte-1a7i8ec"); }, m(target, anchor) { diff --git a/test/js/samples/css-media-query/expected.js b/test/js/samples/css-media-query/expected.js index d4be134376..82b7c5dfc8 100644 --- a/test/js/samples/css-media-query/expected.js +++ b/test/js/samples/css-media-query/expected.js @@ -2,6 +2,7 @@ import { SvelteComponent, append, + attr, detach, element, init, @@ -23,7 +24,7 @@ function create_fragment(ctx) { return { c() { div = element("div"); - div.className = "svelte-1slhpfn"; + attr(div, "class", "svelte-1slhpfn"); }, m(target, anchor) { diff --git a/test/js/samples/each-block-changed-check/expected.js b/test/js/samples/each-block-changed-check/expected.js index 951565bae4..b4d4577df3 100644 --- a/test/js/samples/each-block-changed-check/expected.js +++ b/test/js/samples/each-block-changed-check/expected.js @@ -2,6 +2,7 @@ import { SvelteComponent, append, + attr, destroy_each, detach, detach_after, @@ -39,8 +40,8 @@ function create_each_block(ctx) { t5 = text(" ago:"); t6 = space(); raw_before = element('noscript'); - span.className = "meta"; - div.className = "comment"; + attr(span, "class", "meta"); + attr(div, "class", "comment"); }, m(target, anchor) { diff --git a/test/js/samples/event-handler-no-passive/expected.js b/test/js/samples/event-handler-no-passive/expected.js index 41fcbeeb2a..e8ca72c556 100644 --- a/test/js/samples/event-handler-no-passive/expected.js +++ b/test/js/samples/event-handler-no-passive/expected.js @@ -1,6 +1,7 @@ /* generated by Svelte vX.Y.Z */ import { SvelteComponent, + attr, detach, element, init, @@ -17,7 +18,7 @@ function create_fragment(ctx) { c() { a = element("a"); a.textContent = "this should not navigate to example.com"; - a.href = "https://example.com"; + attr(a, "href", "https://example.com"); dispose = listen(a, "touchstart", touchstart_handler); }, diff --git a/test/js/samples/head-no-whitespace/expected.js b/test/js/samples/head-no-whitespace/expected.js index b95177bba7..457df77dc8 100644 --- a/test/js/samples/head-no-whitespace/expected.js +++ b/test/js/samples/head-no-whitespace/expected.js @@ -2,6 +2,7 @@ import { SvelteComponent, append, + attr, detach, element, init, @@ -16,10 +17,10 @@ function create_fragment(ctx) { c() { meta0 = element("meta"); meta1 = element("meta"); - meta0.name = "twitter:creator"; - meta0.content = "@sveltejs"; - meta1.name = "twitter:title"; - meta1.content = "Svelte"; + attr(meta0, "name", "twitter:creator"); + attr(meta0, "content", "@sveltejs"); + attr(meta1, "name", "twitter:title"); + attr(meta1, "content", "Svelte"); }, m(target, anchor) { diff --git a/test/js/samples/inline-style-unoptimized/expected.js b/test/js/samples/inline-style-unoptimized/expected.js index 8f3b668827..9349ade12c 100644 --- a/test/js/samples/inline-style-unoptimized/expected.js +++ b/test/js/samples/inline-style-unoptimized/expected.js @@ -1,6 +1,7 @@ /* generated by Svelte vX.Y.Z */ import { SvelteComponent, + attr, detach, element, init, @@ -18,8 +19,8 @@ function create_fragment(ctx) { div0 = element("div"); t = space(); div1 = element("div"); - div0.style.cssText = ctx.style; - div1.style.cssText = div1_style_value = "" + ctx.key + ": " + ctx.value; + attr(div0, "style", ctx.style); + attr(div1, "style", div1_style_value = "" + ctx.key + ": " + ctx.value); }, m(target, anchor) { @@ -30,11 +31,11 @@ function create_fragment(ctx) { p(changed, ctx) { if (changed.style) { - div0.style.cssText = ctx.style; + attr(div0, "style", ctx.style); } if ((changed.key || changed.value) && div1_style_value !== (div1_style_value = "" + ctx.key + ": " + ctx.value)) { - div1.style.cssText = div1_style_value; + attr(div1, "style", div1_style_value); } }, diff --git a/test/runtime/samples/contenteditable-html/_config.js b/test/runtime/samples/contenteditable-html/_config.js index 013fa30f39..285512b6c9 100644 --- a/test/runtime/samples/contenteditable-html/_config.js +++ b/test/runtime/samples/contenteditable-html/_config.js @@ -4,7 +4,7 @@ export default { }, html: ` - <editor><b>world</b></editor> + <editor contenteditable="true"><b>world</b></editor> <p>hello <b>world</b></p> `, @@ -21,7 +21,7 @@ export default { // No updates to data yet assert.htmlEqual(target.innerHTML, ` - <editor>every<span>body</span></editor> + <editor contenteditable="true">every<span>body</span></editor> <p>hello <b>world</b></p> `); @@ -29,14 +29,14 @@ export default { const event = new window.Event('input'); await el.dispatchEvent(event); assert.htmlEqual(target.innerHTML, ` - <editor>every<span>body</span></editor> + <editor contenteditable="true">every<span>body</span></editor> <p>hello every<span>body</span></p> `); component.name = 'good<span>bye</span>'; assert.equal(el.innerHTML, 'good<span>bye</span>'); assert.htmlEqual(target.innerHTML, ` - <editor>good<span>bye</span></editor> + <editor contenteditable="true">good<span>bye</span></editor> <p>hello good<span>bye</span></p> `); }, diff --git a/test/runtime/samples/contenteditable-text/_config.js b/test/runtime/samples/contenteditable-text/_config.js index 4935a3a9a7..059cda7cfe 100644 --- a/test/runtime/samples/contenteditable-text/_config.js +++ b/test/runtime/samples/contenteditable-text/_config.js @@ -4,7 +4,7 @@ export default { }, html: ` - <editor>world</editor> + <editor contenteditable="true">world</editor> <p>hello world</p> `, @@ -23,14 +23,14 @@ export default { await el.dispatchEvent(event); assert.htmlEqual(target.innerHTML, ` - <editor>everybody</editor> + <editor contenteditable="true">everybody</editor> <p>hello everybody</p> `); component.name = 'goodbye'; assert.equal(el.textContent, 'goodbye'); assert.htmlEqual(target.innerHTML, ` - <editor>goodbye</editor> + <editor contenteditable="true">goodbye</editor> <p>hello goodbye</p> `); }, diff --git a/test/runtime/samples/set-undefined-attr/_config.js b/test/runtime/samples/set-undefined-attr/_config.js index e28bad8257..b23f51dfc9 100644 --- a/test/runtime/samples/set-undefined-attr/_config.js +++ b/test/runtime/samples/set-undefined-attr/_config.js @@ -1,5 +1,5 @@ export default { - html: '<div></div>', + html: `<div draggable='false'></div>`, - ssrHtml: '<div foo=1></div>' + ssrHtml: `<div foo='1' draggable='false'></div>`, }; diff --git a/test/runtime/samples/set-undefined-attr/main.svelte b/test/runtime/samples/set-undefined-attr/main.svelte index 8191acbeff..77a1885415 100644 --- a/test/runtime/samples/set-undefined-attr/main.svelte +++ b/test/runtime/samples/set-undefined-attr/main.svelte @@ -3,10 +3,11 @@ export let foo = 1; export let bar; + export let _class; onMount(() => { foo = undefined; }); </script> -<div {foo} {bar}></div> +<div {foo} {bar} class={_class} draggable='false'></div> From d36478657ce70ac5e2884ee08a7ff9ca85ac89f9 Mon Sep 17 00:00:00 2001 From: Richard Harris <richard.a.harris@gmail.com> Date: Sun, 16 Jun 2019 13:59:24 -0400 Subject: [PATCH 49/49] move get_name to get_name_from_filename and add unit tests --- package.json | 2 +- src/compiler/compile/index.ts | 30 ++----------------- src/compiler/compile/utils/__test__.ts | 15 ++++++++++ .../compile/utils/get_name_from_filename.ts | 26 ++++++++++++++++ 4 files changed, 44 insertions(+), 29 deletions(-) create mode 100644 src/compiler/compile/utils/get_name_from_filename.ts diff --git a/package.json b/package.json index 7106e60d69..4c9b5614be 100644 --- a/package.json +++ b/package.json @@ -24,7 +24,7 @@ "types": "types/runtime", "scripts": { "test": "mocha --opts mocha.opts", - "test:unit": "mocha --require sucrase/register --recursive ./**/__test__.ts", + "test:unit": "mocha --require sucrase/register --recursive src/**/__test__.ts", "quicktest": "mocha --opts mocha.opts", "precoverage": "c8 mocha --opts mocha.coverage.opts", "coverage": "c8 report --reporter=text-lcov > coverage.lcov && c8 report --reporter=html", diff --git a/src/compiler/compile/index.ts b/src/compiler/compile/index.ts index 896f235c61..973847a1b9 100644 --- a/src/compiler/compile/index.ts +++ b/src/compiler/compile/index.ts @@ -6,6 +6,7 @@ import render_ssr from './render-ssr/index'; import { CompileOptions, Warning } from '../interfaces'; import Component from './Component'; import fuzzymatch from '../utils/fuzzymatch'; +import { get_name_from_filename } from './utils/get_name_from_filename'; const valid_options = [ 'format', @@ -55,33 +56,6 @@ function validate_options(options: CompileOptions, warnings: Warning[]) { } } -function get_name(filename: string) { - if (!filename) return null; - // eslint-disable-next-line no-useless-escape - const parts = filename.split(/[\/\\]/); - - if (parts.length > 1) { - const index_match = parts[parts.length - 1].match(/^index(\.\w+)/); - if (index_match) { - parts.pop(); - parts[parts.length - 1] += index_match[1]; - } - } - - const base = parts.pop() - .replace(/\.[^.]+$/, "") - .replace(/[^a-zA-Z_$0-9]+/g, '_') - .replace(/^_/, '') - .replace(/_$/, '') - .replace(/^(\d)/, '_$1'); - - if (!base) { - throw new Error(`Could not derive component name from file ${filename}`); - } - - return base[0].toUpperCase() + base.slice(1); -} - export default function compile(source: string, options: CompileOptions = {}) { options = assign({ generate: 'dom', dev: false }, options); @@ -98,7 +72,7 @@ export default function compile(source: string, options: CompileOptions = {}) { const component = new Component( ast, source, - options.name || get_name(options.filename) || 'Component', + options.name || get_name_from_filename(options.filename) || 'Component', options, stats, warnings diff --git a/src/compiler/compile/utils/__test__.ts b/src/compiler/compile/utils/__test__.ts index 7a8b5a6fd7..b5bc5d8ea8 100644 --- a/src/compiler/compile/utils/__test__.ts +++ b/src/compiler/compile/utils/__test__.ts @@ -1,6 +1,7 @@ import * as assert from 'assert'; import deindent from './deindent'; import CodeBuilder from './CodeBuilder'; +import get_name_from_filename from './get_name_from_filename'; describe('deindent', () => { it('deindents a simple string', () => { @@ -164,3 +165,17 @@ describe('CodeBuilder', () => { ); }); }); + +describe('get_name_from_filename', () => { + it('uses the basename', () => { + assert.equal(get_name_from_filename('path/to/Widget.svelte'), 'Widget'); + }); + + it('uses the directory name, if basename is index', () => { + assert.equal(get_name_from_filename('path/to/Widget/index.svelte'), 'Widget'); + }); + + it('handles unusual filenames', () => { + assert.equal(get_name_from_filename('path/to/[...parts].svelte'), 'Parts'); + }); +}); diff --git a/src/compiler/compile/utils/get_name_from_filename.ts b/src/compiler/compile/utils/get_name_from_filename.ts new file mode 100644 index 0000000000..19c781825c --- /dev/null +++ b/src/compiler/compile/utils/get_name_from_filename.ts @@ -0,0 +1,26 @@ +export default function get_name_from_filename(filename: string) { + if (!filename) return null; + // eslint-disable-next-line no-useless-escape + const parts = filename.split(/[\/\\]/); + + if (parts.length > 1) { + const index_match = parts[parts.length - 1].match(/^index(\.\w+)/); + if (index_match) { + parts.pop(); + parts[parts.length - 1] += index_match[1]; + } + } + + const base = parts.pop() + .replace(/\.[^.]+$/, "") + .replace(/[^a-zA-Z_$0-9]+/g, '_') + .replace(/^_/, '') + .replace(/_$/, '') + .replace(/^(\d)/, '_$1'); + + if (!base) { + throw new Error(`Could not derive component name from file ${filename}`); + } + + return base[0].toUpperCase() + base.slice(1); +} \ No newline at end of file