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)
+ })
})
-import { EMPTY_OBJ } from '@vue/shared'
+import { EMPTY_OBJ, isArray } from '@vue/shared'
import {
ComponentInternalInstance,
callWithAsyncErrorHandling
// AFTER it was attached.
if (e.timeStamp >= invoker.lastUpdated - 1) {
callWithAsyncErrorHandling(
- invoker.value,
+ patchStopImmediatePropagation(e, invoker.value),
instance,
ErrorCodes.NATIVE_EVENT_HANDLER,
[e]
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
+ }
+}