node
node copied to clipboard
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.cancelable
istrue
in the event listener for "message'. - Calling
e.preventDefault()
will sete.defaultPrevented
totrue
.
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
MessageEvent
class 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).