Skip to content

Commit 5f7a741

Browse files
authored
Add no-unknown-style-directive-property rule (#128)
1 parent 7394202 commit 5f7a741

File tree

15 files changed

+248
-0
lines changed

15 files changed

+248
-0
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -248,6 +248,7 @@ These rules relate to possible syntax or logic errors in Svelte code:
248248
| [@ota-meshi/svelte/no-not-function-handler](https://ota-meshi.github.io/eslint-plugin-svelte/rules/no-not-function-handler/) | disallow use of not function in event handler | :star: |
249249
| [@ota-meshi/svelte/no-object-in-text-mustaches](https://ota-meshi.github.io/eslint-plugin-svelte/rules/no-object-in-text-mustaches/) | disallow objects in text mustache interpolation | :star: |
250250
| [@ota-meshi/svelte/no-shorthand-style-property-overrides](https://ota-meshi.github.io/eslint-plugin-svelte/rules/no-shorthand-style-property-overrides/) | disallow shorthand style properties that override related longhand properties | :star: |
251+
| [@ota-meshi/svelte/no-unknown-style-directive-property](https://ota-meshi.github.io/eslint-plugin-svelte/rules/no-unknown-style-directive-property/) | disallow unknown `style:property` | :star: |
251252
| [@ota-meshi/svelte/valid-compile](https://ota-meshi.github.io/eslint-plugin-svelte/rules/valid-compile/) | disallow warnings when compiling. | :star: |
252253

253254
## Security Vulnerability

docs/rules.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ These rules relate to possible syntax or logic errors in Svelte code:
2121
| [@ota-meshi/svelte/no-not-function-handler](./rules/no-not-function-handler.md) | disallow use of not function in event handler | :star: |
2222
| [@ota-meshi/svelte/no-object-in-text-mustaches](./rules/no-object-in-text-mustaches.md) | disallow objects in text mustache interpolation | :star: |
2323
| [@ota-meshi/svelte/no-shorthand-style-property-overrides](./rules/no-shorthand-style-property-overrides.md) | disallow shorthand style properties that override related longhand properties | :star: |
24+
| [@ota-meshi/svelte/no-unknown-style-directive-property](./rules/no-unknown-style-directive-property.md) | disallow unknown `style:property` | :star: |
2425
| [@ota-meshi/svelte/valid-compile](./rules/valid-compile.md) | disallow warnings when compiling. | :star: |
2526

2627
## Security Vulnerability

docs/rules/no-shorthand-style-property-overrides.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,12 @@ This rule was inspired by [Stylelint's declaration-block-no-shorthand-property-o
4545

4646
Nothing.
4747

48+
## :books: Further reading
49+
50+
- [Stylelint - declaration-block-no-shorthand-property-overrides]
51+
52+
[stylelint - declaration-block-no-shorthand-property-overrides]: https://stylelint.io/user-guide/rules/list/declaration-block-no-shorthand-property-overrides/
53+
4854
## :mag: Implementation
4955

5056
- [Rule source](https://github.com/ota-meshi/eslint-plugin-svelte/blob/main/src/rules/no-shorthand-style-property-overrides.ts)
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
---
2+
pageClass: "rule-details"
3+
sidebarDepth: 0
4+
title: "@ota-meshi/svelte/no-unknown-style-directive-property"
5+
description: "disallow unknown `style:property`"
6+
---
7+
8+
# @ota-meshi/svelte/no-unknown-style-directive-property
9+
10+
> disallow unknown `style:property`
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+
- :gear: This rule is included in `"plugin:@ota-meshi/svelte/recommended"`.
14+
15+
## :book: Rule Details
16+
17+
This rule reports an unknown CSS property in style directive.
18+
19+
This rule was inspired by [Stylelint's property-no-unknown rule](https://stylelint.io/user-guide/rules/list/property-no-unknown/).
20+
21+
Note that this rule only checks the `style:property` directive. If you want to check inside the `style` attribute and `style` element, consider introducing [Stylelint](https://stylelint.io/).
22+
23+
<ESLintCodeBlock>
24+
25+
<!--eslint-skip-->
26+
27+
```svelte
28+
<script>
29+
/* eslint @ota-meshi/svelte/no-unknown-style-directive-property: "error" */
30+
let red = "red"
31+
let color = red
32+
</script>
33+
34+
<!-- ✓ GOOD -->
35+
<div style:color={red}>...</div>
36+
<div style:color>...</div>
37+
38+
<!-- ✗ BAD -->
39+
<div style:unknown-color={red}>...</div>
40+
<div style:red>...</div>
41+
```
42+
43+
</ESLintCodeBlock>
44+
45+
## :wrench: Options
46+
47+
```json
48+
{
49+
"@ota-meshi/svelte/no-unknown-style-directive-property": [
50+
"error",
51+
{
52+
"ignoreProperties": [],
53+
"ignorePrefixed": true
54+
}
55+
]
56+
}
57+
```
58+
59+
- `ignoreProperties` ... You can specify property names or patterns that you want to ignore from checking.
60+
- `ignorePrefixed` ... If `true`, ignores properties with vendor prefix from checking. Default is `true`.
61+
62+
## :books: Further reading
63+
64+
- [Stylelint - property-no-unknown]
65+
66+
[stylelint - property-no-unknown]: https://stylelint.io/user-guide/rules/list/property-no-unknown/
67+
68+
## :mag: Implementation
69+
70+
- [Rule source](https://github.com/ota-meshi/eslint-plugin-svelte/blob/main/src/rules/no-unknown-style-directive-property.ts)
71+
- [Test source](https://github.com/ota-meshi/eslint-plugin-svelte/blob/main/tests/src/rules/no-unknown-style-directive-property.ts)

src/configs/recommended.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ export = {
1616
"@ota-meshi/svelte/no-not-function-handler": "error",
1717
"@ota-meshi/svelte/no-object-in-text-mustaches": "error",
1818
"@ota-meshi/svelte/no-shorthand-style-property-overrides": "error",
19+
"@ota-meshi/svelte/no-unknown-style-directive-property": "error",
1920
"@ota-meshi/svelte/no-unused-svelte-ignore": "error",
2021
"@ota-meshi/svelte/system": "error",
2122
"@ota-meshi/svelte/valid-compile": "error",
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
import { createRule } from "../utils"
2+
import { all as allKnownCSSProperties } from "known-css-properties"
3+
import { toRegExp } from "../utils/regexp"
4+
import { hasVendorPrefix } from "../utils/css-utils"
5+
6+
export default createRule("no-unknown-style-directive-property", {
7+
meta: {
8+
docs: {
9+
description: "disallow unknown `style:property`",
10+
category: "Possible Errors",
11+
recommended: true,
12+
},
13+
schema: [
14+
{
15+
type: "object",
16+
properties: {
17+
ignoreProperties: {
18+
type: "array",
19+
items: {
20+
type: "string",
21+
},
22+
uniqueItems: true,
23+
minItems: 1,
24+
},
25+
ignorePrefixed: { type: "boolean" },
26+
},
27+
additionalProperties: false,
28+
},
29+
],
30+
messages: {
31+
unknown: "Unexpected unknown style directive property '{{property}}'.",
32+
},
33+
type: "problem",
34+
},
35+
create(context) {
36+
const ignoreProperties = [
37+
...(context.options[0]?.ignoreProperties ?? []),
38+
].map(toRegExp)
39+
const ignorePrefixed: boolean = context.options[0]?.ignorePrefixed ?? true
40+
const knownProperties = new Set<string>(allKnownCSSProperties)
41+
42+
/** Checks whether given name is valid */
43+
function validName(name: string) {
44+
return (
45+
name.startsWith("--") ||
46+
knownProperties.has(name) ||
47+
ignoreProperties.some((r) => r.test(name)) ||
48+
(ignorePrefixed && hasVendorPrefix(name))
49+
)
50+
}
51+
52+
return {
53+
SvelteStyleDirective(node) {
54+
const prop = node.key.name
55+
56+
if (validName(prop.name)) {
57+
return
58+
}
59+
context.report({
60+
node: prop,
61+
messageId: "unknown",
62+
data: {
63+
property: prop.name,
64+
},
65+
})
66+
},
67+
}
68+
},
69+
})

src/utils/rules.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import noNotFunctionHandler from "../rules/no-not-function-handler"
1717
import noObjectInTextMustaches from "../rules/no-object-in-text-mustaches"
1818
import noShorthandStylePropertyOverrides from "../rules/no-shorthand-style-property-overrides"
1919
import noTargetBlank from "../rules/no-target-blank"
20+
import noUnknownStyleDirectiveProperty from "../rules/no-unknown-style-directive-property"
2021
import noUnusedSvelteIgnore from "../rules/no-unused-svelte-ignore"
2122
import noUselessMustaches from "../rules/no-useless-mustaches"
2223
import preferClassDirective from "../rules/prefer-class-directive"
@@ -46,6 +47,7 @@ export const rules = [
4647
noObjectInTextMustaches,
4748
noShorthandStylePropertyOverrides,
4849
noTargetBlank,
50+
noUnknownStyleDirectiveProperty,
4951
noUnusedSvelteIgnore,
5052
noUselessMustaches,
5153
preferClassDirective,
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"options": [{ "ignoreProperties": ["foo", "/^bar/"] }]
3+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
[
2+
{
3+
"message": "Unexpected unknown style directive property 'unknown-color'.",
4+
"line": 8,
5+
"column": 12
6+
},
7+
{
8+
"message": "Unexpected unknown style directive property 'unknown'.",
9+
"line": 9,
10+
"column": 12
11+
},
12+
{
13+
"message": "Unexpected unknown style directive property 'foo-bar'.",
14+
"line": 15,
15+
"column": 12
16+
}
17+
]
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
<script>
2+
let red = "red"
3+
let unknown = red
4+
let foo = red
5+
let bar = red
6+
</script>
7+
8+
<div style:unknown-color={red}>...</div>
9+
<div style:unknown>...</div>
10+
<div style:foo={red}>...</div>
11+
<div style:foo>...</div>
12+
<div style:bar={red}>...</div>
13+
<div style:bar>...</div>
14+
<div style:bar-foo={red}>...</div>
15+
<div style:foo-bar={red}>...</div>

0 commit comments

Comments
 (0)