events.js 2.6 KB

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