123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242 |
- var jQuery = (typeof(window) != 'undefined') ? window.jQuery : require('jquery');
- // Sphinx theme nav state
- function ThemeNav () {
- var nav = {
- navBar: null,
- win: null,
- winScroll: false,
- winResize: false,
- linkScroll: false,
- winPosition: 0,
- winHeight: null,
- docHeight: null,
- isRunning: false
- };
- nav.enable = function (withStickyNav) {
- var self = this;
- // TODO this can likely be removed once the theme javascript is broken
- // out from the RTD assets. This just ensures old projects that are
- // calling `enable()` get the sticky menu on by default. All other cals
- // to `enable` should include an argument for enabling the sticky menu.
- if (typeof(withStickyNav) == 'undefined') {
- withStickyNav = true;
- }
- if (self.isRunning) {
- // Only allow enabling nav logic once
- return;
- }
- self.isRunning = true;
- jQuery(function ($) {
- self.init($);
- self.reset();
- self.win.on('hashchange', self.reset);
- if (withStickyNav) {
- // Set scroll monitor
- self.win.on('scroll', function () {
- if (!self.linkScroll) {
- if (!self.winScroll) {
- self.winScroll = true;
- requestAnimationFrame(function() { self.onScroll(); });
- }
- }
- });
- }
- // Set resize monitor
- self.win.on('resize', function () {
- if (!self.winResize) {
- self.winResize = true;
- requestAnimationFrame(function() { self.onResize(); });
- }
- });
- self.onResize();
- });
- };
- // TODO remove this with a split in theme and Read the Docs JS logic as
- // well, it's only here to support 0.3.0 installs of our theme.
- nav.enableSticky = function() {
- this.enable(true);
- };
- nav.init = function ($) {
- var doc = $(document),
- self = this;
- this.navBar = $('div.wy-side-scroll:first');
- this.win = $(window);
- // Set up javascript UX bits
- $(document)
- // Shift nav in mobile when clicking the menu.
- .on('click', "[data-toggle='wy-nav-top']", function() {
- $("[data-toggle='wy-nav-shift']").toggleClass("shift");
- $("[data-toggle='rst-versions']").toggleClass("shift");
- })
- // Nav menu link click operations
- .on('click', ".wy-menu-vertical .current ul li a", function() {
- var target = $(this);
- // Close menu when you click a link.
- $("[data-toggle='wy-nav-shift']").removeClass("shift");
- $("[data-toggle='rst-versions']").toggleClass("shift");
- // Handle dynamic display of l3 and l4 nav lists
- self.toggleCurrent(target);
- self.hashChange();
- })
- .on('click', "[data-toggle='rst-current-version']", function() {
- $("[data-toggle='rst-versions']").toggleClass("shift-up");
- })
- // Make tables responsive
- $("table.docutils:not(.field-list,.footnote,.citation)")
- .wrap("<div class='wy-table-responsive'></div>");
- // Add extra class to responsive tables that contain
- // footnotes or citations so that we can target them for styling
- $("table.docutils.footnote")
- .wrap("<div class='wy-table-responsive footnote'></div>");
- $("table.docutils.citation")
- .wrap("<div class='wy-table-responsive citation'></div>");
- // Add expand links to all parents of nested ul
- $('.wy-menu-vertical ul').not('.simple').siblings('a').each(function () {
- var link = $(this);
- expand = $('<span class="toctree-expand"></span>');
- expand.on('click', function (ev) {
- self.toggleCurrent(link);
- ev.stopPropagation();
- return false;
- });
- link.prepend(expand);
- });
- };
- nav.reset = function () {
- // Get anchor from URL and open up nested nav
- var anchor = encodeURI(window.location.hash) || '#';
- try {
- var vmenu = $('.wy-menu-vertical');
- var link = vmenu.find('[href="' + anchor + '"]');
- if (link.length === 0) {
- // this link was not found in the sidebar.
- // Find associated id element, then its closest section
- // in the document and try with that one.
- var id_elt = $('.document [id="' + anchor.substring(1) + '"]');
- var closest_section = id_elt.closest('div.section');
- link = vmenu.find('[href="#' + closest_section.attr("id") + '"]');
- if (link.length === 0) {
- // still not found in the sidebar. fall back to main section
- link = vmenu.find('[href="#"]');
- }
- }
- // If we found a matching link then reset current and re-apply
- // otherwise retain the existing match
- if (link.length > 0) {
- $('.wy-menu-vertical .current').removeClass('current');
- link.addClass('current');
- link.closest('li.toctree-l1').addClass('current');
- link.closest('li.toctree-l1').parent().addClass('current');
- link.closest('li.toctree-l1').addClass('current');
- link.closest('li.toctree-l2').addClass('current');
- link.closest('li.toctree-l3').addClass('current');
- link.closest('li.toctree-l4').addClass('current');
- link.closest('li.toctree-l5').addClass('current');
- link[0].scrollIntoView();
- }
- }
- catch (err) {
- console.log("Error expanding nav for anchor", err);
- }
- };
- nav.onScroll = function () {
- this.winScroll = false;
- var newWinPosition = this.win.scrollTop(),
- winBottom = newWinPosition + this.winHeight,
- navPosition = this.navBar.scrollTop(),
- newNavPosition = navPosition + (newWinPosition - this.winPosition);
- if (newWinPosition < 0 || winBottom > this.docHeight) {
- return;
- }
- this.navBar.scrollTop(newNavPosition);
- this.winPosition = newWinPosition;
- };
- nav.onResize = function () {
- this.winResize = false;
- this.winHeight = this.win.height();
- this.docHeight = $(document).height();
- };
- nav.hashChange = function () {
- this.linkScroll = true;
- this.win.one('hashchange', function () {
- this.linkScroll = false;
- });
- };
- nav.toggleCurrent = function (elem) {
- var parent_li = elem.closest('li');
- parent_li.siblings('li.current').removeClass('current');
- parent_li.siblings().find('li.current').removeClass('current');
- parent_li.find('> ul li.current').removeClass('current');
- parent_li.toggleClass('current');
- }
- return nav;
- };
- _ThemeNav = ThemeNav();
- if (typeof(window) != 'undefined') {
- window.SphinxRtdTheme = {
- Navigation: _ThemeNav,
- // TODO remove this once static assets are split up between the theme
- // and Read the Docs. For now, this patches 0.3.0 to be backwards
- // compatible with a pre-0.3.0 layout.html
- StickyNav: _ThemeNav,
- };
- }
- // requestAnimationFrame polyfill by Erik Möller. fixes from Paul Irish and Tino Zijdel
- // https://gist.github.com/paulirish/1579671
- // MIT license
- (function() {
- var lastTime = 0;
- var vendors = ['ms', 'moz', 'webkit', 'o'];
- for(var x = 0; x < vendors.length && !window.requestAnimationFrame; ++x) {
- window.requestAnimationFrame = window[vendors[x]+'RequestAnimationFrame'];
- window.cancelAnimationFrame = window[vendors[x]+'CancelAnimationFrame']
- || window[vendors[x]+'CancelRequestAnimationFrame'];
- }
- if (!window.requestAnimationFrame)
- window.requestAnimationFrame = function(callback, element) {
- var currTime = new Date().getTime();
- var timeToCall = Math.max(0, 16 - (currTime - lastTime));
- var id = window.setTimeout(function() { callback(currTime + timeToCall); },
- timeToCall);
- lastTime = currTime + timeToCall;
- return id;
- };
- if (!window.cancelAnimationFrame)
- window.cancelAnimationFrame = function(id) {
- clearTimeout(id);
- };
- }());
|