-
-
Notifications
You must be signed in to change notification settings - Fork 33.6k
/
events.js
83 lines (76 loc) · 2.41 KB
/
events.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
/* @flow */
const fnExpRE = /^\s*([\w$_]+|\([^)]*?\))\s*=>|^function\s*\(/
const simplePathRE = /^\s*[A-Za-z_$][\w$]*(?:\.[A-Za-z_$][\w$]*|\['.*?']|\[".*?"]|\[\d+]|\[[A-Za-z_$][\w$]*])*\s*$/
// keyCode aliases
const keyCodes: { [key: string]: number | Array<number> } = {
esc: 27,
tab: 9,
enter: 13,
space: 32,
up: 38,
left: 37,
right: 39,
down: 40,
'delete': [8, 46]
}
const modifierCode: { [key: string]: string } = {
stop: '$event.stopPropagation();',
prevent: '$event.preventDefault();',
// #4868: modifiers that prevent the execution of the listener
// need to explicitly return null so that we can determine whether to remove
// the listener for .once
self: 'if($event.target !== $event.currentTarget)return null;',
ctrl: 'if(!$event.ctrlKey)return null;',
shift: 'if(!$event.shiftKey)return null;',
alt: 'if(!$event.altKey)return null;',
meta: 'if(!$event.metaKey)return null;'
}
export function genHandlers (events: ASTElementHandlers, native?: boolean): string {
let res = native ? 'nativeOn:{' : 'on:{'
for (const name in events) {
res += `"${name}":${genHandler(name, events[name])},`
}
return res.slice(0, -1) + '}'
}
function genHandler (
name: string,
handler: ASTElementHandler | Array<ASTElementHandler>
): string {
if (!handler) {
return 'function(){}'
} else if (Array.isArray(handler)) {
return `[${handler.map(handler => genHandler(name, handler)).join(',')}]`
} else if (!handler.modifiers) {
return fnExpRE.test(handler.value) || simplePathRE.test(handler.value)
? handler.value
: `function($event){${handler.value}}`
} else {
let code = ''
const keys = []
for (const key in handler.modifiers) {
if (modifierCode[key]) {
code += modifierCode[key]
} else {
keys.push(key)
}
}
if (keys.length) {
code = genKeyFilter(keys) + code
}
const handlerCode = simplePathRE.test(handler.value)
? handler.value + '($event)'
: handler.value
return `function($event){${code}${handlerCode}}`
}
}
function genKeyFilter (keys: Array<string>): string {
return `if(${keys.map(genFilterCode).join('&&')})return null;`
}
function genFilterCode (key: string): string {
const keyVal = parseInt(key, 10)
if (keyVal) {
return `$event.keyCode!==${keyVal}`
}
const alias = keyCodes[key]
return `_k($event.keyCode,${JSON.stringify(key)}${alias ? ',' + JSON.stringify(alias) : ''})`
}