@@ -14,11 +14,20 @@ function triggerFocusChange(element: HTMLElement, event: 'focus' | 'blur') {
14
14
element . addEventListener ( event , handler ) ;
15
15
element [ event ] ( ) ;
16
16
element . removeEventListener ( event , handler ) ;
17
+
18
+ // Some browsers won't move focus if the browser window is blurred while other will move it
19
+ // asynchronously. If that is the case, we fake the event sequence as a fallback.
17
20
if ( ! eventFired ) {
18
- dispatchFakeEvent ( element , event ) ;
21
+ simulateFocusSequence ( element , event ) ;
19
22
}
20
23
}
21
24
25
+ /** Simulates the full event sequence for a focus event. */
26
+ function simulateFocusSequence ( element : HTMLElement , event : 'focus' | 'blur' ) {
27
+ dispatchFakeEvent ( element , event ) ;
28
+ dispatchFakeEvent ( element , event === 'focus' ? 'focusin' : 'focusout' ) ;
29
+ }
30
+
22
31
/**
23
32
* Patches an elements focus and blur methods to emit events consistently and predictably.
24
33
* This is necessary, because some browsers can call the focus handlers asynchronously,
@@ -28,8 +37,8 @@ function triggerFocusChange(element: HTMLElement, event: 'focus' | 'blur') {
28
37
// TODO: Check if this element focus patching is still needed for local testing,
29
38
// where browser is not necessarily focused.
30
39
export function patchElementFocus ( element : HTMLElement ) {
31
- element . focus = ( ) => dispatchFakeEvent ( element , 'focus' ) ;
32
- element . blur = ( ) => dispatchFakeEvent ( element , 'blur' ) ;
40
+ element . focus = ( ) => simulateFocusSequence ( element , 'focus' ) ;
41
+ element . blur = ( ) => simulateFocusSequence ( element , 'blur' ) ;
33
42
}
34
43
35
44
/** @docs -private */
0 commit comments