From f110ab6fbcd01c3fff5542cba4d1843ac45e51c4 Mon Sep 17 00:00:00 2001 From: Miquel de Domingo Date: Fri, 15 Nov 2024 09:20:44 +0100 Subject: [PATCH 1/8] feat: add rule `no-invalid-html-elements` --- README.md | 1 + docs/rules.md | 1 + docs/rules/no-invalid-html-elements.md | 57 +++++++++++++++++++ .../eslint-plugin-svelte/src/rule-types.ts | 5 ++ .../src/rules/no-invalid-html-elements.ts | 54 ++++++++++++++++++ .../eslint-plugin-svelte/src/utils/rules.ts | 2 + .../invalid/test01-errors.yaml | 24 ++++++++ .../invalid/test01-input.svelte | 6 ++ .../invalid/test01-output.svelte | 6 ++ .../valid/test01-input.svelte | 8 +++ .../src/rules/no-invalid-html-elements.ts | 12 ++++ 11 files changed, 176 insertions(+) create mode 100644 docs/rules/no-invalid-html-elements.md create mode 100644 packages/eslint-plugin-svelte/src/rules/no-invalid-html-elements.ts create mode 100644 packages/eslint-plugin-svelte/tests/fixtures/rules/no-invalid-html-elements/invalid/test01-errors.yaml create mode 100644 packages/eslint-plugin-svelte/tests/fixtures/rules/no-invalid-html-elements/invalid/test01-input.svelte create mode 100644 packages/eslint-plugin-svelte/tests/fixtures/rules/no-invalid-html-elements/invalid/test01-output.svelte create mode 100644 packages/eslint-plugin-svelte/tests/fixtures/rules/no-invalid-html-elements/valid/test01-input.svelte create mode 100644 packages/eslint-plugin-svelte/tests/src/rules/no-invalid-html-elements.ts diff --git a/README.md b/README.md index 9682cbf66..37b6918bd 100644 --- a/README.md +++ b/README.md @@ -387,6 +387,7 @@ These rules relate to possible syntax or logic errors in Svelte code: | [svelte/no-dupe-use-directives](https://sveltejs.github.io/eslint-plugin-svelte/rules/no-dupe-use-directives/) | disallow duplicate `use:` directives | | | [svelte/no-dynamic-slot-name](https://sveltejs.github.io/eslint-plugin-svelte/rules/no-dynamic-slot-name/) | disallow dynamic slot name | :star::wrench: | | [svelte/no-export-load-in-svelte-module-in-kit-pages](https://sveltejs.github.io/eslint-plugin-svelte/rules/no-export-load-in-svelte-module-in-kit-pages/) | disallow exporting load functions in `*.svelte` module in SvelteKit page components. | | +| [svelte/no-invalid-html-elements](https://sveltejs.github.io/eslint-plugin-svelte/rules/no-invalid-html-elements/) | Disallows valid Svelte 4 tags, that no are no longer valid in Svelte 5 | | | [svelte/no-not-function-handler](https://sveltejs.github.io/eslint-plugin-svelte/rules/no-not-function-handler/) | disallow use of not function in event handler | :star: | | [svelte/no-object-in-text-mustaches](https://sveltejs.github.io/eslint-plugin-svelte/rules/no-object-in-text-mustaches/) | disallow objects in text mustache interpolation | :star: | | [svelte/no-reactive-reassign](https://sveltejs.github.io/eslint-plugin-svelte/rules/no-reactive-reassign/) | disallow reassigning reactive values | | diff --git a/docs/rules.md b/docs/rules.md index fb067e57c..266c760ca 100644 --- a/docs/rules.md +++ b/docs/rules.md @@ -24,6 +24,7 @@ These rules relate to possible syntax or logic errors in Svelte code: | [svelte/no-dupe-use-directives](./rules/no-dupe-use-directives.md) | disallow duplicate `use:` directives | | | [svelte/no-dynamic-slot-name](./rules/no-dynamic-slot-name.md) | disallow dynamic slot name | :star::wrench: | | [svelte/no-export-load-in-svelte-module-in-kit-pages](./rules/no-export-load-in-svelte-module-in-kit-pages.md) | disallow exporting load functions in `*.svelte` module in SvelteKit page components. | | +| [svelte/no-invalid-html-elements](./rules/no-invalid-html-elements.md) | Disallows valid Svelte 4 tags, that no are no longer valid in Svelte 5 | | | [svelte/no-not-function-handler](./rules/no-not-function-handler.md) | disallow use of not function in event handler | :star: | | [svelte/no-object-in-text-mustaches](./rules/no-object-in-text-mustaches.md) | disallow objects in text mustache interpolation | :star: | | [svelte/no-reactive-reassign](./rules/no-reactive-reassign.md) | disallow reassigning reactive values | | diff --git a/docs/rules/no-invalid-html-elements.md b/docs/rules/no-invalid-html-elements.md new file mode 100644 index 000000000..7eaccb79a --- /dev/null +++ b/docs/rules/no-invalid-html-elements.md @@ -0,0 +1,57 @@ +--- +pageClass: 'rule-details' +sidebarDepth: 0 +title: 'svelte/no-invalid-html-elements' +description: 'Disallows valid Svelte 4 tags, that no are no longer valid in Svelte 5' +--- + +# svelte/no-invalid-html-elements + +> Disallows valid Svelte 4 tags, that no are no longer valid in Svelte 5 + +- :exclamation: **_This rule has not been released yet._** + +## :book: Rule Details + +This rule reports the invalid usage of `head`, `body`, `window`, `document`, `element` and `options` HTML elements, **in Svelte 5**. These elements were valid in Svelte 4, but since Svelte 5 they must be used with `svelte:`. + + + + + +```svelte + + + + + Invalid HTML Elements + + + + + Invalid HTML Elements + +``` + + + +## :wrench: Options + +```json +{ + "svelte/no-invalid-html-elements": ["error", {}] +} +``` + +- + +## :books: Further Reading + +- See special elements section in [Svelte docs](https://svelte.dev/docs/svelte/svelte-window) + +## :mag: Implementation + +- [Rule source](https://github.com/sveltejs/eslint-plugin-svelte/blob/main/packages/eslint-plugin-svelte/src/rules/no-invalid-html-elements.ts) +- [Test source](https://github.com/sveltejs/eslint-plugin-svelte/blob/main/packages/eslint-plugin-svelte/tests/src/rules/no-invalid-html-elements.ts) diff --git a/packages/eslint-plugin-svelte/src/rule-types.ts b/packages/eslint-plugin-svelte/src/rule-types.ts index 8e747b6e4..73626e514 100644 --- a/packages/eslint-plugin-svelte/src/rule-types.ts +++ b/packages/eslint-plugin-svelte/src/rule-types.ts @@ -174,6 +174,11 @@ export interface RuleOptions { * @see https://sveltejs.github.io/eslint-plugin-svelte/rules/no-inspect/ */ 'svelte/no-inspect'?: Linter.RuleEntry<[]> + /** + * Disallows valid Svelte 4 tags, that no are no longer valid in Svelte 5 + * @see https://sveltejs.github.io/eslint-plugin-svelte/rules/no-invalid-html-elements/ + */ + 'svelte/no-invalid-html-elements'?: Linter.RuleEntry<[]> /** * disallow use of not function in event handler * @see https://sveltejs.github.io/eslint-plugin-svelte/rules/no-not-function-handler/ diff --git a/packages/eslint-plugin-svelte/src/rules/no-invalid-html-elements.ts b/packages/eslint-plugin-svelte/src/rules/no-invalid-html-elements.ts new file mode 100644 index 000000000..2a5732077 --- /dev/null +++ b/packages/eslint-plugin-svelte/src/rules/no-invalid-html-elements.ts @@ -0,0 +1,54 @@ +import type { AST } from 'svelte-eslint-parser'; +import { createRule } from '../utils'; +import { getSourceCode } from '../utils/compat'; + +const INVALID_HTML_ELEMENTS = ['head', 'body', 'window', 'document', 'element', 'options']; +const VALID_PREFIX = 'svelte:'; + +export default createRule('no-invalid-html-elements', { + meta: { + docs: { + description: 'Disallows valid Svelte 4 tags, that no are no longer valid in Svelte 5', + category: 'Possible Errors', + // TODO: Switch to recommended in the major version + recommended: false + }, + schema: [], + messages: { + invalidElement: 'Invalid {{name}} element, use svelte:{{name}} instead.' + }, + type: 'problem', // 'problem', or 'layout', + fixable: 'code' + }, + create(context) { + const sourceCode = getSourceCode(context); + const ctx = sourceCode.parserServices.svelteParseContext; + if (!(ctx?.compilerVersion ?? '').startsWith('5')) { + // Only applies to Svelte 5 + return {}; + } + + return { + 'SvelteElement[kind="html"]'(node: AST.SvelteHTMLElement) { + const { name } = node.name; + if (INVALID_HTML_ELEMENTS.includes(name)) { + context.report({ + node, + messageId: 'invalidElement', + data: { name }, + *fix(fixer) { + const { endTag } = node; + yield fixer.insertTextBeforeRange([node.range[0] + 1, node.range[1]], VALID_PREFIX); + if (endTag) { + yield fixer.insertTextBeforeRange( + [endTag.range[0] + 2, endTag.range[1]], + VALID_PREFIX + ); + } + } + }); + } + } + }; + } +}); diff --git a/packages/eslint-plugin-svelte/src/utils/rules.ts b/packages/eslint-plugin-svelte/src/utils/rules.ts index 5bb5a080c..b34a2d31c 100644 --- a/packages/eslint-plugin-svelte/src/utils/rules.ts +++ b/packages/eslint-plugin-svelte/src/utils/rules.ts @@ -34,6 +34,7 @@ import noImmutableReactiveStatements from '../rules/no-immutable-reactive-statem import noInlineStyles from '../rules/no-inline-styles'; import noInnerDeclarations from '../rules/no-inner-declarations'; import noInspect from '../rules/no-inspect'; +import noInvalidHtmlElements from '../rules/no-invalid-html-elements'; import noNotFunctionHandler from '../rules/no-not-function-handler'; import noObjectInTextMustaches from '../rules/no-object-in-text-mustaches'; import noReactiveFunctions from '../rules/no-reactive-functions'; @@ -101,6 +102,7 @@ export const rules = [ noInlineStyles, noInnerDeclarations, noInspect, + noInvalidHtmlElements, noNotFunctionHandler, noObjectInTextMustaches, noReactiveFunctions, diff --git a/packages/eslint-plugin-svelte/tests/fixtures/rules/no-invalid-html-elements/invalid/test01-errors.yaml b/packages/eslint-plugin-svelte/tests/fixtures/rules/no-invalid-html-elements/invalid/test01-errors.yaml new file mode 100644 index 000000000..4c1a42cab --- /dev/null +++ b/packages/eslint-plugin-svelte/tests/fixtures/rules/no-invalid-html-elements/invalid/test01-errors.yaml @@ -0,0 +1,24 @@ +- message: Invalid head element, use svelte:head instead. + line: 1 + column: 1 + suggestions: null +- message: Invalid body element, use svelte:body instead. + line: 2 + column: 1 + suggestions: null +- message: Invalid window element, use svelte:window instead. + line: 3 + column: 1 + suggestions: null +- message: Invalid document element, use svelte:document instead. + line: 4 + column: 1 + suggestions: null +- message: Invalid element element, use svelte:element instead. + line: 5 + column: 1 + suggestions: null +- message: Invalid options element, use svelte:options instead. + line: 6 + column: 1 + suggestions: null diff --git a/packages/eslint-plugin-svelte/tests/fixtures/rules/no-invalid-html-elements/invalid/test01-input.svelte b/packages/eslint-plugin-svelte/tests/fixtures/rules/no-invalid-html-elements/invalid/test01-input.svelte new file mode 100644 index 000000000..0856e15ef --- /dev/null +++ b/packages/eslint-plugin-svelte/tests/fixtures/rules/no-invalid-html-elements/invalid/test01-input.svelte @@ -0,0 +1,6 @@ + + + + + + diff --git a/packages/eslint-plugin-svelte/tests/fixtures/rules/no-invalid-html-elements/invalid/test01-output.svelte b/packages/eslint-plugin-svelte/tests/fixtures/rules/no-invalid-html-elements/invalid/test01-output.svelte new file mode 100644 index 000000000..507eea7d8 --- /dev/null +++ b/packages/eslint-plugin-svelte/tests/fixtures/rules/no-invalid-html-elements/invalid/test01-output.svelte @@ -0,0 +1,6 @@ + + + + + + diff --git a/packages/eslint-plugin-svelte/tests/fixtures/rules/no-invalid-html-elements/valid/test01-input.svelte b/packages/eslint-plugin-svelte/tests/fixtures/rules/no-invalid-html-elements/valid/test01-input.svelte new file mode 100644 index 000000000..ea0dfc2a0 --- /dev/null +++ b/packages/eslint-plugin-svelte/tests/fixtures/rules/no-invalid-html-elements/valid/test01-input.svelte @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/packages/eslint-plugin-svelte/tests/src/rules/no-invalid-html-elements.ts b/packages/eslint-plugin-svelte/tests/src/rules/no-invalid-html-elements.ts new file mode 100644 index 000000000..849429075 --- /dev/null +++ b/packages/eslint-plugin-svelte/tests/src/rules/no-invalid-html-elements.ts @@ -0,0 +1,12 @@ +import { RuleTester } from '../../utils/eslint-compat'; +import rule from '../../../src/rules/no-invalid-html-elements'; +import { loadTestCases } from '../../utils/utils'; + +const tester = new RuleTester({ + languageOptions: { + ecmaVersion: 2020, + sourceType: 'module' + } +}); + +tester.run('no-invalid-html-elements', rule as any, loadTestCases('no-invalid-html-elements')); From fce1137a56375ea62f1c8271db795eb45a931964 Mon Sep 17 00:00:00 2001 From: Miquel de Domingo Date: Sun, 24 Nov 2024 09:53:18 +0100 Subject: [PATCH 2/8] fix: run `pnpm update` --- README.md | 2 +- docs/rules.md | 2 +- docs/rules/no-invalid-html-elements.md | 3 ++- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 37b6918bd..30cfab5ce 100644 --- a/README.md +++ b/README.md @@ -387,7 +387,7 @@ These rules relate to possible syntax or logic errors in Svelte code: | [svelte/no-dupe-use-directives](https://sveltejs.github.io/eslint-plugin-svelte/rules/no-dupe-use-directives/) | disallow duplicate `use:` directives | | | [svelte/no-dynamic-slot-name](https://sveltejs.github.io/eslint-plugin-svelte/rules/no-dynamic-slot-name/) | disallow dynamic slot name | :star::wrench: | | [svelte/no-export-load-in-svelte-module-in-kit-pages](https://sveltejs.github.io/eslint-plugin-svelte/rules/no-export-load-in-svelte-module-in-kit-pages/) | disallow exporting load functions in `*.svelte` module in SvelteKit page components. | | -| [svelte/no-invalid-html-elements](https://sveltejs.github.io/eslint-plugin-svelte/rules/no-invalid-html-elements/) | Disallows valid Svelte 4 tags, that no are no longer valid in Svelte 5 | | +| [svelte/no-invalid-html-elements](https://sveltejs.github.io/eslint-plugin-svelte/rules/no-invalid-html-elements/) | Disallows valid Svelte 4 tags, that no are no longer valid in Svelte 5 | :wrench: | | [svelte/no-not-function-handler](https://sveltejs.github.io/eslint-plugin-svelte/rules/no-not-function-handler/) | disallow use of not function in event handler | :star: | | [svelte/no-object-in-text-mustaches](https://sveltejs.github.io/eslint-plugin-svelte/rules/no-object-in-text-mustaches/) | disallow objects in text mustache interpolation | :star: | | [svelte/no-reactive-reassign](https://sveltejs.github.io/eslint-plugin-svelte/rules/no-reactive-reassign/) | disallow reassigning reactive values | | diff --git a/docs/rules.md b/docs/rules.md index 266c760ca..2a32268d4 100644 --- a/docs/rules.md +++ b/docs/rules.md @@ -24,7 +24,7 @@ These rules relate to possible syntax or logic errors in Svelte code: | [svelte/no-dupe-use-directives](./rules/no-dupe-use-directives.md) | disallow duplicate `use:` directives | | | [svelte/no-dynamic-slot-name](./rules/no-dynamic-slot-name.md) | disallow dynamic slot name | :star::wrench: | | [svelte/no-export-load-in-svelte-module-in-kit-pages](./rules/no-export-load-in-svelte-module-in-kit-pages.md) | disallow exporting load functions in `*.svelte` module in SvelteKit page components. | | -| [svelte/no-invalid-html-elements](./rules/no-invalid-html-elements.md) | Disallows valid Svelte 4 tags, that no are no longer valid in Svelte 5 | | +| [svelte/no-invalid-html-elements](./rules/no-invalid-html-elements.md) | Disallows valid Svelte 4 tags, that no are no longer valid in Svelte 5 | :wrench: | | [svelte/no-not-function-handler](./rules/no-not-function-handler.md) | disallow use of not function in event handler | :star: | | [svelte/no-object-in-text-mustaches](./rules/no-object-in-text-mustaches.md) | disallow objects in text mustache interpolation | :star: | | [svelte/no-reactive-reassign](./rules/no-reactive-reassign.md) | disallow reassigning reactive values | | diff --git a/docs/rules/no-invalid-html-elements.md b/docs/rules/no-invalid-html-elements.md index 7eaccb79a..d73189b95 100644 --- a/docs/rules/no-invalid-html-elements.md +++ b/docs/rules/no-invalid-html-elements.md @@ -10,12 +10,13 @@ description: 'Disallows valid Svelte 4 tags, that no are no longer valid in Svel > Disallows valid Svelte 4 tags, that no are no longer valid in Svelte 5 - :exclamation: **_This rule has not been released yet._** +- :wrench: The `--fix` option on the [command line](https://eslint.org/docs/user-guide/command-line-interface#fixing-problems) can automatically fix some of the problems reported by this rule. ## :book: Rule Details This rule reports the invalid usage of `head`, `body`, `window`, `document`, `element` and `options` HTML elements, **in Svelte 5**. These elements were valid in Svelte 4, but since Svelte 5 they must be used with `svelte:`. - + From d07baa5bb6c7c7bd4315818b7982c6832f2caf26 Mon Sep 17 00:00:00 2001 From: Miquel de Domingo Date: Sun, 24 Nov 2024 09:54:13 +0100 Subject: [PATCH 3/8] chore: add changeset --- .changeset/lazy-eyes-wait.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/lazy-eyes-wait.md diff --git a/.changeset/lazy-eyes-wait.md b/.changeset/lazy-eyes-wait.md new file mode 100644 index 000000000..9af9d85a5 --- /dev/null +++ b/.changeset/lazy-eyes-wait.md @@ -0,0 +1,5 @@ +--- +'eslint-plugin-svelte': minor +--- + +Added new `no-invalid-html-elements` rule From 44465c55602fd2b273cdcfad713d975018892e75 Mon Sep 17 00:00:00 2001 From: Miquel de Domingo Date: Wed, 27 Nov 2024 11:40:50 +0100 Subject: [PATCH 4/8] fix: rename rule --- README.md | 2 +- docs/rules.md | 2 +- ... => no-deprecated-raw-special-elements.md} | 8 +++---- .../eslint-plugin-svelte/src/rule-types.ts | 10 ++++---- ... => no-deprecated-raw-special-elements.ts} | 15 ++++-------- .../eslint-plugin-svelte/src/utils/rules.ts | 4 ++-- .../invalid/test01-errors.yaml | 24 +++++++++++++++++++ .../invalid/test01-input.svelte | 0 .../invalid/test01-output.svelte | 0 .../valid/test01-input.svelte | 0 .../invalid/test01-errors.yaml | 24 ------------------- ... => no-deprecated-raw-special-elements.ts} | 4 ++-- 12 files changed, 43 insertions(+), 50 deletions(-) rename docs/rules/{no-invalid-html-elements.md => no-deprecated-raw-special-elements.md} (84%) rename packages/eslint-plugin-svelte/src/rules/{no-invalid-html-elements.ts => no-deprecated-raw-special-elements.ts} (72%) create mode 100644 packages/eslint-plugin-svelte/tests/fixtures/rules/no-deprecated-raw-special-elements/invalid/test01-errors.yaml rename packages/eslint-plugin-svelte/tests/fixtures/rules/{no-invalid-html-elements => no-deprecated-raw-special-elements}/invalid/test01-input.svelte (100%) rename packages/eslint-plugin-svelte/tests/fixtures/rules/{no-invalid-html-elements => no-deprecated-raw-special-elements}/invalid/test01-output.svelte (100%) rename packages/eslint-plugin-svelte/tests/fixtures/rules/{no-invalid-html-elements => no-deprecated-raw-special-elements}/valid/test01-input.svelte (100%) delete mode 100644 packages/eslint-plugin-svelte/tests/fixtures/rules/no-invalid-html-elements/invalid/test01-errors.yaml rename packages/eslint-plugin-svelte/tests/src/rules/{no-invalid-html-elements.ts => no-deprecated-raw-special-elements.ts} (52%) diff --git a/README.md b/README.md index 30cfab5ce..19f265bd9 100644 --- a/README.md +++ b/README.md @@ -380,6 +380,7 @@ These rules relate to possible syntax or logic errors in Svelte code: | Rule ID | Description | | |:--------|:------------|:---| | [svelte/infinite-reactive-loop](https://sveltejs.github.io/eslint-plugin-svelte/rules/infinite-reactive-loop/) | Svelte runtime prevents calling the same reactive statement twice in a microtask. But between different microtask, it doesn't prevent. | | +| [svelte/no-deprecated-raw-special-elements](https://sveltejs.github.io/eslint-plugin-svelte/rules/no-deprecated-raw-special-elements/) | Disallows valid Svelte 4 tags, that no are no longer valid in Svelte 5 | :wrench: | | [svelte/no-dom-manipulating](https://sveltejs.github.io/eslint-plugin-svelte/rules/no-dom-manipulating/) | disallow DOM manipulating | | | [svelte/no-dupe-else-if-blocks](https://sveltejs.github.io/eslint-plugin-svelte/rules/no-dupe-else-if-blocks/) | disallow duplicate conditions in `{#if}` / `{:else if}` chains | :star: | | [svelte/no-dupe-on-directives](https://sveltejs.github.io/eslint-plugin-svelte/rules/no-dupe-on-directives/) | disallow duplicate `on:` directives | | @@ -387,7 +388,6 @@ These rules relate to possible syntax or logic errors in Svelte code: | [svelte/no-dupe-use-directives](https://sveltejs.github.io/eslint-plugin-svelte/rules/no-dupe-use-directives/) | disallow duplicate `use:` directives | | | [svelte/no-dynamic-slot-name](https://sveltejs.github.io/eslint-plugin-svelte/rules/no-dynamic-slot-name/) | disallow dynamic slot name | :star::wrench: | | [svelte/no-export-load-in-svelte-module-in-kit-pages](https://sveltejs.github.io/eslint-plugin-svelte/rules/no-export-load-in-svelte-module-in-kit-pages/) | disallow exporting load functions in `*.svelte` module in SvelteKit page components. | | -| [svelte/no-invalid-html-elements](https://sveltejs.github.io/eslint-plugin-svelte/rules/no-invalid-html-elements/) | Disallows valid Svelte 4 tags, that no are no longer valid in Svelte 5 | :wrench: | | [svelte/no-not-function-handler](https://sveltejs.github.io/eslint-plugin-svelte/rules/no-not-function-handler/) | disallow use of not function in event handler | :star: | | [svelte/no-object-in-text-mustaches](https://sveltejs.github.io/eslint-plugin-svelte/rules/no-object-in-text-mustaches/) | disallow objects in text mustache interpolation | :star: | | [svelte/no-reactive-reassign](https://sveltejs.github.io/eslint-plugin-svelte/rules/no-reactive-reassign/) | disallow reassigning reactive values | | diff --git a/docs/rules.md b/docs/rules.md index 2a32268d4..0859409d9 100644 --- a/docs/rules.md +++ b/docs/rules.md @@ -17,6 +17,7 @@ These rules relate to possible syntax or logic errors in Svelte code: | Rule ID | Description | | | :------------------------------------------------------------------------------------------------------------- | :------------------------------------------------------------------------------------------------------------------------------------- | :------------- | | [svelte/infinite-reactive-loop](./rules/infinite-reactive-loop.md) | Svelte runtime prevents calling the same reactive statement twice in a microtask. But between different microtask, it doesn't prevent. | | +| [svelte/no-deprecated-raw-special-elements](./rules/no-deprecated-raw-special-elements.md) | Disallows valid Svelte 4 tags, that no are no longer valid in Svelte 5 | :wrench: | | [svelte/no-dom-manipulating](./rules/no-dom-manipulating.md) | disallow DOM manipulating | | | [svelte/no-dupe-else-if-blocks](./rules/no-dupe-else-if-blocks.md) | disallow duplicate conditions in `{#if}` / `{:else if}` chains | :star: | | [svelte/no-dupe-on-directives](./rules/no-dupe-on-directives.md) | disallow duplicate `on:` directives | | @@ -24,7 +25,6 @@ These rules relate to possible syntax or logic errors in Svelte code: | [svelte/no-dupe-use-directives](./rules/no-dupe-use-directives.md) | disallow duplicate `use:` directives | | | [svelte/no-dynamic-slot-name](./rules/no-dynamic-slot-name.md) | disallow dynamic slot name | :star::wrench: | | [svelte/no-export-load-in-svelte-module-in-kit-pages](./rules/no-export-load-in-svelte-module-in-kit-pages.md) | disallow exporting load functions in `*.svelte` module in SvelteKit page components. | | -| [svelte/no-invalid-html-elements](./rules/no-invalid-html-elements.md) | Disallows valid Svelte 4 tags, that no are no longer valid in Svelte 5 | :wrench: | | [svelte/no-not-function-handler](./rules/no-not-function-handler.md) | disallow use of not function in event handler | :star: | | [svelte/no-object-in-text-mustaches](./rules/no-object-in-text-mustaches.md) | disallow objects in text mustache interpolation | :star: | | [svelte/no-reactive-reassign](./rules/no-reactive-reassign.md) | disallow reassigning reactive values | | diff --git a/docs/rules/no-invalid-html-elements.md b/docs/rules/no-deprecated-raw-special-elements.md similarity index 84% rename from docs/rules/no-invalid-html-elements.md rename to docs/rules/no-deprecated-raw-special-elements.md index d73189b95..aa4254bfd 100644 --- a/docs/rules/no-invalid-html-elements.md +++ b/docs/rules/no-deprecated-raw-special-elements.md @@ -1,11 +1,11 @@ --- pageClass: 'rule-details' sidebarDepth: 0 -title: 'svelte/no-invalid-html-elements' +title: 'svelte/no-deprecated-raw-special-elements' description: 'Disallows valid Svelte 4 tags, that no are no longer valid in Svelte 5' --- -# svelte/no-invalid-html-elements +# svelte/no-deprecated-raw-special-elements > Disallows valid Svelte 4 tags, that no are no longer valid in Svelte 5 @@ -54,5 +54,5 @@ This rule reports the invalid usage of `head`, `body`, `window`, `document`, `el ## :mag: Implementation -- [Rule source](https://github.com/sveltejs/eslint-plugin-svelte/blob/main/packages/eslint-plugin-svelte/src/rules/no-invalid-html-elements.ts) -- [Test source](https://github.com/sveltejs/eslint-plugin-svelte/blob/main/packages/eslint-plugin-svelte/tests/src/rules/no-invalid-html-elements.ts) +- [Rule source](https://github.com/sveltejs/eslint-plugin-svelte/blob/main/packages/eslint-plugin-svelte/src/rules/no-deprecated-raw-special-elements.ts) +- [Test source](https://github.com/sveltejs/eslint-plugin-svelte/blob/main/packages/eslint-plugin-svelte/tests/src/rules/no-deprecated-raw-special-elements.ts) diff --git a/packages/eslint-plugin-svelte/src/rule-types.ts b/packages/eslint-plugin-svelte/src/rule-types.ts index 73626e514..6297b9c0f 100644 --- a/packages/eslint-plugin-svelte/src/rule-types.ts +++ b/packages/eslint-plugin-svelte/src/rule-types.ts @@ -104,6 +104,11 @@ export interface RuleOptions { * @see https://sveltejs.github.io/eslint-plugin-svelte/rules/no-at-html-tags/ */ 'svelte/no-at-html-tags'?: Linter.RuleEntry<[]> + /** + * Disallows valid Svelte 4 tags, that no are no longer valid in Svelte 5 + * @see https://sveltejs.github.io/eslint-plugin-svelte/rules/no-deprecated-raw-special-elements/ + */ + 'svelte/no-deprecated-raw-special-elements'?: Linter.RuleEntry<[]> /** * disallow DOM manipulating * @see https://sveltejs.github.io/eslint-plugin-svelte/rules/no-dom-manipulating/ @@ -174,11 +179,6 @@ export interface RuleOptions { * @see https://sveltejs.github.io/eslint-plugin-svelte/rules/no-inspect/ */ 'svelte/no-inspect'?: Linter.RuleEntry<[]> - /** - * Disallows valid Svelte 4 tags, that no are no longer valid in Svelte 5 - * @see https://sveltejs.github.io/eslint-plugin-svelte/rules/no-invalid-html-elements/ - */ - 'svelte/no-invalid-html-elements'?: Linter.RuleEntry<[]> /** * disallow use of not function in event handler * @see https://sveltejs.github.io/eslint-plugin-svelte/rules/no-not-function-handler/ diff --git a/packages/eslint-plugin-svelte/src/rules/no-invalid-html-elements.ts b/packages/eslint-plugin-svelte/src/rules/no-deprecated-raw-special-elements.ts similarity index 72% rename from packages/eslint-plugin-svelte/src/rules/no-invalid-html-elements.ts rename to packages/eslint-plugin-svelte/src/rules/no-deprecated-raw-special-elements.ts index 2a5732077..676d577a7 100644 --- a/packages/eslint-plugin-svelte/src/rules/no-invalid-html-elements.ts +++ b/packages/eslint-plugin-svelte/src/rules/no-deprecated-raw-special-elements.ts @@ -1,11 +1,10 @@ import type { AST } from 'svelte-eslint-parser'; import { createRule } from '../utils'; -import { getSourceCode } from '../utils/compat'; const INVALID_HTML_ELEMENTS = ['head', 'body', 'window', 'document', 'element', 'options']; const VALID_PREFIX = 'svelte:'; -export default createRule('no-invalid-html-elements', { +export default createRule('no-deprecated-raw-special-elements', { meta: { docs: { description: 'Disallows valid Svelte 4 tags, that no are no longer valid in Svelte 5', @@ -15,26 +14,20 @@ export default createRule('no-invalid-html-elements', { }, schema: [], messages: { - invalidElement: 'Invalid {{name}} element, use svelte:{{name}} instead.' + deprecatedElement: + 'Special {{name}} element is deprecated in v5, use svelte:{{name}} instead.' }, type: 'problem', // 'problem', or 'layout', fixable: 'code' }, create(context) { - const sourceCode = getSourceCode(context); - const ctx = sourceCode.parserServices.svelteParseContext; - if (!(ctx?.compilerVersion ?? '').startsWith('5')) { - // Only applies to Svelte 5 - return {}; - } - return { 'SvelteElement[kind="html"]'(node: AST.SvelteHTMLElement) { const { name } = node.name; if (INVALID_HTML_ELEMENTS.includes(name)) { context.report({ node, - messageId: 'invalidElement', + messageId: 'deprecatedElement', data: { name }, *fix(fixer) { const { endTag } = node; diff --git a/packages/eslint-plugin-svelte/src/utils/rules.ts b/packages/eslint-plugin-svelte/src/utils/rules.ts index b34a2d31c..862db8b99 100644 --- a/packages/eslint-plugin-svelte/src/utils/rules.ts +++ b/packages/eslint-plugin-svelte/src/utils/rules.ts @@ -20,6 +20,7 @@ import maxAttributesPerLine from '../rules/max-attributes-per-line'; import mustacheSpacing from '../rules/mustache-spacing'; import noAtDebugTags from '../rules/no-at-debug-tags'; import noAtHtmlTags from '../rules/no-at-html-tags'; +import noDeprecatedRawSpecialElements from '../rules/no-deprecated-raw-special-elements'; import noDomManipulating from '../rules/no-dom-manipulating'; import noDupeElseIfBlocks from '../rules/no-dupe-else-if-blocks'; import noDupeOnDirectives from '../rules/no-dupe-on-directives'; @@ -34,7 +35,6 @@ import noImmutableReactiveStatements from '../rules/no-immutable-reactive-statem import noInlineStyles from '../rules/no-inline-styles'; import noInnerDeclarations from '../rules/no-inner-declarations'; import noInspect from '../rules/no-inspect'; -import noInvalidHtmlElements from '../rules/no-invalid-html-elements'; import noNotFunctionHandler from '../rules/no-not-function-handler'; import noObjectInTextMustaches from '../rules/no-object-in-text-mustaches'; import noReactiveFunctions from '../rules/no-reactive-functions'; @@ -88,6 +88,7 @@ export const rules = [ mustacheSpacing, noAtDebugTags, noAtHtmlTags, + noDeprecatedRawSpecialElements, noDomManipulating, noDupeElseIfBlocks, noDupeOnDirectives, @@ -102,7 +103,6 @@ export const rules = [ noInlineStyles, noInnerDeclarations, noInspect, - noInvalidHtmlElements, noNotFunctionHandler, noObjectInTextMustaches, noReactiveFunctions, diff --git a/packages/eslint-plugin-svelte/tests/fixtures/rules/no-deprecated-raw-special-elements/invalid/test01-errors.yaml b/packages/eslint-plugin-svelte/tests/fixtures/rules/no-deprecated-raw-special-elements/invalid/test01-errors.yaml new file mode 100644 index 000000000..2acb009df --- /dev/null +++ b/packages/eslint-plugin-svelte/tests/fixtures/rules/no-deprecated-raw-special-elements/invalid/test01-errors.yaml @@ -0,0 +1,24 @@ +- message: Special head element is deprecated in v5, use svelte:head instead. + line: 1 + column: 1 + suggestions: null +- message: Special body element is deprecated in v5, use svelte:body instead. + line: 2 + column: 1 + suggestions: null +- message: Special window element is deprecated in v5, use svelte:window instead. + line: 3 + column: 1 + suggestions: null +- message: Special document element is deprecated in v5, use svelte:document instead. + line: 4 + column: 1 + suggestions: null +- message: Special element element is deprecated in v5, use svelte:element instead. + line: 5 + column: 1 + suggestions: null +- message: Special options element is deprecated in v5, use svelte:options instead. + line: 6 + column: 1 + suggestions: null diff --git a/packages/eslint-plugin-svelte/tests/fixtures/rules/no-invalid-html-elements/invalid/test01-input.svelte b/packages/eslint-plugin-svelte/tests/fixtures/rules/no-deprecated-raw-special-elements/invalid/test01-input.svelte similarity index 100% rename from packages/eslint-plugin-svelte/tests/fixtures/rules/no-invalid-html-elements/invalid/test01-input.svelte rename to packages/eslint-plugin-svelte/tests/fixtures/rules/no-deprecated-raw-special-elements/invalid/test01-input.svelte diff --git a/packages/eslint-plugin-svelte/tests/fixtures/rules/no-invalid-html-elements/invalid/test01-output.svelte b/packages/eslint-plugin-svelte/tests/fixtures/rules/no-deprecated-raw-special-elements/invalid/test01-output.svelte similarity index 100% rename from packages/eslint-plugin-svelte/tests/fixtures/rules/no-invalid-html-elements/invalid/test01-output.svelte rename to packages/eslint-plugin-svelte/tests/fixtures/rules/no-deprecated-raw-special-elements/invalid/test01-output.svelte diff --git a/packages/eslint-plugin-svelte/tests/fixtures/rules/no-invalid-html-elements/valid/test01-input.svelte b/packages/eslint-plugin-svelte/tests/fixtures/rules/no-deprecated-raw-special-elements/valid/test01-input.svelte similarity index 100% rename from packages/eslint-plugin-svelte/tests/fixtures/rules/no-invalid-html-elements/valid/test01-input.svelte rename to packages/eslint-plugin-svelte/tests/fixtures/rules/no-deprecated-raw-special-elements/valid/test01-input.svelte diff --git a/packages/eslint-plugin-svelte/tests/fixtures/rules/no-invalid-html-elements/invalid/test01-errors.yaml b/packages/eslint-plugin-svelte/tests/fixtures/rules/no-invalid-html-elements/invalid/test01-errors.yaml deleted file mode 100644 index 4c1a42cab..000000000 --- a/packages/eslint-plugin-svelte/tests/fixtures/rules/no-invalid-html-elements/invalid/test01-errors.yaml +++ /dev/null @@ -1,24 +0,0 @@ -- message: Invalid head element, use svelte:head instead. - line: 1 - column: 1 - suggestions: null -- message: Invalid body element, use svelte:body instead. - line: 2 - column: 1 - suggestions: null -- message: Invalid window element, use svelte:window instead. - line: 3 - column: 1 - suggestions: null -- message: Invalid document element, use svelte:document instead. - line: 4 - column: 1 - suggestions: null -- message: Invalid element element, use svelte:element instead. - line: 5 - column: 1 - suggestions: null -- message: Invalid options element, use svelte:options instead. - line: 6 - column: 1 - suggestions: null diff --git a/packages/eslint-plugin-svelte/tests/src/rules/no-invalid-html-elements.ts b/packages/eslint-plugin-svelte/tests/src/rules/no-deprecated-raw-special-elements.ts similarity index 52% rename from packages/eslint-plugin-svelte/tests/src/rules/no-invalid-html-elements.ts rename to packages/eslint-plugin-svelte/tests/src/rules/no-deprecated-raw-special-elements.ts index 849429075..dbe2fe152 100644 --- a/packages/eslint-plugin-svelte/tests/src/rules/no-invalid-html-elements.ts +++ b/packages/eslint-plugin-svelte/tests/src/rules/no-deprecated-raw-special-elements.ts @@ -1,5 +1,5 @@ import { RuleTester } from '../../utils/eslint-compat'; -import rule from '../../../src/rules/no-invalid-html-elements'; +import rule from '../../../src/rules/no-deprecated-raw-special-elements'; import { loadTestCases } from '../../utils/utils'; const tester = new RuleTester({ @@ -9,4 +9,4 @@ const tester = new RuleTester({ } }); -tester.run('no-invalid-html-elements', rule as any, loadTestCases('no-invalid-html-elements')); +tester.run('no-deprecated-raw-special-elements', rule as any, loadTestCases('no-deprecated-raw-special-elements')); From 11e0f2a73cc8ececaa75a260daf1385bafbc21e4 Mon Sep 17 00:00:00 2001 From: Miquel de Domingo Date: Wed, 27 Nov 2024 12:02:00 +0100 Subject: [PATCH 5/8] docs: correct rule docs --- docs/rules/no-deprecated-raw-special-elements.md | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/docs/rules/no-deprecated-raw-special-elements.md b/docs/rules/no-deprecated-raw-special-elements.md index aa4254bfd..cc7f3a64c 100644 --- a/docs/rules/no-deprecated-raw-special-elements.md +++ b/docs/rules/no-deprecated-raw-special-elements.md @@ -7,14 +7,14 @@ description: 'Disallows valid Svelte 4 tags, that no are no longer valid in Svel # svelte/no-deprecated-raw-special-elements -> Disallows valid Svelte 4 tags, that no are no longer valid in Svelte 5 +> Recommends not using raw special elements in Svelte versions previous to 5. - :exclamation: **_This rule has not been released yet._** - :wrench: The `--fix` option on the [command line](https://eslint.org/docs/user-guide/command-line-interface#fixing-problems) can automatically fix some of the problems reported by this rule. ## :book: Rule Details -This rule reports the invalid usage of `head`, `body`, `window`, `document`, `element` and `options` HTML elements, **in Svelte 5**. These elements were valid in Svelte 4, but since Svelte 5 they must be used with `svelte:`. +This rule reports the usage of `head`, `body`, `window`, `document`, `element` and `options` HTML elements. These elements were valid in in versions proior to 5, but since Svelte 5 they must be used with `svelte:`. @@ -46,8 +46,6 @@ This rule reports the invalid usage of `head`, `body`, `window`, `document`, `el } ``` -- - ## :books: Further Reading - See special elements section in [Svelte docs](https://svelte.dev/docs/svelte/svelte-window) From 1be1e998c8a11cf6ada76e199bd4cb91d4f11b29 Mon Sep 17 00:00:00 2001 From: Miquel de Domingo Date: Wed, 27 Nov 2024 12:06:56 +0100 Subject: [PATCH 6/8] fix: correct rule description --- README.md | 2 +- docs/rules.md | 2 +- docs/rules/no-deprecated-raw-special-elements.md | 2 +- packages/eslint-plugin-svelte/src/rule-types.ts | 2 +- .../src/rules/no-deprecated-raw-special-elements.ts | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 19f265bd9..7c569527b 100644 --- a/README.md +++ b/README.md @@ -380,7 +380,7 @@ These rules relate to possible syntax or logic errors in Svelte code: | Rule ID | Description | | |:--------|:------------|:---| | [svelte/infinite-reactive-loop](https://sveltejs.github.io/eslint-plugin-svelte/rules/infinite-reactive-loop/) | Svelte runtime prevents calling the same reactive statement twice in a microtask. But between different microtask, it doesn't prevent. | | -| [svelte/no-deprecated-raw-special-elements](https://sveltejs.github.io/eslint-plugin-svelte/rules/no-deprecated-raw-special-elements/) | Disallows valid Svelte 4 tags, that no are no longer valid in Svelte 5 | :wrench: | +| [svelte/no-deprecated-raw-special-elements](https://sveltejs.github.io/eslint-plugin-svelte/rules/no-deprecated-raw-special-elements/) | Recommends not using raw special elements in Svelte versions previous to 5. | :wrench: | | [svelte/no-dom-manipulating](https://sveltejs.github.io/eslint-plugin-svelte/rules/no-dom-manipulating/) | disallow DOM manipulating | | | [svelte/no-dupe-else-if-blocks](https://sveltejs.github.io/eslint-plugin-svelte/rules/no-dupe-else-if-blocks/) | disallow duplicate conditions in `{#if}` / `{:else if}` chains | :star: | | [svelte/no-dupe-on-directives](https://sveltejs.github.io/eslint-plugin-svelte/rules/no-dupe-on-directives/) | disallow duplicate `on:` directives | | diff --git a/docs/rules.md b/docs/rules.md index 0859409d9..29701ff7e 100644 --- a/docs/rules.md +++ b/docs/rules.md @@ -17,7 +17,7 @@ These rules relate to possible syntax or logic errors in Svelte code: | Rule ID | Description | | | :------------------------------------------------------------------------------------------------------------- | :------------------------------------------------------------------------------------------------------------------------------------- | :------------- | | [svelte/infinite-reactive-loop](./rules/infinite-reactive-loop.md) | Svelte runtime prevents calling the same reactive statement twice in a microtask. But between different microtask, it doesn't prevent. | | -| [svelte/no-deprecated-raw-special-elements](./rules/no-deprecated-raw-special-elements.md) | Disallows valid Svelte 4 tags, that no are no longer valid in Svelte 5 | :wrench: | +| [svelte/no-deprecated-raw-special-elements](./rules/no-deprecated-raw-special-elements.md) | Recommends not using raw special elements in Svelte versions previous to 5. | :wrench: | | [svelte/no-dom-manipulating](./rules/no-dom-manipulating.md) | disallow DOM manipulating | | | [svelte/no-dupe-else-if-blocks](./rules/no-dupe-else-if-blocks.md) | disallow duplicate conditions in `{#if}` / `{:else if}` chains | :star: | | [svelte/no-dupe-on-directives](./rules/no-dupe-on-directives.md) | disallow duplicate `on:` directives | | diff --git a/docs/rules/no-deprecated-raw-special-elements.md b/docs/rules/no-deprecated-raw-special-elements.md index cc7f3a64c..7d9fb7aab 100644 --- a/docs/rules/no-deprecated-raw-special-elements.md +++ b/docs/rules/no-deprecated-raw-special-elements.md @@ -2,7 +2,7 @@ pageClass: 'rule-details' sidebarDepth: 0 title: 'svelte/no-deprecated-raw-special-elements' -description: 'Disallows valid Svelte 4 tags, that no are no longer valid in Svelte 5' +description: 'Recommends not using raw special elements in Svelte versions previous to 5.' --- # svelte/no-deprecated-raw-special-elements diff --git a/packages/eslint-plugin-svelte/src/rule-types.ts b/packages/eslint-plugin-svelte/src/rule-types.ts index 6297b9c0f..8b7cbe80c 100644 --- a/packages/eslint-plugin-svelte/src/rule-types.ts +++ b/packages/eslint-plugin-svelte/src/rule-types.ts @@ -105,7 +105,7 @@ export interface RuleOptions { */ 'svelte/no-at-html-tags'?: Linter.RuleEntry<[]> /** - * Disallows valid Svelte 4 tags, that no are no longer valid in Svelte 5 + * Recommends not using raw special elements in Svelte versions previous to 5. * @see https://sveltejs.github.io/eslint-plugin-svelte/rules/no-deprecated-raw-special-elements/ */ 'svelte/no-deprecated-raw-special-elements'?: Linter.RuleEntry<[]> diff --git a/packages/eslint-plugin-svelte/src/rules/no-deprecated-raw-special-elements.ts b/packages/eslint-plugin-svelte/src/rules/no-deprecated-raw-special-elements.ts index 676d577a7..d47ef72e1 100644 --- a/packages/eslint-plugin-svelte/src/rules/no-deprecated-raw-special-elements.ts +++ b/packages/eslint-plugin-svelte/src/rules/no-deprecated-raw-special-elements.ts @@ -7,7 +7,7 @@ const VALID_PREFIX = 'svelte:'; export default createRule('no-deprecated-raw-special-elements', { meta: { docs: { - description: 'Disallows valid Svelte 4 tags, that no are no longer valid in Svelte 5', + description: 'Recommends not using raw special elements in Svelte versions previous to 5.', category: 'Possible Errors', // TODO: Switch to recommended in the major version recommended: false From b83179dd1e4d58fcf946eabaa170a8fac7fae22c Mon Sep 17 00:00:00 2001 From: Yosuke Ota Date: Wed, 27 Nov 2024 21:30:41 +0900 Subject: [PATCH 7/8] Update lazy-eyes-wait.md --- .changeset/lazy-eyes-wait.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.changeset/lazy-eyes-wait.md b/.changeset/lazy-eyes-wait.md index 9af9d85a5..74f2c8611 100644 --- a/.changeset/lazy-eyes-wait.md +++ b/.changeset/lazy-eyes-wait.md @@ -2,4 +2,4 @@ 'eslint-plugin-svelte': minor --- -Added new `no-invalid-html-elements` rule +Added new `no-deprecated-raw-special-elements` rule From b0ee149904533ca3e014f2b8f6b564f6380de6f2 Mon Sep 17 00:00:00 2001 From: Yosuke Ota Date: Wed, 27 Nov 2024 21:33:32 +0900 Subject: [PATCH 8/8] Update no-deprecated-raw-special-elements.md --- docs/rules/no-deprecated-raw-special-elements.md | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/docs/rules/no-deprecated-raw-special-elements.md b/docs/rules/no-deprecated-raw-special-elements.md index 7d9fb7aab..4bf863ae6 100644 --- a/docs/rules/no-deprecated-raw-special-elements.md +++ b/docs/rules/no-deprecated-raw-special-elements.md @@ -22,17 +22,17 @@ This rule reports the usage of `head`, `body`, `window`, `document`, `element` a ```svelte - Invalid HTML Elements + Valid - Invalid HTML Elements + Invalid ``` @@ -40,11 +40,7 @@ This rule reports the usage of `head`, `body`, `window`, `document`, `element` a ## :wrench: Options -```json -{ - "svelte/no-invalid-html-elements": ["error", {}] -} -``` +Nothing. ## :books: Further Reading