diff --git a/.changeset/soft-bears-hear.md b/.changeset/soft-bears-hear.md
new file mode 100644
index 000000000..d54cb5bb7
--- /dev/null
+++ b/.changeset/soft-bears-hear.md
@@ -0,0 +1,5 @@
+---
+'eslint-plugin-svelte': major
+---
+
+feat!: Updated the `html-self-closing` rule to follow Svelte5
diff --git a/docs/rules/html-self-closing.md b/docs/rules/html-self-closing.md
index 18c131b68..0cb623119 100644
--- a/docs/rules/html-self-closing.md
+++ b/docs/rules/html-self-closing.md
@@ -14,10 +14,10 @@ since: 'v2.5.0'
## :book: Rule Details
-You can choose either two styles for elements without content
+You can choose either two styles for elements without content.
-- always: `
`
-- never: ``
+- always: ``
+- never: ``
@@ -28,18 +28,21 @@ You can choose either two styles for elements without content
-
Hello
-
+
+
+
+
-
-
-
-
+
+
+
+
+
```
@@ -52,7 +55,7 @@ presets:
{
"svelte/html-self-closing": [
"error",
- "all" // or "html" or "none"
+ "default" // or "all" or "html" or "none"
]
}
```
@@ -65,8 +68,9 @@ config object:
"error",
{
"void": "always", // or "never" or "ignore"
- "normal": "always", // or "never" or "ignore"
- "foreign": "always", // or "never" or "ignore"
+ "normal": "never", // or "always" or "ignore"
+ "svg": "always", // or "never" or "ignore"
+ "never": "never", // or "always" or "ignore"
"component": "always", // or "never" or "ignore"
"svelte": "always" // or "never" or "ignore"
}
@@ -76,23 +80,33 @@ config object:
presets:
-- `all` - all elements should be self closing (unless they have children)
-- `html` - html-compliant - only void elements and svelte special elements should be self closing
-- `none` - no elements should be self closing
+- `default` - MathML and non-void HTML elements should have a closing tag; otherwise, they should be self-closing.
+- `all` - all elements should be self-closing (unless they have children)
+- `html` - html-compliant - only void elements and svelte special elements should be self-closing
+- `none` - no elements should be self-closing
+
+::: warning Note
+We recommend selecting `default` as the preset. Choosing any other option may result in settings that are inconsistent with the compiler when using Svelte5.
+:::
config object:
- `void` (`"always"` in default preset)... Style of HTML void elements
-- `foreign` (`"always"` in default preset)... Style of foreign elements (SVG and MathML)
+- `normal` (`"never"` in default preset)... Style of other elements
+- `svg` (`"always"` in default preset)... Style of SVG
+- `math` (`never` in default preset)... Style of MathML
- `component` (`"always"` in default preset)... Style of svelte components
- `svelte` (`"always"` in default preset)... Style of svelte special elements (``, ``)
-- `normal` (`"always"` in default preset)... Style of other elements
-Every config oject option can be set to
+::: warning
+`foreign` is removed in `eslint-plugin-svelte` v3.
+:::
+
+Every config object option can be set to
-- "always" (``)
-- "never" (``)
-- "ignore" (either `` or ``)
+- "always" (``)
+- "never" (``)
+- "ignore" (either `` or ``)
## :rocket: Version
diff --git a/packages/eslint-plugin-svelte/src/rule-types.ts b/packages/eslint-plugin-svelte/src/rule-types.ts
index 438ec0ff7..3bc21b67f 100644
--- a/packages/eslint-plugin-svelte/src/rule-types.ts
+++ b/packages/eslint-plugin-svelte/src/rule-types.ts
@@ -419,7 +419,8 @@ type SvelteHtmlQuotes = []|[{
type SvelteHtmlSelfClosing = []|[({
void?: ("never" | "always" | "ignore")
normal?: ("never" | "always" | "ignore")
- foreign?: ("never" | "always" | "ignore")
+ svg?: ("never" | "always" | "ignore")
+ math?: ("never" | "always" | "ignore")
component?: ("never" | "always" | "ignore")
svelte?: ("never" | "always" | "ignore")
} | ("all" | "html" | "none"))]
diff --git a/packages/eslint-plugin-svelte/src/rules/html-self-closing.ts b/packages/eslint-plugin-svelte/src/rules/html-self-closing.ts
index 7e3d3ff98..13c8e324f 100644
--- a/packages/eslint-plugin-svelte/src/rules/html-self-closing.ts
+++ b/packages/eslint-plugin-svelte/src/rules/html-self-closing.ts
@@ -1,17 +1,23 @@
import type { AST } from 'svelte-eslint-parser';
import { createRule } from '../utils/index.js';
-import { getNodeName, isVoidHtmlElement, isForeignElement } from '../utils/ast-utils.js';
+import {
+ getNodeName,
+ isVoidHtmlElement,
+ isSvgElement,
+ isMathMLElement
+} from '../utils/ast-utils.js';
import { getSourceCode } from '../utils/compat.js';
const TYPE_MESSAGES = {
normal: 'HTML elements',
void: 'HTML void elements',
- foreign: 'foreign (SVG or MathML) elements',
+ svg: 'SVG elements',
+ math: 'MathML elements',
component: 'Svelte custom components',
svelte: 'Svelte special elements'
};
-type ElementTypes = 'normal' | 'void' | 'foreign' | 'component' | 'svelte';
+type ElementTypes = 'normal' | 'void' | 'svg' | 'math' | 'component' | 'svelte';
export default createRule('html-self-closing', {
meta: {
@@ -38,7 +44,10 @@ export default createRule('html-self-closing', {
normal: {
enum: ['never', 'always', 'ignore']
},
- foreign: {
+ svg: {
+ enum: ['never', 'always', 'ignore']
+ },
+ math: {
enum: ['never', 'always', 'ignore']
},
component: {
@@ -58,34 +67,49 @@ export default createRule('html-self-closing', {
]
},
create(context) {
+ // default
let options = {
void: 'always',
- normal: 'always',
- foreign: 'always',
+ normal: 'never',
+ svg: 'always',
+ math: 'never',
component: 'always',
svelte: 'always'
};
const option = context.options?.[0];
switch (option) {
- case 'none':
+ case 'all':
options = {
- void: 'never',
- normal: 'never',
- foreign: 'never',
- component: 'never',
- svelte: 'never'
+ void: 'always',
+ normal: 'always',
+ svg: 'always',
+ math: 'always',
+ component: 'always',
+ svelte: 'always'
};
break;
case 'html':
options = {
void: 'always',
normal: 'never',
- foreign: 'always',
+ svg: 'always',
+ math: 'never',
component: 'never',
svelte: 'always'
};
break;
+ case 'none':
+ options = {
+ void: 'never',
+ normal: 'never',
+ svg: 'never',
+ math: 'never',
+ component: 'never',
+ svelte: 'never'
+ };
+ break;
+
default:
if (typeof option !== 'object' || option === null) break;
@@ -108,7 +132,8 @@ export default createRule('html-self-closing', {
if (node.kind === 'component') return 'component';
if (node.kind === 'special') return 'svelte';
if (isVoidHtmlElement(node)) return 'void';
- if (isForeignElement(node)) return 'foreign';
+ if (isSvgElement(node)) return 'svg';
+ if (isMathMLElement(node)) return 'math';
return 'normal';
}
diff --git a/packages/eslint-plugin-svelte/src/utils/ast-utils.ts b/packages/eslint-plugin-svelte/src/utils/ast-utils.ts
index d12e56e88..e844ab842 100644
--- a/packages/eslint-plugin-svelte/src/utils/ast-utils.ts
+++ b/packages/eslint-plugin-svelte/src/utils/ast-utils.ts
@@ -567,6 +567,14 @@ export function isForeignElement(node: SvAST.SvelteElement): boolean {
return svgElements.includes(getNodeName(node)) || mathmlElements.includes(getNodeName(node));
}
+export function isSvgElement(node: SvAST.SvelteElement): boolean {
+ return svgElements.includes(getNodeName(node));
+}
+
+export function isMathMLElement(node: SvAST.SvelteElement): boolean {
+ return mathmlElements.includes(getNodeName(node));
+}
+
/** Checks whether the given identifier node is used as an expression. */
export function isExpressionIdentifier(node: TSESTree.Identifier): boolean {
const parent = node.parent;
diff --git a/packages/eslint-plugin-svelte/tests/fixtures/rules/html-self-closing/invalid/foreign-never/svelte-never-errors.yaml b/packages/eslint-plugin-svelte/tests/fixtures/rules/html-self-closing/invalid/foreign-never/svelte-never-errors.yaml
deleted file mode 100644
index a2e0ece09..000000000
--- a/packages/eslint-plugin-svelte/tests/fixtures/rules/html-self-closing/invalid/foreign-never/svelte-never-errors.yaml
+++ /dev/null
@@ -1,8 +0,0 @@
-- message: Disallow self-closing on foreign (SVG or MathML) elements.
- line: 2
- column: 12
- suggestions: null
-- message: Disallow self-closing on foreign (SVG or MathML) elements.
- line: 3
- column: 13
- suggestions: null
diff --git a/packages/eslint-plugin-svelte/tests/fixtures/rules/html-self-closing/invalid/foreign-never/_config.json b/packages/eslint-plugin-svelte/tests/fixtures/rules/html-self-closing/invalid/math-never/_config.json
similarity index 56%
rename from packages/eslint-plugin-svelte/tests/fixtures/rules/html-self-closing/invalid/foreign-never/_config.json
rename to packages/eslint-plugin-svelte/tests/fixtures/rules/html-self-closing/invalid/math-never/_config.json
index 6081aab9f..f40ed66a5 100644
--- a/packages/eslint-plugin-svelte/tests/fixtures/rules/html-self-closing/invalid/foreign-never/_config.json
+++ b/packages/eslint-plugin-svelte/tests/fixtures/rules/html-self-closing/invalid/math-never/_config.json
@@ -1,7 +1,7 @@
{
"options": [
{
- "foreign": "never"
+ "math": "never"
}
]
}
diff --git a/packages/eslint-plugin-svelte/tests/fixtures/rules/html-self-closing/invalid/math-never/svelte-never-errors.yaml b/packages/eslint-plugin-svelte/tests/fixtures/rules/html-self-closing/invalid/math-never/svelte-never-errors.yaml
new file mode 100644
index 000000000..382d8779d
--- /dev/null
+++ b/packages/eslint-plugin-svelte/tests/fixtures/rules/html-self-closing/invalid/math-never/svelte-never-errors.yaml
@@ -0,0 +1,4 @@
+- message: Disallow self-closing on MathML elements.
+ line: 3
+ column: 13
+ suggestions: null
diff --git a/packages/eslint-plugin-svelte/tests/fixtures/rules/html-self-closing/invalid/foreign-never/svelte-never-input.svelte b/packages/eslint-plugin-svelte/tests/fixtures/rules/html-self-closing/invalid/math-never/svelte-never-input.svelte
similarity index 100%
rename from packages/eslint-plugin-svelte/tests/fixtures/rules/html-self-closing/invalid/foreign-never/svelte-never-input.svelte
rename to packages/eslint-plugin-svelte/tests/fixtures/rules/html-self-closing/invalid/math-never/svelte-never-input.svelte
diff --git a/packages/eslint-plugin-svelte/tests/fixtures/rules/html-self-closing/invalid/foreign-never/svelte-never-output.svelte b/packages/eslint-plugin-svelte/tests/fixtures/rules/html-self-closing/invalid/math-never/svelte-never-output.svelte
similarity index 67%
rename from packages/eslint-plugin-svelte/tests/fixtures/rules/html-self-closing/invalid/foreign-never/svelte-never-output.svelte
rename to packages/eslint-plugin-svelte/tests/fixtures/rules/html-self-closing/invalid/math-never/svelte-never-output.svelte
index 76223b771..3e19b1ce6 100644
--- a/packages/eslint-plugin-svelte/tests/fixtures/rules/html-self-closing/invalid/foreign-never/svelte-never-output.svelte
+++ b/packages/eslint-plugin-svelte/tests/fixtures/rules/html-self-closing/invalid/math-never/svelte-never-output.svelte
@@ -1,3 +1,3 @@
-
+
diff --git a/packages/eslint-plugin-svelte/tests/fixtures/rules/html-self-closing/invalid/normal-always/_config.json b/packages/eslint-plugin-svelte/tests/fixtures/rules/html-self-closing/invalid/normal-always/_config.json
new file mode 100644
index 000000000..211f2f072
--- /dev/null
+++ b/packages/eslint-plugin-svelte/tests/fixtures/rules/html-self-closing/invalid/normal-always/_config.json
@@ -0,0 +1,7 @@
+{
+ "options": [
+ {
+ "normal": "always"
+ }
+ ]
+}
diff --git a/packages/eslint-plugin-svelte/tests/fixtures/rules/html-self-closing/invalid/normal-always/component-never-errors.yaml b/packages/eslint-plugin-svelte/tests/fixtures/rules/html-self-closing/invalid/normal-always/component-never-errors.yaml
new file mode 100644
index 000000000..d25b212b4
--- /dev/null
+++ b/packages/eslint-plugin-svelte/tests/fixtures/rules/html-self-closing/invalid/normal-always/component-never-errors.yaml
@@ -0,0 +1,4 @@
+- message: Require self-closing on HTML elements.
+ line: 3
+ column: 7
+ suggestions: null
diff --git a/packages/eslint-plugin-svelte/tests/fixtures/rules/html-self-closing/invalid/normal-always/component-never-input.svelte b/packages/eslint-plugin-svelte/tests/fixtures/rules/html-self-closing/invalid/normal-always/component-never-input.svelte
new file mode 100644
index 000000000..d594af233
--- /dev/null
+++ b/packages/eslint-plugin-svelte/tests/fixtures/rules/html-self-closing/invalid/normal-always/component-never-input.svelte
@@ -0,0 +1,4 @@
+
+
+
+
diff --git a/packages/eslint-plugin-svelte/tests/fixtures/rules/html-self-closing/invalid/normal-always/component-never-output.svelte b/packages/eslint-plugin-svelte/tests/fixtures/rules/html-self-closing/invalid/normal-always/component-never-output.svelte
new file mode 100644
index 000000000..a1b0b4598
--- /dev/null
+++ b/packages/eslint-plugin-svelte/tests/fixtures/rules/html-self-closing/invalid/normal-always/component-never-output.svelte
@@ -0,0 +1,4 @@
+
+