]> git.ipfire.org Git - thirdparty/vuejs/core.git/commitdiff
refactor: adjust event options handling to be JSX friendly
authorEvan You <yyx990803@gmail.com>
Tue, 14 Jul 2020 17:20:59 +0000 (13:20 -0400)
committerEvan You <yyx990803@gmail.com>
Tue, 14 Jul 2020 17:20:59 +0000 (13:20 -0400)
packages/compiler-dom/__tests__/transforms/vOn.spec.ts
packages/compiler-dom/src/transforms/vOn.ts
packages/runtime-core/__tests__/componentEmits.spec.ts
packages/runtime-core/src/componentEmits.ts
packages/runtime-dom/__tests__/patchEvents.spec.ts
packages/runtime-dom/src/modules/events.ts

index 1c7a60edf6af5da08b2f2b30f289c5e4afcad2ae..76d5ca689686f6a62604b523b17c6591166d9568 100644 (file)
@@ -77,13 +77,13 @@ describe('compiler-dom: transform v-on', () => {
   it('should support multiple modifiers and event options w/ prefixIdentifiers: true', () => {
     const {
       props: [prop]
-    } = parseWithVOn(`<div @click.stop.capture.passive="test"/>`, {
+    } = parseWithVOn(`<div @click.stop.capture.once="test"/>`, {
       prefixIdentifiers: true
     })
     expect(prop).toMatchObject({
       type: NodeTypes.JS_PROPERTY,
       key: {
-        content: `onClick.capture.passive`
+        content: `onClickCaptureOnce`
       },
       value: {
         callee: V_ON_WITH_MODIFIERS,
@@ -101,7 +101,7 @@ describe('compiler-dom: transform v-on', () => {
     expect(prop).toMatchObject({
       type: NodeTypes.JS_PROPERTY,
       key: {
-        content: `onKeydown.capture`
+        content: `onKeydownCapture`
       },
       value: {
         callee: V_ON_WITH_KEYS,
@@ -274,7 +274,7 @@ describe('compiler-dom: transform v-on', () => {
     )
     expect(prop).toMatchObject({
       key: {
-        content: `onKeyup.capture`
+        content: `onKeyupCapture`
       },
       value: {
         type: NodeTypes.JS_CACHE_EXPRESSION,
index c08d5c804c27dec4e50c34380caa75c4856c00ab..50c9bf7540102ce78b676ff17d595d6c02c64ca4 100644 (file)
@@ -11,7 +11,7 @@ import {
   isStaticExp
 } from '@vue/compiler-core'
 import { V_ON_WITH_MODIFIERS, V_ON_WITH_KEYS } from '../runtimeHelpers'
-import { makeMap } from '@vue/shared'
+import { makeMap, capitalize } from '@vue/shared'
 
 const isEventOptionModifier = /*#__PURE__*/ makeMap(`passive,once,capture`)
 const isNonKeyModifier = /*#__PURE__*/ makeMap(
@@ -38,7 +38,8 @@ const resolveModifiers = (key: ExpressionNode, modifiers: string[]) => {
     const modifier = modifiers[i]
 
     if (isEventOptionModifier(modifier)) {
-      // eventOptionModifiers: modifiers for addEventListener() options, e.g. .passive & .capture
+      // eventOptionModifiers: modifiers for addEventListener() options,
+      // e.g. .passive & .capture
       eventOptionModifiers.push(modifier)
     } else {
       // runtimeModifiers: modifiers that needs runtime guards
@@ -125,16 +126,10 @@ export const transformOn: DirectiveTransform = (dir, node, context) => {
     }
 
     if (eventOptionModifiers.length) {
+      const modifierPostfix = eventOptionModifiers.map(capitalize).join('')
       key = isStaticExp(key)
-        ? createSimpleExpression(
-            `${key.content}.${eventOptionModifiers.join(`.`)}`,
-            true
-          )
-        : createCompoundExpression([
-            `(`,
-            key,
-            `) + ".${eventOptionModifiers.join(`.`)}"`
-          ])
+        ? createSimpleExpression(`${key.content}${modifierPostfix}`, true)
+        : createCompoundExpression([`(`, key, `) + "${modifierPostfix}"`])
     }
 
     return {
index 1e819b656eeebb44a642e25cb4ac5f66164783a1..effe6571f67933a3335798111951a8c5ea364ca0 100644 (file)
@@ -174,7 +174,7 @@ describe('component: emit', () => {
     const fn = jest.fn()
     render(
       h(Foo, {
-        'onFoo.once': fn
+        onFooOnce: fn
       }),
       nodeOps.createElement('div')
     )
@@ -213,8 +213,8 @@ describe('component: emit', () => {
 
     test('.once listeners', () => {
       const def2 = { emits: { click: null } }
-      expect(isEmitListener(def2, 'onClick.once')).toBe(true)
-      expect(isEmitListener(def2, 'onclick.once')).toBe(false)
+      expect(isEmitListener(def2, 'onClickOnce')).toBe(true)
+      expect(isEmitListener(def2, 'onclickOnce')).toBe(false)
     })
   })
 })
index f8a419dd5338f61fd7e8d9b53174f4771566fb94..cce4db0badd908bc841504be6ee93f1d9e185b9b 100644 (file)
@@ -76,7 +76,7 @@ export function emit(
     handler = props[handlerName]
   }
   if (!handler) {
-    handler = props[handlerName + `.once`]
+    handler = props[handlerName + `Once`]
     if (!instance.emitted) {
       ;(instance.emitted = {} as Record<string, boolean>)[handlerName] = true
     } else if (instance.emitted[handlerName]) {
@@ -136,7 +136,7 @@ export function isEmitListener(comp: Component, key: string): boolean {
   if (!isOn(key) || !(emits = normalizeEmitsOptions(comp))) {
     return false
   }
-  key = key.replace(/\.once$/, '')
+  key = key.replace(/Once$/, '')
   return (
     hasOwn(emits, key[2].toLowerCase() + key.slice(3)) ||
     hasOwn(emits, key.slice(2))
index 8962dbf5795520c530e6ef80f26f5911d1ee06ae..f926cc690098c1117e4e15d297acfaeadc500e69 100644 (file)
@@ -61,7 +61,7 @@ describe(`runtime-dom: events patching`, () => {
     const el = document.createElement('div')
     const event = new Event('click')
     const fn = jest.fn()
-    patchProp(el, 'onClick.once.capture', null, fn)
+    patchProp(el, 'onClickOnceCapture', null, fn)
     el.dispatchEvent(event)
     await timeout()
     el.dispatchEvent(event)
@@ -73,13 +73,17 @@ describe(`runtime-dom: events patching`, () => {
     const el = document.createElement('div')
     const event = new Event('click')
     const fn = jest.fn()
-    patchProp(el, 'onClick.capture', null, fn)
-    patchProp(el, 'onClick.capture', fn, null)
+    patchProp(el, 'onClickCapture', null, fn)
     el.dispatchEvent(event)
     await timeout()
+    expect(fn).toHaveBeenCalledTimes(1)
+
+    patchProp(el, 'onClickCapture', fn, null)
     el.dispatchEvent(event)
     await timeout()
-    expect(fn).not.toHaveBeenCalled()
+    el.dispatchEvent(event)
+    await timeout()
+    expect(fn).toHaveBeenCalledTimes(1)
   })
 
   it('should support native onclick', async () => {
index 755d5841ab1d00c08a85769c365ef8289e2613ff..78199c64f475d2f03059b5c28d532e31e46cb4cf 100644 (file)
@@ -82,23 +82,20 @@ export function patchEvent(
   }
 }
 
-const optionsModifierRE = /\.(once|passive|capture)\b/g
+const optionsModifierRE = /(?:Once|Passive|Capture)$/
 
 function parseName(name: string): [string, EventListenerOptions | undefined] {
-  name = name.slice(2).toLowerCase()
+  let options: EventListenerOptions | undefined
   if (optionsModifierRE.test(name)) {
-    const options: EventListenerOptions = {}
-    name = name.replace(
-      optionsModifierRE,
-      (_, key: keyof EventListenerOptions) => {
-        options[key] = true
-        return ''
-      }
-    )
-    return [name, options]
-  } else {
-    return [name, undefined]
+    options = {}
+    let m
+    while ((m = name.match(optionsModifierRE))) {
+      name = name.slice(0, name.length - m[0].length)
+      ;(options as any)[m[0].toLowerCase()] = true
+      options
+    }
   }
+  return [name.slice(2).toLowerCase(), options]
 }
 
 function createInvoker(