fix(autosubmit): addEventListener with capture for focus events

This commit is contained in:
Paul Chavard 2023-01-17 13:36:38 +01:00
parent 424301376f
commit e4eb54e87a

View file

@ -4,6 +4,9 @@ import invariant from 'tiny-invariant';
export type Detail = Record<string, unknown>; export type Detail = Record<string, unknown>;
// see: https://www.quirksmode.org/blog/archives/2008/04/delegating_the.html
const FOCUS_EVENTS = ['focus', 'blur'];
export class ApplicationController extends Controller { export class ApplicationController extends Controller {
#debounced = new Map<() => void, ReturnType<typeof debounce>>(); #debounced = new Map<() => void, ReturnType<typeof debounce>>();
@ -55,7 +58,12 @@ export class ApplicationController extends Controller {
): void { ): void {
if (typeof targetOrEventName == 'string') { if (typeof targetOrEventName == 'string') {
invariant(typeof eventNameOrHandler != 'string', 'handler is required'); invariant(typeof eventNameOrHandler != 'string', 'handler is required');
this.onTarget(this.element, targetOrEventName, eventNameOrHandler); this.onTarget(
this.element,
targetOrEventName,
eventNameOrHandler,
FOCUS_EVENTS.includes(targetOrEventName)
);
} else { } else {
invariant(eventNameOrHandler == 'string', 'event name is required'); invariant(eventNameOrHandler == 'string', 'event name is required');
invariant(handler, 'handler is required'); invariant(handler, 'handler is required');
@ -73,15 +81,16 @@ export class ApplicationController extends Controller {
private onTarget<HandlerEvent extends Event = Event>( private onTarget<HandlerEvent extends Event = Event>(
target: EventTarget, target: EventTarget,
eventName: string, eventName: string,
handler: (event: HandlerEvent) => void handler: (event: HandlerEvent) => void,
capture?: boolean
): void { ): void {
const disconnect = this.disconnect; const disconnect = this.disconnect;
const callback = (event: Event): void => { const callback = (event: Event): void => {
handler(event as HandlerEvent); handler(event as HandlerEvent);
}; };
target.addEventListener(eventName, callback); target.addEventListener(eventName, callback, capture);
this.disconnect = () => { this.disconnect = () => {
target.removeEventListener(eventName, callback); target.removeEventListener(eventName, callback, capture);
disconnect.call(this); disconnect.call(this);
}; };
} }