blob: 1bdd829a7683d778e63e86fc71ddce6167ea384a [file] [log] [blame]
Ezio Melotti8ad0eac2013-10-14 22:01:28 +03001/*
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});