]> git.ipfire.org Git - thirdparty/vuejs/core.git/commitdiff
fix(runtime-dom/v-on): support event.stopImmediatePropagation on multiple listeners
authorEvan You <yyx990803@gmail.com>
Wed, 15 Apr 2020 14:35:34 +0000 (10:35 -0400)
committerEvan You <yyx990803@gmail.com>
Wed, 15 Apr 2020 14:35:34 +0000 (10:35 -0400)
close #916

packages/runtime-dom/__tests__/patchEvents.spec.ts
packages/runtime-dom/src/modules/events.ts

index b870a8be344013476eb40ca05d74082bc89c3309..2bb8e2ac080875e7317f3db84decdb56a9c071aa 100644 (file)
@@ -134,4 +134,18 @@ describe(`runtime-dom: events patching`, () => {
     expect(fn).toHaveBeenCalledTimes(1)
     expect(fn2).toHaveBeenCalledWith(event)
   })
+
+  it('should support stopImmediatePropagation on multiple listeners', async () => {
+    const el = document.createElement('div')
+    const event = new Event('click')
+    const fn1 = jest.fn((e: Event) => {
+      e.stopImmediatePropagation()
+    })
+    const fn2 = jest.fn()
+    patchProp(el, 'onClick', null, [fn1, fn2])
+    el.dispatchEvent(event)
+    await timeout()
+    expect(fn1).toHaveBeenCalledTimes(1)
+    expect(fn2).toHaveBeenCalledTimes(0)
+  })
 })
index 6789934c7ec7925e7f2670848c4e143b32d88820..bb3ae9be00838da7ba8c970aba315b41f16050e1 100644 (file)
@@ -1,4 +1,4 @@
-import { EMPTY_OBJ } from '@vue/shared'
+import { EMPTY_OBJ, isArray } from '@vue/shared'
 import {
   ComponentInternalInstance,
   callWithAsyncErrorHandling
@@ -130,7 +130,7 @@ function createInvoker(
     // AFTER it was attached.
     if (e.timeStamp >= invoker.lastUpdated - 1) {
       callWithAsyncErrorHandling(
-        invoker.value,
+        patchStopImmediatePropagation(e, invoker.value),
         instance,
         ErrorCodes.NATIVE_EVENT_HANDLER,
         [e]
@@ -142,3 +142,19 @@ function createInvoker(
   invoker.lastUpdated = getNow()
   return invoker
 }
+
+function patchStopImmediatePropagation(
+  e: Event,
+  value: EventValue
+): EventValue {
+  if (isArray(value)) {
+    const originalStop = e.stopImmediatePropagation
+    e.stopImmediatePropagation = () => {
+      originalStop.call(e)
+      ;(e as any)._stopped = true
+    }
+    return value.map(fn => (e: Event) => !(e as any)._stopped && fn(e))
+  } else {
+    return value
+  }
+}