@@ -548,22 +548,25 @@ export class Query {
548548 let handler ;
549549 let targetSelector ;
550550 if ( isObject ( handlerOrOptions ) ) {
551+ // event with options $('foo').one('click', fn, options);
551552 options = handlerOrOptions ;
552553 handler = targetSelectorOrHandler ;
553554 }
554555 else if ( isString ( targetSelectorOrHandler ) ) {
556+ // event delegation $('foo').one('click', '.baz', fn);
555557 targetSelector = targetSelectorOrHandler ;
556558 handler = handlerOrOptions ;
557559 }
558560 else if ( isFunction ( targetSelectorOrHandler ) ) {
561+ // event handler $('foo').one('click', fn);
559562 handler = targetSelectorOrHandler ;
560563 }
561564
562565 const events = this . getEventArray ( eventNames ) ;
563566
564567 // we store a reference using a set of weakmaps
565568 // this allows us to properly gc handlers but still remove them properly
566- const addToRegistry = ( { el, eventHandler } ) => {
569+ const registerEvent = ( { el, eventHandler } ) => {
567570 const elementHandlers = Query . eventRegistry . get ( el ) || new Set ( ) ;
568571 elementHandlers . add ( eventHandler ) ;
569572 Query . eventRegistry . set ( el , elementHandlers ) ; // for $('div').off();
@@ -618,7 +621,7 @@ export class Query {
618621 abort : ( reason ) => abortController . abort ( reason ) ,
619622 } ;
620623 eventHandlers . push ( eventHandler ) ;
621- addToRegistry ( { el, eventHandler } ) ;
624+ registerEvent ( { el, eventHandler } ) ;
622625 } ) ;
623626 } ) ;
624627
@@ -632,14 +635,17 @@ export class Query {
632635 let handler ;
633636 let targetSelector ;
634637 if ( isObject ( handlerOrOptions ) ) {
638+ // event with options $('foo').one('click', fn, options);
635639 options = handlerOrOptions ;
636640 handler = targetSelectorOrHandler ;
637641 }
638642 else if ( isString ( targetSelectorOrHandler ) ) {
643+ // event delegation $('foo').one('click', '.baz', fn);
639644 targetSelector = targetSelectorOrHandler ;
640645 handler = handlerOrOptions ;
641646 }
642647 else if ( isFunction ( targetSelectorOrHandler ) ) {
648+ // event handler $('foo').one('click', fn);
643649 handler = targetSelectorOrHandler ;
644650 }
645651
@@ -656,6 +662,49 @@ export class Query {
656662 : this . on ( eventName , wrappedHandler , options ) ;
657663 }
658664
665+ onNext ( eventName , targetSelectorOrOptions , options ) {
666+ return new Promise ( ( resolve , reject ) => {
667+ let targetSelector ;
668+
669+ // Handle parameter overloading
670+ if ( isString ( targetSelectorOrOptions ) ) {
671+ targetSelector = targetSelectorOrOptions ;
672+ }
673+ else if ( isObject ( targetSelectorOrOptions ) ) {
674+ options = targetSelectorOrOptions ;
675+ }
676+
677+ // Extract timeout if specified
678+ const timeout = options ?. timeout ;
679+ let timeoutId ;
680+
681+ // Set up timeout if specified
682+ if ( timeout ) {
683+ timeoutId = setTimeout ( ( ) => {
684+ // Clean up event listener
685+ this . off ( eventName , handler ) ;
686+ reject ( new Error ( `Event '${ eventName } ' timeout after ${ timeout } ms` ) ) ;
687+ } , timeout ) ;
688+ }
689+
690+ // Event handler that resolves the promise
691+ const handler = ( event ) => {
692+ if ( timeoutId ) {
693+ clearTimeout ( timeoutId ) ;
694+ }
695+ resolve ( event ) ;
696+ } ;
697+
698+ // Use one() to automatically remove after first trigger
699+ if ( targetSelector ) {
700+ this . one ( eventName , targetSelector , handler , options ) ;
701+ }
702+ else {
703+ this . one ( eventName , handler , options ) ;
704+ }
705+ } ) ;
706+ }
707+
659708 off ( eventNames , handler ) {
660709 if ( isFunction ( eventNames ) ) {
661710 handler = eventNames ;
0 commit comments