Skip to content

Commit 7beec6a

Browse files
committed
fixup
1 parent 26c85fa commit 7beec6a

File tree

1 file changed

+144
-112
lines changed

1 file changed

+144
-112
lines changed

lib/internal/event_target.js

Lines changed: 144 additions & 112 deletions
Original file line numberDiff line numberDiff line change
@@ -552,6 +552,8 @@ class EventTarget {
552552
initEventTarget(this);
553553
}
554554

555+
#fastHandlers = new Map();
556+
555557
[kNewListener](size, type, listener, once, capture, passive, weak) {
556558
if (this[kMaxEventTargetListeners] > 0 &&
557559
size > this[kMaxEventTargetListeners] &&
@@ -644,45 +646,58 @@ class EventTarget {
644646
}
645647
}
646648

647-
type = webidl.converters.DOMString(type);
648-
649-
let root = this[kEvents].get(type);
649+
if (options === kEmptyObject && this.#fastHandlers != null) {
650+
const entry = this.#fastHandlers.get(type);
651+
if (entry === undefined) {
652+
this.#fastHandlers.set(type, listener);
653+
} else if (typeof entry === 'function') {
654+
this.#fastHandlers.set(type, new Set([entry, listener]));
655+
} else {
656+
entry.add(listener);
657+
}
658+
} else {
659+
// XXX: Convert fastMode to slowMode....
660+
661+
type = webidl.converters.DOMString(type);
662+
663+
let root = this[kEvents].get(type);
664+
665+
if (root === undefined) {
666+
root = { size: 1, next: undefined, resistStopPropagation: Boolean(resistStopPropagation) };
667+
// This is the first handler in our linked list.
668+
new Listener(this, type, root, listener, once, capture, passive,
669+
isNodeStyleListener, weak, resistStopPropagation);
670+
this[kNewListener](
671+
root.size,
672+
type,
673+
listener,
674+
once,
675+
capture,
676+
passive,
677+
weak);
678+
this[kEvents].set(type, root);
679+
return;
680+
}
650681

651-
if (root === undefined) {
652-
root = { size: 1, next: undefined, resistStopPropagation: Boolean(resistStopPropagation) };
653-
// This is the first handler in our linked list.
654-
new Listener(this, type, root, listener, once, capture, passive,
655-
isNodeStyleListener, weak, resistStopPropagation);
656-
this[kNewListener](
657-
root.size,
658-
type,
659-
listener,
660-
once,
661-
capture,
662-
passive,
663-
weak);
664-
this[kEvents].set(type, root);
665-
return;
666-
}
682+
let handler = root.next;
683+
let previous = root;
667684

668-
let handler = root.next;
669-
let previous = root;
685+
// We have to walk the linked list to see if we have a match
686+
while (handler !== undefined && !handler.same(listener, capture)) {
687+
previous = handler;
688+
handler = handler.next;
689+
}
670690

671-
// We have to walk the linked list to see if we have a match
672-
while (handler !== undefined && !handler.same(listener, capture)) {
673-
previous = handler;
674-
handler = handler.next;
675-
}
691+
if (handler !== undefined) { // Duplicate! Ignore
692+
return;
693+
}
676694

677-
if (handler !== undefined) { // Duplicate! Ignore
678-
return;
695+
new Listener(this, type, previous, listener, once, capture, passive,
696+
isNodeStyleListener, weak, resistStopPropagation);
697+
root.size++;
698+
root.resistStopPropagation ||= Boolean(resistStopPropagation);
699+
this[kNewListener](root.size, type, listener, once, capture, passive, weak);
679700
}
680-
681-
new Listener(this, type, previous, listener, once, capture, passive,
682-
isNodeStyleListener, weak, resistStopPropagation);
683-
root.size++;
684-
root.resistStopPropagation ||= Boolean(resistStopPropagation);
685-
this[kNewListener](root.size, type, listener, once, capture, passive, weak);
686701
}
687702

688703
/**
@@ -700,24 +715,37 @@ class EventTarget {
700715
if (!validateEventListener(listener))
701716
return;
702717

703-
type = webidl.converters.DOMString(type);
704-
const capture = options?.capture === true;
705-
706-
const root = this[kEvents].get(type);
707-
if (root === undefined || root.next === undefined)
708-
return;
709-
710-
let handler = root.next;
711-
while (handler !== undefined) {
712-
if (handler.same(listener, capture)) {
713-
handler.remove();
714-
root.size--;
715-
if (root.size === 0)
716-
this[kEvents].delete(type);
717-
this[kRemoveListener](root.size, type, listener, capture);
718-
break;
718+
if (options === kEmptyObject && this.#fastHandlers != null) {
719+
const entry = this.#fastHandlers.get(type);
720+
if (entry === undefined) {
721+
// Do nothing
722+
} else if (entry === listener) {
723+
this.#fastHandlers.delete(type);
724+
} else {
725+
entry.delete(listener);
726+
}
727+
} else {
728+
// XXX: Convert fastMode to slowMode....
729+
730+
type = webidl.converters.DOMString(type);
731+
const capture = options?.capture === true;
732+
733+
const root = this[kEvents].get(type);
734+
if (root === undefined || root.next === undefined)
735+
return;
736+
737+
let handler = root.next;
738+
while (handler !== undefined) {
739+
if (handler.same(listener, capture)) {
740+
handler.remove();
741+
root.size--;
742+
if (root.size === 0)
743+
this[kEvents].delete(type);
744+
this[kRemoveListener](root.size, type, listener, capture);
745+
break;
746+
}
747+
handler = handler.next;
719748
}
720-
handler = handler.next;
721749
}
722750
}
723751

@@ -764,77 +792,81 @@ class EventTarget {
764792
}
765793

766794
[kHybridDispatch](nodeValue, type, event) {
767-
const createEvent = () => {
768-
if (event === undefined) {
769-
event = this[kCreateEvent](nodeValue, type);
795+
if (this.#fastHandlers != null) {
796+
// XXX: Implement
797+
} else {
798+
const createEvent = () => {
799+
if (event === undefined) {
800+
event = this[kCreateEvent](nodeValue, type);
801+
event[kTarget] = this;
802+
event[kIsBeingDispatched] = true;
803+
}
804+
return event;
805+
};
806+
if (event !== undefined) {
770807
event[kTarget] = this;
771808
event[kIsBeingDispatched] = true;
772809
}
773-
return event;
774-
};
775-
if (event !== undefined) {
776-
event[kTarget] = this;
777-
event[kIsBeingDispatched] = true;
778-
}
779-
780-
const root = this[kEvents].get(type);
781-
if (root === undefined || root.next === undefined) {
782-
if (event !== undefined)
783-
event[kIsBeingDispatched] = false;
784-
return true;
785-
}
786810

787-
let handler = root.next;
788-
let next;
789-
790-
const iterationCondition = () => {
791-
if (handler === undefined) {
792-
return false;
793-
}
794-
return root.resistStopPropagation || handler.passive || event?.[kStop] !== true;
795-
};
796-
while (iterationCondition()) {
797-
// Cache the next item in case this iteration removes the current one
798-
next = handler.next;
799-
800-
if (handler.removed || (event?.[kStop] === true && !handler.resistStopPropagation)) {
801-
// Deal with the case an event is removed while event handlers are
802-
// Being processed (removeEventListener called from a listener)
803-
// And the case of event.stopImmediatePropagation() being called
804-
// For events not flagged as resistStopPropagation
805-
handler = next;
806-
continue;
807-
}
808-
if (handler.once) {
809-
handler.remove();
810-
root.size--;
811-
const { listener, capture } = handler;
812-
this[kRemoveListener](root.size, type, listener, capture);
811+
const root = this[kEvents].get(type);
812+
if (root === undefined || root.next === undefined) {
813+
if (event !== undefined)
814+
event[kIsBeingDispatched] = false;
815+
return true;
813816
}
814817

815-
try {
816-
let arg;
817-
if (handler.isNodeStyleListener) {
818-
arg = nodeValue;
819-
} else {
820-
arg = createEvent();
818+
let handler = root.next;
819+
let next;
820+
821+
const iterationCondition = () => {
822+
if (handler === undefined) {
823+
return false;
824+
}
825+
return root.resistStopPropagation || handler.passive || event?.[kStop] !== true;
826+
};
827+
while (iterationCondition()) {
828+
// Cache the next item in case this iteration removes the current one
829+
next = handler.next;
830+
831+
if (handler.removed || (event?.[kStop] === true && !handler.resistStopPropagation)) {
832+
// Deal with the case an event is removed while event handlers are
833+
// Being processed (removeEventListener called from a listener)
834+
// And the case of event.stopImmediatePropagation() being called
835+
// For events not flagged as resistStopPropagation
836+
handler = next;
837+
continue;
838+
}
839+
if (handler.once) {
840+
handler.remove();
841+
root.size--;
842+
const { listener, capture } = handler;
843+
this[kRemoveListener](root.size, type, listener, capture);
821844
}
822-
const callback = handler.weak ?
823-
handler.callback.deref() : handler.callback;
824-
let result;
825-
if (callback) {
826-
result = FunctionPrototypeCall(callback, this, arg);
827-
if (!handler.isNodeStyleListener) {
828-
arg[kIsBeingDispatched] = false;
845+
846+
try {
847+
let arg;
848+
if (handler.isNodeStyleListener) {
849+
arg = nodeValue;
850+
} else {
851+
arg = createEvent();
852+
}
853+
const callback = handler.weak ?
854+
handler.callback.deref() : handler.callback;
855+
let result;
856+
if (callback) {
857+
result = FunctionPrototypeCall(callback, this, arg);
858+
if (!handler.isNodeStyleListener) {
859+
arg[kIsBeingDispatched] = false;
860+
}
829861
}
862+
if (result !== undefined && result !== null)
863+
addCatch(result);
864+
} catch (err) {
865+
emitUncaughtException(err);
830866
}
831-
if (result !== undefined && result !== null)
832-
addCatch(result);
833-
} catch (err) {
834-
emitUncaughtException(err);
835-
}
836867

837-
handler = next;
868+
handler = next;
869+
}
838870
}
839871

840872
if (event !== undefined)

0 commit comments

Comments
 (0)