aboutsummaryrefslogtreecommitdiff
path: root/node_modules/vue/src/compiler/codegen/events.js
diff options
context:
space:
mode:
Diffstat (limited to 'node_modules/vue/src/compiler/codegen/events.js')
-rw-r--r--node_modules/vue/src/compiler/codegen/events.js167
1 files changed, 167 insertions, 0 deletions
diff --git a/node_modules/vue/src/compiler/codegen/events.js b/node_modules/vue/src/compiler/codegen/events.js
new file mode 100644
index 00000000..4f922246
--- /dev/null
+++ b/node_modules/vue/src/compiler/codegen/events.js
@@ -0,0 +1,167 @@
+/* @flow */
+
+const fnExpRE = /^([\w$_]+|\([^)]*?\))\s*=>|^function\s*\(/
+const simplePathRE = /^[A-Za-z_$][\w$]*(?:\.[A-Za-z_$][\w$]*|\['[^']*?']|\["[^"]*?"]|\[\d+]|\[[A-Za-z_$][\w$]*])*$/
+
+// KeyboardEvent.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]
+}
+
+// KeyboardEvent.key aliases
+const keyNames: { [key: string]: string | Array<string> } = {
+ esc: 'Escape',
+ tab: 'Tab',
+ enter: 'Enter',
+ space: ' ',
+ // #7806: IE11 uses key names without `Arrow` prefix for arrow keys.
+ up: ['Up', 'ArrowUp'],
+ left: ['Left', 'ArrowLeft'],
+ right: ['Right', 'ArrowRight'],
+ down: ['Down', 'ArrowDown'],
+ 'delete': ['Backspace', 'Delete']
+}
+
+// #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
+const genGuard = condition => `if(${condition})return null;`
+
+const modifierCode: { [key: string]: string } = {
+ stop: '$event.stopPropagation();',
+ prevent: '$event.preventDefault();',
+ self: genGuard(`$event.target !== $event.currentTarget`),
+ ctrl: genGuard(`!$event.ctrlKey`),
+ shift: genGuard(`!$event.shiftKey`),
+ alt: genGuard(`!$event.altKey`),
+ meta: genGuard(`!$event.metaKey`),
+ left: genGuard(`'button' in $event && $event.button !== 0`),
+ middle: genGuard(`'button' in $event && $event.button !== 1`),
+ right: genGuard(`'button' in $event && $event.button !== 2`)
+}
+
+export function genHandlers (
+ events: ASTElementHandlers,
+ isNative: boolean,
+ warn: Function
+): string {
+ let res = isNative ? 'nativeOn:{' : 'on:{'
+ for (const name in events) {
+ res += `"${name}":${genHandler(name, events[name])},`
+ }
+ return res.slice(0, -1) + '}'
+}
+
+// Generate handler code with binding params on Weex
+/* istanbul ignore next */
+function genWeexHandler (params: Array<any>, handlerCode: string) {
+ let innerHandlerCode = handlerCode
+ const exps = params.filter(exp => simplePathRE.test(exp) && exp !== '$event')
+ const bindings = exps.map(exp => ({ '@binding': exp }))
+ const args = exps.map((exp, i) => {
+ const key = `$_${i + 1}`
+ innerHandlerCode = innerHandlerCode.replace(exp, key)
+ return key
+ })
+ args.push('$event')
+ return '{\n' +
+ `handler:function(${args.join(',')}){${innerHandlerCode}},\n` +
+ `params:${JSON.stringify(bindings)}\n` +
+ '}'
+}
+
+function genHandler (
+ name: string,
+ handler: ASTElementHandler | Array<ASTElementHandler>
+): string {
+ if (!handler) {
+ return 'function(){}'
+ }
+
+ if (Array.isArray(handler)) {
+ return `[${handler.map(handler => genHandler(name, handler)).join(',')}]`
+ }
+
+ const isMethodPath = simplePathRE.test(handler.value)
+ const isFunctionExpression = fnExpRE.test(handler.value)
+
+ if (!handler.modifiers) {
+ if (isMethodPath || isFunctionExpression) {
+ return handler.value
+ }
+ /* istanbul ignore if */
+ if (__WEEX__ && handler.params) {
+ return genWeexHandler(handler.params, handler.value)
+ }
+ return `function($event){${handler.value}}` // inline statement
+ } else {
+ let code = ''
+ let genModifierCode = ''
+ const keys = []
+ for (const key in handler.modifiers) {
+ if (modifierCode[key]) {
+ genModifierCode += modifierCode[key]
+ // left/right
+ if (keyCodes[key]) {
+ keys.push(key)
+ }
+ } else if (key === 'exact') {
+ const modifiers: ASTModifiers = (handler.modifiers: any)
+ genModifierCode += genGuard(
+ ['ctrl', 'shift', 'alt', 'meta']
+ .filter(keyModifier => !modifiers[keyModifier])
+ .map(keyModifier => `$event.${keyModifier}Key`)
+ .join('||')
+ )
+ } else {
+ keys.push(key)
+ }
+ }
+ if (keys.length) {
+ code += genKeyFilter(keys)
+ }
+ // Make sure modifiers like prevent and stop get executed after key filtering
+ if (genModifierCode) {
+ code += genModifierCode
+ }
+ const handlerCode = isMethodPath
+ ? `return ${handler.value}($event)`
+ : isFunctionExpression
+ ? `return (${handler.value})($event)`
+ : handler.value
+ /* istanbul ignore if */
+ if (__WEEX__ && handler.params) {
+ return genWeexHandler(handler.params, code + handlerCode)
+ }
+ return `function($event){${code}${handlerCode}}`
+ }
+}
+
+function genKeyFilter (keys: Array<string>): string {
+ return `if(!('button' in $event)&&${keys.map(genFilterCode).join('&&')})return null;`
+}
+
+function genFilterCode (key: string): string {
+ const keyVal = parseInt(key, 10)
+ if (keyVal) {
+ return `$event.keyCode!==${keyVal}`
+ }
+ const keyCode = keyCodes[key]
+ const keyName = keyNames[key]
+ return (
+ `_k($event.keyCode,` +
+ `${JSON.stringify(key)},` +
+ `${JSON.stringify(keyCode)},` +
+ `$event.key,` +
+ `${JSON.stringify(keyName)}` +
+ `)`
+ )
+}