Skip to content

EventTarget is broken and not aligned with spec #6022

@ChALkeR

Description

@ChALkeR

Spec: https://dom.spec.whatwg.org/#interface-eventtarget
Used e.g. in WebSocket

extra built-in wrappers around on* handling in EventTarget directly are not aligned with the spec and break usage of anything subclassing EventTarget, as adding on* handlers in subclasses causes double firing and out of order.

const EventsTest1_AC = {
  async test(ctrl, env, ctx) {
    console.log('# Should print: a c')
    const x = new EventTarget()
    x.addEventListener('hit', () => console.log('a'))
    x.onhit = () => console.log('[SHOULD NOT FIRE]')
    x.addEventListener('hit', () => console.log('c'))
    x.dispatchEvent(new Event('hit'))
    await new Promise((accept) => setTimeout(accept, 100))
  },
}

const EventsTest2_ABC = {
  async test(ctrl, env, ctx) {
    console.log('# Should print: a b c')
    const x = new EventTarget()

    for (const type of ['hit']) {
      let current
      Object.defineProperty(x, `on${type}`, {
        get: () => current,
        set(value) {
          if (current) this.removeEventListener(type, current)
          current = value
          if (current) this.addEventListener(type, current)
        },
      })
    }

    x.addEventListener('hit', () => console.log('a'))
    x.onhit = () => console.log('b')
    x.addEventListener('hit', () => console.log('c'))
    x.dispatchEvent(new Event('hit'))

    await new Promise((accept) => setTimeout(accept, 100))
  },
}

if (globalThis.process?.versions?.node || globalThis.window) {
  await EventsTest1_AC.test()
  console.log()
  await EventsTest2_ABC.test()
}

export { EventsTest1_AC, EventsTest2_ABC }

on workerd, prints:

# Should print: a c
[SHOULD NOT FIRE]
a
c

# Should print: a b c
b
a
b
c

on Node.js, Chrome, Safari, Firefox, Deno and Bun prints:

# Should print: a c
a
c

# Should print: a b c
a
b
c

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions