import { getUIValue } from '../document' ; import { isElementType } from '../utils' ; import { PointerTarget , SelectionTarget } from './types' ; export function resolveSelectionTarget ( { target , node , offset , } ) { if ( isElementType ( target , [ 'input' , 'textarea' ] ) ) { return { node : target , offset : offset ?? getUIValue ( target ) . length , } ; } else if ( node ) { return { node , offset : offset ?? ( node . nodeType === 3 ? ( node . nodeValue as string ) . length : node . childNodes . length ) , } ; } return findNodeAtTextOffset ( target , offset ) ; } function findNodeAtTextOffset ( node , offset , isRoot = true ) { let i = offset === undefined ? node . childNodes . length - 1 : 0 ; const step = offset === undefined ? - 1 : + 1 ; while ( offset === undefined ? i >= ( isRoot ? Math . max ( node . childNodes . length - 1 , 0 ) : 0 ) : i <= node . childNodes . length ) { const c = node . childNodes . item ( i ) ; const text = String ( c . textContent ) ; if ( text . length ) { if ( offset !== undefined && text . length < offset ) { offset -= text . length ; } else if ( c . nodeType === 1 ) { return findNodeAtTextOffset ( c as Element , offset , false ) ; } else { if ( c . nodeType === 3 ) { return { node : c as Node , offset : offset ?? ( c . nodeValue as string ) . length , } ; } } } i += step ; } return { node , offset : node . childNodes . length } ; }