Skip to content

Commit

Permalink
fix(runtime-dom/v-on): support event.stopImmediatePropagation on mult…
Browse files Browse the repository at this point in the history
…iple listeners

close #916
  • Loading branch information
yyx990803 committed Apr 15, 2020
1 parent 3178504 commit d45e475
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 2 deletions.
14 changes: 14 additions & 0 deletions packages/runtime-dom/__tests__/patchEvents.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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)
})
})
20 changes: 18 additions & 2 deletions packages/runtime-dom/src/modules/events.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { EMPTY_OBJ } from '@vue/shared'
import { EMPTY_OBJ, isArray } from '@vue/shared'
import {
ComponentInternalInstance,
callWithAsyncErrorHandling
Expand Down Expand Up @@ -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]
Expand All @@ -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
}
}

0 comments on commit d45e475

Please sign in to comment.