import { FOCUS_DISABLED , FOCUS_GROUP } from '../constants' ; import { asArray , toArray } from './array' ; param nodes returns { * } const filterNested = < T extends HTMLElement > ( nodes ) : T [ ] => { const contained = new Set ( ) ; const l = nodes . length ; for ( let i = 0 ; i < l ; i += 1 ) { for ( let j = i + 1 ; j < l ; j += 1 ) { const position = nodes [ i ] . compareDocumentPosition ( nodes [ j ] ) ; if ( ( position & Node . DOCUMENT_POSITION_CONTAINED_BY ) > 0 ) { contained . add ( j ) ; } if ( ( position & Node . DOCUMENT_POSITION_CONTAINS ) > 0 ) { contained . add ( i ) ; } } } return nodes . filter ( ( _ , index ) => ! contained . has ( index ) ) ; } ; param node returns { * } const getTopParent = ( node ) : HTMLElement => node . parentNode ? getTopParent ( node . parentNode as HTMLElement ) : node ; param node returns { T } export const getAllAffectedNodes = ( node ) : HTMLInputElement [ ] => { const nodes = asArray ( node ) ; return nodes . filter ( Boolean ) . reduce ( ( acc , currentNode ) => { const group = currentNode . getAttribute ( FOCUS_GROUP ) ; acc . push ( ... ( group ? filterNested ( toArray ( getTopParent ( currentNode ) . querySelectorAll < HTMLInputElement > ( `[${ FOCUS_GROUP }="${ group }"]:not([${ FOCUS_DISABLED }="disabled"])` ) ) ) : [ currentNode as HTMLInputElement ] ) ) ; return acc ; } , [ ] as HTMLInputElement [ ] ) ; } ;