]> granicus.if.org Git - python/commitdiff
#4965: Implement intelligent scrolling of the sidebar in the docs.
authorEzio Melotti <ezio.melotti@gmail.com>
Sun, 13 Oct 2013 23:58:59 +0000 (02:58 +0300)
committerEzio Melotti <ezio.melotti@gmail.com>
Sun, 13 Oct 2013 23:58:59 +0000 (02:58 +0300)
Doc/tools/sphinxext/static/basic.css
Doc/tools/sphinxext/static/sidebar.js

index b4721e805fd25bb7f2e8f0edd3b61f65e8c74e24..2058b05f941ed3f6464283d921b51c7bc49aef16 100644 (file)
@@ -38,6 +38,8 @@ div.related li.right {
 /* -- sidebar --------------------------------------------------------------- */
 
 div.sphinxsidebarwrapper {
+    position: relative;
+    top: 0;
     padding: 10px 5px 0 10px;
     word-wrap: break-word;
 }
index 0c410e6aa834df19c6b5bea9376fd477749ef450..e8d58f4bfaac49d928fb10605e507f2d9e3cbd7b 100644 (file)
@@ -2,7 +2,8 @@
  * sidebar.js
  * ~~~~~~~~~~
  *
- * This script makes the Sphinx sidebar collapsible.
+ * This script makes the Sphinx sidebar collapsible and implements intelligent
+ * scrolling.
  *
  * .sphinxsidebar contains .sphinxsidebarwrapper.  This script adds in
  * .sphixsidebar, after .sphinxsidebarwrapper, the #sidebarbutton used to
@@ -24,6 +25,8 @@ $(function() {
   // global elements used by the functions.
   // the 'sidebarbutton' element is defined as global after its
   // creation, in the add_sidebar_button function
+  var jwindow = $(window);
+  var jdocument = $(document);
   var bodywrapper = $('.bodywrapper');
   var sidebar = $('.sphinxsidebar');
   var sidebarwrapper = $('.sphinxsidebarwrapper');
@@ -42,6 +45,13 @@ $(function() {
   var dark_color = '#AAAAAA';
   var light_color = '#CCCCCC';
 
+  function get_viewport_height() {
+    if (window.innerHeight)
+      return window.innerHeight;
+    else
+      return jwindow.height();
+  }
+
   function sidebar_is_collapsed() {
     return sidebarwrapper.is(':not(:visible)');
   }
@@ -51,6 +61,8 @@ $(function() {
       expand_sidebar();
     else
       collapse_sidebar();
+    // adjust the scrolling of the sidebar
+    scroll_sidebar();
   }
 
   function collapse_sidebar() {
@@ -95,11 +107,7 @@ $(function() {
     );
     var sidebarbutton = $('#sidebarbutton');
     // find the height of the viewport to center the '<<' in the page
-    var viewport_height;
-    if (window.innerHeight)
-         viewport_height = window.innerHeight;
-    else
-         viewport_height = $(window).height();
+    var viewport_height = get_viewport_height();
     var sidebar_offset = sidebar.offset().top;
     var sidebar_height = Math.max(bodywrapper.height(), sidebar.height());
     sidebarbutton.find('span').css({
@@ -152,4 +160,34 @@ $(function() {
   add_sidebar_button();
   var sidebarbutton = $('#sidebarbutton');
   set_position_from_cookie();
+
+
+  /* intelligent scrolling */
+  function scroll_sidebar() {
+    var sidebar_height = sidebarwrapper.height();
+    var viewport_height = get_viewport_height();
+    var offset = sidebar.position()['top'];
+    var wintop = jwindow.scrollTop();
+    var winbot = wintop + viewport_height;
+    var curtop = sidebarwrapper.position()['top'];
+    var curbot = curtop + sidebar_height;
+    // does sidebar fit in window?
+    if (sidebar_height < viewport_height) {
+      // yes: easy case -- always keep at the top
+      sidebarwrapper.css('top', $u.min([$u.max([0, wintop - offset - 10]),
+                            jdocument.height() - sidebar_height - 200]));
+    }
+    else {
+      // no: only scroll if top/bottom edge of sidebar is at
+      // top/bottom edge of window
+      if (curtop > wintop && curbot > winbot) {
+        sidebarwrapper.css('top', $u.max([wintop - offset - 10, 0]));
+      }
+      else if (curtop < wintop && curbot < winbot) {
+        sidebarwrapper.css('top', $u.min([winbot - sidebar_height - offset - 20,
+                              jdocument.height() - sidebar_height - 200]));
+      }
+    }
+  }
+  jwindow.scroll(scroll_sidebar);
 });