Home | History | Annotate | Download | only in static
      1 /*
      2  * sidebar.js
      3  * ~~~~~~~~~~
      4  *
      5  * This script makes the Sphinx sidebar collapsible and implements
      6  * intelligent scrolling.
      7  *
      8  * .sphinxsidebar contains .sphinxsidebarwrapper.  This script adds
      9  * in .sphixsidebar, after .sphinxsidebarwrapper, the #sidebarbutton
     10  * used to collapse and expand the sidebar.
     11  *
     12  * When the sidebar is collapsed the .sphinxsidebarwrapper is hidden
     13  * and the width of the sidebar and the margin-left of the document
     14  * are decreased. When the sidebar is expanded the opposite happens.
     15  * This script saves a per-browser/per-session cookie used to
     16  * remember the position of the sidebar among the pages.
     17  * Once the browser is closed the cookie is deleted and the position
     18  * reset to the default (expanded).
     19  *
     20  * :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS.
     21  * :license: BSD, see LICENSE for details.
     22  *
     23  */
     24 
     25 $(function() {
     26   // global elements used by the functions.
     27   // the 'sidebarbutton' element is defined as global after its
     28   // creation, in the add_sidebar_button function
     29   var jwindow = $(window);
     30   var jdocument = $(document);
     31   var bodywrapper = $('.bodywrapper');
     32   var sidebar = $('.sphinxsidebar');
     33   var sidebarwrapper = $('.sphinxsidebarwrapper');
     34 
     35   // original margin-left of the bodywrapper and width of the sidebar
     36   // with the sidebar expanded
     37   var bw_margin_expanded = bodywrapper.css('margin-left');
     38   var ssb_width_expanded = sidebar.width();
     39 
     40   // margin-left of the bodywrapper and width of the sidebar
     41   // with the sidebar collapsed
     42   var bw_margin_collapsed = '.8em';
     43   var ssb_width_collapsed = '.8em';
     44 
     45   // colors used by the current theme
     46   var dark_color = $('.related').css('background-color');
     47   var light_color = $('.document').css('background-color');
     48 
     49   function get_viewport_height() {
     50     if (window.innerHeight)
     51       return window.innerHeight;
     52     else
     53       return jwindow.height();
     54   }
     55 
     56   function sidebar_is_collapsed() {
     57     return sidebarwrapper.is(':not(:visible)');
     58   }
     59 
     60   function toggle_sidebar() {
     61     if (sidebar_is_collapsed())
     62       expand_sidebar();
     63     else
     64       collapse_sidebar();
     65     // adjust the scrolling of the sidebar
     66     scroll_sidebar();
     67   }
     68 
     69   function collapse_sidebar() {
     70     sidebarwrapper.hide();
     71     sidebar.css('width', ssb_width_collapsed);
     72     bodywrapper.css('margin-left', bw_margin_collapsed);
     73     sidebarbutton.css({
     74         'margin-left': '0',
     75         'height': bodywrapper.height()
     76     });
     77     sidebarbutton.find('span').text('');
     78     sidebarbutton.attr('title', _('Expand sidebar'));
     79     document.cookie = 'sidebar=collapsed';
     80   }
     81 
     82   function expand_sidebar() {
     83     bodywrapper.css('margin-left', bw_margin_expanded);
     84     sidebar.css('width', ssb_width_expanded);
     85     sidebarwrapper.show();
     86     sidebarbutton.css({
     87         'margin-left': ssb_width_expanded-12,
     88         'height': bodywrapper.height()
     89     });
     90     sidebarbutton.find('span').text('');
     91     sidebarbutton.attr('title', _('Collapse sidebar'));
     92     document.cookie = 'sidebar=expanded';
     93   }
     94 
     95   function add_sidebar_button() {
     96     sidebarwrapper.css({
     97         'float': 'left',
     98         'margin-right': '0',
     99         'width': ssb_width_expanded - 28
    100     });
    101     // create the button
    102     sidebar.append(
    103         '<div id="sidebarbutton"><span>&laquo;</span></div>'
    104     );
    105     var sidebarbutton = $('#sidebarbutton');
    106     light_color = sidebarbutton.css('background-color');
    107     // find the height of the viewport to center the '<<' in the page
    108     var viewport_height = get_viewport_height();
    109     sidebarbutton.find('span').css({
    110         'display': 'block',
    111         'margin-top': (viewport_height - sidebar.position().top - 20) / 2
    112     });
    113 
    114     sidebarbutton.click(toggle_sidebar);
    115     sidebarbutton.attr('title', _('Collapse sidebar'));
    116     sidebarbutton.css({
    117         'color': '#FFFFFF',
    118         'border-left': '1px solid ' + dark_color,
    119         'font-size': '1.2em',
    120         'cursor': 'pointer',
    121         'height': bodywrapper.height(),
    122         'padding-top': '1px',
    123         'margin-left': ssb_width_expanded - 12
    124     });
    125 
    126     sidebarbutton.hover(
    127       function () {
    128           $(this).css('background-color', dark_color);
    129       },
    130       function () {
    131           $(this).css('background-color', light_color);
    132       }
    133     );
    134   }
    135 
    136   function set_position_from_cookie() {
    137     if (!document.cookie)
    138       return;
    139     var items = document.cookie.split(';');
    140     for(var k=0; k<items.length; k++) {
    141       var key_val = items[k].split('=');
    142       var key = key_val[0];
    143       if (key == 'sidebar') {
    144         var value = key_val[1];
    145         if ((value == 'collapsed') && (!sidebar_is_collapsed()))
    146           collapse_sidebar();
    147         else if ((value == 'expanded') && (sidebar_is_collapsed()))
    148           expand_sidebar();
    149       }
    150     }
    151   }
    152 
    153   add_sidebar_button();
    154   var sidebarbutton = $('#sidebarbutton');
    155   set_position_from_cookie();
    156 
    157 
    158   /* intelligent scrolling */
    159   function scroll_sidebar() {
    160     var sidebar_height = sidebarwrapper.height();
    161     var viewport_height = get_viewport_height();
    162     var offset = sidebar.position()['top'];
    163     var wintop = jwindow.scrollTop();
    164     var winbot = wintop + viewport_height;
    165     var curtop = sidebarwrapper.position()['top'];
    166     var curbot = curtop + sidebar_height;
    167     // does sidebar fit in window?
    168     if (sidebar_height < viewport_height) {
    169       // yes: easy case -- always keep at the top
    170       sidebarwrapper.css('top', $u.min([$u.max([0, wintop - offset - 10]),
    171                             jdocument.height() - sidebar_height - 200]));
    172     }
    173     else {
    174       // no: only scroll if top/bottom edge of sidebar is at
    175       // top/bottom edge of window
    176       if (curtop > wintop && curbot > winbot) {
    177         sidebarwrapper.css('top', $u.max([wintop - offset - 10, 0]));
    178       }
    179       else if (curtop < wintop && curbot < winbot) {
    180         sidebarwrapper.css('top', $u.min([winbot - sidebar_height - offset - 20,
    181                               jdocument.height() - sidebar_height - 200]));
    182       }
    183     }
    184   }
    185   jwindow.scroll(scroll_sidebar);
    186 });
    187