@ -159,12 +159,15 @@ export function delegate(events) {
}
}
// used to store the reference to the currently propagated event
// used to store the reference to the currently propagated event
// to prevent garbage collection between microtasks in Firefox
// to prevent garbage collection between microtasks in Firefox (<= 141)
// If the event object is GCed too early, the expando __root property
// If the event object is GCed too early, the expando __root property
// set on the event object is lost, causing the event delegation
// set on the event object is lost, causing the event delegation
// to process the event twice
// to process the event twice
let last _propagated _event = null ;
let last _propagated _event = null ;
// whether a task is already queued to clear `last_propagated_event`
let last _propagated _event _clear _scheduled = false ;
/ * *
/ * *
* @ this { EventTarget }
* @ this { EventTarget }
* @ param { Event } event
* @ param { Event } event
@ -179,6 +182,21 @@ export function handle_event_propagation(event) {
last _propagated _event = event ;
last _propagated _event = event ;
// The reference is only needed while the event can still reach another
// delegated root, i.e. during the current (synchronous) dispatch and its
// microtask checkpoints. Clearing it in a later task preserves the
// Firefox workaround while making sure the slot doesn't retain the last
// event forever — through `event.target` it would otherwise keep the
// entire detached subtree of whatever the user last clicked in alive
// until the next delegated event happens to arrive.
if ( ! last _propagated _event _clear _scheduled ) {
last _propagated _event _clear _scheduled = true ;
setTimeout ( ( ) => {
last _propagated _event _clear _scheduled = false ;
last _propagated _event = null ;
} ) ;
}
// composedPath contains list of nodes the event has propagated through.
// composedPath contains list of nodes the event has propagated through.
// We check `event_symbol` to skip all nodes below it in case this is a
// We check `event_symbol` to skip all nodes below it in case this is a
// parent of the `event_symbol` node, which indicates that there's nested
// parent of the `event_symbol` node, which indicates that there's nested