Skip to content

Commit 54cd80e

Browse files
committed
Rename html-attributes-casing -> attribute-hyphenation
Update implementation
1 parent 2466553 commit 54cd80e

File tree

6 files changed

+238
-290
lines changed

6 files changed

+238
-290
lines changed

docs/rules/attribute-hyphenation.md

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
# Define if attributes on cusom components can be hyphened. (attribute-hyphenation)
2+
3+
## :wrench: Options
4+
5+
Default casing is set to `allways`
6+
7+
```
8+
'vue/attribute-hyphenation': [2, 'allways'|'never']
9+
```
10+
11+
### `"always"` - Use hyphenated name. (It errors on upper case letters.)
12+
13+
:+1: Examples of **correct** code`:
14+
15+
```html
16+
<template>
17+
<foo my-prop="prop">
18+
<a onClick="retrun false"></a>
19+
</foo>
20+
</template>
21+
```
22+
23+
:-1: Examples of **incorrect** code`:
24+
25+
```html
26+
<template>
27+
<foo myProp="prop">
28+
<a onClick="retrun false"></a>
29+
</foo>
30+
</template>
31+
```
32+
33+
### `"never"` - Don't use hyphenated name. (It errors on hyphens except `data-` and `aria-`.)
34+
35+
:+1: Examples of **correct** code`:
36+
37+
```html
38+
<template>
39+
<foo myProp="prop">
40+
<a onClick="retrun false"></a>
41+
</foo>
42+
</template>
43+
```
44+
45+
:-1: Examples of **incorrect** code`:
46+
47+
```html
48+
<template>
49+
<foo my-prop="prop">
50+
<a onClick="retrun false"></a>
51+
</foo>
52+
</template>
53+
```

docs/rules/html-attributes-casing.md

Lines changed: 0 additions & 35 deletions
This file was deleted.

lib/rules/attribute-hyphenation.js

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
/**
2+
* @fileoverview Define a style for the props casing in templates.
3+
* @author Armano
4+
*/
5+
'use strict'
6+
7+
const utils = require('../utils')
8+
const casing = require('../utils/casing')
9+
10+
// ------------------------------------------------------------------------------
11+
// Rule Definition
12+
// ------------------------------------------------------------------------------
13+
14+
function create (context) {
15+
const sourceCode = context.getSourceCode()
16+
const options = context.options[0]
17+
const useHyphenated = options !== 'never'
18+
19+
const kebabCase = casing.getConverter('kebab-case')
20+
const caseConverter = casing.getConverter(useHyphenated ? 'kebab-case' : 'camelCase')
21+
22+
function reportIssue (node, name) {
23+
const text = sourceCode.getText(node.key)
24+
25+
context.report({
26+
node: node.key,
27+
loc: node.loc,
28+
message: useHyphenated ? "Attribute '{{text}}' must be hyphenated." : "Attribute '{{text}}' cann't be hyphenated.",
29+
data: {
30+
text
31+
},
32+
fix: fixer => fixer.replaceText(node.key, text.replace(name, caseConverter(name)))
33+
})
34+
}
35+
36+
function isIgnoredAttribute (value) {
37+
if (value.indexOf('data-') !== -1 || value.indexOf('aria-') !== -1) {
38+
return true
39+
}
40+
return useHyphenated ? kebabCase(value) === value : kebabCase(value) !== value
41+
}
42+
43+
// ----------------------------------------------------------------------
44+
// Public
45+
// ----------------------------------------------------------------------
46+
47+
utils.registerTemplateBodyVisitor(context, {
48+
VAttribute (node) {
49+
if (!utils.isCustomComponent(node.parent.parent)) return
50+
51+
const name = !node.directive ? node.key.name : node.key.name === 'bind' ? node.key.argument : false
52+
if (!name) return
53+
54+
if (isIgnoredAttribute(name)) {
55+
return
56+
}
57+
reportIssue(node, name)
58+
}
59+
})
60+
61+
return {}
62+
}
63+
64+
module.exports = {
65+
meta: {
66+
docs: {
67+
description: 'Define a style for the props casing in templates.',
68+
category: 'Stylistic Issues',
69+
recommended: false
70+
},
71+
fixable: 'code',
72+
schema: [
73+
{
74+
enum: ['always', 'never']
75+
}
76+
]
77+
},
78+
79+
create
80+
}

