diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 2488902b24..14824ecdfa 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -23,3 +23,9 @@ jobs: - uses: actions/checkout@v1 - uses: actions/setup-node@v1 - run: 'npm i && npm run lint' + Unit: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v1 + - uses: actions/setup-node@v1 + - run: 'npm i && npm run test:unit' diff --git a/CHANGELOG.md b/CHANGELOG.md index 5838dcac80..00ea564045 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,10 +1,21 @@ # Svelte changelog -## Unreleased +## 3.18.1 + +* Fix code generation error with adjacent inline and block comments ([#4312](https://github.com/sveltejs/svelte/issues/4312)) +* Fix detection of unused CSS selectors that begin with a `:global()` but contain a scoped portion ([#4314](https://github.com/sveltejs/svelte/issues/4314)) + +## 3.18.0 + +* Fix infinite loop when instantiating another component during `onMount` ([#3218](https://github.com/sveltejs/svelte/issues/3218)) +* Make autosubscribing to a nullish store a no-op ([#2181](https://github.com/sveltejs/svelte/issues/2181)) + +## 3.17.3 * Fix updating a `` inside an `{#if}` or other block ([#4292](https://github.com/sveltejs/svelte/issues/4292)) * Fix using RxJS observables in `derived` stores ([#4298](https://github.com/sveltejs/svelte/issues/4298)) * Add dev mode check to disallow duplicate keys in a keyed `{#each}` ([#4301](https://github.com/sveltejs/svelte/issues/4301)) +* Fix hydration of `` when starting from SSR-generated code with `hydratable: true` ([#4310](https://github.com/sveltejs/svelte/issues/4310)) ## 3.17.2 diff --git a/README.md b/README.md index 9460efce76..e05154bd7c 100644 --- a/README.md +++ b/README.md @@ -7,10 +7,6 @@ <img src="https://img.shields.io/npm/v/svelte.svg" alt="npm version"> </a> - <a href="https://packagephobia.now.sh/result?p=svelte"> - <img src="https://packagephobia.now.sh/badge?p=svelte" alt="install size"> - </a> - <a href="https://github.com/sveltejs/svelte/actions"> <img src="https://github.com/sveltejs/svelte/workflows/CI/badge.svg?branch=master" alt="build status"> diff --git a/package-lock.json b/package-lock.json index ca225baa1b..2872c1b8dd 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "svelte", - "version": "3.17.2", + "version": "3.18.1", "lockfileVersion": 1, "requires": true, "dependencies": { @@ -597,9 +597,9 @@ "dev": true }, "code-red": { - "version": "0.0.31", - "resolved": "https://registry.npmjs.org/code-red/-/code-red-0.0.31.tgz", - "integrity": "sha512-7Gf3vm8pDbs+H/hKsaqOZe0xKlE9Neah12GCfs7qun3fBUaOXwexAMjn0Eo9cvJJvhRMaL0jgPiY9ZGLTWoe8A==", + "version": "0.0.32", + "resolved": "https://registry.npmjs.org/code-red/-/code-red-0.0.32.tgz", + "integrity": "sha512-mE+EZc2vJ4HxiejW5S2CvcVDKtopFEmrqAd9DTBDLCNjLgxekPP8wLi/ZiwDTwZwwW3dzeetaubLaMlIvkhVNw==", "dev": true, "requires": { "acorn": "^7.1.0", diff --git a/package.json b/package.json index 0910dca8c0..ff8b819668 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "svelte", - "version": "3.17.2", + "version": "3.18.1", "description": "Cybernetically enhanced web apps", "module": "index.mjs", "main": "index", @@ -70,7 +70,7 @@ "acorn": "^7.1.0", "agadoo": "^1.1.0", "c8": "^5.0.1", - "code-red": "0.0.31", + "code-red": "0.0.32", "codecov": "^3.5.0", "css-tree": "1.0.0-alpha22", "eslint": "^6.3.0", diff --git a/site/Makefile b/site/Makefile index 4c432dc6c9..6fd08fd8ee 100644 --- a/site/Makefile +++ b/site/Makefile @@ -14,9 +14,9 @@ sapper: docker: @echo "\n~> building docker image" - @gcloud builds submit -t $(IMAGE) + @gcloud builds submit --project $(PROJECT) -t $(IMAGE) deploy: sapper docker @echo "\n~> deploying $(SERVICE) to Cloud Run servers" - @gcloud beta run deploy $(SERVICE) --allow-unauthenticated --platform managed --region us-central1 --image $(IMAGE) --memory=512Mi + @gcloud run deploy $(SERVICE) --project $(PROJECT) --allow-unauthenticated --platform managed --region us-central1 --image $(IMAGE) --memory=512Mi diff --git a/site/content/docs/00-introduction.md b/site/content/docs/00-introduction.md index 2456b85f9c..15fdffbde2 100644 --- a/site/content/docs/00-introduction.md +++ b/site/content/docs/00-introduction.md @@ -2,8 +2,8 @@ title: Before we begin --- -> Temporary note: This document is a work-in-progress. Please forgive any missing or misleading parts, and don't be shy about asking for help in the [Discord chatroom](chat). The [tutorial](tutorial) is more complete; start there. - This page contains detailed API reference documentation. It's intended to be a resource for people who already have some familiarity with Svelte. If that's not you (yet), you may prefer to visit the [interactive tutorial](tutorial) or the [examples](examples) before consulting this reference. + +Don't be shy about asking for help in the [Discord chatroom](chat). \ No newline at end of file diff --git a/site/src/template.html b/site/src/template.html index dc930a7f72..344684d766 100644 --- a/site/src/template.html +++ b/site/src/template.html @@ -15,6 +15,7 @@ <meta name='twitter:site' content='@sveltejs'> <meta name='twitter:creator' content='@sveltejs'> <meta name='twitter:image' content='https://svelte.dev/images/twitter-card.png'> + <meta name='og:image' content='https://svelte.dev/images/twitter-card.png'> <!-- Sapper generates a <style> tag containing critical CSS for the current page. CSS for the rest of the app is diff --git a/src/compiler/compile/css/Selector.ts b/src/compiler/compile/css/Selector.ts index 39bbc2e8d1..6bc046c93e 100644 --- a/src/compiler/compile/css/Selector.ts +++ b/src/compiler/compile/css/Selector.ts @@ -32,7 +32,7 @@ export default class Selector { } this.local_blocks = this.blocks.slice(0, i); - this.used = this.blocks[0].global; + this.used = this.local_blocks.length === 0; } apply(node: Element, stack: Element[]) { diff --git a/src/compiler/compile/render_ssr/handlers/Title.ts b/src/compiler/compile/render_ssr/handlers/Title.ts index a3f271ab1b..f1f458ed5b 100644 --- a/src/compiler/compile/render_ssr/handlers/Title.ts +++ b/src/compiler/compile/render_ssr/handlers/Title.ts @@ -5,11 +5,7 @@ import { x } from 'code-red'; export default function(node: Title, renderer: Renderer, options: RenderOptions) { renderer.push(); - renderer.add_string('<title'); - if (options.hydratable && options.head_id) { - renderer.add_string(` data-svelte="${options.head_id}"`); - } - renderer.add_string('>'); + renderer.add_string(`<title>`); renderer.render(node.children, options); diff --git a/src/compiler/compile/utils/__test__.ts b/src/compiler/compile/utils/__test__.ts index 60ad681b47..7777bc6afb 100644 --- a/src/compiler/compile/utils/__test__.ts +++ b/src/compiler/compile/utils/__test__.ts @@ -10,7 +10,7 @@ describe('get_name_from_filename', () => { 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'); + it('handles Windows filenames', () => { + assert.equal(get_name_from_filename('path\\to\\Widget.svelte'), 'Widget'); }); }); diff --git a/src/runtime/internal/scheduler.ts b/src/runtime/internal/scheduler.ts index 04c1264ab1..1ce255b217 100644 --- a/src/runtime/internal/scheduler.ts +++ b/src/runtime/internal/scheduler.ts @@ -31,8 +31,8 @@ export function add_flush_callback(fn) { flush_callbacks.push(fn); } +const seen_callbacks = new Set(); export function flush() { - const seen_callbacks = new Set(); do { // first, call beforeUpdate functions @@ -52,10 +52,10 @@ export function flush() { const callback = render_callbacks[i]; if (!seen_callbacks.has(callback)) { - callback(); - // ...so guard against infinite loops seen_callbacks.add(callback); + + callback(); } } @@ -67,6 +67,7 @@ export function flush() { } update_scheduled = false; + seen_callbacks.clear(); } function update($$) { diff --git a/src/runtime/internal/utils.ts b/src/runtime/internal/utils.ts index c7722e1a07..4ba7e18c15 100644 --- a/src/runtime/internal/utils.ts +++ b/src/runtime/internal/utils.ts @@ -43,12 +43,15 @@ export function not_equal(a, b) { } export function validate_store(store, name) { - if (!store || typeof store.subscribe !== 'function') { + if (store != null && typeof store.subscribe !== 'function') { throw new Error(`'${name}' is not a store with a 'subscribe' method`); } } export function subscribe(store, ...callbacks) { + if (store == null) { + return noop; + } const unsub = store.subscribe(...callbacks); return unsub.unsubscribe ? () => unsub.unsubscribe() : unsub; } diff --git a/test/css/samples/global-with-unused-descendant/_config.js b/test/css/samples/global-with-unused-descendant/_config.js new file mode 100644 index 0000000000..3ed2dd2728 --- /dev/null +++ b/test/css/samples/global-with-unused-descendant/_config.js @@ -0,0 +1,24 @@ +export default { + warnings: [{ + code: 'css-unused-selector', + end: { + character: 27, + column: 19, + line: 2 + }, + frame: ` + 1: <style> + 2: :global(.foo) .bar { + ^ + 3: color: red; + 4: } + `, + message: 'Unused CSS selector', + pos: 9, + start: { + character: 9, + column: 1, + line: 2 + } + }] +}; diff --git a/test/css/samples/global-with-unused-descendant/expected.css b/test/css/samples/global-with-unused-descendant/expected.css new file mode 100644 index 0000000000..e69de29bb2 diff --git a/test/css/samples/global-with-unused-descendant/input.svelte b/test/css/samples/global-with-unused-descendant/input.svelte new file mode 100644 index 0000000000..ede6eedec3 --- /dev/null +++ b/test/css/samples/global-with-unused-descendant/input.svelte @@ -0,0 +1,5 @@ +<style> + :global(.foo) .bar { + color: red; + } +</style> diff --git a/test/hydration/samples/head-meta-hydrate-duplicate/_before_head.html b/test/hydration/samples/head-meta-hydrate-duplicate/_before_head.html index d2f218fb8d..107753cdd0 100644 --- a/test/hydration/samples/head-meta-hydrate-duplicate/_before_head.html +++ b/test/hydration/samples/head-meta-hydrate-duplicate/_before_head.html @@ -1,4 +1,4 @@ -<title data-svelte="svelte-1s8aodm">Some Title +Some Title \ No newline at end of file diff --git a/test/runtime/samples/lifecycle-onmount-infinite-loop/Child.svelte b/test/runtime/samples/lifecycle-onmount-infinite-loop/Child.svelte new file mode 100644 index 0000000000..ef16875b64 --- /dev/null +++ b/test/runtime/samples/lifecycle-onmount-infinite-loop/Child.svelte @@ -0,0 +1 @@ +Child diff --git a/test/runtime/samples/lifecycle-onmount-infinite-loop/_config.js b/test/runtime/samples/lifecycle-onmount-infinite-loop/_config.js new file mode 100644 index 0000000000..a76a2686ac --- /dev/null +++ b/test/runtime/samples/lifecycle-onmount-infinite-loop/_config.js @@ -0,0 +1,6 @@ +export default { + test({ assert, component }) { + const { count } = component; + assert.deepEqual(count, 1); + } +}; diff --git a/test/runtime/samples/lifecycle-onmount-infinite-loop/main.svelte b/test/runtime/samples/lifecycle-onmount-infinite-loop/main.svelte new file mode 100644 index 0000000000..1fa4263e39 --- /dev/null +++ b/test/runtime/samples/lifecycle-onmount-infinite-loop/main.svelte @@ -0,0 +1,16 @@ + + +
diff --git a/test/runtime/samples/store-auto-subscribe-nullish/_config.js b/test/runtime/samples/store-auto-subscribe-nullish/_config.js new file mode 100644 index 0000000000..52e21cef05 --- /dev/null +++ b/test/runtime/samples/store-auto-subscribe-nullish/_config.js @@ -0,0 +1,13 @@ +import { writable } from '../../../../store'; + +export default { + html: ` +

undefined

+ `, + async test({ assert, component, target }) { + component.store = writable('foo'); + assert.htmlEqual(target.innerHTML, ` +

foo

+ `); + } +}; diff --git a/test/runtime/samples/store-auto-subscribe-nullish/main.svelte b/test/runtime/samples/store-auto-subscribe-nullish/main.svelte new file mode 100644 index 0000000000..9c1ed4a560 --- /dev/null +++ b/test/runtime/samples/store-auto-subscribe-nullish/main.svelte @@ -0,0 +1,5 @@ + + +

{$store}

diff --git a/test/server-side-rendering/samples/head-meta-hydrate-duplicate/_expected-head.html b/test/server-side-rendering/samples/head-meta-hydrate-duplicate/_expected-head.html index d2f218fb8d..107753cdd0 100644 --- a/test/server-side-rendering/samples/head-meta-hydrate-duplicate/_expected-head.html +++ b/test/server-side-rendering/samples/head-meta-hydrate-duplicate/_expected-head.html @@ -1,4 +1,4 @@ -Some Title +Some Title \ No newline at end of file