From d9cc0ffc8fde90af9b945dc1c10094b5a9c31dd7 Mon Sep 17 00:00:00 2001 From: Daniel Sandoval Date: Tue, 31 May 2022 14:09:28 -0600 Subject: [PATCH 01/89] [docs] "What's new in Svelte" June newsletter (#7565) --- ...022-06-01-whats-new-in-svelte-june-2022.md | 113 ++++++++++++++++++ 1 file changed, 113 insertions(+) create mode 100644 site/content/blog/2022-06-01-whats-new-in-svelte-june-2022.md diff --git a/site/content/blog/2022-06-01-whats-new-in-svelte-june-2022.md b/site/content/blog/2022-06-01-whats-new-in-svelte-june-2022.md new file mode 100644 index 0000000000..b7685bf8ad --- /dev/null +++ b/site/content/blog/2022-06-01-whats-new-in-svelte-june-2022.md @@ -0,0 +1,113 @@ +--- +title: "What's new in Svelte: June 2022" +description: "Cancellable dispatched events, deeper {@const} declarations and more!" +author: Daniel Sandoval +authorURL: https://desandoval.net +--- + +With last month's [Svelte Summit](https://www.youtube.com/watch?v=qqj2cBockqE) behind us, we're ready to apply everything we learned in this new month of June! Also new this month are some quality-of-life changes to `createEventDispatcher`, `@const` declarations and tons of progress toward SvelteKit 1.0. + +Let's dive in! + +## What's new in Svelte +- Custom events can now be cancelled in the `createEventDispatcher` function (**3.48.0**, [Docs](https://svelte.dev/docs#run-time-svelte-createeventdispatcher), [PR](https://github.com/sveltejs/svelte/pull/7064)) +- The `{@const}` tag can now be used in `{#if}` blocks to conditionally define variables (**3.48.0**, [Docs](https://svelte.dev/docs#template-syntax-const), [PR](https://github.com/sveltejs/svelte/pull/7451)) +- Lots of bug fixes across ``, animations and various DOM elements. Check out the [CHANGELOG](https://github.com/sveltejs/svelte/blob/master/CHANGELOG.md#3480) for a deeper dive! + + +## What's new in SvelteKit +- Vite 2.9.9 was released as one of the last Vite 2 releases. The Svelte team has been hard at work contributing to the the Vite 3 release to make the integration between SvelteKit and Vite smoother than ever ([Vite 3.0 Milestone](https://github.com/vitejs/vite/milestone/5)) +- `config.kit.alias` lets you more easily declare a custom alias to replace values in `import` statements ([Docs](https://kit.svelte.dev/docs/configuration#alias), [Issue](https://github.com/sveltejs/kit/pull/4922)) +- Pages marked for prerendering will now fail during SSR at runtime ([PR](https://github.com/sveltejs/kit/pull/4812)) + +**Breaking Changes** +- Node 14 is no longer supported ([Issue](https://github.com/sveltejs/kit/issues/4916)) +- Requests to `/favicon.ico` will no longer be suppressed and will instead be handled as a valid route ([PR](https://github.com/sveltejs/kit/pull/5046)) +- AMP support has been moved to a separate `@sveltejs/amp` package ([Docs](https://kit.svelte.dev/docs/seo#manual-setup-amp), [PR](https://github.com/sveltejs/kit/pull/4710)) +- Generated types are now written to `_types` directories - update your imports accordingly ([PR](https://github.com/sveltejs/kit/pull/4705)) +- `%svelte.head%` and `%svelte.body%` are now `%sveltekit.head%` and `%sveltekit.body%` in `app.html` ([Docs](https://kit.svelte.dev/docs/migrating#project-files-src-template-html), [PR](https://github.com/sveltejs/kit/pull/5016/)) +- `LoadInput` is now `LoadEvent` +- Dropped support for Wrangler 1 in favor of Wrangler 2 ([PR}(https://github.com/sveltejs/kit/pull/4887)) + +--- + +## Community Showcase + +**Apps & Sites built with Svelte** +- [Plantarium](https://github.com/jim-fx/plantarium) is a tool for the procedural generation of 3D plants. +- [SPATULA](https://github.com/AlexWarnes/lamina-spatula) is a tool for building shading materials that are exportable as code material in any project that uses lamina and threejs +- [Waaard](https://waaard.com/) lets you create and send protected links with a variety of SSO providers +- [Magidoc](https://github.com/magidoc-org/magidoc) is a fast and highly customizable GraphQL documentation generator +- [myMarkmap](https://github.com/eyssette/myMarkmap) is a custom editor for Markmap, built with SvelteKit +- [PassShare](https://passshare.mynt.pw/) is a way for you to share your passwords to your friends, securely and effortlessly +- [DashingOS](https://beta.dashingos.com/) is a tool (like Notion + CodeSandbox) to make it quick and easy to prototype and document your work all in one place +- [worker-kit-email](https://github.com/miunau/worker-kit-email) helps you develop transactional emails quickly using regular SvelteKit routes +- [kaios-weather-svelte](https://github.com/cyan-2048/kaios-weather-svelte) is a very familiar looking weather app for KaiOS +- [svelte-gantt](https://github.com/ANovokmet/svelte-gantt) is a lightweight and fast interactive gantt chart/resource booking component +- [Miru](https://github.com/ThaUnknown/miru) is a BitTorrent streaming software for cats + +Looking for a great SvelteKit website to contribute to? [Help build the Svelte Society site](https://github.com/svelte-society/sveltesociety.dev/issues)! + + +**Learning Resources** + +_To Read_ +- [Component party](https://component-party.dev/) is a site that compares common patterns in different frameworks +- [Quick tip: style prop defaults](https://geoffrich.net/posts/style-prop-defaults/) by Geoff Rich +- [Working with reduced motion in Svelte](https://ghostdev.xyz/posts/working-with-reduced-motion-in-svelte) by GHOST +- [Building a Musical Instrument with the Web Audio API](https://www.taniarascia.com/musical-instrument-web-audio-api/) by Tania Rascia +- [Svelte-Cubed: Creating an Accessible and Consistent Experience Across Devices](https://dev.to/alexwarnes/svelte-cubed-creating-an-accessible-and-consistent-experience-across-devices-42ae) and [Svelte-Cubed: Loading Your glTF Models](https://dev.to/alexwarnes/svelte-cubed-loading-your-gltf-models-14lf) by Alex Warnes + +_To Watch_ + +From Svelte Society: +- [The Svelte Summit Spring 2022 stream recording](https://www.youtube.com/watch?v=qqj2cBockqE) has been updated with chapter markers to make it easy to watch again and again +- [The full recording of Svelte London, April 2022](https://www.youtube.com/watch?v=zIxzJzTnoxA) is up! Check out the amazing talks from across the Svelte London community +- [Persian Svelte Society](https://www.youtube.com/channel/UCfWH9lCsXN3j8oXq8dru82Q) is making Persian-language videos about Svelte +- Svelte Sirens has been talking monthly to creators and contributors across the Svelte Community: + - [SvelteKit + Sanity.io: a match made in heaven](https://www.youtube.com/watch?v=j0_1hfiEVWA&list=PL8bMgX1kyZThkJ_Rk6AAFI4eY24g5XKwK&index=5) on May 13 + - [Slicing up your Svelte Sites with Prismic](https://www.youtube.com/watch?v=FUbHwwMALkk) on May 20 + - [Rendering your Svelte apps on Render](https://www.youtube.com/watch?v=SnV_hMLVyqs) on May 24 + - [The story behind the (unofficial) Svelte newsletter](https://www.youtube.com/watch?v=aK0xXm3hPxk&list=PL8bMgX1kyZThkJ_Rk6AAFI4eY24g5XKwK&index=7) on May 27 + + +Across the Web: +- [Building vite-plugin-svelte-inspector](https://www.youtube.com/watch?v=udYB24IMtsY), [What is Singleton?](https://www.youtube.com/watch?v=xhi0m1QZue0) and [What is Navigation?](https://www.youtube.com/watch?v=Ym-OnGUps2c) by lihautan +- [Auto Import Components In Svelte Kit - Weekly Svelte](https://www.youtube.com/watch?v=JXvKBtTPr64) by LevelUpTuts +- [๐Ÿงช Test SvelteKit with TDD & VITEST ๐Ÿงช](https://www.youtube.com/watch?v=5bQD3dCoyHA) by Johnny Magrippis +- [Google Analytics With SvelteKit](https://www.youtube.com/watch?v=l-x6H0fnqqQ), [Using WebSockets With SvelteKit](https://www.youtube.com/watch?v=mAcKzdW5fR8), [SvelteKit Authentication Using Cookies](https://www.youtube.com/watch?v=T935Ya4W5X0) and [Svelte Headless UI Component Library](https://www.reddit.com/r/sveltejs/comments/ueu849/svelte_headless_ui_component_library/) by Joy of Code +- [Named Layouts In Nested Routes in SvelteKit](https://www.youtube.com/watch?v=hKg_V3jouLk) by The Svelte Junction +- [SvelteKit Shiki Syntax Highlighting: Markdown Codeblocks](https://rodneylab.com/sveltekit-shiki-syntax-highlighting/) and [Svelte Capsize Styling: Typography Tooling](https://rodneylab.com/svelte-capsize-styling/) by Rodney Lab + +_To Hear_ +- Svelte Radio has been putting out weekly episodes: + - [The Adventures of Running a Svelte Meetup](https://www.svelteradio.com/episodes/the-adventures-of-running-a-svelte-meetup) + - [The other Rich! Geoff! (feat. Geoff Rich)](https://www.svelteradio.com/episodes/the-other-rich-geoff) + - [Inspecting Svelte Code with Dominik G.](https://www.svelteradio.com/episodes/inspecting-svelte-code-with-dominik-g) + - [Stores Galore](https://www.svelteradio.com/episodes/stores-galore) +- [Svelte and the Future of Frontend Development (feat. Rich Harris)](https://thenewstack.io/svelte-and-the-future-of-front-end-development/) from The New Stack + + +**Libraries, Tools & Components** +- [vite-plugin-svelte-console-remover](https://github.com/jhubbardsf/vite-plugin-svelte-console-remover) is a Vite plugin that removes all console statements (log, group, dir, error, etc) from Svelte, JS, and TS files during build so they don't leak into production +- [Svelte Headless Tables](https://github.com/bryanmylee/svelte-headless-table) is an unopinionated and extensible data tables for Svelte +- [y-presence](https://github.com/nimeshnayaju/y-presence) is a lightweight set of libraries to easily add presence (live cursors/avatars) to any web application (now with Svelte support!) +- [Svelcro](https://github.com/oslabs-beta/Svelcro) is a component performance tracker for Svelte applications +- [Svelte-Splitpanes](https://github.com/orefalo/svelte-splitpanes) lets you create dynamic and predictable view panels to layout an application +- [svelte-miniplayer](https://github.com/ThaUnknown/svelte-miniplayer) is a lightweight, fast, resizable and draggable miniplayer for media +- [svelte-keybinds](https://github.com/ThaUnknown/svelte-keybinds) is a minimalistic keybinding interface, with rebinding and saving +- [svelte-speech-recognition](https://github.com/jhubbardsf/svelte-speech-recognition) converts speech from the microphone to text and makes it available to your Svelte components + +**Special Feature: Svelte Stores** +There were lots of Svelte stores released this month from a number of authors... + +- [svelte-mutable-store](https://github.com/feltcoop/svelte-mutable-store) is a Svelte store for mutable values with the `immutable` compiler option +- [svelte-damped-store](https://github.com/aredridel/svelte-damped-store) is a derived writable store that can suspend updates while [svelte-lens-store](https://github.com/aredridel/svelte-lens-store) is a functional lens over Svelte stores +- [svelte-persistent-store](https://github.com/furudean/svelte-persistent-store) is a writable svelte store that saves and loads data from `Window.localStorage` or `Window.sessionStorage`. + + +Did we miss anything? Join us on [Reddit](https://www.reddit.com/r/sveltejs/) or [Discord](https://discord.com/invite/yy75DKs) to add your voice. + +Don't forget that you can also join us in-person at the Svelte Summit in Stockholm! Come join us for two days of awesome Svelte content! [Get your tickets now](https://ti.to/svelte/svelte-summit-fall-edition). + +See y'all next month! From 9dc308a745b2945508b9776760e7d838f9bedacd Mon Sep 17 00:00:00 2001 From: Ben McCann <322311+benmccann@users.noreply.github.com> Date: Tue, 31 May 2022 14:46:37 -0700 Subject: [PATCH 02/89] cleanup PR links in last blog post --- .../blog/2022-06-01-whats-new-in-svelte-june-2022.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/site/content/blog/2022-06-01-whats-new-in-svelte-june-2022.md b/site/content/blog/2022-06-01-whats-new-in-svelte-june-2022.md index b7685bf8ad..d38921b7eb 100644 --- a/site/content/blog/2022-06-01-whats-new-in-svelte-june-2022.md +++ b/site/content/blog/2022-06-01-whats-new-in-svelte-june-2022.md @@ -17,17 +17,17 @@ Let's dive in! ## What's new in SvelteKit - Vite 2.9.9 was released as one of the last Vite 2 releases. The Svelte team has been hard at work contributing to the the Vite 3 release to make the integration between SvelteKit and Vite smoother than ever ([Vite 3.0 Milestone](https://github.com/vitejs/vite/milestone/5)) -- `config.kit.alias` lets you more easily declare a custom alias to replace values in `import` statements ([Docs](https://kit.svelte.dev/docs/configuration#alias), [Issue](https://github.com/sveltejs/kit/pull/4922)) +- `config.kit.alias` lets you more easily declare a custom alias to replace values in `import` statements ([Docs](https://kit.svelte.dev/docs/configuration#alias), [PR](https://github.com/sveltejs/kit/pull/4964)) - Pages marked for prerendering will now fail during SSR at runtime ([PR](https://github.com/sveltejs/kit/pull/4812)) **Breaking Changes** -- Node 14 is no longer supported ([Issue](https://github.com/sveltejs/kit/issues/4916)) +- Node 14 is no longer supported ([PR](https://github.com/sveltejs/kit/pull/4922)) - Requests to `/favicon.ico` will no longer be suppressed and will instead be handled as a valid route ([PR](https://github.com/sveltejs/kit/pull/5046)) - AMP support has been moved to a separate `@sveltejs/amp` package ([Docs](https://kit.svelte.dev/docs/seo#manual-setup-amp), [PR](https://github.com/sveltejs/kit/pull/4710)) - Generated types are now written to `_types` directories - update your imports accordingly ([PR](https://github.com/sveltejs/kit/pull/4705)) - `%svelte.head%` and `%svelte.body%` are now `%sveltekit.head%` and `%sveltekit.body%` in `app.html` ([Docs](https://kit.svelte.dev/docs/migrating#project-files-src-template-html), [PR](https://github.com/sveltejs/kit/pull/5016/)) - `LoadInput` is now `LoadEvent` -- Dropped support for Wrangler 1 in favor of Wrangler 2 ([PR}(https://github.com/sveltejs/kit/pull/4887)) +- Dropped support for Wrangler 1 in favor of Wrangler 2 ([PR](https://github.com/sveltejs/kit/pull/4887)) --- From 7630a25db54f113102ea6d69b7d3e13e82b278fb Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Fri, 3 Jun 2022 10:11:27 -0400 Subject: [PATCH 03/89] [docs] update getting started info (#7573) * update getting started info * Update site/content/blog/2019-04-16-svelte-for-new-developers.md Co-authored-by: Conduitry * Update site/content/tutorial/01-introduction/07-making-an-app/text.md Co-authored-by: gtmnayan <50981692+gtm-nayan@users.noreply.github.com> * Update site/content/blog/2019-04-16-svelte-for-new-developers.md Co-authored-by: Simon H <5968653+dummdidumm@users.noreply.github.com> Co-authored-by: Conduitry Co-authored-by: gtmnayan <50981692+gtm-nayan@users.noreply.github.com> --- .../2019-04-16-svelte-for-new-developers.md | 31 +++++++------------ .../01-introduction/07-making-an-app/text.md | 12 ++++--- 2 files changed, 19 insertions(+), 24 deletions(-) diff --git a/site/content/blog/2019-04-16-svelte-for-new-developers.md b/site/content/blog/2019-04-16-svelte-for-new-developers.md index c4ff4716e3..0a01474bbd 100644 --- a/site/content/blog/2019-04-16-svelte-for-new-developers.md +++ b/site/content/blog/2019-04-16-svelte-for-new-developers.md @@ -56,36 +56,36 @@ To write code, you need a good editor. The most popular choice is [Visual Studio ## Creating a project -We're going to follow the instructions in part two of [The easiest way to get started with Svelte](/blog/the-easiest-way-to-get-started). - -First, we'll use npx to run [degit](https://github.com/Rich-Harris/degit), a program for cloning project templates from [GitHub](https://github.com) and other code storage websites. You don't have to use a project template, but it means you have to do a lot less setup work. You will need to have [Git](https://git-scm.com/) installed in order to use degit. (Eventually you'll probably have to learn [Git](https://git-scm.com/) itself, which most programmers use to manage their projects.) +We're going to use the [Svelte + Vite](https://github.com/vitejs/vite/tree/main/packages/create-vite/template-svelte) template. You don't have to use a project template, but it means you have to do a lot less setup work. On the command line, navigate to where you want to create a new project, then type the following lines (you can paste the whole lot, but you'll develop better muscle memory if you get into the habit of writing each line out one at a time then running it): ```bash -npx degit sveltejs/template my-svelte-project +npm init vite my-svelte-project -- --template svelte cd my-svelte-project npm install ``` -This creates a new directory, `my-svelte-project`, adds files from the [sveltejs/template](https://github.com/sveltejs/template) code repository, and installs a number of packages from npm. Open the directory in your text editor and take a look around. The app's 'source code' lives in the `src` directory, while the files your app can load are in `public`. +> You can replace `--template svelte` with `--template svelte-ts`, if you prefer TypeScript. + +This creates a new directory, `my-svelte-project`, adds files from the [create-vite/template-svelte](https://github.com/vitejs/vite/tree/main/packages/create-vite/template-svelte) template, and installs a number of packages from npm. Open the directory in your text editor and take a look around. The app's 'source code' lives in the `src` directory, while the files your app can load are in `public`. -In the `package.json` file, there is a section called `"scripts"`. These scripts define shortcuts for working with your application โ€” `dev`, `build` and `start`. To launch your app in development mode, type the following: +In the `package.json` file, there is a section called `"scripts"`. These scripts define shortcuts for working with your application โ€” `dev`, `build` and `preview`. To launch your app in development mode, type the following: ```bash npm run dev ``` -Running the `dev` script starts a program called [Rollup](https://rollupjs.org/guide/en/). Rollup's job is to take your application's source files (so far, just `src/main.js` and `src/App.svelte`), pass them to other programs (including Svelte, in our case) and convert them into the code that will actually run when you open the application in a browser. +Running the `dev` script starts a program called [Vite](https://vitejs.dev/). Vite's job is to take your application's source files, pass them to other programs (including Svelte, in our case) and convert them into the code that will actually run when you open the application in a browser. -Speaking of which, open a browser and navigate to http://localhost:8080. This is your application running on a local *web server* (hence 'localhost') on port 8080. +Speaking of which, open a browser and navigate to http://localhost:3000. This is your application running on a local *web server* (hence 'localhost') on port 3000. -Try changing `src/App.svelte` and saving it. The application will reload with your changes. +Try changing `src/App.svelte` and saving it. The application will update with your changes. ## Building your app -In the last step, we were running the app in 'development mode'. In dev mode, Svelte adds extra code that helps with debugging, and Rollup skips the final step where your app's JavaScript is compressed using [Terser](https://terser.org/). +In the last step, we were running the app in 'development mode'. In dev mode, Svelte adds extra code that helps with debugging, and Vite skips the final step where your app's JavaScript is compressed. When you share your app with the world, you want to build it in 'production mode', so that it's as small and efficient as possible for end users. To do that, use the `build` command: @@ -93,15 +93,8 @@ When you share your app with the world, you want to build it in 'production mode npm run build ``` -Your `public` directory now contains a compressed `bundle.js` file containing your app's JavaScript. You can run it like so: +Your `dist` directory now contains an optimised version of your app. You can run it like so: ```bash -npm run start +npm run preview ``` - -This will run the app on http://localhost:8080. - - -## Next steps - -To share your app with the world you'll need to *deploy* it. There are many ways to do so โ€” some are listed in the `README.md` file inside your project. diff --git a/site/content/tutorial/01-introduction/07-making-an-app/text.md b/site/content/tutorial/01-introduction/07-making-an-app/text.md index 132865a364..b65d084f13 100644 --- a/site/content/tutorial/01-introduction/07-making-an-app/text.md +++ b/site/content/tutorial/01-introduction/07-making-an-app/text.md @@ -4,13 +4,15 @@ title: Making an app This tutorial is designed to get you familiar with the process of writing components. But at some point, you'll want to start writing components in the comfort of your own text editor. -First, you'll need to integrate Svelte with a build tool. There are officially maintained plugins for [Vite](https://vitejs.dev/), [Rollup](https://rollupjs.org) and [webpack](https://webpack.js.org/)... +First, you'll need to integrate Svelte with a build tool. We recommend using [Vite](https://vitejs.dev/) with [vite-plugin-svelte](https://github.com/sveltejs/vite-plugin-svelte/)... -* [vite-plugin-svelte](https://github.com/sveltejs/vite-plugin-svelte) -* [rollup-plugin-svelte](https://github.com/sveltejs/rollup-plugin-svelte) -* [svelte-loader](https://github.com/sveltejs/svelte-loader) +```bash +npm init vite my-app -- --template svelte +``` + +...or one of the [community-maintained integrations](https://sveltesociety.dev/tools). -...and a variety of [community-maintained ones](https://sveltesociety.dev/tools). +> [SvelteKit](https://kit.svelte.dev) is the official application framework from the Svelte team. It's currently in development, but if you don't mind using pre-1.0 software then it's the recommended way to build Svelte apps. Don't worry if you're relatively new to web development and haven't used these tools before. We've prepared a simple step-by-step guide, [Svelte for new developers](/blog/svelte-for-new-developers), which walks you through the process. From cab5e7346d14d4511087890e31e90f2be8b1aac9 Mon Sep 17 00:00:00 2001 From: Adam Alexander <50453312+a-alexander@users.noreply.github.com> Date: Wed, 8 Jun 2022 13:07:51 +0100 Subject: [PATCH 04/89] [docs] fix typo in 02-template-syntax.md (#7593) Tiny typo. --- site/content/docs/02-template-syntax.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/site/content/docs/02-template-syntax.md b/site/content/docs/02-template-syntax.md index ac49fb23c5..f2e71ecbe0 100644 --- a/site/content/docs/02-template-syntax.md +++ b/site/content/docs/02-template-syntax.md @@ -1666,7 +1666,7 @@ If `this` is the name of a void tag (e.g., `br`) and `` has chil The `` element allows you to add event listeners to the `window` object without worrying about removing them when the component is destroyed, or checking for the existence of `window` when server-side rendering. -Unlike ``, this element may only appear the top level of your component and must never be inside a block or element. +Unlike ``, this element may only appear at the top level of your component and must never be inside a block or element. ```sv " foo="">" qux="&&&" -> \ No newline at end of file + quux="">" +> + +
diff --git a/test/server-side-rendering/samples/attribute-escaped-quotes-spread/main.svelte b/test/server-side-rendering/samples/attribute-escaped-quotes-spread/main.svelte index 66047eb09a..9d721cd88f 100644 --- a/test/server-side-rendering/samples/attribute-escaped-quotes-spread/main.svelte +++ b/test/server-side-rendering/samples/attribute-escaped-quotes-spread/main.svelte @@ -1,10 +1,15 @@ -
\ No newline at end of file +
+
From ecb29aa8cff53b33a4c8b5a49d774bfd7ef04f08 Mon Sep 17 00:00:00 2001 From: Simon H <5968653+dummdidumm@users.noreply.github.com> Date: Mon, 20 Jun 2022 13:03:47 +0200 Subject: [PATCH 08/89] Update changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9dca374b76..2ca35627cf 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,7 @@ * Faster SSR ([#5701](https://github.com/sveltejs/svelte/pull/5701)) * Fix `class:` directive updates with `` ([#7521](https://github.com/sveltejs/svelte/issues/7521), [#7571](https://github.com/sveltejs/svelte/issues/7571)) +* Harden attribute escaping during ssr ([#7530](https://github.com/sveltejs/svelte/pull/7530)) ## 3.48.0 From d7557e11a265a71a26d78295774f131af366ddce Mon Sep 17 00:00:00 2001 From: hmt Date: Sat, 25 Jun 2022 19:56:06 +0200 Subject: [PATCH 09/89] [docs] remove v2 -> v3 converter mention (#7597) Was never finished --- site/content/faq/1000-how-can-i-update-my-v2-components.md | 5 ----- 1 file changed, 5 deletions(-) delete mode 100644 site/content/faq/1000-how-can-i-update-my-v2-components.md diff --git a/site/content/faq/1000-how-can-i-update-my-v2-components.md b/site/content/faq/1000-how-can-i-update-my-v2-components.md deleted file mode 100644 index 0800dff89b..0000000000 --- a/site/content/faq/1000-how-can-i-update-my-v2-components.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -question: How can I update my components written in Svelte v2? ---- - -svelte-upgrade isn't fully working for v2->v3 yet, [but it's close](https://github.com/sveltejs/svelte-upgrade/pull/12). \ No newline at end of file From 2f562d9e2817d911d0eec437d2b0e45074ec8291 Mon Sep 17 00:00:00 2001 From: Heechul Ryu Date: Wed, 29 Jun 2022 17:07:16 -0700 Subject: [PATCH 10/89] [docs] use npm create instead of npm init (#7641) --- site/content/tutorial/01-introduction/07-making-an-app/text.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/site/content/tutorial/01-introduction/07-making-an-app/text.md b/site/content/tutorial/01-introduction/07-making-an-app/text.md index b65d084f13..68b54e33f5 100644 --- a/site/content/tutorial/01-introduction/07-making-an-app/text.md +++ b/site/content/tutorial/01-introduction/07-making-an-app/text.md @@ -7,7 +7,7 @@ This tutorial is designed to get you familiar with the process of writing compon First, you'll need to integrate Svelte with a build tool. We recommend using [Vite](https://vitejs.dev/) with [vite-plugin-svelte](https://github.com/sveltejs/vite-plugin-svelte/)... ```bash -npm init vite my-app -- --template svelte +npm create vite my-app -- --template svelte ``` ...or one of the [community-maintained integrations](https://sveltesociety.dev/tools). From 6f575715073f4a1eb1abdd7a2d22a75ae6017cf7 Mon Sep 17 00:00:00 2001 From: Simon H <5968653+dummdidumm@users.noreply.github.com> Date: Fri, 1 Jul 2022 14:48:10 +0200 Subject: [PATCH 11/89] [feat] add convenience types ComponentType and ComponentProps (#6770) ComponentType eases typing "this is a variable that expects a Svelte component constructor (of a certain shape)". Removes the need for SvelteComponentTyped to be an extra type so it can be deprecated in v4 and removed in v5, and SvelteComponent(Dev) can receive the same generic typings as SvelteComponetTyped in v4. ComponentProps eases typing "give me the props this component expects". Closes #7584 Co-authored-by: Simon Holthausen Co-authored-by: Hofer Ivan Co-authored-by: Ignatius Bagus --- CHANGELOG.md | 1 + generate-type-definitions.js | 13 ++++++++++ package-lock.json | 12 +++++----- package.json | 2 +- src/runtime/index.ts | 1 + src/runtime/internal/dev.ts | 46 +++++++++++++++++++++++++++++++++--- 6 files changed, 65 insertions(+), 10 deletions(-) create mode 100644 generate-type-definitions.js diff --git a/CHANGELOG.md b/CHANGELOG.md index 2ca35627cf..b5bc4858d8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ * Faster SSR ([#5701](https://github.com/sveltejs/svelte/pull/5701)) * Fix `class:` directive updates with `` ([#7521](https://github.com/sveltejs/svelte/issues/7521), [#7571](https://github.com/sveltejs/svelte/issues/7571)) * Harden attribute escaping during ssr ([#7530](https://github.com/sveltejs/svelte/pull/7530)) +* Add `ComponentType` and `ComponentProps` convenience types ([#6770](https://github.com/sveltejs/svelte/pull/6770)) ## 3.48.0 diff --git a/generate-type-definitions.js b/generate-type-definitions.js new file mode 100644 index 0000000000..6cad31807f --- /dev/null +++ b/generate-type-definitions.js @@ -0,0 +1,13 @@ +// This script generates the TypeScript definitions + +const { execSync } = require('child_process'); +const { readFileSync, writeFileSync } = require('fs'); + +execSync('tsc -p src/compiler --emitDeclarationOnly && tsc -p src/runtime --emitDeclarationOnly'); + +// We need to add these types to the index.d.ts here because if we add them before building, the build will fail, +// because the TS->JS transformation doesn't know these exports are types and produces code that fails at runtime. +// We can't use `export type` syntax either because the TS version we're on doesn't have this feature yet. +const path = 'types/runtime/index.d.ts'; +const content = readFileSync(path, 'utf8'); +writeFileSync(path, content.replace('SvelteComponentTyped', 'SvelteComponentTyped, ComponentType, ComponentConstructorOptions, ComponentProps')); diff --git a/package-lock.json b/package-lock.json index 3e84c9b8c6..83d963b827 100644 --- a/package-lock.json +++ b/package-lock.json @@ -4402,9 +4402,9 @@ "dev": true }, "node_modules/typescript": { - "version": "3.7.5", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.7.5.tgz", - "integrity": "sha512-/P5lkRXkWHNAbcJIiHPfRoKqyd7bsyCma1hZNUGfn20qm64T6ZBlrzprymeu918H+mB/0rIg2gGK/BXkhhYgBw==", + "version": "3.9.10", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.9.10.tgz", + "integrity": "sha512-w6fIxVE/H1PkLKcCPsFqKE7Kv7QUwhU8qQY2MueZXWx5cPZdwFupLgKK3vntcK98BtNHZtAF4LA/yl2a7k8R6Q==", "dev": true, "bin": { "tsc": "bin/tsc", @@ -8096,9 +8096,9 @@ "dev": true }, "typescript": { - "version": "3.7.5", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.7.5.tgz", - "integrity": "sha512-/P5lkRXkWHNAbcJIiHPfRoKqyd7bsyCma1hZNUGfn20qm64T6ZBlrzprymeu918H+mB/0rIg2gGK/BXkhhYgBw==", + "version": "3.9.10", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.9.10.tgz", + "integrity": "sha512-w6fIxVE/H1PkLKcCPsFqKE7Kv7QUwhU8qQY2MueZXWx5cPZdwFupLgKK3vntcK98BtNHZtAF4LA/yl2a7k8R6Q==", "dev": true }, "unbox-primitive": { diff --git a/package.json b/package.json index b3c9c65f98..a1c9ae9a5d 100644 --- a/package.json +++ b/package.json @@ -95,7 +95,7 @@ "pretest": "npm run build", "posttest": "agadoo internal/index.mjs", "prepublishOnly": "node check_publish_env.js && npm run lint && npm test", - "tsd": "tsc -p src/compiler --emitDeclarationOnly && tsc -p src/runtime --emitDeclarationOnly", + "tsd": "node ./generate-type-definitions.js", "lint": "eslint \"{src,test}/**/*.{ts,js}\"" }, "repository": { diff --git a/src/runtime/index.ts b/src/runtime/index.ts index 8e12f9f0ee..08b25ba2ca 100644 --- a/src/runtime/index.ts +++ b/src/runtime/index.ts @@ -13,4 +13,5 @@ export { createEventDispatcher, SvelteComponentDev as SvelteComponent, SvelteComponentTyped + // additional exports added through post-typegen.js } from 'svelte/internal'; diff --git a/src/runtime/internal/dev.ts b/src/runtime/internal/dev.ts index 3144911672..5b00e7dc5b 100644 --- a/src/runtime/internal/dev.ts +++ b/src/runtime/internal/dev.ts @@ -128,7 +128,7 @@ export interface SvelteComponentDev { $destroy(): void; [accessor: string]: any; } -interface IComponentOptions = Record> { +export interface ComponentConstructorOptions = Record> { target: Element | ShadowRoot; anchor?: Element; props?: Props; @@ -164,7 +164,7 @@ export class SvelteComponentDev extends SvelteComponent { */ $$slot_def: any; - constructor(options: IComponentOptions) { + constructor(options: ComponentConstructorOptions) { if (!options || (!options.target && !options.$$inline)) { throw new Error("'target' is a required option"); } @@ -256,11 +256,51 @@ export class SvelteComponentTyped< */ $$slot_def: Slots; - constructor(options: IComponentOptions) { + constructor(options: ComponentConstructorOptions) { super(options); } } +/** + * Convenience type to get the type of a Svelte component. Useful for example in combination with + * dynamic components using ``. + * + * Example: + * ```html + * + * + * + * + * ``` + */ +export type ComponentType = new ( + options: ComponentConstructorOptions< + Component extends SvelteComponentTyped ? Props : Record + > +) => Component; + +/** + * Convenience type to get the props the given component expects. Example: + * ```html + * + * ``` + */ +export type ComponentProps = Component extends SvelteComponentTyped + ? Props + : never; + export function loop_guard(timeout) { const start = Date.now(); return () => { From 31e5f8b5de24e2e058cb1a70467c0092e422ee5d Mon Sep 17 00:00:00 2001 From: Daniel Sandoval Date: Fri, 1 Jul 2022 09:17:52 -0600 Subject: [PATCH 12/89] [docs] "What's new in Svelte" July newsletter (#7637) --- ...022-07-01-whats-new-in-svelte-july-2022.md | 98 +++++++++++++++++++ 1 file changed, 98 insertions(+) create mode 100644 site/content/blog/2022-07-01-whats-new-in-svelte-july-2022.md diff --git a/site/content/blog/2022-07-01-whats-new-in-svelte-july-2022.md b/site/content/blog/2022-07-01-whats-new-in-svelte-july-2022.md new file mode 100644 index 0000000000..e8c76a0857 --- /dev/null +++ b/site/content/blog/2022-07-01-whats-new-in-svelte-july-2022.md @@ -0,0 +1,98 @@ +--- +title: "What's new in Svelte: July 2022" +description: "Faster SSR, language tools improvements and a new paid contributor!" +author: Daniel Sandoval +authorURL: https://desandoval.net +--- + +From faster SSR to support for Vitest and Storybook in SvelteKit, there's a lot to cover in this month's newsletter... + +So let's dive in! + +## OpenCollective funding drives Svelte forward + +Svelte supporters have donated approximately $80,000 to [the project on OpenCollective](https://opencollective.com/svelte). We're happy to share that the funds are being drawn on to move Svelte forward in a meaningful way. **[@gtm-nayan](https://github.com/gtm-nayan)** has begun triaging and fixing SvelteKit issues this past month as a paid contributor to the project to help us get SvelteKit to a 1.0 level of stability! @gtm-nayan has been an active member of the Svelte community for quite some time and is well known for writing the bot that helps keep our Discord server running. We're happy that this funding has allowed Svelte to get much more of his time. + +We will also be utilizing OpenCollective funds to allow Svelte core maintainers to attend [Svelte Summit](https://www.sveltesummit.com/) in person this fall. Thanks to everyone who has donated so far! + +## What's new in Svelte & Language Tools +- [learn.svelte.dev](https://learn.svelte.dev/) is a new way to learn Svelte and SvelteKit from the ground up that is currently in development +- Faster SSR is coming in the next Svelte release. A PR two years in the making, resulting in up to 3x faster rendering in some benchmarking tests! ([PR](https://github.com/sveltejs/svelte/pull/5701)) +- "Find File References" ([0.14.28](https://github.com/sveltejs/language-tools/releases/tag/language-server-0.14.28)) and "Find Component References" ([0.14.29](https://github.com/sveltejs/language-tools/releases/tag/language-server-0.14.29)) in the latest versions of the Svelte extension shows where Svelte files and components have been imported and used ([Demo](https://twitter.com/dummdidumm_/status/1532459709604716544/photo/1)) +- The Svelte extension now supports CSS path completion ([0.14.29](https://github.com/sveltejs/language-tools/releases/tag/language-server-0.14.29)) + + +## What's new in SvelteKit +- Introduced `@sveltejs/kit/experimental/vite` which allows SvelteKit to interoperate with other tools in the Vite ecosystem like Vitest and Storybook ([#5094](https://github.com/sveltejs/kit/pull/5094)). Please [leave feedback](https://github.com/sveltejs/kit/issues/5184) as to whether the feature works and is helpful as we consider taking it out of experimental and making `vite.config.js` required for all users +- Streaming in endpoints is now supported ([#3419](https://github.com/sveltejs/kit/issues/3419)). This was enabled by switching to the Undici `fetch` implementation ([#5117](https://github.com/sveltejs/kit/pull/5117)) +- Static assets can now be symlinked in development environments ([#5089](https://github.com/sveltejs/kit/pull/5089)) +- `server` and `prod` environment variables are now available as a correlary to `browser` and `dev` ([#5251](https://github.com/sveltejs/kit/pull/5251)) + +--- + +## Community Showcase + +**Apps & Sites built with Svelte** +- [Virtual Maker](https://www.virtualmaker.net/) lets you make interactive 3D and VR scenes in your browser +- [Apple Beta Music](https://www.reddit.com/r/sveltejs/comments/v7ic2s/apple_beta_music_uses_svelte/) appears to have been written in some combination of Svelte and web components +- [Itatiaia](https://www.itatiaia.com.br/), the largest radio station in the country of Brazil just relaunched its news portal in SvelteKit +- [Pronauns](https://www.pronauns.com) helps you learn pronunciation online with IPA to speak better and sound more native +- [Immich](https://www.immich.app/) is an open source, high performance self-hosted backup solution for videos and photos on your mobile phone +- [Pendek](https://github.com/leovoon/link-shortener) is a link shortener built with SvelteKit, Prisma and PlanetScale +- [Grunfy](https://grunfy.com/tools) is a set of guitar tools - recently migrated to SvelteKit +- [Radiant: The Future of Radio](https://play.google.com/store/apps/details?id=co.broadcastapp.Radiant) is a personal radio station app built with Svelte and Capacitor +- [Imperfect Reminders](https://imperfectreminders.mildlyupset.com/) is a todo list for things that are only sort of time sensitive +- [Periodic Table](https://github.com/janosh/periodic-table) is a dynamic Periodic Table component written in Svelte +- [Svelvet](https://github.com/open-source-labs/Svelvet) is a lightweight Svelte component library for building interactive node-based diagrams +- [publint](https://github.com/bluwy/publint) lints for packaging errors to ensure compatibility across environments +- [Playlistr](https://github.com/alextana/spotify-playlist-creator) helps manage and create Spotify playlists +- [Geoff Rich's page transitions demo](https://twitter.com/geoffrich_/status/1534980702785003520) shows how SvelteKit's `beforeNavigate`/`afterNavigate` hooks can make smooth document transitions in the latest Chrome Canary +- [Menger Sponge](https://twitter.com/a_warnes/status/1536215896078811137) is a fractal built with Threlte + +Want to contribute to a site using the latest SvelteKit features? [Help build the Svelte Society site](https://github.com/svelte-society/sveltesociety.dev/issues)! + + +**Learning Resources** + +_Starring the Svelte team_ +- [Svelte Origins: A JavaScript Documentary](https://www.youtube.com/watch?v=kMlkCYL9qo0) by OfferZen Origins +- [Full Stack Documentation (announcing learn.svelte.dev)](https://portal.gitnation.org/contents/full-stack-documentation) by Rich Harris @ JSNation 2022 +- [All About the Sirens](https://www.svelteradio.com/episodes/all-about-the-sirens) by Svelte Radio + +_To Watch_ +- [SvelteKit Page Endpoints](https://www.youtube.com/watch?v=yQRf2wmTu5w), [Named Layouts](https://www.youtube.com/watch?v=UHX9TJ0BxZY) and [Passing data from page component to layout component with $page.stuff](https://www.youtube.com/watch?v=CXaCstU5pcw) by lihautan +- [๐Ÿž & ๐Ÿงˆ: Magically load data with SvelteKit Endpoints](https://www.youtube.com/watch?v=f6prqYlbTE4) by Johnny Magrippis +- [Svelte for React developers](https://www.youtube.com/watch?v=7tsrwrx5HtQ) by frontendtier +- [Learn Svelte JS || Javascript Compiler for Building Front end Applications](https://www.youtube.com/watch?v=1rKRarJJFrY&list=PLIGDNOJWiL1-7zCgdR7MKuho-tPC6Ra6C&index=1) by Code with tsksharma +- [SvelteKit Authentication](https://www.youtube.com/watch?v=T935Ya4W5X0&list=PLA9WiRZ-IS_zKrDzhOhV5RGKKTHNIyTDO&index=1) by Joy of Code +- [Svelte + websockets: Build a real-time Auction app](https://www.youtube.com/watch?v=CqgsWFrwQIU) by Evgeny Maksimov + +_To Read_ +- [Up-To-Date Analytics on a Static Website](https://paullj.github.io/posts/up-to-date-analytics-on-a-static-website) and [Fast, Lightweight Fuzzy Search using Fuse.js](https://paullj.github.io/posts/fast-lightweight-fuzzy-search-using-fuse.js) by paullj +- [Use SvelteKit as a handler in the ExpressJs project](https://chientrm.medium.com/use-sveltekit-as-a-handler-in-the-expressjs-project-15524b01128f) by Tran Chien +- [Creating a desktop application with Tauri and SvelteKit](https://github.com/Stijn-B/tauri-sveltekit-example) by Stijn-B +- [List of awesome Svelte stores](https://github.com/samuba/awesome-svelte-stores) by samuba +- [SvelteKit Content Security Policy: CSP for XSS Protection](https://rodneylab.com/sveltekit-content-security-policy/) by Rodney Lab +- [SvelteKit Hooks. Everything You Need To Know](https://kudadam.com/blog/understanding-sveltekit-hooks) by Lucretius K. Biah +- [3 tips for upgrading the performance of your Svelte stores](https://www.mathiaspicker.com/posts/3-tips-for-upgrading-the-performance-of-your-svelte-stores) by Mathias Picker + + +**Libraries, Tools & Components** +- [Svend3r](https://github.com/oslabs-beta/svend3r) is a plug and play D3 charting library for Svelte +- [Svelte Hover Draw SVG](https://github.com/davipon/svelte-hover-draw-svg) is a lightweight Svelte component to draw SVG on hover +- [Svelte French Toast](https://svelte-french-toast.com/) provides buttery smooth toast notifications that are lightweight, customizable, and beautiful by default +- [SVooltip](https://svooltip.vercel.app/) is a basic Svelte tooltip directive, powered by Floating UI +- [Svelte Brick Gallery](https://github.com/anotherempty/svelte-brick-gallery) is a masonry-like image gallery component for Svelte +- [use-vest](https://github.com/enyo/use-vest) is a Svelte action for Vest - a library that makes it easy to validate forms and show errors when necessary +- [Svelidate](https://github.com/svelidate/svelidate) is a simple and lightweight form validation library for Svelte with no dependencies +- [Svve11](https://github.com/oslabs-beta/Svve11) is an "accessbility-first" component library for Svelte +- [Slidy](https://github.com/Valexr/Slidy) is a simple, configurable & reusable carousel sliding action script with templates & some useful plugins +- [Svelte Component Snippets](https://marketplace.visualstudio.com/items?itemName=brysonbw.svelte-component-snippets) is a VS Code extension with access to common Svelte snippets +- [Svelte Confetti](https://github.com/Mitcheljager/svelte-confetti) adds a little bit of flair to your app with some confetti ๐ŸŽŠ + + +What did we miss? Let us know on [Reddit](https://www.reddit.com/r/sveltejs/) or [Discord](https://discord.com/invite/yy75DKs) to add your voice. + +Don't forget that you can also join us in-person at the Svelte Summit in Stockholm! Come join us for two days of awesome Svelte content! [Get your tickets now](https://www.sveltesummit.com/). + +See y'all next month! From 02f60fbebf7cdb036472d1aec8dc9d9f8215cd7a Mon Sep 17 00:00:00 2001 From: qinmu Date: Mon, 4 Jul 2022 09:45:39 +0800 Subject: [PATCH 13/89] [fix]destroy empty component (#7492) * fix: destroy non-fragment element such as empty components * fix: fragment property of Empty Component is set as true in dev mode, inconsistent with production mode * chore: revert 'removal' of component.compile_options.dev * feat: add test for destroying empty component * chore: update typechecking callback * chore: revert fragment dev checks * chore: remove unnecessary comment * chore: update test for empty-component-destroy * fix: revert back the patching of console.log * use before_test and after_test Co-authored-by: qinmu Co-authored-by: tanhauhau --- src/compiler/compile/render_dom/index.ts | 2 +- src/runtime/internal/transitions.ts | 4 ++- .../empty-component-destroy/Empty.svelte | 8 ++++++ .../empty-component-destroy/_config.js | 25 +++++++++++++++++++ .../empty-component-destroy/main.svelte | 8 ++++++ 5 files changed, 45 insertions(+), 2 deletions(-) create mode 100644 test/runtime/samples/empty-component-destroy/Empty.svelte create mode 100644 test/runtime/samples/empty-component-destroy/_config.js create mode 100644 test/runtime/samples/empty-component-destroy/main.svelte diff --git a/src/compiler/compile/render_dom/index.ts b/src/compiler/compile/render_dom/index.ts index 9d9699bdbf..5fdac9bce4 100644 --- a/src/compiler/compile/render_dom/index.ts +++ b/src/compiler/compile/render_dom/index.ts @@ -333,7 +333,7 @@ export default function dom( // $$props arg is still needed for unknown prop check args.push(x`$$props`); } - + // has_create_fragment is intentionally to be true in dev mode. const has_create_fragment = component.compile_options.dev || block.has_content(); if (has_create_fragment) { body.push(b` diff --git a/src/runtime/internal/transitions.ts b/src/runtime/internal/transitions.ts index a0134668ef..306a5e3793 100644 --- a/src/runtime/internal/transitions.ts +++ b/src/runtime/internal/transitions.ts @@ -79,6 +79,8 @@ export function transition_out(block: Fragment, local: 0 | 1, detach?: 0 | 1, ca }); block.o(local); + } else if (callback) { + callback(); } } @@ -143,7 +145,7 @@ export function create_in_transition(node: Element & ElementCSSInlineStyle, fn: return { start() { if (started) return; - + started = true; delete_rule(node); diff --git a/test/runtime/samples/empty-component-destroy/Empty.svelte b/test/runtime/samples/empty-component-destroy/Empty.svelte new file mode 100644 index 0000000000..14551c069a --- /dev/null +++ b/test/runtime/samples/empty-component-destroy/Empty.svelte @@ -0,0 +1,8 @@ + + diff --git a/test/runtime/samples/empty-component-destroy/_config.js b/test/runtime/samples/empty-component-destroy/_config.js new file mode 100644 index 0000000000..76b9ae4bb8 --- /dev/null +++ b/test/runtime/samples/empty-component-destroy/_config.js @@ -0,0 +1,25 @@ +let log; +export default { + html: ` + + `, + + before_test() { + log = console.log; + }, + after_test() { + console.log = log; + }, + + async test({ assert, target, window }) { + const button = target.querySelector('button'); + const event = new window.MouseEvent('click'); + const messages = []; + console.log = msg => messages.push(msg); + await button.dispatchEvent(event); + assert.htmlEqual(target.innerHTML, ` + + `); + assert.deepEqual(messages, ['destroy']); + } +}; diff --git a/test/runtime/samples/empty-component-destroy/main.svelte b/test/runtime/samples/empty-component-destroy/main.svelte new file mode 100644 index 0000000000..0ee5ef4a04 --- /dev/null +++ b/test/runtime/samples/empty-component-destroy/main.svelte @@ -0,0 +1,8 @@ + + + + + From 4583b170842208bcafcbb095221c8ac12689f739 Mon Sep 17 00:00:00 2001 From: Tan Li Hau Date: Mon, 4 Jul 2022 09:48:12 +0800 Subject: [PATCH 14/89] Update CHANGELOG.md --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index b5bc4858d8..4dbdb0bd5e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,7 @@ * Fix `class:` directive updates with `` ([#7521](https://github.com/sveltejs/svelte/issues/7521), [#7571](https://github.com/sveltejs/svelte/issues/7571)) * Harden attribute escaping during ssr ([#7530](https://github.com/sveltejs/svelte/pull/7530)) * Add `ComponentType` and `ComponentProps` convenience types ([#6770](https://github.com/sveltejs/svelte/pull/6770)) +* Fix empty component not properly destroyed ([#7488](https://github.com/sveltejs/svelte/issues/7488)) ## 3.48.0 From 7e1691cd62df0593882480d00eb7e9a7616bb029 Mon Sep 17 00:00:00 2001 From: kindoflew Date: Mon, 4 Jul 2022 10:55:34 -0400 Subject: [PATCH 15/89] [fix] support @layer (#7514) * add test * add layer to apply check --- src/compiler/compile/css/Stylesheet.ts | 2 +- test/css/samples/at-layer/expected.css | 1 + test/css/samples/at-layer/input.svelte | 17 +++++++++++++++++ 3 files changed, 19 insertions(+), 1 deletion(-) create mode 100644 test/css/samples/at-layer/expected.css create mode 100644 test/css/samples/at-layer/input.svelte diff --git a/src/compiler/compile/css/Stylesheet.ts b/src/compiler/compile/css/Stylesheet.ts index 0a3098db6d..1a9ea7feeb 100644 --- a/src/compiler/compile/css/Stylesheet.ts +++ b/src/compiler/compile/css/Stylesheet.ts @@ -170,7 +170,7 @@ class Atrule { } apply(node: Element) { - if (this.node.name === 'media' || this.node.name === 'supports') { + if (this.node.name === 'media' || this.node.name === 'supports' || this.node.name === 'layer') { this.children.forEach(child => { child.apply(node); }); diff --git a/test/css/samples/at-layer/expected.css b/test/css/samples/at-layer/expected.css new file mode 100644 index 0000000000..e5f3de80c9 --- /dev/null +++ b/test/css/samples/at-layer/expected.css @@ -0,0 +1 @@ +@layer base, special;@layer special{div.svelte-xyz{color:rebeccapurple}}@layer base{div.svelte-xyz{color:green}} \ No newline at end of file diff --git a/test/css/samples/at-layer/input.svelte b/test/css/samples/at-layer/input.svelte new file mode 100644 index 0000000000..60289e1e5f --- /dev/null +++ b/test/css/samples/at-layer/input.svelte @@ -0,0 +1,17 @@ +
hello
+ + From a3ecb44b5346dbf116c5bec5dcf47cd7f459784d Mon Sep 17 00:00:00 2001 From: Yuichiro Yamashita Date: Mon, 4 Jul 2022 23:58:16 +0900 Subject: [PATCH 16/89] update changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4dbdb0bd5e..5e48244f4a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,7 @@ * Harden attribute escaping during ssr ([#7530](https://github.com/sveltejs/svelte/pull/7530)) * Add `ComponentType` and `ComponentProps` convenience types ([#6770](https://github.com/sveltejs/svelte/pull/6770)) * Fix empty component not properly destroyed ([#7488](https://github.com/sveltejs/svelte/issues/7488)) +* Add CSS at-rule `@layer` support ([#7504](https://github.com/sveltejs/svelte/issues/7504)) ## 3.48.0 From 0fa0a38d5168a1767843fdb0a43c00aa30b8670f Mon Sep 17 00:00:00 2001 From: Simon H <5968653+dummdidumm@users.noreply.github.com> Date: Wed, 6 Jul 2022 11:58:43 +0200 Subject: [PATCH 17/89] [fix] export CompileOptions (#7658) It's used by SvelteKit and in order to properly use it under the new TS moduleResolution NodeNext it needs to be part of a file that is defined in the exports map --- generate-type-definitions.js | 19 +++++++++++++++---- src/compiler/index.ts | 1 + src/runtime/index.ts | 2 +- 3 files changed, 17 insertions(+), 5 deletions(-) diff --git a/generate-type-definitions.js b/generate-type-definitions.js index 6cad31807f..00b079eb5d 100644 --- a/generate-type-definitions.js +++ b/generate-type-definitions.js @@ -5,9 +5,20 @@ const { readFileSync, writeFileSync } = require('fs'); execSync('tsc -p src/compiler --emitDeclarationOnly && tsc -p src/runtime --emitDeclarationOnly'); -// We need to add these types to the index.d.ts here because if we add them before building, the build will fail, +// We need to add these types to the .d.ts files here because if we add them before building, the build will fail, // because the TS->JS transformation doesn't know these exports are types and produces code that fails at runtime. // We can't use `export type` syntax either because the TS version we're on doesn't have this feature yet. -const path = 'types/runtime/index.d.ts'; -const content = readFileSync(path, 'utf8'); -writeFileSync(path, content.replace('SvelteComponentTyped', 'SvelteComponentTyped, ComponentType, ComponentConstructorOptions, ComponentProps')); + +function modify(path, modifyFn) { + const content = readFileSync(path, 'utf8'); + writeFileSync(path, modifyFn(content)); +} + +modify( + 'types/runtime/index.d.ts', + content => content.replace('SvelteComponentTyped', 'SvelteComponentTyped, ComponentType, ComponentConstructorOptions, ComponentProps') +); +modify( + 'types/compiler/index.d.ts', + content => content + '\nexport { CompileOptions, ModuleFormat, EnableSourcemap, CssHashGetter } from "./interfaces"' +); diff --git a/src/compiler/index.ts b/src/compiler/index.ts index 14d55f5470..76eb45d37f 100644 --- a/src/compiler/index.ts +++ b/src/compiler/index.ts @@ -4,3 +4,4 @@ export { default as preprocess } from './preprocess/index'; export { walk } from 'estree-walker'; export const VERSION = '__VERSION__'; +// additional exports added through generate-type-definitions.js diff --git a/src/runtime/index.ts b/src/runtime/index.ts index 08b25ba2ca..2029f67a04 100644 --- a/src/runtime/index.ts +++ b/src/runtime/index.ts @@ -13,5 +13,5 @@ export { createEventDispatcher, SvelteComponentDev as SvelteComponent, SvelteComponentTyped - // additional exports added through post-typegen.js + // additional exports added through generate-type-definitions.js } from 'svelte/internal'; From 3798808e7484b7eeee6acb2860c45bb2e59d84bd Mon Sep 17 00:00:00 2001 From: Simon H <5968653+dummdidumm@users.noreply.github.com> Date: Wed, 6 Jul 2022 11:59:44 +0200 Subject: [PATCH 18/89] update changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5e48244f4a..0beea49892 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,7 @@ * Add `ComponentType` and `ComponentProps` convenience types ([#6770](https://github.com/sveltejs/svelte/pull/6770)) * Fix empty component not properly destroyed ([#7488](https://github.com/sveltejs/svelte/issues/7488)) * Add CSS at-rule `@layer` support ([#7504](https://github.com/sveltejs/svelte/issues/7504)) +* Export `CompileOptions` from `svelte/compiler` ([#7658](https://github.com/sveltejs/svelte/pull/7658)) ## 3.48.0 From 52153dbce0237f0c36e4ff36377398d7f95276ef Mon Sep 17 00:00:00 2001 From: Conduitry Date: Thu, 7 Jul 2022 12:43:08 -0400 Subject: [PATCH 19/89] -> v3.49.0 --- CHANGELOG.md | 12 ++++++------ package-lock.json | 4 ++-- package.json | 2 +- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0beea49892..70c05b01e9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,14 +1,14 @@ # Svelte changelog -## Unreleased +## 3.49.0 -* Faster SSR ([#5701](https://github.com/sveltejs/svelte/pull/5701)) -* Fix `class:` directive updates with `` ([#7521](https://github.com/sveltejs/svelte/issues/7521), [#7571](https://github.com/sveltejs/svelte/issues/7571)) -* Harden attribute escaping during ssr ([#7530](https://github.com/sveltejs/svelte/pull/7530)) +* Improve performance of string escaping during SSR ([#5701](https://github.com/sveltejs/svelte/pull/5701)) * Add `ComponentType` and `ComponentProps` convenience types ([#6770](https://github.com/sveltejs/svelte/pull/6770)) -* Fix empty component not properly destroyed ([#7488](https://github.com/sveltejs/svelte/issues/7488)) -* Add CSS at-rule `@layer` support ([#7504](https://github.com/sveltejs/svelte/issues/7504)) +* Add support for CSS `@layer` ([#7504](https://github.com/sveltejs/svelte/issues/7504)) * Export `CompileOptions` from `svelte/compiler` ([#7658](https://github.com/sveltejs/svelte/pull/7658)) +* Fix DOM-less components not being properly destroyed ([#7488](https://github.com/sveltejs/svelte/issues/7488)) +* Fix `class:` directive updates with `` ([#7521](https://github.com/sveltejs/svelte/issues/7521), [#7571](https://github.com/sveltejs/svelte/issues/7571)) +* Harden attribute escaping during SSR ([#7530](https://github.com/sveltejs/svelte/pull/7530)) ## 3.48.0 diff --git a/package-lock.json b/package-lock.json index 83d963b827..38abdfc330 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "svelte", - "version": "3.48.0", + "version": "3.49.0", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "svelte", - "version": "3.48.0", + "version": "3.49.0", "license": "MIT", "devDependencies": { "@ampproject/remapping": "^0.3.0", diff --git a/package.json b/package.json index a1c9ae9a5d..de712b9bab 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "svelte", - "version": "3.48.0", + "version": "3.49.0", "description": "Cybernetically enhanced web apps", "module": "index.mjs", "main": "index", From c01dc62314ccdff556ddd0c948dad2cb9128101d Mon Sep 17 00:00:00 2001 From: Sepehr Safari Date: Sun, 10 Jul 2022 11:52:00 +0430 Subject: [PATCH 20/89] [docs] fix typo (#7672) * [docs] fix typo Fixed "quckly" to "quickly" * [docs] fix typo Fixed "beend" to "been". * [docs] fix typo Fixed "propsoal" to "proposal". --- .../blog/2021-08-01-whats-new-in-svelte-august-2021.md | 2 +- .../blog/2021-10-01-whats-new-in-svelte-october-2021.md | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/site/content/blog/2021-08-01-whats-new-in-svelte-august-2021.md b/site/content/blog/2021-08-01-whats-new-in-svelte-august-2021.md index 0dd54ca22f..145d3aa784 100644 --- a/site/content/blog/2021-08-01-whats-new-in-svelte-august-2021.md +++ b/site/content/blog/2021-08-01-whats-new-in-svelte-august-2021.md @@ -59,7 +59,7 @@ To see all updates to SvelteKit, check out the [SvelteKit changelog](https://git - [Svelte-Capacitor](https://github.com/drannex42/svelte-capacitor/) just released v2.0.0 - making it even easier to build hybrid mobile apps for iOS and Android using Svelte and Capacitor with near native performance. - [svelte-remixicon](https://github.com/ABarnob/svelte-remixicon) is an icon library for Svelte based on Remix Icon, consisting of more than 2000 icons. - [SveltePress](https://github.com/GeopJr/SveltePress) is a documentation tool built on top of SvelteKit. -- [Svelte Starter Kit](https://github.com/one-aalam/svelte-starter-kit/tree/auth-supabase) is a boilerplate to quckly get up and running with Svelte, with Auth and User Profiles powered by Supabase. +- [Svelte Starter Kit](https://github.com/one-aalam/svelte-starter-kit/tree/auth-supabase) is a boilerplate to quickly get up and running with Svelte, with Auth and User Profiles powered by Supabase. - [Kahi UI](https://github.com/novacbn/kahi-ui) is a Svelte-first UI kit with Dark Mode built-in. - [typesafe-i18n](https://github.com/ivanhofer/typesafe-i18n) is an opinionated, fully type-safe, lightweight localization library for TypeScript and JavaScript projects with no external dependencies. diff --git a/site/content/blog/2021-10-01-whats-new-in-svelte-october-2021.md b/site/content/blog/2021-10-01-whats-new-in-svelte-october-2021.md index 5ffd65bb0a..4b5b65d6f0 100644 --- a/site/content/blog/2021-10-01-whats-new-in-svelte-october-2021.md +++ b/site/content/blog/2021-10-01-whats-new-in-svelte-october-2021.md @@ -33,7 +33,7 @@ Notable SvelteKit improvements this month include... - Svelte libraries should now work out-of-the-box without any Vite configuration ([#2343](https://github.com/sveltejs/kit/pull/2343)) - Improvements to package exports field ([#2345](https://github.com/sveltejs/kit/pull/2345) and [#2327](https://github.com/sveltejs/kit/pull/2327)) - [breaking] The `prerender.pages` config option has been renamed to `prerender.entries` ([#2380](https://github.com/sveltejs/kit/pull/2380)) -- A new generic argument has beend added to allow typing Body from hooks ([#2413](https://github.com/sveltejs/kit/pull/2413)) +- A new generic argument has been added to allow typing Body from hooks ([#2413](https://github.com/sveltejs/kit/pull/2413)) - The `svelte` field will be added to package.json when running the package command ([#2431](https://github.com/sveltejs/kit/pull/2431)) - [breaking] The `context` parameter of the load function was renamed to `stuff` ([#2439](https://github.com/sveltejs/kit/pull/2439)) - Added an `entryPoint` option for building a custom server with `adapter-node` ([#2414](https://github.com/sveltejs/kit/pull/2414)) @@ -92,7 +92,7 @@ Check out the community site [sveltesociety.dev](https://sveltesociety.dev/templ ## Before you go, answer the call for speakers! -Svelte Summit Fall 2021 (happening 20 November 2021) is looking for speakers. Submit your talk propsoal before 30 October... all are welcome to present and attend. +Svelte Summit Fall 2021 (happening 20 November 2021) is looking for speakers. Submit your talk proposal before 30 October... all are welcome to present and attend. ### More info on the [sessionize site](https://sessionize.com/svelte-summit-fall-2021/) From 1d19aebe38bed7bbaafdc304eb055f5bf455fb36 Mon Sep 17 00:00:00 2001 From: Mel Date: Sun, 10 Jul 2022 20:23:41 +0200 Subject: [PATCH 21/89] a11y: Add role-has-required-aria-props rule (#5852) * Check required props for ARIA roles * Test required ARIA props check * Properly indent with tabs in test * swtich to use aria-query * fix validation test * update docs Co-authored-by: tanhauhau --- package-lock.json | 29 + package.json | 2 + .../content/docs/05-accessibility-warnings.md | 11 + src/compiler/compile/compiler_warnings.ts | 4 + src/compiler/compile/nodes/Element.ts | 16 +- .../a11y-no-redundant-roles/warnings.json | 1367 +++++++++-------- .../input.svelte | 9 + .../warnings.json | 62 + 8 files changed, 867 insertions(+), 633 deletions(-) create mode 100644 test/validator/samples/a11y-role-has-required-aria-props/input.svelte create mode 100644 test/validator/samples/a11y-role-has-required-aria-props/warnings.json diff --git a/package-lock.json b/package-lock.json index 38abdfc330..ab4b20ed59 100644 --- a/package-lock.json +++ b/package-lock.json @@ -18,12 +18,14 @@ "@rollup/plugin-typescript": "^2.0.1", "@rollup/plugin-virtual": "^2.0.0", "@sveltejs/eslint-config": "github:sveltejs/eslint-config#v5.8.0", + "@types/aria-query": "^5.0.0", "@types/mocha": "^7.0.0", "@types/node": "^8.10.53", "@typescript-eslint/eslint-plugin": "^5.22.0", "@typescript-eslint/parser": "^5.22.0", "acorn": "^8.4.1", "agadoo": "^1.1.0", + "aria-query": "^5.0.0", "code-red": "^0.2.5", "css-tree": "^1.1.2", "eslint": "^8.0.0", @@ -285,6 +287,12 @@ "resolved": "git+ssh://git@github.com/sveltejs/eslint-config.git#31fd4faeea88990069502460b023698b1c9c2d13", "dev": true }, + "node_modules/@types/aria-query": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/@types/aria-query/-/aria-query-5.0.0.tgz", + "integrity": "sha512-P+dkdFu0n08PDIvw+9nT9ByQnd+Udc8DaWPb9HKfaPwCvWvQpC5XaMRx2xLWECm9x1VKNps6vEAlirjA6+uNrQ==", + "dev": true + }, "node_modules/@types/estree": { "version": "0.0.50", "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.50.tgz", @@ -698,6 +706,15 @@ "sprintf-js": "~1.0.2" } }, + "node_modules/aria-query": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.0.0.tgz", + "integrity": "sha512-V+SM7AbUwJ+EBnB8+DXs0hPZHO0W6pqBcc0dW90OwtVG02PswOu/teuARoLQjdDOH+t9pJgGnW5/Qmouf3gPJg==", + "dev": true, + "engines": { + "node": ">=6.0" + } + }, "node_modules/array-equal": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/array-equal/-/array-equal-1.0.0.tgz", @@ -4927,6 +4944,12 @@ "dev": true, "from": "@sveltejs/eslint-config@github:sveltejs/eslint-config#v5.8.0" }, + "@types/aria-query": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/@types/aria-query/-/aria-query-5.0.0.tgz", + "integrity": "sha512-P+dkdFu0n08PDIvw+9nT9ByQnd+Udc8DaWPb9HKfaPwCvWvQpC5XaMRx2xLWECm9x1VKNps6vEAlirjA6+uNrQ==", + "dev": true + }, "@types/estree": { "version": "0.0.50", "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.50.tgz", @@ -5208,6 +5231,12 @@ "sprintf-js": "~1.0.2" } }, + "aria-query": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.0.0.tgz", + "integrity": "sha512-V+SM7AbUwJ+EBnB8+DXs0hPZHO0W6pqBcc0dW90OwtVG02PswOu/teuARoLQjdDOH+t9pJgGnW5/Qmouf3gPJg==", + "dev": true + }, "array-equal": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/array-equal/-/array-equal-1.0.0.tgz", diff --git a/package.json b/package.json index de712b9bab..ade713f4e3 100644 --- a/package.json +++ b/package.json @@ -124,12 +124,14 @@ "@rollup/plugin-typescript": "^2.0.1", "@rollup/plugin-virtual": "^2.0.0", "@sveltejs/eslint-config": "github:sveltejs/eslint-config#v5.8.0", + "@types/aria-query": "^5.0.0", "@types/mocha": "^7.0.0", "@types/node": "^8.10.53", "@typescript-eslint/eslint-plugin": "^5.22.0", "@typescript-eslint/parser": "^5.22.0", "acorn": "^8.4.1", "agadoo": "^1.1.0", + "aria-query": "^5.0.0", "code-red": "^0.2.5", "css-tree": "^1.1.2", "eslint": "^8.0.0", diff --git a/site/content/docs/05-accessibility-warnings.md b/site/content/docs/05-accessibility-warnings.md index b39b06f9ff..9d0835b443 100644 --- a/site/content/docs/05-accessibility-warnings.md +++ b/site/content/docs/05-accessibility-warnings.md @@ -54,6 +54,17 @@ The following elements are visually distracting: `` and ``. --- +### `role-has-required-aria-props` + +Elements with ARIA roles must have all required attributes for that role. + +```sv + + +``` + +--- + ### `a11y-hidden` Certain DOM elements are useful for screen reader navigation and should not be hidden. diff --git a/src/compiler/compile/compiler_warnings.ts b/src/compiler/compile/compiler_warnings.ts index 86ec98cb8b..833722c3b9 100644 --- a/src/compiler/compile/compiler_warnings.ts +++ b/src/compiler/compile/compiler_warnings.ts @@ -80,6 +80,10 @@ export default { code: 'a11y-no-redundant-roles', message: `A11y: Redundant role '${role}'` }), + a11y_role_has_required_aria_props: (role: string, props: string[]) => ({ + code: 'a11y-role-has-required-aria-props', + message: `A11y: Elements with the ARIA role "${role}" must have the following attributes defined: ${props.map(name => `"${name}"`).join(', ')}` + }), a11y_accesskey: { code: 'a11y-accesskey', message: 'A11y: Avoid using accesskey' diff --git a/src/compiler/compile/nodes/Element.ts b/src/compiler/compile/nodes/Element.ts index 735562d627..35131cefcf 100644 --- a/src/compiler/compile/nodes/Element.ts +++ b/src/compiler/compile/nodes/Element.ts @@ -23,6 +23,7 @@ import { string_literal } from '../utils/stringify'; import { Literal } from 'estree'; import compiler_warnings from '../compiler_warnings'; import compiler_errors from '../compiler_errors'; +import { ARIARoleDefintionKey, roles } from 'aria-query'; const svg = /^(?:altGlyph|altGlyphDef|altGlyphItem|animate|animateColor|animateMotion|animateTransform|circle|clipPath|color-profile|cursor|defs|desc|discard|ellipse|feBlend|feColorMatrix|feComponentTransfer|feComposite|feConvolveMatrix|feDiffuseLighting|feDisplacementMap|feDistantLight|feDropShadow|feFlood|feFuncA|feFuncB|feFuncG|feFuncR|feGaussianBlur|feImage|feMerge|feMergeNode|feMorphology|feOffset|fePointLight|feSpecularLighting|feSpotLight|feTile|feTurbulence|filter|font|font-face|font-face-format|font-face-name|font-face-src|font-face-uri|foreignObject|g|glyph|glyphRef|hatch|hatchpath|hkern|image|line|linearGradient|marker|mask|mesh|meshgradient|meshpatch|meshrow|metadata|missing-glyph|mpath|path|pattern|polygon|polyline|radialGradient|rect|set|solidcolor|stop|svg|switch|symbol|text|textPath|tref|tspan|unknown|use|view|vkern)$/; @@ -407,9 +408,9 @@ export default class Element extends Node { } validate_attributes_a11y() { - const { component } = this; + const { component, attributes } = this; - this.attributes.forEach(attribute => { + attributes.forEach(attribute => { if (attribute.is_spread) return; const name = attribute.name.toLowerCase(); @@ -462,6 +463,17 @@ export default class Element extends Node { component.warn(attribute, compiler_warnings.a11y_no_redundant_roles(value)); } } + + // role-has-required-aria-props + const role = roles.get(value as ARIARoleDefintionKey); + if (role) { + const required_role_props = Object.keys(role.requiredProps); + const has_missing_props = required_role_props.some(prop => !attributes.find(a => a.name === prop)); + + if (has_missing_props) { + component.warn(attribute, compiler_warnings.a11y_role_has_required_aria_props(value as string, required_role_props)); + } + } } // no-access-key diff --git a/test/validator/samples/a11y-no-redundant-roles/warnings.json b/test/validator/samples/a11y-no-redundant-roles/warnings.json index 8aa3520b32..0947a467af 100644 --- a/test/validator/samples/a11y-no-redundant-roles/warnings.json +++ b/test/validator/samples/a11y-no-redundant-roles/warnings.json @@ -1,632 +1,737 @@ [ - { - "code": "a11y-no-redundant-roles", - "end": { - "character": 23, - "column": 23, - "line": 1 - }, - "message": "A11y: Redundant role 'link'", - "pos": 12, - "start": { - "character": 12, - "column": 12, - "line": 1 - } - }, - { - "code": "a11y-no-redundant-roles", - "end": { - "character": 58, - "column": 23, - "line": 2 - }, - "message": "A11y: Redundant role 'article'", - "pos": 44, - "start": { - "character": 44, - "column": 9, - "line": 2 - } - }, - { - "code": "a11y-no-redundant-roles", - "end": { - "character": 89, - "column": 27, - "line": 3 - }, - "message": "A11y: Redundant role 'complementary'", - "pos": 69, - "start": { - "character": 69, - "column": 7, - "line": 3 - } - }, - { - "code": "a11y-no-redundant-roles", - "end": { - "character": 114, - "column": 21, - "line": 4 - }, - "message": "A11y: Redundant role 'document'", - "pos": 99, - "start": { - "character": 99, - "column": 6, - "line": 4 - } - }, - { - "code": "a11y-no-redundant-roles", - "end": { - "character": 139, - "column": 21, - "line": 5 - }, - "message": "A11y: Redundant role 'button'", - "pos": 126, - "start": { - "character": 126, - "column": 8, - "line": 5 - } - }, - { - "code": "a11y-no-redundant-roles", - "end": { - "character": 167, - "column": 24, - "line": 6 - }, - "message": "A11y: Redundant role 'listbox'", - "pos": 153, - "start": { - "character": 153, - "column": 10, - "line": 6 - } - }, - { - "code": "a11y-no-redundant-roles", - "end": { - "character": 192, - "column": 21, - "line": 7 - }, - "message": "A11y: Redundant role 'definition'", - "pos": 175, - "start": { - "character": 175, - "column": 4, - "line": 7 - } - }, - { - "code": "a11y-no-redundant-roles", - "end": { - "character": 212, - "column": 16, - "line": 8 - }, - "message": "A11y: Redundant role 'term'", - "pos": 201, - "start": { - "character": 201, - "column": 5, - "line": 8 - } - }, - { - "code": "a11y-no-redundant-roles", - "end": { - "character": 237, - "column": 21, - "line": 9 - }, - "message": "A11y: Redundant role 'group'", - "pos": 225, - "start": { - "character": 225, - "column": 9, - "line": 9 - } - }, - { - "code": "a11y-no-redundant-roles", - "end": { - "character": 262, - "column": 21, - "line": 10 - }, - "message": "A11y: Redundant role 'dialog'", - "pos": 249, - "start": { - "character": 249, - "column": 8, - "line": 10 - } - }, - { - "code": "a11y-no-redundant-roles", - "end": { - "character": 281, - "column": 15, - "line": 11 - }, - "message": "A11y: Redundant role 'term'", - "pos": 270, - "start": { - "character": 270, - "column": 4, - "line": 11 - } - }, - { - "code": "a11y-no-redundant-roles", - "end": { - "character": 307, - "column": 22, - "line": 12 - }, - "message": "A11y: Redundant role 'group'", - "pos": 295, - "start": { - "character": 295, - "column": 10, - "line": 12 - } - }, - { - "code": "a11y-no-redundant-roles", - "end": { - "character": 332, - "column": 21, - "line": 13 - }, - "message": "A11y: Redundant role 'figure'", - "pos": 319, - "start": { - "character": 319, - "column": 8, - "line": 13 - } - }, - { - "code": "a11y-no-redundant-roles", - "end": { - "character": 353, - "column": 17, - "line": 14 - }, - "message": "A11y: Redundant role 'form'", - "pos": 342, - "start": { - "character": 342, - "column": 6, - "line": 14 - } - }, - { - "code": "a11y-no-redundant-roles", - "end": { - "character": 383, - "column": 18, - "line": 15 - }, - "message": "A11y: Redundant role 'heading'", - "pos": 369, - "start": { - "character": 369, - "column": 4, - "line": 15 - } - }, - { - "code": "a11y-no-redundant-roles", - "end": { - "character": 415, - "column": 18, - "line": 16 - }, - "message": "A11y: Redundant role 'heading'", - "pos": 401, - "start": { - "character": 401, - "column": 4, - "line": 16 - } - }, - { - "code": "a11y-no-redundant-roles", - "end": { - "character": 447, - "column": 18, - "line": 17 - }, - "message": "A11y: Redundant role 'heading'", - "pos": 433, - "start": { - "character": 433, - "column": 4, - "line": 17 - } - }, - { - "code": "a11y-no-redundant-roles", - "end": { - "character": 479, - "column": 18, - "line": 18 - }, - "message": "A11y: Redundant role 'heading'", - "pos": 465, - "start": { - "character": 465, - "column": 4, - "line": 18 - } - }, - { - "code": "a11y-no-redundant-roles", - "end": { - "character": 511, - "column": 18, - "line": 19 - }, - "message": "A11y: Redundant role 'heading'", - "pos": 497, - "start": { - "character": 497, - "column": 4, - "line": 19 - } - }, - { - "code": "a11y-no-redundant-roles", - "end": { - "character": 543, - "column": 18, - "line": 20 - }, - "message": "A11y: Redundant role 'heading'", - "pos": 529, - "start": { - "character": 529, - "column": 4, - "line": 20 - } - }, - { - "code": "a11y-no-redundant-roles", - "end": { - "character": 577, - "column": 20, - "line": 21 - }, - "message": "A11y: Redundant role 'separator'", - "pos": 561, - "start": { - "character": 561, - "column": 4, - "line": 21 - } - }, - { - "code": "a11y-no-redundant-roles", - "end": { - "character": 600, - "column": 19, - "line": 22 - }, - "message": "A11y: Redundant role 'listitem'", - "pos": 585, - "start": { - "character": 585, - "column": 4, - "line": 22 - } - }, - { - "code": "a11y-no-redundant-roles", - "end": { - "character": 621, - "column": 17, - "line": 23 - }, - "message": "A11y: Redundant role 'link'", - "pos": 610, - "start": { - "character": 610, - "column": 6, - "line": 23 - } - }, - { - "code": "a11y-no-redundant-roles", - "end": { - "character": 642, - "column": 17, - "line": 24 - }, - "message": "A11y: Redundant role 'main'", - "pos": 631, - "start": { - "character": 631, - "column": 6, - "line": 24 - } - }, - { - "code": "a11y-no-redundant-roles", - "end": { - "character": 668, - "column": 17, - "line": 25 - }, - "message": "A11y: Redundant role 'list'", - "pos": 657, - "start": { - "character": 657, - "column": 6, - "line": 25 - } - }, - { - "code": "a11y-no-redundant-roles", - "end": { - "character": 694, - "column": 22, - "line": 26 - }, - "message": "A11y: Redundant role 'navigation'", - "pos": 677, - "start": { - "character": 677, - "column": 5, - "line": 26 - } - }, - { - "code": "a11y-no-redundant-roles", - "end": { - "character": 713, - "column": 15, - "line": 27 - }, - "message": "A11y: Redundant role 'list'", - "pos": 702, - "start": { - "character": 702, - "column": 4, - "line": 27 - } - }, - { - "code": "a11y-no-redundant-roles", - "end": { - "character": 739, - "column": 22, - "line": 28 - }, - "message": "A11y: Redundant role 'group'", - "pos": 727, - "start": { - "character": 727, - "column": 10, - "line": 28 - } - }, - { - "code": "a11y-no-redundant-roles", - "end": { - "character": 764, - "column": 21, - "line": 29 - }, - "message": "A11y: Redundant role 'option'", - "pos": 751, - "start": { - "character": 751, - "column": 8, - "line": 29 - } - }, - { - "code": "a11y-no-redundant-roles", - "end": { - "character": 789, - "column": 21, - "line": 30 - }, - "message": "A11y: Redundant role 'status'", - "pos": 776, - "start": { - "character": 776, - "column": 8, - "line": 30 - } - }, - { - "code": "a11y-no-redundant-roles", - "end": { - "character": 821, - "column": 28, - "line": 31 - }, - "message": "A11y: Redundant role 'progressbar'", - "pos": 803, - "start": { - "character": 803, - "column": 10, - "line": 31 - } - }, - { - "code": "a11y-no-redundant-roles", - "end": { - "character": 847, - "column": 22, - "line": 32 - }, - "message": "A11y: Redundant role 'region'", - "pos": 834, - "start": { - "character": 834, - "column": 9, - "line": 32 - } - }, - { - "code": "a11y-no-redundant-roles", - "end": { - "character": 873, - "column": 22, - "line": 33 - }, - "message": "A11y: Redundant role 'button'", - "pos": 860, - "start": { - "character": 860, - "column": 9, - "line": 33 - } - }, - { - "code": "a11y-no-redundant-roles", - "end": { - "character": 896, - "column": 19, - "line": 34 - }, - "message": "A11y: Redundant role 'table'", - "pos": 884, - "start": { - "character": 884, - "column": 7, - "line": 34 - } - }, - { - "code": "a11y-no-redundant-roles", - "end": { - "character": 922, - "column": 22, - "line": 35 - }, - "message": "A11y: Redundant role 'rowgroup'", - "pos": 907, - "start": { - "character": 907, - "column": 7, - "line": 35 - } - }, - { - "code": "a11y-no-redundant-roles", - "end": { - "character": 950, - "column": 24, - "line": 36 - }, - "message": "A11y: Redundant role 'textbox'", - "pos": 936, - "start": { - "character": 936, - "column": 10, - "line": 36 - } - }, - { - "code": "a11y-no-redundant-roles", - "end": { - "character": 976, - "column": 22, - "line": 37 - }, - "message": "A11y: Redundant role 'rowgroup'", - "pos": 961, - "start": { - "character": 961, - "column": 7, - "line": 37 - } - }, - { - "code": "a11y-no-redundant-roles", - "end": { - "character": 1002, - "column": 22, - "line": 38 - }, - "message": "A11y: Redundant role 'rowgroup'", - "pos": 987, - "start": { - "character": 987, - "column": 7, - "line": 38 - } - }, - { - "code": "a11y-no-redundant-roles", - "end": { - "character": 1020, - "column": 14, - "line": 39 - }, - "message": "A11y: Redundant role 'row'", - "pos": 1010, - "start": { - "character": 1010, - "column": 4, - "line": 39 - } - }, - { - "code": "a11y-no-redundant-roles", - "end": { - "character": 1039, - "column": 15, - "line": 40 - }, - "message": "A11y: Redundant role 'list'", - "pos": 1028, - "start": { - "character": 1028, - "column": 4, - "line": 40 - } - }, - { - "code": "a11y-no-redundant-roles", - "end": { - "character": 1125, - "column": 21, - "line": 43 - }, - "message": "A11y: Redundant role 'banner'", - "pos": 1112, - "start": { - "character": 1112, - "column": 8, - "line": 43 - } - }, - { - "code": "a11y-no-redundant-roles", - "end": { - "character": 1162, - "column": 26, - "line": 44 - }, - "message": "A11y: Redundant role 'contentinfo'", - "pos": 1144, - "start": { - "character": 1144, - "column": 8, - "line": 44 - } - } -] \ No newline at end of file + { + "code": "a11y-no-redundant-roles", + "end": { + "character": 23, + "column": 23, + "line": 1 + }, + "message": "A11y: Redundant role 'link'", + "pos": 12, + "start": { + "character": 12, + "column": 12, + "line": 1 + } + }, + { + "code": "a11y-no-redundant-roles", + "end": { + "character": 58, + "column": 23, + "line": 2 + }, + "message": "A11y: Redundant role 'article'", + "pos": 44, + "start": { + "character": 44, + "column": 9, + "line": 2 + } + }, + { + "code": "a11y-no-redundant-roles", + "end": { + "character": 89, + "column": 27, + "line": 3 + }, + "message": "A11y: Redundant role 'complementary'", + "pos": 69, + "start": { + "character": 69, + "column": 7, + "line": 3 + } + }, + { + "code": "a11y-no-redundant-roles", + "end": { + "character": 114, + "column": 21, + "line": 4 + }, + "message": "A11y: Redundant role 'document'", + "pos": 99, + "start": { + "character": 99, + "column": 6, + "line": 4 + } + }, + { + "code": "a11y-no-redundant-roles", + "end": { + "character": 139, + "column": 21, + "line": 5 + }, + "message": "A11y: Redundant role 'button'", + "pos": 126, + "start": { + "character": 126, + "column": 8, + "line": 5 + } + }, + { + "code": "a11y-no-redundant-roles", + "end": { + "character": 167, + "column": 24, + "line": 6 + }, + "message": "A11y: Redundant role 'listbox'", + "pos": 153, + "start": { + "character": 153, + "column": 10, + "line": 6 + } + }, + { + "code": "a11y-no-redundant-roles", + "end": { + "character": 192, + "column": 21, + "line": 7 + }, + "message": "A11y: Redundant role 'definition'", + "pos": 175, + "start": { + "character": 175, + "column": 4, + "line": 7 + } + }, + { + "code": "a11y-no-redundant-roles", + "end": { + "character": 212, + "column": 16, + "line": 8 + }, + "message": "A11y: Redundant role 'term'", + "pos": 201, + "start": { + "character": 201, + "column": 5, + "line": 8 + } + }, + { + "code": "a11y-no-redundant-roles", + "end": { + "character": 237, + "column": 21, + "line": 9 + }, + "message": "A11y: Redundant role 'group'", + "pos": 225, + "start": { + "character": 225, + "column": 9, + "line": 9 + } + }, + { + "code": "a11y-no-redundant-roles", + "end": { + "character": 262, + "column": 21, + "line": 10 + }, + "message": "A11y: Redundant role 'dialog'", + "pos": 249, + "start": { + "character": 249, + "column": 8, + "line": 10 + } + }, + { + "code": "a11y-no-redundant-roles", + "end": { + "character": 281, + "column": 15, + "line": 11 + }, + "message": "A11y: Redundant role 'term'", + "pos": 270, + "start": { + "character": 270, + "column": 4, + "line": 11 + } + }, + { + "code": "a11y-no-redundant-roles", + "end": { + "character": 307, + "column": 22, + "line": 12 + }, + "message": "A11y: Redundant role 'group'", + "pos": 295, + "start": { + "character": 295, + "column": 10, + "line": 12 + } + }, + { + "code": "a11y-no-redundant-roles", + "end": { + "character": 332, + "column": 21, + "line": 13 + }, + "message": "A11y: Redundant role 'figure'", + "pos": 319, + "start": { + "character": 319, + "column": 8, + "line": 13 + } + }, + { + "code": "a11y-no-redundant-roles", + "end": { + "character": 353, + "column": 17, + "line": 14 + }, + "message": "A11y: Redundant role 'form'", + "pos": 342, + "start": { + "character": 342, + "column": 6, + "line": 14 + } + }, + { + "code": "a11y-no-redundant-roles", + "end": { + "character": 383, + "column": 18, + "line": 15 + }, + "message": "A11y: Redundant role 'heading'", + "pos": 369, + "start": { + "character": 369, + "column": 4, + "line": 15 + } + }, + { + "code": "a11y-role-has-required-aria-props", + "end": { + "character": 383, + "column": 18, + "line": 15 + }, + "message": "A11y: Elements with the ARIA role \"heading\" must have the following attributes defined: \"aria-level\"", + "pos": 369, + "start": { + "character": 369, + "column": 4, + "line": 15 + } + }, + { + "code": "a11y-no-redundant-roles", + "end": { + "character": 415, + "column": 18, + "line": 16 + }, + "message": "A11y: Redundant role 'heading'", + "pos": 401, + "start": { + "character": 401, + "column": 4, + "line": 16 + } + }, + { + "code": "a11y-role-has-required-aria-props", + "message": "A11y: Elements with the ARIA role \"heading\" must have the following attributes defined: \"aria-level\"", + "pos": 401, + "start": { + "character": 401, + "column": 4, + "line": 16 + }, + "end": { + "character": 415, + "column": 18, + "line": 16 + } + }, + { + "code": "a11y-no-redundant-roles", + "end": { + "character": 447, + "column": 18, + "line": 17 + }, + "message": "A11y: Redundant role 'heading'", + "pos": 433, + "start": { + "character": 433, + "column": 4, + "line": 17 + } + }, + { + "code": "a11y-role-has-required-aria-props", + "end": { + "character": 447, + "column": 18, + "line": 17 + }, + "message": "A11y: Elements with the ARIA role \"heading\" must have the following attributes defined: \"aria-level\"", + "pos": 433, + "start": { + "character": 433, + "column": 4, + "line": 17 + } + }, + { + "code": "a11y-no-redundant-roles", + "end": { + "character": 479, + "column": 18, + "line": 18 + }, + "message": "A11y: Redundant role 'heading'", + "pos": 465, + "start": { + "character": 465, + "column": 4, + "line": 18 + } + }, + { + "code": "a11y-role-has-required-aria-props", + "message": "A11y: Elements with the ARIA role \"heading\" must have the following attributes defined: \"aria-level\"", + "pos": 465, + "start": { + "character": 465, + "column": 4, + "line": 18 + }, + "end": { + "character": 479, + "column": 18, + "line": 18 + } + }, + { + "code": "a11y-no-redundant-roles", + "end": { + "character": 511, + "column": 18, + "line": 19 + }, + "message": "A11y: Redundant role 'heading'", + "pos": 497, + "start": { + "character": 497, + "column": 4, + "line": 19 + } + }, + { + "code": "a11y-role-has-required-aria-props", + "message": "A11y: Elements with the ARIA role \"heading\" must have the following attributes defined: \"aria-level\"", + "pos": 497, + "start": { + "character": 497, + "column": 4, + "line": 19 + }, + "end": { + "character": 511, + "column": 18, + "line": 19 + } + }, + { + "code": "a11y-no-redundant-roles", + "end": { + "character": 543, + "column": 18, + "line": 20 + }, + "message": "A11y: Redundant role 'heading'", + "pos": 529, + "start": { + "character": 529, + "column": 4, + "line": 20 + } + }, + { + "code": "a11y-role-has-required-aria-props", + "message": "A11y: Elements with the ARIA role \"heading\" must have the following attributes defined: \"aria-level\"", + "pos": 529, + "start": { + "character": 529, + "column": 4, + "line": 20 + }, + "end": { + "character": 543, + "column": 18, + "line": 20 + } + }, + { + "code": "a11y-no-redundant-roles", + "end": { + "character": 577, + "column": 20, + "line": 21 + }, + "message": "A11y: Redundant role 'separator'", + "pos": 561, + "start": { + "character": 561, + "column": 4, + "line": 21 + } + }, + { + "code": "a11y-no-redundant-roles", + "end": { + "character": 600, + "column": 19, + "line": 22 + }, + "message": "A11y: Redundant role 'listitem'", + "pos": 585, + "start": { + "character": 585, + "column": 4, + "line": 22 + } + }, + { + "code": "a11y-no-redundant-roles", + "end": { + "character": 621, + "column": 17, + "line": 23 + }, + "message": "A11y: Redundant role 'link'", + "pos": 610, + "start": { + "character": 610, + "column": 6, + "line": 23 + } + }, + { + "code": "a11y-no-redundant-roles", + "end": { + "character": 642, + "column": 17, + "line": 24 + }, + "message": "A11y: Redundant role 'main'", + "pos": 631, + "start": { + "character": 631, + "column": 6, + "line": 24 + } + }, + { + "code": "a11y-no-redundant-roles", + "end": { + "character": 668, + "column": 17, + "line": 25 + }, + "message": "A11y: Redundant role 'list'", + "pos": 657, + "start": { + "character": 657, + "column": 6, + "line": 25 + } + }, + { + "code": "a11y-no-redundant-roles", + "end": { + "character": 694, + "column": 22, + "line": 26 + }, + "message": "A11y: Redundant role 'navigation'", + "pos": 677, + "start": { + "character": 677, + "column": 5, + "line": 26 + } + }, + { + "code": "a11y-no-redundant-roles", + "end": { + "character": 713, + "column": 15, + "line": 27 + }, + "message": "A11y: Redundant role 'list'", + "pos": 702, + "start": { + "character": 702, + "column": 4, + "line": 27 + } + }, + { + "code": "a11y-no-redundant-roles", + "end": { + "character": 739, + "column": 22, + "line": 28 + }, + "message": "A11y: Redundant role 'group'", + "pos": 727, + "start": { + "character": 727, + "column": 10, + "line": 28 + } + }, + { + "code": "a11y-no-redundant-roles", + "end": { + "character": 764, + "column": 21, + "line": 29 + }, + "message": "A11y: Redundant role 'option'", + "pos": 751, + "start": { + "character": 751, + "column": 8, + "line": 29 + } + }, + { + "code": "a11y-role-has-required-aria-props", + "message": "A11y: Elements with the ARIA role \"option\" must have the following attributes defined: \"aria-selected\"", + "pos": 751, + "start": { + "character": 751, + "column": 8, + "line": 29 + }, + "end": { + "character": 764, + "column": 21, + "line": 29 + } + }, + { + "code": "a11y-no-redundant-roles", + "end": { + "character": 789, + "column": 21, + "line": 30 + }, + "message": "A11y: Redundant role 'status'", + "pos": 776, + "start": { + "character": 776, + "column": 8, + "line": 30 + } + }, + { + "code": "a11y-no-redundant-roles", + "end": { + "character": 821, + "column": 28, + "line": 31 + }, + "message": "A11y: Redundant role 'progressbar'", + "pos": 803, + "start": { + "character": 803, + "column": 10, + "line": 31 + } + }, + { + "code": "a11y-no-redundant-roles", + "end": { + "character": 847, + "column": 22, + "line": 32 + }, + "message": "A11y: Redundant role 'region'", + "pos": 834, + "start": { + "character": 834, + "column": 9, + "line": 32 + } + }, + { + "code": "a11y-no-redundant-roles", + "end": { + "character": 873, + "column": 22, + "line": 33 + }, + "message": "A11y: Redundant role 'button'", + "pos": 860, + "start": { + "character": 860, + "column": 9, + "line": 33 + } + }, + { + "code": "a11y-no-redundant-roles", + "end": { + "character": 896, + "column": 19, + "line": 34 + }, + "message": "A11y: Redundant role 'table'", + "pos": 884, + "start": { + "character": 884, + "column": 7, + "line": 34 + } + }, + { + "code": "a11y-no-redundant-roles", + "end": { + "character": 922, + "column": 22, + "line": 35 + }, + "message": "A11y: Redundant role 'rowgroup'", + "pos": 907, + "start": { + "character": 907, + "column": 7, + "line": 35 + } + }, + { + "code": "a11y-no-redundant-roles", + "end": { + "character": 950, + "column": 24, + "line": 36 + }, + "message": "A11y: Redundant role 'textbox'", + "pos": 936, + "start": { + "character": 936, + "column": 10, + "line": 36 + } + }, + { + "code": "a11y-no-redundant-roles", + "end": { + "character": 976, + "column": 22, + "line": 37 + }, + "message": "A11y: Redundant role 'rowgroup'", + "pos": 961, + "start": { + "character": 961, + "column": 7, + "line": 37 + } + }, + { + "code": "a11y-no-redundant-roles", + "end": { + "character": 1002, + "column": 22, + "line": 38 + }, + "message": "A11y: Redundant role 'rowgroup'", + "pos": 987, + "start": { + "character": 987, + "column": 7, + "line": 38 + } + }, + { + "code": "a11y-no-redundant-roles", + "end": { + "character": 1020, + "column": 14, + "line": 39 + }, + "message": "A11y: Redundant role 'row'", + "pos": 1010, + "start": { + "character": 1010, + "column": 4, + "line": 39 + } + }, + { + "code": "a11y-no-redundant-roles", + "end": { + "character": 1039, + "column": 15, + "line": 40 + }, + "message": "A11y: Redundant role 'list'", + "pos": 1028, + "start": { + "character": 1028, + "column": 4, + "line": 40 + } + }, + { + "code": "a11y-no-redundant-roles", + "end": { + "character": 1125, + "column": 21, + "line": 43 + }, + "message": "A11y: Redundant role 'banner'", + "pos": 1112, + "start": { + "character": 1112, + "column": 8, + "line": 43 + } + }, + { + "code": "a11y-no-redundant-roles", + "end": { + "character": 1162, + "column": 26, + "line": 44 + }, + "message": "A11y: Redundant role 'contentinfo'", + "pos": 1144, + "start": { + "character": 1144, + "column": 8, + "line": 44 + } + } +] diff --git a/test/validator/samples/a11y-role-has-required-aria-props/input.svelte b/test/validator/samples/a11y-role-has-required-aria-props/input.svelte new file mode 100644 index 0000000000..8e88b08908 --- /dev/null +++ b/test/validator/samples/a11y-role-has-required-aria-props/input.svelte @@ -0,0 +1,9 @@ +
+ +
+
+ +
+ +
+
diff --git a/test/validator/samples/a11y-role-has-required-aria-props/warnings.json b/test/validator/samples/a11y-role-has-required-aria-props/warnings.json new file mode 100644 index 0000000000..4de7c84001 --- /dev/null +++ b/test/validator/samples/a11y-role-has-required-aria-props/warnings.json @@ -0,0 +1,62 @@ +[ + { + "code": "a11y-role-has-required-aria-props", + "message": "A11y: Elements with the ARIA role \"heading\" must have the following attributes defined: \"aria-level\"", + "start": { + "line": 1, + "column": 5, + "character": 5 + }, + "end": { + "line": 1, + "column": 19, + "character": 19 + }, + "pos": 5 + }, + { + "code": "a11y-role-has-required-aria-props", + "message": "A11y: Elements with the ARIA role \"checkbox\" must have the following attributes defined: \"aria-checked\"", + "start": { + "line": 2, + "column": 6, + "character": 33 + }, + "end": { + "line": 2, + "column": 21, + "character": 48 + }, + "pos": 33 + }, + { + "code": "a11y-role-has-required-aria-props", + "message": "A11y: Elements with the ARIA role \"meter\" must have the following attributes defined: \"aria-valuenow\"", + "start": { + "line": 3, + "column": 5, + "character": 62 + }, + "end": { + "line": 3, + "column": 17, + "character": 74 + }, + "pos": 62 + }, + { + "code": "a11y-role-has-required-aria-props", + "message": "A11y: Elements with the ARIA role \"scrollbar\" must have the following attributes defined: \"aria-controls\", \"aria-valuenow\"", + "start": { + "character": 87, + "column": 5, + "line": 4 + }, + "end": { + "character": 103, + "column": 21, + "line": 4 + }, + "pos": 87 + } +] From 4617c0d5f5af1dae09cc00ce0134e433588a62d1 Mon Sep 17 00:00:00 2001 From: Tan Li Hau Date: Mon, 11 Jul 2022 02:27:58 +0800 Subject: [PATCH 22/89] Update CHANGELOG.md --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 70c05b01e9..4140333c7a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Svelte changelog +## Unreleased + +* Add a11y warning `a11y-role-has-required-aria-props` which checks that elements with `role` attribute has all required attributes for that role. ([#5852](https://github.com/sveltejs/svelte/pull/5852)) + ## 3.49.0 * Improve performance of string escaping during SSR ([#5701](https://github.com/sveltejs/svelte/pull/5701)) From 39901986d6bc3b1a47d607f2f5e93cbb9c9445bb Mon Sep 17 00:00:00 2001 From: kwangure <86817609+kwangure@users.noreply.github.com> Date: Mon, 11 Jul 2022 04:40:12 +0300 Subject: [PATCH 23/89] [feat]: Add A11y aria-proptypes check (#6978) * Add aria prop type list * feat: check aria attribute types * feat: add proptype tests * Add documentation * use aria-query Co-authored-by: Nurassyl Zekenov Co-authored-by: mka_882@yahoo.com Co-authored-by: tanhauhau Co-authored-by: David Mosher --- .../content/docs/05-accessibility-warnings.md | 12 +++ src/compiler/compile/compiler_warnings.ts | 33 +++++++- src/compiler/compile/nodes/Element.ts | 40 +++++++++- .../a11y-aria-proptypes-boolean/input.svelte | 8 ++ .../a11y-aria-proptypes-boolean/warnings.json | 32 ++++++++ .../a11y-aria-proptypes-integer/input.svelte | 7 ++ .../a11y-aria-proptypes-integer/warnings.json | 47 +++++++++++ .../a11y-aria-proptypes-number/input.svelte | 7 ++ .../a11y-aria-proptypes-number/warnings.json | 47 +++++++++++ .../a11y-aria-proptypes-string/input.svelte | 5 ++ .../a11y-aria-proptypes-string/warnings.json | 17 ++++ .../a11y-aria-proptypes-token/input.svelte | 6 ++ .../a11y-aria-proptypes-token/warnings.json | 62 +++++++++++++++ .../input.svelte | 7 ++ .../warnings.json | 77 +++++++++++++++++++ .../a11y-aria-proptypes-tristate/input.svelte | 8 ++ .../warnings.json | 32 ++++++++ 17 files changed, 445 insertions(+), 2 deletions(-) create mode 100644 test/validator/samples/a11y-aria-proptypes-boolean/input.svelte create mode 100644 test/validator/samples/a11y-aria-proptypes-boolean/warnings.json create mode 100644 test/validator/samples/a11y-aria-proptypes-integer/input.svelte create mode 100644 test/validator/samples/a11y-aria-proptypes-integer/warnings.json create mode 100644 test/validator/samples/a11y-aria-proptypes-number/input.svelte create mode 100644 test/validator/samples/a11y-aria-proptypes-number/warnings.json create mode 100644 test/validator/samples/a11y-aria-proptypes-string/input.svelte create mode 100644 test/validator/samples/a11y-aria-proptypes-string/warnings.json create mode 100644 test/validator/samples/a11y-aria-proptypes-token/input.svelte create mode 100644 test/validator/samples/a11y-aria-proptypes-token/warnings.json create mode 100644 test/validator/samples/a11y-aria-proptypes-tokenlist/input.svelte create mode 100644 test/validator/samples/a11y-aria-proptypes-tokenlist/warnings.json create mode 100644 test/validator/samples/a11y-aria-proptypes-tristate/input.svelte create mode 100644 test/validator/samples/a11y-aria-proptypes-tristate/warnings.json diff --git a/site/content/docs/05-accessibility-warnings.md b/site/content/docs/05-accessibility-warnings.md index 9d0835b443..438f2e4743 100644 --- a/site/content/docs/05-accessibility-warnings.md +++ b/site/content/docs/05-accessibility-warnings.md @@ -98,6 +98,18 @@ Enforce img alt attribute does not contain the word image, picture, or photo. Sc --- +### `a11y-incorrect-aria-attribute-type` + +Enforce that only the correct type of value is used for aria attributes. For example, `aria-hidden` +should only receive a boolean. + +```sv + +
+``` + +--- + ### `a11y-invalid-attribute` Enforce that attributes important for accessibility have a valid value. For example, `href` should not be empty, `'#'`, or `javascript:`. diff --git a/src/compiler/compile/compiler_warnings.ts b/src/compiler/compile/compiler_warnings.ts index 833722c3b9..267a97afcc 100644 --- a/src/compiler/compile/compiler_warnings.ts +++ b/src/compiler/compile/compiler_warnings.ts @@ -1,12 +1,14 @@ // All compiler warnings should be listed and accessed from here +import { ARIAPropertyDefinition } from 'aria-query'; + /** * @internal */ export default { custom_element_no_tag: { code: 'custom-element-no-tag', - message: 'No custom element \'tag\' option was specified. To automatically register a custom element, specify a name with a hyphen in it, e.g. . To hide this warning, use ' + message: 'No custom element \'tag\' option was specified. To automatically register a custom element, specify a name with a hyphen in it, e.g. . To hide this warning, use ' }, unused_export_let: (component: string, property: string) => ({ code: 'unused-export-let', @@ -60,6 +62,35 @@ export default { code: 'a11y-aria-attributes', message: `A11y: <${name}> should not have aria-* attributes` }), + a11y_incorrect_attribute_type: (schema: ARIAPropertyDefinition, attribute: string) => { + let message; + switch (schema.type) { + case 'boolean': + message = `The value of '${attribute}' must be exactly one of true or false`; + break; + case 'id': + message = `The value of '${attribute}' must be a string that represents a DOM element ID`; + break; + case 'idlist': + message = `The value of '${attribute}' must be a space-separated list of strings that represent DOM element IDs`; + break; + case 'tristate': + message = `The value of '${attribute}' must be exactly one of true, false, or mixed`; + break; + case 'token': + message = `The value of '${attribute}' must be exactly one of ${(schema.values || []).join(', ')}`; + break; + case 'tokenlist': + message = `The value of '${attribute}' must be a space-separated list of one or more of ${(schema.values || []).join(', ')}`; + break; + default: + message = `The value of '${attribute}' must be of type ${schema.type}`; + } + return { + code: 'a11y-incorrect-aria-attribute-type', + message: `A11y: ${message}` + }; + }, a11y_unknown_aria_attribute: (attribute: string, suggestion?: string) => ({ code: 'a11y-unknown-aria-attribute', message: `A11y: Unknown aria attribute 'aria-${attribute}'` + (suggestion ? ` (did you mean '${suggestion}'?)` : '') diff --git a/src/compiler/compile/nodes/Element.ts b/src/compiler/compile/nodes/Element.ts index 35131cefcf..b7b2572986 100644 --- a/src/compiler/compile/nodes/Element.ts +++ b/src/compiler/compile/nodes/Element.ts @@ -23,7 +23,7 @@ import { string_literal } from '../utils/stringify'; import { Literal } from 'estree'; import compiler_warnings from '../compiler_warnings'; import compiler_errors from '../compiler_errors'; -import { ARIARoleDefintionKey, roles } from 'aria-query'; +import { ARIARoleDefintionKey, roles, aria, ARIAPropertyDefinition, ARIAProperty } from 'aria-query'; const svg = /^(?:altGlyph|altGlyphDef|altGlyphItem|animate|animateColor|animateMotion|animateTransform|circle|clipPath|color-profile|cursor|defs|desc|discard|ellipse|feBlend|feColorMatrix|feComponentTransfer|feComposite|feConvolveMatrix|feDiffuseLighting|feDisplacementMap|feDistantLight|feDropShadow|feFlood|feFuncA|feFuncB|feFuncG|feFuncR|feGaussianBlur|feImage|feMerge|feMergeNode|feMorphology|feOffset|fePointLight|feSpecularLighting|feSpotLight|feTile|feTurbulence|filter|font|font-face|font-face-format|font-face-name|font-face-src|font-face-uri|foreignObject|g|glyph|glyphRef|hatch|hatchpath|hkern|image|line|linearGradient|marker|mask|mesh|meshgradient|meshpatch|meshrow|metadata|missing-glyph|mpath|path|pattern|polygon|polyline|radialGradient|rect|set|solidcolor|stop|svg|switch|symbol|text|textPath|tref|tspan|unknown|use|view|vkern)$/; @@ -177,6 +177,32 @@ function get_namespace(parent: Element, element: Element, explicit_namespace: st return parent_element.namespace; } +function is_valid_aria_attribute_value(schema: ARIAPropertyDefinition, value: string | boolean): boolean { + switch (schema.type) { + case 'boolean': + return typeof value === 'boolean'; + case 'string': + case 'id': + return typeof value === 'string'; + case 'tristate': + return typeof value === 'boolean' || value === 'mixed'; + case 'integer': + case 'number': + return typeof value !== 'boolean' && isNaN(Number(value)) === false; + case 'token': // single token + return (schema.values || []) + .indexOf(typeof value === 'string' ? value.toLowerCase() : value) > -1; + case 'idlist': // if list of ids, split each + return typeof value === 'string' + && value.split(' ').every((id) => typeof id === 'string'); + case 'tokenlist': // if list of tokens, split each + return typeof value === 'string' + && value.split(' ').every((token) => (schema.values || []).indexOf(token.toLowerCase()) > -1); + default: + return false; + } +} + export default class Element extends Node { type: 'Element'; name: string; @@ -431,6 +457,18 @@ export default class Element extends Node { if (name === 'aria-hidden' && /^h[1-6]$/.test(this.name)) { component.warn(attribute, compiler_warnings.a11y_hidden(this.name)); } + + // aria-proptypes + let value = attribute.get_static_value(); + if (value === 'true') value = true; + if (value === 'false') value = false; + + if (value !== null && value !== undefined && aria.has(name as ARIAProperty)) { + const schema = aria.get(name as ARIAProperty); + if (!is_valid_aria_attribute_value(schema, value)) { + component.warn(attribute, compiler_warnings.a11y_incorrect_attribute_type(schema, name)); + } + } } // aria-role diff --git a/test/validator/samples/a11y-aria-proptypes-boolean/input.svelte b/test/validator/samples/a11y-aria-proptypes-boolean/input.svelte new file mode 100644 index 0000000000..c992928229 --- /dev/null +++ b/test/validator/samples/a11y-aria-proptypes-boolean/input.svelte @@ -0,0 +1,8 @@ + + +