w3c / dom

Moved to https://dom.spec.whatwg.org/
60 stars 18 forks source link

Make EventTarget constructible and its methods generic #140

Closed andyearnshaw closed 7 years ago

andyearnshaw commented 7 years ago

EventTarget, EventEmitter, etc are such a common pattern on the web, it seems like we should just be able to use the native implementation rather than rolling our own or borrowing from somewhere else.

Things that feel like they should work:

let event = new CustomEvent('foo');

let target1 = new EventTarget();
target1.dispatchEvent(event);

let target2 = Object.create(EventTarget.prototype);
target2.dispatchEvent(event);

let target3 = new (class A extends EventTarget {});
target3.dispatchEvent(event);

let target4 = Object.assign({}, EventTarget.prototype);
target4.dispatchEvent(event);

I'm certain this discussion came up a long time ago, but I cannot find the old thread for it so I'm unsure of the outcome. I remember some of the arguments against implied that it wasn't possible, but I'm hoping that's not the case. If event handlers were stored in some kind of internal WeakMap, it seems like addEventListener, removeEventListener and dispatchEvent could all be generic.

The steps to run through for these methods already make them sound very generic. The only thing that seems to imply otherwise is this sentence in the spec:

Each EventTarget has an associated list of event listeners.

This could be removed from the spec, with text added to addEventListener to "create an associated list of event listeners for target" if one does not already exist, with dispatchEvent and removeEventListener having a step to "fetch the associated list for target" and abort if null.

Addendum: it seems like it's not technically feasible to recreate EventTarget in JavaScript. This is because of it appears to execute each callback in its own task, so execution continues regardless if it throws. You can get close using hacky script tags, but you can't emulate this in pure JavaScript because exceptions are considered to be "handled" if they are thrown in a try block.

andyearnshaw commented 7 years ago

Damn, I'm really bad at searching today.

https://github.com/whatwg/dom/issues/441