Skip to content

Commit d45e475

Browse files
committed
fix(runtime-dom/v-on): support event.stopImmediatePropagation on multiple listeners
close #916
1 parent 3178504 commit d45e475

File tree

2 files changed

+32
-2
lines changed

2 files changed

+32
-2
lines changed

packages/runtime-dom/__tests__/patchEvents.spec.ts

+14
Original file line numberDiff line numberDiff line change
@@ -134,4 +134,18 @@ describe(`runtime-dom: events patching`, () => {
134134
expect(fn).toHaveBeenCalledTimes(1)
135135
expect(fn2).toHaveBeenCalledWith(event)
136136
})
137+
138+
it('should support stopImmediatePropagation on multiple listeners', async () => {
139+
const el = document.createElement('div')
140+
const event = new Event('click')
141+
const fn1 = jest.fn((e: Event) => {
142+
e.stopImmediatePropagation()
143+
})
144+
const fn2 = jest.fn()
145+
patchProp(el, 'onClick', null, [fn1, fn2])
146+
el.dispatchEvent(event)
147+
await timeout()
148+
expect(fn1).toHaveBeenCalledTimes(1)
149+
expect(fn2).toHaveBeenCalledTimes(0)
150+
})
137151
})

packages/runtime-dom/src/modules/events.ts

+18-2
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { EMPTY_OBJ } from '@vue/shared'
1+
import { EMPTY_OBJ, isArray } from '@vue/shared'
22
import {
33
ComponentInternalInstance,
44
callWithAsyncErrorHandling
@@ -130,7 +130,7 @@ function createInvoker(
130130
// AFTER it was attached.
131131
if (e.timeStamp >= invoker.lastUpdated - 1) {
132132
callWithAsyncErrorHandling(
133-
invoker.value,
133+
patchStopImmediatePropagation(e, invoker.value),
134134
instance,
135135
ErrorCodes.NATIVE_EVENT_HANDLER,
136136
[e]
@@ -142,3 +142,19 @@ function createInvoker(
142142
invoker.lastUpdated = getNow()
143143
return invoker
144144
}
145+
146+
function patchStopImmediatePropagation(
147+
e: Event,
148+
value: EventValue
149+
): EventValue {
150+
if (isArray(value)) {
151+
const originalStop = e.stopImmediatePropagation
152+
e.stopImmediatePropagation = () => {
153+
originalStop.call(e)
154+
;(e as any)._stopped = true
155+
}
156+
return value.map(fn => (e: Event) => !(e as any)._stopped && fn(e))
157+
} else {
158+
return value
159+
}
160+
}

0 commit comments

Comments
 (0)