chore: use unbound event listeners (#12165)

pull/12175/head
Rich Harris 1 year ago committed by GitHub
parent 752f872a1d
commit 7e462eec26
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -44,7 +44,7 @@ export function create_event(event_name, dom, handler, options) {
function target_handler(/** @type {Event} */ event) { function target_handler(/** @type {Event} */ event) {
if (!options.capture) { if (!options.capture) {
// Only call in the bubble phase, else delegated events would be called before the capturing events // Only call in the bubble phase, else delegated events would be called before the capturing events
handle_event_propagation(dom, event); handle_event_propagation.call(dom, event);
} }
if (!event.cancelBubble) { if (!event.cancelBubble) {
return handler.call(this, event); return handler.call(this, event);
@ -143,11 +143,12 @@ export function delegate(events) {
} }
/** /**
* @param {EventTarget} handler_element * @this {EventTarget}
* @param {Event} event * @param {Event} event
* @returns {void} * @returns {void}
*/ */
export function handle_event_propagation(handler_element, event) { export function handle_event_propagation(event) {
var handler_element = this;
var owner_document = /** @type {Node} */ (handler_element).ownerDocument; var owner_document = /** @type {Node} */ (handler_element).ownerDocument;
var event_name = event.type; var event_name = event.type;
var path = event.composedPath?.() || []; var path = event.composedPath?.() || [];

@ -196,38 +196,23 @@ function _mount(Component, { target, anchor, props = {}, events, context, intro
const registered_events = new Set(); const registered_events = new Set();
const bound_event_listener = handle_event_propagation.bind(null, target);
const bound_document_event_listener = handle_event_propagation.bind(null, document);
/** @param {Array<string>} events */ /** @param {Array<string>} events */
const event_handle = (events) => { const event_handle = (events) => {
for (let i = 0; i < events.length; i++) { for (let i = 0; i < events.length; i++) {
const event_name = events[i]; const event_name = events[i];
const passive = PassiveDelegatedEvents.includes(event_name);
if (!registered_events.has(event_name)) { if (!registered_events.has(event_name)) {
registered_events.add(event_name); registered_events.add(event_name);
// Add the event listener to both the container and the document. // Add the event listener to both the container and the document.
// The container listener ensures we catch events from within in case // The container listener ensures we catch events from within in case
// the outer content stops propagation of the event. // the outer content stops propagation of the event.
target.addEventListener( target.addEventListener(event_name, handle_event_propagation, { passive });
event_name,
bound_event_listener,
PassiveDelegatedEvents.includes(event_name)
? {
passive: true
}
: undefined
);
// The document listener ensures we catch events that originate from elements that were // The document listener ensures we catch events that originate from elements that were
// manually moved outside of the container (e.g. via manual portals). // manually moved outside of the container (e.g. via manual portals).
document.addEventListener( document.addEventListener(event_name, handle_event_propagation, { passive });
event_name,
bound_document_event_listener,
PassiveDelegatedEvents.includes(event_name)
? {
passive: true
}
: undefined
);
} }
} }
}; };
@ -264,9 +249,10 @@ function _mount(Component, { target, anchor, props = {}, events, context, intro
return () => { return () => {
for (const event_name of registered_events) { for (const event_name of registered_events) {
target.removeEventListener(event_name, bound_event_listener); target.removeEventListener(event_name, handle_event_propagation);
document.removeEventListener(event_name, bound_document_event_listener); document.removeEventListener(event_name, handle_event_propagation);
} }
root_event_handles.delete(event_handle); root_event_handles.delete(event_handle);
mounted_components.delete(component); mounted_components.delete(component);
}; };

Loading…
Cancel
Save