Deploy to GitHub pages
[m6w6/libmemcached] / _static / js / theme.js
1 var jQuery = (typeof(window) != 'undefined') ? window.jQuery : require('jquery');
2
3 // Sphinx theme nav state
4 function ThemeNav () {
5
6 var nav = {
7 navBar: null,
8 win: null,
9 winScroll: false,
10 winResize: false,
11 linkScroll: false,
12 winPosition: 0,
13 winHeight: null,
14 docHeight: null,
15 isRunning: false
16 };
17
18 nav.enable = function (withStickyNav) {
19 var self = this;
20
21 // TODO this can likely be removed once the theme javascript is broken
22 // out from the RTD assets. This just ensures old projects that are
23 // calling `enable()` get the sticky menu on by default. All other cals
24 // to `enable` should include an argument for enabling the sticky menu.
25 if (typeof(withStickyNav) == 'undefined') {
26 withStickyNav = true;
27 }
28
29 if (self.isRunning) {
30 // Only allow enabling nav logic once
31 return;
32 }
33
34 self.isRunning = true;
35 jQuery(function ($) {
36 self.init($);
37
38 self.reset();
39 self.win.on('hashchange', self.reset);
40
41 if (withStickyNav) {
42 // Set scroll monitor
43 self.win.on('scroll', function () {
44 if (!self.linkScroll) {
45 if (!self.winScroll) {
46 self.winScroll = true;
47 requestAnimationFrame(function() { self.onScroll(); });
48 }
49 }
50 });
51 }
52
53 // Set resize monitor
54 self.win.on('resize', function () {
55 if (!self.winResize) {
56 self.winResize = true;
57 requestAnimationFrame(function() { self.onResize(); });
58 }
59 });
60
61 self.onResize();
62 });
63
64 };
65
66 // TODO remove this with a split in theme and Read the Docs JS logic as
67 // well, it's only here to support 0.3.0 installs of our theme.
68 nav.enableSticky = function() {
69 this.enable(true);
70 };
71
72 nav.init = function ($) {
73 var doc = $(document),
74 self = this;
75
76 this.navBar = $('div.wy-side-scroll:first');
77 this.win = $(window);
78
79 // Set up javascript UX bits
80 $(document)
81 // Shift nav in mobile when clicking the menu.
82 .on('click', "[data-toggle='wy-nav-top']", function() {
83 $("[data-toggle='wy-nav-shift']").toggleClass("shift");
84 $("[data-toggle='rst-versions']").toggleClass("shift");
85 })
86
87 // Nav menu link click operations
88 .on('click', ".wy-menu-vertical .current ul li a", function() {
89 var target = $(this);
90 // Close menu when you click a link.
91 $("[data-toggle='wy-nav-shift']").removeClass("shift");
92 $("[data-toggle='rst-versions']").toggleClass("shift");
93 // Handle dynamic display of l3 and l4 nav lists
94 self.toggleCurrent(target);
95 self.hashChange();
96 })
97 .on('click', "[data-toggle='rst-current-version']", function() {
98 $("[data-toggle='rst-versions']").toggleClass("shift-up");
99 })
100
101 // Make tables responsive
102 $("table.docutils:not(.field-list,.footnote,.citation)")
103 .wrap("<div class='wy-table-responsive'></div>");
104
105 // Add extra class to responsive tables that contain
106 // footnotes or citations so that we can target them for styling
107 $("table.docutils.footnote")
108 .wrap("<div class='wy-table-responsive footnote'></div>");
109 $("table.docutils.citation")
110 .wrap("<div class='wy-table-responsive citation'></div>");
111
112 // Add expand links to all parents of nested ul
113 $('.wy-menu-vertical ul').not('.simple').siblings('a').each(function () {
114 var link = $(this);
115 expand = $('<span class="toctree-expand"></span>');
116 expand.on('click', function (ev) {
117 self.toggleCurrent(link);
118 ev.stopPropagation();
119 return false;
120 });
121 link.prepend(expand);
122 });
123 };
124
125 nav.reset = function () {
126 // Get anchor from URL and open up nested nav
127 var anchor = encodeURI(window.location.hash) || '#';
128
129 try {
130 var vmenu = $('.wy-menu-vertical');
131 var link = vmenu.find('[href="' + anchor + '"]');
132 if (link.length === 0) {
133 // this link was not found in the sidebar.
134 // Find associated id element, then its closest section
135 // in the document and try with that one.
136 var id_elt = $('.document [id="' + anchor.substring(1) + '"]');
137 var closest_section = id_elt.closest('div.section');
138 link = vmenu.find('[href="#' + closest_section.attr("id") + '"]');
139 if (link.length === 0) {
140 // still not found in the sidebar. fall back to main section
141 link = vmenu.find('[href="#"]');
142 }
143 }
144 // If we found a matching link then reset current and re-apply
145 // otherwise retain the existing match
146 if (link.length > 0) {
147 $('.wy-menu-vertical .current').removeClass('current');
148 link.addClass('current');
149 link.closest('li.toctree-l1').addClass('current');
150 link.closest('li.toctree-l1').parent().addClass('current');
151 link.closest('li.toctree-l1').addClass('current');
152 link.closest('li.toctree-l2').addClass('current');
153 link.closest('li.toctree-l3').addClass('current');
154 link.closest('li.toctree-l4').addClass('current');
155 link[0].scrollIntoView();
156 }
157 }
158 catch (err) {
159 console.log("Error expanding nav for anchor", err);
160 }
161
162 };
163
164 nav.onScroll = function () {
165 this.winScroll = false;
166 var newWinPosition = this.win.scrollTop(),
167 winBottom = newWinPosition + this.winHeight,
168 navPosition = this.navBar.scrollTop(),
169 newNavPosition = navPosition + (newWinPosition - this.winPosition);
170 if (newWinPosition < 0 || winBottom > this.docHeight) {
171 return;
172 }
173 this.navBar.scrollTop(newNavPosition);
174 this.winPosition = newWinPosition;
175 };
176
177 nav.onResize = function () {
178 this.winResize = false;
179 this.winHeight = this.win.height();
180 this.docHeight = $(document).height();
181 };
182
183 nav.hashChange = function () {
184 this.linkScroll = true;
185 this.win.one('hashchange', function () {
186 this.linkScroll = false;
187 });
188 };
189
190 nav.toggleCurrent = function (elem) {
191 var parent_li = elem.closest('li');
192 parent_li.siblings('li.current').removeClass('current');
193 parent_li.siblings().find('li.current').removeClass('current');
194 parent_li.find('> ul li.current').removeClass('current');
195 parent_li.toggleClass('current');
196 }
197
198 return nav;
199 };
200
201 _ThemeNav = ThemeNav();
202
203 if (typeof(window) != 'undefined') {
204 window.SphinxRtdTheme = {
205 Navigation: _ThemeNav,
206 // TODO remove this once static assets are split up between the theme
207 // and Read the Docs. For now, this patches 0.3.0 to be backwards
208 // compatible with a pre-0.3.0 layout.html
209 StickyNav: _ThemeNav,
210 };
211 }
212
213
214 // requestAnimationFrame polyfill by Erik Möller. fixes from Paul Irish and Tino Zijdel
215 // https://gist.github.com/paulirish/1579671
216 // MIT license
217
218 (function() {
219 var lastTime = 0;
220 var vendors = ['ms', 'moz', 'webkit', 'o'];
221 for(var x = 0; x < vendors.length && !window.requestAnimationFrame; ++x) {
222 window.requestAnimationFrame = window[vendors[x]+'RequestAnimationFrame'];
223 window.cancelAnimationFrame = window[vendors[x]+'CancelAnimationFrame']
224 || window[vendors[x]+'CancelRequestAnimationFrame'];
225 }
226
227 if (!window.requestAnimationFrame)
228 window.requestAnimationFrame = function(callback, element) {
229 var currTime = new Date().getTime();
230 var timeToCall = Math.max(0, 16 - (currTime - lastTime));
231 var id = window.setTimeout(function() { callback(currTime + timeToCall); },
232 timeToCall);
233 lastTime = currTime + timeToCall;
234 return id;
235 };
236
237 if (!window.cancelAnimationFrame)
238 window.cancelAnimationFrame = function(id) {
239 clearTimeout(id);
240 };
241 }());