Skip to content

Commit a43aeee

Browse files
committed
1 parent 3f7c138 commit a43aeee

File tree

1 file changed

+241
-0
lines changed

1 file changed

+241
-0
lines changed

docs/source/_static/js/theme.js

Lines changed: 241 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,241 @@
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+
module.exports.ThemeNav = ThemeNav();
202+
203+
if (typeof(window) != 'undefined') {
204+
window.SphinxRtdTheme = {
205+
Navigation: module.exports.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: module.exports.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+
}());

0 commit comments

Comments
 (0)