MessageEvent cannot be prevented even if cancelable is true
Version
v18.14.2 (the same on LTS v20.11.0)
Platform
Darwin imac.home 22.6.0 Darwin Kernel Version 22.6.0: Wed Jul 5 22:21:56 PDT 2023; root:xnu-8796.141.3~6/RELEASE_X86_64 x86_64
Subsystem
No response
What steps will reproduce the bug?
// example.js
let t = new EventTarget()
t.addEventListener('message', (e) => console.log('cancelable?', e.cancelable))
t.dispatchEvent(new MessageEvent('message', { cancelable: true }))
node example.js
How often does it reproduce? Is there a required condition?
The issue can be reproduced every time.
What is the expected behavior? Why is that the expected behavior?
I expect the following:
-
e.cancelableistruein the event listener for "message'. - Calling
e.preventDefault()will sete.defaultPreventedtotrue.
In other words, I expect the same behavior as with the regular Event instance:
let t = new EventTarget()
t.addEventListener('message', (e) => console.log('cancelable?', e.cancelable))
// Regular Event behaves correctly and can be canceled.
t.dispatchEvent(new Event('message', { cancelable: true }))
What do you see instead?
The cancelable attribute on the MessageEvent instance is always false, no matter the cancelable value in the event init dictionary.
Calling e.preventDefault() has no effect on e.defaultPrevented (much likely because the cancelable attribute is false.
Additional information
I'm constructing a MessageEvent that I then dispatch on EventTarget and want to have the listeners being able to cancel that event (prevent its default).
This is either an intentional behavior or a bug. In case this is intentional, can we please get some clarification as to why and have the docs updated to mention this behavior difference?
Note that both Event and MessageEvent scenarios run correctly in the browser (both events are cancelable and their defaults can be prevented).
The only detail I can spot is that the event init dictionary for the MessageEvent is being transformed here:
https://github.com/nodejs/node/blob/10c6596f6d7abf7451112e767f8277fcd276d796/deps/undici/src/lib/websocket/events.js#L17
I don't know if this
MessageEventclass is what we get as a global in Node.js though. I imagine it is since message events are WebSocket-specific events.
https://github.com/nodejs/node/blob/fc801687eafe39f61880c7271e3b7529bdebb44a/lib/internal/worker/io.js#L131
undici's MessageEvent isn't exposed, I had no idea node implemented it honestly.
@KhafraDev, it seems to be a global MessageEvent class, nothing from Undici. You can reproduce the issue using the code snippets I posted above even in a terminal (no dependencies).