1/* 2 * sidebar.js 3 * ~~~~~~~~~~ 4 * 5 * This script makes the Sphinx sidebar collapsible and implements intelligent 6 * scrolling. 7 * 8 * .sphinxsidebar contains .sphinxsidebarwrapper. This script adds in 9 * .sphixsidebar, after .sphinxsidebarwrapper, the #sidebarbutton used to 10 * collapse and expand the sidebar. 11 * 12 * When the sidebar is collapsed the .sphinxsidebarwrapper is hidden and the 13 * width of the sidebar and the margin-left of the document are decreased. 14 * When the sidebar is expanded the opposite happens. This script saves a 15 * per-browser/per-session cookie used to remember the position of the sidebar 16 * among the pages. Once the browser is closed the cookie is deleted and the 17 * position reset to the default (expanded). 18 * 19 * :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS. 20 * :license: BSD, see LICENSE for details. 21 * 22 */ 23 24$(function() { 25 // global elements used by the functions. 26 // the 'sidebarbutton' element is defined as global after its 27 // creation, in the add_sidebar_button function 28 var jwindow = $(window); 29 var jdocument = $(document); 30 var bodywrapper = $('.bodywrapper'); 31 var sidebar = $('.sphinxsidebar'); 32 var sidebarwrapper = $('.sphinxsidebarwrapper'); 33 34 // original margin-left of the bodywrapper and width of the sidebar 35 // with the sidebar expanded 36 var bw_margin_expanded = bodywrapper.css('margin-left'); 37 var ssb_width_expanded = sidebar.width(); 38 39 // margin-left of the bodywrapper and width of the sidebar 40 // with the sidebar collapsed 41 var bw_margin_collapsed = '.8em'; 42 var ssb_width_collapsed = '.8em'; 43 44 // colors used by the current theme 45 var dark_color = '#AAAAAA'; 46 var light_color = '#CCCCCC'; 47 48 function get_viewport_height() { 49 if (window.innerHeight) 50 return window.innerHeight; 51 else 52 return jwindow.height(); 53 } 54 55 function sidebar_is_collapsed() { 56 return sidebarwrapper.is(':not(:visible)'); 57 } 58 59 function toggle_sidebar() { 60 if (sidebar_is_collapsed()) 61 expand_sidebar(); 62 else 63 collapse_sidebar(); 64 // adjust the scrolling of the sidebar 65 scroll_sidebar(); 66 } 67 68 function collapse_sidebar() { 69 sidebarwrapper.hide(); 70 sidebar.css('width', ssb_width_collapsed); 71 bodywrapper.css('margin-left', bw_margin_collapsed); 72 sidebarbutton.css({ 73 'margin-left': '0', 74 'height': bodywrapper.height(), 75 'border-radius': '5px' 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 'border-radius': '0 5px 5px 0' 90 }); 91 sidebarbutton.find('span').text('«'); 92 sidebarbutton.attr('title', _('Collapse sidebar')); 93 //sidebarwrapper.css({'padding-top': 94 // Math.max(window.pageYOffset - sidebarwrapper.offset().top, 10)}); 95 document.cookie = 'sidebar=expanded'; 96 } 97 98 function add_sidebar_button() { 99 sidebarwrapper.css({ 100 'float': 'left', 101 'margin-right': '0', 102 'width': ssb_width_expanded - 28 103 }); 104 // create the button 105 sidebar.append( 106 '<div id="sidebarbutton"><span>«</span></div>' 107 ); 108 var sidebarbutton = $('#sidebarbutton'); 109 // find the height of the viewport to center the '<<' in the page 110 var viewport_height = get_viewport_height(); 111 var sidebar_offset = sidebar.offset().top; 112 var sidebar_height = Math.max(bodywrapper.height(), sidebar.height()); 113 sidebarbutton.find('span').css({ 114 'display': 'block', 115 'position': 'fixed', 116 'top': Math.min(viewport_height/2, sidebar_height/2 + sidebar_offset) - 10 117 }); 118 119 sidebarbutton.click(toggle_sidebar); 120 sidebarbutton.attr('title', _('Collapse sidebar')); 121 sidebarbutton.css({ 122 'border-radius': '0 5px 5px 0', 123 'color': '#444444', 124 'background-color': '#CCCCCC', 125 'font-size': '1.2em', 126 'cursor': 'pointer', 127 'height': sidebar_height, 128 'padding-top': '1px', 129 'padding-left': '1px', 130 'margin-left': ssb_width_expanded - 12 131 }); 132 133 sidebarbutton.hover( 134 function () { 135 $(this).css('background-color', dark_color); 136 }, 137 function () { 138 $(this).css('background-color', light_color); 139 } 140 ); 141 } 142 143 function set_position_from_cookie() { 144 if (!document.cookie) 145 return; 146 var items = document.cookie.split(';'); 147 for(var k=0; k<items.length; k++) { 148 var key_val = items[k].split('='); 149 var key = key_val[0]; 150 if (key == 'sidebar') { 151 var value = key_val[1]; 152 if ((value == 'collapsed') && (!sidebar_is_collapsed())) 153 collapse_sidebar(); 154 else if ((value == 'expanded') && (sidebar_is_collapsed())) 155 expand_sidebar(); 156 } 157 } 158 } 159 160 add_sidebar_button(); 161 var sidebarbutton = $('#sidebarbutton'); 162 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); 193}); 194