import { append , create , h , S1Node , } from 'stage1' ; import { Link , LinkComponent , LinkProps } from './Link' ; type FolderPopupComponent = HTMLDivElement & { adjustPosition ( ) : void ; } ; const CLOSE_DELAY_MS = 600 ; let emptyPopupView ; let arrowView ; const folderPopupView = create ( 'div' ) ; folderPopupView . className = 'sf' ; const FolderPopup = ( parent , children , topLevel ) : FolderPopupComponent => { const root = folderPopupView . cloneNode ( true ) as FolderPopupComponent ; const parentRect = parent . getBoundingClientRect ( ) ; let top ; let left ; if ( topLevel ) { top = parentRect . bottom ; left = parentRect . left ; } else { top = parentRect . top ; left = parentRect . right ; } root . style . cssText = `top:${ top }px;left:${ left }px;max-height:${ window . innerHeight - top }px` ; if ( ! children . length ) { append ( ( emptyPopupView ??= h ( '<div id=e>(empty)</div>' ) ) , root ) ; } else { children . forEach ( ( item ) => { append ( BookmarkNode ( item ) , root ) ; } ) ; } root . adjustPosition = ( ) => { const viewportWidth = document . documentElement . clientWidth ; const width = root . offsetWidth ; if ( left + width > viewportWidth ) { root . style . left = topLevel ? viewportWidth - width + 'px' : parentRect . left - width + 'px' ; } } ; return root ; } ; type FolderComponent = HTMLDivElement & { closePopup ( this ) : void ; } ; export interface FolderProps extends Omit < chrome . bookmarks . BookmarkTreeNode , 'id' > { end ? : boolean ; } const folderView = create ( 'div' ) ; folderView . className = 'f' ; export const Folder = ( item ) : FolderComponent => { const root = folderView . cloneNode ( true ) as FolderComponent ; let popup ; let timer ; const clearTimer = ( ) => clearTimeout ( timer ) ; const resetTimer = ( ) => { clearTimer ( ) ; timer = setTimeout ( root . closePopup , CLOSE_DELAY_MS ) ; } ; root . textContent = item . title ; if ( item . end ) root . className += ' end' ; if ( + item . parentId ! > 1 ) { append ( ( arrowView ??= h ( `
        <svg class=i>
          <path d="M5 12h14M12 5l7 7-7 7"/>
        </svg>
      ` ) ) . cloneNode ( true ) , root ) ; } root . closePopup = ( ) => { if ( popup ) { popup . remove ( ) ; popup = null ; } } ; root . __mouseover = ( ) => { clearTimer ( ) ; if ( ! popup ) { const parent = root . parentNode as Element ; parent . querySelectorAll < FolderComponent > ( '.f' ) . forEach ( ( folder ) => folder . closePopup ( ) ) ; popup = FolderPopup ( root , item . children ! , parent . id === 'b' ) ; popup . __mouseover = clearTimer ; popup . __mouseout = resetTimer ; append ( popup , root ) ; popup . adjustPosition ( ) ; } } ; root . __mouseout = resetTimer ; return root ; } ; export const BookmarkNode = ( item ) : LinkComponent | FolderComponent => ( item . url ? Link : Folder ) ( item ) ;