Skip to content

Commit 8a560ab

Browse files
committed
[Update] Make vue/attributes-order fixable
1 parent abbde6f commit 8a560ab

File tree

2 files changed

+68
-1
lines changed

2 files changed

+68
-1
lines changed

lib/rules/attributes-order.js

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,31 @@ function create (context) {
5959
message: `Attribute "${currentNode}" should go before "${prevNode}".`,
6060
data: {
6161
currentNode
62+
},
63+
64+
fix (fixer) {
65+
const attributes = node.parent.attributes
66+
const shiftAttrs = attributes.slice(attributes.indexOf(previousNode), attributes.indexOf(node) + 1)
67+
68+
// If we can upgrade requirements to `eslint@>4.1.0`, this code can be replaced by:
69+
// return shiftAttrs.map((attr, i) => {
70+
// const text = attr === previousNode ? sourceCode.getText(node) : sourceCode.getText(shiftAttrs[i - 1])
71+
// return fixer.replaceText(attr, text)
72+
// })
73+
const replaceDataList = shiftAttrs.map((attr, i) => {
74+
const text = attr === previousNode ? sourceCode.getText(node) : sourceCode.getText(shiftAttrs[i - 1])
75+
return {
76+
range: attr.range,
77+
text
78+
}
79+
})
80+
const replaceRange = [previousNode.range[0], node.range[1]]
81+
let text = sourceCode.text.slice(replaceRange[0], replaceRange[1])
82+
replaceDataList.reverse().forEach((data) => {
83+
const textRange = data.range.map(r => r - replaceRange[0])
84+
text = text.slice(0, textRange[0]) + data.text + text.slice(textRange[1], text.length)
85+
})
86+
return fixer.replaceTextRange(replaceRange, text)
6287
}
6388
})
6489
}
@@ -85,7 +110,7 @@ module.exports = {
85110
description: 'enforce order of attributes',
86111
category: 'recommended'
87112
},
88-
fixable: null,
113+
fixable: 'code',
89114
schema: {
90115
type: 'array',
91116
properties: {

tests/lib/rules/attributes-order.js

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -215,6 +215,7 @@ tester.run('attributes-order', rule, {
215215
{
216216
filename: 'test.vue',
217217
code: '<template><div v-cloak is="header"></div></template>',
218+
output: '<template><div is="header" v-cloak></div></template>',
218219
errors: [{
219220
message: 'Attribute "is" should go before "v-cloak".',
220221
type: 'VIdentifier'
@@ -223,6 +224,7 @@ tester.run('attributes-order', rule, {
223224
{
224225
filename: 'test.vue',
225226
code: '<template><div id="uniqueID" v-cloak></div></template>',
227+
output: '<template><div v-cloak id="uniqueID"></div></template>',
226228
errors: [{
227229
message: 'Attribute "v-cloak" should go before "id".',
228230
type: 'VDirectiveKey'
@@ -239,6 +241,15 @@ tester.run('attributes-order', rule, {
239241
:bindingProp="foo">
240242
</div>
241243
</template>`,
244+
output:
245+
`<template>
246+
<div
247+
v-model="toggle"
248+
model="baz"
249+
:bindingProp="foo"
250+
propOne="bar">
251+
</div>
252+
</template>`,
242253
errors: [{
243254
message: 'Attribute "v-model" should go before "model".',
244255
type: 'VDirectiveKey'
@@ -260,6 +271,16 @@ tester.run('attributes-order', rule, {
260271
propOne="bar">
261272
</div>
262273
</template>`,
274+
output:
275+
`<template>
276+
<div
277+
:bindingProp="foo"
278+
model="baz"
279+
v-model="toggle"
280+
v-on="functionCall"
281+
propOne="bar">
282+
</div>
283+
</template>`,
263284
errors: [{
264285
message: 'Attribute "v-model" should go before "v-on".',
265286
type: 'VDirectiveKey'
@@ -272,6 +293,7 @@ tester.run('attributes-order', rule, {
272293
{
273294
filename: 'test.vue',
274295
code: '<template><div data-id="foo" aria-test="bar" is="custom" myProp="prop"></div></template>',
296+
output: '<template><div data-id="foo" is="custom" aria-test="bar" myProp="prop"></div></template>',
275297
errors: [{
276298
message: 'Attribute "is" should go before "aria-test".',
277299
type: 'VIdentifier'
@@ -293,10 +315,30 @@ tester.run('attributes-order', rule, {
293315
'EVENTS',
294316
'CONTENT']
295317
}],
318+
output: '<template><div ref="header" is="header" propone="prop" ></div></template>',
296319
errors: [{
297320
message: 'Attribute "is" should go before "propone".',
298321
type: 'VIdentifier'
299322
}]
323+
},
324+
{
325+
filename: 'test.vue',
326+
code:
327+
`<template>
328+
<div v-cloak
329+
is="header">
330+
</div>
331+
</template>`,
332+
output:
333+
`<template>
334+
<div is="header"
335+
v-cloak>
336+
</div>
337+
</template>`,
338+
errors: [{
339+
message: 'Attribute "is" should go before "v-cloak".',
340+
type: 'VIdentifier'
341+
}]
300342
}
301343
]
302344
})

0 commit comments

Comments
 (0)