@@ -485,6 +485,10 @@ function initNavTree(toroot,relpath,allMembersFile) {
485485
486486 $ ( window ) . resize ( function ( ) { adjustSyncIconPosition ( ) ; } ) ;
487487
488+ let navtree_trampoline = {
489+ updateContentTop : function ( c ) { }
490+ }
491+
488492 function initResizable ( ) {
489493 let sidenav , mainnav , pagenav , container , navtree , content , header , footer , barWidth = 6 ;
490494 const RESIZE_COOKIE_NAME = '' + 'width' ;
@@ -642,22 +646,22 @@ function initNavTree(toroot,relpath,allMembersFile) {
642646 const newWidth = $ ( this ) . width ( ) , newHeight = $ ( this ) . height ( ) ;
643647 if ( newWidth != lastWidth || newHeight != lastHeight ) {
644648 resizeHeight ( ) ;
649+ navtree_trampoline . updateContentTop ( content ) ;
645650 lastWidth = newWidth ;
646651 lastHeight = newHeight ;
647652 }
648653 } ) ;
649654 resizeHeight ( ) ;
650655 $ ( window ) . resize ( function ( ) { resizeHeight ( ) ; } ) ;
651656 content . scroll ( function ( ) {
652- if ( typeof navtree_trampoline !== 'undefined' ) {
653- navtree_trampoline . updateScroll ( content . scrollTop ( ) ) ;
654- }
657+ navtree_trampoline . updateContentTop ( content ) ;
655658 } ) ;
656659 } ) ;
657660 }
658661
659662
660663 function initPageToc ( ) {
664+ const topMapping = [ ] ;
661665 const toc_contents = $ ( '#page-nav-contents' ) ;
662666 const content = $ ( '<ul>' ) . addClass ( 'page-outline' ) ;
663667
@@ -700,14 +704,15 @@ function initNavTree(toroot,relpath,allMembersFile) {
700704 function hasSubItems ( ) {
701705 return item . memTitles . length > 0 || rows . toArray ( ) . some ( function ( el ) { return $ ( el ) . is ( ':visible' ) ; } ) ;
702706 }
703- const li = $ ( '<li>' ) ;
707+ const li = $ ( '<li>' ) . attr ( 'id' , 'nav-' + id ) ;
704708 const div = $ ( '<div>' ) . addClass ( 'item' ) ;
705- const span = $ ( '<span>' ) . addClass ( '< arrow> ' ) . css ( { paddingLeft :'0' } ) ;
709+ const span = $ ( '<span>' ) . addClass ( 'arrow' ) . css ( { paddingLeft :'0' } ) ;
706710 if ( hasSubItems ( ) ) {
707- span . append ( $ ( '<span>' ) . addClass ( 'arrowHead opened' ) ) ;
711+ span . append ( $ ( '<span>' ) . addClass ( 'arrowhead opened' ) ) ;
708712 }
709713 const ahref = $ ( '<a>' ) . attr ( 'href' , '#' + id ) . append ( title ) ;
710714 content . append ( li . append ( div . append ( span ) . append ( ahref ) ) ) ;
715+ topMapping . push ( id ) ;
711716 const ulStack = [ ] ;
712717 ulStack . push ( content ) ;
713718 if ( hasSubItems ( ) ) {
@@ -729,11 +734,12 @@ function initNavTree(toroot,relpath,allMembersFile) {
729734 ulStack . pop ( ) ;
730735 inMemberGroup = false ;
731736 }
732- const li2 = $ ( '<li>' ) ;
737+ const li2 = $ ( '<li>' ) . attr ( 'id' , 'nav-' + id ) ;
733738 const div2 = $ ( '<div>' ) . addClass ( 'item' ) ;
734739 const span2 = $ ( '<span>' ) . addClass ( 'arrow' ) . css ( { paddingLeft :parseInt ( ulStack . length * 16 ) + 'px' } ) ;
735740 const ahref = $ ( '<a>' ) . attr ( 'href' , '#' + id ) . append ( escapeHtml ( text ) ) ;
736741 li2 . append ( div2 . append ( span2 ) . append ( ahref ) ) ;
742+ topMapping . push ( id ) ;
737743 if ( isMemberGroupHeader ) {
738744 span2 . append ( $ ( '<span>' ) . addClass ( 'arrowhead opened' ) ) ;
739745 ulStack [ ulStack . length - 1 ] . append ( li2 ) ;
@@ -753,11 +759,12 @@ function initNavTree(toroot,relpath,allMembersFile) {
753759 const name = text . replace ( / \( \) ( \s * \[ \d + \/ \d + \] ) ? $ / , '' ) // func() [2/8] -> func
754760 id = $ ( data ) . find ( 'span.permalink a' ) . attr ( 'href' )
755761 if ( name != undefined ) {
756- const li2 = $ ( '<li>' ) ;
762+ const li2 = $ ( '<li>' ) . attr ( 'id' , 'nav-' + id . substring ( 1 ) ) ;
757763 const div2 = $ ( '<div>' ) . addClass ( 'item' ) ;
758764 const span2 = $ ( '<span>' ) . addClass ( 'arrow' ) . css ( { paddingLeft :parseInt ( ulStack . length * 16 ) + 'px' } ) ;
759765 const ahref = $ ( '<a>' ) . attr ( 'href' , id ) . append ( escapeHtml ( name ) ) ;
760766 ulStack [ ulStack . length - 1 ] . append ( li2 . append ( div2 . append ( span2 ) . append ( ahref ) ) ) ;
767+ topMapping . push ( id . substring ( 1 ) ) ;
761768 }
762769 } ) ;
763770 }
@@ -773,9 +780,9 @@ function initNavTree(toroot,relpath,allMembersFile) {
773780 const pageName = url . split ( '/' ) . pop ( ) . split ( '#' ) [ 0 ] . replace ( / ( \. [ ^ / . ] + ) $ / , '-members$1' ) ;
774781 const li = $ ( '<li>' ) ;
775782 const div = $ ( '<div>' ) . addClass ( 'item' ) ;
776- const span = $ ( '<span>' ) . addClass ( '< arrow> ' ) . css ( { paddingLeft :'0' } ) ;
783+ const span = $ ( '<span>' ) . addClass ( 'arrow' ) . css ( { paddingLeft :'0' } ) ;
777784 const ahref = $ ( '<a>' ) . attr ( 'href' , srcBaseUrl + dstBaseUrl + pageName ) . addClass ( 'noscroll' ) ;
778- content . append ( li . append ( div . append ( span . append ( ahref . append ( LISTOFALLMEMBERS ) ) ) ) ) ;
785+ content . append ( li . append ( div . append ( span ) . append ( ahref . append ( LISTOFALLMEMBERS ) ) ) ) ;
779786 }
780787
781788 if ( groupSections . length == 0 ) {
@@ -789,18 +796,18 @@ function initNavTree(toroot,relpath,allMembersFile) {
789796 ( sectionStack . length ? sectionStack [ sectionStack . length - 1 ] . children : sectionTree ) . push ( node ) ;
790797 sectionStack . push ( { ...node , level } ) ;
791798 } ) ;
792- if ( sectionTree . length > 0 )
793- {
799+ if ( sectionTree . length > 0 ) {
794800 function render ( nodes , level = 0 ) {
795801 return $ ( '<ul>' ) . addClass ( 'nested' ) . append ( nodes . map ( n => {
796- const li = $ ( '<li>' ) ;
802+ const li = $ ( '<li>' ) . attr ( 'id' , 'nav-' + n . id ) ;
797803 const div = $ ( '<div>' ) . addClass ( 'item' ) ;
798804 const span = $ ( '<span>' ) . addClass ( 'arrow' ) . attr ( 'style' , 'padding-left:' + parseInt ( level * 16 ) + 'px;' ) ;
799805 if ( n . children . length > 0 ) { span . append ( $ ( '<span>' ) . addClass ( 'arrowhead opened' ) ) ; }
800806 const url = $ ( '<a>' ) . attr ( 'href' , '#' + n . id ) ;
801807 url . append ( escapeHtml ( n . text ) )
802808 div . append ( span ) . append ( url )
803809 li . append ( div , render ( n . children , level + 1 ) ) ;
810+ topMapping . push ( n . id ) ;
804811 return li ;
805812 } ) ) ;
806813 }
@@ -810,24 +817,49 @@ function initNavTree(toroot,relpath,allMembersFile) {
810817
811818 toc_contents . append ( content ) ;
812819
813- $ ( '.page-outline .arrow' ) . on ( 'click' , function ( ) {
814- var nestedList = $ ( this ) . parent ( ) . siblings ( '.nested' ) ;
815- var arrowhead = $ ( this ) . find ( '.arrowhead' ) ;
816- if ( nestedList . is ( ':visible' ) ) {
817- nestedList . slideUp ( 'fast' ) ;
818- arrowhead . removeClass ( 'opened' ) ;
819- } else {
820- nestedList . slideDown ( 'fast' ) ;
821- arrowhead . addClass ( 'opened' ) ;
822- }
823- } ) ;
824-
825820 $ ( ".page-outline a[href]:not(.noscroll)" ) . click ( function ( e ) {
826821 e . preventDefault ( ) ;
827822 const aname = $ ( this ) . attr ( "href" ) ;
828823 gotoAnchor ( $ ( aname ) , aname ) ;
829824 } ) ;
830825
826+ navtree_trampoline . updateContentTop = function ( c ) {
827+ const pagenavcontents = $ ( "#page-nav-contents" ) ;
828+ if ( pagenavcontents . length ) {
829+ const height = $ ( '#doc-content' ) . height ( ) ;
830+ const navy = pagenavcontents . offset ( ) . top ;
831+ const yc = $ ( c ) . offset ( ) . top ;
832+ let offsets = [ ]
833+ for ( let i = 0 ; i < topMapping . length ; i ++ ) {
834+ offsets . push ( { id :topMapping [ i ] , y :$ ( '#' + topMapping [ i ] ) . offset ( ) . top - yc } ) ;
835+ }
836+ offsets . push ( { id :'' , y :1000000 } ) ;
837+ let scrollTarget = undefined , minNavY = 100000 , maxNavY = 0 ;
838+ for ( let i = 0 ; i < topMapping . length ; i ++ ) {
839+ const ys = offsets [ i ] . y ;
840+ const ye = offsets [ i + 1 ] . y ;
841+ const id = offsets [ i ] . id ;
842+ const nav = $ ( '#nav-' + id ) ;
843+ if ( ( ys > 2 || ye > 2 ) && ( ys < height - 2 || ye < height - 2 ) ) {
844+ if ( ! scrollTarget ) scrollTarget = nav ;
845+ nav . addClass ( 'vis' ) ;
846+ const ny = nav . offset ( ) . top ;
847+ minNavY = Math . min ( minNavY , ny ) ;
848+ maxNavY = Math . max ( maxNavY , ny ) ;
849+ } else {
850+ nav . removeClass ( 'vis' ) ;
851+ }
852+ }
853+ if ( scrollTarget ) {
854+ const my = ( maxNavY - minNavY ) / 2 ;
855+ pagenavcontents . scrollTo ( scrollTarget , { offset :- height / 2 + my } ) ;
856+ }
857+ }
858+ }
859+ // TODO: find out how to avoid a timeout
860+ setTimeout ( ( ) => {
861+ navtree_trampoline . updateContentTop ( content ) ;
862+ } , 200 ) ;
831863 }
832864 $ ( document ) . ready ( function ( ) { initPageToc ( ) ; initResizable ( ) ; } ) ;
833865
0 commit comments