export function clearSubtree ( elm ) { const removeList = [ ] ; for ( const child of elm . childNodes ) { if ( ! ( child as HTMLElement ) . classList . contains ( "preserve" ) ) { removeList . push ( child ) ; } } for ( const node of removeList ) { elm . removeChild ( node ) ; } } export function findFirstMatch ( root , match ) { if ( match ( root ) ) { return root ; } else { let childElement = root . firstElementChild as HTMLElement ; while ( childElement ) { const result = findFirstMatch ( childElement , match ) ; if ( result ) { return result ; } else { childElement = childElement . nextElementSibling as HTMLElement ; } } } } const textWidthCache = new Map < string , Map < string , number > > ( ) ; const lineHeightCache = new Map < string , number > ( ) ; let cachedCanvas ; export function getLineHeight ( fontstr , lineHeight ? ) { let _fontstr = fontstr ; if ( lineHeight ) { _fontstr += ( `/${ lineHeight }` ) ; } let height = lineHeightCache . get ( _fontstr ) ; if ( height === undefined ) { const elm = document . createElement ( "div" ) ; elm . style . position = "absolute" ; elm . style . zIndex = "-10" ; elm . style . left = "0px" ; elm . style . top = "0px" ; elm . style . font = _fontstr ; document . body . appendChild ( elm ) ; height = getTextHeight ( elm ) ; document . body . removeChild ( elm ) ; lineHeightCache . set ( _fontstr , height ) ; } if ( isNaN ( height ) ) { console . log ( `nan height with fontstr ${ _fontstr }` ) ; } return height ; } export function getTextWidth ( text , font ) { let fontMap = textWidthCache . get ( font ) ; let w ; if ( ! fontMap ) { fontMap = new Map < string , number > ( ) ; } else { w = fontMap . get ( text ) ; } if ( w === undefined ) { const canvas = cachedCanvas || ( cachedCanvas = document . createElement ( "canvas" ) ) ; const context = canvas . getContext ( "2d" ) ; context . font = font ; const metrics = context . measureText ( text ) ; w = metrics . width ; fontMap . set ( text , w ) ; } return w ; } export function getMultiTextWidth ( texts , font ) { const canvas = cachedCanvas || ( cachedCanvas = document . createElement ( "canvas" ) ) ; const context = canvas . getContext ( "2d" ) ; context . font = font ; let sum = 0 ; for ( const text of texts ) { const metrics = context . measureText ( text ) ; sum += metrics . width ; } return sum ; } export function getTextHeight ( elm ) { const computedStyle = getComputedStyle ( elm ) ; if ( computedStyle . lineHeight && ( computedStyle . lineHeight . length > 0 ) && ( computedStyle . lineHeight !== "normal" ) ) { return parseInt ( computedStyle . lineHeight , 10 ) ; } else { return parseInt ( computedStyle . fontSize , 10 ) ; } }