import { customAttr } from './constants' ; import getLevelList from './getLevelList' ; import getStartNode from './getStartNode' ; import getCustomSplitNodeInfo , { ICustomSplitNodeInfo , } from './getCustomSplitNodeInfo' ; interface ISelectedInfo { noteContainer : Element ; range : Range ; } export interface INoteTextHighlightInfoItem { level : number [ ] ; start : number ; end : number ; text : string ; } const defaultCustomNodeInfo = { isStart : false , isEnd : false , start : 0 , end : 0 , } ; const getSelectedInfo = ( { range , noteContainer , } ) : INoteTextHighlightInfoItem [ ] => { const { commonAncestorContainer , endContainer , endOffset , startContainer , startOffset , } = range ; const outerContainer = getStartNode ( commonAncestorContainer as Element , noteContainer ) ; const topLevel = getLevelList ( outerContainer , noteContainer ) ; let node = getStartNode ( startContainer as Element , noteContainer ) ; let isStart = false ; let isEnd = false ; const list = [ ] ; let customNodeInfo = defaultCustomNodeInfo ; outer : while ( node && outerContainer . contains ( node ) && ! isEnd ) { const isCustom = node . getAttribute && node . getAttribute ( customAttr ) ; if ( isCustom ) { customNodeInfo = getCustomSplitNodeInfo ( { range , isStart , node } ) ; isStart = customNodeInfo . isStart ; isEnd = customNodeInfo . isEnd ; } else { if ( node === startContainer ) { isStart = true ; } if ( node === endContainer ) { isEnd = true ; } } if ( isStart ) { const level = getLevelList ( node , outerContainer ) ; if ( node . nodeType === 3 ) { let textStartOffset = 0 ; let textEndOffset = node ?. textContent ?. length || 0 ; if ( node === startContainer ) { textStartOffset = startOffset ; } if ( node === endContainer ) { textEndOffset = endOffset ; } list . push ( { level : [ ... topLevel , ... level ] , start : textStartOffset , end : textEndOffset , text : node . textContent ?. slice ( textStartOffset , textEndOffset ) || '' , } ) ; } else if ( isCustom ) { const { start = 0 , end = 0 } = customNodeInfo ; list . push ( { level : [ ... topLevel , ... level ] , start : start , end : end , text : node ?. textContent ?. slice ( start , end ) || '' , } ) ; } } if ( node . childNodes . length && ! isCustom ) { node = node . childNodes [ 0 ] as Element ; } else if ( node . nextSibling ) { node = node . nextSibling as Element ; } else { do { node = node . parentNode as Element ; if ( noteContainer === node ) { break outer ; } } while ( ! node . nextSibling ) ; node = node . nextSibling as Element ; } } return list . filter ( item => { return item . text && item . text . trim ( ) ; } ) ; } ; export default getSelectedInfo ;