Skip to content

Commit

Permalink
events: remove weak listener for event target
Browse files Browse the repository at this point in the history
  • Loading branch information
rluvaton committed Aug 10, 2023
1 parent f1b3ade commit 9d27708
Showing 1 changed file with 34 additions and 5 deletions.
39 changes: 34 additions & 5 deletions lib/internal/event_target.js
Original file line number Diff line number Diff line change
Expand Up @@ -406,7 +406,7 @@ let weakListenersState = null;
let objectToWeakListenerMap = null;
function weakListeners() {
weakListenersState ??= new SafeFinalizationRegistry(
(listener) => listener.remove(),
({ eventTarget, listener, eventType }) => eventTarget.removeInternalListener(eventType, listener),
);
objectToWeakListenerMap ??= new SafeWeakMap();
return { registry: weakListenersState, map: objectToWeakListenerMap };
Expand All @@ -428,7 +428,7 @@ const kFlagResistStopPropagation = 1 << 6;
// the linked list makes dispatching faster, even if adding/removing is
// slower.
class Listener {
constructor(previous, listener, once, capture, passive,
constructor(eventTarget, eventType, previous, listener, once, capture, passive,
isNodeStyleListener, weak, resistStopPropagation) {
this.next = undefined;
if (previous !== undefined)
Expand All @@ -455,7 +455,12 @@ class Listener {

if (this.weak) {
this.callback = new SafeWeakRef(listener);
weakListeners().registry.register(listener, this, this);
weakListeners().registry.register(listener, {
__proto__: null,
eventTarget,
listener: this,
eventType
}, this);
// Make the retainer retain the listener in a WeakMap
weakListeners().map.set(weak, listener);
this.listener = this.callback;
Expand Down Expand Up @@ -621,7 +626,7 @@ class EventTarget {
if (root === undefined) {
root = { size: 1, next: undefined, resistStopPropagation: Boolean(resistStopPropagation) };
// This is the first handler in our linked list.
new Listener(root, listener, once, capture, passive,
new Listener(this, type, root, listener, once, capture, passive,
isNodeStyleListener, weak, resistStopPropagation);
this[kNewListener](
root.size,
Expand All @@ -648,7 +653,7 @@ class EventTarget {
return;
}

new Listener(previous, listener, once, capture, passive,
new Listener(this, type, previous, listener, once, capture, passive,
isNodeStyleListener, weak, resistStopPropagation);
root.size++;
root.resistStopPropagation ||= Boolean(resistStopPropagation);
Expand Down Expand Up @@ -691,6 +696,30 @@ class EventTarget {
}
}

// TODO - rename this function
removeInternalListener(type, listener) {
type = webidl.converters.DOMString(type);

const root = this[kEvents].get(type);
if (root === undefined || root.next === undefined)
return;

const capture = listener.capture === true;

let handler = root.next;
while (handler !== undefined) {
if (handler === listener) {
handler.remove();
root.size--;
if (root.size === 0)
this[kEvents].delete(type);
this[kRemoveListener](root.size, type, listener.listener, capture);
break;
}
handler = handler.next;
}
}

/**
* @param {Event} event
*/
Expand Down

0 comments on commit 9d27708

Please sign in to comment.