9ace345c |
// The MIT License (MIT)
// Copyright (c) 2013-2018 Dave Snider, Read the Docs, Inc. & contributors
// Permission is hereby granted, free of charge, to any person obtaining a copy of
// this software and associated documentation files (the "Software"), to deal in
// the Software without restriction, including without limitation the rights to
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
// the Software, and to permit persons to whom the Software is furnished to do so,
// subject to the following conditions:
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
a43aeeea |
// 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[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;
};
module.exports.ThemeNav = ThemeNav();
if (typeof(window) != 'undefined') {
window.SphinxRtdTheme = {
Navigation: module.exports.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: module.exports.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);
};
}());
|