lib/rules/html-attributes-casing.js

Lines changed: 0 additions & 85 deletions
This file was deleted.
Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
/**
2+
* @fileoverview Define a style for the props casing in templates.
3+
* @author Armano
4+
*/
5+
'use strict'
6+
7+
// ------------------------------------------------------------------------------
8+
// Requirements
9+
// ------------------------------------------------------------------------------
10+
11+
const rule = require('../../../lib/rules/attribute-hyphenation')
12+
13+
const RuleTester = require('eslint').RuleTester
14+
15+
// ------------------------------------------------------------------------------
16+
// Tests
17+
// ------------------------------------------------------------------------------
18+
19+
const ruleTester = new RuleTester({
20+
parser: 'vue-eslint-parser',
21+
parserOptions: { ecmaVersion: 2015 }
22+
})
23+
24+
ruleTester.run('attribute-hyphenation', rule, {
25+
26+
valid: [
27+
{
28+
filename: 'test.vue',
29+
code: ''
30+
},
31+
{
32+
filename: 'test.vue',
33+
code: '<template><div><custom my-prop="prop"></custom></div></template>',
34+
options: ['always']
35+
},
36+
{
37+
filename: 'test.vue',
38+
code: '<template><div><a onClick="" my-prop="prop"></a></div></template>',
39+
options: ['never']
40+
}
41+
],
42+
43+
invalid: [
44+
{
45+
filename: 'test.vue',
46+
code: '<template><div><custom my-prop="prop"></custom></div></template>',
47+
options: ['never'],
48+
errors: [{
49+
message: "Attribute 'my-prop' cann't be hyphenated.",
50+
type: 'VIdentifier',
51+
line: 1
52+
}]
53+
},
54+
{
55+
filename: 'test.vue',
56+
code: '<template><div><custom MyProp="prop"></custom></div></template>',
57+
options: ['always'],
58+
errors: [{
59+
message: "Attribute 'MyProp' must be hyphenated.",
60+
type: 'VIdentifier',
61+
line: 1
62+
}]
63+
},
64+
{
65+
filename: 'test.vue',
66+
code: '<template><div><custom :my-prop="prop"></custom></div></template>',
67+
options: ['never'],
68+
errors: [{
69+
message: "Attribute ':my-prop' cann't be hyphenated.",
70+
type: 'VDirectiveKey',
71+
line: 1
72+
}]
73+
},
74+
{
75+
filename: 'test.vue',
76+
code: '<template><div><custom :MyProp="prop"></custom></div></template>',
77+
options: ['always'],
78+
errors: [{
79+
message: "Attribute ':MyProp' must be hyphenated.",
80+
type: 'VDirectiveKey',
81+
line: 1
82+
}]
83+
},
84+
{
85+
filename: 'test.vue',
86+
code: '<template><div><custom v-bind:my-prop="prop"></custom></div></template>',
87+
options: ['never'],
88+
errors: [{
89+
message: "Attribute 'v-bind:my-prop' cann't be hyphenated.",
90+
type: 'VDirectiveKey',
91+
line: 1
92+
}]
93+
},
94+
{
95+
filename: 'test.vue',
96+
code: '<template><div><custom v-bind:MyProp="prop"></custom></div></template>',
97+
options: ['always'],
98+
errors: [{
99+
message: "Attribute 'v-bind:MyProp' must be hyphenated.",
100+
type: 'VDirectiveKey',
101+
line: 1
102+
}]
103+
}
104+
]
105+
})

0 commit comments

Comments
 (0)