diff --git a/lib/rules/attributes-order.js b/lib/rules/attributes-order.js
index e5cd19dd5..78efa4b4b 100644
--- a/lib/rules/attributes-order.js
+++ b/lib/rules/attributes-order.js
@@ -59,6 +59,31 @@ function create (context) {
message: `Attribute "${currentNode}" should go before "${prevNode}".`,
data: {
currentNode
+ },
+
+ fix (fixer) {
+ const attributes = node.parent.attributes
+ const shiftAttrs = attributes.slice(attributes.indexOf(previousNode), attributes.indexOf(node) + 1)
+
+ // If we can upgrade requirements to `eslint@>4.1.0`, this code can be replaced by:
+ // return shiftAttrs.map((attr, i) => {
+ // const text = attr === previousNode ? sourceCode.getText(node) : sourceCode.getText(shiftAttrs[i - 1])
+ // return fixer.replaceText(attr, text)
+ // })
+ const replaceDataList = shiftAttrs.map((attr, i) => {
+ const text = attr === previousNode ? sourceCode.getText(node) : sourceCode.getText(shiftAttrs[i - 1])
+ return {
+ range: attr.range,
+ text
+ }
+ })
+ const replaceRange = [previousNode.range[0], node.range[1]]
+ let text = sourceCode.text.slice(replaceRange[0], replaceRange[1])
+ replaceDataList.reverse().forEach((data) => {
+ const textRange = data.range.map(r => r - replaceRange[0])
+ text = text.slice(0, textRange[0]) + data.text + text.slice(textRange[1], text.length)
+ })
+ return fixer.replaceTextRange(replaceRange, text)
}
})
}
@@ -85,7 +110,7 @@ module.exports = {
description: 'enforce order of attributes',
category: 'recommended'
},
- fixable: null,
+ fixable: 'code',
schema: {
type: 'array',
properties: {
diff --git a/tests/lib/rules/attributes-order.js b/tests/lib/rules/attributes-order.js
index 39c207160..9366ac130 100644
--- a/tests/lib/rules/attributes-order.js
+++ b/tests/lib/rules/attributes-order.js
@@ -208,6 +208,40 @@ tester.run('attributes-order', rule, {
'EVENTS',
'CONTENT']
}]
+ },
+ {
+ filename: 'test.vue',
+ code:
+ `
+
+
+ `,
+ options: [
+ { order:
+ [
+ 'CONDITIONALS',
+ 'LIST_RENDERING',
+ 'RENDER_MODIFIERS',
+ 'DEFINITION',
+ 'EVENTS',
+ 'UNIQUE',
+ 'BINDING',
+ 'CONTENT',
+ 'GLOBAL',
+ 'OTHER_ATTR'
+ ]
+ }]
}
],
@@ -215,6 +249,7 @@ tester.run('attributes-order', rule, {
{
filename: 'test.vue',
code: '',
+ output: '',
errors: [{
message: 'Attribute "is" should go before "v-cloak".',
type: 'VIdentifier'
@@ -223,6 +258,7 @@ tester.run('attributes-order', rule, {
{
filename: 'test.vue',
code: '',
+ output: '',
errors: [{
message: 'Attribute "v-cloak" should go before "id".',
type: 'VDirectiveKey'
@@ -239,6 +275,15 @@ tester.run('attributes-order', rule, {
:bindingProp="foo">
`,
+ output:
+ `
+
+
+ `,
errors: [{
message: 'Attribute "v-model" should go before "model".',
type: 'VDirectiveKey'
@@ -260,6 +305,16 @@ tester.run('attributes-order', rule, {
propOne="bar">
`,
+ output:
+ `
+
+
+ `,
errors: [{
message: 'Attribute "v-model" should go before "v-on".',
type: 'VDirectiveKey'
@@ -272,6 +327,7 @@ tester.run('attributes-order', rule, {
{
filename: 'test.vue',
code: '',
+ output: '',
errors: [{
message: 'Attribute "is" should go before "aria-test".',
type: 'VIdentifier'
@@ -293,10 +349,167 @@ tester.run('attributes-order', rule, {
'EVENTS',
'CONTENT']
}],
+ output: '',
errors: [{
message: 'Attribute "is" should go before "propone".',
type: 'VIdentifier'
}]
+ },
+ {
+ filename: 'test.vue',
+ code:
+ `
+
+
+ `,
+ output:
+ `
+
+
+ `,
+ errors: [{
+ message: 'Attribute "is" should go before "v-cloak".',
+ type: 'VIdentifier'
+ }]
+ },
+ {
+ filename: 'test.vue',
+ code:
+ `
+
+
+ `,
+ output:
+ `
+
+
+ `,
+ errors: [
+ {
+ message: 'Attribute "v-for" should go before "v-if".',
+ type: 'VDirectiveKey'
+ },
+ {
+ message: 'Attribute "is" should go before "v-once".',
+ type: 'VIdentifier'
+ },
+ {
+ message: 'Attribute "ref" should go before "v-on:click".',
+ type: 'VIdentifier'
+ },
+ {
+ message: 'Attribute ":prop" should go before "v-on:click".',
+ type: 'VDirectiveKey'
+ },
+ {
+ message: 'Attribute "id" should go before "v-text".',
+ type: 'VIdentifier'
+ },
+ {
+ message: 'Attribute "myProp" should go before "v-text".',
+ type: 'VIdentifier'
+ }
+ ]
+ },
+ {
+ filename: 'test.vue',
+ code:
+ `
+
+
+ `,
+ options: [
+ { order:
+ [
+ 'EVENTS',
+ 'BINDING',
+ 'UNIQUE',
+ 'DEFINITION',
+ 'CONDITIONALS',
+ 'LIST_RENDERING',
+ 'RENDER_MODIFIERS',
+ 'GLOBAL',
+ 'OTHER_ATTR',
+ 'CONTENT'
+ ]
+ }],
+ output:
+ `
+
+
+ `,
+ errors: [
+ {
+ message: 'Attribute "is" should go before "v-once".',
+ nodeType: 'VIdentifier'
+ },
+ {
+ message: 'Attribute "v-on:click" should go before "v-once".',
+ nodeType: 'VDirectiveKey'
+ },
+ {
+ message: 'Attribute "ref" should go before "v-once".',
+ nodeType: 'VIdentifier'
+ },
+ {
+ message: 'Attribute ":prop" should go before "v-once".',
+ nodeType: 'VDirectiveKey'
+ },
+ {
+ message: 'Attribute "id" should go before "v-text".',
+ nodeType: 'VIdentifier'
+ },
+ {
+ message: 'Attribute "myProp" should go before "v-text".',
+ nodeType: 'VIdentifier'
+ }
+ ]
}
]
})