1
+ /* eslint-disable no-restricted-properties */
2
+
1
3
/* eslint-disable no-restricted-globals */
2
4
export const canUseDOM = ! ! (
3
5
typeof window !== 'undefined' &&
@@ -20,18 +22,54 @@ export function composeEventHandlers<E extends { defaultPrevented: boolean }>(
20
22
} ;
21
23
}
22
24
23
- export function getOwnerWindow ( element : Element | null | undefined ) {
25
+ export function getOwnerWindow ( element : Node | null | undefined ) {
24
26
if ( ! canUseDOM ) {
25
27
throw new Error ( 'Cannot access window outside of the DOM' ) ;
26
28
}
27
29
// eslint-disable-next-line no-restricted-globals
28
30
return element ?. ownerDocument ?. defaultView ?? window ;
29
31
}
30
32
31
- export function getOwnerDocument ( element : Element | null | undefined ) {
33
+ export function getOwnerDocument ( element : Node | null | undefined ) {
32
34
if ( ! canUseDOM ) {
33
35
throw new Error ( 'Cannot access document outside of the DOM' ) ;
34
36
}
35
37
// eslint-disable-next-line no-restricted-globals
36
38
return element ?. ownerDocument ?? document ;
37
39
}
40
+
41
+ /**
42
+ * Lifted from https://github.com/ariakit/ariakit/blob/main/packages/ariakit-core/src/utils/dom.ts#L37
43
+ * MIT License, Copyright (c) AriaKit.
44
+ */
45
+ export function getActiveElement (
46
+ node : Node | null | undefined ,
47
+ activeDescendant = false
48
+ ) : HTMLElement | null {
49
+ const { activeElement } = getOwnerDocument ( node ) ;
50
+ if ( ! activeElement ?. nodeName ) {
51
+ // `activeElement` might be an empty object if we're interacting with elements
52
+ // inside of an iframe.
53
+ return null ;
54
+ }
55
+
56
+ if ( isFrame ( activeElement ) && activeElement . contentDocument ) {
57
+ return getActiveElement ( activeElement . contentDocument . body , activeDescendant ) ;
58
+ }
59
+
60
+ if ( activeDescendant ) {
61
+ const id = activeElement . getAttribute ( 'aria-activedescendant' ) ;
62
+ if ( id ) {
63
+ const element = getOwnerDocument ( activeElement ) . getElementById ( id ) ;
64
+ if ( element ) {
65
+ return element ;
66
+ }
67
+ }
68
+ }
69
+
70
+ return activeElement as HTMLElement | null ;
71
+ }
72
+
73
+ export function isFrame ( element : Element ) : element is HTMLIFrameElement {
74
+ return element . tagName === 'IFRAME' ;
75
+ }
0 commit comments