22 * sidebar.js
33 * ~~~~~~~~~~
44 *
5- * This script makes the Sphinx sidebar collapsible.
5+ * This script makes the Sphinx sidebar collapsible and implements intelligent
6+ * scrolling.
67 *
78 * .sphinxsidebar contains .sphinxsidebarwrapper. This script adds in
89 * .sphixsidebar, after .sphinxsidebarwrapper, the #sidebarbutton used to
@@ -24,6 +25,8 @@ $(function() {
2425 // global elements used by the functions.
2526 // the 'sidebarbutton' element is defined as global after its
2627 // creation, in the add_sidebar_button function
28+ var jwindow = $ ( window ) ;
29+ var jdocument = $ ( document ) ;
2730 var bodywrapper = $ ( '.bodywrapper' ) ;
2831 var sidebar = $ ( '.sphinxsidebar' ) ;
2932 var sidebarwrapper = $ ( '.sphinxsidebarwrapper' ) ;
@@ -42,6 +45,13 @@ $(function() {
4245 var dark_color = '#AAAAAA' ;
4346 var light_color = '#CCCCCC' ;
4447
48+ function get_viewport_height ( ) {
49+ if ( window . innerHeight )
50+ return window . innerHeight ;
51+ else
52+ return jwindow . height ( ) ;
53+ }
54+
4555 function sidebar_is_collapsed ( ) {
4656 return sidebarwrapper . is ( ':not(:visible)' ) ;
4757 }
@@ -51,6 +61,8 @@ $(function() {
5161 expand_sidebar ( ) ;
5262 else
5363 collapse_sidebar ( ) ;
64+ // adjust the scrolling of the sidebar
65+ scroll_sidebar ( ) ;
5466 }
5567
5668 function collapse_sidebar ( ) {
@@ -95,11 +107,7 @@ $(function() {
95107 ) ;
96108 var sidebarbutton = $ ( '#sidebarbutton' ) ;
97109 // find the height of the viewport to center the '<<' in the page
98- var viewport_height ;
99- if ( window . innerHeight )
100- viewport_height = window . innerHeight ;
101- else
102- viewport_height = $ ( window ) . height ( ) ;
110+ var viewport_height = get_viewport_height ( ) ;
103111 var sidebar_offset = sidebar . offset ( ) . top ;
104112 var sidebar_height = Math . max ( bodywrapper . height ( ) , sidebar . height ( ) ) ;
105113 sidebarbutton . find ( 'span' ) . css ( {
@@ -152,4 +160,34 @@ $(function() {
152160 add_sidebar_button ( ) ;
153161 var sidebarbutton = $ ( '#sidebarbutton' ) ;
154162 set_position_from_cookie ( ) ;
163+
164+
165+ /* intelligent scrolling */
166+ function scroll_sidebar ( ) {
167+ var sidebar_height = sidebarwrapper . height ( ) ;
168+ var viewport_height = get_viewport_height ( ) ;
169+ var offset = sidebar . position ( ) [ 'top' ] ;
170+ var wintop = jwindow . scrollTop ( ) ;
171+ var winbot = wintop + viewport_height ;
172+ var curtop = sidebarwrapper . position ( ) [ 'top' ] ;
173+ var curbot = curtop + sidebar_height ;
174+ // does sidebar fit in window?
175+ if ( sidebar_height < viewport_height ) {
176+ // yes: easy case -- always keep at the top
177+ sidebarwrapper . css ( 'top' , $u . min ( [ $u . max ( [ 0 , wintop - offset - 10 ] ) ,
178+ jdocument . height ( ) - sidebar_height - 200 ] ) ) ;
179+ }
180+ else {
181+ // no: only scroll if top/bottom edge of sidebar is at
182+ // top/bottom edge of window
183+ if ( curtop > wintop && curbot > winbot ) {
184+ sidebarwrapper . css ( 'top' , $u . max ( [ wintop - offset - 10 , 0 ] ) ) ;
185+ }
186+ else if ( curtop < wintop && curbot < winbot ) {
187+ sidebarwrapper . css ( 'top' , $u . min ( [ winbot - sidebar_height - offset - 20 ,
188+ jdocument . height ( ) - sidebar_height - 200 ] ) ) ;
189+ }
190+ }
191+ }
192+ jwindow . scroll ( scroll_sidebar ) ;
155193} ) ;
0 commit comments