const isElementHidden = ( node ) : boolean => { if ( node . nodeType !== Node . ELEMENT_NODE ) { return false ; } const computedStyle = window . getComputedStyle ( node , null ) ; if ( ! computedStyle || ! computedStyle . getPropertyValue ) { return false ; } return ( computedStyle . getPropertyValue ( 'display' ) === 'none' || computedStyle . getPropertyValue ( 'visibility' ) === 'hidden' ) ; } ; type CheckParentCallback = ( node : HTMLElement | undefined ) => boolean ; const isVisibleUncached = ( node , checkParent ) : boolean => ! node || node === document || ( node && node . nodeType === Node . DOCUMENT_NODE ) || ( ! isElementHidden ( node ) && checkParent ( node . parentNode && node . parentNode . nodeType === Node . DOCUMENT_FRAGMENT_NODE ? ( node . parentNode as any ) . host : node . parentNode ) ) ; export type VisibilityCache = Map < HTMLElement | undefined , boolean > ; export const isVisibleCached = ( visibilityCache , node ) : boolean => { const cached = visibilityCache . get ( node ) ; if ( cached !== undefined ) { return cached ; } const result = isVisibleUncached ( node , isVisibleCached . bind ( undefined , visibilityCache ) ) ; visibilityCache . set ( node , result ) ; return result ; } ; export const notHiddenInput = ( node ) => ! ( ( node . tagName === 'INPUT' || node . tagName === 'BUTTON' ) && ( node . type === 'hidden' || node . disabled ) ) ; export const isGuard = ( node ) : boolean => Boolean ( node && node . dataset && node . dataset . focusGuard ) ; export const isNotAGuard = ( node ) => ! isGuard ( node ) ; export const isDefined = < T > ( x ) : x is T => Boolean ( x ) ;