Skip to content

Commit e544174

Browse files
authored
feat: implement remove native modifier in v-on directive transformation (vuejs#27)
1 parent d119727 commit e544174

File tree

5 files changed

+129
-1
lines changed

5 files changed

+129
-1
lines changed
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
import { runTest } from '../../src/testUtils'
2+
3+
runTest(
4+
'Remove native modifiers in v-on directive',
5+
'remove-v-on-native',
6+
'v-on-native',
7+
'vue',
8+
'vue'
9+
)
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<template>
2+
<div>
3+
<!-- ✓ GOOD -->
4+
<CoolInput v-on:keydown.enter="onKeydownEnter" />
5+
<CoolInput @keydown.enter="onKeydownEnter" />
6+
7+
<!-- ✗ BAD -->
8+
<CoolInput v-on:keydown.native="onKeydown" />
9+
<CoolInput @keydown.enter.native="onKeydownEnter" />
10+
</div>
11+
</template>
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
<template>
2+
<div>
3+
<!-- ✓ GOOD -->
4+
<CoolInput v-on:keydown.enter="onKeydownEnter" />
5+
<CoolInput @keydown.enter="onKeydownEnter" />
6+
7+
<!-- ✗ BAD -->
8+
<!-- native modifier has been removed, please confirm whether the function has been affected -->
9+
<CoolInput v-on:keydown="onKeydown" />
10+
<!-- native modifier has been removed, please confirm whether the function has been affected -->
11+
<CoolInput @keydown.enter="onKeydownEnter" />
12+
</div>
13+
</template>

vue-transformations/index.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,8 @@ const transformationMap: {
1616
'v-bind-order-sensitive': require('./v-bind-order-sensitive'),
1717
'v-for-v-if-precedence-changed': require('./v-for-v-if-precedence-changed'),
1818
'remove-listeners': require('./remove-listeners'),
19-
'v-bind-sync': require('./v-bind-sync')
19+
'v-bind-sync': require('./v-bind-sync'),
20+
'remove-v-on-native': require('./remove-v-on-native')
2021
}
2122

2223
export const excludedVueTransformations = ['v-bind-order-sensitive']
Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
import { Node } from 'vue-eslint-parser/ast/nodes'
2+
import * as OperationUtils from '../src/operationUtils'
3+
import type { Operation } from '../src/operationUtils'
4+
import type { VueASTTransformation } from '../src/wrapVueTransformation'
5+
import * as parser from 'vue-eslint-parser'
6+
import wrap from '../src/wrapVueTransformation'
7+
import _ from 'lodash'
8+
9+
export const transformAST: VueASTTransformation = context => {
10+
let fixOperations: Operation[] = []
11+
const { file } = context
12+
const source = file.source
13+
const toFixNodes: Node[] = findNodes(context)
14+
toFixNodes.forEach(node => {
15+
fixOperations = fixOperations.concat(fix(node, source))
16+
})
17+
return fixOperations
18+
}
19+
20+
export default wrap(transformAST)
21+
/**
22+
* search v-on nodes
23+
*
24+
* @param context
25+
* @returns v-on attribute nodes
26+
*/
27+
function findNodes(context: any): Node[] {
28+
const { file } = context
29+
const source = file.source
30+
const options = { sourceType: 'module' }
31+
const ast = parser.parse(source, options)
32+
let toFixNodes: Node[] = []
33+
let root: Node = <Node>ast.templateBody
34+
parser.AST.traverseNodes(root, {
35+
enterNode(node: Node) {
36+
if (
37+
node.type === 'VAttribute' &&
38+
node.directive &&
39+
node.key.name.name === 'on'
40+
) {
41+
toFixNodes.push(node)
42+
}
43+
},
44+
leaveNode(node: Node) {}
45+
})
46+
return toFixNodes
47+
}
48+
/**
49+
* fix logic
50+
* @param node
51+
*/
52+
function fix(node: Node, source: string): Operation[] {
53+
let fixOperations: Operation[] = []
54+
// @ts-ignore
55+
const keyNode = node.key
56+
const argument = keyNode.argument
57+
const modifiers = keyNode.modifiers
58+
59+
if (argument !== null) {
60+
modifiers.forEach((mod: any) => {
61+
if (mod?.name === 'native') {
62+
const comment =
63+
'<!-- native modifier has been removed, please confirm whether the function has been affected -->'
64+
const vStartTag = mod.parent.parent.parent
65+
const vElement = vStartTag.parent
66+
const siblings = vElement.parent.children
67+
let insertIndent = ''
68+
if (siblings[0] !== vElement) {
69+
let preEle = siblings[0]
70+
for (let i = 1; i < siblings.length; i++) {
71+
if (siblings[i].range === vElement.range) {
72+
insertIndent = preEle.value
73+
break
74+
} else {
75+
preEle = siblings[i]
76+
}
77+
}
78+
}
79+
// insert a comment about navite modifier
80+
fixOperations.push(OperationUtils.insertTextBefore(vStartTag, comment))
81+
// insert new line and indents
82+
fixOperations.push(
83+
OperationUtils.insertTextBefore(vStartTag, insertIndent)
84+
)
85+
// remove native modifier on 'v-on' directive
86+
fixOperations.push(
87+
OperationUtils.removeRange([mod.range[0] - 1, mod.range[1]])
88+
)
89+
}
90+
})
91+
}
92+
93+
return fixOperations
94+
}

0 commit comments

Comments
 (0)