From 59653b705b6fda12370c06b66d6449ba3b377c0f Mon Sep 17 00:00:00 2001
From: IWANABETHATGUY <974153916@qq.com>
Date: Wed, 9 Jun 2021 18:01:47 +0800
Subject: [PATCH 1/3] =?UTF-8?q?feat:=20=F0=9F=8E=B8=20finish=20sort=20orde?=
=?UTF-8?q?r?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../component-name-in-template-casing.js | 3 +-
lib/rules/component-tags-order.js | 83 ++++++++++++++--
tests/lib/rules/component-tags-order.js | 99 +++++++++++++++----
3 files changed, 159 insertions(+), 26 deletions(-)
diff --git a/lib/rules/component-name-in-template-casing.js b/lib/rules/component-name-in-template-casing.js
index b2f60a637..dffca0c88 100644
--- a/lib/rules/component-name-in-template-casing.js
+++ b/lib/rules/component-name-in-template-casing.js
@@ -30,7 +30,8 @@ module.exports = {
description:
'enforce specific casing for the component naming style in template',
categories: undefined,
- url: 'https://eslint.vuejs.org/rules/component-name-in-template-casing.html'
+ url:
+ 'https://eslint.vuejs.org/rules/component-name-in-template-casing.html'
},
fixable: 'code',
schema: [
diff --git a/lib/rules/component-tags-order.js b/lib/rules/component-tags-order.js
index dc7da9725..729b5e10d 100644
--- a/lib/rules/component-tags-order.js
+++ b/lib/rules/component-tags-order.js
@@ -24,7 +24,7 @@ module.exports = {
categories: ['vue3-recommended', 'recommended'],
url: 'https://eslint.vuejs.org/rules/component-tags-order.html'
},
- fixable: null,
+ fixable: 'code',
schema: [
{
type: 'object',
@@ -87,12 +87,43 @@ module.exports = {
return []
}
+ /**
+ *
+ *
+ * @param {{name: string, index: number}[]} list component tag list of the SFC
+ */
+ function getSortedTagList(list) {
+ list.sort((a, b) => {
+ const ao = getOrderPosition(a.name)
+ const bo = getOrderPosition(b.name)
+ // 1. if the tag is customize keep the original position
+ // 2. if two tag has same order, keep the original position
+ if (ao === -1 || bo === -1 || ao === bo) {
+ return 0
+ } else {
+ // else sort the tag position by asc
+ return ao - bo
+ }
+ })
+ return list
+ }
+
/**
* @param {VElement} element
* @param {VElement} firstUnorderedElement
+ * @param {string} code
+ * @param {number[]} replaceRange
+ * @param {boolean} fixable
*/
- function report(element, firstUnorderedElement) {
- context.report({
+ function report(
+ element,
+ firstUnorderedElement,
+ code,
+ replaceRange,
+ fixable
+ ) {
+ /**@type{Rule.ReportDescriptor} */
+ const descriptor = {
node: element,
loc: element.loc,
messageId: 'unexpected',
@@ -101,7 +132,16 @@ module.exports = {
firstUnorderedName: firstUnorderedElement.name,
line: firstUnorderedElement.loc.start.line
}
- })
+ }
+ if (fixable) {
+ descriptor.fix = function (fixer) {
+ return fixer.replaceTextRange(
+ [replaceRange[0], replaceRange[1]],
+ code
+ )
+ }
+ }
+ context.report(descriptor)
}
return {
@@ -110,7 +150,8 @@ module.exports = {
return
}
const elements = getTopLevelHTMLElements()
-
+ /** @type {{element: VElement, firstUnordered: VElement}[]} */
+ const reportCandidates = []
elements.forEach((element, index) => {
const expectedIndex = getOrderPosition(element.name)
if (expectedIndex < 0) {
@@ -123,9 +164,39 @@ module.exports = {
(e1, e2) => getOrderPosition(e1.name) - getOrderPosition(e2.name)
)[0]
if (firstUnordered) {
- report(element, firstUnordered)
+ reportCandidates.push({ element, firstUnordered })
}
})
+ if (reportCandidates.length) {
+ const replaceRange = [
+ elements[0].range[0],
+ elements[elements.length - 1].range[1]
+ ]
+ const sortTagList = getSortedTagList(
+ elements.map((element, index) => ({
+ name: element.name,
+ index
+ }))
+ )
+ const sourceCode = context.getSourceCode().text
+ const reOrderedCode = Array.from(
+ { length: elements.length },
+ (_, i) => {
+ const [start, end] = elements[sortTagList[i].index].range
+ const code = sourceCode.slice(start, end)
+ return code
+ }
+ ).join('\n')
+ reportCandidates.forEach((error, index) => {
+ report(
+ error.element,
+ error.firstUnordered,
+ reOrderedCode,
+ replaceRange,
+ index === 0
+ )
+ })
+ }
}
}
}
diff --git a/tests/lib/rules/component-tags-order.js b/tests/lib/rules/component-tags-order.js
index 0c40d4997..b016c1c34 100644
--- a/tests/lib/rules/component-tags-order.js
+++ b/tests/lib/rules/component-tags-order.js
@@ -73,17 +73,20 @@ tester.run('component-tags-order', rule, {
options: [{ order: ['template', 'docs', 'script', 'style'] }]
},
{
- code: '',
+ code:
+ '',
output: null,
options: [{ order: ['template', 'script', 'style'] }]
},
{
- code: 'text
',
+ code:
+ 'text
',
output: null,
options: [{ order: ['docs', 'script', 'template', 'style'] }]
},
{
- code: '',
+ code:
+ '',
output: null,
options: [{ order: [['docs', 'script', 'template'], 'style'] }]
},
@@ -108,7 +111,10 @@ tester.run('component-tags-order', rule, {
line: 1,
column: 37
}
- ]
+ ],
+ output: `
+
+`
},
{
code: '',
@@ -119,7 +125,10 @@ tester.run('component-tags-order', rule, {
line: 1,
column: 22
}
- ]
+ ],
+ output: `
+
+`
},
{
code: `
@@ -133,7 +142,11 @@ tester.run('component-tags-order', rule, {
message: 'The
+`
},
{
code: `
@@ -147,7 +160,12 @@ tester.run('component-tags-order', rule, {
message: 'The
+
+
+ `
},
{
code: `
@@ -161,7 +179,12 @@ tester.run('component-tags-order', rule, {
message: 'The should be above the
+
+ `
},
{
code: `
@@ -176,7 +199,13 @@ tester.run('component-tags-order', rule, {
message: 'The should be above the on line 2.',
line: 3
}
- ]
+ ],
+ output: `
+
+
+
+
+ `
},
{
code: `
@@ -191,15 +220,21 @@ tester.run('component-tags-order', rule, {
message: 'The
+
+
+
+ `
},
{
code: `
-
-
-
-
+
+
+
+
`,
options: [{ order: ['script', 'template', 'style'] }],
errors: [
@@ -207,7 +242,14 @@ tester.run('component-tags-order', rule, {
message: 'The
+
+
+
+
+ `
},
{
code: `
@@ -220,7 +262,11 @@ tester.run('component-tags-order', rule, {
message: 'The should be above the
+ `
},
{
code: `
@@ -237,7 +283,12 @@ tester.run('component-tags-order', rule, {
message: 'The
+
+ `
},
{
code: `
@@ -255,7 +306,13 @@ tester.run('component-tags-order', rule, {
message: 'The
+
+ `
},
// no
{
@@ -268,7 +325,11 @@ tester.run('component-tags-order', rule, {
message: 'The
+ `
}
]
})
From 4194ec77dd848c654cee4e38fc51caa3dcb3dd85 Mon Sep 17 00:00:00 2001
From: IWANABETHATGUY <974153916@qq.com>
Date: Thu, 10 Jun 2021 10:46:53 +0800
Subject: [PATCH 2/3] =?UTF-8?q?test:=20=F0=9F=92=8D=20pass=20all=20test?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
docs/rules/README.md | 4 +--
docs/rules/component-tags-order.md | 15 ++++-----
lib/rules/component-tags-order.js | 41 ++++++++++++-------------
tests/lib/rules/component-tags-order.js | 15 ++++-----
4 files changed, 35 insertions(+), 40 deletions(-)
diff --git a/docs/rules/README.md b/docs/rules/README.md
index a93d5a640..076d0bfc9 100644
--- a/docs/rules/README.md
+++ b/docs/rules/README.md
@@ -152,7 +152,7 @@ Enforce all the rules in this category, as well as all higher priority rules, wi
| Rule ID | Description | |
|:--------|:------------|:---|
| [vue/attributes-order](./attributes-order.md) | enforce order of attributes | :wrench: |
-| [vue/component-tags-order](./component-tags-order.md) | enforce order of component top-level elements | |
+| [vue/component-tags-order](./component-tags-order.md) | enforce order of component top-level elements | :wrench: |
| [vue/no-lone-template](./no-lone-template.md) | disallow unnecessary `` | |
| [vue/no-multiple-slot-args](./no-multiple-slot-args.md) | disallow to pass multiple arguments to scoped slots | |
| [vue/no-v-html](./no-v-html.md) | disallow use of v-html to prevent XSS attack | |
@@ -262,7 +262,7 @@ Enforce all the rules in this category, as well as all higher priority rules, wi
| Rule ID | Description | |
|:--------|:------------|:---|
| [vue/attributes-order](./attributes-order.md) | enforce order of attributes | :wrench: |
-| [vue/component-tags-order](./component-tags-order.md) | enforce order of component top-level elements | |
+| [vue/component-tags-order](./component-tags-order.md) | enforce order of component top-level elements | :wrench: |
| [vue/no-lone-template](./no-lone-template.md) | disallow unnecessary `` | |
| [vue/no-multiple-slot-args](./no-multiple-slot-args.md) | disallow to pass multiple arguments to scoped slots | |
| [vue/no-v-html](./no-v-html.md) | disallow use of v-html to prevent XSS attack | |
diff --git a/docs/rules/component-tags-order.md b/docs/rules/component-tags-order.md
index e0c0c99f3..ceeafea80 100644
--- a/docs/rules/component-tags-order.md
+++ b/docs/rules/component-tags-order.md
@@ -10,6 +10,7 @@ since: v6.1.0
> enforce order of component top-level elements
- :gear: This rule is included in `"plugin:vue/vue3-recommended"` and `"plugin:vue/recommended"`.
+- :wrench: The `--fix` option on the [command line](https://eslint.org/docs/user-guide/command-line-interface#fixing-problems) can automatically fix some of the problems reported by this rule.
## :book: Rule Details
@@ -29,7 +30,7 @@ This rule warns about the order of the `',
+ code: '',
output: null,
options: [{ order: ['template', 'script', 'style'] }]
},
{
- code:
- 'text
',
+ code: 'text
',
output: null,
options: [{ order: ['docs', 'script', 'template', 'style'] }]
},
{
- code:
- '',
+ code: '',
output: null,
options: [{ order: [['docs', 'script', 'template'], 'style'] }]
},
@@ -245,9 +242,9 @@ tester.run('component-tags-order', rule, {
],
output: `
-
+
`
},
@@ -312,7 +309,7 @@ tester.run('component-tags-order', rule, {
- `
+ `
},
// no
{
@@ -327,8 +324,8 @@ tester.run('component-tags-order', rule, {
}
],
output: `
-
+
`
}
]
From 9e64164b1ee1e3596f3a5b68f6aeecfff35a3bda Mon Sep 17 00:00:00 2001
From: IWANABETHATGUY <974153916@qq.com>
Date: Thu, 10 Jun 2021 10:50:20 +0800
Subject: [PATCH 3/3] =?UTF-8?q?fix:=20=F0=9F=90=9B=20fix=20lint=20problem?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
lib/rules/component-name-in-template-casing.js | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/lib/rules/component-name-in-template-casing.js b/lib/rules/component-name-in-template-casing.js
index dffca0c88..b2f60a637 100644
--- a/lib/rules/component-name-in-template-casing.js
+++ b/lib/rules/component-name-in-template-casing.js
@@ -30,8 +30,7 @@ module.exports = {
description:
'enforce specific casing for the component naming style in template',
categories: undefined,
- url:
- 'https://eslint.vuejs.org/rules/component-name-in-template-casing.html'
+ url: 'https://eslint.vuejs.org/rules/component-name-in-template-casing.html'
},
fixable: 'code',
schema: [