Skip to content

Commit 1f73a20

Browse files
authored
feat: add svelte/no-spaces-around-equal-signs-in-attribute (#191)
* feat: add `svelte/no-spaces-around-equal-signs-in-attribute` Moved to separate PR from #186 * chore: requested changes
1 parent 9b4969c commit 1f73a20

File tree

11 files changed

+250
-0
lines changed

11 files changed

+250
-0
lines changed

README.md

+1
Original file line numberDiff line numberDiff line change
@@ -296,6 +296,7 @@ These rules relate to style guidelines, and are therefore quite subjective:
296296
| [svelte/indent](https://ota-meshi.github.io/eslint-plugin-svelte/rules/indent/) | enforce consistent indentation | :wrench: |
297297
| [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: |
298298
| [svelte/mustache-spacing](https://ota-meshi.github.io/eslint-plugin-svelte/rules/mustache-spacing/) | enforce unified spacing in mustache | :wrench: |
299+
| [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: |
299300
| [svelte/prefer-class-directive](https://ota-meshi.github.io/eslint-plugin-svelte/rules/prefer-class-directive/) | require class directives instead of ternary expressions | :wrench: |
300301
| [svelte/prefer-style-directive](https://ota-meshi.github.io/eslint-plugin-svelte/rules/prefer-style-directive/) | require style directives instead of style attribute | :wrench: |
301302
| [svelte/shorthand-attribute](https://ota-meshi.github.io/eslint-plugin-svelte/rules/shorthand-attribute/) | enforce use of shorthand syntax in attribute | :wrench: |

docs/rules.md

+1
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ These rules relate to style guidelines, and are therefore quite subjective:
5656
| [svelte/indent](./rules/indent.md) | enforce consistent indentation | :wrench: |
5757
| [svelte/max-attributes-per-line](./rules/max-attributes-per-line.md) | enforce the maximum number of attributes per line | :wrench: |
5858
| [svelte/mustache-spacing](./rules/mustache-spacing.md) | enforce unified spacing in mustache | :wrench: |
59+
| [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: |
5960
| [svelte/prefer-class-directive](./rules/prefer-class-directive.md) | require class directives instead of ternary expressions | :wrench: |
6061
| [svelte/prefer-style-directive](./rules/prefer-style-directive.md) | require style directives instead of style attribute | :wrench: |
6162
| [svelte/shorthand-attribute](./rules/shorthand-attribute.md) | enforce use of shorthand syntax in attribute | :wrench: |
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
---
2+
pageClass: "rule-details"
3+
sidebarDepth: 0
4+
title: "svelte/no-spaces-around-equal-signs-in-attribute"
5+
description: "disallow spaces around equal signs in attribute"
6+
---
7+
8+
# svelte/no-spaces-around-equal-signs-in-attribute
9+
10+
> disallow spaces around equal signs in attribute
11+
12+
- :exclamation: <badge text="This rule has not been released yet." vertical="middle" type="error"> **_This rule has not been released yet._** </badge>
13+
- :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.
14+
15+
## :book: Rule Details
16+
17+
This rule disallows spaces around equal signs in attributes
18+
19+
<ESLintCodeBlock fix>
20+
21+
<!-- prettier-ignore-start -->
22+
<!--eslint-skip-->
23+
24+
```svelte
25+
<script>
26+
/* eslint svelte/no-spaces-around-equal-signs-in-attribute: "error" */
27+
</script>
28+
29+
<!-- ✓ GOOD -->
30+
<div class=""/>
31+
<p style="color: red;">hi</p>
32+
<img src="img.png" alt="A photo of a very cute {animal}">
33+
34+
<!-- ✗ BAD -->
35+
<div class = ""/>
36+
<p style ="color: red;">hi</p>
37+
<img src
38+
=
39+
"img.png" alt = "A photo of a very cute {animal}">
40+
```
41+
42+
<!-- prettier-ignore-end -->
43+
44+
</ESLintCodeBlock>
45+
46+
## :wrench: Options
47+
48+
```json
49+
{
50+
"svelte/no-spaces-around-equal-signs-in-attribute": ["error"]
51+
}
52+
```
53+
54+
## :mag: Implementation
55+
56+
- [Rule source](https://github.com/ota-meshi/eslint-plugin-svelte/blob/main/src/rules/no-spaces-around-equal-signs-in-attribute.ts)
57+
- [Test source](https://github.com/ota-meshi/eslint-plugin-svelte/blob/main/tests/src/rules/no-spaces-around-equal-signs-in-attribute.ts)

src/configs/prettier.ts

+1
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ export = {
1111
"svelte/indent": "off",
1212
"svelte/max-attributes-per-line": "off",
1313
"svelte/mustache-spacing": "off",
14+
"svelte/no-spaces-around-equal-signs-in-attribute": "off",
1415
"svelte/shorthand-attribute": "off",
1516
"svelte/shorthand-directive": "off",
1617
},
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
import { createRule } from "../utils"
2+
import type { AST } from "svelte-eslint-parser"
3+
4+
export default createRule("no-spaces-around-equal-signs-in-attribute", {
5+
meta: {
6+
docs: {
7+
description: "disallow spaces around equal signs in attribute",
8+
category: "Stylistic Issues",
9+
recommended: false,
10+
conflictWithPrettier: true,
11+
},
12+
schema: {},
13+
fixable: "whitespace",
14+
messages: {
15+
noSpaces: "Unexpected spaces found around equal signs.",
16+
},
17+
type: "layout",
18+
},
19+
create(ctx) {
20+
const source = ctx.getSourceCode()
21+
22+
/**
23+
* Returns source text between attribute key and value, and range of that source
24+
*/
25+
function getAttrEq(
26+
node:
27+
| AST.SvelteAttribute
28+
| AST.SvelteDirective
29+
| AST.SvelteStyleDirective
30+
| AST.SvelteSpecialDirective,
31+
): [string, AST.Range] {
32+
const keyRange = node.key.range
33+
const eqSource = /^[\s=]*/u.exec(
34+
source.text.slice(keyRange[1], node.range[1]),
35+
)![0]
36+
const valueStart = keyRange[1] + eqSource.length
37+
return [eqSource, [keyRange[1], valueStart]]
38+
}
39+
40+
/**
41+
* Returns true if string contains whitespace characters
42+
*/
43+
function containsWhitespace(string: string): boolean {
44+
return /\s/u.test(string)
45+
}
46+
47+
return {
48+
"SvelteAttribute, SvelteDirective, SvelteStyleDirective, SvelteSpecialDirective"(
49+
node:
50+
| AST.SvelteAttribute
51+
| AST.SvelteDirective
52+
| AST.SvelteStyleDirective
53+
| AST.SvelteSpecialDirective,
54+
) {
55+
const [eqSource, range] = getAttrEq(node)
56+
57+
if (!containsWhitespace(eqSource)) return
58+
59+
const loc = {
60+
start: source.getLocFromIndex(range[0]),
61+
end: source.getLocFromIndex(range[1]),
62+
}
63+
64+
ctx.report({
65+
loc,
66+
messageId: "noSpaces",
67+
*fix(fixer) {
68+
yield fixer.replaceTextRange(range, "=")
69+
},
70+
})
71+
},
72+
}
73+
},
74+
})

src/utils/rules.ts

+2
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import noInnerDeclarations from "../rules/no-inner-declarations"
1515
import noNotFunctionHandler from "../rules/no-not-function-handler"
1616
import noObjectInTextMustaches from "../rules/no-object-in-text-mustaches"
1717
import noShorthandStylePropertyOverrides from "../rules/no-shorthand-style-property-overrides"
18+
import noSpacesAroundEqualSignsInAttribute from "../rules/no-spaces-around-equal-signs-in-attribute"
1819
import noTargetBlank from "../rules/no-target-blank"
1920
import noUnknownStyleDirectiveProperty from "../rules/no-unknown-style-directive-property"
2021
import noUnusedSvelteIgnore from "../rules/no-unused-svelte-ignore"
@@ -45,6 +46,7 @@ export const rules = [
4546
noNotFunctionHandler,
4647
noObjectInTextMustaches,
4748
noShorthandStylePropertyOverrides,
49+
noSpacesAroundEqualSignsInAttribute,
4850
noTargetBlank,
4951
noUnknownStyleDirectiveProperty,
5052
noUnusedSvelteIgnore,
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
[
2+
{
3+
"message": "Unexpected spaces found around equal signs.",
4+
"line": 3,
5+
"column": 11
6+
},
7+
{
8+
"message": "Unexpected spaces found around equal signs.",
9+
"line": 4,
10+
"column": 11
11+
},
12+
{
13+
"message": "Unexpected spaces found around equal signs.",
14+
"line": 5,
15+
"column": 11
16+
},
17+
{
18+
"message": "Unexpected spaces found around equal signs.",
19+
"line": 6,
20+
"column": 11
21+
},
22+
{
23+
"message": "Unexpected spaces found around equal signs.",
24+
"line": 8,
25+
"column": 11
26+
},
27+
{
28+
"message": "Unexpected spaces found around equal signs.",
29+
"line": 10,
30+
"column": 11
31+
},
32+
{
33+
"message": "Unexpected spaces found around equal signs.",
34+
"line": 11,
35+
"column": 11
36+
},
37+
{
38+
"message": "Unexpected spaces found around equal signs.",
39+
"line": 12,
40+
"column": 11
41+
},
42+
{
43+
"message": "Unexpected spaces found around equal signs.",
44+
"line": 13,
45+
"column": 15
46+
},
47+
{
48+
"message": "Unexpected spaces found around equal signs.",
49+
"line": 13,
50+
"column": 35
51+
},
52+
{
53+
"message": "Unexpected spaces found around equal signs.",
54+
"line": 14,
55+
"column": 17
56+
},
57+
{
58+
"message": "Unexpected spaces found around equal signs.",
59+
"line": 16,
60+
"column": 10
61+
}
62+
]
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
<!-- prettier-ignore -->
2+
<div>
3+
<p class = "h"></p>
4+
<p class ="e"></p>
5+
<p class= "l"></p>
6+
<p class=
7+
"l"></p>
8+
<p class
9+
= "o"></p>
10+
<p class= "="></p>
11+
<p class= a></p>
12+
<p class= a></p>
13+
<p bind:test= {value} bind:test2 = {value} />
14+
<p style:width ="10px" />
15+
<!-- prettier-ignore -->
16+
<p this = {expression} />
17+
</div>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
<!-- prettier-ignore -->
2+
<div>
3+
<p class="h"></p>
4+
<p class="e"></p>
5+
<p class="l"></p>
6+
<p class="l"></p>
7+
<p class="o"></p>
8+
<p class="="></p>
9+
<p class=a></p>
10+
<p class=a></p>
11+
<p bind:test={value} bind:test2={value} />
12+
<p style:width="10px" />
13+
<!-- prettier-ignore -->
14+
<p this={expression} />
15+
</div>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
<p class="test" style="" bind:test={value} />
2+
<p class="test2" style style:width="10px" />
3+
<!-- prettier-ignore -->
4+
<p class=p this={expression} />
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import { RuleTester } from "eslint"
2+
import rule from "../../../src/rules/no-spaces-around-equal-signs-in-attribute"
3+
import { loadTestCases } from "../../utils/utils"
4+
5+
const tester = new RuleTester({
6+
parserOptions: {
7+
ecmaVersion: 2020,
8+
sourceType: "module",
9+
},
10+
})
11+
12+
tester.run(
13+
"no-spaces-around-equal-signs-in-attribute",
14+
rule as any,
15+
loadTestCases("no-spaces-around-equal-signs-in-attribute"),
16+
)

0 commit comments

Comments
 (0)