Skip to content

Update attribute-hyphenation to allow a custom ignore list #461

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Apr 22, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
.idea
/.nyc_output
/coverage
/tests/integrations/*/node_modules
Expand Down
24 changes: 19 additions & 5 deletions docs/rules/attribute-hyphenation.md
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
# enforce attribute naming style in template (vue/attribute-hyphenation)
# enforce attribute naming style on custom components in template (vue/attribute-hyphenation)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This part is automatically generated based on the rule's metadata informations. If you want to update it please - do so in rule file instead. Otherwise it'll be overwritten during next release.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it just this one line coming from meta.docs.description and needs updating? If so I've done it, let me know if there is anything else.


- :gear: This rule is included in `"plugin:vue/strongly-recommended"` and `"plugin:vue/recommended"`.
- :wrench: The `--fix` option on the [command line](http://eslint.org/docs/user-guide/command-line-interface#fix) can automatically fix some of the problems reported by this rule.

## :wrench: Options

Default casing is set to `always`
Default casing is set to `always` with `['data-', 'aria-', 'slot-scope']` set to be ignored

```
'vue/attribute-hyphenation': [2, 'always'|'never']
'vue/attribute-hyphenation': [2, 'always'|'never', { 'ignore': ['custom-prop'] }]
```

### `"always"` - Use hyphenated name. (It errors on upper case letters.)
### `[2, "always"]` - Use hyphenated name. (It errors on upper case letters.)

:+1: Examples of **correct** code`:

Expand All @@ -25,7 +25,7 @@ Default casing is set to `always`
<MyComponent myProp="prop"/>
```

### `"never"` - Don't use hyphenated name. (It errors on hyphens except `data-` and `aria-`.)
### `[2, "never"]` - Don't use hyphenated name. (It errors on hyphens except `data-`, `aria-` and `slot-scope-`.)

:+1: Examples of **correct** code`:

Expand All @@ -38,3 +38,17 @@ Default casing is set to `always`
```html
<MyComponent my-prop="prop"/>
```

### `[2, "never", { 'ignore': ['custom-prop'] }]` - Don't use hyphenated name but allow custom attributes

:+1: Examples of **correct** code`:

```html
<MyComponent myProp="prop" custom-prop="foo" data-id="1"/>
```

:-1: Examples of **incorrect** code`:

```html
<MyComponent my-prop="prop" custom-prop="foo" data-id="1"/>
```
37 changes: 33 additions & 4 deletions lib/rules/attribute-hyphenation.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,22 +14,46 @@ const casing = require('../utils/casing')
module.exports = {
meta: {
docs: {
description: 'enforce attribute naming style in template',
description: 'enforce attribute naming style on custom components in template',
category: 'strongly-recommended',
url: 'https://github.com/vuejs/eslint-plugin-vue/blob/v4.4.0/docs/rules/attribute-hyphenation.md'
},
fixable: 'code',
schema: [
{
enum: ['always', 'never']
},
{
type: 'object',
properties: {
'ignore': {
type: 'array',
items: {
allOf: [
{ type: 'string' },
{ not: { type: 'string', pattern: ':exit$' }},
{ not: { type: 'string', pattern: '^\\s*$' }}
]
},
uniqueItems: true,
additionalItems: false
}
},
additionalProperties: false
}
]
},

create (context) {
const sourceCode = context.getSourceCode()
const options = context.options[0]
const useHyphenated = options !== 'never'
const option = context.options[0]
const optionsPayload = context.options[1]
const useHyphenated = option !== 'never'
const ignoredAttributes = ['data-', 'aria-', 'slot-scope']

if (optionsPayload && optionsPayload.ignore) {
ignoredAttributes.push(optionsPayload.ignore)
}

const caseConverter = casing.getConverter(useHyphenated ? 'kebab-case' : 'camelCase')

Expand All @@ -48,9 +72,14 @@ module.exports = {
}

function isIgnoredAttribute (value) {
if (value.indexOf('data-') !== -1 || value.indexOf('aria-') !== -1) {
const isIgnored = ignoredAttributes.some(function (attr) {
return value.indexOf(attr) !== -1
})

if (isIgnored) {
return true
}

return useHyphenated ? value.toLowerCase() === value : !/-/.test(value)
}

Expand Down
11 changes: 8 additions & 3 deletions tests/lib/rules/attribute-hyphenation.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,18 +30,23 @@ ruleTester.run('attribute-hyphenation', rule, {
},
{
filename: 'test.vue',
code: '<template><div><custom data-id="foo" aria-test="bar" my-prop="prop"></custom></div></template>',
code: '<template><div><custom data-id="foo" aria-test="bar" slot-scope="{ data }" my-prop="prop"></custom></div></template>',
options: ['always']
},
{
filename: 'test.vue',
code: '<template><div><custom data-id="foo" aria-test="bar" myProp="prop"></custom></div></template>',
code: '<template><div><custom data-id="foo" aria-test="bar" slot-scope="{ data }" myProp="prop"></custom></div></template>',
options: ['never']
},
{
filename: 'test.vue',
code: '<template><div data-id="foo" aria-test="bar"><a onClick="" my-prop="prop"></a></div></template>',
code: '<template><div data-id="foo" aria-test="bar" slot-scope="{ data }"><a onClick="" my-prop="prop"></a></div></template>',
options: ['never']
},
{
filename: 'test.vue',
code: '<template><div data-id="foo" aria-test="bar" slot-scope="{ data }" custom-hypen="foo"><a onClick="" my-prop="prop"></a></div></template>',
options: ['never', { 'ignore': ['custom-hypen'] }]
}
],

Expand Down