diff --git a/README.md b/README.md index b2e746eeb..cf840ced8 100644 --- a/README.md +++ b/README.md @@ -296,6 +296,7 @@ These rules relate to style guidelines, and are therefore quite subjective: | [svelte/indent](https://ota-meshi.github.io/eslint-plugin-svelte/rules/indent/) | enforce consistent indentation | :wrench: | | [svelte/max-attributes-per-line](https://ota-meshi.github.io/eslint-plugin-svelte/rules/max-attributes-per-line/) | enforce the maximum number of attributes per line | :wrench: | | [svelte/mustache-spacing](https://ota-meshi.github.io/eslint-plugin-svelte/rules/mustache-spacing/) | enforce unified spacing in mustache | :wrench: | +| [svelte/no-spaces-around-equal-signs-in-attribute](https://ota-meshi.github.io/eslint-plugin-svelte/rules/no-spaces-around-equal-signs-in-attribute/) | disallow spaces around equal signs in attribute | :wrench: | | [svelte/prefer-class-directive](https://ota-meshi.github.io/eslint-plugin-svelte/rules/prefer-class-directive/) | require class directives instead of ternary expressions | :wrench: | | [svelte/prefer-style-directive](https://ota-meshi.github.io/eslint-plugin-svelte/rules/prefer-style-directive/) | require style directives instead of style attribute | :wrench: | | [svelte/shorthand-attribute](https://ota-meshi.github.io/eslint-plugin-svelte/rules/shorthand-attribute/) | enforce use of shorthand syntax in attribute | :wrench: | diff --git a/docs/rules.md b/docs/rules.md index 70a940c90..21f7a79dc 100644 --- a/docs/rules.md +++ b/docs/rules.md @@ -56,6 +56,7 @@ These rules relate to style guidelines, and are therefore quite subjective: | [svelte/indent](./rules/indent.md) | enforce consistent indentation | :wrench: | | [svelte/max-attributes-per-line](./rules/max-attributes-per-line.md) | enforce the maximum number of attributes per line | :wrench: | | [svelte/mustache-spacing](./rules/mustache-spacing.md) | enforce unified spacing in mustache | :wrench: | +| [svelte/no-spaces-around-equal-signs-in-attribute](./rules/no-spaces-around-equal-signs-in-attribute.md) | disallow spaces around equal signs in attribute | :wrench: | | [svelte/prefer-class-directive](./rules/prefer-class-directive.md) | require class directives instead of ternary expressions | :wrench: | | [svelte/prefer-style-directive](./rules/prefer-style-directive.md) | require style directives instead of style attribute | :wrench: | | [svelte/shorthand-attribute](./rules/shorthand-attribute.md) | enforce use of shorthand syntax in attribute | :wrench: | diff --git a/docs/rules/no-spaces-around-equal-signs-in-attribute.md b/docs/rules/no-spaces-around-equal-signs-in-attribute.md new file mode 100644 index 000000000..f577ce873 --- /dev/null +++ b/docs/rules/no-spaces-around-equal-signs-in-attribute.md @@ -0,0 +1,57 @@ +--- +pageClass: "rule-details" +sidebarDepth: 0 +title: "svelte/no-spaces-around-equal-signs-in-attribute" +description: "disallow spaces around equal signs in attribute" +--- + +# svelte/no-spaces-around-equal-signs-in-attribute + +> disallow spaces around equal signs in attribute + +- :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 disallows spaces around equal signs in attributes + + + + + + +```svelte + + + +
+

hi

+A photo of a very cute {animal} + + +
+

hi

+A photo of a very cute {animal} +``` + + + + + +## :wrench: Options + +```json +{ + "svelte/no-spaces-around-equal-signs-in-attribute": ["error"] +} +``` + +## :mag: Implementation + +- [Rule source](https://github.com/ota-meshi/eslint-plugin-svelte/blob/main/src/rules/no-spaces-around-equal-signs-in-attribute.ts) +- [Test source](https://github.com/ota-meshi/eslint-plugin-svelte/blob/main/tests/src/rules/no-spaces-around-equal-signs-in-attribute.ts) diff --git a/src/configs/prettier.ts b/src/configs/prettier.ts index 6c0eba387..58795f609 100644 --- a/src/configs/prettier.ts +++ b/src/configs/prettier.ts @@ -11,6 +11,7 @@ export = { "svelte/indent": "off", "svelte/max-attributes-per-line": "off", "svelte/mustache-spacing": "off", + "svelte/no-spaces-around-equal-signs-in-attribute": "off", "svelte/shorthand-attribute": "off", "svelte/shorthand-directive": "off", }, diff --git a/src/rules/no-spaces-around-equal-signs-in-attribute.ts b/src/rules/no-spaces-around-equal-signs-in-attribute.ts new file mode 100644 index 000000000..a0256f20c --- /dev/null +++ b/src/rules/no-spaces-around-equal-signs-in-attribute.ts @@ -0,0 +1,74 @@ +import { createRule } from "../utils" +import type { AST } from "svelte-eslint-parser" + +export default createRule("no-spaces-around-equal-signs-in-attribute", { + meta: { + docs: { + description: "disallow spaces around equal signs in attribute", + category: "Stylistic Issues", + recommended: false, + conflictWithPrettier: true, + }, + schema: {}, + fixable: "whitespace", + messages: { + noSpaces: "Unexpected spaces found around equal signs.", + }, + type: "layout", + }, + create(ctx) { + const source = ctx.getSourceCode() + + /** + * Returns source text between attribute key and value, and range of that source + */ + function getAttrEq( + node: + | AST.SvelteAttribute + | AST.SvelteDirective + | AST.SvelteStyleDirective + | AST.SvelteSpecialDirective, + ): [string, AST.Range] { + const keyRange = node.key.range + const eqSource = /^[\s=]*/u.exec( + source.text.slice(keyRange[1], node.range[1]), + )![0] + const valueStart = keyRange[1] + eqSource.length + return [eqSource, [keyRange[1], valueStart]] + } + + /** + * Returns true if string contains whitespace characters + */ + function containsWhitespace(string: string): boolean { + return /\s/u.test(string) + } + + return { + "SvelteAttribute, SvelteDirective, SvelteStyleDirective, SvelteSpecialDirective"( + node: + | AST.SvelteAttribute + | AST.SvelteDirective + | AST.SvelteStyleDirective + | AST.SvelteSpecialDirective, + ) { + const [eqSource, range] = getAttrEq(node) + + if (!containsWhitespace(eqSource)) return + + const loc = { + start: source.getLocFromIndex(range[0]), + end: source.getLocFromIndex(range[1]), + } + + ctx.report({ + loc, + messageId: "noSpaces", + *fix(fixer) { + yield fixer.replaceTextRange(range, "=") + }, + }) + }, + } + }, +}) diff --git a/src/utils/rules.ts b/src/utils/rules.ts index 19fe075fd..fad23ea56 100644 --- a/src/utils/rules.ts +++ b/src/utils/rules.ts @@ -15,6 +15,7 @@ import noInnerDeclarations from "../rules/no-inner-declarations" import noNotFunctionHandler from "../rules/no-not-function-handler" import noObjectInTextMustaches from "../rules/no-object-in-text-mustaches" import noShorthandStylePropertyOverrides from "../rules/no-shorthand-style-property-overrides" +import noSpacesAroundEqualSignsInAttribute from "../rules/no-spaces-around-equal-signs-in-attribute" import noTargetBlank from "../rules/no-target-blank" import noUnknownStyleDirectiveProperty from "../rules/no-unknown-style-directive-property" import noUnusedSvelteIgnore from "../rules/no-unused-svelte-ignore" @@ -45,6 +46,7 @@ export const rules = [ noNotFunctionHandler, noObjectInTextMustaches, noShorthandStylePropertyOverrides, + noSpacesAroundEqualSignsInAttribute, noTargetBlank, noUnknownStyleDirectiveProperty, noUnusedSvelteIgnore, diff --git a/tests/fixtures/rules/no-spaces-around-equal-signs-in-attribute/invalid/test01-errors.json b/tests/fixtures/rules/no-spaces-around-equal-signs-in-attribute/invalid/test01-errors.json new file mode 100644 index 000000000..13e58e4ba --- /dev/null +++ b/tests/fixtures/rules/no-spaces-around-equal-signs-in-attribute/invalid/test01-errors.json @@ -0,0 +1,62 @@ +[ + { + "message": "Unexpected spaces found around equal signs.", + "line": 3, + "column": 11 + }, + { + "message": "Unexpected spaces found around equal signs.", + "line": 4, + "column": 11 + }, + { + "message": "Unexpected spaces found around equal signs.", + "line": 5, + "column": 11 + }, + { + "message": "Unexpected spaces found around equal signs.", + "line": 6, + "column": 11 + }, + { + "message": "Unexpected spaces found around equal signs.", + "line": 8, + "column": 11 + }, + { + "message": "Unexpected spaces found around equal signs.", + "line": 10, + "column": 11 + }, + { + "message": "Unexpected spaces found around equal signs.", + "line": 11, + "column": 11 + }, + { + "message": "Unexpected spaces found around equal signs.", + "line": 12, + "column": 11 + }, + { + "message": "Unexpected spaces found around equal signs.", + "line": 13, + "column": 15 + }, + { + "message": "Unexpected spaces found around equal signs.", + "line": 13, + "column": 35 + }, + { + "message": "Unexpected spaces found around equal signs.", + "line": 14, + "column": 17 + }, + { + "message": "Unexpected spaces found around equal signs.", + "line": 16, + "column": 10 + } +] diff --git a/tests/fixtures/rules/no-spaces-around-equal-signs-in-attribute/invalid/test01-input.svelte b/tests/fixtures/rules/no-spaces-around-equal-signs-in-attribute/invalid/test01-input.svelte new file mode 100644 index 000000000..fe93f6495 --- /dev/null +++ b/tests/fixtures/rules/no-spaces-around-equal-signs-in-attribute/invalid/test01-input.svelte @@ -0,0 +1,17 @@ + +
+

+

+

+

+

+

+

+

+

+

+ +

+

diff --git a/tests/fixtures/rules/no-spaces-around-equal-signs-in-attribute/invalid/test01-output.svelte b/tests/fixtures/rules/no-spaces-around-equal-signs-in-attribute/invalid/test01-output.svelte new file mode 100644 index 000000000..adbfdf361 --- /dev/null +++ b/tests/fixtures/rules/no-spaces-around-equal-signs-in-attribute/invalid/test01-output.svelte @@ -0,0 +1,15 @@ + +
+

+

+

+

+

+

+

+

+

+

+ +

+

diff --git a/tests/fixtures/rules/no-spaces-around-equal-signs-in-attribute/valid/test-01-input.svelte b/tests/fixtures/rules/no-spaces-around-equal-signs-in-attribute/valid/test-01-input.svelte new file mode 100644 index 000000000..f3760fe71 --- /dev/null +++ b/tests/fixtures/rules/no-spaces-around-equal-signs-in-attribute/valid/test-01-input.svelte @@ -0,0 +1,4 @@ +

+

+ +

diff --git a/tests/src/rules/no-spaces-around-equal-signs-in-attribute.ts b/tests/src/rules/no-spaces-around-equal-signs-in-attribute.ts new file mode 100644 index 000000000..edd7fe8bf --- /dev/null +++ b/tests/src/rules/no-spaces-around-equal-signs-in-attribute.ts @@ -0,0 +1,16 @@ +import { RuleTester } from "eslint" +import rule from "../../../src/rules/no-spaces-around-equal-signs-in-attribute" +import { loadTestCases } from "../../utils/utils" + +const tester = new RuleTester({ + parserOptions: { + ecmaVersion: 2020, + sourceType: "module", + }, +}) + +tester.run( + "no-spaces-around-equal-signs-in-attribute", + rule as any, + loadTestCases("no-spaces-around-equal-signs-in-attribute"), +)